Fixed the issue of creating and event handling in context menus (GAL).

When creating a copy of CONTEXT_MENU, always a CONTEXT_MENU instance was
constructed, whereas an inherited type should be used. Solved with
CONTEXT_MENU::create() that has to be overridden in inheriting classes.

Event & update handlers are now virtual functions, instead of setting
the handlers with Set{Event,Update}Handler().
This commit is contained in:
Maciej Suminski 2017-01-20 18:33:11 +01:00
parent d7ed3ede72
commit 682da70a86
14 changed files with 201 additions and 177 deletions

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -30,44 +30,26 @@
#include <functional>
using namespace std::placeholders;
#include <cassert>
CONTEXT_MENU::CONTEXT_MENU() :
m_titleSet( false ), m_selected( -1 ), m_tool( NULL ), m_parent( NULL ), m_icon( NULL ),
m_menu_handler( CONTEXT_MENU::menuHandlerStub ),
m_update_handler( CONTEXT_MENU::updateHandlerStub )
m_titleSet( false ), m_selected( -1 ), m_tool( nullptr ), m_parent( nullptr ), m_icon( nullptr )
{
setupEvents();
}
CONTEXT_MENU::CONTEXT_MENU( const CONTEXT_MENU& aMenu )
{
copyFrom( aMenu );
setupEvents();
}
CONTEXT_MENU::~CONTEXT_MENU()
{
// Set parent to NULL to prevent submenus from unregistering from a notexisting object
for( std::list<CONTEXT_MENU*>::iterator it = m_submenus.begin(); it != m_submenus.end(); ++it )
(*it)->m_parent = NULL;
//for( std::list<CONTEXT_MENU*>::iterator it = m_submenus.begin(); it != m_submenus.end(); ++it )
for( auto menu : m_submenus )
menu->m_parent = nullptr;
if( m_parent )
m_parent->m_submenus.remove( this );
}
CONTEXT_MENU& CONTEXT_MENU::operator=( const CONTEXT_MENU& aMenu )
{
Clear();
copyFrom( aMenu );
return *this;
}
void CONTEXT_MENU::setupEvents()
{
Connect( wxEVT_MENU_HIGHLIGHT, wxMenuEventHandler( CONTEXT_MENU::onMenuEvent ), NULL, this );
@ -124,14 +106,15 @@ wxMenuItem* CONTEXT_MENU::Add( const TOOL_ACTION& aAction )
m_toolActions[getMenuId( aAction )] = &aAction;
return Append( item );
wxMenuItem* i = Append( item );
return i;
}
std::list<wxMenuItem*> CONTEXT_MENU::Add( CONTEXT_MENU* aMenu, const wxString& aLabel, bool aExpand )
{
std::list<wxMenuItem*> items;
CONTEXT_MENU* menuCopy = new CONTEXT_MENU( *aMenu );
CONTEXT_MENU* menuCopy = aMenu->Clone();
m_submenus.push_back( menuCopy );
menuCopy->m_parent = this;
@ -173,7 +156,7 @@ void CONTEXT_MENU::Clear()
m_submenus.clear();
m_parent = NULL;
assert( GetMenuItemCount() == 0 );
wxASSERT( GetMenuItemCount() == 0 );
}
@ -181,11 +164,11 @@ void CONTEXT_MENU::UpdateAll()
{
try
{
m_update_handler();
update();
}
catch( std::exception& e )
{
std::cerr << "CONTEXT_MENU error running update handler: " << e.what() << std::endl;
wxLogDebug( wxString::Format( "CONTEXT_MENU update handler exception: %s", e.what() ) );
}
if( m_tool )
@ -198,15 +181,34 @@ void CONTEXT_MENU::UpdateAll()
void CONTEXT_MENU::SetTool( TOOL_INTERACTIVE* aTool )
{
m_tool = aTool;
runOnSubmenus( std::bind( &CONTEXT_MENU::SetTool, _1, aTool ) );
}
CONTEXT_MENU* CONTEXT_MENU::Clone() const
{
CONTEXT_MENU* clone = create();
clone->Clear();
clone->copyFrom( *this );
return clone;
}
CONTEXT_MENU* CONTEXT_MENU::create() const
{
CONTEXT_MENU* menu = new CONTEXT_MENU();
wxASSERT_MSG( typeid( *this ) == typeid( *menu ),
wxString::Format( "You need to override create() method for class %s", typeid(*this).name() ) );
return menu;
}
TOOL_MANAGER* CONTEXT_MENU::getToolManager()
{
assert( m_tool );
return m_tool->GetManager();
wxASSERT( m_tool );
return m_tool ? m_tool->GetManager() : nullptr;
}
@ -269,23 +271,22 @@ void CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent )
}
else
{
runEventHandlers( aEvent, evt );
// Under Linux, every submenu can have a separate event handler, under
// Windows all submenus are handled by the main menu.
#ifdef __WINDOWS__
if( !evt )
{
// Try to find the submenu which holds the selected item
wxMenu* menu = NULL;
wxMenu* menu = nullptr;
FindItem( m_selected, &menu );
if( menu && menu != this )
{
menu->ProcessEvent( aEvent );
return;
CONTEXT_MENU* cxmenu = static_cast<CONTEXT_MENU*>( menu );
evt = cxmenu->eventHandler( aEvent );
}
}
#else
if( !evt )
runEventHandlers( aEvent, evt );
#endif
// Handling non-action menu entries (e.g. items in clarification list)
@ -294,17 +295,20 @@ void CONTEXT_MENU::onMenuEvent( wxMenuEvent& aEvent )
}
}
assert( m_tool ); // without tool & tool manager we cannot handle events
wxASSERT( m_tool ); // without tool & tool manager we cannot handle events
// forward the action/update event to the TOOL_MANAGER
if( evt && m_tool )
{
//aEvent.StopPropagation();
m_tool->GetManager()->ProcessEvent( *evt );
}
}
void CONTEXT_MENU::runEventHandlers( const wxMenuEvent& aMenuEvent, OPT_TOOL_EVENT& aToolEvent )
{
aToolEvent = m_menu_handler( aMenuEvent );
aToolEvent = eventHandler( aMenuEvent );
if( !aToolEvent )
runOnSubmenus( std::bind( &CONTEXT_MENU::runEventHandlers, _1, aMenuEvent, aToolEvent ) );
@ -319,7 +323,25 @@ void CONTEXT_MENU::runOnSubmenus( std::function<void(CONTEXT_MENU*)> aFunction )
}
catch( std::exception& e )
{
std::cerr << "CONTEXT_MENU runOnSubmenus error: " << e.what() << std::endl;
wxLogDebug( wxString::Format( "CONTEXT_MENU runOnSubmenus exception: %s", e.what() ) );
}
}
void CONTEXT_MENU::copyFrom( const CONTEXT_MENU& aMenu )
{
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_parent = NULL; // aMenu.m_parent;
// Copy all the menu entries
for( int i = 0; i < (int) aMenu.GetMenuItemCount(); ++i )
{
wxMenuItem* item = aMenu.FindItemByPosition( i );
appendCopy( item );
}
}
@ -334,59 +356,25 @@ wxMenuItem* CONTEXT_MENU::appendCopy( const wxMenuItem* aSource )
if( aSource->IsSubMenu() )
{
#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 = dynamic_cast<CONTEXT_MENU*>( aSource->GetSubMenu() );
wxASSERT_MSG( menu, "Submenus are expected to be a CONTEXT_MENU" );
CONTEXT_MENU* menu = new CONTEXT_MENU( static_cast<const CONTEXT_MENU&>( *aSource->GetSubMenu() ) );
newItem->SetSubMenu( menu );
Append( newItem );
m_submenus.push_back( menu );
menu->m_parent = this;
if( menu )
{
CONTEXT_MENU* menuCopy = menu->Clone();
newItem->SetSubMenu( menuCopy );
m_submenus.push_back( menuCopy );
menuCopy->m_parent = this; // TODO remove m_parent
}
}
else
{
Append( newItem );
newItem->SetKind( aSource->GetKind() );
newItem->SetHelp( aSource->GetHelp() );
newItem->Enable( aSource->IsEnabled() );
if( aSource->IsCheckable() )
newItem->Check( aSource->IsChecked() );
}
// wxMenuItem has to be added before enabling/disabling or checking
Append( newItem );
if( aSource->IsCheckable() )
newItem->Check( aSource->IsChecked() );
newItem->Enable( aSource->IsEnabled() );
return newItem;
}
void CONTEXT_MENU::copyFrom( const CONTEXT_MENU& aMenu )
{
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_parent = NULL; // aMenu.m_parent;
m_menu_handler = aMenu.m_menu_handler;
m_update_handler = aMenu.m_update_handler;
// Copy all the menu entries
for( int i = 0; i < (int) aMenu.GetMenuItemCount(); ++i )
{
wxMenuItem* item = aMenu.FindItemByPosition( i );
appendCopy( item );
}
}
OPT_TOOL_EVENT CONTEXT_MENU::menuHandlerStub( const wxMenuEvent& )
{
return boost::none;
}
void CONTEXT_MENU::updateHandlerStub()
{
}

