Added a symbol selection dialog, with optional font selection and full
[wxWidgets.git] / src / richtext / richtextsymboldlg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: richtextsymboldlg.cpp
3 // Purpose:
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 10/5/2006 3:11:58 PM
7 // RCS-ID:
8 // Copyright: (c) Julian Smart
9 // 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 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 ////@begin includes
24 ////@end includes
25
26 #include "wx/fontenum.h"
27 #include "wx/dcbuffer.h"
28 #include "wx/settings.h"
29
30 #include "../../include/wx/richtext/richtextsymboldlg.h"
31
32 ////@begin XPM images
33 ////@end XPM images
34
35 /* Microsoft Unicode subset numbering
36 */
37
38 typedef enum
39 {
40 U_BASIC_LATIN = 0,
41 U_LATIN_1_SUPPLEMENT = 1,
42 U_LATIN_EXTENDED_A = 2,
43 U_LATIN_EXTENDED_B = 3,
44 U_IPA_EXTENSIONS = 4,
45 U_SPACING_MODIFIER_LETTERS = 5,
46 U_COMBINING_DIACRITICAL_MARKS = 6,
47 U_BASIC_GREEK = 7,
48 U_GREEK_SYMBOLS_AND_COPTIC = 8,
49 U_CYRILLIC = 9,
50 U_ARMENIAN = 10,
51 U_HEBREW_EXTENDED = 12,
52 U_BASIC_HEBREW = 11,
53 U_BASIC_ARABIC = 13,
54 U_ARABIC_EXTENDED = 14,
55 U_DEVANAGARI = 15,
56 U_BENGALI = 16,
57 U_GURMUKHI = 17,
58 U_GUJARATI = 18,
59 U_ORIYA = 19,
60 U_TAMIL = 20,
61 U_TELUGU = 21,
62 U_KANNADA = 22,
63 U_MALAYALAM = 23,
64 U_THAI = 24,
65 U_LAO = 25,
66 U_GEORGIAN_EXTENDED = 27,
67 U_BASIC_GEORGIAN = 26,
68 U_HANGUL_JAMO = 28,
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,
76 U_NUMBER_FORMS = 36,
77 U_ARROWS = 37,
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,
83 U_BOX_DRAWING = 43,
84 U_BLOCK_ELEMENTS = 44,
85 U_GEOMETRIC_SHAPES = 45,
86 U_MISCELLANEOUS_SYMBOLS = 46,
87 U_DINGBATS = 47,
88 U_CJK_SYMBOLS_AND_PUNCTUATION = 48,
89 U_HIRAGANA = 49,
90 U_KATAKANA = 50,
91 U_BOPOMOFO = 51,
92 U_HANGUL_COMPATIBILITY_JAMO = 52,
93 U_CJK_MISCELLANEOUS = 53,
94 U_ENCLOSED_CJK = 54,
95 U_CJK_COMPATIBILITY = 55,
96 U_HANGUL = 56,
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,
108 U_SPECIALS = 69,
109 U_HALFWIDTH_AND_FULLWIDTH_FORMS = 68,
110 U_LAST_PLUS_ONE
111 } wxUnicodeSubsetCodes;
112
113 /* Unicode subsets */
114
115 static struct
116 {
117 int m_low, m_high;
118 wxUnicodeSubsetCodes m_subset;
119 wxChar* m_name;
120 } g_UnicodeSubsetTable[] =
121 {
122 { 0x0000, 0x007E,
123 U_BASIC_LATIN, wxT("Basic Latin") },
124 { 0x00A0, 0x00FF,
125 U_LATIN_1_SUPPLEMENT, wxT("Latin-1 Supplement") },
126 { 0x0100, 0x017F,
127 U_LATIN_EXTENDED_A, wxT("Latin Extended-A") },
128 { 0x0180, 0x024F,
129 U_LATIN_EXTENDED_B, wxT("Latin Extended-B") },
130 { 0x0250, 0x02AF,
131 U_IPA_EXTENSIONS, wxT("IPA Extensions") },
132 { 0x02B0, 0x02FF,
133 U_SPACING_MODIFIER_LETTERS, wxT("Spacing Modifier Letters") },
134 { 0x0300, 0x036F,
135 U_COMBINING_DIACRITICAL_MARKS, wxT("Combining Diacritical Marks") },
136 { 0x0370, 0x03CF,
137 U_BASIC_GREEK, wxT("Basic Greek") },
138 { 0x03D0, 0x03FF,
139 U_GREEK_SYMBOLS_AND_COPTIC, wxT("Greek Symbols and Coptic") },
140 { 0x0400, 0x04FF,
141 U_CYRILLIC, wxT("Cyrillic") },
142 { 0x0530, 0x058F,
143 U_ARMENIAN, wxT("Armenian") },
144 { 0x0590, 0x05CF,
145 U_HEBREW_EXTENDED, wxT("Hebrew Extended") },
146 { 0x05D0, 0x05FF,
147 U_BASIC_HEBREW, wxT("Basic Hebrew") },
148 { 0x0600, 0x0652,
149 U_BASIC_ARABIC, wxT("Basic Arabic") },
150 { 0x0653, 0x06FF,
151 U_ARABIC_EXTENDED, wxT("Arabic Extended") },
152 { 0x0900, 0x097F,
153 U_DEVANAGARI, wxT("Devanagari") },
154 { 0x0980, 0x09FF,
155 U_BENGALI, wxT("Bengali") },
156 { 0x0A00, 0x0A7F,
157 U_GURMUKHI, wxT("Gurmukhi") },
158 { 0x0A80, 0x0AFF,
159 U_GUJARATI, wxT("Gujarati") },
160 { 0x0B00, 0x0B7F,
161 U_ORIYA, wxT("Oriya") },
162 { 0x0B80, 0x0BFF,
163 U_TAMIL, wxT("Tamil") },
164 { 0x0C00, 0x0C7F,
165 U_TELUGU, wxT("Telugu") },
166 { 0x0C80, 0x0CFF,
167 U_KANNADA, wxT("Kannada") },
168 { 0x0D00, 0x0D7F,
169 U_MALAYALAM, wxT("Malayalam") },
170 { 0x0E00, 0x0E7F,
171 U_THAI, wxT("Thai") },
172 { 0x0E80, 0x0EFF,
173 U_LAO, wxT("Lao") },
174 { 0x10A0, 0x10CF,
175 U_GEORGIAN_EXTENDED, wxT("Georgian Extended") },
176 { 0x10D0, 0x10FF,
177 U_BASIC_GEORGIAN, wxT("Basic Georgian") },
178 { 0x1100, 0x11FF,
179 U_HANGUL_JAMO, wxT("Hangul Jamo") },
180 { 0x1E00, 0x1EFF,
181 U_LATIN_EXTENDED_ADDITIONAL, wxT("Latin Extended Additional") },
182 { 0x1F00, 0x1FFF,
183 U_GREEK_EXTENDED, wxT("Greek Extended") },
184 { 0x2000, 0x206F,
185 U_GENERAL_PUNCTUATION, wxT("General Punctuation") },
186 { 0x2070, 0x209F,
187 U_SUPERSCRIPTS_AND_SUBSCRIPTS, wxT("Superscripts and Subscripts") },
188 { 0x20A0, 0x20CF,
189 U_CURRENCY_SYMBOLS, wxT("Currency Symbols") },
190 { 0x20D0, 0x20FF,
191 U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, wxT("Combining Diacritical Marks for Symbols") },
192 { 0x2100, 0x214F,
193 U_LETTERLIKE_SYMBOLS, wxT("Letterlike Symbols") },
194 { 0x2150, 0x218F,
195 U_NUMBER_FORMS, wxT("Number Forms") },
196 { 0x2190, 0x21FF,
197 U_ARROWS, wxT("Arrows") },
198 { 0x2200, 0x22FF,
199 U_MATHEMATICAL_OPERATORS, wxT("Mathematical Operators") },
200 { 0x2300, 0x23FF,
201 U_MISCELLANEOUS_TECHNICAL, wxT("Miscellaneous Technical") },
202 { 0x2400, 0x243F,
203 U_CONTROL_PICTURES, wxT("Control Pictures") },
204 { 0x2440, 0x245F,
205 U_OPTICAL_CHARACTER_RECOGNITION, wxT("Optical Character Recognition") },
206 { 0x2460, 0x24FF,
207 U_ENCLOSED_ALPHANUMERICS, wxT("Enclosed Alphanumerics") },
208 { 0x2500, 0x257F,
209 U_BOX_DRAWING, wxT("Box Drawing") },
210 { 0x2580, 0x259F,
211 U_BLOCK_ELEMENTS, wxT("Block Elements") },
212 { 0x25A0, 0x25FF,
213 U_GEOMETRIC_SHAPES, wxT("Geometric Shapes") },
214 { 0x2600, 0x26FF,
215 U_MISCELLANEOUS_SYMBOLS, wxT("Miscellaneous Symbols") },
216 { 0x2700, 0x27BF,
217 U_DINGBATS, wxT("Dingbats") },
218 { 0x3000, 0x303F,
219 U_CJK_SYMBOLS_AND_PUNCTUATION, wxT("CJK Symbols and Punctuation") },
220 { 0x3040, 0x309F,
221 U_HIRAGANA, wxT("Hiragana") },
222 { 0x30A0, 0x30FF,
223 U_KATAKANA, wxT("Katakana") },
224 { 0x3100, 0x312F,
225 U_BOPOMOFO, wxT("Bopomofo") },
226 { 0x3130, 0x318F,
227 U_HANGUL_COMPATIBILITY_JAMO, wxT("Hangul Compatibility Jamo") },
228 { 0x3190, 0x319F,
229 U_CJK_MISCELLANEOUS, wxT("CJK Miscellaneous") },
230 { 0x3200, 0x32FF,
231 U_ENCLOSED_CJK, wxT("Enclosed CJK") },
232 { 0x3300, 0x33FF,
233 U_CJK_COMPATIBILITY, wxT("CJK Compatibility") },
234 { 0x3400, 0x4DB5,
235 U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs Extension A") },
236 { 0x4E00, 0x9FFF,
237 U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs") },
238 { 0xAC00, 0xD7A3,
239 U_HANGUL, wxT("Hangul Syllables") },
240 { 0xE000, 0xF8FF,
241 U_PRIVATE_USE_AREA, wxT("Private Use Area") },
242 { 0xF900, 0xFAFF,
243 U_CJK_COMPATIBILITY_IDEOGRAPHS, wxT("CJK Compatibility Ideographs") },
244 { 0xFB00, 0xFB4F,
245 U_ALPHABETIC_PRESENTATION_FORMS, wxT("Alphabetic Presentation Forms") },
246 { 0xFB50, 0xFDFF,
247 U_ARABIC_PRESENTATION_FORMS_A, wxT("Arabic Presentation Forms-A") },
248 { 0xFE20, 0xFE2F,
249 U_COMBINING_HALF_MARKS, wxT("Combining Half Marks") },
250 { 0xFE30, 0xFE4F,
251 U_CJK_COMPATIBILITY_FORMS, wxT("CJK Compatibility Forms") },
252 { 0xFE50, 0xFE6F,
253 U_SMALL_FORM_VARIANTS, wxT("Small Form Variants") },
254 { 0xFE70, 0xFEFE,
255 U_ARABIC_PRESENTATION_FORMS_B, wxT("Arabic Presentation Forms-B") },
256 { 0xFEFF, 0xFEFF,
257 U_SPECIALS, wxT("Specials") },
258 { 0xFF00, 0xFFEF,
259 U_HALFWIDTH_AND_FULLWIDTH_FORMS, wxT("Halfwidth and Fullwidth Forms") },
260 { 0xFFF0, 0xFFFD,
261 U_SPECIALS, wxT("Specials") }
262 };
263
264 #if 0
265 // Not yet used, but could be used to test under Win32 whether this subset is available
266 // for the given font. The Win32 function is allegedly not accurate, however.
267 bool wxSubsetValidForFont(int subsetIndex, FONTSIGNATURE *fontSig)
268 {
269 return (fontSig->fsUsb[g_UnicodeSubsetTable[subsetIndex].m_subset/32] & (1 << (g_UnicodeSubsetTable[subsetIndex].m_subset % 32)));
270 }
271 #endif
272
273 /*!
274 * wxSymbolPickerDialog type definition
275 */
276
277 IMPLEMENT_DYNAMIC_CLASS( wxSymbolPickerDialog, wxDialog )
278
279 /*!
280 * wxSymbolPickerDialog event table definition
281 */
282
283 BEGIN_EVENT_TABLE( wxSymbolPickerDialog, wxDialog )
284 EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL, wxSymbolPickerDialog::OnSymbolSelected)
285
286 ////@begin wxSymbolPickerDialog event table entries
287 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT, wxSymbolPickerDialog::OnFontCtrlSelected )
288
289 #if defined(__UNICODE__)
290 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET, wxSymbolPickerDialog::OnSubsetSelected )
291 #endif
292
293 #if defined(__UNICODE__)
294 EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM, wxSymbolPickerDialog::OnFromUnicodeSelected )
295 #endif
296
297 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
298 EVT_UPDATE_UI( wxID_OK, wxSymbolPickerDialog::OnOkUpdate )
299 #endif
300
301 #if defined(__WXMAC__)
302 EVT_UPDATE_UI( wxID_OK, wxSymbolPickerDialog::OnOkUpdate )
303 #endif
304
305 ////@end wxSymbolPickerDialog event table entries
306
307 END_EVENT_TABLE()
308
309 /*!
310 * wxSymbolPickerDialog constructors
311 */
312
313 wxSymbolPickerDialog::wxSymbolPickerDialog( )
314 {
315 Init();
316 }
317
318 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 )
319 {
320 Init();
321 Create(symbol, fontName, normalTextFont, parent, id, caption, pos, size, style);
322 }
323
324 /*!
325 * wxSymbolPickerDialog creator
326 */
327
328 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 )
329 {
330 m_fontName = fontName;
331 m_normalTextFontName = normalTextFont;
332 m_symbol = symbol;
333
334 ////@begin wxSymbolPickerDialog creation
335 SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP);
336 wxDialog::Create( parent, id, caption, pos, size, style );
337
338 CreateControls();
339 if (GetSizer())
340 {
341 GetSizer()->SetSizeHints(this);
342 }
343 Centre();
344 ////@end wxSymbolPickerDialog creation
345 return true;
346 }
347
348 /*!
349 * Member initialisation for wxSymbolPickerDialog
350 */
351
352 void wxSymbolPickerDialog::Init()
353 {
354 ////@begin wxSymbolPickerDialog member initialisation
355 m_fromUnicode = true;
356 m_fontCtrl = NULL;
357 #if defined(__UNICODE__)
358 m_subsetCtrl = NULL;
359 #endif
360 m_symbolsCtrl = NULL;
361 m_symbolStaticCtrl = NULL;
362 m_characterCodeCtrl = NULL;
363 #if defined(__UNICODE__)
364 m_fromUnicodeCtrl = NULL;
365 #endif
366 ////@end wxSymbolPickerDialog member initialisation
367 m_dontUpdate = false;
368 }
369
370 /*!
371 * Control creation for wxSymbolPickerDialog
372 */
373
374 void wxSymbolPickerDialog::CreateControls()
375 {
376 ////@begin wxSymbolPickerDialog content construction
377 wxSymbolPickerDialog* itemDialog1 = this;
378
379 wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
380 itemDialog1->SetSizer(itemBoxSizer2);
381
382 wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
383 itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5);
384
385 wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
386 itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5);
387
388 wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
389 itemBoxSizer4->Add(itemBoxSizer5, 1, wxGROW, 5);
390
391 wxStaticText* itemStaticText6 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 );
392 itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
393
394 wxString* m_fontCtrlStrings = NULL;
395 m_fontCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FONT, _T(""), wxDefaultPosition, wxSize(240, -1), 0, m_fontCtrlStrings, wxCB_READONLY );
396 itemBoxSizer5->Add(m_fontCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
397
398 itemBoxSizer5->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
399
400 #if defined(__UNICODE__)
401 wxStaticText* itemStaticText9 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Subset:"), wxDefaultPosition, wxDefaultSize, 0 );
402 itemBoxSizer5->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
403
404 #endif
405
406 #if defined(__UNICODE__)
407 wxString* m_subsetCtrlStrings = NULL;
408 m_subsetCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_SUBSET, _T(""), wxDefaultPosition, wxDefaultSize, 0, m_subsetCtrlStrings, wxCB_READONLY );
409 m_subsetCtrl->SetHelpText(_("Shows a Unicode subset."));
410 if (ShowToolTips())
411 m_subsetCtrl->SetToolTip(_("Shows a Unicode subset."));
412 itemBoxSizer5->Add(m_subsetCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
413
414 #endif
415
416 m_symbolsCtrl = new wxSymbolListCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_LISTCTRL, wxDefaultPosition, wxSize(500, 240), wxSIMPLE_BORDER );
417 itemBoxSizer3->Add(m_symbolsCtrl, 1, wxGROW|wxALL, 5);
418
419 wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
420 itemBoxSizer3->Add(itemBoxSizer12, 0, wxGROW, 5);
421
422 m_symbolStaticCtrl = new wxStaticText( itemDialog1, wxID_STATIC, _("xxxx"), wxDefaultPosition, wxSize(40, -1), wxALIGN_CENTRE );
423 itemBoxSizer12->Add(m_symbolStaticCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
424
425 itemBoxSizer12->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
426
427 wxStaticText* itemStaticText15 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Character code:"), wxDefaultPosition, wxDefaultSize, 0 );
428 itemBoxSizer12->Add(itemStaticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
429
430 m_characterCodeCtrl = new wxTextCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_CHARACTERCODE, _T(""), wxDefaultPosition, wxSize(140, -1), wxTE_READONLY|wxTE_CENTRE );
431 itemBoxSizer12->Add(m_characterCodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
432
433 itemBoxSizer12->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
434
435 #if defined(__UNICODE__)
436 wxStaticText* itemStaticText18 = new wxStaticText( itemDialog1, wxID_STATIC, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 );
437 itemBoxSizer12->Add(itemStaticText18, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
438
439 #endif
440
441 #if defined(__UNICODE__)
442 wxString m_fromUnicodeCtrlStrings[] = {
443 _("ASCII"),
444 _("Unicode")
445 };
446 m_fromUnicodeCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FROM, _("ASCII"), wxDefaultPosition, wxDefaultSize, 2, m_fromUnicodeCtrlStrings, wxCB_READONLY );
447 m_fromUnicodeCtrl->SetStringSelection(_("ASCII"));
448 itemBoxSizer12->Add(m_fromUnicodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
449
450 #endif
451
452 #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
453 wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL);
454 itemBoxSizer3->Add(itemBoxSizer20, 0, wxGROW, 5);
455
456 itemBoxSizer20->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
457
458 wxButton* itemButton22 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
459 itemButton22->SetDefault();
460 itemButton22->SetHelpText(_("Inserts the chosen symbol."));
461 if (ShowToolTips())
462 itemButton22->SetToolTip(_("Inserts the chosen symbol."));
463 itemBoxSizer20->Add(itemButton22, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
464
465 wxButton* itemButton23 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
466 itemButton23->SetHelpText(_("Closes the dialog without inserting a symbol."));
467 if (ShowToolTips())
468 itemButton23->SetToolTip(_("Closes the dialog without inserting a symbol."));
469 itemBoxSizer20->Add(itemButton23, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
470
471 #endif
472
473 #if defined(__WXMAC__)
474 wxBoxSizer* itemBoxSizer24 = new wxBoxSizer(wxHORIZONTAL);
475 itemBoxSizer3->Add(itemBoxSizer24, 0, wxGROW, 5);
476
477 itemBoxSizer24->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
478
479 wxButton* itemButton26 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
480 itemButton26->SetHelpText(_("Closes the dialog without inserting a symbol."));
481 if (ShowToolTips())
482 itemButton26->SetToolTip(_("Closes the dialog without inserting a symbol."));
483 itemBoxSizer24->Add(itemButton26, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
484
485 wxButton* itemButton27 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
486 itemButton27->SetDefault();
487 itemButton27->SetHelpText(_("Inserts the chosen symbol."));
488 if (ShowToolTips())
489 itemButton27->SetToolTip(_("Inserts the chosen symbol."));
490 itemBoxSizer24->Add(itemButton27, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
491
492 #endif
493
494 ////@end wxSymbolPickerDialog content construction
495
496 }
497
498 /// Data transfer
499 bool wxSymbolPickerDialog::TransferDataToWindow()
500 {
501 m_dontUpdate = true;
502
503 if (m_fontCtrl->GetCount() == 0)
504 {
505 wxFontEnumerator enumerator;
506 enumerator.EnumerateFacenames();
507 wxArrayString faceNames = enumerator.GetFacenames();
508 faceNames.Sort();
509
510 faceNames.Insert(_("(Normal text)"), 0);
511 m_fontCtrl->Append(faceNames);
512 }
513
514 if (m_fontName.IsEmpty())
515 m_fontCtrl->SetSelection(0);
516 else
517 {
518 if (m_fontCtrl->FindString(m_fontName) != wxNOT_FOUND)
519 m_fontCtrl->SetStringSelection(m_fontName);
520 else
521 m_fontCtrl->SetSelection(0);
522 }
523
524 if (!m_symbol.IsEmpty())
525 {
526 int sel = (int) m_symbol[0];
527 m_symbolsCtrl->SetSelection(sel);
528 }
529
530 #if defined(__UNICODE__)
531 if (m_subsetCtrl->GetCount() == 0)
532 {
533 // Insert items into subset combo
534 int i;
535 for (i = 0; i < (int) (sizeof(g_UnicodeSubsetTable)/sizeof(g_UnicodeSubsetTable[0])); i++)
536 {
537 m_subsetCtrl->Append(g_UnicodeSubsetTable[i].m_name);
538 }
539 m_subsetCtrl->SetSelection(0);
540 }
541 #endif
542
543 UpdateSymbolDisplay();
544
545 m_dontUpdate = false;
546
547 return true;
548 }
549
550 void wxSymbolPickerDialog::UpdateSymbolDisplay(bool updateSymbolList, bool showAtSubset)
551 {
552 wxFont font;
553 wxString fontNameToUse;
554 if (m_fontName.IsEmpty())
555 fontNameToUse = m_normalTextFontName;
556 else
557 fontNameToUse = m_fontName;
558
559 if (!fontNameToUse.IsEmpty())
560 {
561 font = wxFont(14, wxDEFAULT, wxNORMAL, wxNORMAL, false, fontNameToUse);
562 }
563 else
564 font = *wxNORMAL_FONT;
565
566 if (updateSymbolList)
567 {
568 m_symbolsCtrl->SetFont(font);
569 }
570
571 if (!m_symbol.IsEmpty())
572 {
573 m_symbolStaticCtrl->SetFont(font);
574 m_symbolStaticCtrl->SetLabel(m_symbol);
575
576 int symbol = (int) m_symbol[0];
577 m_characterCodeCtrl->SetValue(wxString::Format(wxT("%X hex (%d dec)"), symbol, symbol));
578 }
579 else
580 {
581 m_symbolStaticCtrl->SetLabel(wxEmptyString);
582 m_characterCodeCtrl->SetValue(wxEmptyString);
583 }
584
585 #if defined(__UNICODE__)
586 if (showAtSubset)
587 ShowAtSubset();
588 #else
589 wxUnusedVar(showAtSubset);
590 #endif
591 }
592
593 /// Show at the current subset selection
594 void wxSymbolPickerDialog::ShowAtSubset()
595 {
596 #if defined(__UNICODE__)
597 if (m_fromUnicode)
598 {
599 int sel = m_subsetCtrl->GetSelection();
600 int low = g_UnicodeSubsetTable[sel].m_low;
601 m_symbolsCtrl->EnsureVisible(low);
602 }
603 #endif
604 }
605
606 // Handle font selection
607 void wxSymbolPickerDialog::OnFontCtrlSelected( wxCommandEvent& WXUNUSED(event) )
608 {
609 if (m_fontCtrl->GetSelection() == 0)
610 m_fontName = wxEmptyString;
611 else
612 m_fontName = m_fontCtrl->GetStringSelection();
613
614 UpdateSymbolDisplay();
615 }
616
617 /// Respond to symbol selection
618 void wxSymbolPickerDialog::OnSymbolSelected( wxCommandEvent& event )
619 {
620 if (m_dontUpdate)
621 return;
622
623 int sel = event.GetSelection();
624 if (sel == -1)
625 m_symbol = wxEmptyString;
626 else
627 {
628 m_symbol = wxEmptyString;
629 m_symbol << (wxChar) sel;
630 }
631
632 #if defined(__UNICODE__)
633 if (sel != -1 && m_fromUnicode)
634 {
635 // Need to make the subset selection reflect the current symbol
636 int i;
637 for (i = 0; i < (int) (sizeof(g_UnicodeSubsetTable)/sizeof(g_UnicodeSubsetTable[0])); i++)
638 {
639 if (sel >= g_UnicodeSubsetTable[i].m_low && sel <= g_UnicodeSubsetTable[i].m_high)
640 {
641 m_dontUpdate = true;
642 m_subsetCtrl->SetSelection(i);
643 m_dontUpdate = false;
644 break;
645 }
646 }
647 }
648 #endif
649
650 UpdateSymbolDisplay(false, false);
651 }
652
653 #if defined(__UNICODE__)
654 // Handle Unicode/ASCII selection
655 void wxSymbolPickerDialog::OnFromUnicodeSelected( wxCommandEvent& WXUNUSED(event) )
656 {
657 if (m_dontUpdate)
658 return;
659
660 m_fromUnicode = (m_fromUnicodeCtrl->GetSelection() == 1);
661 m_symbolsCtrl->SetUnicodeMode(m_fromUnicode);
662 UpdateSymbolDisplay(false);
663 }
664
665 // Handle subset selection
666 void wxSymbolPickerDialog::OnSubsetSelected( wxCommandEvent& WXUNUSED(event) )
667 {
668 if (m_dontUpdate)
669 return;
670
671 ShowAtSubset();
672 }
673 #endif
674
675 /*!
676 * wxEVT_UPDATE_UI event handler for wxID_OK
677 */
678
679 void wxSymbolPickerDialog::OnOkUpdate( wxUpdateUIEvent& event )
680 {
681 event.Enable(HasSelection());
682 }
683
684 /// Set Unicode mode
685 void wxSymbolPickerDialog::SetUnicodeMode(bool unicodeMode)
686 {
687 #if defined(__UNICODE__)
688 m_dontUpdate = true;
689 m_fromUnicode = unicodeMode;
690 if (m_fromUnicodeCtrl)
691 m_fromUnicodeCtrl->SetSelection(m_fromUnicode ? 1 : 0);
692 UpdateSymbolDisplay();
693 m_dontUpdate = false;
694 #else
695 wxUnusedVar(unicodeMode);
696 #endif
697 }
698
699 /// Get the selected symbol character
700 int wxSymbolPickerDialog::GetSymbolChar() const
701 {
702 if (m_symbol.IsEmpty())
703 return -1;
704 else
705 return (int) m_symbol[0];
706 }
707
708
709 /*!
710 * Should we show tooltips?
711 */
712
713 bool wxSymbolPickerDialog::ShowToolTips()
714 {
715 return true;
716 }
717
718 /*!
719 * Get bitmap resources
720 */
721
722 wxBitmap wxSymbolPickerDialog::GetBitmapResource( const wxString& name )
723 {
724 // Bitmap retrieval
725 ////@begin wxSymbolPickerDialog bitmap retrieval
726 wxUnusedVar(name);
727 return wxNullBitmap;
728 ////@end wxSymbolPickerDialog bitmap retrieval
729 }
730
731 /*!
732 * Get icon resources
733 */
734
735 wxIcon wxSymbolPickerDialog::GetIconResource( const wxString& name )
736 {
737 // Icon retrieval
738 ////@begin wxSymbolPickerDialog icon retrieval
739 wxUnusedVar(name);
740 return wxNullIcon;
741 ////@end wxSymbolPickerDialog icon retrieval
742 }
743
744 /*!
745 * The scrolling symbol list.
746 */
747
748 // ----------------------------------------------------------------------------
749 // event tables
750 // ----------------------------------------------------------------------------
751
752 BEGIN_EVENT_TABLE(wxSymbolListCtrl, wxVScrolledWindow)
753 EVT_PAINT(wxSymbolListCtrl::OnPaint)
754 EVT_SIZE(wxSymbolListCtrl::OnSize)
755
756 EVT_KEY_DOWN(wxSymbolListCtrl::OnKeyDown)
757 EVT_LEFT_DOWN(wxSymbolListCtrl::OnLeftDown)
758 EVT_LEFT_DCLICK(wxSymbolListCtrl::OnLeftDClick)
759 END_EVENT_TABLE()
760
761 // ============================================================================
762 // implementation
763 // ============================================================================
764
765 IMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl, wxVScrolledWindow)
766
767 // ----------------------------------------------------------------------------
768 // wxSymbolListCtrl creation
769 // ----------------------------------------------------------------------------
770
771 void wxSymbolListCtrl::Init()
772 {
773 m_current = wxNOT_FOUND;
774 m_doubleBuffer = NULL;
775 m_cellSize = wxSize(40, 40);
776 m_minSymbolValue = 0;
777 m_maxSymbolValue = 255;
778 m_symbolsPerLine = 0;
779 m_unicodeMode = false;
780 }
781
782 bool wxSymbolListCtrl::Create(wxWindow *parent,
783 wxWindowID id,
784 const wxPoint& pos,
785 const wxSize& size,
786 long style,
787 const wxString& name)
788 {
789 style |= wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE;
790 if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
791 return false;
792
793 // make sure the native widget has the right colour since we do
794 // transparent drawing by default
795 SetBackgroundColour(GetBackgroundColour());
796 m_colBgSel = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
797
798 // flicker-free drawing requires this
799 SetBackgroundStyle(wxBG_STYLE_CUSTOM);
800
801 SetFont(*wxNORMAL_FONT);
802
803 SetupCtrl();
804
805 return true;
806 }
807
808 wxSymbolListCtrl::~wxSymbolListCtrl()
809 {
810 delete m_doubleBuffer;
811 }
812
813 // ----------------------------------------------------------------------------
814 // selection handling
815 // ----------------------------------------------------------------------------
816
817 bool wxSymbolListCtrl::IsSelected(int item) const
818 {
819 return item == m_current;
820 }
821
822 bool wxSymbolListCtrl::DoSetCurrent(int current)
823 {
824 wxASSERT_MSG( current == wxNOT_FOUND ||
825 (current >= m_minSymbolValue && current <= m_maxSymbolValue),
826 _T("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") );
827
828 if ( current == m_current )
829 {
830 // nothing to do
831 return false;
832 }
833
834 if ( m_current != wxNOT_FOUND )
835 RefreshLine(SymbolValueToLineNumber(m_current));
836
837 m_current = current;
838
839 if ( m_current != wxNOT_FOUND )
840 {
841 int lineNo = SymbolValueToLineNumber(m_current);
842
843 // if the line is not visible at all, we scroll it into view but we
844 // don't need to refresh it -- it will be redrawn anyhow
845 if ( !IsVisible(lineNo) )
846 {
847 ScrollToLine(lineNo);
848 }
849 else // line is at least partly visible
850 {
851 // it is, indeed, only partly visible, so scroll it into view to
852 // make it entirely visible
853 while ( (size_t)lineNo == GetLastVisibleLine() &&
854 ScrollToLine(GetVisibleBegin()+1) ) ;
855
856 // but in any case refresh it as even if it was only partly visible
857 // before we need to redraw it entirely as its background changed
858 RefreshLine(lineNo);
859 }
860 }
861
862 return true;
863 }
864
865 void wxSymbolListCtrl::SendSelectedEvent()
866 {
867 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
868 event.SetEventObject(this);
869 event.SetInt(m_current);
870
871 (void)GetEventHandler()->ProcessEvent(event);
872 }
873
874 void wxSymbolListCtrl::SetSelection(int selection)
875 {
876 wxCHECK_RET( selection == wxNOT_FOUND ||
877 (selection >= m_minSymbolValue && selection < m_maxSymbolValue),
878 _T("wxSymbolListCtrl::SetSelection(): invalid symbol value") );
879
880 DoSetCurrent(selection);
881 }
882
883 // ----------------------------------------------------------------------------
884 // wxSymbolListCtrl appearance parameters
885 // ----------------------------------------------------------------------------
886
887 void wxSymbolListCtrl::SetMargins(const wxPoint& pt)
888 {
889 if ( pt != m_ptMargins )
890 {
891 m_ptMargins = pt;
892
893 Refresh();
894 }
895 }
896
897 void wxSymbolListCtrl::SetSelectionBackground(const wxColour& col)
898 {
899 m_colBgSel = col;
900 }
901
902 // ----------------------------------------------------------------------------
903 // wxSymbolListCtrl painting
904 // ----------------------------------------------------------------------------
905
906 wxCoord wxSymbolListCtrl::OnGetLineHeight(size_t WXUNUSED(line)) const
907 {
908 return m_cellSize.y + 2*m_ptMargins.y + 1 /* for divider */ ;
909 }
910
911 // draws a line of symbols
912 void wxSymbolListCtrl::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
913 {
914 wxColour oldTextColour = dc.GetTextForeground();
915 int startSymbol = n*m_symbolsPerLine;
916
917 int i;
918 for (i = 0; i < m_symbolsPerLine; i++)
919 {
920 bool resetColour = false;
921 int symbol = startSymbol+i;
922 if (symbol == m_current)
923 {
924 dc.SetBrush(wxBrush(m_colBgSel));
925
926 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
927 resetColour = true;
928
929 wxPen oldPen = dc.GetPen();
930 dc.SetPen(*wxTRANSPARENT_PEN);
931
932 dc.DrawRectangle(rect.x + i*m_cellSize.x, rect.y, m_cellSize.x, rect.y+rect.height);
933 dc.SetPen(oldPen);
934 }
935
936 // Don't draw first line
937 if (i != 0)
938 dc.DrawLine(rect.x + i*m_cellSize.x, rect.y, i*m_cellSize.x, rect.y+rect.height);
939
940 if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
941 {
942 wxString text;
943 text << (wxChar) symbol;
944
945 wxCoord w, h;
946 dc.GetTextExtent(text, & w, & h);
947
948 int x = rect.x + i*m_cellSize.x + (m_cellSize.x - w)/2;
949 int y = rect.y + (m_cellSize.y - h)/2;
950 dc.DrawText(text, x, y);
951 }
952
953 if (resetColour)
954 dc.SetTextForeground(oldTextColour);
955 }
956
957 // Draw horizontal separator line
958 dc.DrawLine(rect.x, rect.y+rect.height-1, rect.x+rect.width, rect.y+rect.height-1);
959 }
960
961 void wxSymbolListCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
962 {
963 // If size is larger, recalculate double buffer bitmap
964 wxSize clientSize = GetClientSize();
965
966 if ( !m_doubleBuffer ||
967 clientSize.x > m_doubleBuffer->GetWidth() ||
968 clientSize.y > m_doubleBuffer->GetHeight() )
969 {
970 delete m_doubleBuffer;
971 m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
972 }
973
974 wxBufferedPaintDC dc(this,*m_doubleBuffer);
975
976 // the update rectangle
977 wxRect rectUpdate = GetUpdateClientRect();
978
979 // fill it with background colour
980 dc.SetBackground(GetBackgroundColour());
981 dc.Clear();
982
983 // set the font to be displayed
984 dc.SetFont(GetFont());
985
986 // the bounding rectangle of the current line
987 wxRect rectLine;
988 rectLine.width = clientSize.x;
989
990 dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
991 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
992 dc.SetBackgroundMode(wxTRANSPARENT);
993
994 // iterate over all visible lines
995 const size_t lineMax = GetVisibleEnd();
996 for ( size_t line = GetFirstVisibleLine(); line < lineMax; line++ )
997 {
998 const wxCoord hLine = OnGetLineHeight(line);
999
1000 rectLine.height = hLine;
1001
1002 // and draw the ones which intersect the update rect
1003 if ( rectLine.Intersects(rectUpdate) )
1004 {
1005 // don't allow drawing outside of the lines rectangle
1006 wxDCClipper clip(dc, rectLine);
1007
1008 wxRect rect = rectLine;
1009 rect.Deflate(m_ptMargins.x, m_ptMargins.y);
1010 OnDrawItem(dc, rect, line);
1011 }
1012 else // no intersection
1013 {
1014 if ( rectLine.GetTop() > rectUpdate.GetBottom() )
1015 {
1016 // we are already below the update rect, no need to continue
1017 // further
1018 break;
1019 }
1020 //else: the next line may intersect the update rect
1021 }
1022
1023 rectLine.y += hLine;
1024 }
1025 }
1026
1027 // ============================================================================
1028 // wxSymbolListCtrl keyboard/mouse handling
1029 // ============================================================================
1030
1031 void wxSymbolListCtrl::DoHandleItemClick(int item, int WXUNUSED(flags))
1032 {
1033 if (m_current != item)
1034 {
1035 m_current = item;
1036 Refresh();
1037 SendSelectedEvent();
1038 }
1039 }
1040
1041 // ----------------------------------------------------------------------------
1042 // keyboard handling
1043 // ----------------------------------------------------------------------------
1044
1045 void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event)
1046 {
1047 // No keyboard interface for now
1048 event.Skip();
1049 #if 0
1050 // flags for DoHandleItemClick()
1051 int flags = ItemClick_Kbd;
1052
1053 int currentLineNow = SymbolValueToLineNumber(m_current);
1054
1055 int currentLine;
1056 switch ( event.GetKeyCode() )
1057 {
1058 case WXK_HOME:
1059 currentLine = 0;
1060 break;
1061
1062 case WXK_END:
1063 currentLine = GetLineCount() - 1;
1064 break;
1065
1066 case WXK_DOWN:
1067 if ( currentLineNow == (int)GetLineCount() - 1 )
1068 return;
1069
1070 currentLine = currentLineNow + 1;
1071 break;
1072
1073 case WXK_UP:
1074 if ( m_current == wxNOT_FOUND )
1075 currentLine = GetLineCount() - 1;
1076 else if ( currentLineNow != 0 )
1077 currentLine = currentLineNow - 1;
1078 else // currentLineNow == 0
1079 return;
1080 break;
1081
1082 case WXK_PAGEDOWN:
1083 PageDown();
1084 currentLine = GetFirstVisibleLine();
1085 break;
1086
1087 case WXK_PAGEUP:
1088 if ( currentLineNow == (int)GetFirstVisibleLine() )
1089 {
1090 PageUp();
1091 }
1092
1093 currentLine = GetFirstVisibleLine();
1094 break;
1095
1096 case WXK_SPACE:
1097 // hack: pressing space should work like a mouse click rather than
1098 // like a keyboard arrow press, so trick DoHandleItemClick() in
1099 // thinking we were clicked
1100 flags &= ~ItemClick_Kbd;
1101 currentLine = currentLineNow;
1102 break;
1103
1104 #ifdef __WXMSW__
1105 case WXK_TAB:
1106 // Since we are using wxWANTS_CHARS we need to send navigation
1107 // events for the tabs on MSW
1108 {
1109 wxNavigationKeyEvent ne;
1110 ne.SetDirection(!event.ShiftDown());
1111 ne.SetCurrentFocus(this);
1112 ne.SetEventObject(this);
1113 GetParent()->GetEventHandler()->ProcessEvent(ne);
1114 }
1115 // fall through to default
1116 #endif
1117 default:
1118 event.Skip();
1119 currentLine = 0; // just to silent the stupid compiler warnings
1120 wxUnusedVar(currentNow);
1121 return;
1122 }
1123
1124 #if 0
1125 if ( event.ShiftDown() )
1126 flags |= ItemClick_Shift;
1127 if ( event.ControlDown() )
1128 flags |= ItemClick_Ctrl;
1129
1130 DoHandleItemClick(current, flags);
1131 #endif
1132 #endif
1133 }
1134
1135 // ----------------------------------------------------------------------------
1136 // wxSymbolListCtrl mouse handling
1137 // ----------------------------------------------------------------------------
1138
1139 void wxSymbolListCtrl::OnLeftDown(wxMouseEvent& event)
1140 {
1141 SetFocus();
1142
1143 int item = HitTest(event.GetPosition());
1144
1145 if ( item != wxNOT_FOUND )
1146 {
1147 int flags = 0;
1148 if ( event.ShiftDown() )
1149 flags |= ItemClick_Shift;
1150
1151 // under Mac Apple-click is used in the same way as Ctrl-click
1152 // elsewhere
1153 #ifdef __WXMAC__
1154 if ( event.MetaDown() )
1155 #else
1156 if ( event.ControlDown() )
1157 #endif
1158 flags |= ItemClick_Ctrl;
1159
1160 DoHandleItemClick(item, flags);
1161 }
1162 }
1163
1164 void wxSymbolListCtrl::OnLeftDClick(wxMouseEvent& eventMouse)
1165 {
1166 int item = HitTest(eventMouse.GetPosition());
1167 if ( item != wxNOT_FOUND )
1168 {
1169
1170 // if item double-clicked was not yet selected, then treat
1171 // this event as a left-click instead
1172 if ( item == m_current )
1173 {
1174 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, GetId());
1175 event.SetEventObject(this);
1176 event.SetInt(item);
1177
1178 (void)GetEventHandler()->ProcessEvent(event);
1179 }
1180 else
1181 {
1182 OnLeftDown(eventMouse);
1183 }
1184
1185 }
1186 }
1187
1188 // calculate line number from symbol value
1189 int wxSymbolListCtrl::SymbolValueToLineNumber(int item)
1190 {
1191 return (int) (item/m_symbolsPerLine);
1192 }
1193
1194 // initialise control from current min/max values
1195 void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection)
1196 {
1197 wxSize sz = GetClientSize();
1198
1199 m_symbolsPerLine = sz.x/(m_cellSize.x+m_ptMargins.x);
1200 int noLines = (1 + SymbolValueToLineNumber(m_maxSymbolValue));
1201
1202 SetLineCount(noLines);
1203 Refresh();
1204
1205 if (scrollToSelection && m_current != wxNOT_FOUND && m_current >= m_minSymbolValue && m_current <= m_maxSymbolValue)
1206 {
1207 ScrollToLine(SymbolValueToLineNumber(m_current));
1208 }
1209 }
1210
1211 // make this item visible
1212 void wxSymbolListCtrl::EnsureVisible(int item)
1213 {
1214 if (item != wxNOT_FOUND && item >= m_minSymbolValue && item <= m_maxSymbolValue)
1215 {
1216 ScrollToLine(SymbolValueToLineNumber(item));
1217 }
1218 }
1219
1220
1221 // hit testing
1222 int wxSymbolListCtrl::HitTest(const wxPoint& pt)
1223 {
1224 wxCoord lineHeight = OnGetLineHeight(0);
1225
1226 int atLine = GetVisibleBegin() + (pt.y/lineHeight);
1227 int symbol = (atLine*m_symbolsPerLine) + (pt.x/(m_cellSize.x+1));
1228
1229 if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
1230 return symbol;
1231 else
1232 return -1;
1233 }
1234
1235 // Respond to size change
1236 void wxSymbolListCtrl::OnSize(wxSizeEvent& event)
1237 {
1238 SetupCtrl();
1239 event.Skip();
1240 }
1241
1242 // set the current font
1243 bool wxSymbolListCtrl::SetFont(const wxFont& font)
1244 {
1245 wxVScrolledWindow::SetFont(font);
1246
1247 SetupCtrl();
1248
1249 return true;
1250 }
1251
1252 // set Unicode/ASCII mode
1253 void wxSymbolListCtrl::SetUnicodeMode(bool unicodeMode)
1254 {
1255 bool changed = false;
1256 if (unicodeMode && !m_unicodeMode)
1257 {
1258 changed = true;
1259
1260 m_minSymbolValue = 0;
1261 m_maxSymbolValue = 65535;
1262 }
1263 else if (!unicodeMode && m_unicodeMode)
1264 {
1265 changed = true;
1266 m_minSymbolValue = 0;
1267 m_maxSymbolValue = 255;
1268 }
1269 m_unicodeMode = unicodeMode;
1270
1271 if (changed)
1272 SetupCtrl();
1273 }
1274
1275 // ----------------------------------------------------------------------------
1276 // use the same default attributes as wxListBox
1277 // ----------------------------------------------------------------------------
1278
1279 //static
1280 wxVisualAttributes
1281 wxSymbolListCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
1282 {
1283 return wxListBox::GetClassDefaultAttributes(variant);
1284 }
1285
1286