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 )
216#if defined( __WXMSW__ )
218 Delete( GetCount() - 1 );
229 wxString selection = GetValue();
239 for(
const wxString& font : menuList )
246 Append(
_(
"Default Font" ) );
253 if( !selection.IsEmpty() )
254 SetStringSelection( selection );
274 SetSelection( GetCount() - 1 );
282 int sel = GetSelection();
296 if( GetSelection() <= 0 )
314 if( item == wxNOT_FOUND )
317 wxString
name = GetString( item );
319 dc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) );
320 dc.DrawText(
name, rect.x + 2, rect.y + 2 );
325 dc.GetTextExtent(
name, &w, &h );
326 wxFont sampleFont( wxFontInfo( dc.GetFont().GetPointSize() ).FaceName(
name ) );
327 dc.SetFont( sampleFont );
328 dc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
329 dc.DrawText( wxS(
"AaBbCcDd123456" ), rect.x + w + 15, rect.y + 2 );
342 int keyCode = aEvent.GetKeyCode();
344 if( keyCode == WXK_RETURN || keyCode == WXK_NUMPAD_ENTER || keyCode == WXK_ESCAPE )
353 else if( keyCode == WXK_BACK && !IsPopupShown() )
358 wxString currentText = GetValue();
359 long selStart, selEnd;
360 GetSelection( &selStart, &selEnd );
362 if( selStart != selEnd )
365 wxString newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
367 ChangeValue( newText );
368 SetInsertionPoint( selStart );
371 else if( selStart > 0 )
374 wxString newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
376 ChangeValue( newText );
377 SetInsertionPoint( selStart - 1 );
389 int keyCode = aEvent.GetUnicodeKey();
390 wchar_t wc =
static_cast<wchar_t>( keyCode );
394 if( !IsPopupShown() )
400 if( std::iswprint( wc ) && !std::iswcntrl( wc ) )
403 wxString currentText = GetValue();
404 long selStart, selEnd;
405 GetSelection( &selStart, &selEnd );
407 wxChar newChar = (wxChar)keyCode;
410 if( selStart != selEnd )
413 newText = currentText.Left( selStart ) + newChar + currentText.Mid( selEnd );
418 long insertionPoint = GetInsertionPoint();
419 newText = currentText.Left( insertionPoint ) + newChar + currentText.Mid( insertionPoint );
424 ChangeValue( newText );
425 SetInsertionPoint( selStart + 1 );
440 wxString currentText = GetValue();
441 long selStart, selEnd;
442 GetSelection( &selStart, &selEnd );
445 long newInsertionPoint;
447 if( selStart != selEnd )
450 newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
451 newInsertionPoint = selStart;
453 else if( selStart > 0 )
456 newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
457 newInsertionPoint = selStart - 1;
465 ChangeValue( newText );
466 SetInsertionPoint( newInsertionPoint );
469 wxString trimmedNewText = newText;
470 trimmedNewText.Trim().Trim(
false );
472 if( trimmedNewText.IsEmpty() )
485 case WXK_NUMPAD_ENTER:
504 SetStringSelection( defaultFont );
532 wxString currentText = GetValue();
551 wxString trimmedText = currentText;
552 trimmedText.Trim().Trim(
false);
555 if( trimmedText.IsEmpty() )
568 if( bestMatch != wxNOT_FOUND )
606 if( !GetValue().IsEmpty() && !IsPopupShown() )
609 CallAfter( [
this]() {
610 if( HasFocus() && !IsPopupShown() )
624 if( GetInsertionPoint() != GetLastPosition() )
626 SetInsertionPointEnd();
630 wxString currentText = GetValue();
631 currentText.Trim().Trim(
false);
634 if( currentText.IsEmpty() )
637 SetStringSelection( defaultFont );
647 SetStringSelection( currentText );
656 if( !partialMatch.IsEmpty() )
658 SetStringSelection( partialMatch );
665 SetStringSelection( defaultFont );
681 if( aText.IsEmpty() )
687 if( bestMatch == wxNOT_FOUND )
691 wxString matchText = GetString( bestMatch );
694 if( matchText.Length() > aText.Length() && matchText.Lower().StartsWith( aText.Lower() ) )
698 ChangeValue( matchText );
699 SetInsertionPoint( aText.Length() );
700 SetSelection( aText.Length(), matchText.Length() );
704 SetSelection( bestMatch );
713 wxString trimmedFilter = aFilter;
714 trimmedFilter.Trim().Trim(
false);
716 if( trimmedFilter.IsEmpty() )
722 wxArrayString filteredList;
729 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
730 filteredList.Add( fontName );
738 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
739 filteredList.Add( fontName );
743 wxString currentText = GetValue();
746 bool hadItemsBefore = GetCount() > 0;
747 bool haveItemsNow = filteredList.GetCount() > 0;
748 bool needsPopupRefresh = hadItemsBefore && !haveItemsNow && IsPopupShown();
756 Append( filteredList );
763 if( !currentText.IsEmpty() )
765 ChangeValue( currentText );
766 SetInsertionPointEnd();
772 if( needsPopupRefresh )
777 else if( !IsPopupShown() && haveItemsNow )
786 else if( IsPopupShown() && !haveItemsNow )
793 if( IsPopupShown() && haveItemsNow )
806 wxString selection = GetValue();
813 if( !selection.IsEmpty() )
815 ChangeValue( selection );
816 SetInsertionPointEnd();
825 if( aText.IsEmpty() )
829 wxString trimmedText = aText;
830 trimmedText.Trim().Trim(
false);
832 if( trimmedText.IsEmpty() )
835 wxString lowerText = trimmedText.Lower();
842 if( itemText.StartsWith( lowerText ) )
847 for(
unsigned int j = 0; j < GetCount(); j++ )
849 if( GetString( j ) == fullFontName )
861 if( aText.IsEmpty() )
862 return wxEmptyString;
865 wxString trimmedText = aText;
866 trimmedText.Trim().Trim(
false);
868 if( trimmedText.IsEmpty() )
869 return wxEmptyString;
871 wxString testText = trimmedText;
875 while( testText.Length() >= 2 )
877 wxString lowerTestText = testText.Lower();
884 if( itemText.StartsWith( lowerTestText ) )
892 testText = testText.Left( testText.Length() - 1 );
896 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.