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 wxString
name = GetString( aItem );
317 int sysW = 0, sysH = 0;
318 GetTextExtent(
name, &sysW, &sysH );
320 return sysH + FromDIP( 6 );
326 static const wxString c_sampleString = wxS(
"AaBbCcDd123456" );
328 if( aItem == wxNOT_FOUND )
331 wxString
name = GetString( aItem );
333 aDc.SetFont( wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ) );
336 int sysW = 0, sysH = 0, sysDescent = 0;
337 aDc.GetTextExtent(
name, &sysW, &sysH, &sysDescent );
340 wxRect nameRect = wxRect( aRect.x + 2, aRect.y, sysW, sysH ).CenterIn( aRect, wxVERTICAL );
341 aDc.DrawText(
name, nameRect.GetTopLeft() );
345 wxFont sampleFont( wxFontInfo( aDc.GetFont().GetPointSize() ).FaceName(
name ) );
346 aDc.SetFont( sampleFont );
348 if( aFlags & wxODCB_PAINTING_SELECTED )
349 aDc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT ) );
351 aDc.SetTextForeground( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
354 int sampleW = 0, sampleH = 0, sampleDescent = 0;
355 aDc.GetTextExtent(
name, &sampleW, &sampleH, &sampleDescent );
358 aDc.DrawText( c_sampleString, nameRect.GetRight() + 15,
359 nameRect.GetBottom() - sysDescent - sampleH + sampleDescent + 1 );
372 int keyCode = aEvent.GetKeyCode();
374 if( keyCode == WXK_RETURN || keyCode == WXK_NUMPAD_ENTER || keyCode == WXK_ESCAPE )
383 else if( keyCode == WXK_BACK && !IsPopupShown() )
388 wxString currentText = GetValue();
389 long selStart, selEnd;
390 GetSelection( &selStart, &selEnd );
392 if( selStart != selEnd )
395 wxString newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
397 ChangeValue( newText );
398 SetInsertionPoint( selStart );
401 else if( selStart > 0 )
404 wxString newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
406 ChangeValue( newText );
407 SetInsertionPoint( selStart - 1 );
419 int keyCode = aEvent.GetUnicodeKey();
420 wchar_t wc =
static_cast<wchar_t>( keyCode );
424 if( !IsPopupShown() )
430 if( std::iswprint( wc ) && !std::iswcntrl( wc ) )
433 wxString currentText = GetValue();
434 long selStart, selEnd;
435 GetSelection( &selStart, &selEnd );
437 wxChar newChar = (wxChar)keyCode;
440 if( selStart != selEnd )
443 newText = currentText.Left( selStart ) + newChar + currentText.Mid( selEnd );
448 long insertionPoint = GetInsertionPoint();
449 newText = currentText.Left( insertionPoint ) + newChar + currentText.Mid( insertionPoint );
454 ChangeValue( newText );
455 SetInsertionPoint( selStart + 1 );
470 wxString currentText = GetValue();
471 long selStart, selEnd;
472 GetSelection( &selStart, &selEnd );
475 long newInsertionPoint;
477 if( selStart != selEnd )
480 newText = currentText.Left( selStart ) + currentText.Mid( selEnd );
481 newInsertionPoint = selStart;
483 else if( selStart > 0 )
486 newText = currentText.Left( selStart - 1 ) + currentText.Mid( selStart );
487 newInsertionPoint = selStart - 1;
495 ChangeValue( newText );
496 SetInsertionPoint( newInsertionPoint );
499 wxString trimmedNewText = newText;
500 trimmedNewText.Trim().Trim(
false );
502 if( trimmedNewText.IsEmpty() )
515 case WXK_NUMPAD_ENTER:
534 SetStringSelection( defaultFont );
562 wxString currentText = GetValue();
581 wxString trimmedText = currentText;
582 trimmedText.Trim().Trim(
false);
585 if( trimmedText.IsEmpty() )
598 if( bestMatch != wxNOT_FOUND )
636 if( !GetValue().IsEmpty() && !IsPopupShown() )
639 CallAfter( [
this]() {
640 if( HasFocus() && !IsPopupShown() )
654 if( GetInsertionPoint() != GetLastPosition() )
656 SetInsertionPointEnd();
660 wxString currentText = GetValue();
661 currentText.Trim().Trim(
false);
664 if( currentText.IsEmpty() )
667 SetStringSelection( defaultFont );
677 SetStringSelection( currentText );
686 if( !partialMatch.IsEmpty() )
688 SetStringSelection( partialMatch );
695 SetStringSelection( defaultFont );
711 if( aText.IsEmpty() )
717 if( bestMatch == wxNOT_FOUND )
721 wxString matchText = GetString( bestMatch );
724 if( matchText.Length() > aText.Length() && matchText.Lower().StartsWith( aText.Lower() ) )
728 ChangeValue( matchText );
729 SetInsertionPoint( aText.Length() );
730 SetSelection( aText.Length(), matchText.Length() );
734 SetSelection( bestMatch );
743 wxString trimmedFilter = aFilter;
744 trimmedFilter.Trim().Trim(
false);
746 if( trimmedFilter.IsEmpty() )
752 wxArrayString filteredList;
758 filteredList.Add( fontName );
766 if( fontName.Lower().StartsWith( trimmedFilter.Lower() ) )
767 filteredList.Add( fontName );
771 wxString currentText = GetValue();
774 bool hadItemsBefore = GetCount() > 0;
775 bool haveItemsNow = filteredList.GetCount() > 0;
776 bool needsPopupRefresh = hadItemsBefore && !haveItemsNow && IsPopupShown();
784 Append( filteredList );
791 if( !currentText.IsEmpty() )
793 ChangeValue( currentText );
794 SetInsertionPointEnd();
800 if( needsPopupRefresh )
805 else if( !IsPopupShown() && haveItemsNow )
814 else if( IsPopupShown() && !haveItemsNow )
821 if( IsPopupShown() && haveItemsNow )
834 wxString selection = GetValue();
841 if( !selection.IsEmpty() )
843 ChangeValue( selection );
844 SetInsertionPointEnd();
853 if( aText.IsEmpty() )
857 wxString trimmedText = aText;
858 trimmedText.Trim().Trim(
false);
860 if( trimmedText.IsEmpty() )
863 wxString lowerText = trimmedText.Lower();
870 if( itemText.StartsWith( lowerText ) )
875 for(
unsigned int j = 0; j < GetCount(); j++ )
877 if( GetString( j ) == fullFontName )
889 if( aText.IsEmpty() )
890 return wxEmptyString;
893 wxString trimmedText = aText;
894 trimmedText.Trim().Trim(
false);
896 if( trimmedText.IsEmpty() )
897 return wxEmptyString;
899 wxString testText = trimmedText;
903 while( testText.Length() >= 2 )
905 wxString lowerTestText = testText.Lower();
912 if( itemText.StartsWith( lowerTestText ) )
920 testText = testText.Left( testText.Length() - 1 );
924 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)
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.