Added functions for handling hotkeys, interface for adding TOOL_ACTIONs to CONTEXT_MENU.
Less objects are allocated dynamically. CONTEXT_MENU is being run using its copy (it saves a hassle of following the lifetime of object).
This commit is contained in:
parent
7b7a331645
commit
61066fa608
|
@ -22,62 +22,45 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <wx/wx.h>
|
|
||||||
#include <wx/menu.h>
|
|
||||||
|
|
||||||
#include <tool/tool_event.h>
|
#include <tool/tool_event.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tool/tool_interactive.h>
|
#include <tool/tool_interactive.h>
|
||||||
|
|
||||||
#include <tool/context_menu.h>
|
#include <tool/context_menu.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
class CONTEXT_MENU::CMEventHandler : public wxEvtHandler
|
CONTEXT_MENU::CONTEXT_MENU() :
|
||||||
|
m_titleSet( false ), m_handler( this ), m_tool( NULL )
|
||||||
{
|
{
|
||||||
public:
|
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
|
||||||
CMEventHandler( CONTEXT_MENU* aMenu ):
|
NULL, &m_handler );
|
||||||
m_menu( aMenu ) {};
|
m_menu.Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ),
|
||||||
|
NULL, &m_handler );
|
||||||
void onEvent( wxEvent& aEvent )
|
|
||||||
{
|
|
||||||
TOOL_EVENT evt;
|
|
||||||
wxEventType type = aEvent.GetEventType();
|
|
||||||
|
|
||||||
if( type == wxEVT_MENU_HIGHLIGHT )
|
|
||||||
evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
|
||||||
else if( type == wxEVT_COMMAND_MENU_SELECTED )
|
|
||||||
evt = TOOL_EVENT( TC_Command, TA_ContextMenuChoice, aEvent.GetId() );
|
|
||||||
|
|
||||||
if( m_menu->m_tool )
|
|
||||||
m_menu->m_tool->GetManager()->ProcessEvent( evt );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CONTEXT_MENU* m_menu;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CONTEXT_MENU::CONTEXT_MENU()
|
|
||||||
{
|
|
||||||
m_tool = NULL;
|
|
||||||
m_menu = new wxMenu();
|
|
||||||
m_handler = new CMEventHandler( this );
|
|
||||||
m_menu->Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
|
|
||||||
NULL, m_handler );
|
|
||||||
m_menu->Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ),
|
|
||||||
NULL, m_handler );
|
|
||||||
|
|
||||||
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
|
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
|
||||||
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, 0, m_menu );
|
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, 0, &m_menu );
|
||||||
m_menu->AddPendingEvent( menuEvent );
|
m_menu.AddPendingEvent( menuEvent );
|
||||||
|
|
||||||
m_titleSet = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CONTEXT_MENU::~CONTEXT_MENU()
|
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu ) :
|
||||||
|
m_titleSet( aMenu.m_titleSet ), m_handler( this ), m_tool( aMenu.m_tool )
|
||||||
{
|
{
|
||||||
delete m_menu;
|
m_menu.Connect( wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ),
|
||||||
delete m_handler;
|
NULL, &m_handler );
|
||||||
|
m_menu.Connect( wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ),
|
||||||
|
NULL, &m_handler );
|
||||||
|
|
||||||
|
// Workaround for the case when mouse cursor never reaches menu (it hangs up tools using menu)
|
||||||
|
wxMenuEvent menuEvent( wxEVT_MENU_HIGHLIGHT, 0, &m_menu );
|
||||||
|
m_menu.AddPendingEvent( menuEvent );
|
||||||
|
|
||||||
|
// Copy all the menu entries
|
||||||
|
for( unsigned i = 0; i < aMenu.m_menu.GetMenuItemCount(); ++i )
|
||||||
|
{
|
||||||
|
wxMenuItem* item = aMenu.m_menu.FindItemByPosition( i );
|
||||||
|
m_menu.Append( new wxMenuItem( &m_menu, item->GetId(), item->GetItemLabel(),
|
||||||
|
wxEmptyString, wxITEM_NORMAL ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,23 +69,70 @@ void CONTEXT_MENU::SetTitle( const wxString& aTitle )
|
||||||
// Unfortunately wxMenu::SetTitle() does nothing..
|
// Unfortunately wxMenu::SetTitle() does nothing..
|
||||||
if( m_titleSet )
|
if( m_titleSet )
|
||||||
{
|
{
|
||||||
m_menu->Delete( m_menu->FindItemByPosition( 0 ) ); // fixme: this is LAME!
|
m_menu.FindItemByPosition( 0 )->SetItemLabel( aTitle );
|
||||||
m_menu->Delete( m_menu->FindItemByPosition( 0 ) );
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_menu.InsertSeparator( 0 );
|
||||||
|
m_menu.Insert( 0, new wxMenuItem( &m_menu, -1, aTitle, wxEmptyString, wxITEM_NORMAL ) );
|
||||||
|
m_titleSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_menu->InsertSeparator( 0 );
|
|
||||||
m_menu->Insert( 0, new wxMenuItem( m_menu, -1, aTitle, wxEmptyString, wxITEM_NORMAL ) );
|
|
||||||
m_titleSet = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::Add( const wxString& aItem, int aId )
|
void CONTEXT_MENU::Add( const wxString& aLabel, int aId )
|
||||||
{
|
{
|
||||||
m_menu->Append( new wxMenuItem( m_menu, aId, aItem, wxEmptyString, wxITEM_NORMAL ) );
|
m_menu.Append( new wxMenuItem( &m_menu, aId, aLabel, wxEmptyString, wxITEM_NORMAL ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CONTEXT_MENU::Add( const TOOL_ACTION& aAction, int aId )
|
||||||
|
{
|
||||||
|
m_menu.Append( new wxMenuItem( &m_menu, aId,
|
||||||
|
wxString( aAction.GetDescription() + '\t' + getHotKeyDescription( aAction ) ),
|
||||||
|
wxEmptyString, wxITEM_NORMAL ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CONTEXT_MENU::Clear()
|
void CONTEXT_MENU::Clear()
|
||||||
{
|
{
|
||||||
m_titleSet = false;
|
m_titleSet = false;
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < m_menu.GetMenuItemCount(); ++i )
|
||||||
|
m_menu.Destroy( m_menu.FindItemByPosition( 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string CONTEXT_MENU::getHotKeyDescription( const TOOL_ACTION& aAction ) const
|
||||||
|
{
|
||||||
|
int hotkey = aAction.GetHotKey();
|
||||||
|
|
||||||
|
std::string description = "";
|
||||||
|
|
||||||
|
if( hotkey & MD_ModAlt )
|
||||||
|
description += "ALT+";
|
||||||
|
if( hotkey & MD_ModCtrl )
|
||||||
|
description += "CTRL+";
|
||||||
|
if( hotkey & MD_ModShift )
|
||||||
|
description += "SHIFT+";
|
||||||
|
|
||||||
|
// TODO dispatch keys such as Fx, TAB, PG_UP/DN, HOME, END, etc.
|
||||||
|
description += char( hotkey & ~MD_ModifierMask );
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CONTEXT_MENU::CMEventHandler::onEvent( wxEvent& aEvent )
|
||||||
|
{
|
||||||
|
TOOL_EVENT evt;
|
||||||
|
wxEventType type = aEvent.GetEventType();
|
||||||
|
|
||||||
|
if( type == wxEVT_MENU_HIGHLIGHT )
|
||||||
|
evt = TOOL_EVENT( TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
||||||
|
else if( type == wxEVT_COMMAND_MENU_SELECTED )
|
||||||
|
evt = TOOL_EVENT( TC_Command, TA_ContextMenuChoice, aEvent.GetId() );
|
||||||
|
|
||||||
|
if( m_menu->m_tool )
|
||||||
|
m_menu->m_tool->GetManager()->ProcessEvent( evt );
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/range/adaptor/map.hpp>
|
#include <boost/range/adaptor/map.hpp>
|
||||||
|
|
||||||
|
@ -380,14 +381,15 @@ bool TOOL_MANAGER::ProcessEvent( TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) )
|
if( st->contextMenuTrigger == CMENU_BUTTON && !aEvent.IsClick( MB_Right ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
st->pendingWait = true;
|
st->pendingWait = true;
|
||||||
st->waitEvents = TOOL_EVENT( TC_Any, TA_Any );
|
st->waitEvents = TOOL_EVENT( TC_Any, TA_Any );
|
||||||
|
|
||||||
if( st->contextMenuTrigger == CMENU_NOW )
|
if( st->contextMenuTrigger == CMENU_NOW )
|
||||||
st->contextMenuTrigger = CMENU_OFF;
|
st->contextMenuTrigger = CMENU_OFF;
|
||||||
|
|
||||||
GetEditFrame()->PopupMenu( st->contextMenu->GetMenu() );
|
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *st->contextMenu ) );
|
||||||
|
GetEditFrame()->PopupMenu( menu->GetMenu() );
|
||||||
|
|
||||||
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
|
TOOL_EVENT evt( TC_Command, TA_ContextMenuChoice );
|
||||||
dispatchInternal( evt );
|
dispatchInternal( evt );
|
||||||
|
|
|
@ -25,7 +25,8 @@
|
||||||
#ifndef __CONTEXT_MENU_H
|
#ifndef __CONTEXT_MENU_H
|
||||||
#define __CONTEXT_MENU_H
|
#define __CONTEXT_MENU_H
|
||||||
|
|
||||||
#include <wx/string.h>
|
#include <wx/menu.h>
|
||||||
|
#include <tool/tool_action.h>
|
||||||
|
|
||||||
class wxMenu;
|
class wxMenu;
|
||||||
class TOOL_INTERACTIVE;
|
class TOOL_INTERACTIVE;
|
||||||
|
@ -41,23 +42,29 @@ class CONTEXT_MENU
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CONTEXT_MENU();
|
CONTEXT_MENU();
|
||||||
~CONTEXT_MENU();
|
CONTEXT_MENU( const CONTEXT_MENU& aMenu );
|
||||||
|
|
||||||
void SetTitle( const wxString& aTitle );
|
void SetTitle( const wxString& aTitle );
|
||||||
void Add( const wxString& aItem, int aId );
|
void Add( const wxString& aLabel, int aId );
|
||||||
|
void Add( const TOOL_ACTION& aAction, int aId = -1 );
|
||||||
// fixme: unimplemented
|
|
||||||
// void Add ( const TOOL_ACTION& aAction, int aId = -1 );
|
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
wxMenu* GetMenu() const
|
wxMenu* GetMenu() const
|
||||||
{
|
{
|
||||||
return m_menu;
|
return const_cast<wxMenu*>( &m_menu );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CMEventHandler;
|
class CMEventHandler : public wxEvtHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMEventHandler( CONTEXT_MENU* aMenu ) : m_menu( aMenu ) {};
|
||||||
|
|
||||||
|
void onEvent( wxEvent& aEvent );
|
||||||
|
|
||||||
|
private:
|
||||||
|
CONTEXT_MENU* m_menu;
|
||||||
|
};
|
||||||
|
|
||||||
friend class TOOL_INTERACTIVE;
|
friend class TOOL_INTERACTIVE;
|
||||||
|
|
||||||
|
@ -66,10 +73,19 @@ private:
|
||||||
m_tool = aTool;
|
m_tool = aTool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hot key in the string format accepted by wxMenu.
|
||||||
|
*
|
||||||
|
* @param aAction is the action with hot key to be converted.
|
||||||
|
* @return Hot key in the string format compatible with wxMenu.
|
||||||
|
*/
|
||||||
|
std::string getHotKeyDescription( const TOOL_ACTION& aAction ) const;
|
||||||
|
|
||||||
|
/// Flag indicating that the menu title was set up
|
||||||
bool m_titleSet;
|
bool m_titleSet;
|
||||||
|
|
||||||
wxMenu* m_menu;
|
wxMenu m_menu;
|
||||||
CMEventHandler* m_handler;
|
CMEventHandler m_handler;
|
||||||
TOOL_INTERACTIVE* m_tool;
|
TOOL_INTERACTIVE* m_tool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#define __TOOL_ACTION_H
|
#define __TOOL_ACTION_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wx/wx.h>
|
#include <cassert>
|
||||||
|
|
||||||
#include <tool/tool_base.h>
|
#include <tool/tool_base.h>
|
||||||
#include <tool/action_manager.h>
|
#include <tool/action_manager.h>
|
||||||
|
@ -38,8 +38,9 @@
|
||||||
class TOOL_ACTION
|
class TOOL_ACTION
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TOOL_ACTION( const std::string& aName, TOOL_ActionScope aScope = AS_CONTEXT, int aDefaultHotKey = 0,
|
TOOL_ACTION( const std::string& aName, TOOL_ActionScope aScope = AS_CONTEXT,
|
||||||
const wxString& aMenuItem = wxT( "" ), const wxString& aMenuDesc = wxT( "" ) ) :
|
int aDefaultHotKey = 0, const std::string& aMenuItem = std::string( "" ),
|
||||||
|
const std::string& aMenuDesc = std::string( "" ) ) :
|
||||||
m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ),
|
m_name( aName ), m_scope( aScope ), m_defaultHotKey( aDefaultHotKey ),
|
||||||
m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
|
m_currentHotKey( aDefaultHotKey ), m_menuItem( aMenuItem ),
|
||||||
m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL )
|
m_menuDescription( aMenuDesc ), m_id( -1 ), m_actionMgr( NULL )
|
||||||
|
@ -86,6 +87,15 @@ public:
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetHotKey()
|
||||||
|
* Returns the associated hot key.
|
||||||
|
*/
|
||||||
|
int GetHotKey() const
|
||||||
|
{
|
||||||
|
return m_currentHotKey;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function ChangeHotKey()
|
* Function ChangeHotKey()
|
||||||
* Assigns a new hot key.
|
* Assigns a new hot key.
|
||||||
|
@ -94,8 +104,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void ChangeHotKey( int aNewHotKey )
|
void ChangeHotKey( int aNewHotKey )
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
|
assert( false );
|
||||||
// I mean it has to be changed in the ACTION_MANAGER, or change the implementation
|
// hotkey has to be changed in the ACTION_MANAGER, or change the implementation
|
||||||
m_currentHotKey = aNewHotKey;
|
m_currentHotKey = aNewHotKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +115,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void RestoreHotKey()
|
void RestoreHotKey()
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( false, wxT( "It is not fully implemented yet") );
|
assert( false );
|
||||||
// I mean it has to be changed in the ACTION_MANAGER, or change the implementation
|
// hotkey has to be changed in the ACTION_MANAGER, or change the implementation
|
||||||
m_currentHotKey = m_defaultHotKey;
|
m_currentHotKey = m_defaultHotKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +144,26 @@ public:
|
||||||
return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
|
return TOOL_EVENT( TC_Command, TA_Action, m_name, m_scope );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& GetMenuItem() const
|
||||||
|
{
|
||||||
|
return m_menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMenuItem( const std::string& aItem )
|
||||||
|
{
|
||||||
|
m_menuItem = aItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& GetDescription() const
|
||||||
|
{
|
||||||
|
return m_menuDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDescription( const std::string& aDescription )
|
||||||
|
{
|
||||||
|
m_menuDescription = aDescription;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ACTION_MANAGER;
|
friend class ACTION_MANAGER;
|
||||||
|
|
||||||
|
@ -162,10 +192,10 @@ private:
|
||||||
int m_currentHotKey;
|
int m_currentHotKey;
|
||||||
|
|
||||||
/// Menu entry text
|
/// Menu entry text
|
||||||
wxString m_menuItem;
|
std::string m_menuItem;
|
||||||
|
|
||||||
/// Pop-up help
|
/// Pop-up help
|
||||||
wxString m_menuDescription;
|
std::string m_menuDescription;
|
||||||
|
|
||||||
// Icon for menu entry
|
// Icon for menu entry
|
||||||
//KiBitmap m_bitmap;
|
//KiBitmap m_bitmap;
|
||||||
|
@ -182,4 +212,5 @@ private:
|
||||||
/// Originating UI object
|
/// Originating UI object
|
||||||
// wxWindow* m_uiOrigin;
|
// wxWindow* m_uiOrigin;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue