KiCad PCB EDA Suite
position_relative_tool.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <functional>
25 #include <memory>
26 using namespace std::placeholders;
27 
28 #include "position_relative_tool.h"
29 #include "pcb_actions.h"
30 #include "selection_tool.h"
31 #include "edit_tool.h"
32 #include "pcbnew_picker_tool.h"
34 #include <status_popup.h>
35 #include <board_commit.h>
36 #include <bitmaps.h>
37 #include <confirm.h>
38 
39 
41  PCB_TOOL_BASE( "pcbnew.PositionRelative" ),
42  m_dialog( NULL ),
43  m_selectionTool( NULL ),
44  m_anchor_item( NULL )
45 {
46 }
47 
48 
50 {
51  if( aReason != RUN )
52  m_commit = std::make_unique<BOARD_COMMIT>( this );
53 }
54 
55 
57 {
58  // Find the selection tool, so they can cooperate
60 
61  return m_selectionTool != nullptr;
62 }
63 
64 
66 {
67  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
68 
70  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool )
71  { EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED | EXCLUDE_TRANSIENTS, sTool ); } );
72 
73  if( selection.Empty() )
74  return 0;
75 
77 
78  // The dialog is not modal and not deleted between calls.
79  // It means some options can have changed since the last call.
80  // Therefore we need to rebuild it in case UI units have changed since the last call.
81  if( m_dialog && m_dialog->GetUserUnits() != editFrame->GetUserUnits() )
82  {
83  m_dialog->Destroy();
84  m_dialog = nullptr;
85  }
86 
87  if( !m_dialog )
89 
90  m_dialog->Show( true );
91 
92  return 0;
93 }
94 
96 {
98 }
99 
100 
101 int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint aPosAnchor, wxPoint aTranslation )
102 {
103  wxPoint aggregateTranslation = aPosAnchor + aTranslation - GetSelectionAnchorPosition();
104 
105  for( auto item : m_selection )
106  {
107  // Don't move a pad by itself unless editing the footprint
108  if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB_EDITOR ) )
109  item = item->GetParent();
110 
111  m_commit->Modify( item );
112  static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
113  }
114 
115  m_commit->Push( _( "Position Relative" ) );
116 
117  if( m_selection.IsHover() )
119 
121 
122  canvas()->Refresh();
123  return 0;
124 }
125 
126 
128 {
129  std::string tool = "pcbnew.PositionRelative.selectReferenceItem";
131  STATUS_TEXT_POPUP statusPopup( frame() );
132  bool done = false;
133 
134  Activate();
135 
136  statusPopup.SetText( _( "Click on reference item..." ) );
137 
138  picker->SetClickHandler(
139  [&]( const VECTOR2D& aPoint ) -> bool
140  {
143  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool ) {
145  aCollector, EXCLUDE_TRANSIENTS | INCLUDE_PADS_AND_MODULES, sTool );
146  } );
147 
148  if( sel.Empty() )
149  return true; // still looking for an item
150 
151  m_anchor_item = sel.Front();
152  statusPopup.Hide();
153 
154  if( m_dialog )
155  m_dialog->UpdateAnchor( sel.Front() );
156 
157  return false; // got our item; don't need any more
158  } );
159 
160  picker->SetMotionHandler(
161  [&] ( const VECTOR2D& aPos )
162  {
163  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
164  } );
165 
166  picker->SetCancelHandler(
167  [&]()
168  {
169  statusPopup.Hide();
170 
171  if( m_dialog )
173  } );
174 
175  picker->SetFinalizeHandler(
176  [&]( const int& aFinalState )
177  {
178  done = true;
179  } );
180 
181  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
182  statusPopup.Popup();
183 
184  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
185 
186  while( !done )
187  {
188  // Pass events unless we receive a null event, then we must shut down
189  if( TOOL_EVENT* evt = Wait() )
190  evt->SetPassEvent();
191  else
192  break;
193  }
194 
195  return 0;
196 }
197 
198 
200 {
204 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:62
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
std::unique_ptr< BOARD_COMMIT > m_commit
bool IsHover() const
Definition: selection.h:70
wxPoint GetSelectionAnchorPosition() const
Function GetSelectionAnchorPosition()
#define INCLUDE_PADS_AND_MODULES
Definition: edit_tool.h:56
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
int PositionRelative(const TOOL_EVENT &aEvent)
Function PositionRelative()
EDA_ITEM * GetTopLeftItem(bool onlyModules=false) const override
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags, SELECTION_TOOL *selectionTool)
Definition: edit_tool.cpp:64
This file is part of the common library.
SELECTION_TOOL.
STATUS_TEXT_POPUP.
Definition: status_popup.h:82
Tool is invoked after being inactive.
Definition: tool_base.h:81
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:141
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:235
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
virtual wxPoint GetPosition() const
Definition: eda_item.h:326
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void SetFinalizeHandler(FINALIZE_HANDLER aHandler)
Function SetFinalizeHandler() Sets a handler for the finalize event.
static const TOOL_EVENT SelectedItemsModified
Definition: actions.h:213
static TOOL_ACTION pickerTool
Definition: actions.h:153
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:132
PCB_BASE_EDIT_FRAME * frame() const
DIALOG_POSITION_RELATIVE * m_dialog
Generic tool for picking a point.
const PCBNEW_SELECTION & selection() const
#define NULL
SELECTION_TOOL * m_selectionTool
Selection tool used for obtaining selected items
int SelectPositionRelativeItem(const TOOL_EVENT &aEvent)
Function SelectPositionRelativeItem()
bool ProcessEvent(const TOOL_EVENT &aEvent)
Propagates an event to tools that requested events of matching type(s).
void setTransitions() override
Sets up handlers for various events.
TOOL_EVENT.
Definition: tool_event.h:171
bool Show(bool show) override
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:55
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:120
int RelativeItemSelectionMove(wxPoint anchor, wxPoint translation)
Function RelativeItemSelectionMove()
PCBNEW_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=nullptr, bool aConfirmLockedItems=false)
Function RequestSelection()
bool IsType(FRAME_T aType) const
#define _(s)
Definition: 3d_actions.cpp:33
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
void SetMotionHandler(MOTION_HANDLER aHandler)
Function SetMotionHandler() Sets a handler for mouse motion.
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:232
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
void Activate()
Function Activate() Runs the tool.
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:53
PCB_DRAW_PANEL_GAL * canvas() const
void SetCancelHandler(CANCEL_HANDLER aHandler)
Function SetCancelHandler() Sets a handler for cancel events (ESC or context-menu Cancel).
PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
EDA_ITEM * Front() const
Definition: selection.h:178
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.