Expandable CONTEXT_MENUs (GAL). Minor CONTEXT_MENU
This commit is contained in:
parent
946b9d1933
commit
4be876a13a
|
@ -33,14 +33,11 @@
|
||||||
CONTEXT_MENU::CONTEXT_MENU() :
|
CONTEXT_MENU::CONTEXT_MENU() :
|
||||||
m_titleSet( false ), m_selected( -1 ), m_tool( NULL ), m_icon( NULL )
|
m_titleSet( false ), m_selected( -1 ), m_tool( NULL ), m_icon( NULL )
|
||||||
{
|
{
|
||||||
setCustomEventHandler( boost::bind( &CONTEXT_MENU::handleCustomEvent, this, _1 ) );
|
|
||||||
setupEvents();
|
setupEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
|
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu )
|
||||||
m_titleSet( aMenu.m_titleSet ), m_selected( -1 ), m_tool( aMenu.m_tool ),
|
|
||||||
m_toolActions( aMenu.m_toolActions ), m_customHandler( aMenu.m_customHandler )
|
|
||||||
{
|
{
|
||||||
copyFrom( aMenu );
|
copyFrom( aMenu );
|
||||||
setupEvents();
|
setupEvents();
|
||||||
|
@ -51,12 +48,6 @@ CONTEXT_MENU& CONTEXT_MENU::operator=( const CONTEXT_MENU& aMenu )
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
|
||||||
m_titleSet = aMenu.m_titleSet;
|
|
||||||
m_selected = aMenu.m_selected;
|
|
||||||
m_tool = aMenu.m_tool;
|
|
||||||
m_toolActions = aMenu.m_toolActions;
|
|
||||||
m_customHandler = aMenu.m_customHandler;
|
|
||||||
|
|
||||||
copyFrom( aMenu );
|
copyFrom( aMenu );
|
||||||
setupEvents();
|
setupEvents();
|
||||||
|
|
||||||
|
@ -90,7 +81,7 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aIcon )
|
wxMenuItem* CONTEXT_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aIcon )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
@ -103,18 +94,18 @@ void CONTEXT_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aI
|
||||||
if( aIcon )
|
if( aIcon )
|
||||||
item->SetBitmap( KiBitmap( aIcon ) );
|
item->SetBitmap( KiBitmap( aIcon ) );
|
||||||
|
|
||||||
Append( item );
|
return Append( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
|
wxMenuItem* CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
|
||||||
{
|
{
|
||||||
/// ID numbers for tool actions need to have a value higher than m_actionId
|
/// ID numbers for tool actions need to have a value higher than ACTION_ID
|
||||||
int id = m_actionId + aAction.GetId();
|
int id = ACTION_ID + aAction.GetId();
|
||||||
const BITMAP_OPAQUE* icon = aAction.GetIcon();
|
const BITMAP_OPAQUE* icon = aAction.GetIcon();
|
||||||
|
|
||||||
wxMenuItem* item = new wxMenuItem( this, id,
|
wxMenuItem* item = new wxMenuItem( this, id, aAction.GetMenuItem(),
|
||||||
aAction.GetMenuItem(), aAction.GetDescription(), wxITEM_NORMAL );
|
aAction.GetDescription(), wxITEM_NORMAL );
|
||||||
|
|
||||||
if( icon )
|
if( icon )
|
||||||
item->SetBitmap( KiBitmap( icon ) );
|
item->SetBitmap( KiBitmap( icon ) );
|
||||||
|
@ -136,24 +127,45 @@ void CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
|
||||||
item->SetAccel( &accel );
|
item->SetAccel( &accel );
|
||||||
}
|
}
|
||||||
|
|
||||||
Append( item );
|
|
||||||
m_toolActions[id] = &aAction;
|
m_toolActions[id] = &aAction;
|
||||||
|
|
||||||
|
return Append( item );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::Add( CONTEXT_MENU* aMenu, const wxString& aLabel )
|
std::list<wxMenuItem*> CONTEXT_MENU::Add( CONTEXT_MENU* aMenu, const wxString& aLabel, bool aExpand )
|
||||||
{
|
{
|
||||||
if( aMenu->m_icon )
|
std::list<wxMenuItem*> items;
|
||||||
|
|
||||||
|
if( aExpand )
|
||||||
{
|
{
|
||||||
wxMenuItem* newItem = new wxMenuItem( this, -1, aLabel, wxEmptyString, wxITEM_NORMAL );
|
unsigned int i = 0;
|
||||||
newItem->SetBitmap( KiBitmap( aMenu->m_icon ) );
|
|
||||||
newItem->SetSubMenu( aMenu );
|
for( i = 0; i < aMenu->GetMenuItemCount(); ++i )
|
||||||
Append( newItem );
|
{
|
||||||
|
wxMenuItem* item = aMenu->FindItemByPosition( i );
|
||||||
|
items.push_back( appendCopy( item ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AppendSubMenu( aMenu, aLabel );
|
if( aMenu->m_icon )
|
||||||
|
{
|
||||||
|
wxMenuItem* newItem = new wxMenuItem( this, -1, aLabel, wxEmptyString, wxITEM_NORMAL );
|
||||||
|
newItem->SetBitmap( KiBitmap( aMenu->m_icon ) );
|
||||||
|
newItem->SetSubMenu( aMenu );
|
||||||
|
items.push_back( Append( newItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
items.push_back( AppendSubMenu( aMenu, aLabel ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_toolActions.insert( aMenu->m_toolActions.begin(), aMenu->m_toolActions.end() );
|
||||||
|
m_handlers.insert( m_handlers.end(), aMenu->m_handlers.begin(), aMenu->m_handlers.end() );
|
||||||
|
|
||||||
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,6 +176,7 @@ void CONTEXT_MENU::Clear()
|
||||||
GetMenuItems().DeleteContents( true );
|
GetMenuItems().DeleteContents( true );
|
||||||
GetMenuItems().Clear();
|
GetMenuItems().Clear();
|
||||||
m_toolActions.clear();
|
m_toolActions.clear();
|
||||||
|
m_handlers.clear();
|
||||||
GetMenuItems().DeleteContents( false ); // restore the default so destructor does not go wild
|
GetMenuItems().DeleteContents( false ); // restore the default so destructor does not go wild
|
||||||
|
|
||||||
assert( GetMenuItemCount() == 0 );
|
assert( GetMenuItemCount() == 0 );
|
||||||
|
@ -211,7 +224,14 @@ void CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
evt = m_customHandler( aEvent );
|
for( std::list<CUSTOM_MENU_HANDLER>::iterator it = m_handlers.begin();
|
||||||
|
it != m_handlers.end(); ++it )
|
||||||
|
{
|
||||||
|
evt = (*it)( aEvent );
|
||||||
|
|
||||||
|
if( evt )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Handling non-action menu entries (e.g. items in clarification list)
|
// Handling non-action menu entries (e.g. items in clarification list)
|
||||||
if( !evt )
|
if( !evt )
|
||||||
|
@ -244,49 +264,56 @@ void CONTEXT_MENU::setTool( TOOL_INTERACTIVE* aTool )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::copyItem( const wxMenuItem* aSource, wxMenuItem* aDest ) const
|
wxMenuItem* CONTEXT_MENU::appendCopy( const wxMenuItem* aSource )
|
||||||
{
|
{
|
||||||
assert( !aSource->IsSubMenu() ); // it does not transfer submenus
|
wxMenuItem* newItem = new wxMenuItem( this, aSource->GetId(), aSource->GetItemLabel(),
|
||||||
|
aSource->GetHelp(), aSource->GetKind() );
|
||||||
|
|
||||||
aDest->SetKind( aSource->GetKind() );
|
if( aSource->GetKind() == wxITEM_NORMAL )
|
||||||
aDest->SetHelp( aSource->GetHelp() );
|
newItem->SetBitmap( aSource->GetBitmap() );
|
||||||
aDest->Enable( aSource->IsEnabled() );
|
|
||||||
|
|
||||||
if( aSource->IsCheckable() )
|
if( aSource->IsSubMenu() )
|
||||||
aDest->Check( aSource->IsChecked() );
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Submenus of a CONTEXT_MENU are supposed to be CONTEXT_MENUs as well
|
||||||
|
assert( dynamic_cast<CONTEXT_MENU*>( aSource->GetSubMenu() ) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CONTEXT_MENU* menu = new CONTEXT_MENU( static_cast<const CONTEXT_MENU&>( *aSource->GetSubMenu() ) );
|
||||||
|
newItem->SetSubMenu( menu );
|
||||||
|
Append( newItem );
|
||||||
|
|
||||||
|
m_toolActions.insert( menu->m_toolActions.begin(), menu->m_toolActions.end() );
|
||||||
|
m_handlers.insert( m_handlers.end(), menu->m_handlers.begin(), menu->m_handlers.end() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Append( newItem );
|
||||||
|
newItem->SetKind( aSource->GetKind() );
|
||||||
|
newItem->SetHelp( aSource->GetHelp() );
|
||||||
|
newItem->Enable( aSource->IsEnabled() );
|
||||||
|
|
||||||
|
if( aSource->IsCheckable() )
|
||||||
|
newItem->Check( aSource->IsChecked() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::copyFrom( const CONTEXT_MENU& aMenu )
|
void CONTEXT_MENU::copyFrom( const CONTEXT_MENU& aMenu )
|
||||||
{
|
{
|
||||||
m_icon = aMenu.m_icon;
|
m_icon = aMenu.m_icon;
|
||||||
|
m_titleSet = aMenu.m_titleSet;
|
||||||
|
m_selected = -1; // aMenu.m_selected;
|
||||||
|
m_tool = aMenu.m_tool;
|
||||||
|
m_toolActions = aMenu.m_toolActions;
|
||||||
|
m_handlers = aMenu.m_handlers;
|
||||||
|
|
||||||
// Copy all the menu entries
|
// Copy all the menu entries
|
||||||
for( unsigned i = 0; i < aMenu.GetMenuItemCount(); ++i )
|
for( unsigned i = 0; i < aMenu.GetMenuItemCount(); ++i )
|
||||||
{
|
{
|
||||||
wxMenuItem* item = aMenu.FindItemByPosition( i );
|
wxMenuItem* item = aMenu.FindItemByPosition( i );
|
||||||
|
appendCopy( item );
|
||||||
wxMenuItem* newItem = new wxMenuItem( this, item->GetId(), item->GetItemLabel(),
|
|
||||||
item->GetHelp(), item->GetKind() );
|
|
||||||
|
|
||||||
if( item->GetKind() == wxITEM_NORMAL )
|
|
||||||
newItem->SetBitmap( item->GetBitmap() );
|
|
||||||
|
|
||||||
if( item->IsSubMenu() )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
// Submenus of a CONTEXT_MENU are supposed to be CONTEXT_MENUs as well
|
|
||||||
assert( dynamic_cast<CONTEXT_MENU*>( item->GetSubMenu() ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CONTEXT_MENU* menu = new CONTEXT_MENU( static_cast<const CONTEXT_MENU&>( *item->GetSubMenu() ) );
|
|
||||||
newItem->SetSubMenu( menu );
|
|
||||||
Append( newItem );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Append( newItem );
|
|
||||||
copyItem( item, newItem );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ public:
|
||||||
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
|
* @param aId is the ID that is sent in the TOOL_EVENT. It should be unique for every entry.
|
||||||
* @param aIcon is an optional icon.
|
* @param aIcon is an optional icon.
|
||||||
*/
|
*/
|
||||||
void Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aIcon = NULL );
|
wxMenuItem* Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aIcon = NULL );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Add()
|
* Function Add()
|
||||||
|
@ -85,7 +85,7 @@ public:
|
||||||
* a TOOL_EVENT command containing name of the action is sent.
|
* a TOOL_EVENT command containing name of the action is sent.
|
||||||
* @param aAction is the action to be added to menu entry.
|
* @param aAction is the action to be added to menu entry.
|
||||||
*/
|
*/
|
||||||
void Add( const TOOL_ACTION& aAction );
|
wxMenuItem* Add( const TOOL_ACTION& aAction );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Add()
|
* Function Add()
|
||||||
|
@ -93,8 +93,10 @@ public:
|
||||||
* is the capability to handle icons.
|
* is the capability to handle icons.
|
||||||
* @param aMenu is the submenu to be added.
|
* @param aMenu is the submenu to be added.
|
||||||
* @param aLabel is the caption displayed for the menu entry.
|
* @param aLabel is the caption displayed for the menu entry.
|
||||||
|
* @param aExpand allows to add all entries from the menu as individual entries rather than
|
||||||
|
* add everything as a submenu.
|
||||||
*/
|
*/
|
||||||
void Add( CONTEXT_MENU* aMenu, const wxString& aLabel );
|
std::list<wxMenuItem*> Add( CONTEXT_MENU* aMenu, const wxString& aLabel, bool aExpand = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Clear()
|
* Function Clear()
|
||||||
|
@ -114,23 +116,21 @@ public:
|
||||||
return m_selected;
|
return m_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
///> Function type to handle menu events in a custom way.
|
||||||
void setCustomEventHandler( boost::function<OPT_TOOL_EVENT(const wxMenuEvent&)> aHandler )
|
typedef boost::function<OPT_TOOL_EVENT(const wxMenuEvent&)> CUSTOM_MENU_HANDLER;
|
||||||
{
|
|
||||||
m_customHandler = aHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual OPT_TOOL_EVENT handleCustomEvent( const wxMenuEvent& aEvent )
|
///> Adds an event handler to the custom menu event handlers chain.
|
||||||
|
void AppendCustomEventHandler( CUSTOM_MENU_HANDLER aHandler )
|
||||||
{
|
{
|
||||||
return OPT_TOOL_EVENT();
|
m_handlers.push_back( aHandler );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Function copyItem
|
* Function appendCopy
|
||||||
* Copies all properties of a menu entry to another.
|
* Appends a copy of wxMenuItem.
|
||||||
*/
|
*/
|
||||||
void copyItem( const wxMenuItem* aSource, wxMenuItem* aDest ) const;
|
wxMenuItem* appendCopy( const wxMenuItem* aSource );
|
||||||
|
|
||||||
///> Common part of copy constructor and assignment operator.
|
///> Common part of copy constructor and assignment operator.
|
||||||
void copyFrom( const CONTEXT_MENU& aMenu );
|
void copyFrom( const CONTEXT_MENU& aMenu );
|
||||||
|
@ -154,22 +154,19 @@ private:
|
||||||
///> Stores the id number of selected item.
|
///> Stores the id number of selected item.
|
||||||
int m_selected;
|
int m_selected;
|
||||||
|
|
||||||
///> Instance of menu event handler.
|
|
||||||
//CMEventHandler m_handler;
|
|
||||||
|
|
||||||
///> Creator of the menu
|
///> Creator of the menu
|
||||||
TOOL_INTERACTIVE* m_tool;
|
TOOL_INTERACTIVE* m_tool;
|
||||||
|
|
||||||
/// Menu items with ID higher than that are considered TOOL_ACTIONs
|
///> Menu items with ID higher than that are considered TOOL_ACTIONs
|
||||||
static const int m_actionId = 10000;
|
static const int ACTION_ID = 30000;
|
||||||
|
|
||||||
/// Associates tool actions with menu item IDs. Non-owning.
|
///> Associates tool actions with menu item IDs. Non-owning.
|
||||||
std::map<int, const TOOL_ACTION*> m_toolActions;
|
std::map<int, const TOOL_ACTION*> m_toolActions;
|
||||||
|
|
||||||
/// Custom events handler, allows to translate wxEvents to TOOL_EVENTs.
|
///> Chain of custom menu event handlers.
|
||||||
boost::function<OPT_TOOL_EVENT(const wxMenuEvent& aEvent)> m_customHandler;
|
std::list<CUSTOM_MENU_HANDLER> m_handlers;
|
||||||
|
|
||||||
/// Optional icon
|
///> Optional icon
|
||||||
const BITMAP_OPAQUE* m_icon;
|
const BITMAP_OPAQUE* m_icon;
|
||||||
|
|
||||||
friend class TOOL_INTERACTIVE;
|
friend class TOOL_INTERACTIVE;
|
||||||
|
|
|
@ -96,8 +96,8 @@ public:
|
||||||
{
|
{
|
||||||
m_board = NULL;
|
m_board = NULL;
|
||||||
SetIcon( width_track_via_xpm );
|
SetIcon( width_track_via_xpm );
|
||||||
setCustomEventHandler( boost::bind( &CONTEXT_TRACK_WIDTH_MENU::handleCustomEvent,
|
AppendCustomEventHandler( boost::bind( &CONTEXT_TRACK_WIDTH_MENU::handleCustomEvent,
|
||||||
this, _1 ) );
|
this, _1 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBoard( BOARD* aBoard )
|
void SetBoard( BOARD* aBoard )
|
||||||
|
|
|
@ -242,7 +242,7 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition )
|
void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CONDITION& aCondition )
|
||||||
{
|
{
|
||||||
assert( aAction.GetId() > 0 ); // Check if the action was registered before in ACTION_MANAGER
|
assert( aAction.GetId() > 0 ); // Check if action was previously registered in ACTION_MANAGER
|
||||||
|
|
||||||
m_menu.Add( aAction );
|
m_menu.Add( aAction );
|
||||||
m_menuConditions.push_back( aCondition );
|
m_menuConditions.push_back( aCondition );
|
||||||
|
@ -250,10 +250,12 @@ void SELECTION_TOOL::AddMenuItem( const TOOL_ACTION& aAction, const SELECTION_CO
|
||||||
|
|
||||||
|
|
||||||
void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
|
void SELECTION_TOOL::AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
|
||||||
const SELECTION_CONDITION& aCondition )
|
const SELECTION_CONDITION& aCondition, bool aExpand )
|
||||||
{
|
{
|
||||||
m_menu.Add( aMenu, aLabel );
|
std::list<wxMenuItem*> items = m_menu.Add( aMenu, aLabel, aExpand );
|
||||||
m_menuConditions.push_back( aCondition );
|
|
||||||
|
for( unsigned int i = 0; i < items.size(); ++i )
|
||||||
|
m_menuConditions.push_back( aCondition );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1285,7 +1287,7 @@ void SELECTION_TOOL::generateMenu()
|
||||||
|
|
||||||
assert( m_menuCopy.GetMenuItemCount() == m_menuConditions.size() );
|
assert( m_menuCopy.GetMenuItemCount() == m_menuConditions.size() );
|
||||||
|
|
||||||
// Filter out entries that does not apply to the current selection
|
// Filter out entries that do not comply with the current selection
|
||||||
for( int i = m_menuCopy.GetMenuItemCount() - 1; i >= 0; --i )
|
for( int i = m_menuCopy.GetMenuItemCount() - 1; i >= 0; --i )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -141,9 +141,11 @@ public:
|
||||||
* @param aMenu is the submenu to be added.
|
* @param aMenu is the submenu to be added.
|
||||||
* @param aLabel is the label of added submenu.
|
* @param aLabel is the label of added submenu.
|
||||||
* @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
|
* @param aCondition is a condition that has to be fulfilled to enable the submenu entry.
|
||||||
|
* @param aExpand determines if the added submenu items should be added as individual items.
|
||||||
*/
|
*/
|
||||||
void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
|
void AddSubMenu( CONTEXT_MENU* aMenu, const wxString& aLabel,
|
||||||
const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways );
|
const SELECTION_CONDITION& aCondition = SELECTION_CONDITIONS::ShowAlways,
|
||||||
|
bool aExpand = false );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function EditModules()
|
* Function EditModules()
|
||||||
|
|
Loading…
Reference in New Issue