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 using namespace std::placeholders;
26 
27 #include "position_relative_tool.h"
28 #include "pcb_actions.h"
29 #include "selection_tool.h"
30 #include "edit_tool.h"
31 #include "pcbnew_picker_tool.h"
33 #include <status_popup.h>
34 #include <board_commit.h>
35 #include <bitmaps.h>
36 #include <confirm.h>
37 
38 
40  PCB_TOOL_BASE( "pcbnew.PositionRelative" ),
41  m_dialog( NULL ),
42  m_selectionTool( NULL ),
43  m_anchor_item( NULL )
44 {
45 }
46 
47 
49 {
50  if( aReason != RUN )
51  m_commit.reset( new BOARD_COMMIT( this ) );
52 }
53 
54 
56 {
57  // Find the selection tool, so they can cooperate
59 
60  return m_selectionTool != nullptr;
61 }
62 
63 
65 {
66  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
67 
69  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
71 
72  if( selection.Empty() )
73  return 0;
74 
76 
77  // The dialog is not modal and not deleted between calls.
78  // It means some options can have changed since the last call.
79  // Therefore we need to rebuild it in case UI units have changed since the last call.
80  if( m_dialog && m_dialog->GetUserUnits() != editFrame->GetUserUnits() )
81  {
82  m_dialog->Destroy();
83  m_dialog = nullptr;
84  }
85 
86  if( !m_dialog )
88 
89  m_dialog->Show( true );
90 
91  return 0;
92 }
93 
94 
95 int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint aPosAnchor, wxPoint aTranslation )
96 {
97  wxPoint aSelAnchor( INT_MAX, INT_MAX );
98 
99  // Find top-left item anchor in selection
100  for( auto item : m_selection )
101  {
102  wxPoint itemAnchor = static_cast<BOARD_ITEM*>( item )->GetPosition();
103 
104  if( EuclideanNorm( itemAnchor ) < EuclideanNorm( aSelAnchor ) )
105  aSelAnchor = itemAnchor;
106  }
107 
108  wxPoint aggregateTranslation = aPosAnchor + aTranslation - aSelAnchor;
109 
110  for( auto item : m_selection )
111  {
112  // Don't move a pad by itself unless editing the footprint
113  if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB_EDITOR ) )
114  item = item->GetParent();
115 
116  m_commit->Modify( item );
117  static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
118  }
119 
120  m_commit->Push( _( "Position Relative" ) );
121 
122  if( m_selection.IsHover() )
124 
126 
127  canvas()->Refresh();
128  return 0;
129 }
130 
131 
133 {
134  std::string tool = "pcbnew.PositionRelative.selectReferenceItem";
136  STATUS_TEXT_POPUP statusPopup( frame() );
137  bool done = false;
138 
139  Activate();
140 
141  statusPopup.SetText( _( "Select reference item..." ) );
142 
143  picker->SetClickHandler(
144  [&]( const VECTOR2D& aPoint ) -> bool
145  {
148  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
149  {
151  } );
152 
153  if( sel.Empty() )
154  return true; // still looking for an item
155 
156  m_anchor_item = sel.Front();
157  statusPopup.Hide();
158 
159  if( m_dialog )
160  m_dialog->UpdateAnchor( sel.Front() );
161 
162  return false; // got our item; don't need any more
163  } );
164 
165  picker->SetMotionHandler(
166  [&] ( const VECTOR2D& aPos )
167  {
168  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
169  } );
170 
171  picker->SetCancelHandler(
172  [&]()
173  {
174  statusPopup.Hide();
175 
176  if( m_dialog )
178  } );
179 
180  picker->SetFinalizeHandler(
181  [&]( const int& aFinalState )
182  {
183  done = true;
184  } );
185 
186  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
187  statusPopup.Popup();
188 
189  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
190 
191  while( !done )
192  Wait();
193 
194  return 0;
195 }
196 
197 
199 {
203 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
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:69
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
int PositionRelative(const TOOL_EVENT &aEvent)
Function PositionRelative()
This file is part of the common library.
Class SELECTION_TOOL.
Class STATUS_TEXT_POPUP.
Definition: status_popup.h:79
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:109
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:227
class D_PAD, a pad in a footprint
Definition: typeinfo.h:90
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:201
static TOOL_ACTION pickerTool
Definition: actions.h:145
PCB_BASE_EDIT_FRAME * frame() const
DIALOG_POSITION_RELATIVE * m_dialog
Generic tool for picking a point.
const PCBNEW_SELECTION & selection() const
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.
Class TOOL_EVENT.
Definition: tool_event.h:171
#define _(s)
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:119
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()
EDA_UNITS_T GetUserUnits() const
Definition: dialog_shim.h:135
bool IsType(FRAME_T aType) const
EDA_UNITS_T GetUserUnits() const
Return the user units currently in use.
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:224
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 EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags)
Definition: edit_tool.cpp:60
void SetCancelHandler(CANCEL_HANDLER aHandler)
Function SetCancelHandler() Sets a handler for cancel events (ESC or context-menu Cancel).
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
EDA_ITEM * Front() const
Definition: selection.h:182
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.