27#include <wx/fontenum.h>
28#include <wx/settings.h>
29#include <wx/textctrl.h>
33#include <condition_variable>
58 std::condition_variable
m_cv;
72 std::lock_guard<std::mutex> lock(
m_mutex );
78 std::lock_guard<std::mutex> lock(
m_mutex );
84 std::lock_guard<std::mutex> lock(
m_mutex );
106 std::lock_guard<std::mutex> lock(
m_mutex );
120 std::unique_lock<std::mutex> lock(
m_mutex );
126 m_cv.wait_for( lock, std::chrono::seconds( 30 ), [&] {
return m_quit.load(); } );
139 std::vector<std::string> fontNames;
140 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ) );
142 wxArrayString menuList;
144 for(
const std::string&
name : fontNames )
145 menuList.Add( wxString(
name ) );
151 std::lock_guard<std::mutex> lock(
m_mutex );
159 CallAfter( [
this]() {
160 std::vector<FONT_CHOICE*> controlsCopy;
164 std::lock_guard<std::mutex> lock(
m_mutex );
171 if( ctrl && !ctrl->IsShownOnScreen() )
172 ctrl->RefreshFonts();
179 int nChoices, wxString* aChoices,
int aStyle ) :
180 wxOwnerDrawnComboBox( aParent, aId, wxEmptyString, aPosition, aSize, 0, nullptr, aStyle )
212 wxString selection = GetValue();
222 for(
const wxString& font : menuList )
229 Append(
_(
"Default Font" ) );
236 if( !selection.IsEmpty() )
237 SetStringSelection( selection );
257 SetSelection( GetCount() - 1 );
265 int sel = GetSelection();
279 if( GetSelection() <= 0 )
297 if( item == wxNOT_FOUND )
300 wxString
name = GetString( item );
302 dc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) );
303 dc.DrawText(
name, rect.x + 2, rect.y + 2 );
308 dc.GetTextExtent(
name, &w, &h );
309 wxFont sampleFont( wxFontInfo( dc.GetFont().GetPointSize() ).FaceName(
name ) );
310 dc.SetFont( sampleFont );
311 dc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
312 dc.DrawText( wxS(
"AaBbCcDd123456" ), rect.x + w + 15, rect.y + 2 );
325 int keyCode = aEvent.GetKeyCode();
327 if( keyCode == WXK_RETURN || keyCode == WXK_NUMPAD_ENTER || keyCode == WXK_ESCAPE )
336 else if( keyCode == WXK_BACK && !IsPopupShown() )
341 wxString currentText = GetValue();
342 long selStart, selEnd;
343 GetSelection( &selStart, &selEnd );
345 if( selStart != selEnd )
348 wxString newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
350 ChangeValue( newText );
351 SetInsertionPoint( selStart );
354 else if( selStart > 0 )
357 wxString newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
359 ChangeValue( newText );
360 SetInsertionPoint( selStart - 1 );
372 int keyCode = aEvent.GetUnicodeKey();
373 wchar_t wc =
static_cast<wchar_t>( keyCode );
377 if( !IsPopupShown() )
383 if( std::iswprint( wc ) && !std::iswcntrl( wc ) )
386 wxString currentText = GetValue();
387 long selStart, selEnd;
388 GetSelection( &selStart, &selEnd );
390 wxChar newChar = (wxChar)keyCode;
393 if( selStart != selEnd )
396 newText = currentText.Left( selStart ) + newChar + currentText.Mid( selEnd );
401 long insertionPoint = GetInsertionPoint();
402 newText = currentText.Left( insertionPoint ) + newChar + currentText.Mid( insertionPoint );
407 ChangeValue( newText );
408 SetInsertionPoint( selStart + 1 );
423 wxString currentText = GetValue();
424 long selStart, selEnd;
425 GetSelection( &selStart, &selEnd );
428 long newInsertionPoint;
430 if( selStart != selEnd )
433 newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
434 newInsertionPoint = selStart;
436 else if( selStart > 0 )
439 newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
440 newInsertionPoint = selStart - 1;
448 ChangeValue( newText );
449 SetInsertionPoint( newInsertionPoint );
452 wxString trimmedNewText = newText;
453 trimmedNewText.Trim().Trim(
false );
455 if( trimmedNewText.IsEmpty() )
468 case WXK_NUMPAD_ENTER:
487 SetStringSelection( defaultFont );
515 wxString currentText = GetValue();
534 wxString trimmedText = currentText;
535 trimmedText.Trim().Trim(
false);
538 if( trimmedText.IsEmpty() )
551 if( bestMatch != wxNOT_FOUND )
589 if( !GetValue().IsEmpty() && !IsPopupShown() )
592 CallAfter( [
this]() {
593 if( HasFocus() && !IsPopupShown() )
607 if( GetInsertionPoint() != GetLastPosition() )
609 SetInsertionPointEnd();
613 wxString currentText = GetValue();
614 currentText.Trim().Trim(
false);
617 if( currentText.IsEmpty() )
620 SetStringSelection( defaultFont );
630 SetStringSelection( currentText );
639 if( !partialMatch.IsEmpty() )
641 SetStringSelection( partialMatch );
648 SetStringSelection( defaultFont );
664 if( aText.IsEmpty() )
670 if( bestMatch == wxNOT_FOUND )
674 wxString matchText = GetString( bestMatch );
677 if( matchText.Length() > aText.Length() && matchText.Lower().StartsWith( aText.Lower() ) )
681 ChangeValue( matchText );
682 SetInsertionPoint( aText.Length() );
683 SetSelection( aText.Length(), matchText.Length() );
687 SetSelection( bestMatch );
696 wxString trimmedFilter = aFilter;
697 trimmedFilter.Trim().Trim(
false);
699 if( trimmedFilter.IsEmpty() )
705 wxArrayString filteredList;
712 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
713 filteredList.Add( fontName );
721 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
722 filteredList.Add( fontName );
726 wxString currentText = GetValue();
729 bool hadItemsBefore = GetCount() > 0;
730 bool haveItemsNow = filteredList.GetCount() > 0;
731 bool needsPopupRefresh = hadItemsBefore && !haveItemsNow && IsPopupShown();
739 Append( filteredList );
746 if( !currentText.IsEmpty() )
748 ChangeValue( currentText );
749 SetInsertionPointEnd();
755 if( needsPopupRefresh )
760 else if( !IsPopupShown() && haveItemsNow )
769 else if( IsPopupShown() && !haveItemsNow )
776 if( IsPopupShown() && haveItemsNow )
789 wxString selection = GetValue();
796 if( !selection.IsEmpty() )
798 ChangeValue( selection );
799 SetInsertionPointEnd();
808 if( aText.IsEmpty() )
812 wxString trimmedText = aText;
813 trimmedText.Trim().Trim(
false);
815 if( trimmedText.IsEmpty() )
818 wxString lowerText = trimmedText.Lower();
825 if( itemText.StartsWith( lowerText ) )
830 for(
unsigned int j = 0; j < GetCount(); j++ )
832 if( GetString( j ) == fullFontName )
844 if( aText.IsEmpty() )
845 return wxEmptyString;
848 wxString trimmedText = aText;
849 trimmedText.Trim().Trim(
false);
851 if( trimmedText.IsEmpty() )
852 return wxEmptyString;
854 wxString testText = trimmedText;
858 while( testText.Length() >= 2 )
860 wxString lowerTestText = testText.Lower();
867 if( itemText.StartsWith( lowerTestText ) )
875 testText = testText.Left( testText.Length() - 1 );
879 return wxEmptyString;
void SetFontSelection(KIFONT::FONT *aFont, bool aSilentMode=false)
Set the selection in wxChoice widget.
void FilterFontList(const wxString &aFilter)
void OnKeyDown(wxKeyEvent &aEvent)
void RestoreFullFontList()
void OnDropDown(wxCommandEvent &aEvent)
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic, bool aForDrawingSheet=false) const
bool HaveFontSelection() const
wxString m_originalSelection
FONT_CHOICE(wxWindow *aParent, int aId, wxPoint aPosition, wxSize aSize, int nChoices, wxString *aChoices, int aStyle)
void OnKillFocus(wxFocusEvent &aEvent)
wxArrayString m_fullFontList
void OnDrawItem(wxDC &dc, const wxRect &rect, int item, int flags) const override
int FindBestMatch(const wxString &aText)
wxString GetDefaultFontName() const
void DoAutoComplete(const wxString &aText)
void OnCloseUp(wxCommandEvent &aEvent)
void OnSetFocus(wxFocusEvent &aEvent)
wxString FindBestPartialMatch(const wxString &aText)
void OnTextCtrl(wxCommandEvent &aEvent)
void OnCharHook(wxKeyEvent &aEvent)
wxString GetStringSelection() const override
std::vector< FONT_CHOICE * > m_controls
void Register(FONT_CHOICE *aCtrl)
wxArrayString GetFonts() const
static FONT_LIST_MANAGER & Get()
void Unregister(FONT_CHOICE *aCtrl)
std::condition_variable m_cv
std::atomic< bool > m_quit
FONT is an abstract base class for both outline and stroke fonts.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
const wxString & GetName() const
FONTCONFIG * Fontconfig()
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
PGM_BASE & Pgm()
The global program "get" accessor.
wxString result
Test unit parsing edge cases and error handling.