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.