wxFontEnumerator class for Motif/X
[wxWidgets.git] / samples / font / font.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: font.cpp
3 // Purpose: wxFont demo
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 30.09.99
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include <wx/wxprec.h>
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 // for all others, include the necessary headers (this file is usually all you
20 // need because it includes almost all <standard< wxWindows headers
21 #ifndef WX_PRECOMP
22 #include <wx/wx.h>
23
24 #include <wx/log.h>
25 #endif
26
27 #include <wx/fontdlg.h>
28 #include <wx/fontenum.h>
29
30 // ----------------------------------------------------------------------------
31 // private classes
32 // ----------------------------------------------------------------------------
33
34 // Define a new application type, each program should derive a class from wxApp
35 class MyApp : public wxApp
36 {
37 public:
38 // override base class virtuals
39 // ----------------------------
40
41 // this one is called on application startup and is a good place for the app
42 // initialization (doing it here and not in the ctor allows to have an error
43 // return: if OnInit() returns false, the application terminates)
44 virtual bool OnInit();
45 };
46
47 // MyCanvas is a canvas on which we show the font sample
48 class MyCanvas: public wxWindow
49 {
50 public:
51 MyCanvas( wxWindow *parent );
52 ~MyCanvas();
53
54 // accessors for the frame
55 const wxFont& GetTextFont() const { return m_font; }
56 const wxColour& GetColour() const { return m_colour; }
57 void SetTextFont(const wxFont& font) { m_font = font; }
58 void SetColour(const wxColour& colour) { m_colour = colour; }
59
60 // event handlers
61 void OnPaint( wxPaintEvent &event );
62
63 private:
64 wxColour m_colour;
65 wxFont m_font;
66
67 DECLARE_EVENT_TABLE()
68 };
69
70 // Define a new frame type: this is going to be our main frame
71 class MyFrame : public wxFrame
72 {
73 public:
74 // ctor(s)
75 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
76
77 // accessors
78 MyCanvas *GetCanvas() const { return m_canvas; }
79
80 // event handlers (these functions should _not_ be virtual)
81 void OnQuit(wxCommandEvent& event);
82 void OnAbout(wxCommandEvent& event);
83 void OnSelectFont(wxCommandEvent& event);
84 void OnCreateFont(wxCommandEvent& event);
85 void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event))
86 { DoEnumerateFamilies(FALSE); }
87 void OnEnumerateFixedFamilies(wxCommandEvent& WXUNUSED(event))
88 { DoEnumerateFamilies(TRUE); }
89
90 protected:
91 void DoEnumerateFamilies(bool fixedWidthOnly);
92
93 MyCanvas *m_canvas;
94
95 private:
96 // any class wishing to process wxWindows events must use this macro
97 DECLARE_EVENT_TABLE()
98 };
99
100 // A custom font dialog which allows to directly edit wxFont proprieties
101 class MyFontDialog : public wxDialog
102 {
103 public:
104 MyFontDialog(MyFrame *frame);
105
106 // event handlers
107 void OnApply(wxCommandEvent& WXUNUSED(event)) { DoApply(); }
108
109 protected:
110 void DoApply();
111
112 MyCanvas *m_canvas;
113
114 private:
115 //DECLARE_EVENT_TABLE() TODO
116 };
117
118 // ----------------------------------------------------------------------------
119 // constants
120 // ----------------------------------------------------------------------------
121
122 // IDs for the controls and the menu commands
123 enum
124 {
125 // menu items
126 Font_Quit = 1,
127 Font_About,
128 Font_Choose = 100,
129 Font_Create,
130 Font_EnumFamilies,
131 Font_EnumFixedFamilies,
132 Font_Max
133 };
134
135 // ----------------------------------------------------------------------------
136 // event tables and other macros for wxWindows
137 // ----------------------------------------------------------------------------
138
139 // the event tables connect the wxWindows events with the functions (event
140 // handlers) which process them. It can be also done at run-time, but for the
141 // simple menu events like this the static method is much simpler.
142 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
143 EVT_MENU(Font_Quit, MyFrame::OnQuit)
144 EVT_MENU(Font_About, MyFrame::OnAbout)
145 EVT_MENU(Font_Choose, MyFrame::OnSelectFont)
146 EVT_MENU(Font_Create, MyFrame::OnCreateFont)
147 EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies)
148 EVT_MENU(Font_EnumFixedFamilies, MyFrame::OnEnumerateFixedFamilies)
149 END_EVENT_TABLE()
150
151 // Create a new application object: this macro will allow wxWindows to create
152 // the application object during program execution (it's better than using a
153 // static object for many reasons) and also declares the accessor function
154 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
155 // not wxApp)
156 IMPLEMENT_APP(MyApp)
157
158 // ============================================================================
159 // implementation
160 // ============================================================================
161
162 // ----------------------------------------------------------------------------
163 // the application class
164 // ----------------------------------------------------------------------------
165
166 // `Main program' equivalent: the program execution "starts" here
167 bool MyApp::OnInit()
168 {
169 // Create the main application window
170 MyFrame *frame = new MyFrame("Font wxWindows demo",
171 wxPoint(50, 50), wxSize(450, 340));
172
173 // Show it and tell the application that it's our main window
174 frame->Show(TRUE);
175 SetTopWindow(frame);
176
177 // success: wxApp::OnRun() will be called which will enter the main message
178 // loop and the application will run. If we returned FALSE here, the
179 // application would exit immediately.
180 return TRUE;
181 }
182
183 // ----------------------------------------------------------------------------
184 // main frame
185 // ----------------------------------------------------------------------------
186
187 // frame constructor
188 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
189 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
190 {
191 // create a menu bar
192 wxMenu *menuFile = new wxMenu;
193
194 menuFile->Append(Font_About, "&About...\tCtrl-A", "Show about dialog");
195 menuFile->AppendSeparator();
196 menuFile->Append(Font_Quit, "E&xit\tAlt-X", "Quit this program");
197
198 wxMenu *menuFont = new wxMenu;
199 menuFont->Append(Font_Choose, "&Select font...\tCtrl-S",
200 "Select a standard font");
201 menuFont->Append(Font_Create, "&Create font...\tCtrl-C",
202 "Create a custom font");
203 menuFont->AppendSeparator();
204 menuFont->Append(Font_EnumFamilies, "&Enumerate font families\tCtrl-E");
205 menuFont->Append(Font_EnumFixedFamilies,
206 "&Enumerate fixed font families\tCtrl-F");
207
208 // now append the freshly created menu to the menu bar...
209 wxMenuBar *menuBar = new wxMenuBar;
210 menuBar->Append(menuFile, "&File");
211 menuBar->Append(menuFont, "F&ont");
212
213 // ... and attach this menu bar to the frame
214 SetMenuBar(menuBar);
215
216 m_canvas = new MyCanvas(this);
217
218 // create a status bar just for fun (by default with 1 pane only)
219 CreateStatusBar(2);
220 SetStatusText("Welcome to wxWindows!");
221 }
222
223
224 // event handlers
225
226 void MyFrame::DoEnumerateFamilies(bool fixedWidthOnly)
227 {
228 class MyFontEnumerator : public wxFontEnumerator
229 {
230 public:
231 MyFontEnumerator() { m_n = 0; }
232
233 protected:
234 virtual bool OnFontFamily(const wxString& family)
235 {
236 wxLogMessage("Font family %d: %s\n", ++m_n, family.c_str());
237
238 return TRUE;
239 }
240
241 private:
242 size_t m_n;
243 } fontEnumerator;
244
245 wxLogMessage("Enumerating %s font families:",
246 fixedWidthOnly ? "fixed width" : "all");
247 fontEnumerator.EnumerateFamilies(fixedWidthOnly);
248 }
249
250 void MyFrame::OnCreateFont(wxCommandEvent& WXUNUSED(event))
251 {
252 MyFontDialog dialog(this);
253
254 (void)dialog.ShowModal();
255 }
256
257 void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event))
258 {
259 wxFontData data;
260 data.SetInitialFont(m_canvas->GetTextFont());
261 data.SetColour(m_canvas->GetColour());
262
263 wxFontDialog dialog(this, &data);
264 if ( dialog.ShowModal() == wxID_OK )
265 {
266 wxFontData retData = dialog.GetFontData();
267 m_canvas->SetTextFont(retData.GetChosenFont());
268 m_canvas->SetColour(retData.GetColour());
269 m_canvas->Refresh();
270 }
271 }
272
273 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
274 {
275 // TRUE is to force the frame to close
276 Close(TRUE);
277 }
278
279 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
280 {
281 wxMessageBox("wxWindows font demo.", "About Font",
282 wxOK | wxICON_INFORMATION, this);
283 }
284
285
286 // ----------------------------------------------------------------------------
287 // MyCanvas
288 // ----------------------------------------------------------------------------
289
290 BEGIN_EVENT_TABLE(MyCanvas, wxWindow)
291 EVT_PAINT(MyCanvas::OnPaint)
292 END_EVENT_TABLE()
293
294 MyCanvas::MyCanvas( wxWindow *parent )
295 : wxWindow( parent, -1 )
296 {
297 m_font = *wxNORMAL_FONT;
298 m_colour = *wxRED;
299 }
300
301 MyCanvas::~MyCanvas()
302 {
303 }
304
305 void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
306 {
307 wxPaintDC dc(this);
308 PrepareDC(dc);
309
310 // set background
311 dc.SetBackground(wxBrush("white", wxSOLID));
312 dc.Clear();
313
314 // output the font name/info
315 wxString fontInfo;
316 fontInfo.Printf("Font family is '%s', style '%s', weight '%s'",
317 m_font.GetFamilyString().c_str(),
318 m_font.GetStyleString().c_str(),
319 m_font.GetWeightString().c_str());
320
321 dc.DrawText(fontInfo, 5, 5);
322
323 // prepare to draw the font
324 dc.SetFont(m_font);
325 dc.SetTextForeground(m_colour);
326
327 // the size of one cell (char + small margin)
328 int w = dc.GetCharWidth() + 5,
329 h = dc.GetCharHeight() + 4;
330
331 // the origin for our table
332 int x = 5,
333 y = 2*h + 5;
334
335 // print all font symbols from 32 to 256 in 7 rows of 32 chars each
336 for ( int i = 1; i < 8; i++ )
337 {
338 for ( int j = 0; j < 32; j++ )
339 {
340 dc.DrawText(char(32*i + j), x + w*j, y + h*i);
341 }
342 }
343
344 // draw the lines between them
345 dc.SetPen(wxPen(wxColour("blue"), 1, wxSOLID));
346 int l;
347
348 // horizontal
349 y += h;
350 for ( l = 0; l < 8; l++ )
351 {
352 int yl = y + h*l - 2;
353 dc.DrawLine(x - 2, yl, x + 32*w - 2, yl);
354 }
355
356 // and vertical
357 for ( l = 0; l < 33; l++ )
358 {
359 int xl = x + w*l - 2;
360 dc.DrawLine(xl, y, xl, y + 7*h - 2);
361 }
362 }
363
364 // ----------------------------------------------------------------------------
365 // MyFontDialog
366 // ----------------------------------------------------------------------------
367
368 MyFontDialog::MyFontDialog(MyFrame *frame)
369 : wxDialog(frame, -1, wxString("Edit font attributes"))
370 {
371 m_canvas = frame->GetCanvas();
372
373 // create controls
374 wxSize sizeBtn = wxButton::GetDefaultSize();
375
376 // TODO
377
378 // position and size the dialog
379 SetClientSize(4*sizeBtn.x, 10*sizeBtn.y);
380 Centre();
381 }
382
383 void MyFontDialog::DoApply()
384 {
385 wxFont font; //(size, family, style, weight, underlined, face, encoding);
386 if ( !font.Ok() )
387 {
388 wxLogError("Font creation failed.");
389 }
390 else
391 {
392 m_canvas->SetTextFont(font);
393 m_canvas->Refresh();
394 }
395 }