KiCad PCB EDA Suite
Loading...
Searching...
No Matches
filter_combobox.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
20
22
23#include <wx/dc.h>
24#include <wx/textctrl.h>
25#include <wx/vlbox.h>
26#include <wx/settings.h>
27#include <wx/sizer.h>
28#include <wx/stattext.h>
29#include <wx/valtext.h>
30#include <wx/listbox.h>
31
32#include <kiplatform/ui.h>
33#include <widgets/ui_common.h>
34
35wxDEFINE_EVENT( FILTERED_ITEM_SELECTED, wxCommandEvent );
36
37#if defined( __WXOSX_MAC__ )
38 #define POPUP_PADDING 2
39 #define LIST_ITEM_PADDING 2
40 #define LIST_PADDING 7
41#elif defined( __WXMSW__ )
42 #define POPUP_PADDING 0
43 #define LIST_ITEM_PADDING 2
44 #define LIST_PADDING 5
45#else
46 #define POPUP_PADDING 0
47 #define LIST_ITEM_PADDING 6
48 #define LIST_PADDING 5
49#endif
50
51
52void FILTER_COMBOPOPUP_LISTBOX::SetDisplayStyleCallback( const std::function<int( const wxString& aItem )>& aCallback )
53{
54 m_displayStyleCallback = aCallback;
55}
56
57
58wxCoord FILTER_COMBOPOPUP_LISTBOX::OnMeasureItem( size_t aItem ) const
59{
60 return GetFont().GetPixelSize().GetHeight() + 4;
61}
62
63
64void FILTER_COMBOPOPUP_LISTBOX::OnDrawItem( wxDC& aDC, const wxRect& aRect, size_t aItem ) const
65{
66 wxFont font = aDC.GetFont();
67 wxString item = GetString( aItem );
68
69 font.SetStyle( wxFONTSTYLE_NORMAL );
70 font.SetWeight( wxFONTWEIGHT_NORMAL );
71
72 if( int style = m_displayStyleCallback( item ) )
73 {
74 if( style & ITALIC )
75 font.SetStyle( wxFONTSTYLE_ITALIC );
76
77 if( style & BOLD )
78 font.SetWeight( wxFONTWEIGHT_BOLD );
79 }
80
81 aDC.SetFont(font);
82
83 if( IsSelected( aItem ) )
84 {
85 aDC.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
86 }
87 else
88 {
89 aDC.SetTextForeground( wxListBox::GetClassDefaultAttributes( GetWindowVariant() ).colFg );
90 }
91
92 // Draw the text inside the item bounds
93 aDC.DrawText( item, aRect.x + 2, aRect.y + 2);
94}
95
96
97void FILTER_COMBOPOPUP_LISTBOX::OnDrawBackground( wxDC& aDC, const wxRect& aRect, size_t aItem ) const
98{
99 // Letting wxVList do this itself results in a darker highlight (at least on OSX) than our other
100 // listboxes use. wxSYS_COLOUR_HIGHLIGHT, on the other hand, uses a much lighter colour --
101 // which matches the OSX native look -- just not any of the other dropdowns in KiCad. If other
102 // platforms need something different than wxSYS_COLOUR_HOTLIGHT, please if-def it.
103
104 wxColour background;
105
106 if( IsSelected( aItem ) )
107 {
108 background = wxSystemSettings::GetColour( wxSYS_COLOUR_HOTLIGHT );
109 }
110 else
111 {
112 background = wxListBox::GetClassDefaultAttributes( GetWindowVariant() ).colBg;
113 }
114
115 aDC.SetBrush( wxBrush( background ) );
116 aDC.SetPen( wxPen( background ) );
117 aDC.DrawRectangle( aRect );
118}
119
120
121int FILTER_COMBOPOPUP_LISTBOX::HitTest(const wxPoint& aPoint) const
122{
123 for( size_t ii = 0; ii < m_choices.size(); ++ii )
124 {
125 if( GetItemRect( ii ).Contains( aPoint ) )
126 return (int) ii;
127 }
128
129 return -1;
130}
131
132
134 m_filterValidator( nullptr ),
135 m_filterCtrl( nullptr ),
136 m_listBox( nullptr ),
137 m_minPopupWidth( -1 ),
138 m_maxPopupHeight( 1000 ),
139 m_focusHandler( nullptr )
140{
142 []( const wxString& aItem ) -> int
143 {
144 return 0;
145 };
146}
147
148
149bool FILTER_COMBOPOPUP::Create( wxWindow* aParent )
150{
151 wxPanel::Create( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER );
152
153 wxBoxSizer* mainSizer;
154 mainSizer = new wxBoxSizer( wxVERTICAL );
155
156 wxStaticText* filterLabel = new wxStaticText( this, wxID_ANY, _( "Filter:" ) );
157 mainSizer->Add( filterLabel, 0, wxEXPAND, 0 );
158
159 m_filterCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
160 wxTE_PROCESS_ENTER );
161 m_filterValidator = new wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST );
162 m_filterValidator->SetCharExcludes( " " );
163 m_filterCtrl->SetValidator( *m_filterValidator );
164 mainSizer->Add( m_filterCtrl, 0, wxEXPAND, 0 );
165
166 m_listBox = new FILTER_COMBOPOPUP_LISTBOX( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
167 wxLB_SINGLE | wxLB_NEEDED_SB );
168 mainSizer->Add( m_listBox, 1, wxEXPAND | wxTOP, 2 );
169
170 SetSizer( mainSizer );
171 Layout();
172
173 Connect( wxEVT_IDLE, wxIdleEventHandler( FILTER_COMBOPOPUP::onIdle ), nullptr, this );
174 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( FILTER_COMBOPOPUP::onKeyDown ), nullptr, this );
175 Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( FILTER_COMBOPOPUP::onMouseClick ), nullptr, this );
176 m_listBox->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( FILTER_COMBOPOPUP::onMouseClick ), nullptr, this );
177 m_filterCtrl->Connect( wxEVT_TEXT, wxCommandEventHandler( FILTER_COMBOPOPUP::onFilterEdit ), nullptr, this );
178 m_filterCtrl->Connect( wxEVT_TEXT_ENTER, wxCommandEventHandler( FILTER_COMBOPOPUP::onEnter ), nullptr, this );
179
180 // <enter> in a ListBox comes in as a double-click on GTK
181 m_listBox->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( FILTER_COMBOPOPUP::onEnter ),
182 nullptr, this );
183
184 return true;
185}
186
187
188void FILTER_COMBOPOPUP::SetStringList( const wxArrayString& aStringList )
189{
190 m_stringList = aStringList;
191 m_stringList.Sort();
192 rebuildList();
193}
194
195
197{
198 return m_selectedString;
199}
200
201
202void FILTER_COMBOPOPUP::SetStringValue( const wxString& aNetName )
203{
204 if( GetWindowStyleFlag() & wxCB_READONLY )
205 /* shouldn't be here (combo is read-only) */;
206 else
207 wxComboPopup::SetStringValue( aNetName );
208}
209
210
211void FILTER_COMBOPOPUP::SetSelectedString( const wxString& aString )
212{
213 m_selectedString = aString;
214 GetComboCtrl()->SetValue( m_selectedString );
215}
216
217
218void FILTER_COMBOPOPUP::SetDisplayStyleCallback( const std::function<int( const wxString& aItem )>& aCallback )
219{
220 m_displayStyleCallback = aCallback;
221 m_listBox->SetDisplayStyleCallback( aCallback );
222}
223
224
226{
227 // While it can sometimes be useful to keep the filter, it's always unexpected.
228 // Better to clear it.
229 m_filterCtrl->Clear();
230
231 m_listBox->SetStringSelection( GetStringValue() );
232 m_filterCtrl->SetFocus();
233
234 // The updateSize() call in GetAdjustedSize() leaves the height off-by-one for
235 // some reason, so do it again.
236 updateSize();
237}
238
239
240void FILTER_COMBOPOPUP::OnStartingKey( wxKeyEvent& aEvent )
241{
243 doStartingKey( aEvent );
244}
245
246
248{
249 wxString selectedString = getSelectedValue().value_or( wxEmptyString );
250
251 Dismiss();
252
253 // No update on empty
254 if( !selectedString.IsEmpty() && selectedString != m_selectedString )
255 {
256 m_selectedString = selectedString;
257 GetComboCtrl()->SetValue( m_selectedString );
258
259 wxCommandEvent changeEvent( FILTERED_ITEM_SELECTED );
260 wxPostEvent( GetComboCtrl(), changeEvent );
261 }
262}
263
264
265wxSize FILTER_COMBOPOPUP::GetAdjustedSize( int aMinWidth, int aPrefHeight, int aMaxHeight )
266{
267 // Called when the popup is first shown. Stash the minWidth and maxHeight so we
268 // can use them later when refreshing the sizes after filter changes.
269 m_minPopupWidth = aMinWidth;
270 m_maxPopupHeight = aMaxHeight;
271
272 return updateSize();
273}
274
275
276void FILTER_COMBOPOPUP::getListContent( wxArrayString& aListContent )
277{
278 wxString filterString = getFilterValue();
279 bool excludeItalicItems = false;
280
281 if( filterString.StartsWith( wxT( "::" ) ) )
282 {
283 excludeItalicItems = true;
284 filterString = filterString.Mid( 2 );
285 }
286
287 // Simple substring, case-insensitive search
288 for( const wxString& str : m_stringList )
289 {
290 if( excludeItalicItems && ( m_displayStyleCallback( str ) & ITALIC ) != 0 )
291 continue;
292
293 if( filterString.IsEmpty() || str.Lower().Contains( filterString.Lower() ) )
294 aListContent.push_back( str );
295 }
296}
297
298
300{
301 wxArrayString newList;
302 getListContent( newList );
303
304 m_listBox->Set( newList );
305}
306
307
308std::optional<wxString> FILTER_COMBOPOPUP::getSelectedValue() const
309{
310 int selection = m_listBox->GetSelection();
311
312 if( selection >= 0 )
313 return m_listBox->GetString( selection );
314
315 return std::nullopt;
316}
317
318
320{
321 return m_filterCtrl->GetValue().Trim( true ).Trim( false );
322}
323
324
326{
327 int listTop = m_listBox->GetRect().y;
328 int itemHeight = KIUI::GetTextSize( wxT( "Xy" ), this ).y + LIST_ITEM_PADDING;
329 int listHeight = ( (int) m_listBox->GetCount() * itemHeight ) + ( LIST_PADDING * 3 );
330
331 if( listTop + listHeight >= m_maxPopupHeight )
332 listHeight = m_maxPopupHeight - listTop - 1;
333
334 int listWidth = m_minPopupWidth;
335
336 for( size_t i = 0; i < m_listBox->GetCount(); ++i )
337 {
338 int itemWidth = KIUI::GetTextSize( m_listBox->GetString( i ), m_listBox ).x;
339 listWidth = std::max( listWidth, itemWidth + LIST_PADDING * 2 );
340 }
341
342 wxSize listSize( listWidth, listHeight );
343 wxSize popupSize( listWidth, listTop + listHeight );
344
345 SetSize( popupSize ); // us
346 GetParent()->SetSize( popupSize ); // the window that wxComboCtrl put us in
347
348 m_listBox->SetMinSize( listSize );
349 m_listBox->SetSize( listSize );
350
351 return popupSize;
352}
353
354
355void FILTER_COMBOPOPUP::onIdle( wxIdleEvent& aEvent )
356{
357 // Only process when the popup is actually visible to avoid ClientToScreen warnings.
358 // Use IsShownOnScreen() instead of IsShown() because wx may report the window as shown
359 // before GTK has fully realized it, causing ClientToScreen to fail.
360 if( !IsShownOnScreen() )
361 return;
362
363 // Generate synthetic (but reliable) MouseMoved events
364 static wxPoint lastPos;
365 wxPoint screenPos = KIPLATFORM::UI::GetMousePosition();
366
367 if( screenPos != lastPos )
368 {
369 lastPos = screenPos;
370 onMouseMoved( screenPos );
371 }
372
373 if( m_focusHandler )
374 {
375 m_filterCtrl->PushEventHandler( m_focusHandler );
376 m_focusHandler = nullptr;
377 }
378}
379
380
381// Hot-track the mouse (for focus and listbox selection)
382void FILTER_COMBOPOPUP::onMouseMoved( const wxPoint aScreenPos )
383{
384 if( m_listBox->GetScreenRect().Contains( aScreenPos ) )
385 {
387
388 wxPoint relativePos = m_listBox->ScreenToClient( aScreenPos );
389 int item = m_listBox->HitTest( relativePos );
390
391 if( item >= 0 )
392 m_listBox->SetSelection( item );
393 }
394 else if( m_filterCtrl->GetScreenRect().Contains( aScreenPos ) )
395 {
397 }
398}
399
400
401void FILTER_COMBOPOPUP::onMouseClick( wxMouseEvent& aEvent )
402{
403 // Accept a click event from anywhere. Different platform implementations have
404 // different foibles with regard to transient popups and their children.
405 if( aEvent.GetEventObject() == m_listBox )
406 {
407 m_listBox->SetSelection( m_listBox->HitTest( aEvent.GetPosition() ) );
408 Accept();
409 return;
410 }
411
412 wxWindow* window = dynamic_cast<wxWindow*>( aEvent.GetEventObject() );
413
414 if( window )
415 {
416 wxPoint screenPos = window->ClientToScreen( aEvent.GetPosition() );
417
418 if( m_listBox->GetScreenRect().Contains( screenPos ) )
419 {
420 wxPoint localPos = m_listBox->ScreenToClient( screenPos );
421
422 m_listBox->SetSelection( m_listBox->HitTest( localPos ) );
423 Accept();
424 }
425 }
426}
427
428
429void FILTER_COMBOPOPUP::onKeyDown( wxKeyEvent& aEvent )
430{
431 switch( aEvent.GetKeyCode() )
432 {
433 // Control keys go to the parent combobox
434 case WXK_TAB:
435 Dismiss();
436
437 m_parent->NavigateIn( ( aEvent.ShiftDown() ? 0 : wxNavigationKeyEvent::IsForward ) |
438 ( aEvent.ControlDown() ? wxNavigationKeyEvent::WinChange : 0 ) );
439 break;
440
441 case WXK_ESCAPE:
442 Dismiss();
443 break;
444
445 case WXK_RETURN:
446 case WXK_NUMPAD_ENTER:
447 Accept();
448 break;
449
450 // Arrows go to the list box
451 case WXK_DOWN:
452 case WXK_NUMPAD_DOWN:
454 m_listBox->SetSelection( std::min( m_listBox->GetSelection() + 1,
455 (int) m_listBox->GetCount() - 1 ) );
456 break;
457
458 case WXK_UP:
459 case WXK_NUMPAD_UP:
461 m_listBox->SetSelection( std::max( m_listBox->GetSelection() - 1, 0 ) );
462 break;
463
464 // Everything else goes to the filter textbox
465 default:
466 if( !m_filterCtrl->HasFocus() )
467 {
469
470 // Because we didn't have focus we missed our chance to have the native widget
471 // handle the keystroke. We'll have to do the first character ourselves.
472 doStartingKey( aEvent );
473 }
474 else
475 {
476 // On some platforms a wxComboFocusHandler will have been pushed which
477 // unhelpfully gives the event right back to the popup. Make sure the filter
478 // control is going to get the event.
479 if( m_filterCtrl->GetEventHandler() != m_filterCtrl )
480 m_focusHandler = m_filterCtrl->PopEventHandler();
481
482 aEvent.Skip();
483 }
484 break;
485 }
486}
487
488
489void FILTER_COMBOPOPUP::onEnter( wxCommandEvent& aEvent )
490{
491 Accept();
492}
493
494
495void FILTER_COMBOPOPUP::onFilterEdit( wxCommandEvent& aEvent )
496{
497 rebuildList();
498 updateSize();
499
500 if( m_listBox->GetCount() > 0 )
501 m_listBox->SetSelection( 0 );
502}
503
504
505void FILTER_COMBOPOPUP::doStartingKey( wxKeyEvent& aEvent )
506{
507 if( aEvent.GetKeyCode() == WXK_BACK )
508 {
509 const long pos = m_filterCtrl->GetLastPosition();
510 m_filterCtrl->Remove( pos - 1, pos );
511 }
512 else
513 {
514 bool isPrintable;
515 int ch = aEvent.GetUnicodeKey();
516
517 if( ch != WXK_NONE )
518 isPrintable = true;
519 else
520 {
521 ch = aEvent.GetKeyCode();
522 isPrintable = ch > WXK_SPACE && ch < WXK_START;
523 }
524
525 if( isPrintable )
526 {
527 wxString text( static_cast<wxChar>( ch ) );
528
529 // wxCHAR_HOOK chars have been converted to uppercase.
530 if( !aEvent.ShiftDown() )
531 text.MakeLower();
532
533 m_filterCtrl->AppendText( text );
534 }
535 }
536}
537
538
539void FILTER_COMBOPOPUP::doSetFocus( wxWindow* aWindow )
540{
541#ifndef __WXGTK__ // Cannot focus in non-toplevel windows on GTK
543#endif
544}
545
546
547FILTER_COMBOBOX::FILTER_COMBOBOX( wxWindow *parent, wxWindowID id, const wxPoint &pos,
548 const wxSize &size, long style ) :
549 wxComboCtrl( parent, id, wxEmptyString, pos, size, style|wxTE_PROCESS_ENTER ),
550 m_filterPopup( nullptr )
551{
552 UseAltPopupWindow();
553 Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( FILTER_COMBOBOX::onKeyDown ), nullptr, this );
554
555#ifdef __WXMSW__
556 // On Windows the listbox background doesn't have the right colour in dark mode
558 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
559 else
560#endif
561 SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX ) );
562}
563
564
565FILTER_COMBOBOX::FILTER_COMBOBOX( wxWindow* parent, wxWindowID id, const wxString& value,
566 const wxPoint& pos, const wxSize& size,
567 int count, wxString strings[], long style ) :
568 FILTER_COMBOBOX( parent, id, pos, size, style )
569{
570 // These arguments are just to match wxFormBuilder's expected API; they are not supported
571 wxASSERT( value.IsEmpty() && count == 0 && strings == nullptr );
572
575}
576
577
579{
580 Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( FILTER_COMBOBOX::onKeyDown ), nullptr, this );
581}
582
583
584void FILTER_COMBOBOX::SetStringList( const wxArrayString& aList )
585{
586 m_filterPopup->SetStringList( aList );
587}
588
589
590void FILTER_COMBOBOX::SetSelectedString( const wxString& aString )
591{
592 m_filterPopup->SetSelectedString( aString );
593}
594
595
596void FILTER_COMBOBOX::SetDisplayStyleCallback( const std::function<int( const wxString& aItem )>& aCallback )
597{
598 if( m_filterPopup )
599 m_filterPopup->SetDisplayStyleCallback( aCallback );
600}
601
602
604{
605 m_filterPopup = aPopup;
606 SetPopupControl( aPopup );
607}
608
609
610void FILTER_COMBOBOX::onKeyDown( wxKeyEvent& aEvt )
611{
612 int key = aEvt.GetKeyCode();
613
614 if( IsPopupShown() )
615 {
616 // If the popup is shown then it's CHAR_HOOK should be eating these before they
617 // even get to us. But just to be safe, we go ahead and skip.
618 aEvt.Skip();
619 }
620 // Shift-return accepts dialog
621 else if( ( key == WXK_RETURN || key == WXK_NUMPAD_ENTER ) && aEvt.ShiftDown() )
622 {
623 wxPostEvent( m_parent, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
624 }
625 // Return, arrow-down and space-bar all open popup
626 else if( key == WXK_RETURN || key == WXK_NUMPAD_ENTER || key == WXK_DOWN
627 || key == WXK_NUMPAD_DOWN || key == WXK_SPACE )
628 {
629 Popup();
630 }
631 // Non-control characters go to filterbox in popup for read-only controls
632 else if( key > WXK_SPACE && key < WXK_START && ( GetWindowStyleFlag() & wxCB_READONLY ) )
633 {
634 Popup();
635 m_filterPopup->OnStartingKey( aEvt );
636 }
637 else
638 {
639 aEvt.Skip();
640 }
641}
virtual void SetSelectedString(const wxString &aString)
FILTER_COMBOPOPUP * m_filterPopup
void setFilterPopup(FILTER_COMBOPOPUP *aPopup)
virtual void SetStringList(const wxArrayString &aStringList)
FILTER_COMBOBOX(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0)
void onKeyDown(wxKeyEvent &aEvt)
void SetDisplayStyleCallback(const std::function< int(const wxString &aItem)> &aCallback)
void OnDrawBackground(wxDC &aDC, const wxRect &aRect, size_t aItem) const override
wxString GetString(size_t aIdx) const
std::function< int(const wxString &aItem)> m_displayStyleCallback
wxCoord OnMeasureItem(size_t aItem) const override
int HitTest(const wxPoint &aPoint) const
void OnDrawItem(wxDC &aDC, const wxRect &aRect, size_t aItem) const override
void SetDisplayStyleCallback(const std::function< int(const wxString &aItem)> &aCallback)
void SetSelectedString(const wxString &aString)
void onEnter(wxCommandEvent &aEvent)
wxTextValidator * m_filterValidator
void onFilterEdit(wxCommandEvent &aEvent)
void SetStringValue(const wxString &aNetName) override
virtual void getListContent(wxArrayString &aStringList)
Fill the combobox list.
void onMouseClick(wxMouseEvent &aEvent)
void doStartingKey(wxKeyEvent &aEvent)
void rebuildList()
Call this to rebuild the list from the getListContent() method.
wxString getFilterValue() const
Get the current value of the filter control.
virtual void Accept()
void OnStartingKey(wxKeyEvent &aEvent)
void SetDisplayStyleCallback(const std::function< int(const wxString &aItem)> &aCallback)
std::optional< wxString > getSelectedValue() const
Get the currently selected value in the list, or std::nullopt.
void onIdle(wxIdleEvent &aEvent)
wxString GetStringValue() const override
wxArrayString m_stringList
wxSize GetAdjustedSize(int aMinWidth, int aPrefHeight, int aMaxHeight) override
std::function< int(const wxString &aItem)> m_displayStyleCallback
wxEvtHandler * m_focusHandler
FILTER_COMBOPOPUP_LISTBOX * m_listBox
bool Create(wxWindow *aParent) override
void OnPopup() override
void doSetFocus(wxWindow *aWindow)
void SetStringList(const wxArrayString &aStringList)
void onKeyDown(wxKeyEvent &aEvent)
void onMouseMoved(const wxPoint aScreenPos)
wxTextCtrl * m_filterCtrl
#define _(s)
#define LIST_ITEM_PADDING
#define LIST_PADDING
wxDEFINE_EVENT(FILTERED_ITEM_SELECTED, wxCommandEvent)
@ BOLD
Definition font.h:43
@ ITALIC
Definition font.h:44
wxPoint GetMousePosition()
Returns the mouse position in screen coordinates.
Definition wxgtk/ui.cpp:839
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition wxgtk/ui.cpp:127
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition wxgtk/ui.cpp:51
KICOMMON_API wxSize GetTextSize(const wxString &aSingleLine, wxWindow *aWindow)
Return the size of aSingleLine of text when it is rendered in aWindow using whatever font is currentl...
Definition ui_common.cpp:78
Functions to provide common constants and other functions to assist in making a consistent UI.