View File

@ -28,7 +28,6 @@
#include <stack>
#include <algorithm>
#include <boost/scoped_ptr.hpp>
#include <boost/optional.hpp>
#include <boost/range/adaptor/map.hpp>
@ -631,10 +630,11 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
VECTOR2D cursorPos = m_viewControls->GetCursorPosition();
m_viewControls->ForceCursorPosition( true, m_viewControls->GetCursorPosition() );
// Run update handlers
m->UpdateAll();
// Display a copy of menu
std::unique_ptr<CONTEXT_MENU> menu( m->Clone() );
boost::scoped_ptr<CONTEXT_MENU> menu( new CONTEXT_MENU( *m ) );
// Run update handlers on the created copy
menu->UpdateAll();
GetEditFrame()->PopupMenu( menu.get() );
// If nothing was chosen from the context menu, we must notify the tool as well
@ -645,12 +645,12 @@ void TOOL_MANAGER::dispatchContextMenu( const TOOL_EVENT& aEvent )
dispatchInternal( evt );
}
// Notify the tools that menu has been closed
TOOL_EVENT evt( TC_COMMAND, TA_CONTEXT_MENU_CLOSED );
evt.SetParameter( m );
dispatchInternal( evt );
m_viewControls->ForceCursorPosition( forcedCursor, cursorPos );
break;
}
}

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2013-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -47,12 +47,10 @@ public:
///> Default constructor
CONTEXT_MENU();
///> Copy constructor
CONTEXT_MENU( const CONTEXT_MENU& aMenu );
virtual ~CONTEXT_MENU();
CONTEXT_MENU& operator=( const CONTEXT_MENU& aMenu );
CONTEXT_MENU( const CONTEXT_MENU& aMenu ) = delete;
CONTEXT_MENU& operator=( const CONTEXT_MENU& aMenu ) = delete;
/**
* Function SetTitle()
@ -125,28 +123,6 @@ public:
*/
void UpdateAll();
// Helper typedefs
typedef std::function<OPT_TOOL_EVENT(const wxMenuEvent&)> MENU_HANDLER;
typedef std::function<void()> UPDATE_HANDLER;
/**
* Function SetMenuHandler()
* Sets the menu event handler to another function.
*/
inline void SetMenuHandler( MENU_HANDLER aMenuHandler )
{
m_menu_handler = aMenuHandler;
}
/**
* Function SetUpdateHandler()
* Sets the update handler to a different function.
*/
inline void SetUpdateHandler( UPDATE_HANDLER aUpdateHandler )
{
m_update_handler = aUpdateHandler;
}
/**
* Function SetTool()
* Sets a tool that is the creator of the menu.
@ -154,7 +130,15 @@ public:
*/
void SetTool( TOOL_INTERACTIVE* aTool );
/**
* Creates a deep, recursive copy of this CONTEXT_MENU.
*/
CONTEXT_MENU* Clone() const;
protected:
///> Returns an instance of this class. It has to be overridden in inheriting classes.
virtual CONTEXT_MENU* create() const;
///> Returns an instance of TOOL_MANAGER class.
TOOL_MANAGER* getToolManager();
@ -164,20 +148,36 @@ protected:
return aAction.GetId() + ACTION_ID;
}
private:
// Empty stubs used by the default constructor
static OPT_TOOL_EVENT menuHandlerStub(const wxMenuEvent& );
static void updateHandlerStub();
/**
* Update menu state stub. It is called before a menu is shown, in order to update its state.
* Here you can tick current settings, enable/disable entries, etc.
*/
virtual void update()
{
}
/**
* Event handler stub. It should be used if you want to generate a TOOL_EVENT from a wxMenuEvent.
* It will be called when a menu entry is clicked.
*/
virtual OPT_TOOL_EVENT eventHandler( const wxMenuEvent& )
{
return OPT_TOOL_EVENT();
}
/**
* Copies another menus data to this instance. Old entries are preserved, and ones form aMenu
* are copied.
*/
void copyFrom( const CONTEXT_MENU& aMenu );
private:
/**
* Function appendCopy
* Appends a copy of wxMenuItem.
*/
wxMenuItem* appendCopy( const wxMenuItem* aSource );
///> Common part of copy constructor and assignment operator.
void copyFrom( const CONTEXT_MENU& aMenu );
///> Initializes handlers for events.
void setupEvents();
@ -204,7 +204,7 @@ private:
TOOL_INTERACTIVE* m_tool;
///> Menu items with ID higher than that are considered TOOL_ACTIONs
static const int ACTION_ID = 30000;
static const int ACTION_ID = 2000;
///> Associates tool actions with menu item IDs. Non-owning.
std::map<int, const TOOL_ACTION*> m_toolActions;
@ -218,12 +218,6 @@ private:
///> Optional icon
const BITMAP_OPAQUE* m_icon;
///> Optional callback to translate wxMenuEvents to TOOL_EVENTs.
MENU_HANDLER m_menu_handler;
///> Optional callback to update the menu state before it is displayed.
UPDATE_HANDLER m_update_handler;
friend class TOOL_INTERACTIVE;
};

