From 75fb04d650cee412a94292e4708a898cbbc54450 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 18 Jan 2017 09:04:11 +0100 Subject: [PATCH] TOOL_ACTIONs are handled with transitions, no handlers needed in the event loops There used to be a number of TOOL_ACTIONs that had entries both in SetTransitions() and the event loop, which seemed redundant and troublesome. Now it is not necessary anymore, transitions setup is enough to execute associated actions. --- common/tool/tool_manager.cpp | 19 +- pcbnew/router/length_tuner_tool.cpp | 79 ++++---- pcbnew/router/length_tuner_tool.h | 9 +- pcbnew/router/pns_tool_base.cpp | 2 +- pcbnew/router/pns_tool_base.h | 2 +- pcbnew/router/router_tool.cpp | 163 ++++++++-------- pcbnew/router/router_tool.h | 16 +- pcbnew/tools/edit_tool.cpp | 17 +- pcbnew/tools/point_editor.cpp | 284 ++++++++++++++-------------- pcbnew/tools/point_editor.h | 7 +- pcbnew/tools/selection_tool.cpp | 43 +---- 11 files changed, 306 insertions(+), 335 deletions(-) diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp index de5d3eb634..304b23548c 100644 --- a/common/tool/tool_manager.cpp +++ b/common/tool/tool_manager.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2017 CERN * @author Tomasz Wlostowski * @author Maciej Suminski * @@ -164,13 +164,11 @@ struct TOOL_MANAGER::TOOL_STATE *this = *stateStack.top(); delete stateStack.top(); stateStack.pop(); - return true; } else { cofunc = NULL; - return false; } } @@ -534,9 +532,11 @@ void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent ) for( TOOL_STATE* st : ( m_toolState | boost::adaptors::map_values ) ) { + bool handled = false; + // no state handler in progress - check if there are any transitions (defined by // Go() method that match the event. - if( !st->pendingWait && !st->transitions.empty() ) + if( !st->transitions.empty() ) { for( TRANSITION& tr : st->transitions ) { @@ -559,11 +559,16 @@ void TOOL_MANAGER::dispatchInternal( const TOOL_EVENT& aEvent ) if( !st->cofunc->Running() ) finishTool( st ); // The couroutine has finished immediately? + handled = true; + // there is no point in further checking, as transitions got cleared break; } } } + + if( handled ) + break; // only the first tool gets the event } } @@ -656,10 +661,6 @@ bool TOOL_MANAGER::finishTool( TOOL_STATE* aState, bool aDeactivate ) { bool shouldDeactivate = false; - // Reset VIEW_CONTROLS only if the most recent tool is finished - if( m_activeTools.empty() || m_activeTools.front() == aState->theTool->GetId() ) - m_viewControls->Reset(); - if( !aState->Pop() ) // if there are no other contexts saved on the stack { // find the tool and deactivate it @@ -669,12 +670,14 @@ bool TOOL_MANAGER::finishTool( TOOL_STATE* aState, bool aDeactivate ) if( tool != m_activeTools.end() ) { shouldDeactivate = true; + m_viewControls->Reset(); if( aDeactivate ) m_activeTools.erase( tool ); } } + // Set transitions to be ready for future TOOL_EVENTs aState->theTool->SetTransitions(); return shouldDeactivate; diff --git a/pcbnew/router/length_tuner_tool.cpp b/pcbnew/router/length_tuner_tool.cpp index 29f49ecfbf..88a1874d73 100644 --- a/pcbnew/router/length_tuner_tool.cpp +++ b/pcbnew/router/length_tuner_tool.cpp @@ -1,7 +1,7 @@ /* * KiRouter - a push-and-(sometimes-)shove PCB router * - * Copyright (C) 2013-2015 CERN + * Copyright (C) 2013-2017 CERN * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Author: Tomasz Wlostowski * @@ -109,37 +109,6 @@ void LENGTH_TUNER_TOOL::Reset( RESET_REASON aReason ) } -void LENGTH_TUNER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent ) -{ - if( aEvent.IsAction( &ACT_RouterOptions ) ) - { - DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() ); - - if( settingsDlg.ShowModal() == wxID_OK ) - { - // FIXME: do we need an explicit update? - } - } - - PNS::MEANDER_PLACER_BASE* placer = static_cast( m_router->Placer() ); - - if( !placer ) - return; - - if( aEvent.IsAction( &ACT_Settings ) ) - { - PNS::MEANDER_SETTINGS settings = placer->MeanderSettings(); - DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( m_frame, settings, m_router->Mode() ); - - if( settingsDlg.ShowModal() ) - { - placer->UpdateSettings( settings ); - } - - m_savedMeanderSettings = placer->MeanderSettings(); - } -} - void LENGTH_TUNER_TOOL::updateStatusPopup( PNS_TUNE_STATUS_POPUP& aPopup ) { wxPoint p = wxGetMousePosition(); @@ -151,6 +120,7 @@ void LENGTH_TUNER_TOOL::updateStatusPopup( PNS_TUNE_STATUS_POPUP& aPopup ) aPopup.Move( p ); } + void LENGTH_TUNER_TOOL::performTuning() { if( m_startItem ) @@ -171,7 +141,7 @@ void LENGTH_TUNER_TOOL::performTuning() return; } - PNS::MEANDER_PLACER_BASE* placer = static_cast( + PNS::MEANDER_PLACER_BASE* placer = static_cast( m_router->Placer() ); placer->UpdateSettings( m_savedMeanderSettings ); @@ -224,8 +194,6 @@ void LENGTH_TUNER_TOOL::performTuning() placer->SpacingStep( 1 ); m_router->Move( end, NULL ); } - - handleCommonEvents( *evt ); } m_router->StopRouting(); @@ -254,6 +222,13 @@ int LENGTH_TUNER_TOOL::TuneDiffPairSkew( const TOOL_EVENT& aEvent ) } +void LENGTH_TUNER_TOOL::SetTransitions() +{ + Go( &LENGTH_TUNER_TOOL::routerOptionsDialog, ACT_RouterOptions.MakeEvent() ); + Go( &LENGTH_TUNER_TOOL::meanderSettingsDialog, ACT_Settings.MakeEvent() ); +} + + int LENGTH_TUNER_TOOL::mainLoop( PNS::ROUTER_MODE aMode ) { // Deselect all items @@ -286,8 +261,6 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS::ROUTER_MODE aMode ) updateStartItem( *evt ); performTuning(); } - - handleCommonEvents( *evt ); } m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); @@ -299,3 +272,35 @@ int LENGTH_TUNER_TOOL::mainLoop( PNS::ROUTER_MODE aMode ) return 0; } + + +int LENGTH_TUNER_TOOL::routerOptionsDialog( const TOOL_EVENT& aEvent ) +{ + DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() ); + + if( settingsDlg.ShowModal() == wxID_OK ) + { + // FIXME: do we need an explicit update? + } + + return 0; +} + + +int LENGTH_TUNER_TOOL::meanderSettingsDialog( const TOOL_EVENT& aEvent ) +{ + PNS::MEANDER_PLACER_BASE* placer = static_cast( m_router->Placer() ); + + if( !placer ) + return 0; + + PNS::MEANDER_SETTINGS settings = placer->MeanderSettings(); + DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( m_frame, settings, m_router->Mode() ); + + if( settingsDlg.ShowModal() ) + placer->UpdateSettings( settings ); + + m_savedMeanderSettings = placer->MeanderSettings(); + + return 0; +} diff --git a/pcbnew/router/length_tuner_tool.h b/pcbnew/router/length_tuner_tool.h index 89724c48dc..f7f7ba8205 100644 --- a/pcbnew/router/length_tuner_tool.h +++ b/pcbnew/router/length_tuner_tool.h @@ -1,7 +1,7 @@ /* * KiRouter - a push-and-(sometimes-)shove PCB router * - * Copyright (C) 2013-2015 CERN + * Copyright (C) 2013-2017 CERN * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Author: Tomasz Wlostowski * Author: Maciej Suminski @@ -39,14 +39,17 @@ public: int TuneSingleTrace( const TOOL_EVENT& aEvent ); int TuneDiffPair( const TOOL_EVENT& aEvent ); int TuneDiffPairSkew( const TOOL_EVENT& aEvent ); - int ClearMeanders( const TOOL_EVENT& aEvent ); + + void SetTransitions() override; private: void performTuning(); int mainLoop( PNS::ROUTER_MODE aMode ); - void handleCommonEvents( const TOOL_EVENT& aEvent ); void updateStatusPopup( PNS_TUNE_STATUS_POPUP& aPopup ); + int routerOptionsDialog( const TOOL_EVENT& aEvent ); + int meanderSettingsDialog( const TOOL_EVENT& aEvent ); + PNS::MEANDER_SETTINGS m_savedMeanderSettings; }; diff --git a/pcbnew/router/pns_tool_base.cpp b/pcbnew/router/pns_tool_base.cpp index 0f90500d3a..ad4417810e 100644 --- a/pcbnew/router/pns_tool_base.cpp +++ b/pcbnew/router/pns_tool_base.cpp @@ -235,7 +235,7 @@ void TOOL_BASE::updateStartItem( TOOL_EVENT& aEvent ) } -void TOOL_BASE::updateEndItem( TOOL_EVENT& aEvent ) +void TOOL_BASE::updateEndItem( const TOOL_EVENT& aEvent ) { VECTOR2I mp = m_ctls->GetMousePosition(); VECTOR2I p = getView()->ToWorld( mp ); diff --git a/pcbnew/router/pns_tool_base.h b/pcbnew/router/pns_tool_base.h index fcd63043e2..8974aa42d0 100644 --- a/pcbnew/router/pns_tool_base.h +++ b/pcbnew/router/pns_tool_base.h @@ -63,7 +63,7 @@ protected: virtual ITEM* pickSingleItem( const VECTOR2I& aWhere, int aNet = -1, int aLayer = -1 ); virtual void highlightNet( bool aEnabled, int aNetcode = -1 ); virtual void updateStartItem( TOOL_EVENT& aEvent ); - virtual void updateEndItem( TOOL_EVENT& aEvent ); + virtual void updateEndItem( const TOOL_EVENT& aEvent ); void deleteTraces( ITEM* aStartItem, bool aWholeTrack ); MSG_PANEL_ITEMS m_panelItems; diff --git a/pcbnew/router/router_tool.cpp b/pcbnew/router/router_tool.cpp index 7aa4b8e8ca..6456229e87 100644 --- a/pcbnew/router/router_tool.cpp +++ b/pcbnew/router/router_tool.cpp @@ -1,7 +1,7 @@ /* * KiRouter - a push-and-(sometimes-)shove PCB router * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2017 CERN * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Author: Tomasz Wlostowski * @@ -60,50 +60,50 @@ using namespace std::placeholders; using namespace KIGFX; using boost::optional; -static TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT, +static const TOOL_ACTION ACT_NewTrack( "pcbnew.InteractiveRouter.NewTrack", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_NEW_TRACK ), _( "New Track" ), _( "Starts laying a new track." ), add_tracks_xpm ); -static TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END, +static const TOOL_ACTION ACT_EndTrack( "pcbnew.InteractiveRouter.EndTrack", AS_CONTEXT, WXK_END, _( "End Track" ), _( "Stops laying the current track." ), checked_ok_xpm ); -static TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', +static const TOOL_ACTION ACT_AutoEndRoute( "pcbnew.InteractiveRouter.AutoEndRoute", AS_CONTEXT, 'F', _( "Auto-end Track" ), _( "Automagically finishes currently routed track." ) ); -static TOOL_ACTION ACT_Drag( "pcbnew.InteractiveRouter.Drag", AS_CONTEXT, +static const TOOL_ACTION ACT_Drag( "pcbnew.InteractiveRouter.Drag", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_DRAG_TRACK_KEEP_SLOPE ), _( "Drag Track/Via" ), _( "Drags a track or a via." ), drag_track_segment_xpm ); -static TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia", +static const TOOL_ACTION ACT_PlaceThroughVia( "pcbnew.InteractiveRouter.PlaceVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_THROUGH_VIA ), _( "Place Through Via" ), _( "Adds a through-hole via at the end of currently routed track." ), via_xpm ); -static TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia", +static const TOOL_ACTION ACT_PlaceBlindVia( "pcbnew.InteractiveRouter.PlaceBlindVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_BLIND_BURIED_VIA ), _( "Place Blind/Buried Via" ), _( "Adds a blind or buried via at the end of currently routed track."), via_buried_xpm ); -static TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia", +static const TOOL_ACTION ACT_PlaceMicroVia( "pcbnew.InteractiveRouter.PlaceMicroVia", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_ADD_MICROVIA ), _( "Place Microvia" ), _( "Adds a microvia at the end of currently routed track." ), via_microvia_xpm ); -static TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize", +static const TOOL_ACTION ACT_CustomTrackWidth( "pcbnew.InteractiveRouter.CustomTrackViaSize", AS_CONTEXT, 'Q', _( "Custom Track/Via Size" ), _( "Shows a dialog for changing the track width and via size." ), width_track_xpm ); -static TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, +static const TOOL_ACTION ACT_SwitchPosture( "pcbnew.InteractiveRouter.SwitchPosture", AS_CONTEXT, TOOL_ACTION::LegacyHotKey( HK_SWITCH_TRACK_POSTURE ), _( "Switch Track Posture" ), _( "Switches posture of the currently routed track." ), change_entry_orient_xpm ); -static TOOL_ACTION ACT_SetDpDimensions( "pcbnew.InteractiveRouter.SetDpDimensions", +static const TOOL_ACTION ACT_SetDpDimensions( "pcbnew.InteractiveRouter.SetDpDimensions", AS_CONTEXT, 'P', _( "Differential Pair Dimensions..." ), _( "Sets the width and gap of the currently routed differential pair." ), @@ -251,12 +251,6 @@ bool ROUTER_TOOL::Init() void ROUTER_TOOL::Reset( RESET_REASON aReason ) { TOOL_BASE::Reset( aReason ); - - Go( &ROUTER_TOOL::RouteSingleTrace, COMMON_ACTIONS::routerActivateSingle.MakeEvent() ); - Go( &ROUTER_TOOL::RouteDiffPair, COMMON_ACTIONS::routerActivateDiffPair.MakeEvent() ); - Go( &ROUTER_TOOL::DpDimensionsDialog, COMMON_ACTIONS::routerActivateDpDimensionsDialog.MakeEvent() ); - Go( &ROUTER_TOOL::SettingsDialog, COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent() ); - Go( &ROUTER_TOOL::InlineDrag, COMMON_ACTIONS::routerInlineDrag.MakeEvent() ); } @@ -306,46 +300,7 @@ void ROUTER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent ) break; } } - else #endif - if( aEvent.IsAction( &ACT_RouterOptions ) ) - { - DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() ); - - if( settingsDlg.ShowModal() == wxID_OK ) - { - // FIXME: do we need an explicit update? - } - } - else if( aEvent.IsAction( &ACT_SetDpDimensions ) ) - { - PNS::SIZES_SETTINGS sizes = m_router->Sizes(); - DIALOG_PNS_DIFF_PAIR_DIMENSIONS settingsDlg( m_frame, sizes ); - - if( settingsDlg.ShowModal() ) - { - m_router->UpdateSizes( sizes ); - } - } - else if( aEvent.IsAction( &ACT_CustomTrackWidth ) ) - { - BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); - DIALOG_TRACK_VIA_SIZE sizeDlg( m_frame, bds ); - - if( sizeDlg.ShowModal() ) - { - bds.UseCustomTrackViaSize( true ); - m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); - } - } - - else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) ) - { - - PNS::SIZES_SETTINGS sizes( m_router->Sizes() ); - sizes.ImportCurrent( m_board->GetDesignSettings() ); - m_router->UpdateSizes( sizes ); - } } @@ -387,8 +342,19 @@ void ROUTER_TOOL::switchLayerOnViaPlacement() } -bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) +int ROUTER_TOOL::onViaCommand( const TOOL_EVENT& aEvent ) { + VIATYPE_T viaType = VIA_THROUGH; + + if( aEvent.IsAction( &ACT_PlaceThroughVia ) ) + viaType = VIA_THROUGH; + else if( aEvent.IsAction( &ACT_PlaceBlindVia ) ) + viaType = VIA_BLIND_BURIED; + else if( aEvent.IsAction( &ACT_PlaceMicroVia ) ) + viaType = VIA_MICROVIA; + else + wxASSERT_MSG( false, "Unhandled via type" ); + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); const int layerCount = bds.GetCopperLayerCount(); @@ -404,27 +370,27 @@ bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) if( !m_router->IsPlacingVia() ) { // Cannot place microvias or blind vias if not allowed (obvious) - if( ( aType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) + if( ( viaType == VIA_BLIND_BURIED ) && ( !bds.m_BlindBuriedViaAllowed ) ) { DisplayError( m_frame, _( "Blind/buried vias have to be enabled in the design settings." ) ); return false; } - if( ( aType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) + if( ( viaType == VIA_MICROVIA ) && ( !bds.m_MicroViasAllowed ) ) { DisplayError( m_frame, _( "Microvias have to be enabled in the design settings." ) ); return false; } // Can only place through vias on 2-layer boards - if( ( aType != VIA_THROUGH ) && ( layerCount <= 2 ) ) + if( ( viaType != VIA_THROUGH ) && ( layerCount <= 2 ) ) { DisplayError( m_frame, _( "Only through vias are allowed on 2 layer boards." ) ); return false; } // Can only place microvias if we're on an outer layer, or directly adjacent to one - if( ( aType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) ) + if( ( viaType == VIA_MICROVIA ) && ( currentLayer > In1_Cu ) && ( currentLayer < layerCount - 2 ) ) { DisplayError( m_frame, _( "Microvias can be placed only between the outer layers " \ "(F.Cu/B.Cu) and the ones directly adjacent to them." ) ); @@ -433,14 +399,14 @@ bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) } // Convert blind/buried via to a through hole one, if it goes through all layers - if( aType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) ) + if( viaType == VIA_BLIND_BURIED && ( ( currentLayer == B_Cu ) || ( currentLayer == F_Cu ) ) && ( ( pairTop == B_Cu && pairBottom == F_Cu ) || ( pairTop == F_Cu && pairBottom == B_Cu ) ) ) { - aType = VIA_THROUGH; + viaType = VIA_THROUGH; } - switch( aType ) + switch( viaType ) { case VIA_THROUGH: sizes.SetViaDiameter( bds.GetCurrentViaSize() ); @@ -475,7 +441,7 @@ bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) break; } - sizes.SetViaType( aType ); + sizes.SetViaType( viaType ); m_router->UpdateSizes( sizes ); m_router->ToggleViaPlacement(); @@ -484,7 +450,7 @@ bool ROUTER_TOOL::onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ) m_router->Move( m_endSnapPoint, m_endItem ); // refresh - return false; + return 0; } @@ -582,18 +548,6 @@ void ROUTER_TOOL::performRouting() m_router->Move( m_endSnapPoint, m_endItem ); m_startItem = NULL; } - else if( evt->IsAction( &ACT_PlaceThroughVia ) ) - { - onViaCommand( *evt, VIA_THROUGH ); - } - else if( evt->IsAction( &ACT_PlaceBlindVia ) ) - { - onViaCommand( *evt, VIA_BLIND_BURIED ); - } - else if( evt->IsAction( &ACT_PlaceMicroVia ) ) - { - onViaCommand( *evt, VIA_MICROVIA ); - } else if( evt->IsAction( &ACT_SwitchPosture ) ) { m_router->FlipPosture(); @@ -615,8 +569,6 @@ void ROUTER_TOOL::performRouting() } else if( evt->IsCancel() || evt->IsActivate() || evt->IsUndoRedo() ) break; - - handleCommonEvents( *evt ); } finishInteractive(); @@ -647,13 +599,33 @@ int ROUTER_TOOL::SettingsDialog( const TOOL_EVENT& aEvent ) DIALOG_PNS_SETTINGS settingsDlg( m_frame, m_router->Settings() ); if( settingsDlg.ShowModal() ) - { m_savedSettings = m_router->Settings(); - } + return 0; } +void ROUTER_TOOL::SetTransitions() +{ + Go( &ROUTER_TOOL::RouteSingleTrace, COMMON_ACTIONS::routerActivateSingle.MakeEvent() ); + Go( &ROUTER_TOOL::RouteDiffPair, COMMON_ACTIONS::routerActivateDiffPair.MakeEvent() ); + Go( &ROUTER_TOOL::DpDimensionsDialog, COMMON_ACTIONS::routerActivateDpDimensionsDialog.MakeEvent() ); + Go( &ROUTER_TOOL::SettingsDialog, COMMON_ACTIONS::routerActivateSettingsDialog.MakeEvent() ); + Go( &ROUTER_TOOL::InlineDrag, COMMON_ACTIONS::routerInlineDrag.MakeEvent() ); + + Go( &ROUTER_TOOL::onViaCommand, ACT_PlaceThroughVia.MakeEvent() ); + Go( &ROUTER_TOOL::onViaCommand, ACT_PlaceBlindVia.MakeEvent() ); + Go( &ROUTER_TOOL::onViaCommand, ACT_PlaceMicroVia.MakeEvent() ); + + // TODO is not this redundant? the same actions can be used for menus and hotkeys + Go( &ROUTER_TOOL::SettingsDialog, ACT_RouterOptions.MakeEvent() ); + Go( &ROUTER_TOOL::DpDimensionsDialog, ACT_SetDpDimensions.MakeEvent() ); + + Go( &ROUTER_TOOL::CustomTrackWidthDialog, ACT_CustomTrackWidth.MakeEvent() ); + Go( &ROUTER_TOOL::onTrackViaSizeChanged, COMMON_ACTIONS::trackViaSizeChanged.MakeEvent() ); +} + + int ROUTER_TOOL::RouteSingleTrace( const TOOL_EVENT& aEvent ) { m_frame->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Route Track" ) ); @@ -732,8 +704,6 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode ) { deleteTraces( m_startItem, false ); } - - handleCommonEvents( *evt ); } frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); @@ -863,3 +833,28 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent ) return 0; } + + +int ROUTER_TOOL::CustomTrackWidthDialog( const TOOL_EVENT& aEvent ) +{ + BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings(); + DIALOG_TRACK_VIA_SIZE sizeDlg( m_frame, bds ); + + if( sizeDlg.ShowModal() ) + { + bds.UseCustomTrackViaSize( true ); + m_toolMgr->RunAction( COMMON_ACTIONS::trackViaSizeChanged ); + } + + return 0; +} + + +int ROUTER_TOOL::onTrackViaSizeChanged( const TOOL_EVENT& aEvent ) +{ + PNS::SIZES_SETTINGS sizes( m_router->Sizes() ); + sizes.ImportCurrent( m_board->GetDesignSettings() ); + m_router->UpdateSizes( sizes ); + + return 0; +} diff --git a/pcbnew/router/router_tool.h b/pcbnew/router/router_tool.h index c25ca6f442..be9b01a863 100644 --- a/pcbnew/router/router_tool.h +++ b/pcbnew/router/router_tool.h @@ -1,7 +1,7 @@ /* * KiRouter - a push-and-(sometimes-)shove PCB router * - * Copyright (C) 2013-2014 CERN + * Copyright (C) 2013-2017 CERN * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors. * Author: Tomasz Wlostowski * Author: Maciej Suminski @@ -38,11 +38,14 @@ public: int RouteDiffPair( const TOOL_EVENT& aEvent ); int InlineDrag( const TOOL_EVENT& aEvent ); - int DpDimensionsDialog ( const TOOL_EVENT& aEvent ); - int SettingsDialog ( const TOOL_EVENT& aEvent ); + // TODO make this private? + int DpDimensionsDialog( const TOOL_EVENT& aEvent ); + int SettingsDialog( const TOOL_EVENT& aEvent ); + int CustomTrackWidthDialog( const TOOL_EVENT& aEvent ); + + void SetTransitions() override; private: - int mainLoop( PNS::ROUTER_MODE aMode ); int getDefaultWidth( int aNetCode ); @@ -55,7 +58,10 @@ private: int getStartLayer( const PNS::ITEM* aItem ); void switchLayerOnViaPlacement(); - bool onViaCommand( TOOL_EVENT& aEvent, VIATYPE_T aType ); + + int onViaCommand( const TOOL_EVENT& aEvent ); + int onTrackViaSizeChanged( const TOOL_EVENT& aEvent ); + int onLayerChanged( const TOOL_EVENT& aEvent ); bool prepareInteractive(); bool finishInteractive(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 62164ff97f..bdb6549756 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -251,19 +251,10 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent ) { wxPoint modPoint = getModificationPoint( selection ); - if( evt->IsAction( &COMMON_ACTIONS::rotate ) ) + if( evt->IsAction( &COMMON_ACTIONS::remove ) ) { - Rotate( aEvent ); - } - else if( evt->IsAction( &COMMON_ACTIONS::flip ) ) - { - Flip( aEvent ); - } - else if( evt->IsAction( &COMMON_ACTIONS::remove ) ) - { - Remove( aEvent ); - - break; // exit the loop, as there is no further processing for removed items + // exit the loop, as there is no further processing for removed items + break; } else if( evt->IsAction( &COMMON_ACTIONS::duplicate ) ) { @@ -408,6 +399,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) // TODO selectionModified m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true ); + editFrame->Refresh(); return 0; } @@ -438,6 +430,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent ) m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true ); + getEditFrame()->Refresh(); return 0; } diff --git a/pcbnew/tools/point_editor.cpp b/pcbnew/tools/point_editor.cpp index e792869648..dcb58482e3 100644 --- a/pcbnew/tools/point_editor.cpp +++ b/pcbnew/tools/point_editor.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2017 CERN * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -212,8 +212,7 @@ bool POINT_EDITOR::Init() } auto& menu = m_selectionTool->GetToolMenu().GetMenu(); - menu.AddItem( COMMON_ACTIONS::pointEditorAddCorner, - POINT_EDITOR::addCornerCondition ); + menu.AddItem( COMMON_ACTIONS::pointEditorAddCorner, POINT_EDITOR::addCornerCondition ); menu.AddItem( COMMON_ACTIONS::pointEditorRemoveCorner, std::bind( &POINT_EDITOR::removeCornerCondition, this, _1 ) ); @@ -277,22 +276,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) if ( !modified ) updateEditedPoint( *evt ); - if( evt->IsAction( &COMMON_ACTIONS::pointEditorAddCorner ) ) - { - addCorner( controls->GetCursorPosition() ); - updatePoints(); - } - - else if( evt->IsAction( &COMMON_ACTIONS::pointEditorRemoveCorner ) ) - { - if( m_editedPoint ) - { - removeCorner( m_editedPoint ); - updatePoints(); - } - } - - else if( evt->IsDrag( BUT_LEFT ) && m_editedPoint ) + if( evt->IsDrag( BUT_LEFT ) && m_editedPoint ) { if( !modified ) { @@ -320,11 +304,6 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent ) updatePoints(); } - else if( evt->IsAction( &COMMON_ACTIONS::editModifiedSelection ) ) - { - updatePoints(); - } - else if( evt->IsMouseUp( BUT_LEFT ) ) { controls->SetAutoPan( false ); @@ -551,6 +530,9 @@ void POINT_EDITOR::finishItem() const void POINT_EDITOR::updatePoints() { + if( !m_editPoints ) + return; + EDA_ITEM* item = m_editPoints->GetParent(); switch( item->Type() ) @@ -723,125 +705,11 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const } -void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint ) -{ - EDA_ITEM* item = m_editPoints->GetParent(); - PCB_BASE_EDIT_FRAME* frame = getEditFrame(); - BOARD_COMMIT commit( frame ); - - if( item->Type() == PCB_ZONE_AREA_T ) - { - ZONE_CONTAINER* zone = static_cast( item ); - CPolyLine* outline = zone->Outline(); - - commit.Modify( zone ); - - // Handle the last segment, so other segments can be easily handled in a loop - unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0; - SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ), - VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); - unsigned int nearestDist = side.Distance( aBreakPoint ); - - for( int i = 0; i < outline->GetCornersCount() - 1; ++i ) - { - side = SEG( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); - - unsigned int distance = side.Distance( aBreakPoint ); - if( distance < nearestDist ) - { - nearestDist = distance; - nearestIdx = i; - nextNearestIdx = i + 1; - } - } - - // Find the point on the closest segment - VECTOR2I sideOrigin( outline->GetPos( nearestIdx ) ); - VECTOR2I sideEnd( outline->GetPos( nextNearestIdx ) ); - SEG nearestSide( sideOrigin, sideEnd ); - VECTOR2I nearestPoint = nearestSide.NearestPoint( aBreakPoint ); - - // Do not add points that have the same coordinates as ones that already belong to polygon - // instead, add a point in the middle of the side - if( nearestPoint == sideOrigin || nearestPoint == sideEnd ) - nearestPoint = ( sideOrigin + sideEnd ) / 2; - - outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); - - commit.Push( _( "Add a zone corner" ) ); - } - - else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) - { - bool moduleEdge = item->Type() == PCB_MODULE_EDGE_T; - - DRAWSEGMENT* segment = static_cast( item ); - - if( segment->GetShape() == S_SEGMENT ) - { - commit.Modify( segment ); - - SEG seg( segment->GetStart(), segment->GetEnd() ); - VECTOR2I nearestPoint = seg.NearestPoint( aBreakPoint ); - - // Move the end of the line to the break point.. - segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) ); - - // and add another one starting from the break point - DRAWSEGMENT* newSegment; - - if( moduleEdge ) - { - EDGE_MODULE* edge = static_cast( segment ); - assert( edge->Type() == PCB_MODULE_EDGE_T ); - assert( edge->GetParent()->Type() == PCB_MODULE_T ); - newSegment = new EDGE_MODULE( *edge ); - } - else - { - newSegment = new DRAWSEGMENT( *segment ); - } - - newSegment->ClearSelected(); - newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) ); - newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) ); - - commit.Add( newSegment ); - commit.Push( _( "Split segment" ) ); - } - } -} - - -void POINT_EDITOR::removeCorner( EDIT_POINT* aPoint ) -{ - EDA_ITEM* item = m_editPoints->GetParent(); - - if( item->Type() == PCB_ZONE_AREA_T ) - { - PCB_BASE_FRAME* frame = getEditFrame(); - BOARD_COMMIT commit( frame ); - - ZONE_CONTAINER* zone = static_cast( item ); - CPolyLine* outline = zone->Outline(); - commit.Modify( zone ); - - for( int i = 0; i < outline->GetCornersCount(); ++i ) - { - if( VECTOR2I( outline->GetPos( i ) ) == aPoint->GetPosition() ) - { - outline->DeleteCorner( i ); - setEditedPoint( NULL ); - commit.Push( _( "Remove a zone corner" ) ); - break; - } - } - } -} - - void POINT_EDITOR::SetTransitions() { + Go( &POINT_EDITOR::addCorner, COMMON_ACTIONS::pointEditorAddCorner.MakeEvent() ); + Go( &POINT_EDITOR::removeCorner, COMMON_ACTIONS::pointEditorRemoveCorner.MakeEvent() ); + Go( &POINT_EDITOR::modifiedSelection, COMMON_ACTIONS::editModifiedSelection.MakeEvent() ); Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::SelectedEvent ); Go( &POINT_EDITOR::OnSelectionChange, SELECTION_TOOL::UnselectedEvent ); } @@ -882,3 +750,137 @@ bool POINT_EDITOR::removeCornerCondition( const SELECTION& ) return m_editedPoint != NULL; } + + +int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent ) +{ + EDA_ITEM* item = m_editPoints->GetParent(); + PCB_BASE_EDIT_FRAME* frame = getEditFrame(); + const VECTOR2I& cursorPos = getViewControls()->GetCursorPosition(); + BOARD_COMMIT commit( frame ); + + if( item->Type() == PCB_ZONE_AREA_T ) + { + ZONE_CONTAINER* zone = static_cast( item ); + CPolyLine* outline = zone->Outline(); + + commit.Modify( zone ); + + // Handle the last segment, so other segments can be easily handled in a loop + unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0; + SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ), + VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); + unsigned int nearestDist = side.Distance( cursorPos ); + + for( int i = 0; i < outline->GetCornersCount() - 1; ++i ) + { + side = SEG( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); + + unsigned int distance = side.Distance( cursorPos ); + if( distance < nearestDist ) + { + nearestDist = distance; + nearestIdx = i; + nextNearestIdx = i + 1; + } + } + + // Find the point on the closest segment + VECTOR2I sideOrigin( outline->GetPos( nearestIdx ) ); + VECTOR2I sideEnd( outline->GetPos( nextNearestIdx ) ); + SEG nearestSide( sideOrigin, sideEnd ); + VECTOR2I nearestPoint = nearestSide.NearestPoint( cursorPos ); + + // Do not add points that have the same coordinates as ones that already belong to polygon + // instead, add a point in the middle of the side + if( nearestPoint == sideOrigin || nearestPoint == sideEnd ) + nearestPoint = ( sideOrigin + sideEnd ) / 2; + + outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); + + commit.Push( _( "Add a zone corner" ) ); + } + + else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) + { + bool moduleEdge = item->Type() == PCB_MODULE_EDGE_T; + + DRAWSEGMENT* segment = static_cast( item ); + + if( segment->GetShape() == S_SEGMENT ) + { + commit.Modify( segment ); + + SEG seg( segment->GetStart(), segment->GetEnd() ); + VECTOR2I nearestPoint = seg.NearestPoint( cursorPos ); + + // Move the end of the line to the break point.. + segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) ); + + // and add another one starting from the break point + DRAWSEGMENT* newSegment; + + if( moduleEdge ) + { + EDGE_MODULE* edge = static_cast( segment ); + assert( edge->Type() == PCB_MODULE_EDGE_T ); + assert( edge->GetParent()->Type() == PCB_MODULE_T ); + newSegment = new EDGE_MODULE( *edge ); + } + else + { + newSegment = new DRAWSEGMENT( *segment ); + } + + newSegment->ClearSelected(); + newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) ); + newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) ); + + commit.Add( newSegment ); + commit.Push( _( "Split segment" ) ); + } + } + updatePoints(); + return 0; +} + + +int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent ) +{ + if( !m_editedPoint ) + return 0; + + EDA_ITEM* item = m_editPoints->GetParent(); + + if( item->Type() == PCB_ZONE_AREA_T ) + { + PCB_BASE_FRAME* frame = getEditFrame(); + BOARD_COMMIT commit( frame ); + + ZONE_CONTAINER* zone = static_cast( item ); + CPolyLine* outline = zone->Outline(); + commit.Modify( zone ); + + for( int i = 0; i < outline->GetCornersCount(); ++i ) + { + if( VECTOR2I( outline->GetPos( i ) ) == m_editedPoint->GetPosition() ) + { + outline->DeleteCorner( i ); + setEditedPoint( NULL ); + commit.Push( _( "Remove a zone corner" ) ); + break; + } + } + + updatePoints(); + } + + return 0; +} + + +int POINT_EDITOR::modifiedSelection( const TOOL_EVENT& aEvent ) +{ + updatePoints(); + return 0; +} diff --git a/pcbnew/tools/point_editor.h b/pcbnew/tools/point_editor.h index 2dbe1330b3..cc3e7bf129 100644 --- a/pcbnew/tools/point_editor.h +++ b/pcbnew/tools/point_editor.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2017 CERN * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -116,6 +116,11 @@ private: ///> Condition to display "Remove corner" context menu entry. bool removeCornerCondition( const SELECTION& aSelection ); + + /// TOOL_ACTION handlers + int addCorner( const TOOL_EVENT& aEvent ); + int removeCorner( const TOOL_EVENT& aEvent ); + int modifiedSelection( const TOOL_EVENT& aEvent ); }; #endif diff --git a/pcbnew/tools/selection_tool.cpp b/pcbnew/tools/selection_tool.cpp index 64a16ed4f2..f4f4ea5af4 100644 --- a/pcbnew/tools/selection_tool.cpp +++ b/pcbnew/tools/selection_tool.cpp @@ -217,52 +217,11 @@ int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent ) } } - else if( evt->IsAction( &COMMON_ACTIONS::selectionCursor ) ) - { - selectCursor( true ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::find ) ) - { - find( *evt ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::findMove ) ) - { - findMove( *evt ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::selectItem ) ) - { - SelectItem( *evt ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::unselectItem ) ) - { - UnselectItem( *evt ); - } - - else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE || - evt->IsAction( &COMMON_ACTIONS::selectionClear ) ) + else if( evt->IsCancel() || evt->Action() == TA_UNDO_REDO_PRE ) { clearSelection(); } - else if( evt->IsAction( &COMMON_ACTIONS::selectConnection ) ) - { - selectConnection( *evt ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::selectCopper ) ) - { - selectCopper( *evt ); - } - - else if( evt->IsAction( &COMMON_ACTIONS::selectNet ) ) - { - selectNet( *evt ); - } - else if( evt->Action() == TA_CONTEXT_MENU_CLOSED ) { if( m_preliminary )