KiCad PCB EDA Suite
Loading...
Searching...
No Matches
hotkey_cycle_popup.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21#include <eda_draw_frame.h>
22
23#include <wx/utils.h>
24
25#ifdef __WXGTK__
26#define LIST_BOX_H_PADDING 20
27#define LIST_BOX_V_PADDING 8
28#elif __WXMAC__
29#define LIST_BOX_H_PADDING 40
30#define LIST_BOX_V_PADDING 5
31#else
32#define LIST_BOX_H_PADDING 10
33#define LIST_BOX_V_PADDING 5
34#endif
35
36#define SHOW_TIME_MS 500
37
38
40 EDA_VIEW_SWITCHER_BASE( aParent ),
41 m_drawFrame( aParent )
42{
43 m_showTimer = new wxTimer( this );
44 Bind( wxEVT_TIMER, [&]( wxTimerEvent& ) { Show( false ); m_drawFrame->GetCanvas()->SetFocus(); },
45 m_showTimer->GetId() );
46
47 // On macOS, we can't change focus to the canvas before sending the event, so the key events
48 // just get discarded via the "don't steal from an input control" logic. So, set this input
49 // control with a special flag because we really do want to steal from it.
51
52#ifdef __WXOSX__
53 m_listBox->Bind( wxEVT_CHAR_HOOK,
54 [=, this]( wxKeyEvent& aEvent )
55 {
56 aEvent.SetEventType( wxEVT_CHAR );
57 m_drawFrame->GetCanvas()->SetFocus();
58 m_drawFrame->GetCanvas()->OnEvent( aEvent );
59 } );
60#endif
61}
62
63
68
69
70void HOTKEY_CYCLE_POPUP::Popup( const wxString& aTitle, const wxArrayString& aItems,
71 int aSelection )
72{
73 m_stTitle->SetLabel( aTitle );
74 m_listBox->Clear();
75 m_listBox->InsertItems( aItems, 0 );
76 m_listBox->SetSelection( std::min( aSelection,
77 static_cast<int>( m_listBox->GetCount() ) - 1 ) );
78
79 int width = m_stTitle->GetTextExtent( aTitle ).x;
80 int height = 0;
81
82 for( const wxString& item : aItems )
83 {
84 wxSize extents = m_listBox->GetTextExtent( item );
85 width = std::max( width, extents.x );
86 height += extents.y + LIST_BOX_V_PADDING;
87 }
88
89 m_listBox->SetMinSize( wxSize( width + LIST_BOX_H_PADDING,
90 height + ( LIST_BOX_V_PADDING * 2 ) ) );
91
92 // this line fixes an issue on Linux Ubuntu using Unity (dialog not shown),
93 // and works fine on all systems
94 GetSizer()->Fit( this );
95
96 if( m_showTimer->IsRunning() )
97 {
98 m_showTimer->StartOnce( SHOW_TIME_MS );
99 SetFocus();
100 return;
101 }
102
103 m_showTimer->StartOnce( SHOW_TIME_MS );
104
105 Show( true );
106 SetFocus();
107}
108
109
110bool HOTKEY_CYCLE_POPUP::Show( bool aShow )
111{
112#ifdef __WXGTK__
113 // On Wayland, window positions cannot be changed after mapping. DIALOG_SHIM::Show() calls
114 // Raise() -> gtk_window_present() before wxDialog::Show(), prematurely mapping the window so
115 // the compositor places it at its default position instead of centered on the parent. Centre
116 // before mapping and bypass DIALOG_SHIM::Show() since this transient popup needs no geometry
117 // save/restore.
118 if( aShow && wxGetEnv( wxT( "WAYLAND_DISPLAY" ), nullptr ) )
119 {
121 Centre();
122 return wxDialog::Show( true );
123 }
124#endif
125
126 bool ret = DIALOG_SHIM::Show( aShow );
127
128 if( aShow )
129 Centre();
130
131 return ret;
132}
133
134
135bool HOTKEY_CYCLE_POPUP::TryBefore( wxEvent& aEvent )
136{
137 if( aEvent.GetEventType() == wxEVT_CHAR || aEvent.GetEventType() == wxEVT_CHAR_HOOK )
138 {
139 aEvent.SetEventType( wxEVT_CHAR );
140 //m_drawFrame->GetCanvas()->SetFocus(); // on GTK causes focus flicker and is not needed
141 m_drawFrame->GetCanvas()->OnEvent( aEvent );
142 return true;
143 }
144
145 return EDA_VIEW_SWITCHER_BASE::TryBefore( aEvent );
146}
bool Show(bool show) override
void clampToWorkArea()
Shrink the dialog's minimum and current size down to the work area of the display it occupies,...
The base class for create windows for drawing purpose.
EDA_VIEW_SWITCHER_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("View Preset Switcher"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxSTAY_ON_TOP)
bool Show(bool aShow) override
void Popup(const wxString &aTitle, const wxArrayString &aItems, int aSelection)
EDA_DRAW_FRAME * m_drawFrame
HOTKEY_CYCLE_POPUP(EDA_DRAW_FRAME *aParent)
bool TryBefore(wxEvent &aEvent) override
#define LIST_BOX_V_PADDING
#define LIST_BOX_H_PADDING
#define SHOW_TIME_MS
KICOMMON_API const wxString s_FocusStealableInputName
Definition ui_common.cpp:46