View File

@ -33,6 +33,7 @@
#if BOOST_VERSION < 106100
#include <boost/context/fcontext.hpp>
#include <memory>
#else
#include <boost/context/execution_context.hpp>
#include <boost/context/protected_fixedsize_stack.hpp>

View File

@ -73,10 +73,10 @@ LENGTH_TUNER_TOOL::LENGTH_TUNER_TOOL() :
}
class TUNER_TOOL_MENU: public CONTEXT_MENU
class TUNER_TOOL_MENU : public CONTEXT_MENU
{
public:
TUNER_TOOL_MENU( BOARD* aBoard )
TUNER_TOOL_MENU()
{
SetTitle( _( "Length Tuner" ) );
@ -91,6 +91,12 @@ public:
Add( ACT_AmplDecrease );
Add( ACT_Settings );
}
private:
CONTEXT_MENU* create() const override
{
return new TUNER_TOOL_MENU();
}
};
@ -242,7 +248,7 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
m_ctls->ShowCursor( true );
m_frame->UndoRedoBlock( true );
std::unique_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU( m_board ) );
std::unique_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU );
SetContextMenu( ctxMenu.get() );
// Main loop: keep receiving events

View File

@ -117,19 +117,21 @@ ROUTER_TOOL::ROUTER_TOOL() :
}
class CONTEXT_TRACK_WIDTH_MENU: public CONTEXT_TRACK_VIA_SIZE_MENU
class TRACK_WIDTH_MENU: public TRACK_VIA_SIZE_MENU
{
public:
CONTEXT_TRACK_WIDTH_MENU()
: CONTEXT_TRACK_VIA_SIZE_MENU( true, true ), m_board( NULL )
TRACK_WIDTH_MENU( const BOARD* aBoard )
: TRACK_VIA_SIZE_MENU( true, true )
{
SetMenuHandler( std::bind( &CONTEXT_TRACK_WIDTH_MENU::EventHandler, this, _1 ) );
SetBoard( aBoard );
}
void SetBoard( BOARD* aBoard )
void SetBoard( const BOARD* aBoard )
{
m_board = aBoard;
Clear();
Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Custom size" ),
wxEmptyString, wxITEM_CHECK );
@ -145,7 +147,13 @@ public:
AppendSizes( aBoard );
}
OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent )
protected:
CONTEXT_MENU* create() const override
{
return new TRACK_WIDTH_MENU( m_board );
}
OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override
{
BOARD_DESIGN_SETTINGS &bds = m_board->GetDesignSettings();
int id = aEvent.GetId();
@ -198,20 +206,20 @@ public:
bds.UseCustomTrackViaSize( useCustomTrackViaSize );
}
return OPT_TOOL_EVENT( COMMON_ACTIONS::trackViaSizeChanged.MakeEvent() );
}
private:
BOARD* m_board;
const BOARD* m_board;
};
class ROUTER_TOOL_MENU: public CONTEXT_MENU
class ROUTER_TOOL_MENU : public CONTEXT_MENU
{
public:
ROUTER_TOOL_MENU( BOARD* aBoard, PCB_EDIT_FRAME& frame, PNS::ROUTER_MODE aMode ) :
m_zoomMenu( &frame ), m_gridMenu( &frame )
ROUTER_TOOL_MENU( const BOARD* aBoard, PCB_EDIT_FRAME& aFrame, PNS::ROUTER_MODE aMode ) :
m_board( aBoard ), m_frame( aFrame ), m_mode( aMode ),
m_widthMenu( aBoard ), m_zoomMenu( &aFrame ), m_gridMenu( &aFrame )
{
SetTitle( _( "Interactive Router" ) );
Add( ACT_NewTrack );
@ -242,7 +250,15 @@ public:
}
private:
CONTEXT_TRACK_WIDTH_MENU m_widthMenu;
CONTEXT_MENU* create() const override
{
return new ROUTER_TOOL_MENU( m_board, m_frame, m_mode );
}
const BOARD* m_board;
PCB_EDIT_FRAME& m_frame;
PNS::ROUTER_MODE m_mode;
TRACK_WIDTH_MENU m_widthMenu;
ZOOM_MENU m_zoomMenu;
GRID_MENU m_gridMenu;
};
@ -253,6 +269,7 @@ ROUTER_TOOL::~ROUTER_TOOL()
m_savedSettings.Save( GetSettings() );
}
bool ROUTER_TOOL::Init()
{
m_savedSettings.Load( GetSettings() );
@ -724,9 +741,6 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
m_savedSettings = m_router->Settings();
m_savedSizes = m_router->Sizes();
// Disable the context menu before it is destroyed
SetContextMenu( NULL, CMENU_OFF );
return 0;
}

