KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_picker_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) 2015 CERN
5 * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include "pcb_picker_tool.h"
27#include "pcb_actions.h"
28#include "pcb_grid_helper.h"
30#include <view/view_controls.h>
32
33
35 PCB_TOOL_BASE( "pcbnew.InteractivePicker" ),
36 PICKER_TOOL_BASE() // calls reset()
37{
38}
39
40
42{
43 PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
44 MAGNETIC_SETTINGS& magneticSettings = *frame->GetMagneticItemsSettings();
45 CONDITIONAL_MENU& menu = m_menu->GetMenu();
46
47 const auto snapIsSetToAllLayers = [&]( const SELECTION& aSel )
48 {
49 return magneticSettings.allLayers;
50 };
51
52 // "Cancel" goes at the top of the context menu when a tool is active
54
55 menu.AddSeparator( 1 );
56
57 menu.AddItem( PCB_ACTIONS::magneticSnapAllLayers, !snapIsSetToAllLayers, 1 );
58 menu.AddItem( PCB_ACTIONS::magneticSnapActiveLayer, snapIsSetToAllLayers, 1 );
59
60 menu.AddSeparator( 1 );
61
62 if( frame )
63 frame->AddStandardSubMenus( *m_menu.get() );
64
65 return true;
66}
67
68
70{
72 PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
73 PCB_GRID_HELPER grid( m_toolMgr, frame->GetMagneticItemsSettings() );
74 int finalize_state = WAIT_CANCEL;
75
76 TOOL_EVENT sourceEvent;
77
78 if( aEvent.IsAction( &ACTIONS::pickerTool ) )
79 {
80 wxCHECK_MSG( aEvent.Parameter<const TOOL_EVENT*>(), -1,
81 wxT( "PCB_PICKER_TOOL::Main() called without a source event" ) );
82
83 sourceEvent = *aEvent.Parameter<const TOOL_EVENT*>();
84 frame->PushTool( sourceEvent );
85 }
86
87 Activate();
89
90 auto setCursor =
91 [&]()
92 {
93 frame->GetCanvas()->SetCurrentCursor( m_cursor );
94 controls->ShowCursor( true );
95 };
96
97 // Set initial cursor
98 setCursor();
99 VECTOR2D cursorPos;
100
101 while( TOOL_EVENT* evt = Wait() )
102 {
103 setCursor();
104 cursorPos = controls->GetMousePosition();
105
106 if( m_snap )
107 {
108 grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
109 grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
110 cursorPos = grid.BestSnapAnchor( cursorPos, m_layerMask );
111 controls->ForceCursorPosition( true, cursorPos );
112 }
113
114 if( evt->IsCancelInteractive() || evt->IsActivate() )
115 {
116 if( m_cancelHandler )
117 {
118 try
119 {
120 (*m_cancelHandler)();
121 }
122 catch( std::exception& )
123 {
124 }
125 }
126
127 // Activating a new tool may have alternate finalization from canceling the current tool
128 if( evt->IsActivate() )
129 finalize_state = END_ACTIVATE;
130 else
131 finalize_state = EVT_CANCEL;
132
133 break;
134 }
135 else if( evt->IsClick( BUT_LEFT ) )
136 {
137 bool getNext = false;
138
139 m_picked = cursorPos;
140
141 if( m_clickHandler )
142 {
143 try
144 {
145 getNext = (*m_clickHandler)( *m_picked );
146 }
147 catch( std::exception& )
148 {
149 finalize_state = EXCEPTION_CANCEL;
150 break;
151 }
152 }
153
154 if( !getNext )
155 {
156 finalize_state = CLICK_CANCEL;
157 break;
158 }
159 else
160 {
161 setControls();
162 }
163 }
164 else if( evt->IsMotion() )
165 {
166 if( m_motionHandler )
167 {
168 try
169 {
170 (*m_motionHandler)( cursorPos );
171 }
172 catch( std::exception& )
173 {
174 }
175 }
176 }
177 else if( evt->IsDblClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) )
178 {
179 // Not currently used, but we don't want to pass them either
180 }
181 else if( evt->IsClick( BUT_RIGHT ) )
182 {
184 m_menu->ShowContextMenu( dummy );
185 }
186 // TODO: It'd be nice to be able to say "don't allow any non-trivial editing actions",
187 // but we don't at present have that, so we just knock out some of the egregious ones.
188 else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
189 {
190 wxBell();
191 }
192 else
193 {
194 evt->SetPassEvent();
195 }
196 }
197
199 {
200 try
201 {
202 (*m_finalizeHandler)( finalize_state );
203 }
204 catch( std::exception& )
205 {
206 }
207 }
208
209 reset();
211 controls->ShowCursor( false );
212
213 if( aEvent.IsAction( &ACTIONS::pickerTool ) )
214 frame->PopTool( sourceEvent );
215
216 return 0;
217}
218
219
221{
224}
225
226
228{
230
231 controls->CaptureCursor( false );
232 controls->SetAutoPan( false );
233}
234
235
237{
240}
241
242
static TOOL_ACTION pickerSubTool
Definition: actions.h:195
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
static TOOL_ACTION pickerTool
Definition: actions.h:194
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Add a menu entry to run a TOOL_ACTION on selected items.
void AddSeparator(int aOrder=ANY_ORDER)
Add a separator to the menu.
An interface for classes handling user events controlling the view behavior such as zooming,...
virtual void CaptureCursor(bool aEnabled)
Force the cursor to stay within the drawing panel area.
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
static LSET AllLayersMask()
Definition: lset.cpp:695
static TOOL_ACTION magneticSnapAllLayers
Definition: pcb_actions.h:244
static TOOL_ACTION magneticSnapActiveLayer
Snapping controls.
Definition: pcb_actions.h:243
Base PCB main window class for Pcbnew, Gerbview, and CvPcb footprint viewer.
LSET m_layerMask
< The layer set to use for optional snapping.
bool Init() override
Main event loop.
int Main(const TOOL_EVENT &aEvent)
void setControls()
Reinitialize tool to its initial state.
void reset() override
< Reinitializes tool to its initial state.
void setTransitions() override
<
T * frame() const
KIGFX::VIEW_CONTROLS * controls() const
std::optional< VECTOR2D > m_picked
Definition: picker_tool.h:126
std::optional< FINALIZE_HANDLER > m_finalizeHandler
Definition: picker_tool.h:124
std::optional< MOTION_HANDLER > m_motionHandler
Definition: picker_tool.h:122
std::optional< CLICK_HANDLER > m_clickHandler
Definition: picker_tool.h:121
std::optional< CANCEL_HANDLER > m_cancelHandler
Definition: picker_tool.h:123
KICURSOR m_cursor
Definition: picker_tool.h:117
virtual void reset()
< Reinitializes tool to its initial state.
Definition: picker_tool.cpp:32
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:218
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
Generic, UI-independent tool event.
Definition: tool_event.h:167
bool IsAction(const TOOL_ACTION *aAction) const
Test if the event contains an action issued upon activation of the given TOOL_ACTION.
Definition: tool_event.cpp:82
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:460
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Define which state (aStateFunc) to go when a certain event arrives (aConditions).
std::unique_ptr< TOOL_MENU > m_menu
The functions below are not yet implemented - their interface may change.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Suspend execution of the tool until an event specified in aEventList arrives.
void Activate()
Run the tool.
static bool IsZoneFillAction(const TOOL_EVENT *aEvent)
std::vector< FAB_LAYER_COLOR > dummy
@ MD_SHIFT
Definition: tool_event.h:142
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132