KiCad PCB EDA Suite
microwave_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 change_log.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 "microwave_tool.h"
25 
27 #include <class_draw_panel_gal.h>
28 #include <view/view_controls.h>
29 #include <view/view.h>
30 #include <tool/tool_manager.h>
31 #include <board_commit.h>
32 #include <confirm.h>
35 
36 // For frame ToolID values
37 #include <pcbnew_id.h>
38 
39 // For action icons
40 #include <bitmaps.h>
41 
42 #include <class_board_item.h>
43 #include <class_module.h>
44 
46 
47 #include "pcb_actions.h"
48 #include "selection_tool.h"
49 #include "tool_event_utils.h"
50 
51 
55 {
56  GAP,
60 };
61 
63  "pcbnew.MicrowaveTool.createGap",
64  AS_GLOBAL, 0,
65  _( "Add Gap" ), _( "Create gap of specified length for microwave applications" ),
66  mw_add_gap_xpm, AF_ACTIVATE, (void*) MWAVE_TOOL_SIMPLE_ID::GAP );
67 
69  "pcbnew.MicrowaveTool.createStub",
70  AS_GLOBAL, 0,
71  _( "Add Stub" ), _( "Create stub of specified length for microwave applications" ),
72  mw_add_stub_xpm, AF_ACTIVATE, (void*) MWAVE_TOOL_SIMPLE_ID::STUB );
73 
75  "pcbnew.MicrowaveTool.createStubArc",
76  AS_GLOBAL, 0,
77  _( "Add Arc Stub" ), _( "Create stub (arc) of specified length for microwave applications" ),
78  mw_add_stub_arc_xpm, AF_ACTIVATE, (void*) MWAVE_TOOL_SIMPLE_ID::STUB_ARC );
79 
81  "pcbnew.MicrowaveTool.createFunctionShape",
82  AS_GLOBAL, 0,
83  _( "Add Polynomial Shape" ), _( "Create polynomial shape for microwave applications" ),
84  mw_add_gap_xpm, AF_ACTIVATE, (void*) MWAVE_TOOL_SIMPLE_ID::FUNCTION_SHAPE );
85 
87  "pcbnew.MicrowaveTool.createLine",
88  AS_GLOBAL, 0,
89  _( "Add Microwave Line" ), _( "Create line of specified length for microwave applications" ),
90  mw_add_line_xpm, AF_ACTIVATE );
91 
92 
94  PCB_TOOL( "pcbnew.MicrowaveTool" ),
95  m_menu( *this )
96 {
97 }
98 
99 
101 {}
102 
103 
105 {
106 }
107 
108 
110 {
111  auto activeToolFunctor = [ this ] ( const SELECTION& aSel ) {
112  return true;
113  };
114 
115  auto& ctxMenu = m_menu.GetMenu();
116 
117  // cancel current goes in main context menu at the top if present
118  ctxMenu.AddItem( ACTIONS::cancelInteractive, activeToolFunctor, 1000 );
119  ctxMenu.AddSeparator( activeToolFunctor, 1000 );
120 
121  m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
122 
123  return true;
124 }
125 
126 
128 {
129  using MOD_CREATOR = std::function<std::unique_ptr<MODULE>()>;
130 
131  wxString name;
132  int toolId;
134 };
135 
136 
138 {
139  MICROWAVE_TOOL_INFO info;
140 
141  switch( aParam )
142  {
144  info.name = _( "Add Gap" );
146  info.creatorFunc = [&frame] () {
147  return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 0 ) );
148  };
149  break;
150 
152  info.name = _( "Add Stub" );
154  info.creatorFunc = [&frame] () {
155  return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 1 ) );
156  };
157  break;
158 
160  info.name = _( "Add Stub (Arc)" );
162  info.creatorFunc = [&frame] () {
163  return std::unique_ptr<MODULE>( frame.Create_MuWaveComponent( 2 ) );
164  };
165  break;
166 
168  info.name = _( "Add Polynomial Shape" );
170  info.creatorFunc = [&frame] () {
171  return std::unique_ptr<MODULE>( frame.Create_MuWavePolygonShape() );
172  };
173  break;
174  };
175 
176  return info;
177 }
178 
179 
181 {
182  auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
183 
184  const int param = aEvent.Parameter<intptr_t>();
185 
187 
188  // failed to find suitable item info - shouldn't be possible
189  // if all the id's are handled
190  if( !info.name )
191  {
192  wxASSERT_MSG( 0, "Failed to find suitable microwave tool info" );
193  return 0;
194  }
195 
196  frame.SetToolID( info.toolId, wxCURSOR_PENCIL, info.name );
197 
198  ITEM_CREATOR moduleCreator = [this, &info] ( const TOOL_EVENT& aAddingEvent ) {
199  auto module = info.creatorFunc();
200 
201  // Module has been added in the legacy backend,
202  // so we have to remove it before committing the change
203  // @todo LEGACY
204  if( module )
205  {
206  board()->Remove( module.get() );
207  }
208 
209  return module;
210  };
211 
212  doInteractiveItemPlacement( moduleCreator, _( "Place microwave feature" ) );
213 
214  frame.SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
215 
216  return 0;
217 }
218 
219 
220 void MICROWAVE_TOOL::createInductorBetween( const VECTOR2I& aStart, const VECTOR2I& aEnd )
221 {
222  auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
223 
224  MWAVE::INDUCTOR_PATTERN pattern;
225 
227 
228  pattern.m_Start = { aStart.x, aStart.y };
229  pattern.m_End = { aEnd.x, aEnd.y };
230 
231  wxString errorMessage;
232 
233  auto inductorModule = std::unique_ptr<MODULE>(
234  CreateMicrowaveInductor( pattern, &frame, errorMessage )
235  );
236 
237  if( inductorModule )
238  {
239  // legacy mode tools add to the board
240  // so remove it and add it back with the commit object
241  // this has to happen, even if we don't end up storing the module
242  // @todo LEGACY
243  board()->Remove( inductorModule.get() );
244  }
245 
246  // on any error, report if we can
247  if ( !inductorModule || !errorMessage.IsEmpty() )
248  {
249  if ( !errorMessage.IsEmpty() )
250  {
251  DisplayError( &frame, errorMessage );
252  }
253  }
254  else
255  {
256  // at this point, we can save the module
257  frame.SetCurItem( inductorModule.get() );
258 
259  BOARD_COMMIT commit( this );
260  commit.Add( inductorModule.release() );
261  commit.Push( _("Add microwave inductor" ) );
262  }
263 }
264 
265 
266 static const COLOR4D inductorAreaFill( 0.3, 0.3, 0.5, 0.3 );
267 static const COLOR4D inductorAreaStroke( 0.4, 1.0, 1.0, 1.0 );
268 static const double inductorAreaStrokeWidth = 1.0;
269 
272 static const double inductorAreaAspect = 0.5;
273 
274 
276 {
277  using namespace KIGFX::PREVIEW;
278 
279  KIGFX::VIEW& view = *getView();
280  KIGFX::VIEW_CONTROLS& controls = *getViewControls();
281  auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
282 
283  frame.SetToolID( ID_PCB_MUWAVE_TOOL_SELF_CMD, wxCURSOR_PENCIL, _( "Add Microwave Inductor" ) );
284 
285  Activate();
286 
287  TWO_POINT_GEOMETRY_MANAGER tpGeomMgr;
288 
289  CENTRELINE_RECT_ITEM previewRect( tpGeomMgr, inductorAreaAspect );
290 
291  previewRect.SetFillColor( inductorAreaFill );
292  previewRect.SetStrokeColor( inductorAreaStroke );
293  previewRect.SetLineWidth( inductorAreaStrokeWidth );
294 
295  bool originSet = false;
296 
297  controls.ShowCursor( true );
298  controls.SetSnapping( true );
299 
300  view.Add( &previewRect );
301 
302  while( auto evt = Wait() )
303  {
304  VECTOR2I cursorPos = controls.GetCursorPosition();
305 
307  {
308  // overriding action, or we're cancelling without
309  // an in-progress preview area
310  if ( evt->IsActivate() || !originSet )
311  {
312  break;
313  }
314 
315  // had an in-progress area, so start again but don't
316  // cancel the tool
317  originSet = false;
318  view.SetVisible( &previewRect, false );
319  view.Update( &previewRect, KIGFX::GEOMETRY );
320  }
321 
322  // A click or drag starts
323  else if( !originSet &&
324  ( evt->IsClick( BUT_LEFT ) || evt->IsDrag( BUT_LEFT ) ) )
325  {
326  tpGeomMgr.SetOrigin( cursorPos );
327  tpGeomMgr.SetEnd( cursorPos );
328 
329  originSet = true;
330 
331  controls.CaptureCursor( true );
332  controls.SetAutoPan( true );
333  }
334 
335  // another click after origin set is the end
336  // left up is also the end, as you'll only get that after a drag
337  else if( originSet &&
338  ( evt->IsClick( BUT_LEFT ) || evt->IsMouseUp( BUT_LEFT ) ) )
339  {
340  // second click, we're done:
341  // delegate to the point-to-point inductor creator function
342  createInductorBetween( tpGeomMgr.GetOrigin(), tpGeomMgr.GetEnd() );
343 
344  // start again if needed
345  originSet = false;
346 
347  view.SetVisible( &previewRect, false );
348  view.Update( &previewRect, KIGFX::GEOMETRY );
349  }
350 
351  // any move or drag once the origin was set updates
352  // the end point
353  else if( originSet &&
354  ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
355  {
356  tpGeomMgr.SetAngleSnap( evt->Modifier( MD_CTRL ) );
357  tpGeomMgr.SetEnd( cursorPos );
358 
359  view.SetVisible( &previewRect, true );
360  view.Update( &previewRect, KIGFX::GEOMETRY );
361  }
362 
363  else if( evt->IsClick( BUT_RIGHT ) )
364  {
366  }
367  }
368 
369  view.Remove( &previewRect );
370 
371  frame.SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
372 
373  return 0;
374 }
375 
376 
378 {
383 
385 }
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
static const double inductorAreaStrokeWidth
KIGFX::VIEW * view() const
Definition: pcb_tool.h:108
bool Init() override
Basic initalization
void SetLineWidth(double aNewWidth)
Set the line width to set before drawing preview
virtual void SetToolID(int aId, int aCursor, const wxString &aToolMsg) override
Function SetToolID sets the tool command ID to aId and sets the cursor to aCursor.
std::function< std::unique_ptr< MODULE >()> MOD_CREATOR
void SetStrokeColor(const COLOR4D &aNewColor)
Set the stroke colour to set before drawing preview
This file is part of the common library.
static const double inductorAreaAspect
Aspect of the preview rectangle - this is hardcoded in the microwave backend for now ...
static TOOL_ACTION microwaveCreateStubArc
Definition: pcb_actions.h:302
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
VIEW_CONTROLS class definition.
Classes BOARD_ITEM and BOARD_CONNECTED_ITEM.
Class TWO_POINT_GEOMETRY_MANAGER.
CONDITIONAL_MENU & GetMenu()
Function GetMenu.
Definition: tool_menu.cpp:49
Parameters for construction of a microwave inductor.
void Reset(RESET_REASON aReason) override
React to model/view changes
static TOOL_ACTION cancelInteractive
Definition: actions.h:45
void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:340
void SetCurItem(BOARD_ITEM *aItem, bool aDisplayInfo=true)
Function SetCurItem sets the currently selected item and displays it in the MsgPanel.
OPT_TOOL_EVENT Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
static TOOL_ACTION microwaveCreateLine
Definition: pcb_actions.h:306
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
static const COLOR4D inductorAreaFill(0.3, 0.3, 0.5, 0.3)
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true) override
Executes the changes.
TOOL_MENU m_menu
Menu model displayed by the tool.
void createInductorBetween(const VECTOR2I &aStart, const VECTOR2I &aEnd)
Create an inductor between the two points
MICROWAVE_TOOL_INFO getMicrowaveItemCreator(PCB_EDIT_FRAME &frame, int aParam)
void AddStandardSubMenus(EDA_DRAW_FRAME &aFrame)
Function CreateBasicMenu.
Definition: tool_menu.cpp:95
MODULE * Create_MuWavePolygonShape()
Definition: muonde.cpp:579
static const COLOR4D inductorAreaStroke(0.4, 1.0, 1.0, 1.0)
MODULE * Create_MuWaveComponent(int shape_type)
Create_MuWaveComponent creates a module "GAP" or "STUB" used in micro wave designs.
Definition: muonde.cpp:226
virtual VECTOR2D GetCursorPosition() const =0
Function GetCursorPosition() Returns the current cursor position in world coordinates.
virtual void CaptureCursor(bool aEnabled)
Function CaptureCursor() Forces the cursor to stay within the drawing panel area. ...
void SetTransitions() override
Bind handlers to corresponding TOOL_ACTIONs
PCB_EDIT_FRAME * frame() const
Definition: pcb_tool.h:109
Class TOOL_EVENT.
Definition: tool_event.h:162
void SetOrigin(const VECTOR2I &aOrigin)
Set the origin of the ruler (the fixed end)
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
Definition: view_controls.h:94
static TOOL_ACTION microwaveCreateGap
Definition: pcb_actions.h:298
bool IsCancelInteractive(const TOOL_EVENT &aEvt)
Function IsCancelInteractive()
All active tools
Definition: tool_event.h:138
void SetFillColor(const COLOR4D &aNewColor)
Set the fill colour to set before drawing preview
Class PCB_TOOL.
Definition: pcb_tool.h:45
void Update(VIEW_ITEM *aItem)
Function Update() For dynamic VIEWs, informs the associated VIEW that the graphical representation of...
Definition: view.cpp:1378
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg...
KIGFX::VIEW_CONTROLS * getViewControls() const
Function getViewControls()
Definition: tool_base.cpp:36
static TOOL_ACTION microwaveCreateStub
Definition: pcb_actions.h:300
int drawMicrowaveInductor(const TOOL_EVENT &aEvent)
Draw a microwave inductor interactively
KIGFX::VIEW * getView() const
Function getView()
Definition: tool_base.cpp:30
static TOOL_ACTION microwaveCreateFunctionShape
Definition: pcb_actions.h:304
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:373
MODULE * CreateMicrowaveInductor(INDUCTOR_PATTERN &aPattern, PCB_EDIT_FRAME *aPcbFrame, wxString &aErrorMessage)
Creates an S-shaped coil footprint for microwave applications.
int addMicrowaveFootprint(const TOOL_EVENT &aEvent)
Main interactive tool
void doInteractiveItemPlacement(ITEM_CREATOR aItemCreator, const wxString &aCommitMessage)
Helper function for performing a common interactive idiom: wait for a left click, place an item there...
Definition: pcb_tool.cpp:39
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition=SELECTION_CONDITIONS::ShowAlways, int aOrder=ANY_ORDER)
Function AddItem()
Class TOOL_ACTION.
Definition: tool_action.h:46
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:80
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Function SetVisible() Sets the item visibility.
Definition: view.cpp:1330
void Activate()
Function Activate() Runs the tool.
void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:310
Module description (excepted pads)
Class VIEW.
Definition: view.h:58
std::function< std::unique_ptr< BOARD_ITEM >(const TOOL_EVENT &aEvt) > ITEM_CREATOR
Callable that returns a new board item.
Definition: pcb_tool.h:91
int GetCurrentTrackWidth() const
Function GetCurrentTrackWidth.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:69
MWAVE_TOOL_SIMPLE_ID
Type of items that are "simple" - just get placed on the board directly, without a graphical interact...
void ShowContextMenu(SELECTION &aSelection)
Function ShowContextMenu.
Definition: tool_menu.cpp:62
void Remove(BOARD_ITEM *aBoardItem) override
>
void SetEnd(const VECTOR2I &aEnd)
Set the current end of the rectangle (the end that moves with the cursor.
Color has changed.
Definition: view_item.h:57
BOARD * board() const
Definition: pcb_tool.h:110
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39