View File

@ -72,7 +72,6 @@ CONTEXT_MENU* CONDITIONAL_MENU::Generate( SELECTION& aSelection )
break;
case ENTRY::MENU:
it->Menu()->UpdateAll();
m_menu->Add( it->Menu(), it->Label(), it->Expand() );
break;

View File

@ -37,8 +37,6 @@ GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
BASE_SCREEN* screen = aParent->GetScreen();
SetIcon( grid_select_xpm );
SetMenuHandler( std::bind( &GRID_MENU::EventHandler, this, _1 ) );
SetUpdateHandler( std::bind( &GRID_MENU::Update, this ) );
wxArrayString gridsList;
screen->BuildGridsChoiceList( gridsList, g_UserUnit != INCHES );
@ -51,7 +49,7 @@ GRID_MENU::GRID_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
}
OPT_TOOL_EVENT GRID_MENU::EventHandler( const wxMenuEvent& aEvent )
OPT_TOOL_EVENT GRID_MENU::eventHandler( const wxMenuEvent& aEvent )
{
OPT_TOOL_EVENT event( COMMON_ACTIONS::gridPreset.MakeEvent() );
long idx = aEvent.GetId() - ID_POPUP_GRID_SELECT - 1;
@ -61,10 +59,11 @@ OPT_TOOL_EVENT GRID_MENU::EventHandler( const wxMenuEvent& aEvent )
}
void GRID_MENU::Update()
void GRID_MENU::update()
{
for( unsigned int i = 0; i < GetMenuItemCount(); ++i )
Check( ID_POPUP_GRID_SELECT + 1 + i, false );
// Check the current grid size
Check( m_parent->GetScreen()->GetGridCmdId(), true );
}

