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-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Tomasz Wlostowski <[email protected]>
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
24#include <tool/tool_manager.h>
25#include <tools/pcb_actions.h>
27#include "pns_router.h"
28#include "pns_meander_placer.h" // fixme: move settings to separate header
30
31#include "length_tuner_tool.h"
32#include <bitmaps.h>
34
35using namespace KIGFX;
36
37// Actions, being statically-defined, require specialized I18N handling. We continue to
38// use the _() macro so that string harvesting by the I18N framework doesn't have to be
39// specialized, but we don't translate on initialization and instead do it in the getters.
40
41#undef _
42#define _(s) s
43
44static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning",
46 'X', LEGACY_HK_NAME( "Add New Track" ),
47 _( "New Track" ), _( "Starts laying a new track." ) );
48
49static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning",
51 WXK_END, LEGACY_HK_NAME( "Stop laying the current track." ),
52 _( "End Track" ), _( "Stops laying the current meander." ) );
53
54static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease",
56 '1', LEGACY_HK_NAME( "Increase meander spacing by one step." ),
57 _( "Increase Spacing" ), _( "Increase meander spacing by one step." ),
59
60static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease",
62 '2', LEGACY_HK_NAME( "Decrease meander spacing by one step." ),
63 _( "Decrease Spacing" ), _( "Decrease meander spacing by one step." ),
65
66static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease",
68 '3', LEGACY_HK_NAME( "Increase meander amplitude by one step." ),
69 _( "Increase Amplitude" ), _( "Increase meander amplitude by one step." ),
71
72static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease",
74 '4', LEGACY_HK_NAME( "Decrease meander amplitude by one step." ),
75 _( "Decrease Amplitude" ), _( "Decrease meander amplitude by one step." ),
77
78#undef _
79#define _(s) wxGetTranslation((s))
80
81
83 TOOL_BASE( "pcbnew.LengthTuner" )
84{
85 // set the initial tune mode for the settings dialog,
86 // in case the dialog is opened before the tool is activated the first time
88}
89
90
92{
93}
94
95
97{
98 auto& menu = m_menu.GetMenu();
99
100 menu.SetTitle( _( "Length Tuner" ) );
101 menu.SetIcon( BITMAPS::router_len_tuner );
102 menu.DisplayTitle( true );
103
105
106 menu.AddSeparator();
107
113
114 return true;
115}
116
117
119{
120 if( aReason == RUN )
121 TOOL_BASE::Reset( aReason );
122}
123
124
126{
127 // fixme: wx code not allowed inside tools!
128 wxPoint p = wxGetMousePosition();
129
130 p.x += 20;
131 p.y += 20;
132
133 aPopup.UpdateStatus( m_router );
134 aPopup.Move( p );
135}
136
137
139{
140 if( m_startItem )
141 {
143
144 if( m_startItem->Net() >= 0 )
145 highlightNets( true, { m_startItem->Net() } );
146 }
147
148 controls()->ForceCursorPosition( false );
149 controls()->SetAutoPan( true );
150
151 int layer = m_startItem ? m_startItem->Layer() : static_cast<int>( frame()->GetActiveLayer() );
152
154 {
156 highlightNets( false );
157 return;
158 }
159
160 auto placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
161
163 frame()->UndoRedoBlock( true );
164
166
167 // Create an instance of PNS_TUNE_STATUS_POPUP.
168 PNS_TUNE_STATUS_POPUP statusPopup( frame() );
169 statusPopup.Popup();
170 canvas()->SetStatusPopup( statusPopup.GetPanel() );
171
172 m_router->Move( end, nullptr );
173 updateStatusPopup( statusPopup );
174
175 auto setCursor =
176 [&]()
177 {
179 };
180
181 // Set initial cursor
182 setCursor();
183
184 while( TOOL_EVENT* evt = Wait() )
185 {
186 setCursor();
187
188 if( evt->IsCancelInteractive() || evt->IsActivate() )
189 {
190 break;
191 }
192 else if( evt->IsMotion() )
193 {
194 end = evt->Position();
195 m_router->Move( end, nullptr );
196 updateStatusPopup( statusPopup );
197 }
198 else if( evt->IsClick( BUT_LEFT ) )
199 {
200 if( m_router->FixRoute( evt->Position(), nullptr ) )
201 break;
202 }
203 else if( evt->IsClick( BUT_RIGHT ) )
204 {
206 }
207 else if( evt->IsAction( &ACT_EndTuning ) )
208 {
209 if( m_router->FixRoute( end, nullptr ) )
210 break;
211 }
212 else if( evt->IsAction( &ACT_AmplDecrease ) )
213 {
214 placer->AmplitudeStep( -1 );
215 m_router->Move( end, nullptr );
216 updateStatusPopup( statusPopup );
217 }
218 else if( evt->IsAction( &ACT_AmplIncrease ) )
219 {
220 placer->AmplitudeStep( 1 );
221 m_router->Move( end, nullptr );
222 updateStatusPopup( statusPopup );
223 }
224 else if(evt->IsAction( &ACT_SpacingDecrease ) )
225 {
226 placer->SpacingStep( -1 );
227 m_router->Move( end, nullptr );
228 updateStatusPopup( statusPopup );
229 }
230 else if( evt->IsAction( &ACT_SpacingIncrease ) )
231 {
232 placer->SpacingStep( 1 );
233 m_router->Move( end, nullptr );
234 updateStatusPopup( statusPopup );
235 }
236 else if( evt->IsAction( &PCB_ACTIONS::lengthTunerSettingsDialog ) )
237 {
238 statusPopup.Hide();
241 statusPopup.Show();
242 }
243 // TODO: It'd be nice to be able to say "don't allow any non-trivial editing actions",
244 // but we don't at present have that, so we just knock out some of the egregious ones.
245 else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
246 {
247 wxBell();
248 }
249 else
250 {
251 evt->SetPassEvent();
252 }
253 }
254
256 frame()->UndoRedoBlock( false );
257
258 canvas()->SetStatusPopup( nullptr );
259 controls()->SetAutoPan( false );
260 controls()->ForceCursorPosition( false );
262 highlightNets( false );
263}
264
265
267{
272
273 // in case tool is inactive, otherwise the event is handled in the tool loop
276}
277
278
280{
281 // Deselect all items
283
284 frame()->PushTool( aEvent );
285
286 auto setCursor =
287 [&]()
288 {
290 };
291
292 Activate();
293 // Must be done after Activate() so that it gets set into the correct context
294 controls()->ShowCursor( true );
295 // Set initial cursor
296 setCursor();
297
298 // Router mode must be set after Activate()
301
302 // Main loop: keep receiving events
303 while( TOOL_EVENT* evt = Wait() )
304 {
305 setCursor();
306
307 if( evt->IsCancelInteractive() || evt->IsActivate() )
308 {
309 break; // Finish
310 }
311 else if( evt->Action() == TA_UNDO_REDO_PRE )
312 {
314 }
315 else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
316 {
318 }
319 else if( evt->IsMotion() )
320 {
321 updateStartItem( *evt );
322 }
323 else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
324 {
325 updateStartItem( *evt );
327 }
328 else if( evt->IsAction( &PCB_ACTIONS::lengthTunerSettingsDialog ) )
329 {
332 }
333 else if( evt->IsClick( BUT_RIGHT ) )
334 {
336 }
337 else
338 {
339 evt->SetPassEvent();
340 }
341 }
342
343 // Store routing settings till the next invocation
345
347 frame()->PopTool( aEvent );
348 return 0;
349}
350
351
353{
355
356 PNS::MEANDER_SETTINGS settings = placer ? placer->MeanderSettings() : m_savedMeanderSettings;
357 DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( frame(), settings, m_lastTuneMode );
358
359 if( settingsDlg.ShowModal() == wxID_OK )
360 {
361 if( placer )
362 placer->UpdateSettings( settings );
363
364 m_savedMeanderSettings = settings;
365 }
366
367 return 0;
368}
#define LEGACY_HK_NAME(x)
Definition: actions.h:32
@ router_len_tuner_dist_incr
@ router_len_tuner_dist_decr
@ router_len_tuner
@ router_len_tuner_amplitude_incr
@ router_len_tuner_amplitude_decr
static TOOL_ACTION cancelInteractive
Definition: actions.h:63
void SetTitle(const wxString &aTitle) override
Set title for the menu.
Definition: action_menu.cpp:87
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...
void SetCurrentCursor(KICURSOR aCursor)
Set the current cursor shape for this panel.
void SetStatusPopup(wxWindow *aPopup)
virtual void ForceCursorPosition(bool aEnabled, const VECTOR2D &aPosition=VECTOR2D(0, 0))
Place the cursor immediately at a given point.
virtual void ShowCursor(bool aEnabled)
Enable or disables display of cursor.
virtual VECTOR2D GetMousePosition(bool aWorldCoordinates=true) const =0
Return the current mouse pointer position.
virtual void SetAutoPan(bool aEnabled)
Turn on/off auto panning (this feature is used when there is a tool active (eg.
int Start() const
Definition: pns_layerset.h:82
int meanderSettingsDialog(const TOOL_EVENT &aEvent)
void Reset(RESET_REASON aReason) override
Bring the tool to a known, initial state.
PNS::ROUTER_MODE m_lastTuneMode
int MainLoop(const TOOL_EVENT &aEvent)
PNS::MEANDER_SETTINGS m_savedMeanderSettings
bool Init() override
Init() is called once upon a registration of the tool.
void updateStatusPopup(PNS_TUNE_STATUS_POPUP &aPopup)
void setTransitions() override
This method is meant to be overridden in order to specify handlers for events.
static TOOL_ACTION routerTuneDiffPair
Activation of the Push and Shove router (diff pair tuning mode)
Definition: pcb_actions.h:217
static TOOL_ACTION routerTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:220
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:59
static TOOL_ACTION routerTuneSingleTrace
Activation of the Push and Shove router (tune single line mode)
Definition: pcb_actions.h:214
static TOOL_ACTION lengthTunerSettingsDialog
Definition: pcb_actions.h:233
void UndoRedoBlock(bool aBlock=true)
Enable/disable undo and redo operations.
virtual PCB_LAYER_ID GetActiveLayer() const
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
virtual void SetActiveLayer(PCB_LAYER_ID aLayer)
PCB_BASE_EDIT_FRAME * frame() const
KIGFX::VIEW_CONTROLS * controls() const
PCB_DRAW_PANEL_GAL * canvas() const
const PCB_SELECTION & selection() const
virtual int Layer() const
Definition: pns_item.h:160
const LAYER_RANGE & Layers() const
Definition: pns_item.h:156
int Net() const
Definition: pns_item.h:154
Base class for Single trace & Differential pair meandering tools, as both of them share a lot of code...
virtual void UpdateSettings(const MEANDER_SETTINGS &aSettings)
virtual const MEANDER_SETTINGS & MeanderSettings() const
Return the current meandering configuration.
Dimensions for the meandering algorithm.
Definition: pns_meander.h:59
void SetMode(ROUTER_MODE aMode)
void StopRouting()
Definition: pns_router.cpp:906
PLACEMENT_ALGO * Placer()
Definition: pns_router.h:209
void ClearWorld()
Definition: pns_router.cpp:102
void SyncWorld()
Definition: pns_router.cpp:92
const wxString & FailureReason() const
Definition: pns_router.h:207
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:861
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:390
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:204
bool Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:459
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
virtual void highlightNets(bool aEnabled, std::set< int > aNetcodes={})
SIZES_SETTINGS m_savedSizes
Definition: pns_tool_base.h:69
ITEM * m_startItem
Definition: pns_tool_base.h:70
ROUTER * m_router
Definition: pns_tool_base.h:79
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:71
void UpdateStatus(PNS::ROUTER *aRouter)
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
wxWindow * GetPanel()
Definition: status_popup.h:62
virtual void Popup(wxWindow *aFocus=nullptr)
virtual void Move(const wxPoint &aWhere)
virtual void PopTool(const TOOL_EVENT &aEvent)
Pops a tool from the stack.
virtual void PushTool(const TOOL_EVENT &aEvent)
NB: the definition of "tool" is different at the user level.
Represent a single user action.
Definition: tool_action.h:68
Base abstract interface for all kinds of tools.
Definition: tool_base.h:66
virtual void Reset(RESET_REASON aReason)=0
Bring the tool to a known, initial state.
KIGFX::VIEW_CONTROLS * getViewControls() const
Return the instance of VIEW_CONTROLS object used in the application.
Definition: tool_base.cpp:42
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:214
RESET_REASON
Determine the reason of reset for a tool.
Definition: tool_base.h:78
@ RUN
Tool is invoked after being inactive.
Definition: tool_base.h:79
Generic, UI-independent tool event.
Definition: tool_event.h:156
T Parameter() const
Return a non-standard parameter assigned to the event.
Definition: tool_event.h:442
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).
TOOL_MENU m_menu
The functions below are not yet implemented - their interface may change.
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.
void Activate()
Run the tool.
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Run the specified action.
Definition: tool_manager.h:142
CONDITIONAL_MENU & GetMenu()
Definition: tool_menu.cpp:44
void ShowContextMenu(SELECTION &aSelection)
Helper function to set and immediately show a CONDITIONAL_MENU in concert with the given SELECTION.
Definition: tool_menu.cpp:57
static bool IsZoneFillAction(const TOOL_EVENT *aEvent)
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)
static TOOL_ACTION ACT_StartTuning("pcbnew.LengthTuner.StartTuning", AS_CONTEXT, 'X', LEGACY_HK_NAME("Add New Track"), _("New Track"), _("Starts laying a new track."))
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)
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)
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."))
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)
#define _(s)
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:266
ROUTER_MODE
Definition: pns_router.h:62
@ PNS_MODE_TUNE_SINGLE
Definition: pns_router.h:65
std::vector< FAB_LAYER_COLOR > dummy
@ AS_CONTEXT
Action belongs to a particular tool (i.e. a part of a pop-up menu)
Definition: tool_action.h:43
@ TA_MODEL_CHANGE
Definition: tool_event.h:116
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:101
@ TA_UNDO_REDO_POST
Definition: tool_event.h:104
@ BUT_LEFT
Definition: tool_event.h:127
@ BUT_RIGHT
Definition: tool_event.h:128