KiCad PCB EDA Suite
pcb_viewer_tools.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) 2020 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 
25 #include <kiplatform/ui.h>
26 #include <pcb_base_frame.h>
27 #include <pcbnew_settings.h>
29 #include <tool/actions.h>
30 #include <tools/pcb_grid_helper.h>
31 #include <tools/pcb_actions.h>
32 #include <tools/pcb_viewer_tools.h>
33 #include <view/view_controls.h>
34 #include <wx/debug.h>
35 
36 
38 {
39  // Populate the context menu displayed during the tool (primarily the measure tool)
40  auto activeToolCondition =
41  [ this ] ( const SELECTION& aSel )
42  {
43  return !frame()->ToolStackIsEmpty();
44  };
45 
46  auto& ctxMenu = m_menu.GetMenu();
47 
48  // "Cancel" goes at the top of the context menu when a tool is active
49  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolCondition, 1 );
50  ctxMenu.AddSeparator( 1 );
51 
53 
54  return true;
55 }
56 
57 
59 {
60 }
61 
62 
64 {
65  EDA_3D_VIEWER* draw3DFrame = frame()->CreateAndShow3D_Frame();
66 
67  if( frame()->IsType( FRAME_FOOTPRINT_VIEWER )
68  || frame()->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
69  || frame()->IsType( FRAME_FOOTPRINT_WIZARD ) )
70  {
71  frame()->Update3DView( true );
72 
73  // A stronger version of Raise() which promotes the window to its parent's level.
75  }
76  return 0;
77 }
78 
79 
80 template<class T> void Flip( T& aValue )
81 {
82  aValue = !aValue;
83 }
84 
85 
87 {
88  frame()->SetAutoZoom( !frame()->GetAutoZoom() );
89 
90  return 0;
91 }
92 
93 
95 {
96  auto opts = displayOptions();
97 
98  Flip( opts.m_DisplayPadNum );
99  frame()->SetDisplayOptions( opts );
100 
101  for( FOOTPRINT* fp : board()->Footprints() )
102  {
103  for( PAD* pad : fp->Pads() )
104  view()->Update( pad, KIGFX::GEOMETRY );
105  }
106 
107  canvas()->Refresh();
108 
109  return 0;
110 }
111 
112 
114 {
115  auto opts = displayOptions();
116 
117  Flip( opts.m_DisplayPadFill );
118  frame()->SetDisplayOptions( opts );
119 
120  for( FOOTPRINT* fp : board()->Footprints() )
121  {
122  for( PAD* pad : fp->Pads() )
123  view()->Update( pad, KIGFX::GEOMETRY );
124  }
125 
126  canvas()->Refresh();
127 
128  return 0;
129 }
130 
131 
133 {
135 
136  Flip( opts.m_DisplayGraphicsFill );
137  frame()->SetDisplayOptions( opts );
138 
139  for( FOOTPRINT* fp : board()->Footprints() )
140  {
141  for( BOARD_ITEM* item : fp->GraphicalItems() )
142  {
143  if( item->Type() == PCB_FP_SHAPE_T )
144  view()->Update( item, KIGFX::GEOMETRY );
145  }
146  }
147 
148  for( BOARD_ITEM* item : board()->Drawings() )
149  {
150  KICAD_T t = item->Type();
151 
152  if( t == PCB_SHAPE_T || BaseType( t ) == PCB_DIMENSION_T || t == PCB_TARGET_T )
153  view()->Update( item, KIGFX::GEOMETRY );
154  }
155 
156  canvas()->Refresh();
157 
158  return 0;
159 }
160 
161 
163 {
165 
166  Flip( opts.m_DisplayTextFill );
167  frame()->SetDisplayOptions( opts );
168 
169  for( FOOTPRINT* fp : board()->Footprints() )
170  {
171  view()->Update( &fp->Reference(), KIGFX::GEOMETRY );
172  view()->Update( &fp->Value(), KIGFX::GEOMETRY );
173 
174  for( BOARD_ITEM* item : fp->GraphicalItems() )
175  {
176  if( item->Type() == PCB_FP_TEXT_T )
177  view()->Update( item, KIGFX::GEOMETRY );
178  }
179  }
180 
181  for( BOARD_ITEM* item : board()->Drawings() )
182  {
183  KICAD_T t = item->Type();
184 
185  if( t == PCB_TEXT_T || BaseType( t ) == PCB_DIMENSION_T )
186  view()->Update( item, KIGFX::GEOMETRY );
187  }
188 
189  canvas()->Refresh();
190 
191  return 0;
192 }
193 
194 
196 {
197  if( IsFootprintFrame() && !frame()->GetModel() )
198  return 0;
199 
200  if( frame()->IsCurrentTool( ACTIONS::measureTool ) )
201  return 0;
202 
203  auto& view = *getView();
204  auto& controls = *getViewControls();
205 
206  std::string tool = aEvent.GetCommandStr().get();
207  frame()->PushTool( tool );
208  Activate();
209 
211 
212  EDA_UNITS units = frame()->GetUserUnits();
213  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
214 
215  view.Add( &ruler );
216  view.SetVisible( &ruler, false );
217 
218  PCB_GRID_HELPER grid( m_toolMgr, frame()->GetMagneticItemsSettings() );
219 
220  bool originSet = false;
221 
222  controls.ShowCursor( true );
223  controls.SetAutoPan( false );
224  controls.CaptureCursor( false );
225 
226  auto setCursor =
227  [&]()
228  {
230  };
231 
232  // Set initial cursor
233  setCursor();
234 
235  while( TOOL_EVENT* evt = Wait() )
236  {
237  setCursor();
238  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
239  grid.SetUseGrid( view.GetGAL()->GetGridSnapping() && !evt->Modifier( MD_ALT ) );
240  const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
241  controls.ForceCursorPosition(true, cursorPos );
242 
243  auto clearRuler =
244  [&] ()
245  {
246  view.SetVisible( &ruler, false );
247  controls.SetAutoPan( false );
248  controls.CaptureCursor( false );
249  originSet = false;
250  };
251 
252  if( evt->IsCancelInteractive() )
253  {
254  if( originSet )
255  clearRuler();
256  else
257  {
258  frame()->PopTool( tool );
259  break;
260  }
261  }
262  else if( evt->IsActivate() )
263  {
264  if( originSet )
265  clearRuler();
266 
267  if( evt->IsMoveTool() )
268  {
269  // leave ourselves on the stack so we come back after the move
270  break;
271  }
272  else
273  {
274  frame()->PopTool( tool );
275  break;
276  }
277  }
278  // click or drag starts
279  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
280  {
281  twoPtMgr.SetOrigin( cursorPos );
282  twoPtMgr.SetEnd( cursorPos );
283 
284  controls.CaptureCursor( true );
285  controls.SetAutoPan( true );
286 
287  originSet = true;
288  }
289  // second click or mouse up after drag ends
290  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
291  {
292  originSet = false;
293 
294  controls.SetAutoPan( false );
295  controls.CaptureCursor( false );
296  }
297  // move or drag when origin set updates rules
298  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
299  {
300  twoPtMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
301  twoPtMgr.SetEnd( cursorPos );
302 
303  view.SetVisible( &ruler, true );
304  view.Update( &ruler, KIGFX::GEOMETRY );
305  }
306  else if( evt->IsAction( &ACTIONS::updateUnits ) )
307  {
308  if( frame()->GetUserUnits() != units )
309  {
310  units = frame()->GetUserUnits();
311  ruler.SwitchUnits( units );
312  view.Update( &ruler, KIGFX::GEOMETRY );
313  canvas()->Refresh();
314  }
315  evt->SetPassEvent();
316  }
317  else if( evt->IsClick( BUT_RIGHT ) )
318  {
320  }
321  else
322  {
323  evt->SetPassEvent();
324  }
325  }
326 
327  view.SetVisible( &ruler, false );
328  view.Remove( &ruler );
329 
331  return 0;
332 }
333 
334 
336 {
338 
339  // Display modes
345 
347 }
int ShowPadNumbers(const TOOL_EVENT &aEvent)
static TOOL_ACTION show3DViewer
Definition: actions.h:161
void AddStandardSubMenus(TOOL_MENU &aMenu)
Construct a "basic" menu for a tool, containing only items that apply to all tools (e....
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
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.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
constexpr KICAD_T BaseType(const KICAD_T aType)
Returns the underlying type of the given type.
Definition: typeinfo.h:235
int MeasureTool(const TOOL_EVENT &aEvent)
virtual void Update3DView(bool aReloadRequest, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
Represent a very simple geometry manager for items that have a start and end point.
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:46
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:189
PCB_BASE_FRAME * frame() const
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
void SwitchUnits(EDA_UNITS aUnits)
Switch the ruler units.
Definition: ruler_item.h:76
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions)
static TOOL_ACTION zoomFootprintAutomatically
Definition: pcb_actions.h:252
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).
void SetCurrentCursor(KICURSOR cursor)
Set the current cursor shape for this panel.
virtual void Remove(VIEW_ITEM *aItem) override
Remove a VIEW_ITEM from the view.
Definition: pcb_view.cpp:75
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
KIGFX::PCB_VIEW * view() const
Classes used in Pcbnew, CvPcb and GerbView.
static TOOL_ACTION measureTool
Definition: actions.h:157
bool GetGridSnapping() const
Container for display options like enable/disable some optional drawings.
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:92
VECTOR2I BestSnapAnchor(const VECTOR2I &aOrigin, BOARD_ITEM *aReferenceItem)
Chooses the "best" snap anchor around the given point, optionally taking layers from the reference it...
int Show3DViewer(const TOOL_EVENT &aEvent)
Show the 3D viewer.
EDA_3D_VIEWER * CreateAndShow3D_Frame()
Shows the 3D view frame.
virtual void PopTool(const std::string &actionName)
static TOOL_ACTION showPadNumbers
Definition: pcb_actions.h:251
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
Generic, UI-independent tool event.
Definition: tool_event.h:173
void SetOrigin(const VECTOR2I &aOrigin)
< Set the origin of the ruler (the fixed end)
bool ToolStackIsEmpty()
Definition: tools_holder.h:117
A drawn ruler item for showing the distance between two points.
Definition: ruler_item.h:41
class DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:99
KIGFX::VIEW * getView() const
Returns the instance of #VIEW object used in the application.
Definition: tool_base.cpp:36
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...
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
void SetSnap(bool aSnap)
Definition: grid_helper.h:64
static TOOL_ACTION padDisplayMode
Definition: pcb_actions.h:245
int ZoomAutomatically(const TOOL_EVENT &aEvent)
static TOOL_ACTION graphicsOutlines
Display footprint graphics as outlines.
Definition: pcb_actions.h:390
bool IsFootprintFrame() const
EDA_UNITS
Definition: eda_units.h:38
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
static TOOL_ACTION updateUnits
Definition: actions.h:150
void SetUseGrid(bool aSnapToGrid)
Definition: grid_helper.h:67
Declaration of the eda_3d_viewer class.
void Flip(T &aValue)
virtual void SetAutoZoom(bool aAutoZoom)
Does nothing.
const PCB_DISPLAY_OPTIONS & displayOptions() const
int GraphicOutlines(const TOOL_EVENT &aEvent)
BOARD * board() const
PCB_DRAW_PANEL_GAL * canvas() const
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1454
void Activate()
Run the tool.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
Definition: eda_3d_viewer.h:66
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1) override
Add a VIEW_ITEM to the view.
Definition: pcb_view.cpp:58
int TextOutlines(const TOOL_EVENT &aEvent)
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
SGLIB_API S3DMODEL * GetModel(SCENEGRAPH *aNode)
Function GetModel creates an S3DMODEL representation of aNode (raw data, no transforms)
Definition: ifsg_api.cpp:336
Definition: pad.h:60
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
void ReparentQuasiModal(wxNonOwnedWindow *aWindow)
Move a window's parent to be the top-level window and force the window to be on top.
Definition: gtk/ui.cpp:50
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 ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:59
bool Init() override
Init() is called once upon a registration of the tool.
int PadDisplayMode(const TOOL_EVENT &aEvent)
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
Position or shape has changed.
Definition: view_item.h:54
static TOOL_ACTION textOutlines
Display texts as lines.
Definition: pcb_actions.h:393