1 /////////////////////////////////////////////////////////////////////////////
2 // Name: richtextsymboldlg.cpp
4 // Author: Julian Smart
6 // Created: 10/5/2006 3:11:58 PM
8 // Copyright: (c) Julian Smart
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
26 #include "wx/fontenum.h"
27 #include "wx/dcbuffer.h"
28 #include "wx/settings.h"
30 #include "../../include/wx/richtext/richtextsymboldlg.h"
35 /* Microsoft Unicode subset numbering
41 U_LATIN_1_SUPPLEMENT
= 1,
42 U_LATIN_EXTENDED_A
= 2,
43 U_LATIN_EXTENDED_B
= 3,
45 U_SPACING_MODIFIER_LETTERS
= 5,
46 U_COMBINING_DIACRITICAL_MARKS
= 6,
48 U_GREEK_SYMBOLS_AND_COPTIC
= 8,
51 U_HEBREW_EXTENDED
= 12,
54 U_ARABIC_EXTENDED
= 14,
66 U_GEORGIAN_EXTENDED
= 27,
67 U_BASIC_GEORGIAN
= 26,
69 U_LATIN_EXTENDED_ADDITIONAL
= 29,
70 U_GREEK_EXTENDED
= 30,
71 U_GENERAL_PUNCTUATION
= 31,
72 U_SUPERSCRIPTS_AND_SUBSCRIPTS
= 32,
73 U_CURRENCY_SYMBOLS
= 33,
74 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS
= 34,
75 U_LETTERLIKE_SYMBOLS
= 35,
78 U_MATHEMATICAL_OPERATORS
= 38,
79 U_MISCELLANEOUS_TECHNICAL
= 39,
80 U_CONTROL_PICTURES
= 40,
81 U_OPTICAL_CHARACTER_RECOGNITION
= 41,
82 U_ENCLOSED_ALPHANUMERICS
= 42,
84 U_BLOCK_ELEMENTS
= 44,
85 U_GEOMETRIC_SHAPES
= 45,
86 U_MISCELLANEOUS_SYMBOLS
= 46,
88 U_CJK_SYMBOLS_AND_PUNCTUATION
= 48,
92 U_HANGUL_COMPATIBILITY_JAMO
= 52,
93 U_CJK_MISCELLANEOUS
= 53,
95 U_CJK_COMPATIBILITY
= 55,
97 U_HANGUL_SUPPLEMENTARY_A
= 57,
98 U_HANGUL_SUPPLEMENTARY_B
= 58,
99 U_CJK_UNIFIED_IDEOGRAPHS
= 59,
100 U_PRIVATE_USE_AREA
= 60,
101 U_CJK_COMPATIBILITY_IDEOGRAPHS
= 61,
102 U_ALPHABETIC_PRESENTATION_FORMS
= 62,
103 U_ARABIC_PRESENTATION_FORMS_A
= 63,
104 U_COMBINING_HALF_MARKS
= 64,
105 U_CJK_COMPATIBILITY_FORMS
= 65,
106 U_SMALL_FORM_VARIANTS
= 66,
107 U_ARABIC_PRESENTATION_FORMS_B
= 67,
109 U_HALFWIDTH_AND_FULLWIDTH_FORMS
= 68,
111 } wxUnicodeSubsetCodes
;
113 /* Unicode subsets */
119 wxUnicodeSubsetCodes m_subset
;
121 } g_UnicodeSubsetTable
[] =
124 U_BASIC_LATIN
, wxT("Basic Latin") },
126 U_LATIN_1_SUPPLEMENT
, wxT("Latin-1 Supplement") },
128 U_LATIN_EXTENDED_A
, wxT("Latin Extended-A") },
130 U_LATIN_EXTENDED_B
, wxT("Latin Extended-B") },
132 U_IPA_EXTENSIONS
, wxT("IPA Extensions") },
134 U_SPACING_MODIFIER_LETTERS
, wxT("Spacing Modifier Letters") },
136 U_COMBINING_DIACRITICAL_MARKS
, wxT("Combining Diacritical Marks") },
138 U_BASIC_GREEK
, wxT("Basic Greek") },
140 U_GREEK_SYMBOLS_AND_COPTIC
, wxT("Greek Symbols and Coptic") },
142 U_CYRILLIC
, wxT("Cyrillic") },
144 U_ARMENIAN
, wxT("Armenian") },
146 U_HEBREW_EXTENDED
, wxT("Hebrew Extended") },
148 U_BASIC_HEBREW
, wxT("Basic Hebrew") },
150 U_BASIC_ARABIC
, wxT("Basic Arabic") },
152 U_ARABIC_EXTENDED
, wxT("Arabic Extended") },
154 U_DEVANAGARI
, wxT("Devanagari") },
156 U_BENGALI
, wxT("Bengali") },
158 U_GURMUKHI
, wxT("Gurmukhi") },
160 U_GUJARATI
, wxT("Gujarati") },
162 U_ORIYA
, wxT("Oriya") },
164 U_TAMIL
, wxT("Tamil") },
166 U_TELUGU
, wxT("Telugu") },
168 U_KANNADA
, wxT("Kannada") },
170 U_MALAYALAM
, wxT("Malayalam") },
172 U_THAI
, wxT("Thai") },
176 U_GEORGIAN_EXTENDED
, wxT("Georgian Extended") },
178 U_BASIC_GEORGIAN
, wxT("Basic Georgian") },
180 U_HANGUL_JAMO
, wxT("Hangul Jamo") },
182 U_LATIN_EXTENDED_ADDITIONAL
, wxT("Latin Extended Additional") },
184 U_GREEK_EXTENDED
, wxT("Greek Extended") },
186 U_GENERAL_PUNCTUATION
, wxT("General Punctuation") },
188 U_SUPERSCRIPTS_AND_SUBSCRIPTS
, wxT("Superscripts and Subscripts") },
190 U_CURRENCY_SYMBOLS
, wxT("Currency Symbols") },
192 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS
, wxT("Combining Diacritical Marks for Symbols") },
194 U_LETTERLIKE_SYMBOLS
, wxT("Letterlike Symbols") },
196 U_NUMBER_FORMS
, wxT("Number Forms") },
198 U_ARROWS
, wxT("Arrows") },
200 U_MATHEMATICAL_OPERATORS
, wxT("Mathematical Operators") },
202 U_MISCELLANEOUS_TECHNICAL
, wxT("Miscellaneous Technical") },
204 U_CONTROL_PICTURES
, wxT("Control Pictures") },
206 U_OPTICAL_CHARACTER_RECOGNITION
, wxT("Optical Character Recognition") },
208 U_ENCLOSED_ALPHANUMERICS
, wxT("Enclosed Alphanumerics") },
210 U_BOX_DRAWING
, wxT("Box Drawing") },
212 U_BLOCK_ELEMENTS
, wxT("Block Elements") },
214 U_GEOMETRIC_SHAPES
, wxT("Geometric Shapes") },
216 U_MISCELLANEOUS_SYMBOLS
, wxT("Miscellaneous Symbols") },
218 U_DINGBATS
, wxT("Dingbats") },
220 U_CJK_SYMBOLS_AND_PUNCTUATION
, wxT("CJK Symbols and Punctuation") },
222 U_HIRAGANA
, wxT("Hiragana") },
224 U_KATAKANA
, wxT("Katakana") },
226 U_BOPOMOFO
, wxT("Bopomofo") },
228 U_HANGUL_COMPATIBILITY_JAMO
, wxT("Hangul Compatibility Jamo") },
230 U_CJK_MISCELLANEOUS
, wxT("CJK Miscellaneous") },
232 U_ENCLOSED_CJK
, wxT("Enclosed CJK") },
234 U_CJK_COMPATIBILITY
, wxT("CJK Compatibility") },
236 U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs Extension A") },
238 U_CJK_UNIFIED_IDEOGRAPHS
, wxT("CJK Unified Ideographs") },
240 U_HANGUL
, wxT("Hangul Syllables") },
242 U_PRIVATE_USE_AREA
, wxT("Private Use Area") },
244 U_CJK_COMPATIBILITY_IDEOGRAPHS
, wxT("CJK Compatibility Ideographs") },
246 U_ALPHABETIC_PRESENTATION_FORMS
, wxT("Alphabetic Presentation Forms") },
248 U_ARABIC_PRESENTATION_FORMS_A
, wxT("Arabic Presentation Forms-A") },
250 U_COMBINING_HALF_MARKS
, wxT("Combining Half Marks") },
252 U_CJK_COMPATIBILITY_FORMS
, wxT("CJK Compatibility Forms") },
254 U_SMALL_FORM_VARIANTS
, wxT("Small Form Variants") },
256 U_ARABIC_PRESENTATION_FORMS_B
, wxT("Arabic Presentation Forms-B") },
258 U_SPECIALS
, wxT("Specials") },
260 U_HALFWIDTH_AND_FULLWIDTH_FORMS
, wxT("Halfwidth and Fullwidth Forms") },
262 U_SPECIALS
, wxT("Specials") }
265 #endif // __UNICODE__
268 // Not yet used, but could be used to test under Win32 whether this subset is available
269 // for the given font. The Win32 function is allegedly not accurate, however.
270 bool wxSubsetValidForFont(int subsetIndex
, FONTSIGNATURE
*fontSig
)
272 return (fontSig
->fsUsb
[g_UnicodeSubsetTable
[subsetIndex
].m_subset
/32] & (1 << (g_UnicodeSubsetTable
[subsetIndex
].m_subset
% 32)));
277 * wxSymbolPickerDialog type definition
280 IMPLEMENT_DYNAMIC_CLASS( wxSymbolPickerDialog
, wxDialog
)
283 * wxSymbolPickerDialog event table definition
286 BEGIN_EVENT_TABLE( wxSymbolPickerDialog
, wxDialog
)
287 EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxSymbolPickerDialog
::OnSymbolSelected
)
289 ////@begin wxSymbolPickerDialog event table entries
290 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT
, wxSymbolPickerDialog
::OnFontCtrlSelected
)
292 #if defined(__UNICODE__)
293 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET
, wxSymbolPickerDialog
::OnSubsetSelected
)
296 #if defined(__UNICODE__)
297 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM
, wxSymbolPickerDialog
::OnFromUnicodeSelected
)
300 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
301 EVT_UPDATE_UI( wxID_OK
, wxSymbolPickerDialog
::OnOkUpdate
)
304 #if defined(__WXMAC__)
305 EVT_UPDATE_UI( wxID_OK
, wxSymbolPickerDialog
::OnOkUpdate
)
308 ////@end wxSymbolPickerDialog event table entries
313 * wxSymbolPickerDialog constructors
316 wxSymbolPickerDialog
::wxSymbolPickerDialog( )
321 wxSymbolPickerDialog
::wxSymbolPickerDialog( const wxString
& symbol
, const wxString
& fontName
, const wxString
& normalTextFont
, wxWindow
* parent
, wxWindowID id
, const wxString
& caption
, const wxPoint
& pos
, const wxSize
& size
, long style
)
324 Create(symbol
, fontName
, normalTextFont
, parent
, id
, caption
, pos
, size
, style
);
328 * wxSymbolPickerDialog creator
331 bool wxSymbolPickerDialog
::Create( const wxString
& symbol
, const wxString
& fontName
, const wxString
& normalTextFont
, wxWindow
* parent
, wxWindowID id
, const wxString
& caption
, const wxPoint
& pos
, const wxSize
& size
, long style
)
333 m_fontName
= fontName
;
334 m_normalTextFontName
= normalTextFont
;
337 ////@begin wxSymbolPickerDialog creation
338 SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS
|wxDIALOG_EX_CONTEXTHELP
);
339 wxDialog
::Create( parent
, id
, caption
, pos
, size
, style
);
344 GetSizer()->SetSizeHints(this);
347 ////@end wxSymbolPickerDialog creation
352 * Member initialisation for wxSymbolPickerDialog
355 void wxSymbolPickerDialog
::Init()
357 ////@begin wxSymbolPickerDialog member initialisation
358 m_fromUnicode
= true;
360 #if defined(__UNICODE__)
363 m_symbolsCtrl
= NULL
;
364 m_symbolStaticCtrl
= NULL
;
365 m_characterCodeCtrl
= NULL
;
366 #if defined(__UNICODE__)
367 m_fromUnicodeCtrl
= NULL
;
369 ////@end wxSymbolPickerDialog member initialisation
370 m_dontUpdate
= false;
374 * Control creation for wxSymbolPickerDialog
377 void wxSymbolPickerDialog
::CreateControls()
379 ////@begin wxSymbolPickerDialog content construction
380 wxSymbolPickerDialog
* itemDialog1
= this;
382 wxBoxSizer
* itemBoxSizer2
= new wxBoxSizer(wxVERTICAL
);
383 itemDialog1
->SetSizer(itemBoxSizer2
);
385 wxBoxSizer
* itemBoxSizer3
= new wxBoxSizer(wxVERTICAL
);
386 itemBoxSizer2
->Add(itemBoxSizer3
, 1, wxGROW
|wxALL
, 5);
388 wxBoxSizer
* itemBoxSizer4
= new wxBoxSizer(wxHORIZONTAL
);
389 itemBoxSizer3
->Add(itemBoxSizer4
, 0, wxGROW
, 5);
391 wxBoxSizer
* itemBoxSizer5
= new wxBoxSizer(wxHORIZONTAL
);
392 itemBoxSizer4
->Add(itemBoxSizer5
, 1, wxGROW
, 5);
394 wxStaticText
* itemStaticText6
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Font:"), wxDefaultPosition
, wxDefaultSize
, 0 );
395 itemBoxSizer5
->Add(itemStaticText6
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5);
397 wxString
* m_fontCtrlStrings
= NULL
;
398 m_fontCtrl
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_FONT
, _T(""), wxDefaultPosition
, wxSize(240, -1), 0, m_fontCtrlStrings
, wxCB_READONLY
);
399 itemBoxSizer5
->Add(m_fontCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
401 itemBoxSizer5
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
403 #if defined(__UNICODE__)
404 wxStaticText
* itemStaticText9
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Subset:"), wxDefaultPosition
, wxDefaultSize
, 0 );
405 itemBoxSizer5
->Add(itemStaticText9
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5);
409 #if defined(__UNICODE__)
410 wxString
* m_subsetCtrlStrings
= NULL
;
411 m_subsetCtrl
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_SUBSET
, _T(""), wxDefaultPosition
, wxDefaultSize
, 0, m_subsetCtrlStrings
, wxCB_READONLY
);
412 m_subsetCtrl
->SetHelpText(_("Shows a Unicode subset."));
414 m_subsetCtrl
->SetToolTip(_("Shows a Unicode subset."));
415 itemBoxSizer5
->Add(m_subsetCtrl
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
419 m_symbolsCtrl
= new wxSymbolListCtrl( itemDialog1
, ID_SYMBOLPICKERDIALOG_LISTCTRL
, wxDefaultPosition
, wxSize(500, 240), wxSIMPLE_BORDER
);
420 itemBoxSizer3
->Add(m_symbolsCtrl
, 1, wxGROW
|wxALL
, 5);
422 wxBoxSizer
* itemBoxSizer12
= new wxBoxSizer(wxHORIZONTAL
);
423 itemBoxSizer3
->Add(itemBoxSizer12
, 0, wxGROW
, 5);
425 m_symbolStaticCtrl
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("xxxx"), wxDefaultPosition
, wxSize(40, -1), wxALIGN_CENTRE
);
426 itemBoxSizer12
->Add(m_symbolStaticCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5);
428 itemBoxSizer12
->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
430 wxStaticText
* itemStaticText15
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&Character code:"), wxDefaultPosition
, wxDefaultSize
, 0 );
431 itemBoxSizer12
->Add(itemStaticText15
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5);
433 m_characterCodeCtrl
= new wxTextCtrl( itemDialog1
, ID_SYMBOLPICKERDIALOG_CHARACTERCODE
, _T(""), wxDefaultPosition
, wxSize(140, -1), wxTE_READONLY
|wxTE_CENTRE
);
434 itemBoxSizer12
->Add(m_characterCodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
436 itemBoxSizer12
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
438 #if defined(__UNICODE__)
439 wxStaticText
* itemStaticText18
= new wxStaticText( itemDialog1
, wxID_STATIC
, _("&From:"), wxDefaultPosition
, wxDefaultSize
, 0 );
440 itemBoxSizer12
->Add(itemStaticText18
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
|wxADJUST_MINSIZE
, 5);
444 #if defined(__UNICODE__)
445 wxString m_fromUnicodeCtrlStrings
[] = {
449 m_fromUnicodeCtrl
= new wxComboBox( itemDialog1
, ID_SYMBOLPICKERDIALOG_FROM
, _("ASCII"), wxDefaultPosition
, wxDefaultSize
, 2, m_fromUnicodeCtrlStrings
, wxCB_READONLY
);
450 m_fromUnicodeCtrl
->SetStringSelection(_("ASCII"));
451 itemBoxSizer12
->Add(m_fromUnicodeCtrl
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
455 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
456 wxBoxSizer
* itemBoxSizer20
= new wxBoxSizer(wxHORIZONTAL
);
457 itemBoxSizer3
->Add(itemBoxSizer20
, 0, wxGROW
, 5);
459 itemBoxSizer20
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
461 wxButton
* itemButton22
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 );
462 itemButton22
->SetDefault();
463 itemButton22
->SetHelpText(_("Inserts the chosen symbol."));
465 itemButton22
->SetToolTip(_("Inserts the chosen symbol."));
466 itemBoxSizer20
->Add(itemButton22
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
468 wxButton
* itemButton23
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
469 itemButton23
->SetHelpText(_("Closes the dialog without inserting a symbol."));
471 itemButton23
->SetToolTip(_("Closes the dialog without inserting a symbol."));
472 itemBoxSizer20
->Add(itemButton23
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
476 #if defined(__WXMAC__)
477 wxBoxSizer
* itemBoxSizer24
= new wxBoxSizer(wxHORIZONTAL
);
478 itemBoxSizer3
->Add(itemBoxSizer24
, 0, wxGROW
, 5);
480 itemBoxSizer24
->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
482 wxButton
* itemButton26
= new wxButton( itemDialog1
, wxID_CANCEL
, _("Close"), wxDefaultPosition
, wxDefaultSize
, 0 );
483 itemButton26
->SetHelpText(_("Closes the dialog without inserting a symbol."));
485 itemButton26
->SetToolTip(_("Closes the dialog without inserting a symbol."));
486 itemBoxSizer24
->Add(itemButton26
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
488 wxButton
* itemButton27
= new wxButton( itemDialog1
, wxID_OK
, _("Insert"), wxDefaultPosition
, wxDefaultSize
, 0 );
489 itemButton27
->SetDefault();
490 itemButton27
->SetHelpText(_("Inserts the chosen symbol."));
492 itemButton27
->SetToolTip(_("Inserts the chosen symbol."));
493 itemBoxSizer24
->Add(itemButton27
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
497 ////@end wxSymbolPickerDialog content construction
502 bool wxSymbolPickerDialog
::TransferDataToWindow()
506 if (m_fontCtrl
->GetCount() == 0)
508 wxFontEnumerator enumerator
;
509 enumerator
.EnumerateFacenames();
510 wxArrayString faceNames
= enumerator
.GetFacenames();
513 faceNames
.Insert(_("(Normal text)"), 0);
514 m_fontCtrl
->Append(faceNames
);
517 if (m_fontName
.IsEmpty())
518 m_fontCtrl
->SetSelection(0);
521 if (m_fontCtrl
->FindString(m_fontName
) != wxNOT_FOUND
)
522 m_fontCtrl
->SetStringSelection(m_fontName
);
524 m_fontCtrl
->SetSelection(0);
527 if (!m_symbol
.IsEmpty())
529 int sel
= (int) m_symbol
[0];
530 m_symbolsCtrl
->SetSelection(sel
);
533 #if defined(__UNICODE__)
534 if (m_subsetCtrl
->GetCount() == 0)
536 // Insert items into subset combo
538 for (i
= 0; i
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++)
540 m_subsetCtrl
->Append(g_UnicodeSubsetTable
[i
].m_name
);
542 m_subsetCtrl
->SetSelection(0);
546 UpdateSymbolDisplay();
548 m_dontUpdate
= false;
553 void wxSymbolPickerDialog
::UpdateSymbolDisplay(bool updateSymbolList
, bool showAtSubset
)
556 wxString fontNameToUse
;
557 if (m_fontName
.IsEmpty())
558 fontNameToUse
= m_normalTextFontName
;
560 fontNameToUse
= m_fontName
;
562 if (!fontNameToUse
.IsEmpty())
564 font
= wxFont(14, wxDEFAULT
, wxNORMAL
, wxNORMAL
, false, fontNameToUse
);
567 font
= *wxNORMAL_FONT
;
569 if (updateSymbolList
)
571 m_symbolsCtrl
->SetFont(font
);
574 if (!m_symbol
.IsEmpty())
576 m_symbolStaticCtrl
->SetFont(font
);
577 m_symbolStaticCtrl
->SetLabel(m_symbol
);
579 int symbol
= (int) m_symbol
[0];
580 m_characterCodeCtrl
->SetValue(wxString
::Format(wxT("%X hex (%d dec)"), symbol
, symbol
));
584 m_symbolStaticCtrl
->SetLabel(wxEmptyString
);
585 m_characterCodeCtrl
->SetValue(wxEmptyString
);
588 #if defined(__UNICODE__)
592 wxUnusedVar(showAtSubset
);
596 /// Show at the current subset selection
597 void wxSymbolPickerDialog
::ShowAtSubset()
599 #if defined(__UNICODE__)
602 int sel
= m_subsetCtrl
->GetSelection();
603 int low
= g_UnicodeSubsetTable
[sel
].m_low
;
604 m_symbolsCtrl
->EnsureVisible(low
);
609 // Handle font selection
610 void wxSymbolPickerDialog
::OnFontCtrlSelected( wxCommandEvent
& WXUNUSED(event
) )
612 if (m_fontCtrl
->GetSelection() == 0)
613 m_fontName
= wxEmptyString
;
615 m_fontName
= m_fontCtrl
->GetStringSelection();
617 UpdateSymbolDisplay();
620 /// Respond to symbol selection
621 void wxSymbolPickerDialog
::OnSymbolSelected( wxCommandEvent
& event
)
626 int sel
= event
.GetSelection();
628 m_symbol
= wxEmptyString
;
631 m_symbol
= wxEmptyString
;
632 m_symbol
<< (wxChar
) sel
;
635 #if defined(__UNICODE__)
636 if (sel
!= -1 && m_fromUnicode
)
638 // Need to make the subset selection reflect the current symbol
640 for (i
= 0; i
< (int) (sizeof(g_UnicodeSubsetTable
)/sizeof(g_UnicodeSubsetTable
[0])); i
++)
642 if (sel
>= g_UnicodeSubsetTable
[i
].m_low
&& sel
<= g_UnicodeSubsetTable
[i
].m_high
)
645 m_subsetCtrl
->SetSelection(i
);
646 m_dontUpdate
= false;
653 UpdateSymbolDisplay(false, false);
656 #if defined(__UNICODE__)
657 // Handle Unicode/ASCII selection
658 void wxSymbolPickerDialog
::OnFromUnicodeSelected( wxCommandEvent
& WXUNUSED(event
) )
663 m_fromUnicode
= (m_fromUnicodeCtrl
->GetSelection() == 1);
664 m_symbolsCtrl
->SetUnicodeMode(m_fromUnicode
);
665 UpdateSymbolDisplay(false);
668 // Handle subset selection
669 void wxSymbolPickerDialog
::OnSubsetSelected( wxCommandEvent
& WXUNUSED(event
) )
679 * wxEVT_UPDATE_UI event handler for wxID_OK
682 void wxSymbolPickerDialog
::OnOkUpdate( wxUpdateUIEvent
& event
)
684 event
.Enable(HasSelection());
688 void wxSymbolPickerDialog
::SetUnicodeMode(bool unicodeMode
)
690 #if defined(__UNICODE__)
692 m_fromUnicode
= unicodeMode
;
693 if (m_fromUnicodeCtrl
)
694 m_fromUnicodeCtrl
->SetSelection(m_fromUnicode ?
1 : 0);
695 UpdateSymbolDisplay();
696 m_dontUpdate
= false;
698 wxUnusedVar(unicodeMode
);
702 /// Get the selected symbol character
703 int wxSymbolPickerDialog
::GetSymbolChar() const
705 if (m_symbol
.IsEmpty())
708 return (int) m_symbol
[0];
713 * Should we show tooltips?
716 bool wxSymbolPickerDialog
::ShowToolTips()
722 * Get bitmap resources
725 wxBitmap wxSymbolPickerDialog
::GetBitmapResource( const wxString
& name
)
728 ////@begin wxSymbolPickerDialog bitmap retrieval
731 ////@end wxSymbolPickerDialog bitmap retrieval
738 wxIcon wxSymbolPickerDialog
::GetIconResource( const wxString
& name
)
741 ////@begin wxSymbolPickerDialog icon retrieval
744 ////@end wxSymbolPickerDialog icon retrieval
748 * The scrolling symbol list.
751 // ----------------------------------------------------------------------------
753 // ----------------------------------------------------------------------------
755 BEGIN_EVENT_TABLE(wxSymbolListCtrl
, wxVScrolledWindow
)
756 EVT_PAINT(wxSymbolListCtrl
::OnPaint
)
757 EVT_SIZE(wxSymbolListCtrl
::OnSize
)
759 EVT_KEY_DOWN(wxSymbolListCtrl
::OnKeyDown
)
760 EVT_LEFT_DOWN(wxSymbolListCtrl
::OnLeftDown
)
761 EVT_LEFT_DCLICK(wxSymbolListCtrl
::OnLeftDClick
)
764 // ============================================================================
766 // ============================================================================
768 IMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl
, wxVScrolledWindow
)
770 // ----------------------------------------------------------------------------
771 // wxSymbolListCtrl creation
772 // ----------------------------------------------------------------------------
774 void wxSymbolListCtrl
::Init()
776 m_current
= wxNOT_FOUND
;
777 m_doubleBuffer
= NULL
;
778 m_cellSize
= wxSize(40, 40);
779 m_minSymbolValue
= 0;
780 m_maxSymbolValue
= 255;
781 m_symbolsPerLine
= 0;
782 m_unicodeMode
= false;
785 bool wxSymbolListCtrl
::Create(wxWindow
*parent
,
790 const wxString
& name
)
792 style
|= wxWANTS_CHARS
| wxFULL_REPAINT_ON_RESIZE
;
793 if ( !wxVScrolledWindow
::Create(parent
, id
, pos
, size
, style
, name
) )
796 // make sure the native widget has the right colour since we do
797 // transparent drawing by default
798 SetBackgroundColour(GetBackgroundColour());
799 m_colBgSel
= wxSystemSettings
::GetColour(wxSYS_COLOUR_HIGHLIGHT
);
801 // flicker-free drawing requires this
802 SetBackgroundStyle(wxBG_STYLE_CUSTOM
);
804 SetFont(*wxNORMAL_FONT
);
811 wxSymbolListCtrl
::~wxSymbolListCtrl()
813 delete m_doubleBuffer
;
816 // ----------------------------------------------------------------------------
817 // selection handling
818 // ----------------------------------------------------------------------------
820 bool wxSymbolListCtrl
::IsSelected(int item
) const
822 return item
== m_current
;
825 bool wxSymbolListCtrl
::DoSetCurrent(int current
)
827 wxASSERT_MSG( current
== wxNOT_FOUND
||
828 (current
>= m_minSymbolValue
&& current
<= m_maxSymbolValue
),
829 _T("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") );
831 if ( current
== m_current
)
837 if ( m_current
!= wxNOT_FOUND
)
838 RefreshLine(SymbolValueToLineNumber(m_current
));
842 if ( m_current
!= wxNOT_FOUND
)
844 int lineNo
= SymbolValueToLineNumber(m_current
);
846 // if the line is not visible at all, we scroll it into view but we
847 // don't need to refresh it -- it will be redrawn anyhow
848 if ( !IsVisible(lineNo
) )
850 ScrollToLine(lineNo
);
852 else // line is at least partly visible
854 // it is, indeed, only partly visible, so scroll it into view to
855 // make it entirely visible
856 while ( (size_t)lineNo
== GetLastVisibleLine() &&
857 ScrollToLine(GetVisibleBegin()+1) ) ;
859 // but in any case refresh it as even if it was only partly visible
860 // before we need to redraw it entirely as its background changed
868 void wxSymbolListCtrl
::SendSelectedEvent()
870 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_SELECTED
, GetId());
871 event
.SetEventObject(this);
872 event
.SetInt(m_current
);
874 (void)GetEventHandler()->ProcessEvent(event
);
877 void wxSymbolListCtrl
::SetSelection(int selection
)
879 wxCHECK_RET( selection
== wxNOT_FOUND
||
880 (selection
>= m_minSymbolValue
&& selection
< m_maxSymbolValue
),
881 _T("wxSymbolListCtrl::SetSelection(): invalid symbol value") );
883 DoSetCurrent(selection
);
886 // ----------------------------------------------------------------------------
887 // wxSymbolListCtrl appearance parameters
888 // ----------------------------------------------------------------------------
890 void wxSymbolListCtrl
::SetMargins(const wxPoint
& pt
)
892 if ( pt
!= m_ptMargins
)
900 void wxSymbolListCtrl
::SetSelectionBackground(const wxColour
& col
)
905 // ----------------------------------------------------------------------------
906 // wxSymbolListCtrl painting
907 // ----------------------------------------------------------------------------
909 wxCoord wxSymbolListCtrl
::OnGetLineHeight(size_t WXUNUSED(line
)) const
911 return m_cellSize
.y
+ 2*m_ptMargins
.y
+ 1 /* for divider */ ;
914 // draws a line of symbols
915 void wxSymbolListCtrl
::OnDrawItem(wxDC
& dc
, const wxRect
& rect
, size_t n
) const
917 wxColour oldTextColour
= dc
.GetTextForeground();
918 int startSymbol
= n
*m_symbolsPerLine
;
921 for (i
= 0; i
< m_symbolsPerLine
; i
++)
923 bool resetColour
= false;
924 int symbol
= startSymbol
+i
;
925 if (symbol
== m_current
)
927 dc
.SetBrush(wxBrush(m_colBgSel
));
929 dc
.SetTextForeground(wxSystemSettings
::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
));
932 wxPen oldPen
= dc
.GetPen();
933 dc
.SetPen(*wxTRANSPARENT_PEN
);
935 dc
.DrawRectangle(rect
.x
+ i
*m_cellSize
.x
, rect
.y
, m_cellSize
.x
, rect
.y
+rect
.height
);
939 // Don't draw first line
941 dc
.DrawLine(rect
.x
+ i
*m_cellSize
.x
, rect
.y
, i
*m_cellSize
.x
, rect
.y
+rect
.height
);
943 if (symbol
>= m_minSymbolValue
&& symbol
<= m_maxSymbolValue
)
946 text
<< (wxChar
) symbol
;
949 dc
.GetTextExtent(text
, & w
, & h
);
951 int x
= rect
.x
+ i
*m_cellSize
.x
+ (m_cellSize
.x
- w
)/2;
952 int y
= rect
.y
+ (m_cellSize
.y
- h
)/2;
953 dc
.DrawText(text
, x
, y
);
957 dc
.SetTextForeground(oldTextColour
);
960 // Draw horizontal separator line
961 dc
.DrawLine(rect
.x
, rect
.y
+rect
.height
-1, rect
.x
+rect
.width
, rect
.y
+rect
.height
-1);
964 void wxSymbolListCtrl
::OnPaint(wxPaintEvent
& WXUNUSED(event
))
966 // If size is larger, recalculate double buffer bitmap
967 wxSize clientSize
= GetClientSize();
969 if ( !m_doubleBuffer
||
970 clientSize
.x
> m_doubleBuffer
->GetWidth() ||
971 clientSize
.y
> m_doubleBuffer
->GetHeight() )
973 delete m_doubleBuffer
;
974 m_doubleBuffer
= new wxBitmap(clientSize
.x
+25,clientSize
.y
+25);
977 wxBufferedPaintDC
dc(this,*m_doubleBuffer
);
979 // the update rectangle
980 wxRect rectUpdate
= GetUpdateClientRect();
982 // fill it with background colour
983 dc
.SetBackground(GetBackgroundColour());
986 // set the font to be displayed
987 dc
.SetFont(GetFont());
989 // the bounding rectangle of the current line
991 rectLine
.width
= clientSize
.x
;
993 dc
.SetPen(wxPen(wxSystemSettings
::GetColour(wxSYS_COLOUR_WINDOWTEXT
)));
994 dc
.SetTextForeground(wxSystemSettings
::GetColour(wxSYS_COLOUR_WINDOWTEXT
));
995 dc
.SetBackgroundMode(wxTRANSPARENT
);
997 // iterate over all visible lines
998 const size_t lineMax
= GetVisibleEnd();
999 for ( size_t line
= GetFirstVisibleLine(); line
< lineMax
; line
++ )
1001 const wxCoord hLine
= OnGetLineHeight(line
);
1003 rectLine
.height
= hLine
;
1005 // and draw the ones which intersect the update rect
1006 if ( rectLine
.Intersects(rectUpdate
) )
1008 // don't allow drawing outside of the lines rectangle
1009 wxDCClipper
clip(dc
, rectLine
);
1011 wxRect rect
= rectLine
;
1012 rect
.Deflate(m_ptMargins
.x
, m_ptMargins
.y
);
1013 OnDrawItem(dc
, rect
, line
);
1015 else // no intersection
1017 if ( rectLine
.GetTop() > rectUpdate
.GetBottom() )
1019 // we are already below the update rect, no need to continue
1023 //else: the next line may intersect the update rect
1026 rectLine
.y
+= hLine
;
1030 // ============================================================================
1031 // wxSymbolListCtrl keyboard/mouse handling
1032 // ============================================================================
1034 void wxSymbolListCtrl
::DoHandleItemClick(int item
, int WXUNUSED(flags
))
1036 if (m_current
!= item
)
1040 SendSelectedEvent();
1044 // ----------------------------------------------------------------------------
1045 // keyboard handling
1046 // ----------------------------------------------------------------------------
1048 void wxSymbolListCtrl
::OnKeyDown(wxKeyEvent
& event
)
1050 // No keyboard interface for now
1053 // flags for DoHandleItemClick()
1054 int flags
= ItemClick_Kbd
;
1056 int currentLineNow
= SymbolValueToLineNumber(m_current
);
1059 switch ( event
.GetKeyCode() )
1066 currentLine
= GetLineCount() - 1;
1070 if ( currentLineNow
== (int)GetLineCount() - 1 )
1073 currentLine
= currentLineNow
+ 1;
1077 if ( m_current
== wxNOT_FOUND
)
1078 currentLine
= GetLineCount() - 1;
1079 else if ( currentLineNow
!= 0 )
1080 currentLine
= currentLineNow
- 1;
1081 else // currentLineNow == 0
1087 currentLine
= GetFirstVisibleLine();
1091 if ( currentLineNow
== (int)GetFirstVisibleLine() )
1096 currentLine
= GetFirstVisibleLine();
1100 // hack: pressing space should work like a mouse click rather than
1101 // like a keyboard arrow press, so trick DoHandleItemClick() in
1102 // thinking we were clicked
1103 flags
&= ~ItemClick_Kbd
;
1104 currentLine
= currentLineNow
;
1109 // Since we are using wxWANTS_CHARS we need to send navigation
1110 // events for the tabs on MSW
1112 wxNavigationKeyEvent ne
;
1113 ne
.SetDirection(!event
.ShiftDown());
1114 ne
.SetCurrentFocus(this);
1115 ne
.SetEventObject(this);
1116 GetParent()->GetEventHandler()->ProcessEvent(ne
);
1118 // fall through to default
1122 currentLine
= 0; // just to silent the stupid compiler warnings
1123 wxUnusedVar(currentNow
);
1128 if ( event
.ShiftDown() )
1129 flags
|= ItemClick_Shift
;
1130 if ( event
.ControlDown() )
1131 flags
|= ItemClick_Ctrl
;
1133 DoHandleItemClick(current
, flags
);
1138 // ----------------------------------------------------------------------------
1139 // wxSymbolListCtrl mouse handling
1140 // ----------------------------------------------------------------------------
1142 void wxSymbolListCtrl
::OnLeftDown(wxMouseEvent
& event
)
1146 int item
= HitTest(event
.GetPosition());
1148 if ( item
!= wxNOT_FOUND
)
1151 if ( event
.ShiftDown() )
1152 flags
|= ItemClick_Shift
;
1154 // under Mac Apple-click is used in the same way as Ctrl-click
1157 if ( event
.MetaDown() )
1159 if ( event
.ControlDown() )
1161 flags
|= ItemClick_Ctrl
;
1163 DoHandleItemClick(item
, flags
);
1167 void wxSymbolListCtrl
::OnLeftDClick(wxMouseEvent
& eventMouse
)
1169 int item
= HitTest(eventMouse
.GetPosition());
1170 if ( item
!= wxNOT_FOUND
)
1173 // if item double-clicked was not yet selected, then treat
1174 // this event as a left-click instead
1175 if ( item
== m_current
)
1177 wxCommandEvent
event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
, GetId());
1178 event
.SetEventObject(this);
1181 (void)GetEventHandler()->ProcessEvent(event
);
1185 OnLeftDown(eventMouse
);
1191 // calculate line number from symbol value
1192 int wxSymbolListCtrl
::SymbolValueToLineNumber(int item
)
1194 return (int) (item
/m_symbolsPerLine
);
1197 // initialise control from current min/max values
1198 void wxSymbolListCtrl
::SetupCtrl(bool scrollToSelection
)
1200 wxSize sz
= GetClientSize();
1202 m_symbolsPerLine
= sz
.x
/(m_cellSize
.x
+m_ptMargins
.x
);
1203 int noLines
= (1 + SymbolValueToLineNumber(m_maxSymbolValue
));
1205 SetLineCount(noLines
);
1208 if (scrollToSelection
&& m_current
!= wxNOT_FOUND
&& m_current
>= m_minSymbolValue
&& m_current
<= m_maxSymbolValue
)
1210 ScrollToLine(SymbolValueToLineNumber(m_current
));
1214 // make this item visible
1215 void wxSymbolListCtrl
::EnsureVisible(int item
)
1217 if (item
!= wxNOT_FOUND
&& item
>= m_minSymbolValue
&& item
<= m_maxSymbolValue
)
1219 ScrollToLine(SymbolValueToLineNumber(item
));
1225 int wxSymbolListCtrl
::HitTest(const wxPoint
& pt
)
1227 wxCoord lineHeight
= OnGetLineHeight(0);
1229 int atLine
= GetVisibleBegin() + (pt
.y
/lineHeight
);
1230 int symbol
= (atLine
*m_symbolsPerLine
) + (pt
.x
/(m_cellSize
.x
+1));
1232 if (symbol
>= m_minSymbolValue
&& symbol
<= m_maxSymbolValue
)
1238 // Respond to size change
1239 void wxSymbolListCtrl
::OnSize(wxSizeEvent
& event
)
1245 // set the current font
1246 bool wxSymbolListCtrl
::SetFont(const wxFont
& font
)
1248 wxVScrolledWindow
::SetFont(font
);
1255 // set Unicode/ASCII mode
1256 void wxSymbolListCtrl
::SetUnicodeMode(bool unicodeMode
)
1258 bool changed
= false;
1259 if (unicodeMode
&& !m_unicodeMode
)
1263 m_minSymbolValue
= 0;
1264 m_maxSymbolValue
= 65535;
1266 else if (!unicodeMode
&& m_unicodeMode
)
1269 m_minSymbolValue
= 0;
1270 m_maxSymbolValue
= 255;
1272 m_unicodeMode
= unicodeMode
;
1278 // ----------------------------------------------------------------------------
1279 // use the same default attributes as wxListBox
1280 // ----------------------------------------------------------------------------
1284 wxSymbolListCtrl
::GetClassDefaultAttributes(wxWindowVariant variant
)
1286 return wxListBox
::GetClassDefaultAttributes(variant
);