View File

@ -34,10 +34,15 @@ class GRID_MENU : public CONTEXT_MENU
public:
GRID_MENU( EDA_DRAW_FRAME* aParent );
OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent );
void Update();
private:
CONTEXT_MENU* create() const override
{
return new GRID_MENU( m_parent );
}
OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override;
void update() override;
EDA_DRAW_FRAME* m_parent;
};

View File

@ -60,7 +60,6 @@ public:
ZONE_CONTEXT_MENU()
{
SetIcon( add_zone_xpm );
SetUpdateHandler( std::bind( &ZONE_CONTEXT_MENU::update, this ) );
Add( COMMON_ACTIONS::zoneFill );
Add( COMMON_ACTIONS::zoneFillAll );
Add( COMMON_ACTIONS::zoneUnfill );
@ -68,8 +67,14 @@ public:
Add( COMMON_ACTIONS::zoneMerge );
}
protected:
CONTEXT_MENU* create() const override
{
return new ZONE_CONTEXT_MENU();
}
private:
void update()
void update() override
{
SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
@ -100,6 +105,11 @@ public:
Add( COMMON_ACTIONS::unlock );
Add( COMMON_ACTIONS::toggleLock );
}
CONTEXT_MENU* create() const override
{
return new LOCK_CONTEXT_MENU();
}
};

