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
42const wxChar wxFontPickerCtrlNameStr[] = wxT("fontpicker");
43const wxChar wxFontPickerWidgetNameStr[] = wxT("fontpickerwidget");
44
45DEFINE_EVENT_TYPE(wxEVT_COMMAND_FONTPICKER_CHANGED)
46IMPLEMENT_DYNAMIC_CLASS(wxFontPickerCtrl, wxPickerBase)
47IMPLEMENT_DYNAMIC_CLASS(wxFontPickerEvent, wxCommandEvent)
48
49// ----------------------------------------------------------------------------
50// wxFontPickerCtrl
51// ----------------------------------------------------------------------------
52
53#define M_PICKER     ((wxFontPickerWidget*)m_picker)
54
55bool 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
81wxString 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
94wxFont 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
118void wxFontPickerCtrl::SetSelectedFont(const wxFont &f)
119{
120    M_PICKER->SetSelectedFont(f);
121    UpdateTextCtrlFromPicker();
122}
123
124void 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
153void 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
171void 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