1 /////////////////////////////////////////////////////////////////////////////
2 // Name: font.cpp
3 // Purpose: wxFont demo
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 30.09.99
7 // Copyright: (c) 1999 Vadim Zeitlin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx/wx.h".
12 #include "wx/wxprec.h"
13
14
15 // for all others, include the necessary headers (this file is usually all you
16 // need because it includes almost all standard wxWidgets headers
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19
20 #include "wx/log.h"
21 #endif
22
23 #include "wx/checkbox.h"
24 #include "wx/choicdlg.h"
25 #include "wx/fontdlg.h"
26 #include "wx/fontenum.h"
27 #include "wx/fontmap.h"
28 #include "wx/encconv.h"
29 #include "wx/sizer.h"
30 #include "wx/spinctrl.h"
31 #include "wx/splitter.h"
32 #include "wx/statline.h"
33 #include "wx/stdpaths.h"
34 #include "wx/textfile.h"
35 #include "wx/settings.h"
36
37 #include "../sample.xpm"
38
39 #ifdef __WXMAC__
40 #undef wxFontDialog
41 #include "wx/osx/fontdlg.h"
42 #endif
43
44 // used as title for several dialog boxes
GetSampleTitle()45 static wxString GetSampleTitle()
46 {
47 return "wxWidgets Font Sample";
48 }
49
50 // ----------------------------------------------------------------------------
51 // private classes
52 // ----------------------------------------------------------------------------
53
54 // Define a new application type, each program should derive a class from wxApp
55 class MyApp : public wxApp
56 {
57 public:
58 // override base class virtuals
59 // ----------------------------
60
61 // this one is called on application startup and is a good place for the app
62 // initialization (doing it here and not in the ctor allows to have an error
63 // return: if OnInit() returns false, the application terminates)
64 virtual bool OnInit() wxOVERRIDE;
65 };
66
67 // FontPanel contains controls allowing to specify the font properties
68 class FontPanel : public wxPanel
69 {
70 public:
71 explicit FontPanel(wxWindow* parent);
72
ShowFont(const wxFont & font)73 void ShowFont(const wxFont& font) { m_font = font; DoUpdate(); }
74
75 wxFontInfo GetFontInfo() const;
76
77 private:
78 // Update m_useXXX flags depending on which control was changed last.
OnFacename(wxCommandEvent & e)79 void OnFacename(wxCommandEvent& e) { m_useFamily = false; e.Skip(); }
OnFamily(wxCommandEvent & e)80 void OnFamily(wxCommandEvent& e) { m_useFamily = true; e.Skip(); }
81
OnWeightChoice(wxCommandEvent & e)82 void OnWeightChoice(wxCommandEvent& e) { m_useNumericWeight = false; e.Skip(); }
OnWeightSpin(wxCommandEvent & e)83 void OnWeightSpin(wxCommandEvent& e) { m_useNumericWeight = true; e.Skip(); }
84
85
86 // Unlike wxFontXXX, the elements of these enum are consecutive, which is
87 // more convenient here.
88 enum Family
89 {
90 Family_Default,
91 Family_Decorative,
92 Family_Roman,
93 Family_Script,
94 Family_Swiss,
95 Family_Modern,
96 Family_Teletype
97 };
98
99 enum Style
100 {
101 Style_Normal,
102 Style_Italic,
103 Style_Slant
104 };
105
106 enum Weight
107 {
108 Weight_Thin,
109 Weight_Extralight,
110 Weight_Light,
111 Weight_Normal,
112 Weight_Medium,
113 Weight_Semibold,
114 Weight_Bold,
115 Weight_Extrabold,
116 Weight_Heavy,
117 Weight_Extraheavy
118 };
119
120 void DoUpdate();
121
122 wxFont m_font;
123
124 wxTextCtrl* m_textFaceName;
125 wxChoice* m_choiceFamily;
126 wxSpinCtrlDouble* m_spinPointSize;
127 wxChoice* m_choiceStyle;
128 wxChoice* m_choiceWeight;
129 wxSpinCtrl* m_spinWeight;
130 wxCheckBox* m_checkUnderlined;
131 wxCheckBox* m_checkStrikethrough;
132 wxCheckBox* m_checkFixedWidth;
133 wxStaticText* m_labelInfo;
134
135 bool m_useFamily;
136 bool m_useNumericWeight;
137 };
138
139 // FontCanvas shows the font characters.
140 class FontCanvas : public wxWindow
141 {
142 public:
143 explicit FontCanvas( wxWindow *parent );
144
145 // accessors for FontWindow
GetTextFont() const146 const wxFont& GetTextFont() const { return m_font; }
GetColour() const147 const wxColour& GetColour() const { return m_colour; }
SetTextFont(const wxFont & font)148 void SetTextFont(const wxFont& font) { m_font = font; }
SetColour(const wxColour & colour)149 void SetColour(const wxColour& colour) { m_colour = colour; }
150
151 // event handlers
152 void OnPaint( wxPaintEvent &event );
153
154 protected:
DoGetBestClientSize() const155 virtual wxSize DoGetBestClientSize() const wxOVERRIDE
156 {
157 return wxSize(80*GetCharWidth(), 15*GetCharHeight());
158 }
159
160 private:
161 wxColour m_colour;
162 wxFont m_font;
163
164 wxDECLARE_EVENT_TABLE();
165 };
166
167 // FontWindow contains both FontPanel and FontCanvas
168 class FontWindow : public wxWindow
169 {
170 public:
171 explicit FontWindow(wxWindow *parent);
172
GetTextFont() const173 const wxFont& GetTextFont() const { return m_canvas->GetTextFont(); }
GetColour() const174 const wxColour& GetColour() const { return m_canvas->GetColour(); }
175
MakeNewFont() const176 wxFont MakeNewFont() const { return m_panel->GetFontInfo(); }
177
178 void UpdateFont(const wxFont& font, const wxColour& colour);
179
180 private:
181 FontPanel* const m_panel;
182 FontCanvas* const m_canvas;
183 };
184
185 // Define a new frame type: this is going to be our main frame
186 class MyFrame : public wxFrame
187 {
188 public:
189 // ctor(s)
190 MyFrame();
191
192 // event handlers (these functions should _not_ be virtual)
193 void OnQuit(wxCommandEvent& event);
194 void OnAbout(wxCommandEvent& event);
195
OnGetBaseFont(wxCommandEvent & WXUNUSED (event))196 void OnGetBaseFont(wxCommandEvent& WXUNUSED(event))
197 { DoChangeFont(m_fontWindow->GetTextFont().GetBaseFont()); }
OnIncFont(wxCommandEvent & WXUNUSED (event))198 void OnIncFont(wxCommandEvent& WXUNUSED(event)) { DoResizeFont(+2); }
OnDecFont(wxCommandEvent & WXUNUSED (event))199 void OnDecFont(wxCommandEvent& WXUNUSED(event)) { DoResizeFont(-2); }
200
201 void OnBold(wxCommandEvent& event);
202 void OnLight(wxCommandEvent& event);
203
204 void OnItalic(wxCommandEvent& event);
205 void OnSlant(wxCommandEvent& event);
206
207 void OnUnderline(wxCommandEvent& event);
208 void OnStrikethrough(wxCommandEvent& event);
209
210 void OnwxPointerFont(wxCommandEvent& event);
211 void OnFontDefault(wxCommandEvent& event);
212 void OnwxSystemSettingsFont(wxCommandEvent& event);
213
214 void OnTestTextValue(wxCommandEvent& event);
215 void OnViewMsg(wxCommandEvent& event);
216 void OnSelectFont(wxCommandEvent& event);
217 void OnEnumerateFamiliesForEncoding(wxCommandEvent& event);
OnEnumerateFamilies(wxCommandEvent & WXUNUSED (event))218 void OnEnumerateFamilies(wxCommandEvent& WXUNUSED(event))
219 { DoEnumerateFamilies(false); }
OnEnumerateFixedFamilies(wxCommandEvent & WXUNUSED (event))220 void OnEnumerateFixedFamilies(wxCommandEvent& WXUNUSED(event))
221 { DoEnumerateFamilies(true); }
222 void OnEnumerateEncodings(wxCommandEvent& event);
223
224 void OnSetNativeDesc(wxCommandEvent& event);
225 void OnSetNativeUserDesc(wxCommandEvent& event);
226
227 void OnSetFamily(wxCommandEvent& event);
228 void OnSetFaceName(wxCommandEvent& event);
229 void OnSetEncoding(wxCommandEvent& event);
230 void OnPrivateFont(wxCommandEvent& event);
231
OnFontPanelApply(wxCommandEvent & WXUNUSED (event))232 void OnFontPanelApply(wxCommandEvent& WXUNUSED(event))
233 { DoChangeFont(m_fontWindow->MakeNewFont()); }
234
235 protected:
236 bool DoEnumerateFamilies(bool fixedWidthOnly,
237 wxFontEncoding encoding = wxFONTENCODING_SYSTEM,
238 bool silent = false);
239
240 void DoResizeFont(int diff);
241 void DoChangeFont(const wxFont& font, const wxColour& col = wxNullColour);
242
243 // ask the user to choose an encoding and return it or
244 // wxFONTENCODING_SYSTEM if the dialog was cancelled
245 wxFontEncoding GetEncodingFromUser();
246
247 // ask the user to choose a font family and return it or
248 // wxFONTFAMILY_DEFAULT if the dialog was cancelled
249 wxFontFamily GetFamilyFromUser();
250
251 wxTextCtrl *m_textctrl;
252 FontWindow *m_fontWindow;
253
254 private:
255 // any class wishing to process wxWidgets events must use this macro
256 wxDECLARE_EVENT_TABLE();
257 };
258
259 // ----------------------------------------------------------------------------
260 // constants
261 // ----------------------------------------------------------------------------
262
263 // IDs for the controls and the menu commands
264 enum
265 {
266 // menu items
267 Font_Quit = wxID_EXIT,
268 Font_About = wxID_ABOUT,
269
270 Font_ViewMsg = wxID_HIGHEST+1,
271 Font_TestTextValue,
272
273 Font_IncSize,
274 Font_DecSize,
275
276 Font_GetBaseFont,
277
278 Font_Bold,
279 Font_Light,
280
281 Font_Italic,
282 Font_Slant,
283
284 Font_Underlined,
285 Font_Strikethrough,
286
287 // standard global wxFont objects:
288 Font_wxNORMAL_FONT,
289 Font_wxSMALL_FONT,
290 Font_wxITALIC_FONT,
291 Font_wxSWISS_FONT,
292 Font_wxFont_Default,
293 Font_Standard,
294
295 // wxSystemSettings::GetFont possible objects:
296 Font_wxSYS_OEM_FIXED_FONT,
297 Font_wxSYS_ANSI_FIXED_FONT,
298 Font_wxSYS_ANSI_VAR_FONT,
299 Font_wxSYS_SYSTEM_FONT,
300 Font_wxSYS_DEVICE_DEFAULT_FONT,
301 Font_wxSYS_DEFAULT_GUI_FONT,
302 Font_SystemSettings,
303
304 Font_Choose = 100,
305 Font_EnumFamiliesForEncoding,
306 Font_EnumFamilies,
307 Font_EnumFixedFamilies,
308 Font_EnumEncodings,
309 Font_SetNativeDesc,
310 Font_SetNativeUserDesc,
311 Font_SetFamily,
312 Font_SetFaceName,
313 Font_SetEncoding,
314
315 Font_Private,
316 Font_Max
317 };
318
319 // ----------------------------------------------------------------------------
320 // event tables and other macros for wxWidgets
321 // ----------------------------------------------------------------------------
322
323 // the event tables connect the wxWidgets events with the functions (event
324 // handlers) which process them. It can be also done at run-time, but for the
325 // simple menu events like this the static method is much simpler.
326 wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
327 EVT_MENU(Font_Quit, MyFrame::OnQuit)
328 EVT_MENU(Font_TestTextValue, MyFrame::OnTestTextValue)
329 EVT_MENU(Font_ViewMsg, MyFrame::OnViewMsg)
330 EVT_MENU(Font_About, MyFrame::OnAbout)
331
332 EVT_MENU(Font_GetBaseFont, MyFrame::OnGetBaseFont)
333 EVT_MENU(Font_IncSize, MyFrame::OnIncFont)
334 EVT_MENU(Font_DecSize, MyFrame::OnDecFont)
335
336 EVT_MENU(Font_Bold, MyFrame::OnBold)
337 EVT_MENU(Font_Light, MyFrame::OnLight)
338
339 EVT_MENU(Font_Italic, MyFrame::OnItalic)
340 EVT_MENU(Font_Slant, MyFrame::OnSlant)
341
342 EVT_MENU(Font_Underlined, MyFrame::OnUnderline)
343 EVT_MENU(Font_Strikethrough, MyFrame::OnStrikethrough)
344
345 EVT_MENU(Font_wxNORMAL_FONT, MyFrame::OnwxPointerFont)
346 EVT_MENU(Font_wxSMALL_FONT, MyFrame::OnwxPointerFont)
347 EVT_MENU(Font_wxITALIC_FONT, MyFrame::OnwxPointerFont)
348 EVT_MENU(Font_wxSWISS_FONT, MyFrame::OnwxPointerFont)
349 EVT_MENU(Font_wxFont_Default, MyFrame::OnFontDefault)
350
351 EVT_MENU(Font_wxSYS_OEM_FIXED_FONT, MyFrame::OnwxSystemSettingsFont)
352 EVT_MENU(Font_wxSYS_ANSI_FIXED_FONT, MyFrame::OnwxSystemSettingsFont)
353 EVT_MENU(Font_wxSYS_ANSI_VAR_FONT, MyFrame::OnwxSystemSettingsFont)
354 EVT_MENU(Font_wxSYS_SYSTEM_FONT, MyFrame::OnwxSystemSettingsFont)
355 EVT_MENU(Font_wxSYS_DEVICE_DEFAULT_FONT, MyFrame::OnwxSystemSettingsFont)
356 EVT_MENU(Font_wxSYS_DEFAULT_GUI_FONT, MyFrame::OnwxSystemSettingsFont)
357
358 EVT_MENU(Font_SetNativeDesc, MyFrame::OnSetNativeDesc)
359 EVT_MENU(Font_SetNativeUserDesc, MyFrame::OnSetNativeUserDesc)
360 EVT_MENU(Font_SetFamily, MyFrame::OnSetFamily)
361 EVT_MENU(Font_SetFaceName, MyFrame::OnSetFaceName)
362 EVT_MENU(Font_SetEncoding, MyFrame::OnSetEncoding)
363
364 EVT_MENU(Font_Choose, MyFrame::OnSelectFont)
365 EVT_MENU(Font_EnumFamiliesForEncoding, MyFrame::OnEnumerateFamiliesForEncoding)
366 EVT_MENU(Font_EnumFamilies, MyFrame::OnEnumerateFamilies)
367 EVT_MENU(Font_EnumFixedFamilies, MyFrame::OnEnumerateFixedFamilies)
368 EVT_MENU(Font_EnumEncodings, MyFrame::OnEnumerateEncodings)
369 EVT_MENU(Font_Private, MyFrame::OnPrivateFont)
370 wxEND_EVENT_TABLE()
371
372 // Create a new application object: this macro will allow wxWidgets to create
373 // the application object during program execution (it's better than using a
374 // static object for many reasons) and also declares the accessor function
375 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
376 // not wxApp)
377 wxIMPLEMENT_APP(MyApp);
378
379 // ============================================================================
380 // implementation
381 // ============================================================================
382
383 // ----------------------------------------------------------------------------
384 // the application class
385 // ----------------------------------------------------------------------------
386
387 // `Main program' equivalent: the program execution "starts" here
OnInit()388 bool MyApp::OnInit()
389 {
390 if ( !wxApp::OnInit() )
391 return false;
392
393 // Create the main application window
394 MyFrame *frame = new MyFrame();
395
396 // Show it
397 frame->Show(true);
398
399 // success: wxApp::OnRun() will be called which will enter the main message
400 // loop and the application will run. If we returned 'false' here, the
401 // application would exit immediately.
402 return true;
403 }
404
405 // ----------------------------------------------------------------------------
406 // main frame
407 // ----------------------------------------------------------------------------
408
409 // frame constructor
MyFrame()410 MyFrame::MyFrame()
411 : wxFrame(NULL, wxID_ANY, "wxWidgets font sample")
412 {
413 SetIcon(wxICON(sample));
414
415 // create a menu bar
416 wxMenu *menuFile = new wxMenu;
417
418 menuFile->Append(Font_TestTextValue, "&Test text value",
419 "Verify that getting and setting text value doesn't change it");
420 menuFile->Append(Font_ViewMsg, "&View...\tCtrl-V",
421 "View an email message file");
422 menuFile->AppendSeparator();
423 menuFile->Append(Font_About, "&About\tCtrl-A", "Show about dialog");
424 menuFile->AppendSeparator();
425 menuFile->Append(Font_Quit, "E&xit\tAlt-X", "Quit this program");
426
427 wxMenu *menuFont = new wxMenu;
428 menuFont->Append(Font_IncSize, "&Increase font size by 2 points\tCtrl-I");
429 menuFont->Append(Font_DecSize, "&Decrease font size by 2 points\tCtrl-D");
430 menuFont->Append(Font_GetBaseFont, "Use &base version of the font\tCtrl-0");
431 menuFont->AppendSeparator();
432 menuFont->AppendCheckItem(Font_Bold, "&Bold\tCtrl-B", "Toggle bold state");
433 menuFont->AppendCheckItem(Font_Light, "&Light\tCtrl-L", "Toggle light state");
434 menuFont->AppendSeparator();
435 menuFont->AppendCheckItem(Font_Italic, "&Oblique\tCtrl-O", "Toggle italic state");
436 #ifndef __WXMSW__
437 // under wxMSW slant == italic so there's no reason to provide another menu item for the same thing
438 menuFont->AppendCheckItem(Font_Slant, "&Slant\tCtrl-S", "Toggle slant state");
439 #endif
440 menuFont->AppendSeparator();
441 menuFont->AppendCheckItem(Font_Underlined, "&Underlined\tCtrl-U",
442 "Toggle underlined state");
443 menuFont->AppendCheckItem(Font_Strikethrough, "&Strikethrough",
444 "Toggle strikethrough state");
445
446 menuFont->AppendSeparator();
447 menuFont->Append(Font_SetNativeDesc,
448 "Set native font &description\tShift-Ctrl-D");
449 menuFont->Append(Font_SetNativeUserDesc,
450 "Set &user font description\tShift-Ctrl-U");
451 menuFont->AppendSeparator();
452 menuFont->Append(Font_SetFamily, "Set font family");
453 menuFont->Append(Font_SetFaceName, "Set font face name");
454 menuFont->Append(Font_SetEncoding, "Set font &encoding\tShift-Ctrl-E");
455
456 wxMenu *menuSelect = new wxMenu;
457 menuSelect->Append(Font_Choose, "&Select font...\tCtrl-S",
458 "Select a standard font");
459
460 wxMenu *menuStdFonts = new wxMenu;
461 menuStdFonts->Append(Font_wxNORMAL_FONT, "wxNORMAL_FONT", "Normal font used by wxWidgets");
462 menuStdFonts->Append(Font_wxSMALL_FONT, "wxSMALL_FONT", "Small font used by wxWidgets");
463 menuStdFonts->Append(Font_wxITALIC_FONT, "wxITALIC_FONT", "Italic font used by wxWidgets");
464 menuStdFonts->Append(Font_wxSWISS_FONT, "wxSWISS_FONT", "Swiss font used by wxWidgets");
465 menuStdFonts->Append(Font_wxFont_Default, "wxFont()", "wxFont constructed from default wxFontInfo");
466 menuSelect->Append(Font_Standard, "Standar&d fonts", menuStdFonts);
467
468 wxMenu *menuSettingFonts = new wxMenu;
469 menuSettingFonts->Append(Font_wxSYS_OEM_FIXED_FONT, "wxSYS_OEM_FIXED_FONT",
470 "Original equipment manufacturer dependent fixed-pitch font.");
471 menuSettingFonts->Append(Font_wxSYS_ANSI_FIXED_FONT, "wxSYS_ANSI_FIXED_FONT",
472 "Windows fixed-pitch (monospaced) font. ");
473 menuSettingFonts->Append(Font_wxSYS_ANSI_VAR_FONT, "wxSYS_ANSI_VAR_FONT",
474 "Windows variable-pitch (proportional) font.");
475 menuSettingFonts->Append(Font_wxSYS_SYSTEM_FONT, "wxSYS_SYSTEM_FONT",
476 "System font.");
477 menuSettingFonts->Append(Font_wxSYS_DEVICE_DEFAULT_FONT, "wxSYS_DEVICE_DEFAULT_FONT",
478 "Device-dependent font.");
479 menuSettingFonts->Append(Font_wxSYS_DEFAULT_GUI_FONT, "wxSYS_DEFAULT_GUI_FONT",
480 "Default font for user interface objects such as menus and dialog boxes. ");
481 menuSelect->Append(Font_SystemSettings, "System fonts", menuSettingFonts);
482
483 menuSelect->AppendSeparator();
484 menuSelect->Append(Font_EnumFamilies, "Enumerate font &families\tCtrl-F");
485 menuSelect->Append(Font_EnumFixedFamilies,
486 "Enumerate fi&xed font families\tCtrl-X");
487 menuSelect->Append(Font_EnumEncodings,
488 "Enumerate &encodings\tCtrl-E");
489 menuSelect->Append(Font_EnumFamiliesForEncoding,
490 "Find font for en&coding...\tCtrl-C",
491 "Find font families for given encoding");
492
493 #if wxUSE_PRIVATE_FONTS
494 // Try to use a private font, under most platforms we just look for it in
495 // the current directory but under OS X it must be in a specific location
496 // so look for it there.
497 //
498 // For OS X you also need to ensure that you actually do put wxprivate.ttf
499 // in font.app/Contents/Resources/Fonts and add the following snippet
500 //
501 // <plist version="0.9">
502 // <dict>
503 // ...
504 // <key>ATSApplicationFontsPath</key>
505 // <string>Fonts</string>
506 // ...
507 // </dict>
508 // </plist>
509 //
510 // to your font.app/Contents/Info.plist.
511
512 wxString privfont;
513 #ifdef __WXOSX__
514 privfont << wxStandardPaths::Get().GetResourcesDir() << "/Fonts/";
515 #endif
516 privfont << "wxprivate.ttf";
517
518 if ( !wxFont::AddPrivateFont(privfont) )
519 {
520 wxLogWarning("Failed to add private font from \"%s\"", privfont);
521 }
522 else
523 {
524 menuSelect->AppendSeparator();
525 menuSelect->Append(Font_Private,
526 "Select private font",
527 "Select a font available only in this application");
528 }
529 #endif // wxUSE_PRIVATE_FONTS
530
531
532 // now append the freshly created menu to the menu bar...
533 wxMenuBar *menuBar = new wxMenuBar;
534 menuBar->Append(menuFile, "&File");
535 menuBar->Append(menuFont, "F&ont");
536 menuBar->Append(menuSelect, "&Select");
537
538 // ... and attach this menu bar to the frame
539 SetMenuBar(menuBar);
540
541 wxSplitterWindow *splitter = new wxSplitterWindow(this);
542
543 m_fontWindow = new FontWindow(splitter);
544
545 m_fontWindow->Bind(wxEVT_BUTTON, &MyFrame::OnFontPanelApply, this);
546
547 m_textctrl = new wxTextCtrl(splitter, wxID_ANY,
548 "Paste text here to see how it looks\nlike in the given font",
549 wxDefaultPosition,
550 wxSize(-1, 6*GetCharHeight()),
551 wxTE_MULTILINE);
552
553 splitter->SplitHorizontally(m_fontWindow, m_textctrl, 0);
554
555 #if wxUSE_STATUSBAR
556 // create a status bar just for fun (by default with 1 pane only)
557 CreateStatusBar();
558 SetStatusText("Welcome to wxWidgets font demo!");
559 #endif // wxUSE_STATUSBAR
560
561 SetClientSize(splitter->GetBestSize());
562 splitter->SetSashPosition(m_fontWindow->GetBestSize().y);
563 }
564
565 // --------------------------------------------------------
566
567 class MyEncodingEnumerator : public wxFontEnumerator
568 {
569 public:
MyEncodingEnumerator()570 MyEncodingEnumerator()
571 { m_n = 0; }
572
GetText() const573 const wxString& GetText() const
574 { return m_text; }
575
576 protected:
OnFontEncoding(const wxString & facename,const wxString & encoding)577 virtual bool OnFontEncoding(const wxString& facename,
578 const wxString& encoding) wxOVERRIDE
579 {
580 wxString text;
581 text.Printf("Encoding %u: %s (available in facename '%s')\n",
582 (unsigned int) ++m_n, encoding, facename);
583 m_text += text;
584 return true;
585 }
586
587 private:
588 size_t m_n;
589 wxString m_text;
590 };
591
OnEnumerateEncodings(wxCommandEvent & WXUNUSED (event))592 void MyFrame::OnEnumerateEncodings(wxCommandEvent& WXUNUSED(event))
593 {
594 MyEncodingEnumerator fontEnumerator;
595
596 fontEnumerator.EnumerateEncodings();
597
598 wxLogMessage("Enumerating all available encodings:\n%s",
599 fontEnumerator.GetText());
600 }
601
602 // -------------------------------------------------------------
603
604 class MyFontEnumerator : public wxFontEnumerator
605 {
606 public:
GotAny() const607 bool GotAny() const
608 { return !m_facenames.IsEmpty(); }
609
GetFacenames() const610 const wxArrayString& GetFacenames() const
611 { return m_facenames; }
612
613 protected:
OnFacename(const wxString & facename)614 virtual bool OnFacename(const wxString& facename) wxOVERRIDE
615 {
616 m_facenames.Add(facename);
617 return true;
618 }
619
620 private:
621 wxArrayString m_facenames;
622 };
623
DoEnumerateFamilies(bool fixedWidthOnly,wxFontEncoding encoding,bool silent)624 bool MyFrame::DoEnumerateFamilies(bool fixedWidthOnly,
625 wxFontEncoding encoding,
626 bool silent)
627 {
628 MyFontEnumerator fontEnumerator;
629
630 fontEnumerator.EnumerateFacenames(encoding, fixedWidthOnly);
631
632 if ( fontEnumerator.GotAny() )
633 {
634 int nFacenames = fontEnumerator.GetFacenames().GetCount();
635 if ( !silent )
636 {
637 wxLogStatus(this, "Found %d %sfonts",
638 nFacenames, fixedWidthOnly ? "fixed width " : "");
639 }
640
641 wxString facename;
642
643 if ( silent )
644 {
645 // choose the first
646 facename = fontEnumerator.GetFacenames().Item(0);
647 }
648 else
649 {
650 // let the user choose
651 wxString *facenames = new wxString[nFacenames];
652 int n;
653 for ( n = 0; n < nFacenames; n++ )
654 facenames[n] = fontEnumerator.GetFacenames().Item(n);
655
656 n = wxGetSingleChoiceIndex
657 (
658 "Choose a facename",
659 GetSampleTitle(),
660 nFacenames,
661 facenames,
662 this
663 );
664
665 if ( n != -1 )
666 facename = facenames[n];
667
668 delete [] facenames;
669 }
670
671 if ( !facename.empty() )
672 {
673 wxFont font(wxFontInfo().FaceName(facename).Encoding(encoding));
674
675 DoChangeFont(font);
676 }
677
678 return true;
679 }
680 else if ( !silent )
681 {
682 wxLogWarning("No such fonts found.");
683 }
684
685 return false;
686 }
687
OnEnumerateFamiliesForEncoding(wxCommandEvent & WXUNUSED (event))688 void MyFrame::OnEnumerateFamiliesForEncoding(wxCommandEvent& WXUNUSED(event))
689 {
690 wxFontEncoding enc = GetEncodingFromUser();
691 if ( enc != wxFONTENCODING_SYSTEM )
692 {
693 DoEnumerateFamilies(false, enc);
694 }
695 }
696
OnSetNativeDesc(wxCommandEvent & WXUNUSED (event))697 void MyFrame::OnSetNativeDesc(wxCommandEvent& WXUNUSED(event))
698 {
699 wxString fontInfo = wxGetTextFromUser
700 (
701 "Enter native font string",
702 "Input font description",
703 m_fontWindow->GetTextFont().GetNativeFontInfoDesc(),
704 this
705 );
706 if ( fontInfo.empty() )
707 return; // user clicked "Cancel" - do nothing
708
709 wxFont font;
710 font.SetNativeFontInfo(fontInfo);
711 if ( !font.IsOk() )
712 {
713 wxLogError("Font info string \"%s\" is invalid.",
714 fontInfo);
715 return;
716 }
717
718 DoChangeFont(font);
719 }
720
OnSetNativeUserDesc(wxCommandEvent & WXUNUSED (event))721 void MyFrame::OnSetNativeUserDesc(wxCommandEvent& WXUNUSED(event))
722 {
723 wxString fontdesc = m_fontWindow->GetTextFont().GetNativeFontInfoUserDesc();
724 wxString fontUserInfo = wxGetTextFromUser(
725 "Here you can edit current font description",
726 "Input font description", fontdesc,
727 this);
728 if (fontUserInfo.IsEmpty())
729 return; // user clicked "Cancel" - do nothing
730
731 wxFont font;
732 if (font.SetNativeFontInfoUserDesc(fontUserInfo))
733 {
734 wxASSERT_MSG(font.IsOk(), "The font should now be valid");
735 DoChangeFont(font);
736 }
737 else
738 {
739 wxASSERT_MSG(!font.IsOk(), "The font should now be invalid");
740 wxMessageBox("Error trying to create a font with such description...");
741 }
742 }
743
OnSetFamily(wxCommandEvent & WXUNUSED (event))744 void MyFrame::OnSetFamily(wxCommandEvent& WXUNUSED(event))
745 {
746 wxFontFamily f = GetFamilyFromUser();
747
748 wxFont font = m_fontWindow->GetTextFont();
749 font.SetFamily(f);
750 DoChangeFont(font);
751 }
752
OnSetFaceName(wxCommandEvent & WXUNUSED (event))753 void MyFrame::OnSetFaceName(wxCommandEvent& WXUNUSED(event))
754 {
755 wxString facename = m_fontWindow->GetTextFont().GetFaceName();
756 wxString newFaceName = wxGetTextFromUser(
757 "Here you can edit current font face name.",
758 "Input font facename", facename,
759 this);
760 if (newFaceName.IsEmpty())
761 return; // user clicked "Cancel" - do nothing
762
763 wxFont font(m_fontWindow->GetTextFont());
764 if (font.SetFaceName(newFaceName)) // change facename only
765 {
766 wxASSERT_MSG(font.IsOk(), "The font should now be valid");
767 DoChangeFont(font);
768 }
769 else
770 {
771 wxASSERT_MSG(!font.IsOk(), "The font should now be invalid");
772 wxMessageBox("There is no font with such face name...",
773 "Invalid face name", wxOK|wxICON_ERROR, this);
774 }
775 }
776
OnSetEncoding(wxCommandEvent & WXUNUSED (event))777 void MyFrame::OnSetEncoding(wxCommandEvent& WXUNUSED(event))
778 {
779 wxFontEncoding enc = GetEncodingFromUser();
780 if ( enc == wxFONTENCODING_SYSTEM )
781 return;
782
783 wxFont font = m_fontWindow->GetTextFont();
784 font.SetEncoding(enc);
785 DoChangeFont(font);
786 }
787
GetEncodingFromUser()788 wxFontEncoding MyFrame::GetEncodingFromUser()
789 {
790 wxArrayString names;
791 wxArrayInt encodings;
792
793 const size_t count = wxFontMapper::GetSupportedEncodingsCount();
794 names.reserve(count);
795 encodings.reserve(count);
796
797 for ( size_t n = 0; n < count; n++ )
798 {
799 wxFontEncoding enc = wxFontMapper::GetEncoding(n);
800 encodings.push_back(enc);
801 names.push_back(wxFontMapper::GetEncodingName(enc));
802 }
803
804 int i = wxGetSingleChoiceIndex
805 (
806 "Choose the encoding",
807 GetSampleTitle(),
808 names,
809 this
810 );
811
812 return i == -1 ? wxFONTENCODING_SYSTEM : (wxFontEncoding)encodings[i];
813 }
814
GetFamilyFromUser()815 wxFontFamily MyFrame::GetFamilyFromUser()
816 {
817 wxArrayString names;
818 wxArrayInt families;
819
820 families.push_back(wxFONTFAMILY_DECORATIVE);
821 families.push_back(wxFONTFAMILY_ROMAN);
822 families.push_back(wxFONTFAMILY_SCRIPT);
823 families.push_back(wxFONTFAMILY_SWISS);
824 families.push_back(wxFONTFAMILY_MODERN);
825 families.push_back(wxFONTFAMILY_TELETYPE);
826
827 names.push_back("DECORATIVE");
828 names.push_back("ROMAN");
829 names.push_back("SCRIPT");
830 names.push_back("SWISS");
831 names.push_back("MODERN");
832 names.push_back("TELETYPE");
833
834 int i = wxGetSingleChoiceIndex
835 (
836 "Choose the family",
837 GetSampleTitle(),
838 names,
839 this
840 );
841
842 return i == -1 ? wxFONTFAMILY_DEFAULT : (wxFontFamily)families[i];
843 }
844
DoResizeFont(int diff)845 void MyFrame::DoResizeFont(int diff)
846 {
847 wxFont font = m_fontWindow->GetTextFont();
848
849 font.SetPointSize(font.GetPointSize() + diff);
850 DoChangeFont(font);
851 }
852
OnBold(wxCommandEvent & event)853 void MyFrame::OnBold(wxCommandEvent& event)
854 {
855 wxFont font = m_fontWindow->GetTextFont();
856
857 font.SetWeight(event.IsChecked() ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL);
858 DoChangeFont(font);
859 }
860
OnLight(wxCommandEvent & event)861 void MyFrame::OnLight(wxCommandEvent& event)
862 {
863 wxFont font = m_fontWindow->GetTextFont();
864
865 font.SetWeight(event.IsChecked() ? wxFONTWEIGHT_LIGHT : wxFONTWEIGHT_NORMAL);
866 DoChangeFont(font);
867 }
868
OnItalic(wxCommandEvent & event)869 void MyFrame::OnItalic(wxCommandEvent& event)
870 {
871 wxFont font = m_fontWindow->GetTextFont();
872
873 font.SetStyle(event.IsChecked() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL);
874 DoChangeFont(font);
875 }
876
OnSlant(wxCommandEvent & event)877 void MyFrame::OnSlant(wxCommandEvent& event)
878 {
879 wxFont font = m_fontWindow->GetTextFont();
880
881 font.SetStyle(event.IsChecked() ? wxFONTSTYLE_SLANT : wxFONTSTYLE_NORMAL);
882 DoChangeFont(font);
883 }
884
OnUnderline(wxCommandEvent & event)885 void MyFrame::OnUnderline(wxCommandEvent& event)
886 {
887 wxFont font = m_fontWindow->GetTextFont();
888
889 font.SetUnderlined(event.IsChecked());
890 DoChangeFont(font);
891 }
892
OnStrikethrough(wxCommandEvent & event)893 void MyFrame::OnStrikethrough(wxCommandEvent& event)
894 {
895 wxFont font = m_fontWindow->GetTextFont();
896 font.SetStrikethrough(event.IsChecked());
897 DoChangeFont(font);
898 }
899
OnwxPointerFont(wxCommandEvent & event)900 void MyFrame::OnwxPointerFont(wxCommandEvent& event)
901 {
902 wxFont font;
903
904 switch ( event.GetId() )
905 {
906 case Font_wxNORMAL_FONT:
907 font = *wxNORMAL_FONT;
908 break;
909
910 case Font_wxSMALL_FONT:
911 font = *wxSMALL_FONT;
912 break;
913
914 case Font_wxITALIC_FONT:
915 font = *wxITALIC_FONT;
916 break;
917
918 case Font_wxSWISS_FONT:
919 font = *wxSWISS_FONT;
920 break;
921
922 default:
923 wxFAIL_MSG( "unknown standard font" );
924 return;
925 }
926
927 DoChangeFont(font);
928 }
929
OnFontDefault(wxCommandEvent & WXUNUSED (event))930 void MyFrame::OnFontDefault(wxCommandEvent& WXUNUSED(event))
931 {
932 DoChangeFont(wxFont(wxFontInfo()));
933 }
934
OnwxSystemSettingsFont(wxCommandEvent & event)935 void MyFrame::OnwxSystemSettingsFont(wxCommandEvent& event)
936 {
937 wxFont font;
938
939 switch ( event.GetId() )
940 {
941 case Font_wxSYS_OEM_FIXED_FONT:
942 font = wxSystemSettings::GetFont(wxSYS_OEM_FIXED_FONT);
943 break;
944
945 case Font_wxSYS_ANSI_FIXED_FONT:
946 font = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT);
947 break;
948
949 case Font_wxSYS_ANSI_VAR_FONT:
950 font = wxSystemSettings::GetFont(wxSYS_ANSI_VAR_FONT);
951 break;
952
953 case Font_wxSYS_SYSTEM_FONT:
954 font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
955 break;
956
957 case Font_wxSYS_DEVICE_DEFAULT_FONT:
958 font = wxSystemSettings::GetFont(wxSYS_DEVICE_DEFAULT_FONT);
959 break;
960
961 case Font_wxSYS_DEFAULT_GUI_FONT:
962 font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
963 break;
964
965 default:
966 wxFAIL_MSG( "unknown standard font" );
967 return;
968 }
969
970 DoChangeFont(font);
971 }
972
DoChangeFont(const wxFont & font,const wxColour & col)973 void MyFrame::DoChangeFont(const wxFont& font, const wxColour& col)
974 {
975 m_fontWindow->UpdateFont(font, col);
976
977 m_textctrl->SetFont(font);
978 if ( col.IsOk() )
979 m_textctrl->SetForegroundColour(col);
980 m_textctrl->Refresh();
981
982 // update the state of the bold/italic/underlined menu items
983 wxMenuBar *mbar = GetMenuBar();
984 if ( mbar )
985 {
986 mbar->Check(Font_Light, font.GetWeight() == wxFONTWEIGHT_LIGHT);
987 mbar->Check(Font_Bold, font.GetWeight() == wxFONTWEIGHT_BOLD);
988
989 mbar->Check(Font_Italic, font.GetStyle() == wxFONTSTYLE_ITALIC);
990 #ifndef __WXMSW__
991 mbar->Check(Font_Slant, font.GetStyle() == wxFONTSTYLE_SLANT);
992 #endif
993
994 mbar->Check(Font_Underlined, font.GetUnderlined());
995 mbar->Check(Font_Strikethrough, font.GetStrikethrough());
996 }
997 }
998
OnSelectFont(wxCommandEvent & WXUNUSED (event))999 void MyFrame::OnSelectFont(wxCommandEvent& WXUNUSED(event))
1000 {
1001 wxFontData data;
1002 data.SetInitialFont(m_fontWindow->GetTextFont());
1003 data.SetColour(m_fontWindow->GetColour());
1004
1005 wxFontDialog dialog(this, data);
1006 if ( dialog.ShowModal() == wxID_OK )
1007 {
1008 wxFontData retData = dialog.GetFontData();
1009 wxFont font = retData.GetChosenFont();
1010 wxColour colour = retData.GetColour();
1011
1012 DoChangeFont(font, colour);
1013 }
1014 }
1015
OnPrivateFont(wxCommandEvent & WXUNUSED (event))1016 void MyFrame::OnPrivateFont(wxCommandEvent& WXUNUSED(event))
1017 {
1018 wxFont font(m_fontWindow->GetTextFont());
1019 if (font.SetFaceName("wxprivate"))
1020 {
1021 wxASSERT_MSG( font.IsOk(), "The font should now be valid") ;
1022 DoChangeFont(font);
1023 }
1024 else
1025 {
1026 wxLogError("Failed to use private font.");
1027 }
1028 }
1029
OnQuit(wxCommandEvent & WXUNUSED (event))1030 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1031 {
1032 // true is to force the frame to close
1033 Close(true);
1034 }
1035
OnTestTextValue(wxCommandEvent & WXUNUSED (event))1036 void MyFrame::OnTestTextValue(wxCommandEvent& WXUNUSED(event))
1037 {
1038 wxString value = m_textctrl->GetValue();
1039 m_textctrl->SetValue(value);
1040 if ( m_textctrl->GetValue() != value )
1041 {
1042 wxLogError("Text value changed after getting and setting it");
1043 }
1044 }
1045
OnViewMsg(wxCommandEvent & WXUNUSED (event))1046 void MyFrame::OnViewMsg(wxCommandEvent& WXUNUSED(event))
1047 {
1048 #if wxUSE_FILEDLG
1049 // first, choose the file
1050 static wxString s_dir, s_file;
1051 wxFileDialog dialog(this, "Open an email message file",
1052 s_dir, s_file);
1053 if ( dialog.ShowModal() != wxID_OK )
1054 return;
1055
1056 // save for the next time
1057 s_dir = dialog.GetDirectory();
1058 s_file = dialog.GetFilename();
1059
1060 wxString filename = dialog.GetPath();
1061
1062 // load it and search for Content-Type header
1063 wxTextFile file(filename);
1064 if ( !file.Open() )
1065 return;
1066
1067 wxString charset;
1068
1069 wxString prefix = "Content-Type: text/plain; charset=";
1070 const size_t len = wxStrlen(prefix);
1071
1072 size_t n, count = file.GetLineCount();
1073 for ( n = 0; n < count; n++ )
1074 {
1075 wxString line = file[n];
1076
1077 if ( !line )
1078 {
1079 // if it is an email message, headers are over, no need to parse
1080 // all the file
1081 break;
1082 }
1083
1084 if ( line.Left(len) == prefix )
1085 {
1086 // found!
1087 const wxChar *pc = line.c_str() + len;
1088 if ( *pc == '"')
1089 pc++;
1090
1091 while ( *pc && *pc != '"')
1092 {
1093 charset += *pc++;
1094 }
1095
1096 break;
1097 }
1098 }
1099
1100 if ( !charset )
1101 {
1102 wxLogError("The file '%s' doesn't contain charset information.",
1103 filename);
1104
1105 return;
1106 }
1107
1108 // ok, now get the corresponding encoding
1109 wxFontEncoding fontenc = wxFontMapper::Get()->CharsetToEncoding(charset);
1110 if ( fontenc == wxFONTENCODING_SYSTEM )
1111 {
1112 wxLogError("Charset '%s' is unsupported.", charset);
1113 return;
1114 }
1115
1116 m_textctrl->LoadFile(filename);
1117
1118 if ( fontenc == wxFONTENCODING_UTF8 ||
1119 !wxFontMapper::Get()->IsEncodingAvailable(fontenc) )
1120 {
1121 // try to find some similar encoding:
1122 wxFontEncoding encAlt;
1123 if ( wxFontMapper::Get()->GetAltForEncoding(fontenc, &encAlt) )
1124 {
1125 wxEncodingConverter conv;
1126
1127 if (conv.Init(fontenc, encAlt))
1128 {
1129 fontenc = encAlt;
1130 m_textctrl -> SetValue(conv.Convert(m_textctrl -> GetValue()));
1131 }
1132 else
1133 {
1134 wxLogWarning("Cannot convert from '%s' to '%s'.",
1135 wxFontMapper::GetEncodingDescription(fontenc),
1136 wxFontMapper::GetEncodingDescription(encAlt));
1137 }
1138 }
1139 else
1140 wxLogWarning("No fonts for encoding '%s' on this system.",
1141 wxFontMapper::GetEncodingDescription(fontenc));
1142 }
1143
1144 // and now create the correct font
1145 if ( !DoEnumerateFamilies(false, fontenc, true /* silent */) )
1146 {
1147 wxFont font(wxFontInfo(wxNORMAL_FONT->GetPointSize()).Encoding(fontenc));
1148 if ( font.IsOk() )
1149 {
1150 DoChangeFont(font);
1151 }
1152 else
1153 {
1154 wxLogWarning("No fonts for encoding '%s' on this system.",
1155 wxFontMapper::GetEncodingDescription(fontenc));
1156 }
1157 }
1158 #endif // wxUSE_FILEDLG
1159 }
1160
OnAbout(wxCommandEvent & WXUNUSED (event))1161 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1162 {
1163 wxMessageBox("wxWidgets font sample\n"
1164 "(c) 1999-2006 Vadim Zeitlin",
1165 wxString("About ") + GetSampleTitle(),
1166 wxOK | wxICON_INFORMATION, this);
1167 }
1168
1169 // ----------------------------------------------------------------------------
1170 // FontWindow
1171 // ----------------------------------------------------------------------------
1172
FontWindow(wxWindow * parent)1173 FontWindow::FontWindow(wxWindow *parent)
1174 : wxWindow(parent, wxID_ANY),
1175 m_panel(new FontPanel(this)),
1176 m_canvas(new FontCanvas(this))
1177 {
1178 wxSizer* const sizer = new wxBoxSizer(wxVERTICAL);
1179 sizer->Add(m_panel, wxSizerFlags().Expand().Border());
1180 sizer->Add(new wxStaticLine(this), wxSizerFlags().Expand());
1181 sizer->Add(m_canvas, wxSizerFlags(1).Expand());
1182 SetSizer(sizer);
1183 }
1184
UpdateFont(const wxFont & font,const wxColour & colour)1185 void FontWindow::UpdateFont(const wxFont& font, const wxColour& colour)
1186 {
1187 m_panel->ShowFont(font);
1188
1189 m_canvas->SetTextFont(font);
1190 if ( colour.IsOk() )
1191 m_canvas->SetColour(colour);
1192 m_canvas->Refresh();
1193 }
1194
1195 // ----------------------------------------------------------------------------
1196 // FontPanel
1197 // ----------------------------------------------------------------------------
1198
FontPanel(wxWindow * parent)1199 FontPanel::FontPanel(wxWindow* parent)
1200 : wxPanel(parent)
1201 {
1202 m_useFamily =
1203 m_useNumericWeight = false;
1204
1205 m_textFaceName = new wxTextCtrl(this, wxID_ANY, wxString(),
1206 wxDefaultPosition, wxDefaultSize,
1207 wxTE_PROCESS_ENTER);
1208 m_textFaceName->Bind(wxEVT_TEXT, &FontPanel::OnFacename, this);
1209
1210 // Must be in sync with the Family enum.
1211 const wxString familiesNames[] =
1212 {
1213 "Default",
1214 "Decorative",
1215 "Roman",
1216 "Script",
1217 "Swiss",
1218 "Modern",
1219 "Teletype",
1220 };
1221 m_choiceFamily = new wxChoice(this, wxID_ANY,
1222 wxDefaultPosition, wxDefaultSize,
1223 WXSIZEOF(familiesNames), familiesNames);
1224 m_choiceFamily->Bind(wxEVT_CHOICE, &FontPanel::OnFamily, this);
1225
1226 m_spinPointSize = new wxSpinCtrlDouble(this, wxID_ANY, wxString(),
1227 wxDefaultPosition, wxDefaultSize,
1228 wxSP_ARROW_KEYS,
1229 1.0, 100.0, 10.0, 0.1);
1230
1231 m_spinPointSize->SetInitialSize
1232 (
1233 m_spinPointSize->GetSizeFromTextSize(GetTextExtent("999.9").x)
1234 );
1235
1236 // Must be in sync with the Style enum.
1237 const wxString stylesNames[] =
1238 {
1239 "Normal",
1240 "Italic",
1241 "Slant",
1242 };
1243
1244 m_choiceStyle = new wxChoice(this, wxID_ANY,
1245 wxDefaultPosition, wxDefaultSize,
1246 WXSIZEOF(stylesNames), stylesNames);
1247
1248 // Must be in sync with the Weight enum.
1249 const wxString weightsNames[] =
1250 {
1251 "Thin",
1252 "Extra light",
1253 "Light",
1254 "Normal",
1255 "Medium",
1256 "Semi-bold",
1257 "Bold",
1258 "Extra bold",
1259 "Heavy",
1260 "Extra heavy",
1261 };
1262
1263 m_choiceWeight = new wxChoice(this, wxID_ANY,
1264 wxDefaultPosition, wxDefaultSize,
1265 WXSIZEOF(weightsNames), weightsNames);
1266 m_choiceWeight->Bind(wxEVT_CHOICE, &FontPanel::OnWeightChoice, this);
1267
1268 m_spinWeight = new wxSpinCtrl(this, wxID_ANY, wxString(),
1269 wxDefaultPosition, wxDefaultSize,
1270 wxSP_ARROW_KEYS,
1271 1, wxFONTWEIGHT_MAX);
1272 m_spinWeight->SetInitialSize
1273 (
1274 m_spinWeight->GetSizeFromTextSize(GetTextExtent("9999").x)
1275 );
1276 m_spinWeight->Bind(wxEVT_SPINCTRL, &FontPanel::OnWeightSpin, this);
1277
1278 m_checkUnderlined = new wxCheckBox(this, wxID_ANY, wxString());
1279 m_checkStrikethrough = new wxCheckBox(this, wxID_ANY, wxString());
1280 m_checkFixedWidth = new wxCheckBox(this, wxID_ANY, wxString());
1281 m_checkFixedWidth->Disable(); // Can't be changed by the user.
1282
1283 m_labelInfo = new wxStaticText(this, wxID_ANY, "\n\n\n");
1284
1285
1286 const int border = wxSizerFlags::GetDefaultBorder();
1287
1288 // Columns are: label, control, gap, label, control, label, control (there
1289 // is no second gap column because we don't want any gap in the weight row).
1290 wxFlexGridSizer* const sizer = new wxFlexGridSizer(7, wxSize(border, border));
1291
1292 const wxSizerFlags flagsLabel = wxSizerFlags().CentreVertical();
1293 const wxSizerFlags flagsValue = wxSizerFlags().Expand().CentreVertical();
1294
1295 sizer->Add(new wxStaticText(this, wxID_ANY, "Face &name:"), flagsLabel);
1296 sizer->Add(m_textFaceName, flagsValue);
1297
1298 sizer->AddSpacer(2*border);
1299
1300 sizer->Add(new wxStaticText(this, wxID_ANY, "&Family:"), flagsLabel);
1301 sizer->Add(m_choiceFamily, flagsValue);
1302
1303 sizer->Add(new wxStaticText(this, wxID_ANY, "&Point size:"),
1304 wxSizerFlags().DoubleBorder(wxLEFT).CentreVertical());
1305 sizer->Add(m_spinPointSize, flagsValue);
1306
1307
1308 sizer->Add(new wxStaticText(this, wxID_ANY, "&Style:"), flagsLabel);
1309 sizer->Add(m_choiceStyle, flagsValue);
1310
1311 sizer->AddSpacer(0);
1312
1313 sizer->Add(new wxStaticText(this, wxID_ANY, "&Weight:"), flagsLabel);
1314 sizer->Add(m_choiceWeight, flagsValue);
1315
1316 sizer->Add(new wxStaticText(this, wxID_ANY, "or &raw value:"), flagsLabel);
1317 sizer->Add(m_spinWeight, flagsValue);
1318
1319
1320 sizer->Add(new wxStaticText(this, wxID_ANY, "&Underlined:"), flagsLabel);
1321 sizer->Add(m_checkUnderlined, flagsValue);
1322
1323 sizer->AddSpacer(0);
1324
1325 sizer->Add(new wxStaticText(this, wxID_ANY, "&Strike through:"), flagsLabel);
1326 sizer->Add(m_checkStrikethrough, flagsValue);
1327
1328 sizer->Add(new wxStaticText(this, wxID_ANY, "Fixed width:"), flagsLabel);
1329 sizer->Add(m_checkFixedWidth, flagsValue);
1330
1331 wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL);
1332 sizerTop->Add(sizer, wxSizerFlags().Expand().Border(wxBOTTOM));
1333 sizerTop->Add(new wxButton(this, wxID_APPLY, "&Apply changes"),
1334 wxSizerFlags().Border(wxBOTTOM).Centre());
1335 sizerTop->Add(m_labelInfo, wxSizerFlags().Expand().Border(wxTOP));
1336 SetSizer(sizerTop);
1337
1338 ShowFont(*wxNORMAL_FONT);
1339 }
1340
DoUpdate()1341 void FontPanel::DoUpdate()
1342 {
1343 m_textFaceName->ChangeValue(m_font.GetFaceName());
1344
1345 Family family = Family_Default;
1346 switch ( m_font.GetFamily() )
1347 {
1348 case wxFONTFAMILY_DECORATIVE: family = Family_Decorative; break;
1349 case wxFONTFAMILY_ROMAN: family = Family_Roman; break;
1350 case wxFONTFAMILY_SCRIPT: family = Family_Script; break;
1351 case wxFONTFAMILY_SWISS: family = Family_Swiss; break;
1352 case wxFONTFAMILY_MODERN: family = Family_Modern; break;
1353 case wxFONTFAMILY_TELETYPE: family = Family_Teletype; break;
1354
1355 case wxFONTFAMILY_DEFAULT:
1356 case wxFONTFAMILY_UNKNOWN:
1357 // Leave family as Family_Default, what else can we do.
1358 break;
1359 }
1360 m_choiceFamily->SetSelection(family);
1361
1362 m_spinPointSize->SetValue(m_font.GetFractionalPointSize());
1363
1364 Style style = Style_Normal;
1365 switch ( m_font.GetStyle() )
1366 {
1367 case wxFONTSTYLE_ITALIC: style = Style_Italic; break;
1368 case wxFONTSTYLE_SLANT: style = Style_Slant; break;
1369
1370 case wxFONTSTYLE_NORMAL:
1371 case wxFONTSTYLE_MAX:
1372 break;
1373 }
1374 m_choiceStyle->SetSelection(style);
1375
1376 Weight weight = Weight_Normal;
1377 switch ( m_font.GetWeight() )
1378 {
1379 case wxFONTWEIGHT_THIN: weight = Weight_Thin; break;
1380 case wxFONTWEIGHT_EXTRALIGHT: weight = Weight_Extralight; break;
1381 case wxFONTWEIGHT_LIGHT: weight = Weight_Light; break;
1382 case wxFONTWEIGHT_MEDIUM: weight = Weight_Medium; break;
1383 case wxFONTWEIGHT_SEMIBOLD: weight = Weight_Semibold; break;
1384 case wxFONTWEIGHT_BOLD: weight = Weight_Bold; break;
1385 case wxFONTWEIGHT_EXTRABOLD: weight = Weight_Extrabold; break;
1386 case wxFONTWEIGHT_HEAVY: weight = Weight_Heavy; break;
1387 case wxFONTWEIGHT_EXTRAHEAVY: weight = Weight_Extraheavy; break;
1388
1389 case wxFONTWEIGHT_NORMAL:
1390 case wxFONTWEIGHT_INVALID:
1391 break;
1392 }
1393 m_choiceWeight->SetSelection(weight);
1394 m_spinWeight->SetValue(m_font.GetNumericWeight());
1395
1396 m_checkUnderlined->SetValue(m_font.GetUnderlined());
1397 m_checkStrikethrough->SetValue(m_font.GetStrikethrough());
1398 m_checkFixedWidth->SetValue(m_font.IsFixedWidth());
1399
1400 const wxSize pixelSize = m_font.GetPixelSize();
1401 wxClientDC dc(this);
1402 dc.SetFont(m_font);
1403
1404 m_labelInfo->SetLabelText
1405 (
1406 wxString::Format
1407 (
1408 "Font info string: %s\n"
1409 "Size in pixels: %d*%d, "
1410 "average char size: %d*%d",
1411 m_font.GetNativeFontInfoDesc(),
1412 pixelSize.x, pixelSize.y,
1413 dc.GetCharWidth(), dc.GetCharHeight()
1414 )
1415 );
1416 }
1417
GetFontInfo() const1418 wxFontInfo FontPanel::GetFontInfo() const
1419 {
1420 wxFontInfo info(m_spinPointSize->GetValue());
1421
1422 if ( m_useFamily )
1423 {
1424 const wxFontFamily families[] =
1425 {
1426 wxFONTFAMILY_DEFAULT,
1427 wxFONTFAMILY_DECORATIVE,
1428 wxFONTFAMILY_ROMAN,
1429 wxFONTFAMILY_SCRIPT,
1430 wxFONTFAMILY_SWISS,
1431 wxFONTFAMILY_MODERN,
1432 wxFONTFAMILY_TELETYPE,
1433 };
1434 info.Family(families[m_choiceFamily->GetSelection()]);
1435 }
1436 else
1437 {
1438 info.FaceName(m_textFaceName->GetValue());
1439 }
1440
1441 switch ( m_choiceStyle->GetSelection() )
1442 {
1443 case Style_Normal:
1444 break;
1445
1446 case Style_Italic:
1447 info.Italic();
1448 break;
1449
1450 case Style_Slant:
1451 info.Slant();
1452 break;
1453 }
1454
1455 info.Weight(m_useNumericWeight ? m_spinWeight->GetValue()
1456 : (m_choiceWeight->GetSelection() + 1)*100);
1457
1458 if ( m_checkUnderlined->GetValue() )
1459 info.Underlined();
1460 if ( m_checkStrikethrough->GetValue() )
1461 info.Strikethrough();
1462
1463 return info;
1464 }
1465
1466 // ----------------------------------------------------------------------------
1467 // FontCanvas
1468 // ----------------------------------------------------------------------------
1469
wxBEGIN_EVENT_TABLE(FontCanvas,wxWindow)1470 wxBEGIN_EVENT_TABLE(FontCanvas, wxWindow)
1471 EVT_PAINT(FontCanvas::OnPaint)
1472 wxEND_EVENT_TABLE()
1473
1474 FontCanvas::FontCanvas( wxWindow *parent )
1475 : wxWindow( parent, wxID_ANY ),
1476 m_colour(*wxRED), m_font(*wxNORMAL_FONT)
1477 {
1478 }
1479
OnPaint(wxPaintEvent & WXUNUSED (event))1480 void FontCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
1481 {
1482 wxPaintDC dc(this);
1483 PrepareDC(dc);
1484
1485 // set background
1486 dc.SetBackground(*wxWHITE_BRUSH);
1487 dc.Clear();
1488 dc.SetFont(m_font);
1489
1490 // the current text origin
1491 wxCoord x = 5,
1492 y = 5;
1493
1494 // prepare to draw the font
1495 dc.SetTextForeground(m_colour);
1496
1497 // the size of one cell (Normally biggest char + small margin)
1498 wxCoord maxCharWidth, maxCharHeight;
1499 dc.GetTextExtent("W", &maxCharWidth, &maxCharHeight);
1500 int w = maxCharWidth + 5,
1501 h = maxCharHeight + 4;
1502
1503
1504 // print all font symbols from 32 to 256 in 7 rows of 32 chars each
1505 for ( int i = 0; i < 7; i++ )
1506 {
1507 for ( int j = 0; j < 32; j++ )
1508 {
1509 wxChar c = (wxChar)(32 * (i + 1) + j);
1510
1511 wxCoord charWidth, charHeight;
1512 dc.GetTextExtent(c, &charWidth, &charHeight);
1513 dc.DrawText
1514 (
1515 c,
1516 x + w*j + (maxCharWidth - charWidth) / 2 + 1,
1517 y + h*i + (maxCharHeight - charHeight) / 2
1518 );
1519 }
1520 }
1521
1522 // draw the lines between them
1523 dc.SetPen(*wxBLUE_PEN);
1524 int l;
1525
1526 // horizontal
1527 for ( l = 0; l < 8; l++ )
1528 {
1529 int yl = y + h*l - 2;
1530 dc.DrawLine(x - 2, yl, x + 32*w - 1, yl);
1531 }
1532
1533 // and vertical
1534 for ( l = 0; l < 33; l++ )
1535 {
1536 int xl = x + w*l - 2;
1537 dc.DrawLine(xl, y - 2, xl, y + 7*h - 1);
1538 }
1539 }
1540