Implement a framework to handle wxUpdateUIEvents for tool actions

This allows for the tool framework to keep track of a universal
set of conditions for the UI state (enabled/checked/shown) for
controls of actions. It removes the need for the main menubar
menus to be CONDITIONAL_MENUs and be rebuilt on each open,
and instead makes the updates of the check and enabling of
items handled in the native wxWidgets way.

This commit switchs the 3d viewer and kicad project manager window
over to this system.
This commit is contained in:
Ian McInerney 2020-07-27 23:42:23 +01:00
parent d19ff3e595
commit 72a1c71e07
27 changed files with 851 additions and 452 deletions

View File

@ -45,273 +45,192 @@ void EDA_3D_VIEWER::CreateMenuBar()
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* fileMenu = new ACTION_MENU( false, tool );
fileMenu->AddItem( ID_MENU_SCREENCOPY_PNG, _( "Export Current View as PNG..." ), "",
export_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->Add( _( "Export Current View as PNG..." ),
"",
ID_MENU_SCREENCOPY_PNG,
export_xpm );
fileMenu->AddItem( ID_MENU_SCREENCOPY_JPEG, _( "Export Current View as JPEG..." ), "",
export_xpm, SELECTION_CONDITIONS::ShowAlways );
fileMenu->Add( _( "Export Current View as JPEG..." ),
"",
ID_MENU_SCREENCOPY_JPEG,
export_xpm );
fileMenu->AddSeparator();
fileMenu->AppendSeparator();
fileMenu->AddClose( _( "3D Viewer" ) );
fileMenu->Resolve();
//-- Edit menu -------------------------------------------------------
// Avoid to translate hotkey modifiers like Ctrl and Shift.
// The translated modifiers do not always work
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* editMenu = new ACTION_MENU( false, tool );
editMenu->AddItem( ID_TOOL_SCREENCOPY_TOCLIBBOARD, _( "Copy 3D Image" ), "",
copy_xpm, SELECTION_CONDITIONS::ShowAlways );
editMenu->Add( _( "Copy 3D Image" ),
"",
ID_TOOL_SCREENCOPY_TOCLIBBOARD,
copy_xpm );
editMenu->Resolve();
//-- View menu -------------------------------------------------------
//
CONDITIONAL_MENU* viewMenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* viewMenu = new ACTION_MENU( false, tool );
viewMenu->AddItem( ACTIONS::zoomIn, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( ACTIONS::zoomOut, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( ACTIONS::zoomFitScreen, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( ACTIONS::zoomRedraw, SELECTION_CONDITIONS::ShowAlways );
viewMenu->Add( ACTIONS::zoomIn );
viewMenu->Add( ACTIONS::zoomOut );
viewMenu->Add( ACTIONS::zoomFitScreen );
viewMenu->Add( ACTIONS::zoomRedraw );
viewMenu->AddSeparator();
viewMenu->AddItem( EDA_3D_ACTIONS::rotateXCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::rotateXCCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::rotateXCW );
viewMenu->Add( EDA_3D_ACTIONS::rotateXCCW );
viewMenu->AddSeparator();
viewMenu->AddItem( EDA_3D_ACTIONS::rotateYCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::rotateYCCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::rotateYCW );
viewMenu->Add( EDA_3D_ACTIONS::rotateYCCW );
viewMenu->AddSeparator();
viewMenu->AddItem( EDA_3D_ACTIONS::rotateZCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::rotateZCCW, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::rotateZCW );
viewMenu->Add( EDA_3D_ACTIONS::rotateZCCW );
viewMenu->AddSeparator();
viewMenu->AddItem( EDA_3D_ACTIONS::moveLeft, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::moveRight, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::moveUp, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( EDA_3D_ACTIONS::moveDown, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AppendSeparator();
viewMenu->Add( EDA_3D_ACTIONS::moveLeft );
viewMenu->Add( EDA_3D_ACTIONS::moveRight );
viewMenu->Add( EDA_3D_ACTIONS::moveUp );
viewMenu->Add( EDA_3D_ACTIONS::moveDown );
viewMenu->Resolve();
//-- Preferences menu -----------------------------------------------
//
CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* prefsMenu = new ACTION_MENU( false, tool );
//clang-format off
auto raytracingCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.RenderEngineGet() != RENDER_ENGINE::OPENGL_LEGACY;
};
prefsMenu->Add( _( "Display Options" ), "",
ID_TOOL_SET_VISIBLE_ITEMS,
read_setup_xpm );
auto NormalModeCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::NORMAL;
};
auto DiffuseModeCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::DIFFUSE_ONLY;
};
auto CADModeCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::CAD_MODE;
};
auto boundingBoxesCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_OPENGL_SHOW_MODEL_BBOX );
};
auto renderShadowsCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
};
auto proceduralTexturesCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES );
};
auto showFloorCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_BACKFLOOR );
};
auto useRefractionsCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS );
};
auto useReflectionsCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS );
};
auto antiAliasingCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING );
};
auto postProcessCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
};
auto showAxesCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GetFlag( FL_AXIS );
};
//clang-format on
prefsMenu->AddItem( ID_TOOL_SET_VISIBLE_ITEMS, _( "Display Options" ), "",
read_setup_xpm, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddCheckItem( ID_RENDER_CURRENT_VIEW, _( "Raytracing" ), "",
tools_xpm, raytracingCondition );
prefsMenu->Add( _( "Raytracing" ), "",
ID_RENDER_CURRENT_VIEW,
tools_xpm,
ACTION_MENU::CHECK );
// Render options submenu
CONDITIONAL_MENU* optsSubmenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* optsSubmenu = new ACTION_MENU( false, tool );
optsSubmenu->SetTitle( _( "Render Options" ) );
optsSubmenu->SetIcon( options_3drender_xpm );
// Material properties submenu
CONDITIONAL_MENU* propsSubmenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* propsSubmenu = new ACTION_MENU( false, tool );
propsSubmenu->SetTitle( _( "Material Properties" ) );
propsSubmenu->SetIcon( color_materials_xpm );
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
_( "Use All Properties" ),
propsSubmenu->Add( _( "Use All Properties" ),
_( "Use all material properties from each 3D model file" ),
nullptr, NormalModeCondition );
ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
nullptr,
ACTION_MENU::CHECK );
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY,
_( "Use Diffuse Only" ),
propsSubmenu->Add( _( "Use Diffuse Only" ),
_( "Use only the diffuse color property from model 3D model file" ),
nullptr, DiffuseModeCondition );
ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY,
nullptr,
ACTION_MENU::CHECK );
propsSubmenu->AddCheckItem( ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
_( "CAD Color Style" ),
propsSubmenu->Add( _( "CAD Color Style" ),
_( "Use a CAD color style based on the diffuse color of the material" ),
nullptr, CADModeCondition );
ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
nullptr,
ACTION_MENU::CHECK );
optsSubmenu->AddMenu( propsSubmenu, SELECTION_CONDITIONS::ShowAlways );
optsSubmenu->Add( propsSubmenu );
optsSubmenu->AddCheckItem( EDA_3D_ACTIONS::showBoundingBoxes, boundingBoxesCondition );
optsSubmenu->Add( EDA_3D_ACTIONS::showBoundingBoxes, ACTION_MENU::CHECK );
// Raytracing submenu
CONDITIONAL_MENU* raySubmenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* raySubmenu = new ACTION_MENU( false, tool );
raySubmenu->SetTitle( _( "Raytracing Options" ) );
raySubmenu->SetIcon( tools_xpm );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::renderShadows, renderShadowsCondition );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::proceduralTextures, proceduralTexturesCondition );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::addFloor, showFloorCondition );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::showRefractions, useRefractionsCondition );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::showReflections, useReflectionsCondition );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::antiAliasing, antiAliasingCondition );
raySubmenu->Add( EDA_3D_ACTIONS::renderShadows, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::proceduralTextures, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::addFloor, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::showRefractions, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::showReflections, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::antiAliasing, ACTION_MENU::CHECK );
raySubmenu->Add( EDA_3D_ACTIONS::postProcessing, ACTION_MENU::CHECK );
raySubmenu->AddCheckItem( EDA_3D_ACTIONS::postProcessing, postProcessCondition );
optsSubmenu->Add( raySubmenu );
prefsMenu->Add( optsSubmenu );
optsSubmenu->AddMenu( raySubmenu, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddMenu( optsSubmenu, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddSeparator();
prefsMenu->AppendSeparator();
// Color submenu
CONDITIONAL_MENU* colorSubmenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* colorSubmenu = new ACTION_MENU( false, tool );
colorSubmenu->SetTitle( _( "Choose Colors" ) );
colorSubmenu->SetIcon( palette_xpm );
colorSubmenu->AddItem( ID_MENU3D_BGCOLOR_TOP, _( "Background Top Color..." ), "",
setcolor_3d_bg_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Background Top Color..." ),
ID_MENU3D_BGCOLOR_TOP,
setcolor_3d_bg_xpm );
colorSubmenu->AddItem( ID_MENU3D_BGCOLOR_BOTTOM, _( "Background Bottom Color..." ), "",
setcolor_3d_bg_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Background Bottom Color..." ),
ID_MENU3D_BGCOLOR_BOTTOM,
setcolor_3d_bg_xpm );
colorSubmenu->AddItem( ID_MENU3D_SILKSCREEN_COLOR, _( "Silkscreen Color..." ), "",
setcolor_silkscreen_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Silkscreen Color..." ),
ID_MENU3D_SILKSCREEN_COLOR,
setcolor_silkscreen_xpm );
colorSubmenu->AddItem( ID_MENU3D_SOLDERMASK_COLOR, _( "Solder Mask Color..." ), "",
setcolor_soldermask_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Solder Mask Color..." ),
ID_MENU3D_SOLDERMASK_COLOR,
setcolor_soldermask_xpm );
colorSubmenu->AddItem( ID_MENU3D_SOLDERPASTE_COLOR, _( "Solder Paste Color..." ), "",
setcolor_solderpaste_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Solder Paste Color..." ),
ID_MENU3D_SOLDERPASTE_COLOR,
setcolor_solderpaste_xpm );
colorSubmenu->AddItem( ID_MENU3D_COPPER_COLOR, _( "Copper/Surface Finish Color..." ), "",
setcolor_copper_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Copper/Surface Finish Color..." ),
ID_MENU3D_COPPER_COLOR,
setcolor_copper_xpm );
colorSubmenu->AddItem( ID_MENU3D_PCB_BODY_COLOR, _( "Board Body Color..." ), "",
setcolor_board_body_xpm, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Board Body Color..." ),
ID_MENU3D_PCB_BODY_COLOR,
setcolor_board_body_xpm );
// Only allow the stackup to be used in the PCB editor, since it isn't editable in the other frames
if( Parent()->IsType( FRAME_PCB_EDITOR ) )
{
colorSubmenu->AddItem( ID_MENU3D_STACKUP_COLORS, _( "Get colors from physical stackup" ), "",
nullptr, SELECTION_CONDITIONS::ShowAlways );
colorSubmenu->Add( _( "Get colors from physical stackup" ),
ID_MENU3D_STACKUP_COLORS,
nullptr );
}
prefsMenu->AddMenu( colorSubmenu );
prefsMenu->Add( colorSubmenu );
prefsMenu->AddCheckItem( EDA_3D_ACTIONS::showAxis, showAxesCondition );
prefsMenu->Add( EDA_3D_ACTIONS::showAxis, ACTION_MENU::CHECK );
// Grid submenu
CONDITIONAL_MENU* gridSubmenu = new CONDITIONAL_MENU( false, tool );
ACTION_MENU* gridSubmenu = new ACTION_MENU( false, tool );
gridSubmenu->SetTitle( _( "3D Grid" ) );
gridSubmenu->SetIcon( grid_xpm );
//clang-format off
auto noGridCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GridGet() == GRID3D_TYPE::NONE;
};
gridSubmenu->Add( EDA_3D_ACTIONS::noGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show10mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show2_5mmGrid, ACTION_MENU::CHECK);
gridSubmenu->Add( EDA_3D_ACTIONS::show1mmGrid, ACTION_MENU::CHECK);
auto grid10mmCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GridGet() == GRID3D_TYPE::GRID_10MM;
};
prefsMenu->Add( gridSubmenu );
auto grid5mmCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GridGet() == GRID3D_TYPE::GRID_5MM;
};
auto grid2p5mmCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GridGet() == GRID3D_TYPE::GRID_2P5MM;
};
auto grid_1mmCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.GridGet() == GRID3D_TYPE::GRID_1MM;
};
//clang-format on
gridSubmenu->AddCheckItem( EDA_3D_ACTIONS::noGrid, noGridCondition );
gridSubmenu->AddCheckItem( EDA_3D_ACTIONS::show10mmGrid, grid10mmCondition );
gridSubmenu->AddCheckItem( EDA_3D_ACTIONS::show5mmGrid, grid5mmCondition );
gridSubmenu->AddCheckItem( EDA_3D_ACTIONS::show2_5mmGrid, grid2p5mmCondition );
gridSubmenu->AddCheckItem( EDA_3D_ACTIONS::show1mmGrid, grid_1mmCondition );
prefsMenu->AddMenu( gridSubmenu, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddSeparator();
prefsMenu->AddItem( ID_MENU3D_RESET_DEFAULTS, _( "Reset to Default Settings" ), "",
tools_xpm, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AppendSeparator();
prefsMenu->Add( _( "Reset to Default Settings" ), ID_MENU3D_RESET_DEFAULTS, tools_xpm );
#ifdef __APPLE__ // Note: will get moved to Apple menu by wxWidgets
prefsMenu->AddItem( wxID_PREFERENCES,
_( "Preferences...\tCTRL+," ),
prefsMenu->Add( _( "Preferences...\tCTRL+," ),
_( "Show preferences for all open tools" ),
preference_xpm, SELECTION_CONDITIONS::ShowAlways );
wxID_PREFERENCES,
preference_xpm );
#endif
prefsMenu->Resolve();
//-- Menubar -------------------------------------------------------------
//
menuBar->Append( fileMenu, _( "&File" ) );

View File

@ -99,12 +99,3 @@ void EDA_3D_VIEWER::ReCreateMainToolbar()
m_mainToolBar->Realize();
}
void EDA_3D_VIEWER::SyncToolbars()
{
bool isOrtho = m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
m_mainToolBar->Toggle( EDA_3D_ACTIONS::toggleOrtho, isOrtho );
m_mainToolBar->Refresh();
}

View File

@ -34,6 +34,7 @@
#include "../common_ogl/cogl_att_list.h"
#include <3d_viewer/tools/3d_actions.h>
#include <3d_viewer/tools/3d_controller.h>
#include <3d_viewer/tools/3d_conditions.h>
#include <bitmaps.h>
#include <board_stackup_manager/class_board_stackup.h>
#include <board_stackup_manager/stackup_predefined_prms.h>
@ -44,6 +45,7 @@
#include <project.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <tool/action_manager.h>
#include <tool/common_control.h>
#include <tool/tool_manager.h>
#include <tool/tool_dispatcher.h>
@ -75,11 +77,6 @@ BEGIN_EVENT_TABLE( EDA_3D_VIEWER, EDA_BASE_FRAME )
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER::OnRenderEngineSelection )
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER::OnDisableRayTracing )
EVT_UPDATE_UI( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER::OnUpdateUIEngine )
EVT_UPDATE_UI_RANGE( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,
ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,
EDA_3D_VIEWER::OnUpdateUIMaterial )
EVT_CLOSE( EDA_3D_VIEWER::OnCloseWindow )
END_EVENT_TABLE()
@ -132,6 +129,8 @@ EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent, const wxSt
m_toolManager->RegisterTool( new EDA_3D_CONTROLLER );
m_toolManager->InitTools();
setupUIConditions();
if( EDA_3D_CONTROLLER* ctrlTool = GetToolManager()->GetTool<EDA_3D_CONTROLLER>() )
ctrlTool->SetRotationIncrement( config->m_Camera.rotation_increment );
@ -187,6 +186,74 @@ EDA_3D_VIEWER::~EDA_3D_VIEWER()
}
void EDA_3D_VIEWER::setupUIConditions()
{
EDA_BASE_FRAME::setupUIConditions();
ACTION_MANAGER* mgr = m_toolManager->GetActionManager();
EDA_3D_CONDITIONS cond( &m_boardAdapter );
// Helper to define check conditions
#define MaterialCheck( x ) ACTION_CONDITIONS().SetCheckCondition( cond.MaterialMode( x ) )
#define FlagCheck( x ) ACTION_CONDITIONS().SetCheckCondition( cond.Flag( x ) )
#define GridSizeCheck( x ) ACTION_CONDITIONS().SetCheckCondition( cond.GridSize( x ) )
auto raytracingCondition = [this]( const SELECTION& aSel )
{
return m_boardAdapter.RenderEngineGet() != RENDER_ENGINE::OPENGL_LEGACY;
};
RegisterUIUpdateHandler( ID_RENDER_CURRENT_VIEW,
ACTION_CONDITIONS().SetCheckCondition( raytracingCondition ) );
mgr->SetConditions( ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL,,
MaterialCheck( MATERIAL_MODE::NORMAL ) );
mgr->SetConditions( ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY,,
MaterialCheck( MATERIAL_MODE::DIFFUSE_ONLY ) );
mgr->SetConditions( ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE,,
MaterialCheck( MATERIAL_MODE::CAD_MODE ) );
mgr->SetConditions( EDA_3D_ACTIONS::renderShadows,
FlagCheck( FL_RENDER_RAYTRACING_SHADOWS ) );
mgr->SetConditions( EDA_3D_ACTIONS::proceduralTextures,
FlagCheck( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) );
mgr->SetConditions( EDA_3D_ACTIONS::addFloor,
FlagCheck( FL_RENDER_RAYTRACING_BACKFLOOR ) );
mgr->SetConditions( EDA_3D_ACTIONS::showRefractions,
FlagCheck( FL_RENDER_RAYTRACING_REFRACTIONS ) );
mgr->SetConditions( EDA_3D_ACTIONS::showReflections,
FlagCheck( FL_RENDER_RAYTRACING_REFLECTIONS ) );
mgr->SetConditions( EDA_3D_ACTIONS::antiAliasing,
FlagCheck( FL_RENDER_RAYTRACING_ANTI_ALIASING ) );
mgr->SetConditions( EDA_3D_ACTIONS::postProcessing,
FlagCheck( FL_RENDER_RAYTRACING_POST_PROCESSING ) );
mgr->SetConditions( EDA_3D_ACTIONS::showBoundingBoxes,
FlagCheck( FL_RENDER_OPENGL_SHOW_MODEL_BBOX ) );
mgr->SetConditions( EDA_3D_ACTIONS::showAxis,
FlagCheck( FL_AXIS ) );
mgr->SetConditions( EDA_3D_ACTIONS::noGrid, GridSizeCheck( GRID3D_TYPE::NONE ) );
mgr->SetConditions( EDA_3D_ACTIONS::show10mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_10MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show2_5mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_2P5MM ) );
mgr->SetConditions( EDA_3D_ACTIONS::show1mmGrid, GridSizeCheck( GRID3D_TYPE::GRID_1MM ) );
auto orthoCondition =
[this] ( const SELECTION& )
{
return m_currentCamera.GetProjection() == PROJECTION_TYPE::ORTHO;
};
mgr->SetConditions( EDA_3D_ACTIONS::toggleOrtho,
ACTION_CONDITIONS().SetCheckCondition( orthoCondition ) );
#undef MaterialCheck
#undef FlagCheck
#undef GridSizeCheck
}
void EDA_3D_VIEWER::ReloadRequest()
{
// This will schedule a request to load later
@ -916,35 +983,6 @@ bool EDA_3D_VIEWER::Set3DSolderPasteColorFromUser()
}
void EDA_3D_VIEWER::OnUpdateUIEngine( wxUpdateUIEvent& aEvent )
{
aEvent.Check( m_boardAdapter.RenderEngineGet() != RENDER_ENGINE::OPENGL_LEGACY );
}
void EDA_3D_VIEWER::OnUpdateUIMaterial( wxUpdateUIEvent& aEvent )
{
// Set the state of toggle menus according to the current display options
switch( aEvent.GetId() )
{
case ID_MENU3D_FL_RENDER_MATERIAL_MODE_NORMAL:
aEvent.Check( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::NORMAL );
break;
case ID_MENU3D_FL_RENDER_MATERIAL_MODE_DIFFUSE_ONLY:
aEvent.Check( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::DIFFUSE_ONLY );
break;
case ID_MENU3D_FL_RENDER_MATERIAL_MODE_CAD_MODE:
aEvent.Check( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::CAD_MODE );
break;
default:
wxFAIL_MSG( "Invalid event in EDA_3D_VIEWER::OnUpdateUIMaterial()" );
}
}
void EDA_3D_VIEWER::loadCommonSettings()
{
wxCHECK_RET( m_canvas, "Cannot load settings to null canvas" );

View File

@ -157,6 +157,9 @@ class EDA_3D_VIEWER : public EDA_3D_BOARD_HOLDER, public KIWAY_PLAYER
void SynchroniseColoursWithBoard();
protected:
void setupUIConditions() override;
private:
/// Called when user press the File->Exit
void Exit3DFrame( wxCommandEvent &event );
@ -174,12 +177,8 @@ private:
void Install3DViewOptionDialog( wxCommandEvent &event );
void OnUpdateUIEngine( wxUpdateUIEvent& aEvent );
void OnUpdateUIMaterial( wxUpdateUIEvent& aEvent );
void CreateMenuBar();
void ReCreateMainToolbar();
void SyncToolbars() override;
void SaveSettings( APP_SETTINGS_BASE *aCfg ) override;

View File

@ -0,0 +1,72 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney at ieee.org>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <3d_canvas/board_adapter.h>
#include <3d_viewer/tools/3d_conditions.h>
#include <functional>
using namespace std::placeholders;
SELECTION_CONDITION EDA_3D_CONDITIONS::MaterialMode( MATERIAL_MODE aMaterial )
{
return std::bind( &EDA_3D_CONDITIONS::materialModeFunction, _1, m_adapter, aMaterial );
}
SELECTION_CONDITION EDA_3D_CONDITIONS::Flag( DISPLAY3D_FLG aFlag )
{
return std::bind( &EDA_3D_CONDITIONS::flagFunction, _1, m_adapter, aFlag );
}
SELECTION_CONDITION EDA_3D_CONDITIONS::GridSize( GRID3D_TYPE aGridSize )
{
return std::bind( &EDA_3D_CONDITIONS::gridSizeFunction, _1, m_adapter, aGridSize );
}
bool EDA_3D_CONDITIONS::materialModeFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
MATERIAL_MODE aMaterial )
{
return aAdapter->MaterialModeGet() == aMaterial;
}
bool EDA_3D_CONDITIONS::flagFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
DISPLAY3D_FLG aFlag )
{
return aAdapter->GetFlag( aFlag );
}
bool EDA_3D_CONDITIONS::gridSizeFunction( const SELECTION& aSelection,
BOARD_ADAPTER* aAdapter,
GRID3D_TYPE aGridSize )
{
return aAdapter->GridGet() == aGridSize;
}

