KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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 <kiplatform/ui.h>
25#include <tool/tool_manager.h>
26#include <tools/pcb_actions.h>
28#include "pns_router.h"
29#include "pns_meander_placer.h" // fixme: move settings to separate header
31
32#include "length_tuner_tool.h"
33#include <bitmaps.h>
35
36using namespace KIGFX;
37
38// Actions, being statically-defined, require specialized I18N handling. We continue to
39// use the _() macro so that string harvesting by the I18N framework doesn't have to be
40// specialized, but we don't translate on initialization and instead do it in the getters.
41
42#undef _
43#define _(s) s
44
45static TOOL_ACTION ACT_StartTuning( "pcbnew.LengthTuner.StartTuning",
47 'X', LEGACY_HK_NAME( "Add New Track" ),
48 _( "New Track" ), _( "Starts laying a new track." ) );
49
50static TOOL_ACTION ACT_EndTuning( "pcbnew.LengthTuner.EndTuning",
52 WXK_END, LEGACY_HK_NAME( "Stop laying the current track." ),
53 _( "End Track" ), _( "Stops laying the current meander." ) );
54
55static TOOL_ACTION ACT_SpacingIncrease( "pcbnew.LengthTuner.SpacingIncrease",
57 '1', LEGACY_HK_NAME( "Increase meander spacing by one step." ),
58 _( "Increase Spacing" ), _( "Increase meander spacing by one step." ),
60
61static TOOL_ACTION ACT_SpacingDecrease( "pcbnew.LengthTuner.SpacingDecrease",
63 '2', LEGACY_HK_NAME( "Decrease meander spacing by one step." ),
64 _( "Decrease Spacing" ), _( "Decrease meander spacing by one step." ),
66
67static TOOL_ACTION ACT_AmplIncrease( "pcbnew.LengthTuner.AmplIncrease",
69 '3', LEGACY_HK_NAME( "Increase meander amplitude by one step." ),
70 _( "Increase Amplitude" ), _( "Increase meander amplitude by one step." ),
72
73static TOOL_ACTION ACT_AmplDecrease( "pcbnew.LengthTuner.AmplDecrease",
75 '4', LEGACY_HK_NAME( "Decrease meander amplitude by one step." ),
76 _( "Decrease Amplitude" ), _( "Decrease meander amplitude by one step." ),
78
79#undef _
80#define _(s) wxGetTranslation((s))
81
82
84 TOOL_BASE( "pcbnew.LengthTuner" ),
85 m_inLengthTuner( false )
86{
87 // set the initial tune mode for the settings dialog,
88 // in case the dialog is opened before the tool is activated the first time
90 m_inLengthTuner = false;
91}
92
93
95{
96}
97
98
100{
101 m_inLengthTuner = false;
102
103 auto& menu = m_menu.GetMenu();
104
105 menu.SetTitle( _( "Length Tuner" ) );
106 menu.SetIcon( BITMAPS::router_len_tuner );
107 menu.DisplayTitle( true );
108
110
111 menu.AddSeparator();
112
118
119 return true;
120}
121
122
124{
125 if( aReason == RUN )
126 TOOL_BASE::Reset( aReason );
127}
128
129
131{
132 // fixme: wx code not allowed inside tools!
134
135 p.x += 20;
136 p.y += 20;
137
138 aPopup.UpdateStatus( m_router );
139 aPopup.Move( p );
140}
141
142
144{
145 if( m_startItem )
146 {
148
149 if( m_startItem->Net() )
150 highlightNets( true, { m_startItem->Net() } );
151 }
152
153 controls()->ForceCursorPosition( false );
154 controls()->SetAutoPan( true );
155
156 int layer = m_startItem ? m_startItem->Layer() : static_cast<int>( frame()->GetActiveLayer() );
157
159 {
161 highlightNets( false );
162 return;
163 }
164
165 auto placer = static_cast<PNS::MEANDER_PLACER_BASE*>( m_router->Placer() );
166
168 frame()->UndoRedoBlock( true );
169
171
172 // Create an instance of PNS_TUNE_STATUS_POPUP.
173 PNS_TUNE_STATUS_POPUP statusPopup( frame() );
174 statusPopup.Popup();
175 canvas()->SetStatusPopup( statusPopup.GetPanel() );
176
177 m_router->Move( end, nullptr );
178 updateStatusPopup( statusPopup );
179
180 auto setCursor =
181 [&]()
182 {
183 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
184 };
185
186 // Set initial cursor
187 setCursor();
188
189 while( TOOL_EVENT* evt = Wait() )
190 {
191 setCursor();
192
193 if( evt->IsCancelInteractive() || evt->IsActivate() )
194 {
195 break;
196 }
197 else if( evt->IsMotion() )
198 {
199 end = evt->Position();
200 m_router->Move( end, nullptr );
201 updateStatusPopup( statusPopup );
202 }
203 else if( evt->IsClick( BUT_LEFT ) )
204 {
205 if( m_router->FixRoute( evt->Position(), nullptr ) )
206 break;
207 }
208 else if( evt->IsClick( BUT_RIGHT ) )
209 {
211 }
212 else if( evt->IsAction( &ACT_EndTuning ) )
213 {
214 if( m_router->FixRoute( end, nullptr ) )
215 break;
216 }
217 else if( evt->IsAction( &ACT_AmplDecrease ) )
218 {
219 placer->AmplitudeStep( -1 );
220 m_router->Move( end, nullptr );
221 updateStatusPopup( statusPopup );
222 }
223 else if( evt->IsAction( &ACT_AmplIncrease ) )
224 {
225 placer->AmplitudeStep( 1 );
226 m_router->Move( end, nullptr );
227 updateStatusPopup( statusPopup );
228 }
229 else if(evt->IsAction( &ACT_SpacingDecrease ) )
230 {
231 placer->SpacingStep( -1 );
232 m_router->Move( end, nullptr );
233 updateStatusPopup( statusPopup );
234 }
235 else if( evt->IsAction( &ACT_SpacingIncrease ) )
236 {
237 placer->SpacingStep( 1 );
238 m_router->Move( end, nullptr );
239 updateStatusPopup( statusPopup );
240 }
241 else if( evt->IsAction( &PCB_ACTIONS::lengthTunerSettingsDialog ) )
242 {
243 statusPopup.Hide();
246 statusPopup.Show();
247 }
248 // TODO: It'd be nice to be able to say "don't allow any non-trivial editing actions",
249 // but we don't at present have that, so we just knock out some of the egregious ones.
250 else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
251 {
252 wxBell();
253 }
254 else
255 {
256 evt->SetPassEvent();
257 }
258 }
259
261 frame()->UndoRedoBlock( false );
262
263 canvas()->SetStatusPopup( nullptr );
264 controls()->SetAutoPan( false );
265 controls()->ForceCursorPosition( false );
266 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
267 highlightNets( false );
268}
269
270
272{
277
278 // in case tool is inactive, otherwise the event is handled in the tool loop
281}
282
283
285{
286 if( m_inLengthTuner )
287 return 0;
288
290
291 // Deselect all items
293
294 frame()->PushTool( aEvent );
295
296 auto setCursor =
297 [&]()
298 {
299 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
300 };
301
302 Activate();
303 // Must be done after Activate() so that it gets set into the correct context
304 controls()->ShowCursor( true );
305 // Set initial cursor
306 setCursor();
307
308 // Router mode must be set after Activate()
311
312 // Main loop: keep receiving events
313 while( TOOL_EVENT* evt = Wait() )
314 {
315 setCursor();
316
317 if( evt->IsCancelInteractive() || evt->IsActivate() )
318 {
319 break; // Finish
320 }
321 else if( evt->Action() == TA_UNDO_REDO_PRE )
322 {
324 }
325 else if( evt->Action() == TA_UNDO_REDO_POST || evt->Action() == TA_MODEL_CHANGE )
326 {
328 }
329 else if( evt->IsMotion() )
330 {
331 updateStartItem( *evt );
332 }
333 else if( evt->IsClick( BUT_LEFT ) || evt->IsAction( &ACT_StartTuning ) )
334 {
335 updateStartItem( *evt );
337 }
338 else if( evt->IsAction( &PCB_ACTIONS::lengthTunerSettingsDialog ) )
339 {
342 }
343 else if( evt->IsClick( BUT_RIGHT ) )
344 {
346 }
347 else
348 {
349 evt->SetPassEvent();
350 }
351 }
352
353 // Store routing settings till the next invocation
355
356 frame()->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
357 frame()->PopTool( aEvent );
358 return 0;
359}
360
361
363{
365
366 PNS::MEANDER_SETTINGS settings = placer ? placer->MeanderSettings() : m_savedMeanderSettings;
367 DIALOG_PNS_LENGTH_TUNING_SETTINGS settingsDlg( frame(), settings, m_lastTuneMode );
368
369 if( settingsDlg.ShowModal() == wxID_OK )
370 {
371 if( placer )
372 placer->UpdateSettings( settings );
373
374 m_savedMeanderSettings = settings;
375 }
376
377 return 0;
378}
#define LEGACY_HK_NAME(x)
Definition: actions.h:32
@ router_len_tuner_dist_incr
@ router_len_tuner_dist_decr
@ 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:244
static TOOL_ACTION routerTuneDiffPairSkew
Activation of the Push and Shove router (skew tuning mode)
Definition: pcb_actions.h:247
static TOOL_ACTION selectionClear
Clear the current selection.
Definition: pcb_actions.h:68
static TOOL_ACTION routerTuneSingleTrace
Activation of the Push and Shove router (tune single line mode)
Definition: pcb_actions.h:241
static TOOL_ACTION lengthTunerSettingsDialog
Definition: pcb_actions.h:260
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 NET_HANDLE Net() const
Definition: pns_item.h:193
virtual int Layer() const
Definition: pns_item.h:199
const LAYER_RANGE & Layers() const
Definition: pns_item.h:195
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:922
PLACEMENT_ALGO * Placer()
Definition: pns_router.h:215
void ClearWorld()
Definition: pns_router.cpp:106
void SyncWorld()
Definition: pns_router.cpp:96
const wxString & FailureReason() const
Definition: pns_router.h:213
bool FixRoute(const VECTOR2I &aP, ITEM *aItem, bool aForceFinish=false)
Definition: pns_router.cpp:875
bool StartRouting(const VECTOR2I &aP, ITEM *aItem, int aLayer)
Definition: pns_router.cpp:416
SIZES_SETTINGS & Sizes()
Definition: pns_router.h:210
bool Move(const VECTOR2I &aP, ITEM *aItem)
Definition: pns_router.cpp:476
virtual void updateStartItem(const TOOL_EVENT &aEvent, bool aIgnorePads=false)
virtual void highlightNets(bool aEnabled, std::set< NET_HANDLE > aNetcodes={})
SIZES_SETTINGS m_savedSizes
Definition: pns_tool_base.h:68
ITEM * m_startItem
Definition: pns_tool_base.h:69
ROUTER * m_router
Definition: pns_tool_base.h:78
VECTOR2I m_startSnapPoint
Definition: pns_tool_base.h:70
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:219
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:216
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:167
T Parameter() const
Return a parameter assigned to the event.
Definition: tool_event.h:461
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, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:145
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)
#define _(s)
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:247
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition: gtk/ui.cpp:588
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:46
@ TA_MODEL_CHANGE
Definition: tool_event.h:120
@ TA_UNDO_REDO_PRE
Definition: tool_event.h:105
@ TA_UNDO_REDO_POST
Definition: tool_event.h:108
@ BUT_LEFT
Definition: tool_event.h:131
@ BUT_RIGHT
Definition: tool_event.h:132