KiCad PCB EDA Suite
length_tuner_tool.cpp
Go to the documentation of this file.
1 /*
2  * KiRouter - a push-and-(sometimes-)shove PCB router
3  *
4  * Copyright (C) 2013-2017 CERN
5  * Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
6  * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
7  *
8  * This program is free software: you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation, either version 3 of the License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include "class_draw_panel_gal.h"
24 #include <tool/tool_manager.h>
25 #include <tools/pcb_actions.h>
26 #include "pns_router.h"
27 #include "pns_meander_placer.h" // fixme: move settings to separate header
28 #include "pns_tune_status_popup.h"
29 
30 #include "length_tuner_tool.h"
31 #include <bitmaps.h>
32 #include <tools/tool_event_utils.h>
33 
34 using namespace KIGFX;
35 
36 // Actions, being statically-defined, require specialized I18N handling. We continue to
37 // use the _() macro so that string harvesting by the I18N framework doesn't have to be
38 // specialized, but we don't translate on initialization and instead do it in the getters.
39 
40 #undef _
41 #define _(s) s
42 
43 static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning",
44  AS_CONTEXT,
45  'X', LEGACY_HK_NAME( "Add New Track" ),
46  _( "New Track" ), _( "Starts laying a new track." ) );
47 
48 static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning",
49  AS_CONTEXT,
50  WXK_END, LEGACY_HK_NAME( "Stop laying the current track." ),
51  _( "End Track" ), _( "Stops laying the current meander." ) );
52 
53 static TOOL_ACTION ACT_Settings( "pcbnew.LengthTuner.Settings",
54  AS_CONTEXT,
55  // Don't be tempted to remove "Modern Toolset only". It's in the legacy property name.
56  MD_CTRL + 'L', LEGACY_HK_NAME( "Length Tuning Settings (Modern Toolset only)" ),
57  _( "Length Tuning Settings..." ), _( "Sets the length tuning parameters for currently routed item." ),
59 
60 static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease",
61  AS_CONTEXT,
62  '1', LEGACY_HK_NAME( "Increase meander spacing by one step." ),
63  _( "Increase Spacing" ), _( "Increase meander spacing by one step." ),
65 
66 static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease",
67  AS_CONTEXT,
68  '2', LEGACY_HK_NAME( "Decrease meander spacing by one step." ),
69  _( "Decrease Spacing" ), _( "Decrease meander spacing by one step." ),
71 
72 static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease",
73  AS_CONTEXT,
74  '3', LEGACY_HK_NAME( "Increase meander amplitude by one step." ),
75  _( "Increase Amplitude" ), _( "Increase meander amplitude by one step." ),
77 
78 static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease",
79  AS_CONTEXT,
80  '4', LEGACY_HK_NAME( "Decrease meander amplitude by one step." ),
81  _( "Decrease Amplitude" ), _( "Decrease meander amplitude by one step." ),
83 
84 #undef _
85 #define _(s) wxGetTranslation((s))
86 
87 
89  TOOL_BASE( "pcbnew.LengthTuner" )
90 {
91 }
92 
93 
95 {
96 }
97 
98 
100 {
101  auto& menu = m_menu.GetMenu();
102 
103  menu.SetTitle( _( "Length Tuner" ) );
104  menu.SetIcon( BITMAPS::router_len_tuner );
105  menu.DisplayTitle( true );
106 
108 
109  menu.AddSeparator();
110 
116 
117  return true;
118 }
119 
121 {
122  if( aReason == RUN )
123  TOOL_BASE::Reset( aReason );
124 }
125 
126 
128 {
129  // fixme: wx code not allowed inside tools!
130  wxPoint p = wxGetMousePosition();
131 
132  p.x += 20;
133  p.y += 20;
134 
135  aPopup.UpdateStatus( m_router );
136  aPopup.Move( p );
137 }
138 
139 
141 {
142  if( m_startItem )
143  {
145 
146  if( m_startItem->Net() >= 0 )
147  highlightNet( true, m_startItem->Net() );
148  }
149 
150  controls()->ForceCursorPosition( false );
151  controls()->SetAutoPan( true );
152 
153  int layer = m_startItem ? m_startItem->Layer() : static_cast<int>( frame()->GetActiveLayer() );
154 
156  {
158  highlightNet( false );
159  return;
160  }
161 
162  auto placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
163 
164  placer->UpdateSettings( m_savedMeanderSettings );
165  frame()->UndoRedoBlock( true );
166 
168 
169  // Create an instance of PNS_TUNE_STATUS_POPUP.
170  PNS_TUNE_STATUS_POPUP statusPopup( frame() );
171  statusPopup.Popup();
172 
173  m_router->Move( end, NULL );
174  updateStatusPopup( statusPopup );
175 
176  auto setCursor =
177  [&]()
178  {
180  };
181 
182  // Set initial cursor
183  setCursor();
184 
185  while( TOOL_EVENT* evt = Wait() )
186  {
187  setCursor();
188 
189  if( evt->IsCancelInteractive() || evt->IsActivate() )
190  {
191  break;
192  }
193  else if( evt->IsMotion() )
194  {
195  end = evt->Position();
196  m_router->Move( end, NULL );
197  updateStatusPopup( statusPopup );
198  }
199  else if( evt->IsClick( BUT_LEFT ) )
200  {
201  if( m_router->FixRoute( evt->Position(), NULL ) )
202  break;
203  }
204  else if( evt->IsClick( BUT_RIGHT ) )
205  {
207  }
208  else if( evt->IsAction( &ACT_EndTuning ) )
209  {
210  if( m_router->FixRoute( end, NULL ) )
211  break;
212  }
213  else if( evt->IsAction( &ACT_AmplDecrease ) )
214  {
215  placer->AmplitudeStep( -1 );
216  m_router->Move( end, NULL );
217  updateStatusPopup( statusPopup );
218  }
219  else if( evt->IsAction( &ACT_AmplIncrease ) )
220  {
221  placer->AmplitudeStep( 1 );
222  m_router->Move( end, NULL );
223  updateStatusPopup( statusPopup );
224  }
225  else if(evt->IsAction( &ACT_SpacingDecrease ) )
226  {
227  placer->SpacingStep( -1 );
228  m_router->Move( end, NULL );
229  updateStatusPopup( statusPopup );
230  }
231  else if( evt->IsAction( &ACT_SpacingIncrease ) )
232  {
233  placer->SpacingStep( 1 );
234  m_router->Move( end, NULL );
235  updateStatusPopup( statusPopup );
236  }
237  else if( evt->IsAction( &ACT_Settings ) )
238  {
239  statusPopup.Hide();
242  statusPopup.Show();
243  }
244  }
245 
247  frame()->UndoRedoBlock( false );
248 
249  controls()->SetAutoPan( false );
250  controls()->ForceCursorPosition( false );
252  highlightNet( false );
253 }
254 
255 
257 {
261 }
262 
263 
265 {
266  // Deselect all items
268 
269  std::string tool = aEvent.GetCommandStr().get();
270  frame()->PushTool( tool );
271  Activate();
272 
274 
275  controls()->ShowCursor( true );
276 
277  auto setCursor =
278  [&]()
279  {
281  };
282 
283  // Set initial cursor
284  setCursor();
285 
286  // Main loop: keep receiving events
287  while( TOOL_EVENT* evt = Wait() )
288  {
289  setCursor();
290 
291  if( evt->IsCancelInteractive() || evt->IsActivate() )
292  {
293  break; // Finish
294  }
295  else if( evt->Action() == TA_UNDO_REDO_PRE )
296  {
297  m_router->ClearWorld();
298  }
299  else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
300  {
301  m_router->SyncWorld();
302  }
303  else if( evt->IsMotion() )
304  {
305  updateStartItem( *evt );
306  }
307  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
308  {
309  updateStartItem( *evt );
310  performTuning();
311  }
312  else if( evt->IsAction( &ACT_Settings ) )
313  {
316  }
317  else if( evt->IsClick( BUT_RIGHT ) )
318  {
320  }
321  else
322  {
323  evt->SetPassEvent();
324  }
325  }
326 
327  // Store routing settings till the next invocation
329 
331  frame()->PopTool( tool );
332  return 0;
333 }
334 
336 {
337  PNS::MEANDER_PLACER_BASE* placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
338 
339  PNS::MEANDER_SETTINGS settings = placer ? placer->MeanderSettings() : m_savedMeanderSettings;
340  DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( frame(), settings, m_router->Mode() );
341 
342  if( settingsDlg.ShowModal() == wxID_OK )
343  {
344  if( placer )
345  placer->UpdateSettings( settings );
346 
347  m_savedMeanderSettings = settings;
348  }
349 
350  return 0;
351 }
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:63
const wxString & FailureReason() const
Definition: pns_router.h:206
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
Base class for Single trace & Differential pair meandering tools, as both of them share a lot of code...
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
virtual int Layer() const
Definition: pns_item.h:154
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
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.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
#define LEGACY_HK_NAME(x)
Definition: actions.h:35
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
Action belongs to a particular tool (i.e. a part of a pop-up menu)
Definition: tool_event.h:149
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:70
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
static TOOL_ACTION ACT_StartTuning("pcbnew.LengthTuner.StartTuning", AS_CONTEXT, 'X', LEGACY_HK_NAME("Add New Track"), _("New Track"), _("Starts laying a new track."))
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 is invoked after being inactive.
Definition: tool_base.h:80
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:215
PLACEMENT_ALGO * Placer()
Definition: pns_router.h:208
static TOOL_ACTION routerTuneDiffPair
Activation of the Push and Shove router (diff pair tuning mode)
Definition: pcb_actions.h:194
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.
SIZES_SETTINGS m_savedSizes
Definition: pns_tool_base.h:68
void SyncWorld()
Definition: pns_router.cpp:93
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:141
void updateStatusPopup(PNS_TUNE_STATUS_POPUP &aPopup)
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
void UndoRedoBlock(bool aBlock=true)
Enable/disable undo and redo operations.
Dimensions for the meandering algorithm.
Definition: pns_meander.h:57
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:203
static TOOL_ACTION ACT_SpacingIncrease("pcbnew.LengthTuner.SpacingIncrease", AS_CONTEXT, '1', LEGACY_HK_NAME("Increase meander spacing by one step."), _("Increase Spacing"), _("Increase meander spacing by one step."), BITMAPS::router_len_tuner_dist_incr)
virtual void UpdateSettings(const MEANDER_SETTINGS &aSettings)
static TOOL_ACTION ACT_AmplDecrease("pcbnew.LengthTuner.AmplDecrease", AS_CONTEXT, '4', LEGACY_HK_NAME("Decrease meander amplitude by one step."), _("Decrease Amplitude"), _("Decrease meander amplitude by one step."), BITMAPS::router_len_tuner_amplitude_decr)
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).
static TOOL_ACTION routerTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:197
void ClearWorld()
Definition: pns_router.cpp:102
int meanderSettingsDialog(const TOOL_EVENT &aEvent)
int Start() const
Definition: pns_layerset.h:82
PCB_BASE_EDIT_FRAME * frame() const
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
void ShowInfoBarMsg(const wxString &aMsg, bool aShowCloseButton=false)
Show the WX_INFOBAR displayed on the top of the canvas with a message and an info icon on the left of...
virtual void Reset(RESET_REASON aReason)=0
Bring the tool to a known, initial state.
const PCB_SELECTION & selection() const
#define NULL
PNS::MEANDER_SETTINGS m_savedMeanderSettings
virtual void PopTool(const std::string &actionName)
int Net() const
Definition: pns_item.h:148
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:443
Generic, UI-independent tool event.
Definition: tool_event.h:173
ITEM * m_startItem
Definition: pns_tool_base.h:69
static TOOL_ACTION ACT_AmplIncrease("pcbnew.LengthTuner.AmplIncrease", AS_CONTEXT, '3', LEGACY_HK_NAME("Increase meander amplitude by one step."), _("Increase Amplitude"), _("Increase meander amplitude by one step."), BITMAPS::router_len_tuner_amplitude_incr)
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:630
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
ROUTER * m_router
Definition: pns_tool_base.h:78
virtual void Popup(wxWindow *aFocus=nullptr)
bool Init() override
Init() is called once upon a registration of the tool.
void UpdateStatus(PNS::ROUTER *aRouter)
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
virtual void Move(const wxPoint &aWhere)
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:406
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:351
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
void StopRouting()
Definition: pns_router.cpp:673
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:471
ROUTER_MODE
Definition: pns_router.h:62
static TOOL_ACTION ACT_Settings("pcbnew.LengthTuner.Settings", AS_CONTEXT, MD_CTRL+ 'L', LEGACY_HK_NAME("Length Tuning Settings (Modern Toolset only)"), _("Length Tuning Settings..."), _("Sets the length tuning parameters for currently routed item."), BITMAPS::router_len_tuner_setup)
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:90
KIGFX::VIEW_CONTROLS * controls() const
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:799
static TOOL_ACTION ACT_SpacingDecrease("pcbnew.LengthTuner.SpacingDecrease", AS_CONTEXT, '2', LEGACY_HK_NAME("Decrease meander spacing by one step."), _("Decrease Spacing"), _("Decrease meander spacing by one step."), BITMAPS::router_len_tuner_dist_decr)
int MainLoop(const TOOL_EVENT &aEvent)
Base abstract interface for all kinds of tools.
Definition: tool_base.h:66
Represent a single user action.
Definition: tool_action.h:49
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
void Activate()
Run the tool.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
#define _(s)
ROUTER_MODE Mode() const
Definition: pns_router.h:131
static TOOL_ACTION ACT_EndTuning("pcbnew.LengthTuner.EndTuning", AS_CONTEXT, WXK_END, LEGACY_HK_NAME("Stop laying the current track."), _("End Track"), _("Stops laying the current meander."))
virtual const MEANDER_SETTINGS & MeanderSettings() const
Return the current meandering configuration.
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
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905
const LAYER_RANGE & Layers() const
Definition: pns_item.h:150
static TOOL_ACTION routerTuneSingleTrace
Activation of the Push and Shove router (tune single line mode)
Definition: pcb_actions.h:191