View File

@ -0,0 +1,91 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Ian McInerney <ian.s.mcinerney at ieee.org>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _3D_CONDITIONS_H_
#define _3D_CONDITIONS_H_
#include <3d_enums.h>
#include <tool/selection.h>
#include <tool/selection_conditions.h>
class BOARD_ADAPTER;
class EDA_3D_CONDITIONS : public SELECTION_CONDITIONS
{
public:
/**
* Define conditions for a 3D viewer frame.
*
* @param aAdapter is the board adapter to query for information.
*/
EDA_3D_CONDITIONS( BOARD_ADAPTER* aAdapter ) :
m_adapter( aAdapter )
{}
/**
* Creates a functor that tests if a specific material mode is active.
*
* @param aAdapter is the board adapter the setting is in
* @param aMaterial is the material mode to test for.
* @return Functor testing if a material mode is active.
*/
SELECTION_CONDITION MaterialMode( MATERIAL_MODE aMaterial );
/**
* Creates a functor that tests if the board adapter has a flag set currently.
*
* @param aAdapter is the board adapter the setting is in
* @param aFlag is the flag to test for.
* @return Functor testing if the flag is set.
*/
SELECTION_CONDITION Flag( DISPLAY3D_FLG aFlag );
/**
* Creates a functor that tests the current grid size.
*
* @param aAdapter is the board adapter the setting is in
* @param aGridSize is the grid size to test for.
* @return Functor testing if the flag is set.
*/
SELECTION_CONDITION GridSize( GRID3D_TYPE aGridSize );
private:
///> Helper function used by MaterialMode()
static bool materialModeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
MATERIAL_MODE aMaterial );
///> Helper function used by Flag()
static bool flagFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
DISPLAY3D_FLG aFlag );
///> Helper function used by GridDize()
static bool gridSizeFunction( const SELECTION& aSelection, BOARD_ADAPTER* aAdapter,
GRID3D_TYPE aGridSize );
///> The board adapter to read the 3D viewer state from
BOARD_ADAPTER* m_adapter;
};
#endif /* _3D_CONDITIONS_H_ */

