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 "picker_tool.h"
32 
34 #include <status_popup.h>
35 #include <board_commit.h>
36 #include <hotkeys.h>
37 #include <bitmaps.h>
38 #include <confirm.h>
39 
40 
41 // Position relative tool actions
42 
43 TOOL_ACTION PCB_ACTIONS::positionRelative( "pcbnew.PositionRelative.positionRelative",
45  _( "Position Relative To..." ),
46  _( "Positions the selected item(s) by an exact amount relative to another" ),
47  move_relative_xpm );
48 
49 
51  "pcbnew.PositionRelative.selectpositionRelativeItem",
52  AS_GLOBAL, 0, "", "", nullptr );
53 
54 
56  PCB_TOOL( "pcbnew.PositionRelative" ),
57  m_dialog( NULL ),
58  m_selectionTool( NULL ),
59  m_anchor_item( NULL )
60 {
61 }
62 
63 
65 {
66  if( aReason != RUN )
67  m_commit.reset( new BOARD_COMMIT( this ) );
68 }
69 
70 
72 {
73  // Find the selection tool, so they can cooperate
75 
76  return m_selectionTool != nullptr;
77 }
78 
79 
81 {
82  PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
83 
85  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
87 
88  if( selection.Empty() )
89  return 0;
90 
92 
93  if( !m_dialog )
95 
96  m_dialog->Show( true );
97 
98  return 0;
99 }
100 
101 
103 {
104  wxPoint aSelAnchor( INT_MAX, INT_MAX );
105 
106  // Find top-left item anchor in selection
107  for( auto item : m_selection )
108  {
109  wxPoint itemAnchor = static_cast<BOARD_ITEM*>( item )->GetPosition();
110 
111  if( EuclideanNorm( itemAnchor ) < EuclideanNorm( aSelAnchor ) )
112  aSelAnchor = itemAnchor;
113  }
114 
115  wxPoint aggregateTranslation = aPosAnchor + aTranslation - aSelAnchor;
116 
117  for( auto item : m_selection )
118  {
119  // Don't move a pad by itself unless editing the footprint
120  if( item->Type() == PCB_PAD_T && frame()->IsType( FRAME_PCB ) )
121  item = item->GetParent();
122 
123  m_commit->Modify( item );
124  static_cast<BOARD_ITEM*>( item )->Move( aggregateTranslation );
125  }
126 
127  m_commit->Push( _( "Position Relative" ) );
128 
129  if( m_selection.IsHover() )
131 
133 
134  getEditFrame<PCB_EDIT_FRAME>()->Refresh();
135  return 0;
136 }
137 
138 
140 {
141  Activate();
142 
144  STATUS_TEXT_POPUP statusPopup( frame() );
145  bool picking = true;
146 
147  statusPopup.SetText( _( "Select reference item..." ) );
148  picker->Activate();
149 
150  picker->SetClickHandler( [&]( const VECTOR2D& aPoint ) -> bool
151  {
154  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
155  { EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS ); } );
156 
157  if( sel.Empty() )
158  return true; // still looking for an item
159 
160  m_anchor_item = sel.Front();
161  statusPopup.Hide();
162 
163  if( m_dialog )
164  m_dialog->UpdateAnchor( sel.Front() );
165 
166  picking = false;
167  return false; // got our item; don't need any more
168  } );
169 
170  picker->SetCancelHandler( [&]()
171  {
172  statusPopup.Hide();
173 
174  if( m_dialog )
176 
177  picking = false;
178  } );
179 
180  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
181  statusPopup.Popup();
182 
183  while( picking )
184  {
185  statusPopup.Move( wxGetMousePosition() + wxPoint( 20, -50 ) );
186  Wait();
187  }
188 
189  return 0;
190 }
191 
192 
194 {
198 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
bool Empty() const
Checks if there is anything selected.
Definition: selection.h:116
std::unique_ptr< BOARD_COMMIT > m_commit
SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter)
Function RequestSelection()
int PositionRelative(const TOOL_EVENT &aEvent)
Function PositionRelative()
This file is part of the common library.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
void SetClickHandler(CLICK_HANDLER aHandler)
Function SetClickHandler() Sets a handler for mouse click event.
Definition: picker_tool.h:85
Class SELECTION_TOOL.
Class STATUS_TEXT_POPUP.
Definition: status_popup.h:77
Tool is invoked after being inactive.
Definition: tool_base.h:82
EDA_ITEM * Front() const
Definition: selection.h:152
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
static TOOL_ACTION selectpositionRelativeItem
Selection of anchor item for position relative tool.
Definition: pcb_actions.h:257
static int LegacyHotKey(int aHotKey)
Creates a hot key code that refers to a legacy hot key setting, instead of a particular key...
Definition: tool_action.h:174
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()
static TOOL_ACTION selectionModified
Modified selection notification.
Definition: pcb_actions.h:114
Pcbnew hotkeys.
Generic tool for picking a point.
Definition: picker_tool.h:34
DIALOG_POSITION_RELATIVE * m_dialog
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
SELECTION_TOOL * m_selectionTool
Selection tool used for obtaining selected items
int SelectPositionRelativeItem(const TOOL_EVENT &aEvent)
Function SelectPositionRelativeItem()
void setTransitions() override
Sets up handlers for various events.
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:139
Class TOOL_EVENT.
Definition: tool_event.h:168
const SELECTION & selection() const
Definition: pcb_tool.cpp:245
All active tools
Definition: tool_event.h:144
bool Show(bool show) override
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:47
void SetCancelHandler(CANCEL_HANDLER aHandler)
Function SetCancelHandler() Sets a handler for cancel events (ESC or context-menu Cancel)...
Definition: picker_tool.h:95
int RelativeItemSelectionMove(wxPoint anchor, wxPoint translation)
Function RelativeItemSelectionMove()
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:242
Class TOOL_ACTION.
Definition: tool_action.h:46
void Reset(RESET_REASON aReason) override
Function Reset() Brings the tool to a known, initial state.
static TOOL_ACTION positionRelative
Activation of the position relative tool.
Definition: pcb_actions.h:254
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void Activate()
Function Activate() Runs the tool.
bool IsType(FRAME_T aType) const
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:45
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags)
Definition: edit_tool.cpp:173
class PCB_BASE_FRAME basic PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer...