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 <core/optional.h>
23 
24 #include "class_draw_panel_gal.h"
25 #include "class_board.h"
26 
27 #include <pcb_edit_frame.h>
28 #include <pcbnew_id.h>
29 #include <view/view_controls.h>
30 #include <pcb_painter.h>
33 #include <tool/action_menu.h>
34 #include <tool/tool_manager.h>
35 #include <tools/pcb_actions.h>
36 #include "pns_segment.h"
37 #include "pns_router.h"
38 #include "pns_meander_placer.h" // fixme: move settings to separate header
39 #include "pns_tune_status_popup.h"
40 
41 #include "length_tuner_tool.h"
42 #include <bitmaps.h>
43 #include <tools/tool_event_utils.h>
44 
45 using namespace KIGFX;
46 
47 // Actions, being statically-defined, require specialized I18N handling. We continue to
48 // use the _() macro so that string harvesting by the I18N framework doesn't have to be
49 // specialized, but we don't translate on initialization and instead do it in the getters.
50 
51 #undef _
52 #define _(s) s
53 
54 static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning",
55  AS_CONTEXT,
56  'X', LEGACY_HK_NAME( "Add New Track" ),
57  _( "New Track" ), _( "Starts laying a new track." ) );
58 
59 static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning",
60  AS_CONTEXT,
61  WXK_END, LEGACY_HK_NAME( "Stop laying the current track." ),
62  _( "End Track" ), _( "Stops laying the current meander." ) );
63 
64 static TOOL_ACTION ACT_Settings( "pcbnew.LengthTuner.Settings",
65  AS_CONTEXT,
66  // Don't be tempted to remove "Modern Toolset only". It's in the legacy property name.
67  MD_CTRL + 'L', LEGACY_HK_NAME( "Length Tuning Settings (Modern Toolset only)" ),
68  _( "Length Tuning Settings..." ), _( "Sets the length tuning parameters for currently routed item." ),
70 
71 static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease",
72  AS_CONTEXT,
73  '1', LEGACY_HK_NAME( "Increase meander spacing by one step." ),
74  _( "Increase Spacing" ), _( "Increase meander spacing by one step." ),
76 
77 static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease",
78  AS_CONTEXT,
79  '2', LEGACY_HK_NAME( "Decrease meander spacing by one step." ),
80  _( "Decrease Spacing" ), _( "Decrease meander spacing by one step." ),
82 
83 static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease",
84  AS_CONTEXT,
85  '3', LEGACY_HK_NAME( "Increase meander amplitude by one step." ),
86  _( "Increase Amplitude" ), _( "Increase meander amplitude by one step." ),
88 
89 static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease",
90  AS_CONTEXT,
91  '4', LEGACY_HK_NAME( "Decrease meander amplitude by one step." ),
92  _( "Decrease Amplitude" ), _( "Decrease meander amplitude by one step." ),
94 
95 #undef _
96 #define _(s) wxGetTranslation((s))
97 
98 
100  TOOL_BASE( "pcbnew.LengthTuner" )
101 {
102 }
103 
104 
106 {
107 public:
109  ACTION_MENU( true )
110  {
111  SetTitle( _( "Length Tuner" ) );
113  DisplayTitle( true );
114 
116 
117  AppendSeparator();
118 
123  Add( ACT_Settings );
124  }
125 
126 private:
127  ACTION_MENU* create() const override
128  {
129  return new TUNER_TOOL_MENU();
130  }
131 };
132 
133 
135 {
136 }
137 
138 
140 {
141  if( aReason == RUN )
142  TOOL_BASE::Reset( aReason );
143 }
144 
145 
147 {
148  // fixme: wx code not allowed inside tools!
149  wxPoint p = wxGetMousePosition();
150 
151  p.x += 20;
152  p.y += 20;
153 
154  aPopup.UpdateStatus( m_router );
155  aPopup.Move( p );
156 }
157 
158 
160 {
161  if( m_startItem )
162  {
164 
165  if( m_startItem->Net() >= 0 )
166  highlightNet( true, m_startItem->Net() );
167  }
168 
169  controls()->ForceCursorPosition( false );
170  controls()->SetAutoPan( true );
171 
173  {
174  wxMessageBox( m_router->FailureReason(), _( "Error" ) );
175  highlightNet( false );
176  return;
177  }
178 
179  auto placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
180 
181  placer->UpdateSettings( m_savedMeanderSettings );
182 
183  VECTOR2I end( m_startSnapPoint );
184 
185  // Create an instance of PNS_TUNE_STATUS_POPUP.
186  // DO NOT create it on the stack: otherwise on Windows, wxWidgets 3.1.3
187  // it creates a crash. I am pretty sure this crash is created by the stack switching
188  // when managing events (JPC).
189  std::unique_ptr<PNS_TUNE_STATUS_POPUP> statusPopup( new PNS_TUNE_STATUS_POPUP( frame() ) );
190  statusPopup->Popup();
191 
192  m_router->Move( end, NULL );
193  updateStatusPopup( *statusPopup );
194 
195  while( TOOL_EVENT* evt = Wait() )
196  {
197  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
198 
199  if( evt->IsCancelInteractive() || evt->IsActivate() )
200  break;
201  else if( evt->IsMotion() )
202  {
203  end = evt->Position();
204  m_router->Move( end, NULL );
205  updateStatusPopup( *statusPopup );
206  }
207  else if( evt->IsClick( BUT_LEFT ) )
208  {
209  if( m_router->FixRoute( evt->Position(), NULL ) )
210  break;
211  }
212  else if( evt->IsAction( &ACT_EndTuning ) )
213  {
214  if( m_router->FixRoute( end, NULL ) )
215  break;
216  }
217  else if( evt->IsAction( &ACT_AmplDecrease ) )
218  {
219  placer->AmplitudeStep( -1 );
220  m_router->Move( end, NULL );
221  updateStatusPopup( *statusPopup );
222  }
223  else if( evt->IsAction( &ACT_AmplIncrease ) )
224  {
225  placer->AmplitudeStep( 1 );
226  m_router->Move( end, NULL );
227  updateStatusPopup( *statusPopup );
228  }
229  else if(evt->IsAction( &ACT_SpacingDecrease ) )
230  {
231  placer->SpacingStep( -1 );
232  m_router->Move( end, NULL );
233  updateStatusPopup( *statusPopup );
234  }
235  else if( evt->IsAction( &ACT_SpacingIncrease ) )
236  {
237  placer->SpacingStep( 1 );
238  m_router->Move( end, NULL );
239  updateStatusPopup( *statusPopup );
240  }
241  else if( evt->IsAction( &ACT_Settings ) )
242  {
243  statusPopup->Hide();
246  statusPopup->Show();
247  }
248  }
249 
251  controls()->SetAutoPan( false );
252  controls()->ForceCursorPosition( false );
253  highlightNet( false );
254 }
255 
256 
258 {
262 }
263 
264 
266 {
267  // Deselect all items
269 
270  std::string tool = aEvent.GetCommandStr().get();
271  frame()->PushTool( tool );
272  Activate();
273 
275 
276  controls()->SetSnapping( true );
277  controls()->ShowCursor( true );
278  frame()->UndoRedoBlock( true );
279 
280  std::unique_ptr<TUNER_TOOL_MENU> ctxMenu( new TUNER_TOOL_MENU );
281  SetContextMenu( ctxMenu.get() );
282 
283  // Main loop: keep receiving events
284  while( TOOL_EVENT* evt = Wait() )
285  {
286  frame()->GetCanvas()->SetCurrentCursor( wxCURSOR_ARROW );
287 
288  if( evt->IsCancelInteractive() || evt->IsActivate() )
289  {
290  break; // Finish
291  }
292  else if( evt->IsMotion() )
293  {
294  updateStartItem( *evt );
295  }
296  else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
297  {
298  updateStartItem( *evt );
299  performTuning();
300  }
301  else if( evt->IsAction( &ACT_Settings ) )
302  {
305  }
306  }
307 
308  frame()->UndoRedoBlock( false );
309 
310  // Store routing settings till the next invocation
313 
314  frame()->PopTool( tool );
315  return 0;
316 }
317 
319 {
320  PNS::MEANDER_PLACER_BASE* placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
321 
322  PNS::MEANDER_SETTINGS settings = placer ? placer->MeanderSettings() : m_savedMeanderSettings;
323  DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( frame(), settings, m_router->Mode() );
324 
325  if( settingsDlg.ShowModal() )
326  {
327  if( placer )
328  placer->UpdateSettings( settings );
329 
330  m_savedMeanderSettings = settings;
331  }
332 
333  return 0;
334 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:73
const wxString & FailureReason() const
Definition: pns_router.h:217
virtual void ShowCursor(bool aEnabled)
Function ShowCursor() Enables or disables display of cursor.
virtual void PushTool(const std::string &actionName)
NB: the definition of "tool" is different at the user level.
wxMenuItem * Add(const wxString &aLabel, int aId, const BITMAP_OPAQUE *aIcon)
Function Add() Adds a wxWidgets-style entry to the menu.
TOOL_EVENT * Wait(const TOOL_EVENT_LIST &aEventList=TOOL_EVENT(TC_ANY, TA_ANY))
Function Wait()
const BITMAP_OPAQUE router_len_tuner_setup_xpm[1]
#define LEGACY_HK_NAME(x)
Definition: actions.h:35
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:131
ACTION_MENU.
Definition: action_menu.h:43
void SetCurrentCursor(wxStockCursor aStockCursorID)
Function SetCurrentCursor Set the current cursor shape for this panel.
VIEW_CONTROLS class definition.
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:70
void Reset(RESET_REASON aReason) override
Function Reset() Brings 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.
Tool is invoked after being inactive.
Definition: tool_base.h:81
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
PLACEMENT_ALGO * Placer()
Definition: pns_router.h:219
static TOOL_ACTION routerTuneDiffPair
Activation of the Push and Shove router (diff pair tuning mode)
Definition: pcb_actions.h:187
static TOOL_ACTION cancelInteractive
Definition: actions.h:65
SIZES_SETTINGS m_savedSizes
Stores sizes settings between router invocations.
Definition: pns_tool_base.h:67
virtual void SetSnapping(bool aEnabled)
Function SetSnapping() Enables/disables snapping cursor to grid.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:109
void updateStatusPopup(PNS_TUNE_STATUS_POPUP &aPopup)
void UndoRedoBlock(bool aBlock=true)
Function UndoRedoBlock Enables/disable undo and redo operations.
MEANDER_SETTINGS.
Definition: pns_meander.h:57
void SetContextMenu(ACTION_MENU *aMenu, CONTEXT_MENU_TRIGGER aTrigger=CMENU_BUTTON)
Function SetContextMenu()
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:209
virtual void UpdateSettings(const MEANDER_SETTINGS &aSettings)
const BITMAP_OPAQUE router_len_tuner_dist_incr_xpm[1]
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
static TOOL_ACTION routerTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:190
int meanderSettingsDialog(const TOOL_EVENT &aEvent)
int Start() const
Definition: pns_layerset.h:83
PCB_BASE_EDIT_FRAME * frame() const
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
virtual void Reset(RESET_REASON aReason)=0
Function Reset() Brings the tool to a known, initial state.
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."), router_len_tuner_amplitude_incr_xpm)
#define NULL
const BITMAP_OPAQUE router_len_tuner_amplitude_incr_xpm[1]
PNS::MEANDER_SETTINGS m_savedMeanderSettings
int Net() const
Definition: pns_item.h:148
T Parameter() const
Function Parameter() Returns a non-standard parameter assigned to the event.
Definition: tool_event.h:435
void SetIcon(const BITMAP_OPAQUE *aIcon)
Function SetIcon() Assigns an icon for the entry.
Definition: action_menu.cpp:68
TOOL_EVENT.
Definition: tool_event.h:171
ITEM * m_startItem
Definition: pns_tool_base.h:68
const BITMAP_OPAQUE router_len_tuner_dist_decr_xpm[1]
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:373
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
void UpdateStatus(PNS::ROUTER *aRouter)
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Function ForceCursorPosition() Places the cursor immediately at a given point.
ROUTING_SETTINGS m_savedSettings
Stores routing settings between router invocations.
Definition: pns_tool_base.h:66
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
Function SetActiveLayer will change the currently active layer to aLayer.
virtual void Move(const wxPoint &aWhere)
void Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:230
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:175
virtual void SetAutoPan(bool aEnabled)
Function SetAutoPan Turns on/off auto panning (this feature is used when there is a tool active (eg.
const BITMAP_OPAQUE router_len_tuner_amplitude_decr_xpm[1]
void StopRouting()
Definition: pns_router.cpp:398
virtual void highlightNet(bool aEnabled, int aNetcode=-1)
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."), router_len_tuner_setup_xpm)
const BITMAP_OPAQUE router_len_tuner_xpm[1]
OPT< std::string > GetCommandStr() const
Definition: tool_event.h:463
ROUTER_MODE
Definition: pns_router.h:65
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."), router_len_tuner_dist_incr_xpm)
void SetTitle(const wxString &aTitle) override
Function SetTitle() Sets title for the menu.
Definition: action_menu.cpp:86
KIGFX::VIEW_CONTROLS * controls() const
void SetMode(ROUTER_MODE aMode)
Definition: pns_router.cpp:516
int MainLoop(const TOOL_EVENT &aEvent)
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
TOOL_BASE.
Definition: tool_base.h:67
TOOL_ACTION.
Definition: tool_action.h:46
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."), router_len_tuner_dist_decr_xpm)
RESET_REASON
Determines the reason of reset for a tool
Definition: tool_base.h:79
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."), router_len_tuner_amplitude_decr_xpm)
virtual void PopTool(const std::string &actionName)
void Activate()
Function Activate() Runs the tool.
ACTION_MENU * create() const override
Returns an instance of this class. It has to be overridden in inheriting classes.
#define _(s)
ROUTER_MODE Mode() const
Definition: pns_router.h:127
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
Function MeanderSettings()
ROUTING_SETTINGS & Settings()
Definition: pns_router.h:190
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:823
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:184
void DisplayTitle(bool aDisplay=true)
Function DisplayTitle() Decides whether a title for a pop up menu should be displayed.
Definition: action_menu.cpp:97