28#include <wx/fontenum.h>
29#include <wx/settings.h>
30#include <wx/textctrl.h>
34#include <condition_variable>
59 std::condition_variable
m_cv;
73 std::lock_guard<std::mutex> lock(
m_mutex );
79 std::lock_guard<std::mutex> lock(
m_mutex );
85 std::lock_guard<std::mutex> lock(
m_mutex );
107 std::lock_guard<std::mutex> lock(
m_mutex );
121 std::unique_lock<std::mutex> lock(
m_mutex );
127 m_cv.wait_for( lock, std::chrono::seconds( 30 ), [&] {
return m_quit.load(); } );
140 std::vector<std::string> fontNames;
141 Fontconfig()->ListFonts( fontNames, std::string(
Pgm().GetLanguageTag().utf8_str() ) );
143 wxArrayString menuList;
145 for(
const std::string&
name : fontNames )
146 menuList.Add( wxString(
name ) );
152 std::lock_guard<std::mutex> lock(
m_mutex );
160 CallAfter( [
this]() {
161 std::vector<FONT_CHOICE*> controlsCopy;
165 std::lock_guard<std::mutex> lock(
m_mutex );
172 if( ctrl && !ctrl->IsShownOnScreen() )
173 ctrl->RefreshFonts();
180 int nChoices, wxString* aChoices,
int aStyle ) :
181 wxOwnerDrawnComboBox( aParent, aId, wxEmptyString, aPosition, aSize, 0, nullptr, aStyle )
218#if defined( __WXMSW__ )
220 Delete( GetCount() - 1 );
231 wxString selection = GetValue();
244 for(
const wxString& font : menuList )
254 Append(
_(
"Default Font" ) );
261 if( !selection.IsEmpty() )
262 SetStringSelection( selection );
282 SetSelection( GetCount() - 1 );
290 int sel = GetSelection();
304 if( GetSelection() <= 0 )
326 wxString
name = GetString( aItem );
329 int sysW = 0, sysH = 0;
330 GetTextExtent(
name, &sysW, &sysH );
332 return sysH + FromDIP( 6 );
338 static const wxString c_sampleString = wxS(
"AaBbCcDd123456" );
340 if( aItem == wxNOT_FOUND )
343 wxString
name = GetString( aItem );
345 aDc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) );
348 int sysW = 0, sysH = 0, sysDescent = 0;
349 aDc.GetTextExtent(
name, &sysW, &sysH, &sysDescent );
352 wxRect nameRect = wxRect( aRect.x + 2, aRect.y, sysW, sysH ).CenterIn( aRect, wxVERTICAL );
353 aDc.DrawText(
name, nameRect.GetTopLeft() );
357 wxFont sampleFont( wxFontInfo( aDc.GetFont().GetPointSize() ).FaceName(
name ) );
358 aDc.SetFont( sampleFont );
360 if( aFlags & wxODCB_PAINTING_SELECTED )
361 aDc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
363 aDc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
366 int sampleW = 0, sampleH = 0, sampleDescent = 0;
367 aDc.GetTextExtent(
name, &sampleW, &sampleH, &sampleDescent );
370 aDc.DrawText( c_sampleString, nameRect.GetRight() + 15,
371 nameRect.GetBottom() - sysDescent - sampleH + sampleDescent + 1 );
384 int keyCode = aEvent.GetKeyCode();
386 if( keyCode == WXK_RETURN || keyCode == WXK_NUMPAD_ENTER || keyCode == WXK_ESCAPE )
395 else if( keyCode == WXK_BACK && !IsPopupShown() )
400 wxString currentText = GetValue();
401 long selStart, selEnd;
402 GetSelection( &selStart, &selEnd );
404 if( selStart != selEnd )
407 wxString newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
409 ChangeValue( newText );
410 SetInsertionPoint( selStart );
413 else if( selStart > 0 )
416 wxString newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
418 ChangeValue( newText );
419 SetInsertionPoint( selStart - 1 );
431 int keyCode = aEvent.GetUnicodeKey();
432 wchar_t wc =
static_cast<wchar_t>( keyCode );
436 if( !IsPopupShown() )
442 if( std::iswprint( wc ) && !std::iswcntrl( wc ) )
445 wxString currentText = GetValue();
446 long selStart, selEnd;
447 GetSelection( &selStart, &selEnd );
449 wxChar newChar = (wxChar)keyCode;
452 if( selStart != selEnd )
455 newText = currentText.Left( selStart ) + newChar + currentText.Mid( selEnd );
460 long insertionPoint = GetInsertionPoint();
461 newText = currentText.Left( insertionPoint ) + newChar + currentText.Mid( insertionPoint );
466 ChangeValue( newText );
467 SetInsertionPoint( selStart + 1 );
482 wxString currentText = GetValue();
483 long selStart, selEnd;
484 GetSelection( &selStart, &selEnd );
487 long newInsertionPoint;
489 if( selStart != selEnd )
492 newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
493 newInsertionPoint = selStart;
495 else if( selStart > 0 )
498 newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
499 newInsertionPoint = selStart - 1;
507 ChangeValue( newText );
508 SetInsertionPoint( newInsertionPoint );
511 wxString trimmedNewText = newText;
512 trimmedNewText.Trim().Trim(
false );
514 if( trimmedNewText.IsEmpty() )
527 case WXK_NUMPAD_ENTER:
546 SetStringSelection( defaultFont );
574 wxString currentText = GetValue();
593 wxString trimmedText = currentText;
594 trimmedText.Trim().Trim(
false);
597 if( trimmedText.IsEmpty() )
610 if( bestMatch != wxNOT_FOUND )
648 if( !GetValue().IsEmpty() && !IsPopupShown() )
651 CallAfter( [
this]() {
652 if( HasFocus() && !IsPopupShown() )
666 if( GetInsertionPoint() != GetLastPosition() )
668 SetInsertionPointEnd();
672 wxString currentText = GetValue();
673 currentText.Trim().Trim(
false);
676 if( currentText.IsEmpty() )
679 SetStringSelection( defaultFont );
689 SetStringSelection( currentText );
698 if( !partialMatch.IsEmpty() )
700 SetStringSelection( partialMatch );
707 SetStringSelection( defaultFont );
723 if( aText.IsEmpty() )
729 if( bestMatch == wxNOT_FOUND )
733 wxString matchText = GetString( bestMatch );
736 if( matchText.Length() > aText.Length() && matchText.Lower().StartsWith( aText.Lower() ) )
740 ChangeValue( matchText );
741 SetInsertionPoint( aText.Length() );
742 SetSelection( aText.Length(), matchText.Length() );
746 SetSelection( bestMatch );
755 wxString trimmedFilter = aFilter;
756 trimmedFilter.Trim().Trim(
false);
758 if( trimmedFilter.IsEmpty() )
764 wxArrayString filteredList;
770 filteredList.Add( fontName );
778 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
779 filteredList.Add( fontName );
783 wxString currentText = GetValue();
786 bool hadItemsBefore = GetCount() > 0;
787 bool haveItemsNow = filteredList.GetCount() > 0;
788 bool needsPopupRefresh = hadItemsBefore && !haveItemsNow && IsPopupShown();
796 Append( filteredList );
803 if( !currentText.IsEmpty() )
805 ChangeValue( currentText );
806 SetInsertionPointEnd();
812 if( needsPopupRefresh )
817 else if( !IsPopupShown() && haveItemsNow )
826 else if( IsPopupShown() && !haveItemsNow )
833 if( IsPopupShown() && haveItemsNow )
846 wxString selection = GetValue();
853 if( !selection.IsEmpty() )
855 ChangeValue( selection );
856 SetInsertionPointEnd();
865 if( aText.IsEmpty() )
869 wxString trimmedText = aText;
870 trimmedText.Trim().Trim(
false);
872 if( trimmedText.IsEmpty() )
875 wxString lowerText = trimmedText.Lower();
882 if( itemText.StartsWith( lowerText ) )
887 for(
unsigned int j = 0; j < GetCount(); j++ )
889 if( GetString( j ) == fullFontName )
901 if( aText.IsEmpty() )
902 return wxEmptyString;
905 wxString trimmedText = aText;
906 trimmedText.Trim().Trim(
false);
908 if( trimmedText.IsEmpty() )
909 return wxEmptyString;
911 wxString testText = trimmedText;
915 while( testText.Length() >= 2 )
917 wxString lowerTestText = testText.Lower();
924 if( itemText.StartsWith( lowerTestText ) )
932 testText = testText.Left( testText.Length() - 1 );
936 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
wxCoord OnMeasureItem(size_t aItem) const override
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)
void OnDrawItem(wxDC &aDc, const wxRect &aRect, int aItem, int aFlags) const override
wxArrayString m_fullFontList
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)
bool m_hasIndeterminateChoice
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.
Functions to provide common constants and other functions to assist in making a consistent UI.
#define INDETERMINATE_ACTION