1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/common/fontpickercmn.cpp
3 // Purpose:     wxFontPickerCtrl class implementation
4 // Author:      Francesco Montorsi
5 // Modified by:
6 // Created:     15/04/2006
7 // RCS-ID:      $Id: fontpickercmn.cpp 42999 2006-11-03 21:54:13Z VZ $
8 // Copyright:   (c) Francesco Montorsi
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 #if wxUSE_FONTPICKERCTRL
28 
29 #include "wx/fontpicker.h"
30 
31 #ifndef WX_PRECOMP
32     #include "wx/textctrl.h"
33 #endif
34 
35 #include "wx/fontenum.h"
36 #include "wx/tokenzr.h"
37 
38 // ============================================================================
39 // implementation
40 // ============================================================================
41 
42 const wxChar wxFontPickerCtrlNameStr[] = wxT("fontpicker");
43 const wxChar wxFontPickerWidgetNameStr[] = wxT("fontpickerwidget");
44 
45 DEFINE_EVENT_TYPE(wxEVT_COMMAND_FONTPICKER_CHANGED)
IMPLEMENT_DYNAMIC_CLASS(wxFontPickerCtrl,wxPickerBase)46 IMPLEMENT_DYNAMIC_CLASS(wxFontPickerCtrl, wxPickerBase)
47 IMPLEMENT_DYNAMIC_CLASS(wxFontPickerEvent, wxCommandEvent)
48 
49 // ----------------------------------------------------------------------------
50 // wxFontPickerCtrl
51 // ----------------------------------------------------------------------------
52 
53 #define M_PICKER     ((wxFontPickerWidget*)m_picker)
54 
55 bool wxFontPickerCtrl::Create( wxWindow *parent, wxWindowID id,
56                         const wxFont &initial,
57                         const wxPoint &pos, const wxSize &size,
58                         long style, const wxValidator& validator,
59                         const wxString &name )
60 {
61     if (!wxPickerBase::CreateBase(parent, id,
62                                   Font2String(initial.IsOk() ? initial
63                                                              : *wxNORMAL_FONT),
64                                   pos, size, style, validator, name))
65         return false;
66 
67     // the picker of a wxFontPickerCtrl is a wxFontPickerWidget
68     m_picker = new wxFontPickerWidget(this, wxID_ANY, initial,
69                                       wxDefaultPosition, wxDefaultSize,
70                                       GetPickerStyle(style));
71     // complete sizer creation
72     wxPickerBase::PostCreation();
73 
74     m_picker->Connect(wxEVT_COMMAND_FONTPICKER_CHANGED,
75             wxFontPickerEventHandler(wxFontPickerCtrl::OnFontChange),
76             NULL, this);
77 
78     return true;
79 }
80 
Font2String(const wxFont & f)81 wxString wxFontPickerCtrl::Font2String(const wxFont &f)
82 {
83     wxString ret = f.GetNativeFontInfoUserDesc();
84 #ifdef __WXMSW__
85     // on wxMSW the encoding of the font is appended at the end of the string;
86     // since encoding is not very user-friendly we remove it.
87     wxFontEncoding enc = f.GetEncoding();
88     if ( enc != wxFONTENCODING_DEFAULT && enc != wxFONTENCODING_SYSTEM )
89         ret = ret.BeforeLast(wxT(' '));
90 #endif
91     return ret;
92 }
93 
String2Font(const wxString & s)94 wxFont wxFontPickerCtrl::String2Font(const wxString &s)
95 {
96     wxString str(s);
97     wxFont ret;
98     double n;
99 
100     // put a limit on the maximum point size which the user can enter
101     // NOTE: we suppose the last word of given string is the pointsize
102     wxString size = str.AfterLast(wxT(' '));
103     if (size.ToDouble(&n))
104     {
105         if (n < 1)
106             str = str.Left(str.length() - size.length()) + wxT("1");
107         else if (n >= m_nMaxPointSize)
108             str = str.Left(str.length() - size.length()) +
109                   wxString::Format(wxT("%d"), m_nMaxPointSize);
110     }
111 
112     if (!ret.SetNativeFontInfoUserDesc(str))
113         return wxNullFont;
114 
115     return ret;
116 }
117 
SetSelectedFont(const wxFont & f)118 void wxFontPickerCtrl::SetSelectedFont(const wxFont &f)
119 {
120     M_PICKER->SetSelectedFont(f);
121     UpdateTextCtrlFromPicker();
122 }
123 
UpdatePickerFromTextCtrl()124 void wxFontPickerCtrl::UpdatePickerFromTextCtrl()
125 {
126     wxASSERT(m_text);
127 
128     if (m_bIgnoreNextTextCtrlUpdate)
129     {
130         // ignore this update
131         m_bIgnoreNextTextCtrlUpdate = false;
132         return;
133     }
134 
135     // NB: we don't use the wxFont::wxFont(const wxString &) constructor
136     //     since that constructor expects the native font description
137     //     string returned by wxFont::GetNativeFontInfoDesc() and not
138     //     the user-friendly one returned by wxFont::GetNativeFontInfoUserDesc()
139     wxFont f = String2Font(m_text->GetValue());
140     if (!f.Ok())
141         return;     // invalid user input
142 
143     if (M_PICKER->GetSelectedFont() != f)
144     {
145         M_PICKER->SetSelectedFont(f);
146 
147         // fire an event
148         wxFontPickerEvent event(this, GetId(), f);
149         GetEventHandler()->ProcessEvent(event);
150     }
151 }
152 
UpdateTextCtrlFromPicker()153 void wxFontPickerCtrl::UpdateTextCtrlFromPicker()
154 {
155     if (!m_text)
156         return;     // no textctrl to update
157 
158     // NOTE: this SetValue() will generate an unwanted wxEVT_COMMAND_TEXT_UPDATED
159     //       which will trigger a unneeded UpdateFromTextCtrl(); thus before using
160     //       SetValue() we set the m_bIgnoreNextTextCtrlUpdate flag...
161     m_bIgnoreNextTextCtrlUpdate = true;
162     m_text->SetValue(Font2String(M_PICKER->GetSelectedFont()));
163 }
164 
165 
166 
167 // ----------------------------------------------------------------------------
168 // wxFontPickerCtrl - event handlers
169 // ----------------------------------------------------------------------------
170 
OnFontChange(wxFontPickerEvent & ev)171 void wxFontPickerCtrl::OnFontChange(wxFontPickerEvent &ev)
172 {
173     UpdateTextCtrlFromPicker();
174 
175     // the wxFontPickerWidget sent us a colour-change notification.
176     // forward this event to our parent
177     wxFontPickerEvent event(this, GetId(), ev.GetFont());
178     GetEventHandler()->ProcessEvent(event);
179 }
180 
181 #endif  // wxUSE_FONTPICKERCTRL
182