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  if( !m_dialog )
79 
80  m_dialog->Show( true );
81 
82  return 0;
83 }
84 
85 
86 int POSITION_RELATIVE_TOOL::RelativeItemSelectionMove( wxPoint aPosAnchor, wxPoint aTranslation )
87 {
88  wxPoint aSelAnchor( INT_MAX, INT_MAX );
89 
90  // Find top-left item anchor in selection
91  for( auto item : m_selection )
92  {
93  wxPoint itemAnchor = static_cast<BOARD_ITEM*>( item )->GetPosition();
94 
95  if( EuclideanNorm( itemAnchor ) < EuclideanNorm( aSelAnchor ) )
96  aSelAnchor = itemAnchor;
97  }
98 
99  wxPoint aggregateTranslation = aPosAnchor + aTranslation - aSelAnchor;
100 
101  for( auto item : m_selection )
102  {
103  // Don't move a pad by itself unless editing the footprint
104  if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB ) )
105  item = item->GetParent();
106 
107  m_commit->Modify( item );
108  static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
109  }
110 
111  m_commit->Push( _( "Position Relative" ) );
112 
113  if( m_selection.IsHover() )
115 
117 
118  canvas()->Refresh();
119  return 0;
120 }
121 
122 
124 {
125  std::string tool = "pcbnew.PositionRelative.selectReferenceItem";
127  STATUS_TEXT_POPUP statusPopup( frame() );
128  bool done = false;
129 
130  Activate();
131 
132  statusPopup.SetText( _( "Select reference item..." ) );
133 
134  picker->SetClickHandler(
135  [&]( const VECTOR2D& aPoint ) -> bool
136  {
139  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
140  {
142  } );
143 
144  if( sel.Empty() )
145  return true; // still looking for an item
146 
147  m_anchor_item = sel.Front();
148  statusPopup.Hide();
149 
150  if( m_dialog )
151  m_dialog->UpdateAnchor( sel.Front() );
152 
153  return false; // got our item; don't need any more
154  } );
155 
156  picker->SetMotionHandler(
157  [&] ( const VECTOR2D& aPos )
158  {
159  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
160  } );
161 
162  picker->SetCancelHandler(
163  [&]()
164  {
165  statusPopup.Hide();
166 
167  if( m_dialog )
169  } );
170 
171  picker->SetFinalizeHandler(
172  [&]( const int& aFinalState )
173  {
174  done = true;
175  } );
176 
177  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
178  statusPopup.Popup();
179 
180  m_toolMgr->RunAction( ACTIONS::pickerTool, true, &tool );
181 
182  while( !done )
183  Wait();
184 
185  return 0;
186 }
187 
188 
190 {
194 }
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:223
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:200
static TOOL_ACTION pickerTool
Definition: actions.h:144
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:168
#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()
bool IsType(FRAME_T aType) const
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:220
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:61
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.