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 {
66 
67  if( frame()->IsType( FRAME_FOOTPRINT_VIEWER )
68  || frame()->IsType( FRAME_FOOTPRINT_VIEWER_MODAL )
69  || frame()->IsType( FRAME_FOOTPRINT_WIZARD ) )
70  {
71  // A stronger version of Raise() which promotes the window to its parent's level.
73  }
74 
75  // And load or update the current board
76  frame()->Update3DView( true, true );
77 
78  return 0;
79 }
80 
81 
82 template<class T> void Flip( T& aValue )
83 {
84  aValue = !aValue;
85 }
86 
87 
89 {
90  auto opts = displayOptions();
91 
92  Flip( opts.m_DisplayPadNum );
93  frame()->SetDisplayOptions( opts );
94 
95  for( FOOTPRINT* fp : board()->Footprints() )
96  {
97  for( PAD* pad : fp->Pads() )
99  }
100 
101  canvas()->Refresh();
102 
103  return 0;
104 }
105 
106 
108 {
109  auto opts = displayOptions();
110 
111  Flip( opts.m_DisplayPadFill );
112  frame()->SetDisplayOptions( opts );
113 
114  for( FOOTPRINT* fp : board()->Footprints() )
115  {
116  for( PAD* pad : fp->Pads() )
117  view()->Update( pad, KIGFX::REPAINT );
118  }
119 
120  canvas()->Refresh();
121 
122  return 0;
123 }
124 
125 
127 {
129 
130  Flip( opts.m_DisplayGraphicsFill );
131  frame()->SetDisplayOptions( opts );
132 
133  for( FOOTPRINT* fp : board()->Footprints() )
134  {
135  for( BOARD_ITEM* item : fp->GraphicalItems() )
136  {
137  if( item->Type() == PCB_FP_SHAPE_T )
138  view()->Update( item, KIGFX::REPAINT );
139  }
140  }
141 
142  for( BOARD_ITEM* item : board()->Drawings() )
143  {
144  KICAD_T t = item->Type();
145 
146  if( t == PCB_SHAPE_T || BaseType( t ) == PCB_DIMENSION_T || t == PCB_TARGET_T )
147  view()->Update( item, KIGFX::REPAINT );
148  }
149 
150  canvas()->Refresh();
151 
152  return 0;
153 }
154 
155 
157 {
159 
160  Flip( opts.m_DisplayTextFill );
161  frame()->SetDisplayOptions( opts );
162 
163  for( FOOTPRINT* fp : board()->Footprints() )
164  {
165  view()->Update( &fp->Reference(), KIGFX::REPAINT );
166  view()->Update( &fp->Value(), KIGFX::REPAINT );
167 
168  for( BOARD_ITEM* item : fp->GraphicalItems() )
169  {
170  if( item->Type() == PCB_FP_TEXT_T )
171  view()->Update( item, KIGFX::REPAINT );
172  }
173  }
174 
175  for( BOARD_ITEM* item : board()->Drawings() )
176  {
177  KICAD_T t = item->Type();
178 
179  if( t == PCB_TEXT_T || BaseType( t ) == PCB_DIMENSION_T )
180  view()->Update( item, KIGFX::REPAINT );
181  }
182 
183  canvas()->Refresh();
184 
185  return 0;
186 }
187 
188 
190 
191 
193 {
194  if( IsFootprintFrame() && !frame()->GetModel() )
195  return 0;
196 
197  if( frame()->IsCurrentTool( ACTIONS::measureTool ) )
198  return 0;
199 
200  auto& view = *getView();
201  auto& controls = *getViewControls();
202 
203  std::string tool = aEvent.GetCommandStr().get();
204  frame()->PushTool( tool );
205 
207  PCB_GRID_HELPER grid( m_toolMgr, frame()->GetMagneticItemsSettings() );
208  bool originSet = false;
209  EDA_UNITS units = frame()->GetUserUnits();
210  KIGFX::PREVIEW::RULER_ITEM ruler( twoPtMgr, units );
211 
212  view.Add( &ruler );
213  view.SetVisible( &ruler, false );
214 
215  auto setCursor =
216  [&]()
217  {
219  };
220 
221  auto cleanup =
222  [&] ()
223  {
224  view.SetVisible( &ruler, false );
225  controls.SetAutoPan( false );
226  controls.CaptureCursor( false );
227  originSet = false;
228  };
229 
230  Activate();
231  // Must be done after Activate() so that it gets set into the correct context
232  controls.ShowCursor( true );
233  controls.SetAutoPan( false );
234  controls.CaptureCursor( false );
235  // Set initial cursor
236  setCursor();
237 
238  while( TOOL_EVENT* evt = Wait() )
239  {
240  setCursor();
241  grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
242  grid.SetUseGrid( view.GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
243  const VECTOR2I cursorPos = grid.BestSnapAnchor( controls.GetMousePosition(), nullptr );
244  controls.ForceCursorPosition(true, cursorPos );
245 
246  if( evt->IsCancelInteractive() )
247  {
248  if( originSet )
249  {
250  cleanup();
251  }
252  else
253  {
254  frame()->PopTool( tool );
255  break;
256  }
257  }
258  else if( evt->IsActivate() )
259  {
260  if( originSet )
261  cleanup();
262 
263  if( evt->IsMoveTool() )
264  {
265  // leave ourselves on the stack so we come back after the move
266  break;
267  }
268  else
269  {
270  frame()->PopTool( tool );
271  break;
272  }
273  }
274  // click or drag starts
275  else if( !originSet && ( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) ) )
276  {
277  twoPtMgr.SetOrigin( cursorPos );
278  twoPtMgr.SetEnd( cursorPos );
279 
280  controls.CaptureCursor( true );
281  controls.SetAutoPan( true );
282 
283  originSet = true;
284  }
285  // second click or mouse up after drag ends
286  else if( originSet && ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
287  {
288  originSet = false;
289 
290  controls.SetAutoPan( false );
291  controls.CaptureCursor( false );
292  }
293  // move or drag when origin set updates rules
294  else if( originSet && ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
295  {
296  twoPtMgr.SetAngleSnap( frame()->Settings().m_Use45DegreeLimit );
297  twoPtMgr.SetEnd( cursorPos );
298 
299  view.SetVisible( &ruler, true );
300  view.Update( &ruler, KIGFX::GEOMETRY );
301  }
302  else if( evt->IsAction( &ACTIONS::updateUnits ) )
303  {
304  if( frame()->GetUserUnits() != units )
305  {
306  units = frame()->GetUserUnits();
307  ruler.SwitchUnits( units );
308  view.Update( &ruler, KIGFX::GEOMETRY );
309  canvas()->Refresh();
310  }
311  evt->SetPassEvent();
312  }
313  else if( evt->IsClick( BUT_RIGHT ) )
314  {
316  }
317  else
318  {
319  evt->SetPassEvent();
320  }
321  }
322 
323  view.SetVisible( &ruler, false );
324  view.Remove( &ruler );
325 
327  controls.SetAutoPan( false );
328  controls.CaptureCursor( false );
329  return 0;
330 }
331 
332 
334 {
336 
337  // Display modes
342 
344 }
int ShowPadNumbers(const TOOL_EVENT &aEvent)
static TOOL_ACTION show3DViewer
Definition: actions.h:158
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.
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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:80
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:235
int MeasureTool(const TOOL_EVENT &aEvent)
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:214
static TOOL_ACTION cancelInteractive
Definition: actions.h:62
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:190
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 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).
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:154
bool GetGridSnapping() const
Container for display options like enable/disable some optional drawings.
void SetDisplayOptions(const PCB_DISPLAY_OPTIONS &aOptions, bool aRefresh=true)
Updates the current display options from the given options struct.
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
Item needs to be redrawn.
Definition: view_item.h:57
int Show3DViewer(const TOOL_EVENT &aEvent)
Show the 3D viewer.
Create and handle a window for the 3d viewer connected to a Kiway and a pcbboard.
virtual void PopTool(const std::string &actionName)
static TOOL_ACTION showPadNumbers
Definition: pcb_actions.h:248
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:152
void SetOrigin(const VECTOR2I &aOrigin)
< Set the origin of the ruler (the fixed end)
bool ToolStackIsEmpty()
Definition: tools_holder.h:116
A drawn ruler item for showing the distance between two points.
Definition: ruler_item.h:41
class PCB_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
class PCB_TARGET, a target (graphic item)
Definition: typeinfo.h:104
static TOOL_ACTION padDisplayMode
Definition: pcb_actions.h:241
static TOOL_ACTION graphicsOutlines
Display footprint graphics as outlines.
Definition: pcb_actions.h:391
bool IsFootprintFrame() const
EDA_UNITS
Definition: eda_units.h:38
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:460
static TOOL_ACTION updateUnits
Definition: actions.h:147
void Flip(T &aValue)
virtual void Update3DView(bool aMarkDirty, bool aRefresh, const wxString *aTitle=nullptr)
Update the 3D view, if the viewer is opened by this frame.
const PCB_DISPLAY_OPTIONS & displayOptions() const
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
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:77
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition: view.cpp:1464
void Activate()
Run the tool.
EDA_3D_VIEWER_FRAME * CreateAndShow3D_Frame()
Shows the 3D view frame.
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:57
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:65
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:394