diff --git a/common/tool/actions.cpp b/common/tool/actions.cpp index 09de585c1e..1e01320538 100644 --- a/common/tool/actions.cpp +++ b/common/tool/actions.cpp @@ -697,3 +697,8 @@ const TOOL_EVENT EVENTS::InhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common const TOOL_EVENT EVENTS::UninhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common.Interactive.uninhibit" ); const TOOL_EVENT EVENTS::DisambiguatePoint( TC_MESSAGE, TA_ACTION, "common.Interactive.disambiguate" ); + +// System-wide undo/redo Events + +const TOOL_EVENT EVENTS::UndoRedoPreEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL ); +const TOOL_EVENT EVENTS::UndoRedoPostEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL ); diff --git a/include/tool/actions.h b/include/tool/actions.h index afe1b1db67..ffbfd9843f 100644 --- a/include/tool/actions.h +++ b/include/tool/actions.h @@ -221,6 +221,10 @@ public: ///< Used to inform tool that it should display the disambiguation menu const static TOOL_EVENT DisambiguatePoint; + + const static TOOL_EVENT UndoRedoPreEvent; + const static TOOL_EVENT UndoRedoPostEvent; + }; #endif // __ACTIONS_H diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 637b1841f7..45f03be006 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -1111,7 +1111,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer ) VECTOR2D position = padBBox.Centre(); VECTOR2D padsize = VECTOR2D( padBBox.GetSize() ); - if( aPad->GetFlags() & ENTERED ) + if( aPad->IsEntered() ) { FOOTPRINT* fp = static_cast( aPad->GetParentFootprint() ); diff --git a/pcbnew/tools/pad_tool.cpp b/pcbnew/tools/pad_tool.cpp index d372227f89..dac6ee9c97 100644 --- a/pcbnew/tools/pad_tool.cpp +++ b/pcbnew/tools/pad_tool.cpp @@ -581,10 +581,9 @@ int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent ) return 0; PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); - PCB_RENDER_SETTINGS* settings = static_cast( view()->GetPainter()->GetSettings() ); - WX_INFOBAR* infoBar = frame()->GetInfoBar(); + KIGFX::PCB_PAINTER* painter = static_cast( view()->GetPainter() ); + PCB_RENDER_SETTINGS* settings = painter->GetSettings(); PCB_SELECTION& selection = m_toolMgr->GetTool()->GetSelection(); - wxString msg; if( m_editPad != niluuid ) { @@ -604,65 +603,117 @@ int PAD_TOOL::EditPad( const TOOL_EVENT& aEvent ) PAD* pad = static_cast( selection[0] ); PCB_LAYER_ID layer = explodePad( pad ); + m_editPad = pad->m_Uuid; + m_wasHighContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ); frame()->SetActiveLayer( layer ); settings->m_PadEditModePad = pad; - - canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT, - [&]( KIGFX::VIEW_ITEM* aItem ) -> bool - { - return dynamic_cast( aItem ) != nullptr; - } ); - - if( !m_wasHighContrast ) - m_toolMgr->RunAction( ACTIONS::highContrastMode, true ); - - if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() ) - { - msg.Printf( _( "Pad Edit Mode. Press %s again to exit." ), - KeyNameFromKeyCode( PCB_ACTIONS::recombinePad.GetHotKey() ) ); - } - else - { - msg.Printf( _( "Pad Edit Mode. Press %s to exit." ), - KeyNameFromKeyCode( PCB_ACTIONS::recombinePad.GetHotKey() ) ); - } - - infoBar->RemoveAllButtons(); - infoBar->ShowMessage( msg, wxICON_INFORMATION ); - - m_editPad = pad->m_Uuid; + enterPadEditMode(); } if( m_editPad == niluuid ) { - bool highContrast = ( opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL ); - - if( m_wasHighContrast != highContrast ) - m_toolMgr->RunAction( ACTIONS::highContrastMode, true ); - settings->m_PadEditModePad = nullptr; - - // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as - // they won't be found in the view layer's itemset for re-painting. - canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::ALL, - [&]( KIGFX::VIEW_ITEM* aItem ) -> bool - { - return dynamic_cast( aItem ) != nullptr; - } ); - - // Refresh now (otherwise there's an uncomfortably long pause while the infoBar - // closes before refresh). - canvas()->ForceRefresh(); - - infoBar->Dismiss(); + exitPadEditMode(); } return 0; } +int PAD_TOOL::OnUndoRedo( const TOOL_EVENT& aEvent ) +{ + PAD* flaggedPad = nullptr; + KIID flaggedPadId = niluuid; + + for( FOOTPRINT* fp : board()->Footprints() ) + { + for( PAD* pad : fp->Pads() ) + { + if( pad->IsEntered() ) + { + flaggedPad = pad; + flaggedPadId = pad->m_Uuid; + break; + } + } + } + + if( flaggedPadId != m_editPad ) + { + KIGFX::PCB_PAINTER* painter = static_cast( view()->GetPainter() ); + PCB_RENDER_SETTINGS* settings = painter->GetSettings(); + + m_editPad = flaggedPadId; + settings->m_PadEditModePad = flaggedPad; + + if( flaggedPad ) + enterPadEditMode(); + else + exitPadEditMode(); + } + + return 0; +} + + +void PAD_TOOL::enterPadEditMode() +{ + PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); + bool highContrast = opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL; + WX_INFOBAR* infoBar = frame()->GetInfoBar(); + wxString msg; + + canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::REPAINT, + [&]( KIGFX::VIEW_ITEM* aItem ) -> bool + { + return dynamic_cast( aItem ) != nullptr; + } ); + + if( !highContrast ) + m_toolMgr->RunAction( ACTIONS::highContrastMode, true ); + + if( PCB_ACTIONS::explodePad.GetHotKey() == PCB_ACTIONS::recombinePad.GetHotKey() ) + { + msg.Printf( _( "Pad Edit Mode. Press %s again to exit." ), + KeyNameFromKeyCode( PCB_ACTIONS::recombinePad.GetHotKey() ) ); + } + else + { + msg.Printf( _( "Pad Edit Mode. Press %s to exit." ), + KeyNameFromKeyCode( PCB_ACTIONS::recombinePad.GetHotKey() ) ); + } + + infoBar->RemoveAllButtons(); + infoBar->ShowMessage( msg, wxICON_INFORMATION ); +} + + +void PAD_TOOL::exitPadEditMode() +{ + PCB_DISPLAY_OPTIONS opts = frame()->GetDisplayOptions(); + bool highContrast = opts.m_ContrastModeDisplay != HIGH_CONTRAST_MODE::NORMAL; + + if( m_wasHighContrast != highContrast ) + m_toolMgr->RunAction( ACTIONS::highContrastMode, true ); + + // Note: KIGFX::REPAINT isn't enough for things that go from invisible to visible as + // they won't be found in the view layer's itemset for re-painting. + canvas()->GetView()->UpdateAllItemsConditionally( KIGFX::ALL, + [&]( KIGFX::VIEW_ITEM* aItem ) -> bool + { + return dynamic_cast( aItem ) != nullptr; + } ); + + // Refresh now (otherwise there's an uncomfortably long pause while the infoBar + // closes before refresh). + canvas()->ForceRefresh(); + + frame()->GetInfoBar()->Dismiss(); +} + + PCB_LAYER_ID PAD_TOOL::explodePad( PAD* aPad ) { PCB_LAYER_ID layer; @@ -932,4 +983,6 @@ void PAD_TOOL::setTransitions() Go( &PAD_TOOL::EditPad, PCB_ACTIONS::explodePad.MakeEvent() ); Go( &PAD_TOOL::EditPad, PCB_ACTIONS::recombinePad.MakeEvent() ); + + Go( &PAD_TOOL::OnUndoRedo, EVENTS::UndoRedoPostEvent ); } diff --git a/pcbnew/tools/pad_tool.h b/pcbnew/tools/pad_tool.h index 6b2964a3b5..4a332ffb63 100644 --- a/pcbnew/tools/pad_tool.h +++ b/pcbnew/tools/pad_tool.h @@ -60,6 +60,8 @@ public: */ int EditPad( const TOOL_EVENT& aEvent ); + int OnUndoRedo( const TOOL_EVENT& aEvent ); + bool InPadEditMode() { return m_editPad != niluuid; } wxString GetLastPadNumber() const { return m_lastPadNumber; } @@ -89,6 +91,9 @@ private: PCB_LAYER_ID explodePad( PAD* aPad ); + void enterPadEditMode(); + void exitPadEditMode(); + private: wxString m_lastPadNumber; diff --git a/pcbnew/tools/pcb_point_editor.cpp b/pcbnew/tools/pcb_point_editor.cpp index cc5d2448a6..c266a2e1b9 100644 --- a/pcbnew/tools/pcb_point_editor.cpp +++ b/pcbnew/tools/pcb_point_editor.cpp @@ -1285,7 +1285,7 @@ void PCB_POINT_EDITOR::updateItem() const { for( PAD* pad : fpShape->GetParentFootprint()->Pads() ) { - if( pad->GetFlags() & ENTERED ) + if( pad->IsEntered() ) view()->Update( pad ); } } diff --git a/pcbnew/tools/pcb_selection_tool.cpp b/pcbnew/tools/pcb_selection_tool.cpp index be41115a6c..55bb08c0d0 100644 --- a/pcbnew/tools/pcb_selection_tool.cpp +++ b/pcbnew/tools/pcb_selection_tool.cpp @@ -2329,14 +2329,17 @@ void PCB_SELECTION_TOOL::RebuildSelection() highlight( item, SELECTED, &m_selection ); } - if( item == m_enteredGroup ) + if( item->Type() == PCB_GROUP_T ) { - item->SetFlags( ENTERED ); - enteredGroupFound = true; - } - else - { - item->ClearFlags( ENTERED ); + if( item == m_enteredGroup ) + { + item->SetFlags( ENTERED ); + enteredGroupFound = true; + } + else + { + item->ClearFlags( ENTERED ); + } } return INSPECT_RESULT::CONTINUE; diff --git a/pcbnew/undo_redo.cpp b/pcbnew/undo_redo.cpp index af9404d550..ed1bb396e6 100644 --- a/pcbnew/undo_redo.cpp +++ b/pcbnew/undo_redo.cpp @@ -353,7 +353,7 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) return; // Inform tools that redo command was issued - m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_PRE, AS_GLOBAL } ); + m_toolManager->ProcessEvent( EVENTS::UndoRedoPreEvent ); // Get the old list PICKED_ITEMS_LIST* list = PopCommandFromRedoList(); @@ -367,7 +367,7 @@ void PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent ) OnModify(); - m_toolManager->ProcessEvent( { TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL } ); + m_toolManager->ProcessEvent( EVENTS::UndoRedoPostEvent ); m_toolManager->PostEvent( EVENTS::SelectedItemsModified ); GetCanvas()->Refresh();