reman3/Rayman_X/cpa/tempgrp/ITF/cpasubm.cpp

392 lines
13 KiB
C++

/*=========================================================================
*
* EDTSubm.cpp : popup menu
*
*
* Version 1.0
* Creation date
* Revision date
*
* FBF
*=======================================================================*/
#include "stdafx.h"
#include "acp_base.h"
#include "itf/customid.h"
#ifdef ACTIVE_EDITOR
#include "itf/CPAsubm.hpp"
#include "itf/CPADLLb.hpp"
///////////////////////////////////////////////////////////////////////////////
// MACROS
///////////////////////////////////////////////////////////////////////////////
#define M_Entry(p_oElement) ( (EDT_SubMenuEntry*) p_oElement )
#define M_Menu(p_oElement) ( (EDT_SubMenu*) p_oElement )
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// class EDT_SubMenuEntry
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Description : constructor
// ----------------------------------------------------------------------------
EDT_SubMenuEntry::EDT_SubMenuEntry(CPA_EditorBase *pOwner, char *p_cText, UINT uiMsgID, UINT uiIntID, BOOL _bCheck /*=FALSE*/, BOOL _bEnable /*=TRUE*/)
:EDT_SubMenuElement(C_SMEEntry)
{
ASSERT( p_cText );
m_p_cText = (char*)malloc(strlen(p_cText)+1);
strcpy(m_p_cText, p_cText);
m_pOwner = pOwner;
m_IDCmdMsg = uiMsgID;
m_uiID = uiIntID;
m_bChecked = _bCheck;
m_bEnabled = _bEnable;
}
// ----------------------------------------------------------------------------
// Description : destructor
// ----------------------------------------------------------------------------
EDT_SubMenuEntry::~EDT_SubMenuEntry()
{
if(m_p_cText)
free(m_p_cText);
}
// ----------------------------------------------------------------------------
// Description : call handle function
// ----------------------------------------------------------------------------
UINT EDT_SubMenuEntry::SendCommand(EDT_SubMenu *_p_oSubMenu)
{
if (m_pOwner)
m_pOwner->_OnSubMenuCommand(_p_oSubMenu,m_IDCmdMsg);
return NULL;
}
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// class EDT_SubMenu
//-----------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Description : constructor
// ----------------------------------------------------------------------------
EDT_SubMenu::EDT_SubMenu(tde_SubMenu _eSubMenu,UINT _uiIDStart /*=C_CustomIDUserEnd*/)
:EDT_SubMenuElement(C_SMEMenu)
{
m_eSubMenu = _eSubMenu;
m_uiInternalID = m_uiInternalIDStart = _uiIDStart;
m_bHasFather = FALSE;
m_p_oFather = NULL;
m_szName = NULL;
RemoveAll();
}
// ----------------------------------------------------------------------------
// Description : destructor
// ----------------------------------------------------------------------------
EDT_SubMenu::~EDT_SubMenu()
{
Clear();
if(m_szName)
free(m_szName);
}
// ----------------------------------------------------------------------------
// Description : clear SubMenu content
// ----------------------------------------------------------------------------
void EDT_SubMenu::Clear()
{
POSITION stPos = GetHeadPosition();
while(stPos)
{
EDT_SubMenuElement *p_oElement = GetNext( stPos );
if( p_oElement -> mfn_eGetElementType() == C_SMEMenu )
{
// p_oElement is a SubMenu
M_Menu(p_oElement) -> Clear();
}
delete p_oElement;
}
RemoveAll();
m_uiInternalID = m_uiInternalIDStart;
}
// ----------------------------------------------------------------------------
// Description : return SubMenuType
// ----------------------------------------------------------------------------
tde_SubMenu EDT_SubMenu::GetSubMenuType()
{
return m_eSubMenu;
}
// ----------------------------------------------------------------------------
// Description : set father of SubMenu
// ----------------------------------------------------------------------------
void EDT_SubMenu::fn_vSetFather(EDT_SubMenu *_p_oFather)
{
ASSERT( _p_oFather );
m_bHasFather = TRUE;
m_p_oFather = _p_oFather;
}
// ----------------------------------------------------------------------------
// Description : set SubMenu name
// ----------------------------------------------------------------------------
void EDT_SubMenu::fn_vSetName(char *_szName)
{
ASSERT( _szName );
m_szName = (char*)malloc(strlen(_szName)+1);
strcpy(m_szName, _szName);
}
// ----------------------------------------------------------------------------
// Description : return next internal ID
// ----------------------------------------------------------------------------
UINT EDT_SubMenu::mfn_vGetNextInternalID()
{
if( m_bHasFather )
return m_p_oFather -> mfn_vGetNextInternalID();
else
return m_uiInternalID++;
}
// ----------------------------------------------------------------------------
// Description : build SubMenu
// ----------------------------------------------------------------------------
void EDT_SubMenu::Build(CMenu *pPopupMenu /*=NULL*/)
{
if(pPopupMenu)
{
EDT_SubMenuElement *p_oElement;
CMenu *p_oMenu;
UINT uiFlags;
// delete SubMenu
DeleteEntirePopupMenu(pPopupMenu);
// if last entry is a separator, remove it
if (!IsEmpty())
{
// check last element
p_oElement = GetTail();
if (p_oElement->mfn_eGetElementType() == C_SMESeparator)
RemoveTail();
}
// add all entries
POSITION stPos = GetHeadPosition();
while(stPos)
{
p_oElement = GetNext(stPos);
// add entry
switch ( p_oElement -> mfn_eGetElementType() )
{
case C_SMESeparator: // add a separator
pPopupMenu -> AppendMenu(MF_SEPARATOR);
break;
case C_SMEEntry: // add an item
uiFlags = MF_STRING | (M_Entry(p_oElement)->GetCheck() ? MF_CHECKED : MF_UNCHECKED )
| (M_Entry(p_oElement)->GetEnable() ? MF_ENABLED : MF_GRAYED );
pPopupMenu -> AppendMenu(uiFlags, M_Entry(p_oElement)->GetInternalID(), M_Entry(p_oElement)->GetText());
break;
case C_SMEMenu: // add a SubMenu
// create SubMenu
p_oMenu = new CMenu();
p_oMenu -> CreatePopupMenu();
// fill it
M_Menu(p_oElement) -> Build( p_oMenu );
// add to current SubMenu
pPopupMenu -> AppendMenu ( MF_STRING|MF_POPUP|MF_ENABLED , (UINT)p_oMenu -> Detach() , M_Menu(p_oElement) -> m_szName ) ;
delete p_oMenu;
break;
}
}
}
}
// ----------------------------------------------------------------------------
// Description : delete CMenu content
// ----------------------------------------------------------------------------
void EDT_SubMenu::DeleteEntirePopupMenu(CMenu* pPopupMenu)
{
while(pPopupMenu->GetMenuItemCount() > 0)
{
UINT uiState = pPopupMenu->GetMenuState(0,MF_BYPOSITION);
if(HIWORD(uiState) != 0)
{
// first item is a SubMenu
DeleteEntirePopupMenu(pPopupMenu->GetSubMenu(0));
}
pPopupMenu->DeleteMenu(0,MF_BYPOSITION);
}
}
// ----------------------------------------------------------------------------
// Description : get a new SubMenu (must uses it as sub menu of 'this')
// ----------------------------------------------------------------------------
EDT_SubMenu *EDT_SubMenu::fn_p_oGetNewSubMenu(char *_szName, tde_SubMenu _eMenuType /*=C_SubSubMenu*/)
{
ASSERT( _szName );
EDT_SubMenu *p_oResult = new EDT_SubMenu( _eMenuType == C_SubSubMenu ? GetSubMenuType() : _eMenuType );
p_oResult -> fn_vSetName( _szName );
p_oResult -> fn_vSetFather( this );
return p_oResult;
}
// ----------------------------------------------------------------------------
// Description : add a separator
// ----------------------------------------------------------------------------
void EDT_SubMenu::AddASeparator()
{
AddTail(new EDT_SubMenuSeparator());
}
// ----------------------------------------------------------------------------
// Description : add an entry from DLL
// ----------------------------------------------------------------------------
void EDT_SubMenu::AddAnEntry(CPA_EditorBase *p_oOwner, char *p_cText, UINT uiEntryID, BOOL _bCheck /*=FALSE*/, BOOL _bEnable /*=TRUE*/)
{
AddTail(new EDT_SubMenuEntry(p_oOwner, p_cText, uiEntryID, mfn_vGetNextInternalID(), _bCheck, _bEnable));
}
// ----------------------------------------------------------------------------
// Description : add a SubMenu
// ----------------------------------------------------------------------------
void EDT_SubMenu::AddASubMenu(EDT_SubMenu *_p_oSubMenu)
{
ASSERT( _p_oSubMenu );
// SubMenu must be child of current SubMenu
ASSERT( _p_oSubMenu -> m_p_oFather == this );
// add SubMenu
AddTail( (EDT_SubMenuElement*)_p_oSubMenu );
}
// ----------------------------------------------------------------------------
// Description : handle selected item
// ----------------------------------------------------------------------------
UINT EDT_SubMenu::_OnCommand(UINT uiInternalID)
{
POSITION stPos;
EDT_SubMenuElement *p_oElement;
stPos = GetHeadPosition();
while(stPos)
{
p_oElement = GetNext(stPos);
if( (p_oElement -> mfn_eGetElementType() == C_SMEEntry) && (M_Entry(p_oElement) -> GetInternalID() == uiInternalID) )
{
// entry found!, launch command on owner
return M_Entry(p_oElement) -> SendCommand(this);
}
else if( (p_oElement -> mfn_eGetElementType() == C_SMEMenu) )
{
// search on submenu
UINT uiResult = M_Menu(p_oElement) -> _OnCommand( uiInternalID );
if( uiResult )
// entry found
return uiResult;
}
}
return NULL;
}
// ----------------------------------------------------------------------------
// Description : handle selected item
// ----------------------------------------------------------------------------
BOOL EDT_SubMenu::fn_bFindCmdID (UINT uiInternalID, CPA_EditorBase **pOwner, UINT *CmdID)
{
EDT_SubMenuElement *pElem;
POSITION pos;
pos = GetHeadPosition();
while(pos)
{
pElem = GetNext(pos);
if ((pElem->mfn_eGetElementType() == C_SMEEntry) && (M_Entry(pElem)->GetInternalID() == uiInternalID))
{
// entry found
*CmdID = M_Entry(pElem)->GetCmdID();
if (pOwner)
*pOwner = M_Entry(pElem)->GetOwner();
return TRUE;
}
else if ((pElem->mfn_eGetElementType() == C_SMEMenu))
{
// search on submenu
if (M_Menu(pElem)->fn_bFindCmdID(uiInternalID,pOwner,CmdID))
return TRUE;
}
}
// entry not found
return FALSE;
}
// JMD
char EDT_SubMenu::fn_cGrayedItem (CMenu *pPopupMenu, char *szItem) {
char cFinish = 0 ;
if(pPopupMenu) {
EDT_SubMenuElement *p_oElement;
int iID ;
LPCTSTR szText ;
// add all entries
POSITION stPos = GetHeadPosition();
while(stPos && !cFinish) {
p_oElement = GetNext(stPos);
// add entry
switch ( p_oElement -> mfn_eGetElementType() ) {
case C_SMEEntry: // add an item
iID = M_Entry(p_oElement)->GetInternalID();
szText = M_Entry(p_oElement)->GetText();
if ( !stricmp (szItem, szText) ) {
pPopupMenu->EnableMenuItem ( iID, MF_GRAYED | MF_BYCOMMAND ) ;
cFinish = 1 ;
}
break;
case C_SMEMenu: // add a SubMenu
iID = M_Menu(p_oElement)->m_uiInternalID;
szText = M_Menu(p_oElement)->m_szName ;
if ( !stricmp (szItem, szText) ) {
//pPopupMenu->EnableMenuItem ( iID, MF_BYCOMMAND ) ;
M_Menu(p_oElement)->fn_vGrayedAllMenuItem( pPopupMenu );
cFinish = 1 ;
}
else
cFinish = M_Menu(p_oElement)->fn_cGrayedItem( pPopupMenu, szItem );
break;
}
}
}
return (cFinish) ;
}
void EDT_SubMenu::fn_vGrayedAllMenuItem ( CMenu *pPopupMenu ){
EDT_SubMenuElement *p_oElement;
int iID ;
// add all entries
POSITION stPos = GetHeadPosition();
while(stPos) {
p_oElement = GetNext(stPos);
// add entry
switch ( p_oElement -> mfn_eGetElementType() ) {
case C_SMEEntry: // add an item
iID = M_Entry(p_oElement)->GetInternalID();
pPopupMenu->EnableMenuItem ( iID, MF_GRAYED | MF_BYCOMMAND ) ;
break;
case C_SMEMenu: // add a SubMenu
M_Menu(p_oElement)->fn_vGrayedAllMenuItem( pPopupMenu );
break;
}
}
}
#endif //ACTIVE_EDITOR