View File

@ -92,6 +92,7 @@ set(3D-VIEWER_SRCS
3d_viewer/dialogs/dialog_3D_view_option.cpp
3d_viewer/dialogs/dialog_3D_view_option_base.cpp
3d_viewer/tools/3d_actions.cpp
3d_viewer/tools/3d_conditions.cpp
3d_viewer/tools/3d_controller.cpp
3d_viewer/eda_3d_viewer.cpp
3d_viewer/3d_viewer_settings.cpp

View File

@ -69,6 +69,7 @@ set( GAL_SRCS
add_library( gal STATIC ${GAL_SRCS} )
target_link_libraries( gal
common # This is needed until the circular dependency is removed
kimath
bitmaps
${GLEW_LIBRARIES}

View File

@ -48,6 +48,8 @@
#include <wx/stdpaths.h>
#include <wx/string.h>
#include <functional>
wxDEFINE_EVENT( UNITS_CHANGED, wxCommandEvent );
@ -290,6 +292,89 @@ void EDA_BASE_FRAME::OnMenuEvent( wxMenuEvent& aEvent )
}
void EDA_BASE_FRAME::RegisterUIUpdateHandler( int aID, const ACTION_CONDITIONS& aConditions )
{
UIUpdateHandler evtFunc = std::bind( &EDA_BASE_FRAME::HandleUpdateUIEvent,
std::placeholders::_1,
this,
aConditions );
m_uiUpdateMap[aID] = evtFunc;
Bind( wxEVT_UPDATE_UI, evtFunc, aID );
}
void EDA_BASE_FRAME::UnregisterUIUpdateHandler( int aID )
{
const auto it = m_uiUpdateMap.find( aID );
if( it == m_uiUpdateMap.end() )
return;
Unbind( wxEVT_UPDATE_UI, it->second, aID );
}
void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
ACTION_CONDITIONS aCond )
{
bool checkRes = false;
bool enableRes = true;
bool showRes = true;
SELECTION& selection = aFrame->GetCurrentSelection();
try
{
checkRes = aCond.checkCondition( selection );
enableRes = aCond.enableCondition( selection );
showRes = aCond.showCondition( selection );
}
catch( std::exception& )
{
// Something broke with the conditions, just skip the event.
aEvent.Skip();
return;
}
aEvent.Enable( enableRes );
aEvent.Show( showRes );
bool canCheck = true;
// wxMenuItems don't want to be checked unless they actually are checkable, so we have to check to
// see if they can be and can't just universally apply a check in this event.
if( auto menu = dynamic_cast<wxMenu*>( aEvent.GetEventObject() ) )
canCheck = menu->FindItem( aEvent.GetId() )->IsCheckable();
if( canCheck )
aEvent.Check( checkRes );
}
// Contained inside pgm_base.cpp
extern LANGUAGE_DESCR LanguagesList[];
void EDA_BASE_FRAME::setupUIConditions()
{
// Setup the conditions to check a language menu item
auto isCurrentLang =
[] ( const SELECTION& aSel, int aLangIdentifier )
{
return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
};
for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
{
ACTION_CONDITIONS cond;
cond.SetCheckCondition( std::bind( isCurrentLang, std::placeholders::_1,
LanguagesList[ii].m_WX_Lang_Identifier ) );
RegisterUIUpdateHandler( LanguagesList[ii].m_KI_Lang_Identifier, cond );
}
}
void EDA_BASE_FRAME::ReCreateMenuBar()
{
}
@ -298,9 +383,7 @@ void EDA_BASE_FRAME::ReCreateMenuBar()
void EDA_BASE_FRAME::AddStandardHelpMenu( wxMenuBar* aMenuBar )
{
COMMON_CONTROL* commonControl = m_toolManager->GetTool<COMMON_CONTROL>();
ACTION_MENU* helpMenu = new ACTION_MENU( false );
helpMenu->SetTool( commonControl );
ACTION_MENU* helpMenu = new ACTION_MENU( false, commonControl );
helpMenu->Add( ACTIONS::help );
helpMenu->Add( ACTIONS::gettingStarted );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,33 +31,29 @@
#include <pgm_base.h>
#include <id.h>
#include <menus_helpers.h>
#include <tool/tool_interactive.h>
#include <tool/action_menu.h>
#include <tool/conditional_menu.h>
#include <bitmaps.h>
// Contained inside pgm_base.cpp
extern LANGUAGE_DESCR LanguagesList[];
using namespace std::placeholders;
/**
* Function AddMenuLanguageList
* creates a menu list for language choice, and add it as submenu to \a MasterMenu.
*
* @param aMasterMenu The main menu.
* @param aMasterMenu is the main menu.
* @param aControlTool is the tool to associate with the menu
*/
void AddMenuLanguageList( CONDITIONAL_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool )
void AddMenuLanguageList( ACTION_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool )
{
CONDITIONAL_MENU* langsMenu = new CONDITIONAL_MENU( false, aControlTool );
ACTION_MENU* langsMenu = new ACTION_MENU( false, aControlTool );
langsMenu->SetTitle( _( "Set Language" ) );
langsMenu->SetIcon( language_xpm );
aMasterMenu->AddMenu( langsMenu );
wxString tooltip;
auto isCurrentLang = [] ( int aLangIdentifier ) {
return Pgm().GetSelectedLanguageIdentifier() == aLangIdentifier;
};
wxString tooltip;
for( unsigned ii = 0; LanguagesList[ii].m_KI_Lang_Identifier != 0; ii++ )
{
@ -68,8 +64,17 @@ void AddMenuLanguageList( CONDITIONAL_MENU* aMasterMenu, TOOL_INTERACTIVE* aCont
else
label = wxGetTranslation( LanguagesList[ii].m_Lang_Label );
langsMenu->AddCheckItem( LanguagesList[ii].m_KI_Lang_Identifier, // wxMenuItem wxID
label, tooltip, LanguagesList[ii].m_Lang_Icon,
std::bind( isCurrentLang, LanguagesList[ii].m_WX_Lang_Identifier ) );
wxMenuItem* item = new wxMenuItem( langsMenu,
LanguagesList[ii].m_KI_Lang_Identifier, // wxMenuItem wxID
label,
tooltip,
wxITEM_CHECK );
AddBitmapToMenuItem( item, KiBitmap( LanguagesList[ii].m_Lang_Icon ) );
langsMenu->Append( item );
}
// This must be done after the items are added
aMasterMenu->Add( langsMenu );
}

View File

@ -66,6 +66,32 @@ void ACTION_MANAGER::RegisterAction( TOOL_ACTION* aAction )
}
void ACTION_MANAGER::SetConditions( const TOOL_ACTION& aAction, const ACTION_CONDITIONS& aConditions )
{
// Remove any existing handlers with the old conditions to ensure the UI layer doesn't have stale data
if( m_toolMgr )
m_toolMgr->GetToolHolder()->UnregisterUIUpdateHandler( aAction );
m_uiConditions[aAction.GetId()] = aConditions;
// Register a new handler with the new conditions
if( m_toolMgr )
m_toolMgr->GetToolHolder()->RegisterUIUpdateHandler( aAction, aConditions );
}
const ACTION_CONDITIONS* ACTION_MANAGER::GetCondition( const TOOL_ACTION& aAction ) const
{
const auto it = m_uiConditions.find( aAction.GetUIId() );
// If the action doesn't have something registered, then return null
if( it == m_uiConditions.end() )
return nullptr;
else
return &it->second;
}
int ACTION_MANAGER::MakeActionId( const std::string& aActionName )
{
static int currentActionId = 1;

View File

@ -27,6 +27,7 @@
#include <eda_base_frame.h>
#include <functional>
#include <id.h>
#include <kiface_i.h>
#include <menus_helpers.h>
#include <tool/action_menu.h>
#include <tool/actions.h>
@ -42,13 +43,13 @@
using namespace std::placeholders;
ACTION_MENU::ACTION_MENU( bool isContextMenu ) :
ACTION_MENU::ACTION_MENU( bool isContextMenu, TOOL_INTERACTIVE* aTool ) :
m_dirty( true ),
m_titleDisplayed( false ),
m_isContextMenu( isContextMenu ),
m_icon( nullptr ),
m_selected( -1 ),
m_tool( nullptr )
m_tool( aTool )
{
setupEvents();
}
@ -147,11 +148,12 @@ wxMenuItem* ACTION_MENU::Add( const wxString& aLabel, int aId, const BITMAP_OPAQ
wxMenuItem* ACTION_MENU::Add( const wxString& aLabel, const wxString& aTooltip, int aId,
const BITMAP_OPAQUE* aIcon )
const BITMAP_OPAQUE* aIcon, bool aIsCheckmarkEntry )
{
wxASSERT_MSG( FindItem( aId ) == nullptr, "Duplicate menu IDs!" );
wxMenuItem* item = new wxMenuItem( this, aId, aLabel, aTooltip, wxITEM_NORMAL );
wxMenuItem* item = new wxMenuItem( this, aId, aLabel, aTooltip,
aIsCheckmarkEntry ? wxITEM_CHECK : wxITEM_NORMAL );
if( aIcon )
AddBitmapToMenuItem( item, KiBitmap( aIcon ) );
@ -199,6 +201,33 @@ wxMenuItem* ACTION_MENU::Add( ACTION_MENU* aMenu )
}
void ACTION_MENU::AddClose( wxString aAppname )
{
Add( _( "Close\tCTRL+W" ),
wxString::Format( "Close %s", aAppname ),
wxID_CLOSE,
exit_xpm );
}
void ACTION_MENU::AddQuitOrClose( KIFACE_I* aKiface, wxString aAppname )
{
if( !aKiface || aKiface->IsSingle() ) // not when under a project mgr
{
// Don't use ACTIONS::quit; wxWidgets moves this on OSX and expects to find it via
// wxID_EXIT
Add( _( "Quit" ),
wxString::Format( "Quit %s", aAppname ),
wxID_EXIT,
exit_xpm );
}
else
{
AddClose( aAppname );
}
}
void ACTION_MENU::Clear()
{
m_titleDisplayed = false;

View File

@ -30,9 +30,8 @@
CONDITIONAL_MENU::CONDITIONAL_MENU( bool isContextMenu, TOOL_INTERACTIVE* aTool ) :
ACTION_MENU( isContextMenu )
ACTION_MENU( isContextMenu, aTool )
{
m_tool = aTool;
}
@ -99,29 +98,6 @@ void CONDITIONAL_MENU::AddSeparator( int aOrder )
}
void CONDITIONAL_MENU::AddClose( wxString aAppname )
{
AddItem( wxID_CLOSE, _( "Close\tCTRL+W" ), wxString::Format( "Close %s", aAppname ), exit_xpm,
SELECTION_CONDITIONS::ShowAlways );
}
void CONDITIONAL_MENU::AddQuitOrClose( KIFACE_I* aKiface, wxString aAppname )
{
if( !aKiface || aKiface->IsSingle() ) // not when under a project mgr
{
// Don't use ACTIONS::quit; wxWidgets moves this on OSX and expects to find it via
// wxID_EXIT
AddItem( wxID_EXIT, _( "Quit" ), wxString::Format( "Quit %s", aAppname ), exit_xpm,
SELECTION_CONDITIONS::ShowAlways );
}
else
{
AddClose( aAppname );
}
}
SELECTION g_resolveDummySelection;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013-2019 KiCad Developers, see CHANGELOG.txt for contributors.
* Copyright (C) 2013-2020 KiCad Developers, see CHANGELOG.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -27,8 +27,10 @@
#include <trace_helpers.h>
#include <tool/tool_manager.h>
#include <tool/tools_holder.h>
#include <tool/tool_dispatcher.h>
#include <tool/actions.h>
#include <tool/action_manager.h>
#include <tool/action_menu.h>
#include <view/view.h>
#include <view/wx_view_controls.h>
@ -338,7 +340,7 @@ OPT<TOOL_EVENT> TOOL_DISPATCHER::GetToolEvent( wxKeyEvent* aKeyEvent, bool* keyI
return evt;
}
wxLogTrace( kicadTraceKeyEvent, "TOOL_DISPATCHER::DispatchWxEvent %s", dump( *aKeyEvent ) );
wxLogTrace( kicadTraceKeyEvent, "TOOL_DISPATCHER::GetToolEvent %s", dump( *aKeyEvent ) );
// if the key event must be skipped, skip it here if the event is a wxEVT_CHAR_HOOK
// and do nothing.
@ -613,5 +615,3 @@ void TOOL_DISPATCHER::DispatchWxCommand( wxCommandEvent& aEvent )
else
aEvent.Skip();
}

View File

@ -37,8 +37,6 @@
#include "sch_edit_frame.h"
#include <widgets/wx_menubar.h>
extern void AddMenuLanguageList( CONDITIONAL_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool );
void SCH_EDIT_FRAME::ReCreateMenuBar()
{

View File

@ -40,6 +40,7 @@
#include <wx/laywin.h>
#include <wx/aui/aui.h>
#include <wx/docview.h>
#include <wx/event.h>
#include <fctsys.h>
#include <common.h>
#include <layers_id_colors_and_visibility.h>
@ -89,6 +90,9 @@ enum id_librarytype {
#define DEFAULT_MAX_UNDO_ITEMS 0
#define ABS_MAX_UNDO_ITEMS (INT_MAX / 2)
/// This is the handler functor for the update UI events
typedef std::function< void( wxUpdateUIEvent& ) > UIUpdateHandler;
wxDECLARE_EVENT( UNITS_CHANGED, wxCommandEvent );
@ -159,6 +163,9 @@ protected:
EDA_UNITS m_userUnits;
// Map containing the UI update handlers registered with wx for each action
std::map<int, UIUpdateHandler> m_uiUpdateMap;
///> Default style flags used for wxAUI toolbars
static constexpr int KICAD_AUI_TB_STYLE = wxAUI_TB_DEFAULT_STYLE | wxAUI_TB_PLAIN_BACKGROUND;
@ -205,6 +212,11 @@ protected:
*/
virtual void unitsChangeRefresh() { }
/**
* Setup the UI conditions for the various actions and their controls in this frame.
*/
virtual void setupUIConditions();
DECLARE_EVENT_TABLE()
public:
@ -258,6 +270,43 @@ public:
*/
void OnMenuEvent( wxMenuEvent& event );
virtual void RegisterUIUpdateHandler( const TOOL_ACTION& aAction,
const ACTION_CONDITIONS& aConditions ) override
{
RegisterUIUpdateHandler( aAction.GetUIId(), aConditions );
}
/**
* Register a UI update handler for the control with ID @c aID
*
* @param aID is the control ID to register the handler for
* @param aConditions are the UI conditions to use for the control states
*/
virtual void RegisterUIUpdateHandler( int aID, const ACTION_CONDITIONS& aConditions );
virtual void UnregisterUIUpdateHandler( const TOOL_ACTION& aAction ) override
{
UnregisterUIUpdateHandler( aAction.GetUIId() );
}
/**
* Unregister a UI handler for a given ID that was registered using @c RegisterUIUpdateHandler
*
* @param aID is the control ID to unregister the handler for
*/
virtual void UnregisterUIUpdateHandler( int aID );
/**
* Handles events generated when the UI is trying to figure out the current state of the UI controls
* related to TOOL_ACTIONS (e.g. enabled, checked, etc.).
*
* @param aEvent is the wxUpdateUIEvent to be processed.
* @param aFrame is the frame to get the selection from
* @param aCond are the UI SELECTION_CONDITIONS used
*/
static void HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAME* aFrame,
ACTION_CONDITIONS aCond );
virtual void OnMove( wxMoveEvent& aEvent )
{
aEvent.Skip();

View File

@ -35,11 +35,10 @@
#include <wx/menuitem.h>
#include <bitmaps.h>
class CONDITIONAL_MENU;
class ACTION_MENU;
class TOOL_INTERACTIVE;
void AddMenuLanguageList( CONDITIONAL_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool );
void AddMenuLanguageList( ACTION_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool );
/**
* Add a bitmap to a menuitem

View File

@ -30,10 +30,51 @@
#include <string>
#include <set>
#include <tool/selection_conditions.h>
class TOOL_BASE;
class TOOL_MANAGER;
class TOOL_ACTION;
/**
* Functors that can be used to figure out how the action controls should be displayed in the UI
* and if an action should be enabled given the current selection.
*
* @note @c checkCondition is also used for determing the state of a toggled toolbar item
* (the item is toggled when the condition is true).
*/
struct ACTION_CONDITIONS
{
SELECTION_CONDITION checkCondition; ///< Returns true if the UI control should be checked
SELECTION_CONDITION enableCondition; ///< Returns true if the UI control should be enabled
SELECTION_CONDITION showCondition; ///< Returns true if the UI control should be shown
ACTION_CONDITIONS()
{
checkCondition = SELECTION_CONDITIONS::ShowNever; // Never check by default
enableCondition = SELECTION_CONDITIONS::ShowAlways; // Always enable by default
showCondition = SELECTION_CONDITIONS::ShowAlways; // Always show by default
}
ACTION_CONDITIONS& SetCheckCondition( const SELECTION_CONDITION& aCondition )
{
checkCondition = aCondition;
return *this;
}
ACTION_CONDITIONS& SetEnableCondition( const SELECTION_CONDITION& aCondition )
{
enableCondition = aCondition;
return *this;
}
ACTION_CONDITIONS& SetShowCondition( const SELECTION_CONDITION& aCondition )
{
showCondition = aCondition;
return *this;
}
};
/**
* ACTION_MANAGER
*
@ -44,21 +85,19 @@ class ACTION_MANAGER
{
public:
/**
* Constructor.
* @param aToolManager is a tool manager instance that is used to pass events to tools.
*/
ACTION_MANAGER( TOOL_MANAGER* aToolManager );
/**
* Destructor.
* Unregisters every registered action.
*/
~ACTION_MANAGER();
/**
* Function RegisterAction()
* Adds a tool action to the manager and sets it up. After that is is possible to invoke
* the action using hotkeys or sending a command event with its name.
*
* @param aAction: action to be added. Ownership is not transferred.
*/
void RegisterAction( TOOL_ACTION* aAction );
@ -74,36 +113,34 @@ public:
const std::map<std::string, TOOL_ACTION*>& GetActions();
/**
* Function FindAction()
* Finds an action with a given name (if there is one available).
*
* @param aActionName is the searched action.
* @return Pointer to a TOOL_ACTION object or NULL if there is no such action.
*/
TOOL_ACTION* FindAction( const std::string& aActionName ) const;
/**
* Function RunHotKey()
* Runs an action associated with a hotkey (if there is one available).
*
* @param aHotKey is the hotkey to be handled.
* @return True if there was an action associated with the hotkey, false otherwise.
*/
bool RunHotKey( int aHotKey ) const;
/**
* Function GetHotKey()
* Returns the hot key associated with a given action or 0 if there is none.
*
* @param aAction is the queried action.
*/
int GetHotKey( const TOOL_ACTION& aAction ) const;
/**
* Function UpdateHotKeys()
* Optionally reads the hotkey config files and then rebuilds the internal hotkey maps.
*/
void UpdateHotKeys( bool aFullUpdate );
/**
* Function GetActionList()
* Returns list of TOOL_ACTIONs. TOOL_ACTIONs add themselves to the list upon their
* creation.
* @return List of TOOL_ACTIONs.
@ -115,6 +152,23 @@ public:
return actionList;
}
/**
* Set the conditions the UI elements for activating a specific tool action should use
* for determining the current UI state (e.g. checked, enabled, shown)
*
* @param aAction is the tool action using these conditions
* @param aConditions are the conditions to use for the action
*/
void SetConditions( const TOOL_ACTION& aAction, const ACTION_CONDITIONS& aConditions );
/**
* Get the conditions to use for a specific tool action.
*
* @param aAction is the tool action
* @return the action conditions, returns nullptr if no conditions are registered
*/
const ACTION_CONDITIONS* GetCondition( const TOOL_ACTION& aAction ) const;
private:
// Resolves a hotkey by applying legacy and current settings over the action's
// default hotkey.
@ -133,6 +187,10 @@ private:
///> Quick action<->hot key lookup
std::map<int, int> m_hotkeys;
/// Map the command ID that wx uses for the action to the UI conditions for the
/// menu/toolbar items
std::map<int, ACTION_CONDITIONS> m_uiConditions;
};
#endif /* ACTION_MANAGER_H_ */

View File

@ -34,6 +34,7 @@
#include <wx/textentry.h>
#include <tool/tool_action.h>
class KIFACE_I;
class TOOL_INTERACTIVE;
/**
@ -43,7 +44,7 @@ class ACTION_MENU : public wxMenu
{
public:
///> Default constructor
ACTION_MENU( bool isContextMenu );
ACTION_MENU( bool isContextMenu, TOOL_INTERACTIVE* aTool = nullptr );
~ACTION_MENU() override;
@ -76,7 +77,7 @@ public:
*/
wxMenuItem* Add( const wxString& aLabel, int aId, const BITMAP_OPAQUE* aIcon );
wxMenuItem* Add( const wxString& aLabel, const wxString& aToolTip, int aId,
const BITMAP_OPAQUE* aIcon );
const BITMAP_OPAQUE* aIcon, bool aIsCheckmarkEntry = false );
/**
* Adds an entry to the menu, basing on the TOOL_ACTION object. After selecting the entry,
@ -94,6 +95,22 @@ public:
*/
wxMenuItem* Add( ACTION_MENU* aMenu );
/**
* Add a standard close item to the menu with the accelerator key CTRL-W.
* Emits the wxID_CLOSE event.
*
* @param aAppname is the application name to append to the tooltip
*/
void AddClose( wxString aAppname = "" );
/**
* Adds either a standard Quit or Close item to the menu. If aKiface is NULL or in
* single-instance then Quite (wxID_QUIT) is used, otherwise Close (wxID_CLOSE) is used.
*
* @param aAppname is the application name to append to the tooltip
*/
void AddQuitOrClose( KIFACE_I* aKiface, wxString aAppname = "" );
/**
* Removes all the entries from the menu (as well as its title). It leaves the menu in the
* initial state.
@ -142,6 +159,8 @@ public:
void OnMenuEvent( wxMenuEvent& aEvent );
void OnIdle( wxIdleEvent& event );
static constexpr bool CHECK = true;
protected:
///> Returns an instance of this class. It has to be overridden in inheriting classes.
virtual ACTION_MENU* create() const;

View File

@ -98,7 +98,7 @@ public:
void Toggle( const TOOL_ACTION& aAction, bool aEnabled, bool aChecked );
static const bool TOGGLE = true;
static constexpr bool TOGGLE = true;
protected:
///> The default tool event handler.

View File

@ -33,7 +33,6 @@
class SELECTION_TOOL;
class TOOL_ACTION;
class TOOL_INTERACTIVE;
class KIFACE_I;
class CONDITIONAL_MENU : public ACTION_MENU
@ -100,26 +99,6 @@ public:
*/
void AddSeparator( int aOrder = ANY_ORDER );
/**
* Function AddClose()
*
* Add a standard close item to the menu with the accelerator key CTRL-W.
* Emits the wxID_CLOSE event.
*
* @param aAppname is the application name to append to the tooltip
*/
void AddClose( wxString aAppname = "" );
/**
* Functions AddQuitOrClose()
*
* Adds either a standard Quit or Close item to the menu. If aKiface is NULL or in
* single-instance then Quite (wxID_QUIT) is used, otherwise Close (wxID_CLOSE) is used.
*
* @param aAppname is the application name to append to the tooltip
*/
void AddQuitOrClose( KIFACE_I* aKiface, wxString aAppname = "" );
/**
* Function Evaluate()
*

View File

@ -49,10 +49,10 @@ class SELECTION_CONDITIONS
{
public:
/**
* Function ShowAlways
* The default condition function (always returns true).
*
* @param aSelection is the selection to be tested.
* @return Always true;
* @return Always true.
*/
static bool ShowAlways( const SELECTION& aSelection )
{
@ -60,32 +60,43 @@ public:
}
/**
* Function NotEmpty
* Always returns false.
*
* @param aSelection is the selection to be tested.
* @return Always false.
*/
static bool ShowNever( const SELECTION& aSelection )
{
return false;
}
/**
* Tests if there are any items selected.
*
* @param aSelection is the selection to be tested.
* @return True if there is at least one item selected.
*/
static bool NotEmpty( const SELECTION& aSelection );
/**
* Function HasType
* Creates a functor that tests if among the selected items there is at least one of a given type.
*
* @param aType is the type that is searched.
* @return Functor testing for presence of items of a given type.
*/
static SELECTION_CONDITION HasType( KICAD_T aType );
/**
* Function OnlyType
* Creates a functor that tests if the selected items are *only* of given type.
*
* @param aType is the type that is searched.
* @return Functor testing if selected items are exclusively of one type.
*/
static SELECTION_CONDITION OnlyType( KICAD_T aType );
/**
* Function OnlyTypes
* Creates a functor that tests if the selected items are *only* of given types.
*
* @param aTypes is an array containing types that are searched. It has to be ended with
* KICAD_T::EOT as end marker.
* @return Functor testing if selected items are exclusively of the requested types.
@ -93,27 +104,27 @@ public:
static SELECTION_CONDITION OnlyTypes( const KICAD_T aTypes[] );
/**
* Function Count
* Creates a functor that tests if the number of selected items is equal to the value given as
* parameter.
*
* @param aNumber is the number of expected items.
* @return Functor testing if the number of selected items is equal aNumber.
*/
static SELECTION_CONDITION Count( int aNumber );
/**
* Function MoreThan
* Creates a functor that tests if the number of selected items is greater than the value given
* as parameter.
*
* @param aNumber is the number used for comparison.
* @return Functor testing if the number of selected items is greater than aNumber.
*/
static SELECTION_CONDITION MoreThan( int aNumber );
/**
* Function LessThan
* Creates a functor that tests if the number of selected items is smaller than the value given
* as parameter.
*
* @param aNumber is the number used for comparison.
* @return Functor testing if the number of selected items is smaller than aNumber.
*/

View File

@ -39,8 +39,6 @@ class VIEW;
}
/**
* TOOL_DISPATCHER
*
* - takes wx events,
* - fixes all wx quirks (mouse warping, panning, ordering problems, etc)
* - translates coordinates to world space
@ -52,8 +50,6 @@ class TOOL_DISPATCHER : public wxEvtHandler
{
public:
/**
* Constructor
*
* @param aToolMgr: tool manager instance the events will be sent to
* @param aActions: ACTIONS subclass instance for ACTIONS::TranslateLegacyId()
*/
@ -62,29 +58,27 @@ public:
virtual ~TOOL_DISPATCHER();
/**
* Function ResetState()
* Brings the dispatcher to its initial state.
*/
virtual void ResetState();
/**
* Function DispatchWxEvent()
* Processes wxEvents (mostly UI events), translates them to TOOL_EVENTs, and makes tools
* handle those.
*
* @param aEvent is the wxWidgets event to be processed.
*/
virtual void DispatchWxEvent( wxEvent& aEvent );
/**
* Function GetToolEvent()
* Maps a wxWidgets key event to a TOOL_EVENT.
*/
OPT<TOOL_EVENT> GetToolEvent( wxKeyEvent* aKeyEvent, bool* aSpecialKeyFlag );
/**
* Function DispatchWxCommand()
* Processes wxCommands (mostly menu related events) and runs appropriate actions (eg. run the
* specified tool).
*
* @param aEvent is the wxCommandEvent to be processed.
*/
virtual void DispatchWxCommand( wxCommandEvent& aEvent );

View File

@ -27,6 +27,8 @@
#include <vector>
#include <fctsys.h>
#include <common.h>
#include <tool/action_manager.h>
#include <tool/selection.h>
#include <tool/tool_action.h>
@ -49,6 +51,8 @@ protected:
ACTIONS* m_actions;
TOOL_DISPATCHER* m_toolDispatcher;
SELECTION m_dummySelection; // Empty dummy selection
std::vector<std::string> m_toolStack; // Stack of user-level "tools". This is NOT a
// stack of TOOL instances, because somewhat
// confusingly most TOOLs implement more than one
@ -73,6 +77,35 @@ public:
*/
TOOL_MANAGER* GetToolManager() const { return m_toolManager; }
/**
* Register an action's update conditions with the UI layer to allow the UI to appropriately
* display the state of its controls.
*
* @param aAction is the action to register
* @param aConditions are the UI conditions to use for the control states
*/
virtual void RegisterUIUpdateHandler( const TOOL_ACTION& aAction,
const ACTION_CONDITIONS& aConditions )
{}
/**
* Unregister a UI handler for an action that was registered using @c RegisterUIUpdateHandler
*
* @param aAction is the action to unregister the handler for
*/
virtual void UnregisterUIUpdateHandler( const TOOL_ACTION& aAction )
{}
/**
* Get the current selection from the canvas area.
*
* @return the current selection
*/
virtual SELECTION& GetCurrentSelection()
{
return m_dummySelection;
}
/**
* NB: the definition of "tool" is different at the user level. The implementation uses
* a single TOOL_BASE derived class to implement several user "tools", such as rectangle

View File

@ -40,6 +40,7 @@
#include <reporter.h>
#include <settings/common_settings.h>
#include <settings/settings_manager.h>
#include <tool/action_manager.h>
#include <tool/action_toolbar.h>
#include <tool/common_control.h>
#include <tool/tool_dispatcher.h>
@ -121,22 +122,8 @@ KICAD_MANAGER_FRAME::KICAD_MANAGER_FRAME( wxWindow* parent, const wxString& titl
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxTE_READONLY | wxBORDER_NONE );
// Create the manager
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
m_actions = new KICAD_MANAGER_ACTIONS();
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, m_actions );
// Attach the events to the tool dispatcher
Bind( wxEVT_TOOL, &TOOL_DISPATCHER::DispatchWxCommand, m_toolDispatcher );
Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
// Register tools
m_toolManager->RegisterTool( new COMMON_CONTROL );
m_toolManager->RegisterTool( new KICAD_MANAGER_CONTROL );
m_toolManager->InitTools();
setupTools();
setupUIConditions();
RecreateBaseHToolbar();
RecreateLauncher();
@ -188,6 +175,56 @@ KICAD_MANAGER_FRAME::~KICAD_MANAGER_FRAME()
}
void KICAD_MANAGER_FRAME::setupTools()
{
// Create the manager
m_toolManager = new TOOL_MANAGER;
m_toolManager->SetEnvironment( nullptr, nullptr, nullptr, config(), this );
m_actions = new KICAD_MANAGER_ACTIONS();
m_toolDispatcher = new TOOL_DISPATCHER( m_toolManager, m_actions );
// Attach the events to the tool dispatcher
Bind( wxEVT_TOOL, &TOOL_DISPATCHER::DispatchWxCommand, m_toolDispatcher );
Bind( wxEVT_CHAR, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
Bind( wxEVT_CHAR_HOOK, &TOOL_DISPATCHER::DispatchWxEvent, m_toolDispatcher );
// Register tools
m_toolManager->RegisterTool( new COMMON_CONTROL );
m_toolManager->RegisterTool( new KICAD_MANAGER_CONTROL );
m_toolManager->InitTools();
}
void KICAD_MANAGER_FRAME::setupUIConditions()
{
EDA_BASE_FRAME::setupUIConditions();
ACTION_MANAGER* manager = m_toolManager->GetActionManager();
wxASSERT( manager );
auto activeProject =
[this] ( const SELECTION& )
{
return m_active_project;
};
ACTION_CONDITIONS activeProjectCond;
activeProjectCond.SetEnableCondition( activeProject );
manager->SetConditions( KICAD_MANAGER_ACTIONS::editSchematic, activeProjectCond );
manager->SetConditions( KICAD_MANAGER_ACTIONS::editSymbols, activeProjectCond );
manager->SetConditions( KICAD_MANAGER_ACTIONS::editPCB, activeProjectCond );
manager->SetConditions( KICAD_MANAGER_ACTIONS::editFootprints, activeProjectCond );
manager->SetConditions( ACTIONS::saveAs, activeProjectCond );
manager->SetConditions( KICAD_MANAGER_ACTIONS::closeProject, activeProjectCond );
// TODO: Switch this to an action
RegisterUIUpdateHandler( ID_SAVE_AND_ZIP_FILES, activeProjectCond );
}
wxWindow* KICAD_MANAGER_FRAME::GetToolCanvas() const
{
return m_leftWin;
@ -537,8 +574,7 @@ void KICAD_MANAGER_FRAME::ShowChangedLanguage()
void KICAD_MANAGER_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
{
int historySize = Pgm().GetCommonSettings()->m_System.file_history_size;
GetFileHistory().SetMaxFiles( (unsigned) std::max( 0, historySize ) );
EDA_BASE_FRAME::CommonSettingsChanged( aEnvVarsChanged, aTextVarsChanged );
}

View File

@ -163,8 +163,6 @@ public:
*/
void OnChangeWatchedPaths( wxCommandEvent& aEvent );
void SyncToolbars() override;
void InstallPreferences( PAGED_DIALOG* aParent, PANEL_HOTKEYS_EDITOR* aHotkeysPanel ) override;
const wxString GetProjectFileName() const;
@ -182,7 +180,13 @@ public:
DECLARE_EVENT_TABLE()
protected:
virtual void setupUIConditions() override;
private:
void setupTools();
void setupActions();
APP_SETTINGS_BASE* config() const override;
KICAD_SETTINGS* kicadSettings() const;

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019 CERN
*
* This program is free software; you can redistribute it and/or
@ -27,8 +27,9 @@
#include <bitmaps.h>
#include <filehistory.h>
#include <menus_helpers.h>
#include <tool/tool_manager.h>
#include <tool/action_manager.h>
#include <tool/action_toolbar.h>
#include <tool/tool_manager.h>
#include <tools/kicad_manager_control.h>
#include <tools/kicad_manager_actions.h>
#include "kicad_manager_frame.h"
@ -47,7 +48,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
//-- File menu -----------------------------------------------------------
//
CONDITIONAL_MENU* fileMenu = new CONDITIONAL_MENU( false, controlTool );
ACTION_MENU* fileMenu = new ACTION_MENU( false, controlTool );
FILE_HISTORY& fileHistory = GetFileHistory();
fileHistory.SetClearText( _( "Clear Recent Projects" ) );
@ -58,8 +59,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
// will automatically refresh the menu.
if( !openRecentMenu )
{
openRecentMenu = new ACTION_MENU( false );
openRecentMenu->SetTool( controlTool );
openRecentMenu = new ACTION_MENU( false, controlTool );
openRecentMenu->SetTitle( _( "Open Recent" ) );
openRecentMenu->SetIcon( recent_xpm );
@ -67,95 +67,96 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
fileHistory.AddFilesToMenu();
}
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::newFromTemplate, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::openProject, SELECTION_CONDITIONS::ShowAlways );
fileMenu->AddMenu( openRecentMenu,
FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
fileMenu->Add( KICAD_MANAGER_ACTIONS::newProject );
fileMenu->Add( KICAD_MANAGER_ACTIONS::newFromTemplate );
fileMenu->Add( KICAD_MANAGER_ACTIONS::openProject );
fileMenu->AddItem( KICAD_MANAGER_ACTIONS::closeProject, SELECTION_CONDITIONS::ShowAlways );
wxMenuItem* item = fileMenu->Add( openRecentMenu );
fileMenu->AddSeparator();
fileMenu->AddItem( ACTIONS::saveAs, SELECTION_CONDITIONS::ShowAlways );
// Add the file menu condition here since it needs the item ID for the submenu
ACTION_CONDITIONS cond;
cond.SetEnableCondition( FILE_HISTORY::FileHistoryNotEmpty( fileHistory ) );
RegisterUIUpdateHandler( item->GetId(), cond );
fileMenu->AddSeparator();
fileMenu->AddItem( ID_IMPORT_EAGLE_PROJECT,
_( "Import EAGLE Project..." ),
fileMenu->Add( KICAD_MANAGER_ACTIONS::closeProject );
fileMenu->AppendSeparator();
fileMenu->Add( ACTIONS::saveAs );
fileMenu->AppendSeparator();
fileMenu->Add( _( "Import EAGLE Project..." ),
_( "Import EAGLE CAD XML schematic and board" ),
import_project_xpm, SELECTION_CONDITIONS::ShowAlways );
ID_IMPORT_EAGLE_PROJECT,
import_project_xpm );
fileMenu->AddSeparator();
fileMenu->AddItem( ID_SAVE_AND_ZIP_FILES,
_( "&Archive Project..." ),
fileMenu->AppendSeparator();
fileMenu->Add( _( "&Archive Project..." ),
_( "Archive all needed project files into zip archive" ),
zip_xpm, SELECTION_CONDITIONS::ShowAlways );
ID_SAVE_AND_ZIP_FILES,
zip_xpm );
fileMenu->AddItem( ID_READ_ZIP_ARCHIVE,
_( "&Unarchive Project..." ),
fileMenu->Add( _( "&Unarchive Project..." ),
_( "Unarchive project files from zip archive" ),
unzip_xpm, SELECTION_CONDITIONS::ShowAlways );
ID_READ_ZIP_ARCHIVE,
unzip_xpm );
fileMenu->AddSeparator();
fileMenu->AppendSeparator();
fileMenu->AddQuitOrClose( nullptr, "KiCad" );
fileMenu->Resolve();
//-- View menu -----------------------------------------------------------
//
CONDITIONAL_MENU* viewMenu = new CONDITIONAL_MENU( false, controlTool );
ACTION_MENU* viewMenu = new ACTION_MENU( false, controlTool );
viewMenu->AddItem( ACTIONS::zoomRedraw, SELECTION_CONDITIONS::ShowAlways );
viewMenu->Add( ACTIONS::zoomRedraw );
viewMenu->AddSeparator();
viewMenu->AddItem( KICAD_MANAGER_ACTIONS::openTextEditor, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AddItem( ID_BROWSE_IN_FILE_EXPLORER,
_( "Browse Project Files" ), _( "Open project directory in file browser" ),
directory_browser_xpm, SELECTION_CONDITIONS::ShowAlways );
viewMenu->AppendSeparator();
viewMenu->Add( KICAD_MANAGER_ACTIONS::openTextEditor );
viewMenu->Add( _( "Browse Project Files" ),
_( "Open project directory in file browser" ),
ID_BROWSE_IN_FILE_EXPLORER,
directory_browser_xpm );
#ifdef __APPLE__
viewMenu->AddSeparator();
// Add a separator only on macOS because the OS adds menu items to the view menu after ours
viewMenu->AppendSeparator();
#endif
viewMenu->Resolve();
//-- Tools menu -----------------------------------------------
//
CONDITIONAL_MENU* toolsMenu = new CONDITIONAL_MENU( false, controlTool );
ACTION_MENU* toolsMenu = new ACTION_MENU( false, controlTool );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::editSchematic, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::editSymbols, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::editPCB, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::editFootprints, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::editSchematic );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::editSymbols );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::editPCB );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::editFootprints );
toolsMenu->AddSeparator();
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::viewGerbers, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::convertImage, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::showCalculator, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AddItem( KICAD_MANAGER_ACTIONS::editWorksheet, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->AppendSeparator();
toolsMenu->Add( KICAD_MANAGER_ACTIONS::viewGerbers );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::convertImage );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::showCalculator );
toolsMenu->Add( KICAD_MANAGER_ACTIONS::editWorksheet );
toolsMenu->AddSeparator();
toolsMenu->AddItem( ID_EDIT_LOCAL_FILE_IN_TEXT_EDITOR,
_( "Edit Local File..." ), _( "Edit local file in text editor" ),
browse_files_xpm, SELECTION_CONDITIONS::ShowAlways );
toolsMenu->Resolve();
toolsMenu->AppendSeparator();
toolsMenu->Add( _( "Edit Local File..." ),
_( "Edit local file in text editor" ),
ID_EDIT_LOCAL_FILE_IN_TEXT_EDITOR,
browse_files_xpm );
//-- Preferences menu -----------------------------------------------
//
CONDITIONAL_MENU* prefsMenu = new CONDITIONAL_MENU( false, controlTool );
ACTION_MENU* prefsMenu = new ACTION_MENU( false, controlTool );
prefsMenu->AddItem( ACTIONS::configurePaths, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( ACTIONS::showSymbolLibTable, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( ACTIONS::showFootprintLibTable, SELECTION_CONDITIONS::ShowAlways );
prefsMenu->AddItem( wxID_PREFERENCES,
_( "Preferences...\tCTRL+," ),
prefsMenu->Add( ACTIONS::configurePaths );
prefsMenu->Add( ACTIONS::showSymbolLibTable );
prefsMenu->Add( ACTIONS::showFootprintLibTable );
prefsMenu->Add( _( "Preferences...\tCTRL+," ),
_( "Show preferences for all open tools" ),
preference_xpm, SELECTION_CONDITIONS::ShowAlways );
wxID_PREFERENCES,
preference_xpm );
prefsMenu->AddSeparator();
prefsMenu->AppendSeparator();
AddMenuLanguageList( prefsMenu, controlTool );
prefsMenu->Resolve();
//-- Menubar -------------------------------------------------------------
//
@ -255,17 +256,4 @@ void KICAD_MANAGER_FRAME::RecreateLauncher()
// Create mlauncher
m_launcher->Realize();
// And update the visual tools state:
SyncToolbars();
}
void KICAD_MANAGER_FRAME::SyncToolbars()
{
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editSchematic, m_active_project );
m_launcher->Toggle( KICAD_MANAGER_ACTIONS::editPCB, m_active_project );
m_launcher->Refresh();
}