KiCad PCB EDA Suite
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-2022 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 <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 // If dialog has a grid and the grid has an active cell editor
71 // Esc key closes cell editor, otherwise Esc key closes the dialog.
72 EVT_GRID_EDITOR_SHOWN( DIALOG_SHIM::OnGridEditorShown )
73 EVT_GRID_EDITOR_HIDDEN( DIALOG_SHIM::OnGridEditorHidden )
74 EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
75END_EVENT_TABLE()
76
77
78DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& title,
79 const wxPoint& pos, const wxSize& size, long style,
80 const wxString& name ) :
81 wxDialog( aParent, id, title, pos, size, style, name ),
82 KIWAY_HOLDER( nullptr, KIWAY_HOLDER::DIALOG ),
83 m_units( EDA_UNITS::MILLIMETRES ),
84 m_useCalculatedSize( false ),
85 m_firstPaintEvent( true ),
86 m_initialFocusTarget( nullptr ),
87 m_qmodal_loop( nullptr ),
88 m_qmodal_showing( false ),
89 m_qmodal_parent_disabler( nullptr ),
90 m_parentFrame( nullptr )
91{
92 KIWAY_HOLDER* kiwayHolder = nullptr;
93 m_initialSize = size;
94
95 if( aParent )
96 {
97 kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( aParent );
98
99 while( !kiwayHolder && aParent->GetParent() )
100 {
101 aParent = aParent->GetParent();
102 kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( aParent );
103 }
104 }
105
106 // Inherit units from parent
107 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
108 m_units = static_cast<EDA_BASE_FRAME*>( kiwayHolder )->GetUserUnits();
109 else if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::DIALOG )
110 m_units = static_cast<DIALOG_SHIM*>( kiwayHolder )->GetUserUnits();
111
112 // Don't mouse-warp after a dialog run from the context menu
113 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
114 {
115 m_parentFrame = static_cast<EDA_BASE_FRAME*>( kiwayHolder );
116 TOOL_MANAGER* toolMgr = m_parentFrame->GetToolManager();
117
118 if( toolMgr && toolMgr->IsContextMenuActive() )
119 toolMgr->VetoContextMenuMouseWarp();
120 }
121
122 // Set up the message bus
123 if( kiwayHolder )
124 SetKiway( this, &kiwayHolder->Kiway() );
125
126 if( HasKiway() )
127 Kiway().SetBlockingDialog( this );
128
129 Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
130 Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
131
132#ifdef __WINDOWS__
133 // On Windows, the app top windows can be brought to the foreground (at least temporarily)
134 // in certain circumstances such as when calling an external tool in Eeschema BOM generation.
135 // So set the parent frame (if exists) to top window to avoid this annoying behavior.
136 if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
137 Pgm().App().SetTopWindow( (EDA_BASE_FRAME*) kiwayHolder );
138#endif
139
140 Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_SHIM::OnPaint ) );
141}
142
143
145{
146 // if the dialog is quasi-modal, this will end its event loop
147 if( IsQuasiModal() )
148 EndQuasiModal( wxID_CANCEL );
149
150 if( HasKiway() )
151 Kiway().SetBlockingDialog( nullptr );
152
154}
155
156
158{
159 // must be called from the constructor of derived classes,
160 // when all widgets are initialized, and therefore their size fixed
161
162 // SetSizeHints fixes the minimal size of sizers in the dialog
163 // (SetSizeHints calls Fit(), so no need to call it)
164 GetSizer()->SetSizeHints( this );
165}
166
167
168void DIALOG_SHIM::setSizeInDU( int x, int y )
169{
170 wxSize sz( x, y );
171 SetSize( ConvertDialogToPixels( sz ) );
172}
173
174
176{
177 wxSize sz( x, 0 );
178 return ConvertDialogToPixels( sz ).x;
179}
180
181
183{
184 wxSize sz( 0, y );
185 return ConvertDialogToPixels( sz ).y;
186}
187
188
189// our hashtable is an implementation secret, don't need or want it in a header file
190#include <hashtables.h>
191#include <typeinfo>
192
193static std::unordered_map<std::string, wxRect> class_map;
194
195
196void DIALOG_SHIM::SetPosition( const wxPoint& aNewPosition )
197{
198 wxDialog::SetPosition( aNewPosition );
199
200 // Now update the stored position:
201 const char* hash_key;
202
203 if( m_hash_key.size() )
204 {
205 // a special case like EDA_LIST_DIALOG, which has multiple uses.
206 hash_key = m_hash_key.c_str();
207 }
208 else
209 {
210 hash_key = typeid(*this).name();
211 }
212
213 std::unordered_map<std::string, wxRect>::iterator it = class_map.find( hash_key );
214
215 if( it == class_map.end() )
216 return;
217
218 wxRect rect = it->second;
219 rect.SetPosition( aNewPosition );
220
221 class_map[ hash_key ] = rect;
222}
223
224
225bool DIALOG_SHIM::Show( bool show )
226{
227 bool ret;
228 const char* hash_key;
229
230 if( m_hash_key.size() )
231 {
232 // a special case like EDA_LIST_DIALOG, which has multiple uses.
233 hash_key = m_hash_key.c_str();
234 }
235 else
236 {
237 hash_key = typeid(*this).name();
238 }
239
240 // Show or hide the window. If hiding, save current position and size.
241 // If showing, use previous position and size.
242 if( show )
243 {
244#ifndef __WINDOWS__
245 wxDialog::Raise(); // Needed on OS X and some other window managers (i.e. Unity)
246#endif
247 ret = wxDialog::Show( show );
248
249 // classname is key, returns a zeroed-out default wxRect if none existed before.
250 wxRect savedDialogRect = class_map[ hash_key ];
251
252 if( savedDialogRect.GetSize().x != 0 && savedDialogRect.GetSize().y != 0 )
253 {
255 {
256 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
257 wxDialog::GetSize().x, wxDialog::GetSize().y, 0 );
258 }
259 else
260 {
261 SetSize( savedDialogRect.GetPosition().x, savedDialogRect.GetPosition().y,
262 std::max( wxDialog::GetSize().x, savedDialogRect.GetSize().x ),
263 std::max( wxDialog::GetSize().y, savedDialogRect.GetSize().y ),
264 0 );
265 }
266 }
267 else if( m_initialSize != wxDefaultSize )
268 SetSize( m_initialSize );
269
270 // Be sure that the dialog appears in a visible area
271 // (the dialog position might have been stored at the time when it was
272 // shown on another display)
273 if( wxDisplay::GetFromWindow( this ) == wxNOT_FOUND )
274 Centre();
275 }
276 else
277 {
278 // Save the dialog's position & size before hiding, using classname as key
279 class_map[ hash_key ] = wxRect( wxDialog::GetPosition(), wxDialog::GetSize() );
280
281#ifdef __WXMAC__
282 if ( m_eventLoop )
283 m_eventLoop->Exit( GetReturnCode() ); // Needed for APP-MODAL dlgs on OSX
284#endif
285
286 ret = wxDialog::Show( show );
287 }
288
289 return ret;
290}
291
292
294{
295 const char* hash_key;
296
297 if( m_hash_key.size() )
298 {
299 // a special case like EDA_LIST_DIALOG, which has multiple uses.
300 hash_key = m_hash_key.c_str();
301 }
302 else
303 {
304 hash_key = typeid(*this).name();
305 }
306
307 std::unordered_map<std::string, wxRect>::iterator it = class_map.find( hash_key );
308
309 if( it == class_map.end() )
310 return;
311
312 wxRect rect = it->second;
313 rect.SetSize( wxSize( 0, 0 ) );
314 class_map[ hash_key ] = rect;
315}
316
317
318bool DIALOG_SHIM::Enable( bool enable )
319{
320 // so we can do logging of this state change:
321 return wxDialog::Enable( enable );
322}
323
324
325// Recursive descent doing a SelectAll() in wxTextCtrls.
326// MacOS User Interface Guidelines state that when tabbing to a text control all its
327// text should be selected. Since wxWidgets fails to implement this, we do it here.
328static void selectAllInTextCtrls( wxWindowList& children )
329{
330 for( wxWindow* child : children )
331 {
332 if( wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child ) )
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( !childTextCtrl->GetStringSelection().IsEmpty() )
339 {
340 // Respect an existing selection
341 }
342 else
343 {
344 childTextCtrl->SelectAll();
345 }
346#else
347 ignore_unused( childTextCtrl );
348#endif
349 }
350 else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
351 {
352 if( !scintilla->GetSelectedText().IsEmpty() )
353 {
354 // Respect an existing selection
355 }
356 else if( !scintilla->GetText().Contains( wxT( "\n") ) )
357 {
358 scintilla->SelectAll();
359 }
360 }
361#ifdef __WXMAC__
362 // Temp hack for square (looking) buttons on OSX. Will likely be made redundant
363 // by the image store....
364 else if( dynamic_cast<wxBitmapButton*>( child ) != nullptr )
365 {
366 wxSize minSize( 29, 27 );
367 wxRect rect = child->GetRect();
368
369 child->ConvertDialogToPixels( minSize );
370
371 rect.Inflate( std::max( 0, minSize.x - rect.GetWidth() ),
372 std::max( 0, minSize.y - rect.GetHeight() ) );
373
374 child->SetMinSize( rect.GetSize() );
375 child->SetSize( rect );
376 }
377#endif
378 else
379 {
380 selectAllInTextCtrls( child->GetChildren() );
381 }
382 }
383}
384
385
386void DIALOG_SHIM::OnPaint( wxPaintEvent &event )
387{
389 {
391
392 selectAllInTextCtrls( GetChildren() );
393
396 else
397 KIPLATFORM::UI::ForceFocus( this ); // Focus the dialog itself
398
399 m_firstPaintEvent = false;
400 }
401
402 event.Skip();
403}
404
405
407{
408 if( !GetTitle().StartsWith( wxS( "*" ) ) )
409 SetTitle( wxS( "*" ) + GetTitle() );
410}
411
412
413/*
414 Quasi-Modal Mode Explained:
415
416 The gtk calls in wxDialog::ShowModal() cause event routing problems if that
417 modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up
418 and mostly works but does not respond to the window decoration close button.
419 There is no way to get around this without reversing the gtk calls temporarily.
420
421 Quasi-Modal mode is our own almost modal mode which disables only the parent
422 of the DIALOG_SHIM, leaving other frames operable and while staying captured in the
423 nested event loop. This avoids the gtk calls and leaves event routing pure
424 and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using
425 ShowQuasiModal() you have to use EndQuasiModal() in your dialogs and not
426 EndModal(). There is also IsQuasiModal() but its value can only be true
427 when the nested event loop is active. Do not mix the modal and quasi-modal
428 functions. Use one set or the other.
429
430 You might find this behavior preferable over a pure modal mode, and it was said
431 that only the Mac has this natively, but now other platforms have something
432 similar. You CAN use it anywhere for any dialog. But you MUST use it when
433 you want to use KIWAY_PLAYER::ShowModal() from a dialog event.
434*/
435
437{
438 // This is an exception safe way to zero a pointer before returning.
439 // Yes, even though DismissModal() clears this first normally, this is
440 // here in case there's an exception before the dialog is dismissed.
441 struct NULLER
442 {
443 void*& m_what;
444 NULLER( void*& aPtr ) : m_what( aPtr ) {}
445 ~NULLER() { m_what = nullptr; } // indeed, set it to NULL on destruction
446 } clear_this( (void*&) m_qmodal_loop );
447
448 // release the mouse if it's currently captured as the window having it
449 // will be disabled when this dialog is shown -- but will still keep the
450 // capture making it impossible to do anything in the modal dialog itself
451 wxWindow* win = wxWindow::GetCapture();
452 if( win )
453 win->ReleaseMouse();
454
455 // Get the optimal parent
456 wxWindow* parent = GetParentForModalDialog( GetParent(), GetWindowStyle() );
457
458 wxASSERT_MSG( !m_qmodal_parent_disabler, wxT( "Caller using ShowQuasiModal() twice on same "
459 "window?" ) );
460
461 // quasi-modal: disable only my "optimal" parent
463
464 // Apple in its infinite wisdom will raise a disabled window before even passing
465 // us the event, so we have no way to stop it. Instead, we must set an order on
466 // the windows so that the quasi-modal will be pushed in front of the disabled
467 // window when it is raised.
469
470 Show( true );
471
472 m_qmodal_showing = true;
473
474 WX_EVENT_LOOP event_loop;
475
476 m_qmodal_loop = &event_loop;
477
478 event_loop.Run();
479
480 m_qmodal_showing = false;
481
482 return GetReturnCode();
483}
484
485
486void DIALOG_SHIM::EndQuasiModal( int retCode )
487{
488 // Hook up validator and transfer data from controls handling so quasi-modal dialogs
489 // handle validation in the same way as other dialogs.
490 if( ( retCode == wxID_OK ) && ( !Validate() || !TransferDataFromWindow() ) )
491 return;
492
493 SetReturnCode( retCode );
494
495 if( !IsQuasiModal() )
496 {
497 wxFAIL_MSG( wxT( "Either DIALOG_SHIM::EndQuasiModal was called twice, or ShowQuasiModal"
498 "wasn't called" ) );
499 return;
500 }
501
502 if( m_qmodal_loop )
503 {
504 if( m_qmodal_loop->IsRunning() )
505 m_qmodal_loop->Exit( 0 );
506 else
507 m_qmodal_loop->ScheduleExit( 0 );
508
509 m_qmodal_loop = nullptr;
510 }
511
513 m_qmodal_parent_disabler = nullptr;
514
515 Show( false );
516}
517
518
519void DIALOG_SHIM::OnCloseWindow( wxCloseEvent& aEvent )
520{
521 if( IsQuasiModal() )
522 {
523 EndQuasiModal( wxID_CANCEL );
524 return;
525 }
526
527 // This is mandatory to allow wxDialogBase::OnCloseWindow() to be called.
528 aEvent.Skip();
529}
530
531
532void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
533{
534 const int id = aEvent.GetId();
535
536 // If we are pressing a button to exit, we need to enable the escapeID
537 // otherwise the dialog does not process cancel
538 if( id == wxID_CANCEL )
539 SetEscapeId( wxID_ANY );
540
541 if( IsQuasiModal() )
542 {
543 if( id == GetAffirmativeId() )
544 {
545 EndQuasiModal( id );
546 }
547 else if( id == wxID_APPLY )
548 {
549 // Dialogs that provide Apply buttons should make sure data is valid before
550 // allowing a transfer, as there is no other way to indicate failure
551 // (i.e. the dialog can't refuse to close as it might with OK, because it
552 // isn't closing anyway)
553 if( Validate() )
554 {
555 ignore_unused( TransferDataFromWindow() );
556 }
557 }
558 else if( id == GetEscapeId() || (id == wxID_CANCEL && GetEscapeId() == wxID_ANY) )
559 {
560 EndQuasiModal( wxID_CANCEL );
561 }
562 else // not a standard button
563 {
564 aEvent.Skip();
565 }
566
567 return;
568 }
569
570 // This is mandatory to allow wxDialogBase::OnButton() to be called.
571 aEvent.Skip();
572}
573
574
575void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
576{
577 if( aEvt.GetKeyCode() == 'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
578 {
579 if( m_parentFrame )
580 {
582 return;
583 }
584 }
585 // shift-return (Mac default) or Ctrl-Return (GTK) for OK
586 else if( aEvt.GetKeyCode() == WXK_RETURN && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
587 {
588 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
589 return;
590 }
591 else if( aEvt.GetKeyCode() == WXK_TAB && !aEvt.ControlDown() )
592 {
593 wxWindow* currentWindow = wxWindow::FindFocus();
594 int currentIdx = -1;
595 int delta = aEvt.ShiftDown() ? -1 : 1;
596
597 auto advance =
598 [&]( int& idx )
599 {
600 // Wrap-around modulus
601 int size = (int) m_tabOrder.size();
602 idx = ( ( idx + delta ) % size + size ) % size;
603 };
604
605 for( size_t i = 0; i < m_tabOrder.size(); ++i )
606 {
607 if( m_tabOrder[i] == currentWindow )
608 {
609 currentIdx = (int) i;
610 break;
611 }
612 }
613
614 if( currentIdx >= 0 )
615 {
616 advance( currentIdx );
617
618 //todo: We don't currently have non-textentry dialog boxes but this will break if
619 // we add them.
620#ifdef __APPLE__
621 while( dynamic_cast<wxTextEntry*>( m_tabOrder[ currentIdx ] ) == nullptr )
622 advance( currentIdx );
623#endif
624
625 m_tabOrder[ currentIdx ]->SetFocus();
626 return;
627 }
628 }
629
630 aEvt.Skip();
631}
632
633
634void DIALOG_SHIM::OnGridEditorShown( wxGridEvent& event )
635{
636 SetEscapeId( wxID_NONE );
637 event.Skip();
638}
639
640
641void DIALOG_SHIM::OnGridEditorHidden( wxGridEvent& event )
642{
643 SetEscapeId( wxID_ANY );
644 event.Skip();
645}
646
647
648static void recursiveDescent( wxSizer* aSizer, std::map<int, wxString>& aLabels )
649{
650 wxStdDialogButtonSizer* sdbSizer = dynamic_cast<wxStdDialogButtonSizer*>( aSizer );
651
652 auto setupButton =
653 [&]( wxButton* aButton )
654 {
655 if( aLabels.count( aButton->GetId() ) > 0 )
656 {
657 aButton->SetLabel( aLabels[ aButton->GetId() ] );
658 }
659 else
660 {
661 // wxWidgets has an uneven track record when the language is changed on
662 // the fly so we set them even when they don't appear in the label map
663 switch( aButton->GetId() )
664 {
665 case wxID_OK: aButton->SetLabel( _( "&OK" ) ); break;
666 case wxID_CANCEL: aButton->SetLabel( _( "&Cancel" ) ); break;
667 case wxID_YES: aButton->SetLabel( _( "&Yes" ) ); break;
668 case wxID_NO: aButton->SetLabel( _( "&No" ) ); break;
669 case wxID_APPLY: aButton->SetLabel( _( "&Apply" ) ); break;
670 case wxID_SAVE: aButton->SetLabel( _( "&Save" ) ); break;
671 case wxID_HELP: aButton->SetLabel( _( "&Help" ) ); break;
672 case wxID_CONTEXT_HELP: aButton->SetLabel( _( "&Help" ) ); break;
673 }
674 }
675 };
676
677 if( sdbSizer )
678 {
679 if( sdbSizer->GetAffirmativeButton() )
680 setupButton( sdbSizer->GetAffirmativeButton() );
681
682 if( sdbSizer->GetApplyButton() )
683 setupButton( sdbSizer->GetApplyButton() );
684
685 if( sdbSizer->GetNegativeButton() )
686 setupButton( sdbSizer->GetNegativeButton() );
687
688 if( sdbSizer->GetCancelButton() )
689 setupButton( sdbSizer->GetCancelButton() );
690
691 if( sdbSizer->GetHelpButton() )
692 setupButton( sdbSizer->GetHelpButton() );
693
694 sdbSizer->Layout();
695
696 if( sdbSizer->GetAffirmativeButton() )
697 sdbSizer->GetAffirmativeButton()->SetDefault();
698 }
699
700 for( wxSizerItem* item : aSizer->GetChildren() )
701 {
702 if( item->GetSizer() )
703 recursiveDescent( item->GetSizer(), aLabels );
704 }
705}
706
707
708void DIALOG_SHIM::SetupStandardButtons( std::map<int, wxString> aLabels )
709{
710 recursiveDescent( GetSizer(), aLabels );
711}
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:222
void OnPaint(wxPaintEvent &event)
bool m_qmodal_showing
Definition: dialog_shim.h:217
int vertPixelsFromDU(int y) const
Convert an integer number of dialog units to pixels, vertically.
bool Show(bool show) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
int ShowQuasiModal()
std::string m_hash_key
Definition: dialog_shim.h:203
bool m_firstPaintEvent
Definition: dialog_shim.h:212
int horizPixelsFromDU(int x) const
Convert an integer number of dialog units to pixels, horizontally.
void resetSize()
Clear the existing dialog size and position.
void setSizeInDU(int x, int y)
Set the dialog to the given dimensions in "dialog units".
bool IsQuasiModal() const
Definition: dialog_shim.h:106
void OnGridEditorShown(wxGridEvent &event)
WDO_ENABLE_DISABLE * m_qmodal_parent_disabler
Definition: dialog_shim.h:218
bool m_useCalculatedSize
Definition: dialog_shim.h:207
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:213
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:225
EDA_BASE_FRAME * m_parentFrame
Definition: dialog_shim.h:220
virtual void OnCharHook(wxKeyEvent &aEvt)
void OnGridEditorHidden(wxGridEvent &event)
EDA_UNITS GetUserUnits() const
Definition: dialog_shim.h:121
WX_EVENT_LOOP * m_qmodal_loop
Definition: dialog_shim.h:215
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:625
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
static void selectAllInTextCtrls(wxWindowList &children)
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
void SetPosition(const wxString &aStr, const wxString &aDefaultMeasurementUnit, int *aX, int *aY, const wxString &aActualConversion)
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
constexpr int delta