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