From 30bb9111540038c6f65dcd6ce52b9dc903c151d3 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Wed, 22 Aug 2018 19:05:40 +0100 Subject: [PATCH] Bring PICKER_TOOL in line with other tools. Use standard Magnetize() to handle grid and magnetic pads. Use the standard menu from PCB_TOOL. Delegating the menu to the SELECTION_TOOL just caused grief. Also brings clients (such as Position Relative To) into line, and implements better Cancel behaviour. Also improves visibility of modal status messages: - moves Select Anchor message from status bar to popup - moves Select Reference message from dialog to popup Fixes: lp:1786727 * https://bugs.launchpad.net/kicad/+bug/1786727 --- common/status_popup.cpp | 2 + pcbnew/dialogs/dialog_position_relative.cpp | 19 ++-- pcbnew/dialogs/dialog_position_relative.h | 5 +- pcbnew/router/pns_tune_status_popup.cpp | 7 -- pcbnew/router/pns_tune_status_popup.h | 4 +- pcbnew/tools/drawing_tool.h | 5 - pcbnew/tools/edit_tool.cpp | 89 ++++++++------- pcbnew/tools/edit_tool.h | 4 + pcbnew/tools/pcb_actions.h | 3 - pcbnew/tools/picker_tool.cpp | 71 ++++++------ pcbnew/tools/picker_tool.h | 38 +++---- pcbnew/tools/position_relative_tool.cpp | 116 ++++++++++---------- pcbnew/tools/position_relative_tool.h | 35 +----- 13 files changed, 185 insertions(+), 213 deletions(-) diff --git a/common/status_popup.cpp b/common/status_popup.cpp index 0d81db3b8a..a3fe9cc720 100644 --- a/common/status_popup.cpp +++ b/common/status_popup.cpp @@ -101,6 +101,8 @@ void STATUS_POPUP::onExpire( wxTimerEvent& aEvent ) STATUS_TEXT_POPUP::STATUS_TEXT_POPUP( EDA_DRAW_FRAME* aParent ) : STATUS_POPUP( aParent ) { + m_panel->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW ) ); + m_statusLine = new wxStaticText( m_panel, wxID_ANY, wxEmptyString ) ; m_topSizer->Add( m_statusLine, 1, wxALL | wxEXPAND, 5 ); } diff --git a/pcbnew/dialogs/dialog_position_relative.cpp b/pcbnew/dialogs/dialog_position_relative.cpp index bfd28b98cd..0c2d9e5ed3 100644 --- a/pcbnew/dialogs/dialog_position_relative.cpp +++ b/pcbnew/dialogs/dialog_position_relative.cpp @@ -30,12 +30,12 @@ DIALOG_POSITION_RELATIVE::POSITION_RELATIVE_OPTIONS DIALOG_POSITION_RELATIVE::m_options; -DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, TOOL_MANAGER* toolMgr, - wxPoint& translation, wxPoint& anchorPosition ) : +DIALOG_POSITION_RELATIVE::DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxPoint& translation, + wxPoint& anchor ) : DIALOG_POSITION_RELATIVE_BASE( aParent ), - m_toolMgr( toolMgr ), + m_toolMgr( aParent->GetToolManager() ), m_translation( translation ), - m_anchor_position( anchorPosition ), + m_anchor_position( anchor ), m_xOffset( aParent, m_xLabel, m_xEntry, m_xUnit ), m_yOffset( aParent, m_yLabel, m_yEntry, m_yUnit ) { @@ -115,7 +115,6 @@ void DIALOG_POSITION_RELATIVE::OnPolarChanged( wxCommandEvent& event ) m_xOffset.SetValue( KiROUND( val.x / 10.0 ) * 10 ); m_yOffset.SetValue( KiROUND( val.y / 10.0 ) * 10 ); } - } @@ -157,25 +156,25 @@ void DIALOG_POSITION_RELATIVE::OnSelectItemClick( wxCommandEvent& event ) POSITION_RELATIVE_TOOL* posrelTool = m_toolMgr->GetTool(); wxASSERT( posrelTool ); - - m_referenceInfo->SetLabel( _( "Reference item: " ) ); m_toolMgr->RunAction( PCB_ACTIONS::selectpositionRelativeItem, true ); + + Hide(); } -void DIALOG_POSITION_RELATIVE::UpdateAnchor( BOARD_ITEM* aItem ) +void DIALOG_POSITION_RELATIVE::UpdateAnchor( EDA_ITEM* aItem ) { wxString reference = _( "" ); if( aItem ) { - m_anchor_position = aItem->GetPosition(); + m_anchor_position = dynamic_cast( aItem )->GetPosition(); reference = aItem->GetSelectMenuText( GetUserUnits() ); } m_referenceInfo->SetLabel( _( "Reference item: " ) + reference ); - Raise(); // required at least on OSX + Show( true ); } diff --git a/pcbnew/dialogs/dialog_position_relative.h b/pcbnew/dialogs/dialog_position_relative.h index 7882ad778b..aee4754bfb 100644 --- a/pcbnew/dialogs/dialog_position_relative.h +++ b/pcbnew/dialogs/dialog_position_relative.h @@ -45,11 +45,10 @@ private: public: // Constructor and destructor - DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, TOOL_MANAGER* toolMgr, - wxPoint& translation, wxPoint& anchorposition ); + DIALOG_POSITION_RELATIVE( PCB_BASE_FRAME* aParent, wxPoint& translation, wxPoint& anchor ); ~DIALOG_POSITION_RELATIVE() { }; - void UpdateAnchor( BOARD_ITEM* aItem ); + void UpdateAnchor( EDA_ITEM* aItem ); private: diff --git a/pcbnew/router/pns_tune_status_popup.cpp b/pcbnew/router/pns_tune_status_popup.cpp index 454ea2d50b..5c4c283d2c 100644 --- a/pcbnew/router/pns_tune_status_popup.cpp +++ b/pcbnew/router/pns_tune_status_popup.cpp @@ -24,13 +24,6 @@ #include "pns_router.h" #include "pns_meander_placer.h" -PNS_TUNE_STATUS_POPUP::PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent ) : - STATUS_TEXT_POPUP( aParent ) -{ - m_panel->SetBackgroundColour( wxColour( 64, 64, 64 ) ); -} - - void PNS_TUNE_STATUS_POPUP::UpdateStatus( PNS::ROUTER* aRouter ) { PNS::MEANDER_PLACER_BASE* placer = dynamic_cast( aRouter->Placer() ); diff --git a/pcbnew/router/pns_tune_status_popup.h b/pcbnew/router/pns_tune_status_popup.h index 76c5c79b7c..94f171d460 100644 --- a/pcbnew/router/pns_tune_status_popup.h +++ b/pcbnew/router/pns_tune_status_popup.h @@ -37,7 +37,9 @@ class ROUTER; class PNS_TUNE_STATUS_POPUP : public STATUS_TEXT_POPUP { public: - PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent ); + PNS_TUNE_STATUS_POPUP( EDA_DRAW_FRAME* aParent ) : + STATUS_TEXT_POPUP( aParent ) + { } void UpdateStatus( PNS::ROUTER* aRouter ); }; diff --git a/pcbnew/tools/drawing_tool.h b/pcbnew/tools/drawing_tool.h index 9193164843..df5b883c9b 100644 --- a/pcbnew/tools/drawing_tool.h +++ b/pcbnew/tools/drawing_tool.h @@ -192,11 +192,6 @@ private: GRAPHIC_POLYGON }; - ///> Shows the context menu for the drawing tool - ///> This menu consists of normal UI functions (zoom, grid, etc) - ///> And any suitable global functions for the active drawing type. - void showContextMenu(); - ///> Starts drawing a selected shape (i.e. DRAWSEGMENT). ///> @param aShape is the type of created shape (@see STROKE_T). ///> @param aGraphic is an object that is going to be used by the tool for drawing. It has to diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index da2a463f22..5f93f3afcd 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -37,7 +37,7 @@ #include #include #include - +#include #include #include #include @@ -83,22 +83,6 @@ TOOL_ACTION PCB_ACTIONS::editFootprintInFpEditor( "pcbnew.InteractiveEdit.editFo _( "Opens the selected footprint in the Footprint Editor" ), module_editor_xpm ); -TOOL_ACTION PCB_ACTIONS::copyPadToSettings( "pcbnew.InteractiveEdit.copyPadToSettings", - AS_GLOBAL, 0, - _( "Copy Pad Properties to Default Pad Properties" ), - _( "Copies the properties of the selected pad to the default pad properties." ) ); - -TOOL_ACTION PCB_ACTIONS::copySettingsToPads( "pcbnew.InteractiveEdit.copySettingsToPads", - AS_GLOBAL, 0, - _( "Copy Default Pad Properties to Pads" ), - _( "Copies the default pad properties to the selected pad(s)." ) ); - -TOOL_ACTION PCB_ACTIONS::globalEditPads( "pcbnew.InteractiveEdit.globalPadEdit", - AS_GLOBAL, 0, - _( "Push Pad Settings..." ), - _( "Copies the selected pad's properties to all pads in its footprint (or similar footprints)." ), - push_pad_settings_xpm ); - TOOL_ACTION PCB_ACTIONS::editActivate( "pcbnew.InteractiveEdit", AS_GLOBAL, 0, _( "Edit Activate" ), "", move_xpm, AF_ACTIVATE ); @@ -1395,47 +1379,66 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent ) bool EDIT_TOOL::pickCopyReferencePoint( VECTOR2I& aP ) { + STATUS_TEXT_POPUP statusPopup( frame() ); PICKER_TOOL* picker = m_toolMgr->GetTool(); - assert( picker ); + bool picking = true; + bool retVal = true; + statusPopup.SetText( _( "Select reference point for the copy..." ) ); picker->Activate(); + picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool + { + aP = aPoint; + statusPopup.SetText( _( "Selection copied." ) ); + statusPopup.Expire( 800 ); + picking = false; + return false; // we don't need any more points + } ); + picker->SetCancelHandler( [&]() + { + statusPopup.SetText( _( "Copy cancelled." ) ); + statusPopup.Expire( 800 ); + picking = false; + retVal = false; + } ); - while ( picker->IsPicking() ) + statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); + statusPopup.Popup(); + + while( picking ) + { + statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); Wait(); + } - if( !picker->GetPoint() ) - return false; - - aP = *picker->GetPoint(); - return true; + statusPopup.Hide(); + return retVal; } -int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent ) +int EDIT_TOOL::doCopyToClipboard( bool withAnchor ) { CLIPBOARD_IO io; - VECTOR2I refPoint; Activate(); - auto item1 = MSG_PANEL_ITEM( "", _( "Select reference point for the block being copied..." ), - COLOR4D::BLACK ); - - std::vector msgItems = { item1 }; - SELECTION& selection = m_selectionTool->RequestSelection( m_defaultSelectionFilter ); if( selection.Empty() ) return 1; - frame()->SetMsgPanel( msgItems ); - bool rv = pickCopyReferencePoint( refPoint ); - frame()->SetMsgPanel( board() ); + if( withAnchor ) + { + VECTOR2I refPoint; + bool rv = pickCopyReferencePoint( refPoint ); + frame()->SetMsgPanel( board() ); - if( !rv ) - return 1; + if( !rv ) + return 1; + + selection.SetReferencePoint( refPoint ); + } - selection.SetReferencePoint( refPoint ); io.SetBoard( board() ); io.SaveSelection( selection ); @@ -1443,6 +1446,18 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent ) } +int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent ) +{ + return doCopyToClipboard( true ); +} + + +int EDIT_TOOL::copyToClipboardWithAnchor( const TOOL_EVENT& aEvent ) +{ + return doCopyToClipboard( true ); +} + + int EDIT_TOOL::cutToClipboard( const TOOL_EVENT& aEvent ) { if( !copyToClipboard( aEvent ) ) diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index 2b620baae6..d5454adbaa 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -168,6 +168,10 @@ public: */ int copyToClipboard( const TOOL_EVENT& aEvent ); + int copyToClipboardWithAnchor( const TOOL_EVENT& aEvent ); + + int doCopyToClipboard( bool withAnchor ); + /** * Function cutToClipboard() * Cuts the current selection to the clipboard by formatting it as a fake pcb diff --git a/pcbnew/tools/pcb_actions.h b/pcbnew/tools/pcb_actions.h index b7ebf859dc..987adbfdc0 100644 --- a/pcbnew/tools/pcb_actions.h +++ b/pcbnew/tools/pcb_actions.h @@ -402,9 +402,6 @@ public: static TOOL_ACTION findMove; static TOOL_ACTION editFootprintInFpEditor; - static TOOL_ACTION copyPadToSettings; - static TOOL_ACTION copySettingsToPads; - static TOOL_ACTION globalEditPads; ///> @copydoc COMMON_ACTIONS::TranslateLegacyId() diff --git a/pcbnew/tools/picker_tool.cpp b/pcbnew/tools/picker_tool.cpp index 135f8a4fc3..a11fa4d9be 100644 --- a/pcbnew/tools/picker_tool.cpp +++ b/pcbnew/tools/picker_tool.cpp @@ -25,7 +25,7 @@ #include "picker_tool.h" #include "pcb_actions.h" #include "grid_helper.h" - +#include #include #include #include @@ -33,6 +33,10 @@ #include "selection_tool.h" +extern bool Magnetize( PCB_BASE_EDIT_FRAME* frame, int aCurrentTool, + wxSize aGridSize, wxPoint on_grid, wxPoint* curpos ); + + TOOL_ACTION PCB_ACTIONS::pickerTool( "pcbnew.Picker", AS_GLOBAL, 0, "", "", NULL, AF_ACTIVATE ); @@ -43,51 +47,34 @@ PICKER_TOOL::PICKER_TOOL() } -bool PICKER_TOOL::Init() -{ - auto activeToolCondition = [ this ] ( const SELECTION& aSel ) { - return ( frame()->GetToolId() != ID_NO_TOOL_SELECTED ); - }; - - SELECTION_TOOL* selTool = m_toolMgr->GetTool(); - - // We delegate our context menu to the Selection tool, so make sure it has a - // "Cancel" item at the top. - if( selTool ) - { - auto& toolMenu = selTool->GetToolMenu(); - auto& menu = toolMenu.GetMenu(); - - menu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1000 ); - menu.AddSeparator( activeToolCondition, 1000 ); - } - - return true; -} - - int PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) { KIGFX::VIEW_CONTROLS* controls = getViewControls(); GRID_HELPER grid( frame() ); - assert( !m_picking ); - m_picking = true; - m_picked = NULLOPT; - setControls(); while( OPT_TOOL_EVENT evt = Wait() ) { - auto mousePos = controls->GetMousePosition(); - auto p = grid.BestSnapAnchor( mousePos, nullptr ); - controls->ForceCursorPosition( true, p ); + // TODO: magnetic pad & track processing needs to move to VIEW_CONTROLS. + wxPoint pos( controls->GetMousePosition().x, controls->GetMousePosition().y ); + frame()->SetMousePosition( pos ); + + wxRealPoint gridSize = frame()->GetScreen()->GetGridSize(); + wxSize igridsize; + igridsize.x = KiROUND( gridSize.x ); + igridsize.y = KiROUND( gridSize.y ); + + if( Magnetize( frame(), ID_PCB_HIGHLIGHT_BUTT, igridsize, pos, &pos ) ) + controls->ForceCursorPosition( true, pos ); + else + controls->ForceCursorPosition( false ); if( evt->IsClick( BUT_LEFT ) ) { bool getNext = false; - m_picked = VECTOR2D( p ); + m_picked = VECTOR2D( controls->GetCursorPosition() ); if( m_clickHandler ) { @@ -109,7 +96,24 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) } else if( evt->IsCancel() || TOOL_EVT_UTILS::IsCancelInteractive( *evt ) || evt->IsActivate() ) + { + if( m_cancelHandler ) + { + try + { + (*m_cancelHandler)(); + } + catch( std::exception& e ) + { + std::cerr << "PICKER_TOOL cancel handler error: " << e.what() << std::endl; + } + } + break; + } + + else if( evt->IsClick( BUT_RIGHT ) ) + m_menu.ShowContextMenu(); else m_toolMgr->PassEvent(); @@ -136,8 +140,9 @@ void PICKER_TOOL::reset() m_cursorCapture = false; m_autoPanning = false; - m_picking = false; + m_picked = NULLOPT; m_clickHandler = NULLOPT; + m_cancelHandler = NULLOPT; } diff --git a/pcbnew/tools/picker_tool.h b/pcbnew/tools/picker_tool.h index f92c01b580..7adb3a9ef4 100644 --- a/pcbnew/tools/picker_tool.h +++ b/pcbnew/tools/picker_tool.h @@ -37,11 +37,9 @@ public: PICKER_TOOL(); ~PICKER_TOOL() {} - ///> Mouse event click handler type. + ///> Event handler types. typedef std::function CLICK_HANDLER; - - /// @copydoc TOOL_INTERACTIVE::Init() - bool Init() override; + typedef std::function CANCEL_HANDLER; ///> @copydoc TOOL_INTERACTIVE::Reset() void Reset( RESET_REASON aReason ) override {} @@ -73,22 +71,6 @@ public: */ inline void SetCursorCapture( bool aEnable ) { m_cursorCapture = aEnable; } - /** - * Function GetPoint() - * Returns picked point. - */ - inline OPT GetPoint() const - { - assert( !m_picking ); - return m_picked; - } - - /** - * Function IsPicking() - * Returns information whether the tool is still active. - */ - bool IsPicking() const { return m_picking; } - /** * Function SetClickHandler() * Sets a handler for mouse click event. Handler may decide to receive further click by @@ -100,6 +82,16 @@ public: m_clickHandler = aHandler; } + /** + * Function SetCancelHandler() + * Sets a handler for cancel events (ESC or context-menu Cancel). + */ + inline void SetCancelHandler( CANCEL_HANDLER aHandler ) + { + assert( !m_cancelHandler ); + m_cancelHandler = aHandler; + } + ///> @copydoc TOOL_INTERACTIVE::setTransitions(); void setTransitions() override; @@ -110,15 +102,13 @@ private: bool m_cursorCapture; bool m_autoPanning; - ///> Optional mouse click event handler. + ///> Optional event handlers. OPT m_clickHandler; + OPT m_cancelHandler; ///> Picked point (if any). OPT m_picked; - ///> Activity status. - bool m_picking; - ///> Reinitializes tool to its initial state. void reset(); diff --git a/pcbnew/tools/position_relative_tool.cpp b/pcbnew/tools/position_relative_tool.cpp index 97e93e9f25..d6ab6da654 100644 --- a/pcbnew/tools/position_relative_tool.cpp +++ b/pcbnew/tools/position_relative_tool.cpp @@ -31,7 +31,7 @@ using namespace std::placeholders; #include "picker_tool.h" #include - +#include #include #include #include @@ -54,7 +54,7 @@ TOOL_ACTION PCB_ACTIONS::selectpositionRelativeItem( POSITION_RELATIVE_TOOL::POSITION_RELATIVE_TOOL() : PCB_TOOL( "pcbnew.PositionRelative" ), - m_position_relative_dialog( NULL ), + m_dialog( NULL ), m_selectionTool( NULL ), m_anchor_item( NULL ) { @@ -71,16 +71,9 @@ void POSITION_RELATIVE_TOOL::Reset( RESET_REASON aReason ) bool POSITION_RELATIVE_TOOL::Init() { // Find the selection tool, so they can cooperate - m_selectionTool = - static_cast( m_toolMgr->FindTool( "pcbnew.InteractiveSelection" ) ); + m_selectionTool = m_toolMgr->GetTool(); - if( !m_selectionTool ) - { - DisplayError( NULL, wxT( "pcbnew.InteractiveSelection tool is not available" ) ); - return false; - } - - return true; + return m_selectionTool != nullptr; } @@ -95,55 +88,28 @@ int POSITION_RELATIVE_TOOL::PositionRelative( const TOOL_EVENT& aEvent ) const auto& selection = m_selectionTool->RequestSelection( filter ); - if( m_selectionTool->CheckLock() == SELECTION_LOCKED ) + if( m_selectionTool->CheckLock() == SELECTION_LOCKED || selection.Empty() ) return 0; - if( selection.Empty() ) - return 0; + m_selection = selection; - m_position_relative_selection = selection; + if( !m_dialog ) + m_dialog = new DIALOG_POSITION_RELATIVE( editFrame, m_translation, m_anchor ); - if( !m_position_relative_dialog ) - m_position_relative_dialog = new DIALOG_POSITION_RELATIVE( editFrame, - m_toolMgr, - m_position_relative_translation, - m_anchor_position ); - - m_position_relative_dialog->Show( true ); + m_dialog->Show( true ); return 0; } -static bool selectPRitem( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition ) +int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchor, wxPoint relativePosition, + double rotation ) { - SELECTION_TOOL* selectionTool = aToolMgr->GetTool(); - POSITION_RELATIVE_TOOL* positionRelativeTool = aToolMgr->GetTool(); - wxCHECK( selectionTool, false ); - wxCHECK( positionRelativeTool, false ); - - aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - - const SELECTION& selection = selectionTool->RequestSelection( EnsureEditableFilter ); - - if( selection.Empty() ) - return true; - - positionRelativeTool->UpdateAnchor( static_cast( selection.Front() ) ); - - return true; -} - - -int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchorPosition, - wxPoint relativePosition, - double rotation ) -{ - VECTOR2I rp = m_position_relative_selection.GetCenter(); + VECTOR2I rp = m_selection.GetCenter(); wxPoint rotPoint( rp.x, rp.y ); - wxPoint translation = anchorPosition + relativePosition - rotPoint; + wxPoint translation = anchor + relativePosition - rotPoint; - for( auto item : m_position_relative_selection ) + for( auto item : m_selection ) { m_commit->Modify( item ); @@ -153,7 +119,7 @@ int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint anchorPosition, m_commit->Push( _( "Position Relative" ) ); - if( m_position_relative_selection.IsHover() ) + if( m_selection.IsHover() ) m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); m_toolMgr->RunAction( PCB_ACTIONS::selectionModified, true ); @@ -166,26 +132,54 @@ int POSITION_RELATIVE_TOOL::SelectPositionRelativeItem( const TOOL_EVENT& aEvent Activate(); PICKER_TOOL* picker = m_toolMgr->GetTool(); - assert( picker ); + STATUS_TEXT_POPUP statusPopup( frame() ); + bool picking = true; + statusPopup.SetText( _( "Select reference item..." ) ); picker->SetSnapping( false ); - picker->SetClickHandler( std::bind( selectPRitem, m_toolMgr, _1 ) ); picker->Activate(); - Wait(); + + picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool + { + m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); + const SELECTION& sel = m_selectionTool->RequestSelection( EnsureEditableFilter ); + + if( sel.Empty() ) + return true; // still looking for an item + + m_anchor_item = sel.Front(); + statusPopup.Hide(); + + if( m_dialog ) + m_dialog->UpdateAnchor( sel.Front() ); + + picking = false; + return false; // got our item; don't need any more + } ); + + picker->SetCancelHandler( [&]() + { + statusPopup.Hide(); + + if( m_dialog ) + m_dialog->UpdateAnchor( m_anchor_item ); + + picking = false; + } ); + + statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); + statusPopup.Popup(); + + while( picking ) + { + statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) ); + Wait(); + } return 0; } -void POSITION_RELATIVE_TOOL::UpdateAnchor( BOARD_ITEM* aItem ) -{ - m_anchor_item = aItem; - - if( m_position_relative_dialog ) - m_position_relative_dialog->UpdateAnchor( aItem ); -} - - void POSITION_RELATIVE_TOOL::setTransitions() { Go( &POSITION_RELATIVE_TOOL::PositionRelative, PCB_ACTIONS::positionRelative.MakeEvent() ); diff --git a/pcbnew/tools/position_relative_tool.h b/pcbnew/tools/position_relative_tool.h index ebafac291e..5297910c31 100644 --- a/pcbnew/tools/position_relative_tool.h +++ b/pcbnew/tools/position_relative_tool.h @@ -72,47 +72,24 @@ public: * Positions the m_position_relative_selection selection relative to anchorpostion using the given translation and rotation. * Rotation is around the center of the selection. */ - int RelativeItemSelectionMove( wxPoint anchorposition, wxPoint translation, double rotation ); - - /** - * Function GetAnchorItem() - * - * Gets the last selected anchor item. - */ - BOARD_ITEM* GetAnchorItem() - { - return m_anchor_item; - } - - /** - * Function UpdateAnchor() - * - * Selects the item to be used as the reference for relative move operation. - */ - void UpdateAnchor( BOARD_ITEM* aItem ); + int RelativeItemSelectionMove( wxPoint anchor, wxPoint translation, double rotation ); ///> Sets up handlers for various events. void setTransitions() override; private: - DIALOG_POSITION_RELATIVE* m_position_relative_dialog; + DIALOG_POSITION_RELATIVE* m_dialog; ///> Selection tool used for obtaining selected items SELECTION_TOOL* m_selectionTool; + SELECTION m_selection; std::unique_ptr m_commit; - ///> Last anchor item selected by Position Relative To function. - BOARD_ITEM* m_anchor_item; + EDA_ITEM* m_anchor_item; + wxPoint m_anchor; - ///> Translation for Position Relative To function. - wxPoint m_position_relative_translation; - - ///> Anchor position for Position Relative To function. - wxPoint m_anchor_position; - - ///> Selection that will be moved by Position Relative To function. - SELECTION m_position_relative_selection; + wxPoint m_translation; }; #endif