KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_shim.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) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <dialog_shim.h>
26#include <core/ignore.h>
27#include <kiway_player.h>
28#include <kiway.h>
29#include <pgm_base.h>
30#include <tool/tool_manager.h>
31#include <kiplatform/ui.h>
32
33#include <wx/display.h>
34#include <wx/evtloop.h>
35#include <wx/app.h>
36#include <wx/event.h>
37#include <wx/grid.h>
38#include <wx/bmpbuttn.h>
39#include <wx/textctrl.h>
40#include <wx/stc/stc.h>
41
42#include <algorithm>
43
46{
47 wxWindow* m_win;
48
49public:
50
51 WDO_ENABLE_DISABLE( wxWindow* aWindow ) :
52 m_win( aWindow )
53 {
54 if( m_win )
55 m_win->Disable();
56 }
57
59 {
60 if( m_win )
61 {
62 m_win->Enable();
63 m_win->Raise(); // let's focus back on the parent window
64 }
65 }
66};
67
68
69BEGIN_EVENT_TABLE( DIALOG_SHIM, wxDialog )
70 EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
71END_EVENT_TABLE()
72
73
74DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& title,
75 const wxPoint& pos, const wxSize& size, long style,
76 const wxString& name ) :
77 wxDialog( aParent, id, title, pos, size, style, name ),
78 KIWAY_HOLDER( nullptr, KIWAY_HOLDER::DIALOG ),
79 m_units( EDA_UNITS::MILLIMETRES ),
80 m_useCalculatedSize( false ),
81 m_firstPaintEvent( true ),
82 m_initialFocusTarget( nullptr ),
83 m_qmodal_loop( nullptr ),
84 m_qmodal_showing( false ),
85 m_qmodal_parent_disabler( nullptr ),
86 m_parentFrame( nullptr )
87{
88 KIWAY_HOLDER* kiwayHolder = nullptr;
89 m_initialSize = size;
90
91 if( aParent )
92 {
93 kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( aParent );
94
95 while( !kiwayHolder && aParent->GetParent() )
96 {
97 aParent = aParent->GetParent();
98 kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( aParent );
99 }
100 }
101
102 // Inherit units from parent
103 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
104 m_units = static_cast<EDA_BASE_FRAME*>( kiwayHolder )->GetUserUnits();
105 else if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::DIALOG )
106 m_units = static_cast<DIALOG_SHIM*>( kiwayHolder )->GetUserUnits();
107
108 // Don't mouse-warp after a dialog run from the context menu
109 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
110 {
111 m_parentFrame = static_cast<EDA_BASE_FRAME*>( kiwayHolder );
112 TOOL_MANAGER* toolMgr = m_parentFrame->GetToolManager();
113
114 if( toolMgr && toolMgr->IsContextMenuActive() )
115 toolMgr->VetoContextMenuMouseWarp();
116 }
117
118 // Set up the message bus
119 if( kiwayHolder )
120 SetKiway( this, &kiwayHolder->Kiway() );
121
122 if( HasKiway() )
123 Kiway().SetBlockingDialog( this );
124
125 Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
126 Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
127
128#ifdef __WINDOWS__
129 // On Windows, the app top windows can be brought to the foreground (at least temporarily)
130 // in certain circumstances such as when calling an external tool in Eeschema BOM generation.
131 // So set the parent frame (if exists) to top window to avoid this annoying behavior.
132 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
133 Pgm().App().SetTopWindow( (EDA_BASE_FRAME*) kiwayHolder );
134#endif
135
136 Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_SHIM::OnPaint ) );
137}
138
139
141{
142 // if the dialog is quasi-modal, this will end its event loop
143 if( IsQuasiModal() )
144 EndQuasiModal( wxID_CANCEL );
145
146 if( HasKiway() )
147 Kiway().SetBlockingDialog( nullptr );
148
150}
151
152
154{
155 // must be called from the constructor of derived classes,
156 // when all widgets are initialized, and therefore their size fixed
157
158 // SetSizeHints fixes the minimal size of sizers in the dialog
159 // (SetSizeHints calls Fit(), so no need to call it)
160 GetSizer()->SetSizeHints( this );
161}
162
163
164void DIALOG_SHIM::setSizeInDU( int x, int y )
165{
166 wxSize sz( x, y );
167 SetSize( ConvertDialogToPixels( sz ) );
168}
169
170
172{
173 wxSize sz( x, 0 );
174 return ConvertDialogToPixels( sz ).x;
175}
176
177
179{
180 wxSize sz( 0, y );
181 return ConvertDialogToPixels( sz ).y;
182}
183
184
185// our hashtable is an implementation secret, don't need or want it in a header file
186#include <hashtables.h>
187#include <typeinfo>
188
189static std::unordered_map<std::string, wxRect> class_map;
190
191
192void DIALOG_SHIM::SetPosition( const wxPoint& aNewPosition )
193{
194 wxDialog::SetPosition( aNewPosition );
195
196 // Now update the stored position:
197 const char* hash_key;
198
199 if( m_hash_key.size() )
200 {
201 // a special case like EDA_LIST_DIALOG, which has multiple uses.
202 hash_key = m_hash_key.c_str();
203 }
204 else
205 {
206 hash_key = typeid(*this).name();
207 }
208
209 std::unordered_map<std::string, wxRect>::iterator it = class_map.find( hash_key );
210
211 if( it == class_map.end() )
212 return;
213
214 wxRect rect = it->second;
215 rect.SetPosition( aNewPosition );
216
217 class_map[ hash_key ] = rect;
218}
219
220
221bool DIALOG_SHIM::Show( bool show )
222{
223 bool ret;
224 const char* hash_key;
225
226 if( m_hash_key.size() )
227 {
228 // a special case like EDA_LIST_DIALOG, which has multiple uses.
229 hash_key = m_hash_key.c_str();
230 }
231 else
232 {
233 hash_key = typeid(*this).name();
234 }
235
236 // Show or hide the window. If hiding, save current position and size.
237 // If showing, use previous position and size.
238 if( show )
239 {
240#ifndef __WINDOWS__
241 wxDialog::Raise(); // Needed on OS X and some other window managers (i.e. Unity)
242#endif
243 ret = wxDialog::Show( show );
244
245 // classname is key, returns a zeroed-out default wxRect if none existed before.
246 wxRect savedDialogRect = class_map[ hash_key ];
247
248 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
249 {
251 {
252 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
253 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
254 }
255 else
256 {
257 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
258 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
259 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
260 0 );
261 }
262 }
263 else if( m_initialSize != wxDefaultSize )
264 SetSize( m_initialSize );
265
266 // Be sure that the dialog appears in a visible area
267 // (the dialog position might have been stored at the time when it was
268 // shown on another display)
269 if( wxDisplay::GetFromWindow( this ) == wxNOT_FOUND )
270 Centre();
271 }
272 else
273 {
274 // Save the dialog's position & size before hiding, using classname as key
275 class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
276
277#ifdef __WXMAC__
278 if ( m_eventLoop )
279 m_eventLoop->Exit( GetReturnCode() ); // Needed for APP-MODAL dlgs on OSX
280#endif
281
282 ret = wxDialog::Show( show );
283 }
284
285 return ret;
286}
287
288
290{
291 const char* hash_key;
292
293 if( m_hash_key.size() )
294 {
295 // a special case like EDA_LIST_DIALOG, which has multiple uses.
296 hash_key = m_hash_key.c_str();
297 }
298 else
299 {
300 hash_key = typeid(*this).name();
301 }
302
303 std::unordered_map<std::string, wxRect>::iterator it = class_map.find( hash_key );
304
305 if( it == class_map.end() )
306 return;
307
308 wxRect rect = it->second;
309 rect.SetSize( wxSize( 0, 0 ) );
310 class_map[ hash_key ] = rect;
311}
312
313
314bool DIALOG_SHIM::Enable( bool enable )
315{
316 // so we can do logging of this state change:
317 return wxDialog::Enable( enable );
318}
319
320
321// Recursive descent doing a SelectAll() in wxTextCtrls.
322// MacOS User Interface Guidelines state that when tabbing to a text control all its
323// text should be selected. Since wxWidgets fails to implement this, we do it here.
324void DIALOG_SHIM::selectAllInTextCtrls( wxWindowList& children )
325{
326 for( wxWindow* child : children )
327 {
328 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
329 {
330 m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
331 textCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
332 nullptr, this );
333
334 // We don't currently run this on GTK because some window managers don't hide the
335 // selection in non-active controls, and other window managers do the selection
336 // automatically anyway.
337#if defined( __WXMAC__ ) || defined( __WXMSW__ )
338 if( !textCtrl->GetStringSelection().IsEmpty() )
339 {
340 // Respect an existing selection
341 }
342 else if( textCtrl->IsEditable() )
343 {
344 textCtrl->SelectAll();
345 }
346#else
347 ignore_unused( textCtrl );
348#endif
349 }
350 else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
351 {
352 m_beforeEditValues[ scintilla ] = scintilla->GetText();
353 scintilla->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
354 nullptr, this );
355
356 if( !scintilla->GetSelectedText().IsEmpty() )
357 {
358 // Respect an existing selection
359 }
360 else if( scintilla->IsEditable() )
361 {
362 scintilla->SelectAll();
363 }
364 }
365#ifdef __WXMAC__
366 // Temp hack for square (looking) buttons on OSX. Will likely be made redundant
367 // by the image store....
368 else if( dynamic_cast<wxBitmapButton*>( child ) != nullptr )
369 {
370 wxSize minSize( 29, 27 );
371 wxRect rect = child->GetRect();
372
373 child->ConvertDialogToPixels( minSize );
374
375 rect.Inflate( std::max( 0, minSize.x - rect.GetWidth() ),
376 std::max( 0, minSize.y - rect.GetHeight() ) );
377
378 child->SetMinSize( rect.GetSize() );
379 child->SetSize( rect );
380 }
381#endif
382 else
383 {
384 selectAllInTextCtrls( child->GetChildren() );
385 }
386 }
387}
388
389
390void DIALOG_SHIM::OnPaint( wxPaintEvent &event )
391{
393 {
395
396 selectAllInTextCtrls( GetChildren() );
397
400 else
401 KIPLATFORM::UI::ForceFocus( this ); // Focus the dialog itself
402
403 m_firstPaintEvent = false;
404 }
405
406 event.Skip();
407}
408
409
411{
412 if( !GetTitle().StartsWith( wxS( "*" ) ) )
413 SetTitle( wxS( "*" ) + GetTitle() );
414}
415
416
417/*
418 Quasi-Modal Mode Explained:
419
420 The gtk calls in wxDialog::ShowModal() cause event routing problems if that
421 modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up
422 and mostly works but does not respond to the window decoration close button.
423 There is no way to get around this without reversing the gtk calls temporarily.
424
425 Quasi-Modal mode is our own almost modal mode which disables only the parent
426 of the DIALOG_SHIM, leaving other frames operable and while staying captured in the
427 nested event loop. This avoids the gtk calls and leaves event routing pure
428 and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using
429 ShowQuasiModal() you have to use EndQuasiModal() in your dialogs and not
430 EndModal(). There is also IsQuasiModal() but its value can only be true
431 when the nested event loop is active. Do not mix the modal and quasi-modal
432 functions. Use one set or the other.
433
434 You might find this behavior preferable over a pure modal mode, and it was said
435 that only the Mac has this natively, but now other platforms have something
436 similar. You CAN use it anywhere for any dialog. But you MUST use it when
437 you want to use KIWAY_PLAYER::ShowModal() from a dialog event.
438*/
439
441{
442 // This is an exception safe way to zero a pointer before returning.
443 // Yes, even though DismissModal() clears this first normally, this is
444 // here in case there's an exception before the dialog is dismissed.
445 struct NULLER
446 {
447 void*& m_what;
448 NULLER( void*& aPtr ) : m_what( aPtr ) {}
449 ~NULLER() { m_what = nullptr; } // indeed, set it to NULL on destruction
450 } clear_this( (void*&) m_qmodal_loop );
451
452 // release the mouse if it's currently captured as the window having it
453 // will be disabled when this dialog is shown -- but will still keep the
454 // capture making it impossible to do anything in the modal dialog itself
455 wxWindow* win = wxWindow::GetCapture();
456 if( win )
457 win->ReleaseMouse();
458
459 // Get the optimal parent
460 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
461
462 wxASSERT_MSG( !m_qmodal_parent_disabler, wxT( "Caller using ShowQuasiModal() twice on same "
463 "window?" ) );
464
465 // quasi-modal: disable only my "optimal" parent
467
468 // Apple in its infinite wisdom will raise a disabled window before even passing
469 // us the event, so we have no way to stop it. Instead, we must set an order on
470 // the windows so that the quasi-modal will be pushed in front of the disabled
471 // window when it is raised.
473
474 Show( true );
475
476 m_qmodal_showing = true;
477
478 WX_EVENT_LOOP event_loop;
479
480 m_qmodal_loop = &event_loop;
481
482 event_loop.Run();
483
484 m_qmodal_showing = false;
485
486 return GetReturnCode();
487}
488
489
490void DIALOG_SHIM::EndQuasiModal( int retCode )
491{
492 // Hook up validator and transfer data from controls handling so quasi-modal dialogs
493 // handle validation in the same way as other dialogs.
494 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
495 return;
496
497 SetReturnCode( retCode );
498
499 if( !IsQuasiModal() )
500 {
501 wxFAIL_MSG( wxT( "Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
502 "wasn't called" ) );
503 return;
504 }
505
506 if( m_qmodal_loop )
507 {
508 if( m_qmodal_loop->IsRunning() )
509 m_qmodal_loop->Exit( 0 );
510 else
511 m_qmodal_loop->ScheduleExit( 0 );
512
513 m_qmodal_loop = nullptr;
514 }
515
517 m_qmodal_parent_disabler = nullptr;
518
519 Show( false );
520}
521
522
523void DIALOG_SHIM::OnCloseWindow( wxCloseEvent& aEvent )
524{
525 if( IsQuasiModal() )
526 {
527 EndQuasiModal( wxID_CANCEL );
528 return;
529 }
530
531 // This is mandatory to allow wxDialogBase::OnCloseWindow() to be called.
532 aEvent.Skip();
533}
534
535
536void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
537{
538 const int id = aEvent.GetId();
539
540 if( IsQuasiModal() )
541 {
542 if( id == GetAffirmativeId() )
543 {
544 EndQuasiModal( id );
545 }
546 else if( id == wxID_APPLY )
547 {
548 // Dialogs that provide Apply buttons should make sure data is valid before
549 // allowing a transfer, as there is no other way to indicate failure
550 // (i.e. the dialog can't refuse to close as it might with OK, because it
551 // isn't closing anyway)
552 if( Validate() )
553 {
554 ignore_unused( TransferDataFromWindow() );
555 }
556 }
557 else if( id == wxID_CANCEL )
558 {
559 EndQuasiModal( wxID_CANCEL );
560 }
561 else // not a standard button
562 {
563 aEvent.Skip();
564 }
565
566 return;
567 }
568
569 // This is mandatory to allow wxDialogBase::OnButton() to be called.
570 aEvent.Skip();
571}
572
573
574void DIALOG_SHIM::onChildSetFocus( wxFocusEvent& aEvent )
575{
576 // When setting focus to a text control reset the before-edit value.
577
578 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aEvent.GetEventObject() ) )
579 m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
580 else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() ) )
581 m_beforeEditValues[ scintilla ] = scintilla->GetText();
582
583 aEvent.Skip();
584}
585
586
587void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
588{
589 if( aEvt.GetKeyCode() == 'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
590 {
591 if( m_parentFrame )
592 {
594 return;
595 }
596 }
597 // shift-return (Mac default) or Ctrl-Return (GTK) for OK
598 else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
599 && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
600 {
601 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
602 return;
603 }
604 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
605 {
606 wxWindow* currentWindow = wxWindow::FindFocus();
607 int currentIdx = -1;
608 int delta = aEvt.ShiftDown() ? -1 : 1;
609
610 auto advance =
611 [&]( int& idx )
612 {
613 // Wrap-around modulus
614 int size = (int) m_tabOrder.size();
615 idx = ( ( idx + delta ) % size + size ) % size;
616 };
617
618 for( size_t i = 0; i < m_tabOrder.size(); ++i )
619 {
620 if( m_tabOrder[i] == currentWindow )
621 {
622 currentIdx = (int) i;
623 break;
624 }
625 }
626
627 if( currentIdx >= 0 )
628 {
629 advance( currentIdx );
630
631 //todo: We don't currently have non-textentry dialog boxes but this will break if
632 // we add them.
633#ifdef __APPLE__
634 while( dynamic_cast<wxTextEntry*>( m_tabOrder[ currentIdx ] ) == nullptr )
635 advance( currentIdx );
636#endif
637
638 m_tabOrder[ currentIdx ]->SetFocus();
639 return;
640 }
641 }
642 else if( aEvt.GetKeyCode() == WXK_ESCAPE )
643 {
644 wxObject* eventSource = aEvt.GetEventObject();
645
646 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( eventSource ) )
647 {
648 // First escape after an edit cancels edit
649 if( textCtrl->GetValue() != m_beforeEditValues[ textCtrl ] )
650 {
651 textCtrl->SetValue( m_beforeEditValues[ textCtrl ] );
652 textCtrl->SelectAll();
653 return;
654 }
655 }
656 else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( eventSource ) )
657 {
658 // First escape after an edit cancels edit
659 if( scintilla->GetText() != m_beforeEditValues[ scintilla ] )
660 {
661 scintilla->SetText( m_beforeEditValues[ scintilla ] );
662 scintilla->SelectAll();
663 return;
664 }
665 }
666 }
667
668 aEvt.Skip();
669}
670
671
672static void recursiveDescent( wxSizer* aSizer, std::map<int, wxString>& aLabels )
673{
674 wxStdDialogButtonSizer* sdbSizer = dynamic_cast<wxStdDialogButtonSizer*>( aSizer );
675
676 auto setupButton =
677 [&]( wxButton* aButton )
678 {
679 if( aLabels.count( aButton->GetId() ) > 0 )
680 {
681 aButton->SetLabel( aLabels[ aButton->GetId() ] );
682 }
683 else
684 {
685 // wxWidgets has an uneven track record when the language is changed on
686 // the fly so we set them even when they don't appear in the label map
687 switch( aButton->GetId() )
688 {
689 case wxID_OK: aButton->SetLabel( _( "&OK" ) ); break;
690 case wxID_CANCEL: aButton->SetLabel( _( "&Cancel" ) ); break;
691 case wxID_YES: aButton->SetLabel( _( "&Yes" ) ); break;
692 case wxID_NO: aButton->SetLabel( _( "&No" ) ); break;
693 case wxID_APPLY: aButton->SetLabel( _( "&Apply" ) ); break;
694 case wxID_SAVE: aButton->SetLabel( _( "&Save" ) ); break;
695 case wxID_HELP: aButton->SetLabel( _( "&Help" ) ); break;
696 case wxID_CONTEXT_HELP: aButton->SetLabel( _( "&Help" ) ); break;
697 }
698 }
699 };
700
701 if( sdbSizer )
702 {
703 if( sdbSizer->GetAffirmativeButton() )
704 setupButton( sdbSizer->GetAffirmativeButton() );
705
706 if( sdbSizer->GetApplyButton() )
707 setupButton( sdbSizer->GetApplyButton() );
708
709 if( sdbSizer->GetNegativeButton() )
710 setupButton( sdbSizer->GetNegativeButton() );
711
712 if( sdbSizer->GetCancelButton() )
713 setupButton( sdbSizer->GetCancelButton() );
714
715 if( sdbSizer->GetHelpButton() )
716 setupButton( sdbSizer->GetHelpButton() );
717
718 sdbSizer->Layout();
719
720 if( sdbSizer->GetAffirmativeButton() )
721 sdbSizer->GetAffirmativeButton()->SetDefault();
722 }
723
724 for( wxSizerItem* item : aSizer->GetChildren() )
725 {
726 if( item->GetSizer() )
727 recursiveDescent( item->GetSizer(), aLabels );
728 }
729}
730
731
732void DIALOG_SHIM::SetupStandardButtons( std::map<int, wxString> aLabels )
733{
734 recursiveDescent( GetSizer(), aLabels );
735}
const char * name
Definition: DXF_plotter.cpp:56
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:83
std::vector< wxWindow * > m_tabOrder
Definition: dialog_shim.h:223
void OnPaint(wxPaintEvent &event)
bool m_qmodal_showing
Definition: dialog_shim.h:218
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
bool Show(bool show) override
void onChildSetFocus(wxFocusEvent &aEvent)
void selectAllInTextCtrls(wxWindowList &children)
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
std::string m_hash_key
Definition: dialog_shim.h:204
bool m_firstPaintEvent
Definition: dialog_shim.h:213
int horizPixelsFromDU(int x) const
Convert an integer number of dialog units to pixels, horizontally.
void resetSize()
Clear the existing dialog size and position.
std::map< wxWindow *, wxString > m_beforeEditValues
Definition: dialog_shim.h:229
void setSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
bool IsQuasiModal() const
Definition: dialog_shim.h:106
WDO_ENABLE_DISABLE * m_qmodal_parent_disabler
Definition: dialog_shim.h:219
bool m_useCalculatedSize
Definition: dialog_shim.h:208
void EndQuasiModal(int retCode)
void OnModify()
void OnButton(wxCommandEvent &aEvent)
Properly handle the default button events when in the quasimodal mode when not calling EndQuasiModal ...
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
wxWindow * m_initialFocusTarget
Definition: dialog_shim.h:214
bool Enable(bool enable) override
void SetPosition(const wxPoint &aNewPosition)
Force the position of the dialog to a new position.
void OnCloseWindow(wxCloseEvent &aEvent)
Properly handle the wxCloseEvent when in the quasimodal mode when not calling EndQuasiModal which is ...
wxSize m_initialSize
Definition: dialog_shim.h:226
EDA_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:221
virtual void OnCharHook(wxKeyEvent &aEvt)
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
WX_EVENT_LOOP * m_qmodal_loop
Definition: dialog_shim.h:216
The base frame for deriving all KiCad main window classes.
virtual void ToggleUserUnits()
A mix in class which holds the location of a wxWindow's KIWAY.
Definition: kiway_holder.h:37
KIWAY & Kiway() const
Return a reference to the KIWAY that this object has an opportunity to participate in.
Definition: kiway_holder.h:53
bool HasKiway() const
Safety check before asking for the Kiway reference.
Definition: kiway_holder.h:63
HOLDER_TYPE GetType() const
Definition: kiway_holder.h:46
void SetBlockingDialog(wxWindow *aWin)
Definition: kiway.cpp:690
Master controller class:
Definition: tool_manager.h:55
bool IsContextMenuActive() const
True while processing a context menu.
Definition: tool_manager.h:413
void VetoContextMenuMouseWarp()
Disable mouse warping after the current context menu is closed.
Definition: tool_manager.h:424
EDA_UNITS GetUserUnits() const
Toggle a window's "enable" status to disabled, then enabled on destruction.
Definition: dialog_shim.cpp:46
WDO_ENABLE_DISABLE(wxWindow *aWindow)
Definition: dialog_shim.cpp:51
static void recursiveDescent(wxSizer *aSizer, std::map< int, wxString > &aLabels)
static std::unordered_map< std::string, wxRect > class_map
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
EDA_UNITS
Definition: eda_units.h:43
void ignore_unused(const T &)
Definition: ignore.h:24
KIWAY Kiway
#define WX_EVENT_LOOP
Definition: kiway_player.h:41
void FixupCancelButtonCmdKeyCollision(wxWindow *aWindow)
Definition: gtk/ui.cpp:71
void ReparentQuasiModal(wxNonOwnedWindow *aWindow)
Move a window's parent to be the top-level window and force the window to be on top.
Definition: gtk/ui.cpp:65
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:44
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:115
constexpr int delta