View File

@ -24,14 +24,14 @@
#include <class_board.h>
#include <pcbnew_id.h>
CONTEXT_TRACK_VIA_SIZE_MENU::CONTEXT_TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes ) :
TRACK_VIA_SIZE_MENU::TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes ) :
m_tracks( aTrackSizes ), m_vias( aViaSizes )
{
SetIcon( width_track_via_xpm );
}
void CONTEXT_TRACK_VIA_SIZE_MENU::AppendSizes( const BOARD* aBoard )
void TRACK_VIA_SIZE_MENU::AppendSizes( const BOARD* aBoard )
{
wxString msg;

View File

@ -27,7 +27,7 @@ class BOARD;
* @brief Context menu that displays track and/or via sizes basing on the board design settings
* of a BOARD object.
*/
class CONTEXT_TRACK_VIA_SIZE_MENU: public CONTEXT_MENU
class TRACK_VIA_SIZE_MENU : public CONTEXT_MENU
{
public:
/**
@ -35,9 +35,9 @@ public:
* @param aTrackSizes decides if the context menu should contain track sizes.
* @param aTrackSizes decides if the context menu should contain via sizes.
*/
CONTEXT_TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes );
TRACK_VIA_SIZE_MENU( bool aTrackSizes, bool aViaSizes );
virtual ~CONTEXT_TRACK_VIA_SIZE_MENU() {}
virtual ~TRACK_VIA_SIZE_MENU() {}
/**
* Function AppendSizes()
@ -46,6 +46,11 @@ public:
*/
virtual void AppendSizes( const BOARD* aBoard );
virtual CONTEXT_MENU* create() const override
{
return new TRACK_VIA_SIZE_MENU( m_tracks, m_vias );
}
protected:
///> Whether the generated menu should contain track sizes.
bool m_tracks;

View File

@ -34,10 +34,7 @@ using namespace std::placeholders;
ZOOM_MENU::ZOOM_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
{
BASE_SCREEN* screen = aParent->GetScreen();
SetIcon( zoom_selection_xpm );
SetMenuHandler( std::bind( &ZOOM_MENU::EventHandler, this, _1 ) );
SetUpdateHandler( std::bind( &ZOOM_MENU::Update, this ) );
//int zoom = screen->GetZoom();
int maxZoomIds = std::min( ID_POPUP_ZOOM_LEVEL_END - ID_POPUP_ZOOM_LEVEL_START,
@ -52,7 +49,7 @@ ZOOM_MENU::ZOOM_MENU( EDA_DRAW_FRAME* aParent ) : m_parent( aParent )
}
OPT_TOOL_EVENT ZOOM_MENU::EventHandler( const wxMenuEvent& aEvent )
OPT_TOOL_EVENT ZOOM_MENU::eventHandler( const wxMenuEvent& aEvent )
{
OPT_TOOL_EVENT event( COMMON_ACTIONS::zoomPreset.MakeEvent() );
long idx = aEvent.GetId() - ID_POPUP_ZOOM_LEVEL_START;
@ -62,11 +59,12 @@ OPT_TOOL_EVENT ZOOM_MENU::EventHandler( const wxMenuEvent& aEvent )
}
void ZOOM_MENU::Update()
void ZOOM_MENU::update()
{
double zoom = m_parent->GetScreen()->GetZoom();
const std::vector<double>& zoomList = m_parent->GetScreen()->m_ZoomList;
// Check the current zoom
for( unsigned int i = 0; i < GetMenuItemCount(); ++i )
Check( ID_POPUP_ZOOM_LEVEL_START + i, std::fabs( zoomList[i] - zoom ) < 1e-6 );
}

View File

@ -35,8 +35,13 @@ public:
ZOOM_MENU( EDA_DRAW_FRAME* aParent );
private:
OPT_TOOL_EVENT EventHandler( const wxMenuEvent& aEvent );
void Update();
CONTEXT_MENU* create() const override
{
return new ZOOM_MENU( m_parent );
}
OPT_TOOL_EVENT eventHandler( const wxMenuEvent& aEvent ) override;
void update() override;
EDA_DRAW_FRAME* m_parent;
};