--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: richtextsymboldlg.h
+// Purpose:
+// Author: Julian Smart
+// Modified by:
+// Created: 10/5/2006 3:11:58 PM
+// RCS-ID:
+// Copyright: (c) Julian Smart
+// Licence:
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _RICHTEXTSYMBOLDLG_H_
+#define _RICHTEXTSYMBOLDLG_H_
+
+/*!
+ * Includes
+ */
+
+#include "wx/vscroll.h"
+
+/*!
+ * Forward declarations
+ */
+
+////@begin forward declarations
+class wxSymbolListCtrl;
+////@end forward declarations
+
+#ifndef __UNICODE__
+#if wxUSE_UNICODE
+#define __UNICODE__
+#endif
+#endif
+
+/*!
+ * Symbols
+ */
+
+#define SYMBOL_WXSYMBOLPICKERDIALOG_STYLE wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxCLOSE_BOX
+#define SYMBOL_WXSYMBOLPICKERDIALOG_TITLE _("Symbols")
+#define SYMBOL_WXSYMBOLPICKERDIALOG_IDNAME ID_SYMBOLPICKERDIALOG
+#define SYMBOL_WXSYMBOLPICKERDIALOG_SIZE wxSize(400, 300)
+#define SYMBOL_WXSYMBOLPICKERDIALOG_POSITION wxDefaultPosition
+
+/*!
+ * wxSymbolPickerDialog class declaration
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxSymbolPickerDialog: public wxDialog
+{
+ DECLARE_DYNAMIC_CLASS( wxSymbolPickerDialog )
+ DECLARE_EVENT_TABLE()
+
+public:
+ /// Constructors
+ wxSymbolPickerDialog( );
+ wxSymbolPickerDialog( const wxString& symbol, const wxString& fontName, const wxString& normalTextFont,
+ wxWindow* parent, wxWindowID id = SYMBOL_WXSYMBOLPICKERDIALOG_IDNAME, const wxString& caption = SYMBOL_WXSYMBOLPICKERDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXSYMBOLPICKERDIALOG_POSITION, const wxSize& size = SYMBOL_WXSYMBOLPICKERDIALOG_SIZE, long style = SYMBOL_WXSYMBOLPICKERDIALOG_STYLE );
+
+ /// Creation
+ bool Create( const wxString& symbol, const wxString& fontName, const wxString& normalTextFont,
+ wxWindow* parent, wxWindowID id = SYMBOL_WXSYMBOLPICKERDIALOG_IDNAME, const wxString& caption = SYMBOL_WXSYMBOLPICKERDIALOG_TITLE, const wxPoint& pos = SYMBOL_WXSYMBOLPICKERDIALOG_POSITION, const wxSize& size = SYMBOL_WXSYMBOLPICKERDIALOG_SIZE, long style = SYMBOL_WXSYMBOLPICKERDIALOG_STYLE );
+
+ /// Initialises members variables
+ void Init();
+
+ /// Creates the controls and sizers
+ void CreateControls();
+
+ /// Update the display
+ void UpdateSymbolDisplay(bool updateSymbolList = true, bool showAtSubset = true);
+
+ /// Respond to symbol selection
+ void OnSymbolSelected( wxCommandEvent& event );
+
+ /// Set Unicode mode
+ void SetUnicodeMode(bool unicodeMode);
+
+ /// Show at the current subset selection
+ void ShowAtSubset();
+
+ /// Get the selected symbol character
+ int GetSymbolChar() const;
+
+ /// Is there a selection?
+ bool HasSelection() const { return !m_symbol.IsEmpty(); }
+
+ /// Specifying normal text?
+ bool UseNormalFont() const { return m_fontName.IsEmpty(); }
+
+ /// Data transfer
+ virtual bool TransferDataToWindow();
+
+////@begin wxSymbolPickerDialog event handler declarations
+
+ /// wxEVT_COMMAND_COMBOBOX_SELECTED event handler for ID_SYMBOLPICKERDIALOG_FONT
+ void OnFontCtrlSelected( wxCommandEvent& event );
+
+#if defined(__UNICODE__)
+ /// wxEVT_COMMAND_COMBOBOX_SELECTED event handler for ID_SYMBOLPICKERDIALOG_SUBSET
+ void OnSubsetSelected( wxCommandEvent& event );
+
+#endif
+#if defined(__UNICODE__)
+ /// wxEVT_COMMAND_COMBOBOX_SELECTED event handler for ID_SYMBOLPICKERDIALOG_FROM
+ void OnFromUnicodeSelected( wxCommandEvent& event );
+
+#endif
+#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
+ /// wxEVT_UPDATE_UI event handler for wxID_OK
+ void OnOkUpdate( wxUpdateUIEvent& event );
+
+#endif
+#if defined(__WXMAC__)
+ /// wxEVT_UPDATE_UI event handler for wxID_OK
+ void OnOkUpdate( wxUpdateUIEvent& event );
+
+#endif
+////@end wxSymbolPickerDialog event handler declarations
+
+////@begin wxSymbolPickerDialog member function declarations
+
+ wxString GetFontName() const { return m_fontName ; }
+ void SetFontName(wxString value) { m_fontName = value ; }
+
+ wxString GetSymbol() const { return m_symbol ; }
+ void SetSymbol(wxString value) { m_symbol = value ; }
+
+ bool GetFromUnicode() const { return m_fromUnicode ; }
+ void SetFromUnicode(bool value) { m_fromUnicode = value ; }
+
+ wxString GetNormalTextFontName() const { return m_normalTextFontName ; }
+ void SetNormalTextFontName(wxString value) { m_normalTextFontName = value ; }
+
+ /// Retrieves bitmap resources
+ wxBitmap GetBitmapResource( const wxString& name );
+
+ /// Retrieves icon resources
+ wxIcon GetIconResource( const wxString& name );
+////@end wxSymbolPickerDialog member function declarations
+
+ /// Should we show tooltips?
+ static bool ShowToolTips();
+
+////@begin wxSymbolPickerDialog member variables
+ wxComboBox* m_fontCtrl;
+#if defined(__UNICODE__)
+ wxComboBox* m_subsetCtrl;
+#endif
+ wxSymbolListCtrl* m_symbolsCtrl;
+ wxStaticText* m_symbolStaticCtrl;
+ wxTextCtrl* m_characterCodeCtrl;
+#if defined(__UNICODE__)
+ wxComboBox* m_fromUnicodeCtrl;
+#endif
+ wxString m_fontName;
+ wxString m_symbol;
+ bool m_fromUnicode;
+ wxString m_normalTextFontName;
+ /// Control identifiers
+ enum {
+ ID_SYMBOLPICKERDIALOG = 10600,
+ ID_SYMBOLPICKERDIALOG_FONT = 10602,
+ ID_SYMBOLPICKERDIALOG_SUBSET = 10605,
+ ID_SYMBOLPICKERDIALOG_LISTCTRL = 10608,
+ ID_SYMBOLPICKERDIALOG_CHARACTERCODE = 10601,
+ ID_SYMBOLPICKERDIALOG_FROM = 10603
+ };
+////@end wxSymbolPickerDialog member variables
+
+ bool m_dontUpdate;
+};
+
+/*!
+ * The scrolling symbol list.
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxSymbolListCtrl : public wxVScrolledWindow
+{
+public:
+ // constructors and such
+ // ---------------------
+
+ // default constructor, you must call Create() later
+ wxSymbolListCtrl() { Init(); }
+
+ // normal constructor which calls Create() internally
+ wxSymbolListCtrl(wxWindow *parent,
+ wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0,
+ const wxString& name = wxPanelNameStr)
+ {
+ Init();
+
+ (void)Create(parent, id, pos, size, style, name);
+ }
+
+ // really creates the control and sets the initial number of items in it
+ // (which may be changed later with SetItemCount())
+ //
+ // returns true on success or false if the control couldn't be created
+ bool Create(wxWindow *parent,
+ wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0,
+ const wxString& name = wxPanelNameStr);
+
+ // dtor does some internal cleanup
+ virtual ~wxSymbolListCtrl();
+
+
+ // accessors
+ // ---------
+
+ // set the current font
+ virtual bool SetFont(const wxFont& font);
+
+ // set Unicode/ASCII mode
+ void SetUnicodeMode(bool unicodeMode);
+
+ // get the index of the currently selected item or wxNOT_FOUND if there is no selection
+ int GetSelection() const;
+
+ // is this item selected?
+ bool IsSelected(int item) const;
+
+ // is this item the current one?
+ bool IsCurrentItem(int item) const { return item == m_current; }
+
+ // get the margins around each cell
+ wxPoint GetMargins() const { return m_ptMargins; }
+
+ // get the background colour of selected cells
+ const wxColour& GetSelectionBackground() const { return m_colBgSel; }
+
+ // operations
+ // ----------
+
+ // set the selection to the specified item, if it is wxNOT_FOUND the
+ // selection is unset
+ void SetSelection(int selection);
+
+ // make this item visible
+ void EnsureVisible(int item);
+
+ // set the margins: horizontal margin is the distance between the window
+ // border and the item contents while vertical margin is half of the
+ // distance between items
+ //
+ // by default both margins are 0
+ void SetMargins(const wxPoint& pt);
+ void SetMargins(wxCoord x, wxCoord y) { SetMargins(wxPoint(x, y)); }
+
+ // set the cell size
+ void SetCellSize(const wxSize& sz) { m_cellSize = sz; }
+ const wxSize& GetCellSize() const { return m_cellSize; }
+
+ // change the background colour of the selected cells
+ void SetSelectionBackground(const wxColour& col);
+
+ virtual wxVisualAttributes GetDefaultAttributes() const
+ {
+ return GetClassDefaultAttributes(GetWindowVariant());
+ }
+
+ static wxVisualAttributes
+ GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
+
+ // Get min/max symbol values
+ int GetMinSymbolValue() const { return m_minSymbolValue; }
+ int GetMaxSymbolValue() const { return m_maxSymbolValue; }
+
+ // Respond to size change
+ void OnSize(wxSizeEvent& event);
+
+protected:
+
+ // draws a line of symbols
+ virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
+
+ // gets the line height
+ virtual wxCoord OnGetLineHeight(size_t line) const;
+
+ // event handlers
+ void OnPaint(wxPaintEvent& event);
+ void OnKeyDown(wxKeyEvent& event);
+ void OnLeftDown(wxMouseEvent& event);
+ void OnLeftDClick(wxMouseEvent& event);
+
+ // common part of all ctors
+ void Init();
+
+ // send the wxEVT_COMMAND_LISTBOX_SELECTED event
+ void SendSelectedEvent();
+
+ // change the current item (in single selection listbox it also implicitly
+ // changes the selection); current may be wxNOT_FOUND in which case there
+ // will be no current item any more
+ //
+ // return true if the current item changed, false otherwise
+ bool DoSetCurrent(int current);
+
+ // flags for DoHandleItemClick
+ enum
+ {
+ ItemClick_Shift = 1, // item shift-clicked
+ ItemClick_Ctrl = 2, // ctrl
+ ItemClick_Kbd = 4 // item selected from keyboard
+ };
+
+ // common part of keyboard and mouse handling processing code
+ void DoHandleItemClick(int item, int flags);
+
+ // calculate line number from symbol value
+ int SymbolValueToLineNumber(int item);
+
+ // initialise control from current min/max values
+ void SetupCtrl(bool scrollToSelection = true);
+
+ // hit testing
+ int HitTest(const wxPoint& pt);
+
+private:
+ // the current item or wxNOT_FOUND
+ int m_current;
+
+ // margins
+ wxPoint m_ptMargins;
+
+ // the selection bg colour
+ wxColour m_colBgSel;
+
+ // double buffer
+ wxBitmap* m_doubleBuffer;
+
+ // cell size
+ wxSize m_cellSize;
+
+ // minimum and maximum symbol value
+ int m_minSymbolValue;
+
+ // minimum and maximum symbol value
+ int m_maxSymbolValue;
+
+ // number of items per line
+ int m_symbolsPerLine;
+
+ // Unicode/ASCII mode
+ bool m_unicodeMode;
+
+ DECLARE_EVENT_TABLE()
+ DECLARE_NO_COPY_CLASS(wxSymbolListCtrl)
+ DECLARE_ABSTRACT_CLASS(wxSymbolListCtrl)
+};
+
+#endif
+ // _RICHTEXTSYMBOLDLG_H_
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: richtextsymboldlg.cpp
+// Purpose:
+// Author: Julian Smart
+// Modified by:
+// Created: 10/5/2006 3:11:58 PM
+// RCS-ID:
+// Copyright: (c) Julian Smart
+// Licence:
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+
+////@begin includes
+////@end includes
+
+#include "wx/fontenum.h"
+#include "wx/dcbuffer.h"
+#include "wx/settings.h"
+
+#include "../../include/wx/richtext/richtextsymboldlg.h"
+
+////@begin XPM images
+////@end XPM images
+
+/* Microsoft Unicode subset numbering
+ */
+
+typedef enum
+{
+ U_BASIC_LATIN = 0,
+ U_LATIN_1_SUPPLEMENT = 1,
+ U_LATIN_EXTENDED_A = 2,
+ U_LATIN_EXTENDED_B = 3,
+ U_IPA_EXTENSIONS = 4,
+ U_SPACING_MODIFIER_LETTERS = 5,
+ U_COMBINING_DIACRITICAL_MARKS = 6,
+ U_BASIC_GREEK = 7,
+ U_GREEK_SYMBOLS_AND_COPTIC = 8,
+ U_CYRILLIC = 9,
+ U_ARMENIAN = 10,
+ U_HEBREW_EXTENDED = 12,
+ U_BASIC_HEBREW = 11,
+ U_BASIC_ARABIC = 13,
+ U_ARABIC_EXTENDED = 14,
+ U_DEVANAGARI = 15,
+ U_BENGALI = 16,
+ U_GURMUKHI = 17,
+ U_GUJARATI = 18,
+ U_ORIYA = 19,
+ U_TAMIL = 20,
+ U_TELUGU = 21,
+ U_KANNADA = 22,
+ U_MALAYALAM = 23,
+ U_THAI = 24,
+ U_LAO = 25,
+ U_GEORGIAN_EXTENDED = 27,
+ U_BASIC_GEORGIAN = 26,
+ U_HANGUL_JAMO = 28,
+ U_LATIN_EXTENDED_ADDITIONAL = 29,
+ U_GREEK_EXTENDED = 30,
+ U_GENERAL_PUNCTUATION = 31,
+ U_SUPERSCRIPTS_AND_SUBSCRIPTS = 32,
+ U_CURRENCY_SYMBOLS = 33,
+ U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS = 34,
+ U_LETTERLIKE_SYMBOLS = 35,
+ U_NUMBER_FORMS = 36,
+ U_ARROWS = 37,
+ U_MATHEMATICAL_OPERATORS = 38,
+ U_MISCELLANEOUS_TECHNICAL = 39,
+ U_CONTROL_PICTURES = 40,
+ U_OPTICAL_CHARACTER_RECOGNITION = 41,
+ U_ENCLOSED_ALPHANUMERICS = 42,
+ U_BOX_DRAWING = 43,
+ U_BLOCK_ELEMENTS = 44,
+ U_GEOMETRIC_SHAPES = 45,
+ U_MISCELLANEOUS_SYMBOLS = 46,
+ U_DINGBATS = 47,
+ U_CJK_SYMBOLS_AND_PUNCTUATION = 48,
+ U_HIRAGANA = 49,
+ U_KATAKANA = 50,
+ U_BOPOMOFO = 51,
+ U_HANGUL_COMPATIBILITY_JAMO = 52,
+ U_CJK_MISCELLANEOUS = 53,
+ U_ENCLOSED_CJK = 54,
+ U_CJK_COMPATIBILITY = 55,
+ U_HANGUL = 56,
+ U_HANGUL_SUPPLEMENTARY_A = 57,
+ U_HANGUL_SUPPLEMENTARY_B = 58,
+ U_CJK_UNIFIED_IDEOGRAPHS = 59,
+ U_PRIVATE_USE_AREA = 60,
+ U_CJK_COMPATIBILITY_IDEOGRAPHS = 61,
+ U_ALPHABETIC_PRESENTATION_FORMS = 62,
+ U_ARABIC_PRESENTATION_FORMS_A = 63,
+ U_COMBINING_HALF_MARKS = 64,
+ U_CJK_COMPATIBILITY_FORMS = 65,
+ U_SMALL_FORM_VARIANTS = 66,
+ U_ARABIC_PRESENTATION_FORMS_B = 67,
+ U_SPECIALS = 69,
+ U_HALFWIDTH_AND_FULLWIDTH_FORMS = 68,
+ U_LAST_PLUS_ONE
+} wxUnicodeSubsetCodes;
+
+/* Unicode subsets */
+
+static struct
+{
+ int m_low, m_high;
+ wxUnicodeSubsetCodes m_subset;
+ wxChar* m_name;
+} g_UnicodeSubsetTable[] =
+{
+ { 0x0000, 0x007E,
+ U_BASIC_LATIN, wxT("Basic Latin") },
+ { 0x00A0, 0x00FF,
+ U_LATIN_1_SUPPLEMENT, wxT("Latin-1 Supplement") },
+ { 0x0100, 0x017F,
+ U_LATIN_EXTENDED_A, wxT("Latin Extended-A") },
+ { 0x0180, 0x024F,
+ U_LATIN_EXTENDED_B, wxT("Latin Extended-B") },
+ { 0x0250, 0x02AF,
+ U_IPA_EXTENSIONS, wxT("IPA Extensions") },
+ { 0x02B0, 0x02FF,
+ U_SPACING_MODIFIER_LETTERS, wxT("Spacing Modifier Letters") },
+ { 0x0300, 0x036F,
+ U_COMBINING_DIACRITICAL_MARKS, wxT("Combining Diacritical Marks") },
+ { 0x0370, 0x03CF,
+ U_BASIC_GREEK, wxT("Basic Greek") },
+ { 0x03D0, 0x03FF,
+ U_GREEK_SYMBOLS_AND_COPTIC, wxT("Greek Symbols and Coptic") },
+ { 0x0400, 0x04FF,
+ U_CYRILLIC, wxT("Cyrillic") },
+ { 0x0530, 0x058F,
+ U_ARMENIAN, wxT("Armenian") },
+ { 0x0590, 0x05CF,
+ U_HEBREW_EXTENDED, wxT("Hebrew Extended") },
+ { 0x05D0, 0x05FF,
+ U_BASIC_HEBREW, wxT("Basic Hebrew") },
+ { 0x0600, 0x0652,
+ U_BASIC_ARABIC, wxT("Basic Arabic") },
+ { 0x0653, 0x06FF,
+ U_ARABIC_EXTENDED, wxT("Arabic Extended") },
+ { 0x0900, 0x097F,
+ U_DEVANAGARI, wxT("Devanagari") },
+ { 0x0980, 0x09FF,
+ U_BENGALI, wxT("Bengali") },
+ { 0x0A00, 0x0A7F,
+ U_GURMUKHI, wxT("Gurmukhi") },
+ { 0x0A80, 0x0AFF,
+ U_GUJARATI, wxT("Gujarati") },
+ { 0x0B00, 0x0B7F,
+ U_ORIYA, wxT("Oriya") },
+ { 0x0B80, 0x0BFF,
+ U_TAMIL, wxT("Tamil") },
+ { 0x0C00, 0x0C7F,
+ U_TELUGU, wxT("Telugu") },
+ { 0x0C80, 0x0CFF,
+ U_KANNADA, wxT("Kannada") },
+ { 0x0D00, 0x0D7F,
+ U_MALAYALAM, wxT("Malayalam") },
+ { 0x0E00, 0x0E7F,
+ U_THAI, wxT("Thai") },
+ { 0x0E80, 0x0EFF,
+ U_LAO, wxT("Lao") },
+ { 0x10A0, 0x10CF,
+ U_GEORGIAN_EXTENDED, wxT("Georgian Extended") },
+ { 0x10D0, 0x10FF,
+ U_BASIC_GEORGIAN, wxT("Basic Georgian") },
+ { 0x1100, 0x11FF,
+ U_HANGUL_JAMO, wxT("Hangul Jamo") },
+ { 0x1E00, 0x1EFF,
+ U_LATIN_EXTENDED_ADDITIONAL, wxT("Latin Extended Additional") },
+ { 0x1F00, 0x1FFF,
+ U_GREEK_EXTENDED, wxT("Greek Extended") },
+ { 0x2000, 0x206F,
+ U_GENERAL_PUNCTUATION, wxT("General Punctuation") },
+ { 0x2070, 0x209F,
+ U_SUPERSCRIPTS_AND_SUBSCRIPTS, wxT("Superscripts and Subscripts") },
+ { 0x20A0, 0x20CF,
+ U_CURRENCY_SYMBOLS, wxT("Currency Symbols") },
+ { 0x20D0, 0x20FF,
+ U_COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS, wxT("Combining Diacritical Marks for Symbols") },
+ { 0x2100, 0x214F,
+ U_LETTERLIKE_SYMBOLS, wxT("Letterlike Symbols") },
+ { 0x2150, 0x218F,
+ U_NUMBER_FORMS, wxT("Number Forms") },
+ { 0x2190, 0x21FF,
+ U_ARROWS, wxT("Arrows") },
+ { 0x2200, 0x22FF,
+ U_MATHEMATICAL_OPERATORS, wxT("Mathematical Operators") },
+ { 0x2300, 0x23FF,
+ U_MISCELLANEOUS_TECHNICAL, wxT("Miscellaneous Technical") },
+ { 0x2400, 0x243F,
+ U_CONTROL_PICTURES, wxT("Control Pictures") },
+ { 0x2440, 0x245F,
+ U_OPTICAL_CHARACTER_RECOGNITION, wxT("Optical Character Recognition") },
+ { 0x2460, 0x24FF,
+ U_ENCLOSED_ALPHANUMERICS, wxT("Enclosed Alphanumerics") },
+ { 0x2500, 0x257F,
+ U_BOX_DRAWING, wxT("Box Drawing") },
+ { 0x2580, 0x259F,
+ U_BLOCK_ELEMENTS, wxT("Block Elements") },
+ { 0x25A0, 0x25FF,
+ U_GEOMETRIC_SHAPES, wxT("Geometric Shapes") },
+ { 0x2600, 0x26FF,
+ U_MISCELLANEOUS_SYMBOLS, wxT("Miscellaneous Symbols") },
+ { 0x2700, 0x27BF,
+ U_DINGBATS, wxT("Dingbats") },
+ { 0x3000, 0x303F,
+ U_CJK_SYMBOLS_AND_PUNCTUATION, wxT("CJK Symbols and Punctuation") },
+ { 0x3040, 0x309F,
+ U_HIRAGANA, wxT("Hiragana") },
+ { 0x30A0, 0x30FF,
+ U_KATAKANA, wxT("Katakana") },
+ { 0x3100, 0x312F,
+ U_BOPOMOFO, wxT("Bopomofo") },
+ { 0x3130, 0x318F,
+ U_HANGUL_COMPATIBILITY_JAMO, wxT("Hangul Compatibility Jamo") },
+ { 0x3190, 0x319F,
+ U_CJK_MISCELLANEOUS, wxT("CJK Miscellaneous") },
+ { 0x3200, 0x32FF,
+ U_ENCLOSED_CJK, wxT("Enclosed CJK") },
+ { 0x3300, 0x33FF,
+ U_CJK_COMPATIBILITY, wxT("CJK Compatibility") },
+ { 0x3400, 0x4DB5,
+ U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs Extension A") },
+ { 0x4E00, 0x9FFF,
+ U_CJK_UNIFIED_IDEOGRAPHS, wxT("CJK Unified Ideographs") },
+ { 0xAC00, 0xD7A3,
+ U_HANGUL, wxT("Hangul Syllables") },
+ { 0xE000, 0xF8FF,
+ U_PRIVATE_USE_AREA, wxT("Private Use Area") },
+ { 0xF900, 0xFAFF,
+ U_CJK_COMPATIBILITY_IDEOGRAPHS, wxT("CJK Compatibility Ideographs") },
+ { 0xFB00, 0xFB4F,
+ U_ALPHABETIC_PRESENTATION_FORMS, wxT("Alphabetic Presentation Forms") },
+ { 0xFB50, 0xFDFF,
+ U_ARABIC_PRESENTATION_FORMS_A, wxT("Arabic Presentation Forms-A") },
+ { 0xFE20, 0xFE2F,
+ U_COMBINING_HALF_MARKS, wxT("Combining Half Marks") },
+ { 0xFE30, 0xFE4F,
+ U_CJK_COMPATIBILITY_FORMS, wxT("CJK Compatibility Forms") },
+ { 0xFE50, 0xFE6F,
+ U_SMALL_FORM_VARIANTS, wxT("Small Form Variants") },
+ { 0xFE70, 0xFEFE,
+ U_ARABIC_PRESENTATION_FORMS_B, wxT("Arabic Presentation Forms-B") },
+ { 0xFEFF, 0xFEFF,
+ U_SPECIALS, wxT("Specials") },
+ { 0xFF00, 0xFFEF,
+ U_HALFWIDTH_AND_FULLWIDTH_FORMS, wxT("Halfwidth and Fullwidth Forms") },
+ { 0xFFF0, 0xFFFD,
+ U_SPECIALS, wxT("Specials") }
+};
+
+#if 0
+// Not yet used, but could be used to test under Win32 whether this subset is available
+// for the given font. The Win32 function is allegedly not accurate, however.
+bool wxSubsetValidForFont(int subsetIndex, FONTSIGNATURE *fontSig)
+{
+ return (fontSig->fsUsb[g_UnicodeSubsetTable[subsetIndex].m_subset/32] & (1 << (g_UnicodeSubsetTable[subsetIndex].m_subset % 32)));
+}
+#endif
+
+/*!
+ * wxSymbolPickerDialog type definition
+ */
+
+IMPLEMENT_DYNAMIC_CLASS( wxSymbolPickerDialog, wxDialog )
+
+/*!
+ * wxSymbolPickerDialog event table definition
+ */
+
+BEGIN_EVENT_TABLE( wxSymbolPickerDialog, wxDialog )
+ EVT_LISTBOX(ID_SYMBOLPICKERDIALOG_LISTCTRL, wxSymbolPickerDialog::OnSymbolSelected)
+
+////@begin wxSymbolPickerDialog event table entries
+ EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FONT, wxSymbolPickerDialog::OnFontCtrlSelected )
+
+#if defined(__UNICODE__)
+ EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_SUBSET, wxSymbolPickerDialog::OnSubsetSelected )
+#endif
+
+#if defined(__UNICODE__)
+ EVT_COMBOBOX( ID_SYMBOLPICKERDIALOG_FROM, wxSymbolPickerDialog::OnFromUnicodeSelected )
+#endif
+
+#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
+ EVT_UPDATE_UI( wxID_OK, wxSymbolPickerDialog::OnOkUpdate )
+#endif
+
+#if defined(__WXMAC__)
+ EVT_UPDATE_UI( wxID_OK, wxSymbolPickerDialog::OnOkUpdate )
+#endif
+
+////@end wxSymbolPickerDialog event table entries
+
+END_EVENT_TABLE()
+
+/*!
+ * wxSymbolPickerDialog constructors
+ */
+
+wxSymbolPickerDialog::wxSymbolPickerDialog( )
+{
+ Init();
+}
+
+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 )
+{
+ Init();
+ Create(symbol, fontName, normalTextFont, parent, id, caption, pos, size, style);
+}
+
+/*!
+ * wxSymbolPickerDialog creator
+ */
+
+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 )
+{
+ m_fontName = fontName;
+ m_normalTextFontName = normalTextFont;
+ m_symbol = symbol;
+
+////@begin wxSymbolPickerDialog creation
+ SetExtraStyle(GetExtraStyle()|wxWS_EX_BLOCK_EVENTS|wxDIALOG_EX_CONTEXTHELP);
+ wxDialog::Create( parent, id, caption, pos, size, style );
+
+ CreateControls();
+ if (GetSizer())
+ {
+ GetSizer()->SetSizeHints(this);
+ }
+ Centre();
+////@end wxSymbolPickerDialog creation
+ return true;
+}
+
+/*!
+ * Member initialisation for wxSymbolPickerDialog
+ */
+
+void wxSymbolPickerDialog::Init()
+{
+////@begin wxSymbolPickerDialog member initialisation
+ m_fromUnicode = true;
+ m_fontCtrl = NULL;
+#if defined(__UNICODE__)
+ m_subsetCtrl = NULL;
+#endif
+ m_symbolsCtrl = NULL;
+ m_symbolStaticCtrl = NULL;
+ m_characterCodeCtrl = NULL;
+#if defined(__UNICODE__)
+ m_fromUnicodeCtrl = NULL;
+#endif
+////@end wxSymbolPickerDialog member initialisation
+ m_dontUpdate = false;
+}
+
+/*!
+ * Control creation for wxSymbolPickerDialog
+ */
+
+void wxSymbolPickerDialog::CreateControls()
+{
+////@begin wxSymbolPickerDialog content construction
+ wxSymbolPickerDialog* itemDialog1 = this;
+
+ wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
+ itemDialog1->SetSizer(itemBoxSizer2);
+
+ wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
+ itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW|wxALL, 5);
+
+ wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxHORIZONTAL);
+ itemBoxSizer3->Add(itemBoxSizer4, 0, wxGROW, 5);
+
+ wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
+ itemBoxSizer4->Add(itemBoxSizer5, 1, wxGROW, 5);
+
+ wxStaticText* itemStaticText6 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Font:"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemBoxSizer5->Add(itemStaticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
+
+ wxString* m_fontCtrlStrings = NULL;
+ m_fontCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FONT, _T(""), wxDefaultPosition, wxSize(240, -1), 0, m_fontCtrlStrings, wxCB_READONLY );
+ itemBoxSizer5->Add(m_fontCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ itemBoxSizer5->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#if defined(__UNICODE__)
+ wxStaticText* itemStaticText9 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Subset:"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemBoxSizer5->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
+
+#endif
+
+#if defined(__UNICODE__)
+ wxString* m_subsetCtrlStrings = NULL;
+ m_subsetCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_SUBSET, _T(""), wxDefaultPosition, wxDefaultSize, 0, m_subsetCtrlStrings, wxCB_READONLY );
+ m_subsetCtrl->SetHelpText(_("Shows a Unicode subset."));
+ if (ShowToolTips())
+ m_subsetCtrl->SetToolTip(_("Shows a Unicode subset."));
+ itemBoxSizer5->Add(m_subsetCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#endif
+
+ m_symbolsCtrl = new wxSymbolListCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_LISTCTRL, wxDefaultPosition, wxSize(500, 240), wxSIMPLE_BORDER );
+ itemBoxSizer3->Add(m_symbolsCtrl, 1, wxGROW|wxALL, 5);
+
+ wxBoxSizer* itemBoxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+ itemBoxSizer3->Add(itemBoxSizer12, 0, wxGROW, 5);
+
+ m_symbolStaticCtrl = new wxStaticText( itemDialog1, wxID_STATIC, _("xxxx"), wxDefaultPosition, wxSize(40, -1), wxALIGN_CENTRE );
+ itemBoxSizer12->Add(m_symbolStaticCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
+
+ itemBoxSizer12->Add(5, 5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ wxStaticText* itemStaticText15 = new wxStaticText( itemDialog1, wxID_STATIC, _("&Character code:"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemBoxSizer12->Add(itemStaticText15, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
+
+ m_characterCodeCtrl = new wxTextCtrl( itemDialog1, ID_SYMBOLPICKERDIALOG_CHARACTERCODE, _T(""), wxDefaultPosition, wxSize(140, -1), wxTE_READONLY|wxTE_CENTRE );
+ itemBoxSizer12->Add(m_characterCodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ itemBoxSizer12->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#if defined(__UNICODE__)
+ wxStaticText* itemStaticText18 = new wxStaticText( itemDialog1, wxID_STATIC, _("&From:"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemBoxSizer12->Add(itemStaticText18, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxADJUST_MINSIZE, 5);
+
+#endif
+
+#if defined(__UNICODE__)
+ wxString m_fromUnicodeCtrlStrings[] = {
+ _("ASCII"),
+ _("Unicode")
+ };
+ m_fromUnicodeCtrl = new wxComboBox( itemDialog1, ID_SYMBOLPICKERDIALOG_FROM, _("ASCII"), wxDefaultPosition, wxDefaultSize, 2, m_fromUnicodeCtrlStrings, wxCB_READONLY );
+ m_fromUnicodeCtrl->SetStringSelection(_("ASCII"));
+ itemBoxSizer12->Add(m_fromUnicodeCtrl, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#endif
+
+#if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXOS2__) || defined(__WXMGL__) || defined(__WXMOTIF__) || defined(__WXCOCOA__) || defined(__WXX11__) || defined(__WXPALMOS__)
+ wxBoxSizer* itemBoxSizer20 = new wxBoxSizer(wxHORIZONTAL);
+ itemBoxSizer3->Add(itemBoxSizer20, 0, wxGROW, 5);
+
+ itemBoxSizer20->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ wxButton* itemButton22 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemButton22->SetDefault();
+ itemButton22->SetHelpText(_("Inserts the chosen symbol."));
+ if (ShowToolTips())
+ itemButton22->SetToolTip(_("Inserts the chosen symbol."));
+ itemBoxSizer20->Add(itemButton22, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ wxButton* itemButton23 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemButton23->SetHelpText(_("Closes the dialog without inserting a symbol."));
+ if (ShowToolTips())
+ itemButton23->SetToolTip(_("Closes the dialog without inserting a symbol."));
+ itemBoxSizer20->Add(itemButton23, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#endif
+
+#if defined(__WXMAC__)
+ wxBoxSizer* itemBoxSizer24 = new wxBoxSizer(wxHORIZONTAL);
+ itemBoxSizer3->Add(itemBoxSizer24, 0, wxGROW, 5);
+
+ itemBoxSizer24->Add(5, 5, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ wxButton* itemButton26 = new wxButton( itemDialog1, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemButton26->SetHelpText(_("Closes the dialog without inserting a symbol."));
+ if (ShowToolTips())
+ itemButton26->SetToolTip(_("Closes the dialog without inserting a symbol."));
+ itemBoxSizer24->Add(itemButton26, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+ wxButton* itemButton27 = new wxButton( itemDialog1, wxID_OK, _("Insert"), wxDefaultPosition, wxDefaultSize, 0 );
+ itemButton27->SetDefault();
+ itemButton27->SetHelpText(_("Inserts the chosen symbol."));
+ if (ShowToolTips())
+ itemButton27->SetToolTip(_("Inserts the chosen symbol."));
+ itemBoxSizer24->Add(itemButton27, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+#endif
+
+////@end wxSymbolPickerDialog content construction
+
+}
+
+/// Data transfer
+bool wxSymbolPickerDialog::TransferDataToWindow()
+{
+ m_dontUpdate = true;
+
+ if (m_fontCtrl->GetCount() == 0)
+ {
+ wxFontEnumerator enumerator;
+ enumerator.EnumerateFacenames();
+ wxArrayString faceNames = enumerator.GetFacenames();
+ faceNames.Sort();
+
+ faceNames.Insert(_("(Normal text)"), 0);
+ m_fontCtrl->Append(faceNames);
+ }
+
+ if (m_fontName.IsEmpty())
+ m_fontCtrl->SetSelection(0);
+ else
+ {
+ if (m_fontCtrl->FindString(m_fontName) != wxNOT_FOUND)
+ m_fontCtrl->SetStringSelection(m_fontName);
+ else
+ m_fontCtrl->SetSelection(0);
+ }
+
+ if (!m_symbol.IsEmpty())
+ {
+ int sel = (int) m_symbol[0];
+ m_symbolsCtrl->SetSelection(sel);
+ }
+
+#if defined(__UNICODE__)
+ if (m_subsetCtrl->GetCount() == 0)
+ {
+ // Insert items into subset combo
+ int i;
+ for (i = 0; i < (int) (sizeof(g_UnicodeSubsetTable)/sizeof(g_UnicodeSubsetTable[0])); i++)
+ {
+ m_subsetCtrl->Append(g_UnicodeSubsetTable[i].m_name);
+ }
+ m_subsetCtrl->SetSelection(0);
+ }
+#endif
+
+ UpdateSymbolDisplay();
+
+ m_dontUpdate = false;
+
+ return true;
+}
+
+void wxSymbolPickerDialog::UpdateSymbolDisplay(bool updateSymbolList, bool showAtSubset)
+{
+ wxFont font;
+ wxString fontNameToUse;
+ if (m_fontName.IsEmpty())
+ fontNameToUse = m_normalTextFontName;
+ else
+ fontNameToUse = m_fontName;
+
+ if (!fontNameToUse.IsEmpty())
+ {
+ font = wxFont(14, wxDEFAULT, wxNORMAL, wxNORMAL, false, fontNameToUse);
+ }
+ else
+ font = *wxNORMAL_FONT;
+
+ if (updateSymbolList)
+ {
+ m_symbolsCtrl->SetFont(font);
+ }
+
+ if (!m_symbol.IsEmpty())
+ {
+ m_symbolStaticCtrl->SetFont(font);
+ m_symbolStaticCtrl->SetLabel(m_symbol);
+
+ int symbol = (int) m_symbol[0];
+ m_characterCodeCtrl->SetValue(wxString::Format(wxT("%X hex (%d dec)"), symbol, symbol));
+ }
+ else
+ {
+ m_symbolStaticCtrl->SetLabel(wxEmptyString);
+ m_characterCodeCtrl->SetValue(wxEmptyString);
+ }
+
+#if defined(__UNICODE__)
+ if (showAtSubset)
+ ShowAtSubset();
+#else
+ wxUnusedVar(showAtSubset);
+#endif
+}
+
+/// Show at the current subset selection
+void wxSymbolPickerDialog::ShowAtSubset()
+{
+#if defined(__UNICODE__)
+ if (m_fromUnicode)
+ {
+ int sel = m_subsetCtrl->GetSelection();
+ int low = g_UnicodeSubsetTable[sel].m_low;
+ m_symbolsCtrl->EnsureVisible(low);
+ }
+#endif
+}
+
+// Handle font selection
+void wxSymbolPickerDialog::OnFontCtrlSelected( wxCommandEvent& WXUNUSED(event) )
+{
+ if (m_fontCtrl->GetSelection() == 0)
+ m_fontName = wxEmptyString;
+ else
+ m_fontName = m_fontCtrl->GetStringSelection();
+
+ UpdateSymbolDisplay();
+}
+
+/// Respond to symbol selection
+void wxSymbolPickerDialog::OnSymbolSelected( wxCommandEvent& event )
+{
+ if (m_dontUpdate)
+ return;
+
+ int sel = event.GetSelection();
+ if (sel == -1)
+ m_symbol = wxEmptyString;
+ else
+ {
+ m_symbol = wxEmptyString;
+ m_symbol << (wxChar) sel;
+ }
+
+#if defined(__UNICODE__)
+ if (sel != -1 && m_fromUnicode)
+ {
+ // Need to make the subset selection reflect the current symbol
+ int i;
+ for (i = 0; i < (int) (sizeof(g_UnicodeSubsetTable)/sizeof(g_UnicodeSubsetTable[0])); i++)
+ {
+ if (sel >= g_UnicodeSubsetTable[i].m_low && sel <= g_UnicodeSubsetTable[i].m_high)
+ {
+ m_dontUpdate = true;
+ m_subsetCtrl->SetSelection(i);
+ m_dontUpdate = false;
+ break;
+ }
+ }
+ }
+#endif
+
+ UpdateSymbolDisplay(false, false);
+}
+
+#if defined(__UNICODE__)
+// Handle Unicode/ASCII selection
+void wxSymbolPickerDialog::OnFromUnicodeSelected( wxCommandEvent& WXUNUSED(event) )
+{
+ if (m_dontUpdate)
+ return;
+
+ m_fromUnicode = (m_fromUnicodeCtrl->GetSelection() == 1);
+ m_symbolsCtrl->SetUnicodeMode(m_fromUnicode);
+ UpdateSymbolDisplay(false);
+}
+
+// Handle subset selection
+void wxSymbolPickerDialog::OnSubsetSelected( wxCommandEvent& WXUNUSED(event) )
+{
+ if (m_dontUpdate)
+ return;
+
+ ShowAtSubset();
+}
+#endif
+
+/*!
+ * wxEVT_UPDATE_UI event handler for wxID_OK
+ */
+
+void wxSymbolPickerDialog::OnOkUpdate( wxUpdateUIEvent& event )
+{
+ event.Enable(HasSelection());
+}
+
+/// Set Unicode mode
+void wxSymbolPickerDialog::SetUnicodeMode(bool unicodeMode)
+{
+#if defined(__UNICODE__)
+ m_dontUpdate = true;
+ m_fromUnicode = unicodeMode;
+ if (m_fromUnicodeCtrl)
+ m_fromUnicodeCtrl->SetSelection(m_fromUnicode ? 1 : 0);
+ UpdateSymbolDisplay();
+ m_dontUpdate = false;
+#else
+ wxUnusedVar(unicodeMode);
+#endif
+}
+
+/// Get the selected symbol character
+int wxSymbolPickerDialog::GetSymbolChar() const
+{
+ if (m_symbol.IsEmpty())
+ return -1;
+ else
+ return (int) m_symbol[0];
+}
+
+
+/*!
+ * Should we show tooltips?
+ */
+
+bool wxSymbolPickerDialog::ShowToolTips()
+{
+ return true;
+}
+
+/*!
+ * Get bitmap resources
+ */
+
+wxBitmap wxSymbolPickerDialog::GetBitmapResource( const wxString& name )
+{
+ // Bitmap retrieval
+////@begin wxSymbolPickerDialog bitmap retrieval
+ wxUnusedVar(name);
+ return wxNullBitmap;
+////@end wxSymbolPickerDialog bitmap retrieval
+}
+
+/*!
+ * Get icon resources
+ */
+
+wxIcon wxSymbolPickerDialog::GetIconResource( const wxString& name )
+{
+ // Icon retrieval
+////@begin wxSymbolPickerDialog icon retrieval
+ wxUnusedVar(name);
+ return wxNullIcon;
+////@end wxSymbolPickerDialog icon retrieval
+}
+
+/*!
+ * The scrolling symbol list.
+ */
+
+// ----------------------------------------------------------------------------
+// event tables
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(wxSymbolListCtrl, wxVScrolledWindow)
+ EVT_PAINT(wxSymbolListCtrl::OnPaint)
+ EVT_SIZE(wxSymbolListCtrl::OnSize)
+
+ EVT_KEY_DOWN(wxSymbolListCtrl::OnKeyDown)
+ EVT_LEFT_DOWN(wxSymbolListCtrl::OnLeftDown)
+ EVT_LEFT_DCLICK(wxSymbolListCtrl::OnLeftDClick)
+END_EVENT_TABLE()
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_ABSTRACT_CLASS(wxSymbolListCtrl, wxVScrolledWindow)
+
+// ----------------------------------------------------------------------------
+// wxSymbolListCtrl creation
+// ----------------------------------------------------------------------------
+
+void wxSymbolListCtrl::Init()
+{
+ m_current = wxNOT_FOUND;
+ m_doubleBuffer = NULL;
+ m_cellSize = wxSize(40, 40);
+ m_minSymbolValue = 0;
+ m_maxSymbolValue = 255;
+ m_symbolsPerLine = 0;
+ m_unicodeMode = false;
+}
+
+bool wxSymbolListCtrl::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ style |= wxWANTS_CHARS | wxFULL_REPAINT_ON_RESIZE;
+ if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
+ return false;
+
+ // make sure the native widget has the right colour since we do
+ // transparent drawing by default
+ SetBackgroundColour(GetBackgroundColour());
+ m_colBgSel = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
+
+ // flicker-free drawing requires this
+ SetBackgroundStyle(wxBG_STYLE_CUSTOM);
+
+ SetFont(*wxNORMAL_FONT);
+
+ SetupCtrl();
+
+ return true;
+}
+
+wxSymbolListCtrl::~wxSymbolListCtrl()
+{
+ delete m_doubleBuffer;
+}
+
+// ----------------------------------------------------------------------------
+// selection handling
+// ----------------------------------------------------------------------------
+
+bool wxSymbolListCtrl::IsSelected(int item) const
+{
+ return item == m_current;
+}
+
+bool wxSymbolListCtrl::DoSetCurrent(int current)
+{
+ wxASSERT_MSG( current == wxNOT_FOUND ||
+ (current >= m_minSymbolValue && current <= m_maxSymbolValue),
+ _T("wxSymbolListCtrl::DoSetCurrent(): invalid symbol value") );
+
+ if ( current == m_current )
+ {
+ // nothing to do
+ return false;
+ }
+
+ if ( m_current != wxNOT_FOUND )
+ RefreshLine(SymbolValueToLineNumber(m_current));
+
+ m_current = current;
+
+ if ( m_current != wxNOT_FOUND )
+ {
+ int lineNo = SymbolValueToLineNumber(m_current);
+
+ // if the line is not visible at all, we scroll it into view but we
+ // don't need to refresh it -- it will be redrawn anyhow
+ if ( !IsVisible(lineNo) )
+ {
+ ScrollToLine(lineNo);
+ }
+ else // line is at least partly visible
+ {
+ // it is, indeed, only partly visible, so scroll it into view to
+ // make it entirely visible
+ while ( (size_t)lineNo == GetLastVisibleLine() &&
+ ScrollToLine(GetVisibleBegin()+1) ) ;
+
+ // but in any case refresh it as even if it was only partly visible
+ // before we need to redraw it entirely as its background changed
+ RefreshLine(lineNo);
+ }
+ }
+
+ return true;
+}
+
+void wxSymbolListCtrl::SendSelectedEvent()
+{
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
+ event.SetEventObject(this);
+ event.SetInt(m_current);
+
+ (void)GetEventHandler()->ProcessEvent(event);
+}
+
+void wxSymbolListCtrl::SetSelection(int selection)
+{
+ wxCHECK_RET( selection == wxNOT_FOUND ||
+ (selection >= m_minSymbolValue && selection < m_maxSymbolValue),
+ _T("wxSymbolListCtrl::SetSelection(): invalid symbol value") );
+
+ DoSetCurrent(selection);
+}
+
+// ----------------------------------------------------------------------------
+// wxSymbolListCtrl appearance parameters
+// ----------------------------------------------------------------------------
+
+void wxSymbolListCtrl::SetMargins(const wxPoint& pt)
+{
+ if ( pt != m_ptMargins )
+ {
+ m_ptMargins = pt;
+
+ Refresh();
+ }
+}
+
+void wxSymbolListCtrl::SetSelectionBackground(const wxColour& col)
+{
+ m_colBgSel = col;
+}
+
+// ----------------------------------------------------------------------------
+// wxSymbolListCtrl painting
+// ----------------------------------------------------------------------------
+
+wxCoord wxSymbolListCtrl::OnGetLineHeight(size_t WXUNUSED(line)) const
+{
+ return m_cellSize.y + 2*m_ptMargins.y + 1 /* for divider */ ;
+}
+
+// draws a line of symbols
+void wxSymbolListCtrl::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
+{
+ wxColour oldTextColour = dc.GetTextForeground();
+ int startSymbol = n*m_symbolsPerLine;
+
+ int i;
+ for (i = 0; i < m_symbolsPerLine; i++)
+ {
+ bool resetColour = false;
+ int symbol = startSymbol+i;
+ if (symbol == m_current)
+ {
+ dc.SetBrush(wxBrush(m_colBgSel));
+
+ dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
+ resetColour = true;
+
+ wxPen oldPen = dc.GetPen();
+ dc.SetPen(*wxTRANSPARENT_PEN);
+
+ dc.DrawRectangle(rect.x + i*m_cellSize.x, rect.y, m_cellSize.x, rect.y+rect.height);
+ dc.SetPen(oldPen);
+ }
+
+ // Don't draw first line
+ if (i != 0)
+ dc.DrawLine(rect.x + i*m_cellSize.x, rect.y, i*m_cellSize.x, rect.y+rect.height);
+
+ if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
+ {
+ wxString text;
+ text << (wxChar) symbol;
+
+ wxCoord w, h;
+ dc.GetTextExtent(text, & w, & h);
+
+ int x = rect.x + i*m_cellSize.x + (m_cellSize.x - w)/2;
+ int y = rect.y + (m_cellSize.y - h)/2;
+ dc.DrawText(text, x, y);
+ }
+
+ if (resetColour)
+ dc.SetTextForeground(oldTextColour);
+ }
+
+ // Draw horizontal separator line
+ dc.DrawLine(rect.x, rect.y+rect.height-1, rect.x+rect.width, rect.y+rect.height-1);
+}
+
+void wxSymbolListCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+ // If size is larger, recalculate double buffer bitmap
+ wxSize clientSize = GetClientSize();
+
+ if ( !m_doubleBuffer ||
+ clientSize.x > m_doubleBuffer->GetWidth() ||
+ clientSize.y > m_doubleBuffer->GetHeight() )
+ {
+ delete m_doubleBuffer;
+ m_doubleBuffer = new wxBitmap(clientSize.x+25,clientSize.y+25);
+ }
+
+ wxBufferedPaintDC dc(this,*m_doubleBuffer);
+
+ // the update rectangle
+ wxRect rectUpdate = GetUpdateClientRect();
+
+ // fill it with background colour
+ dc.SetBackground(GetBackgroundColour());
+ dc.Clear();
+
+ // set the font to be displayed
+ dc.SetFont(GetFont());
+
+ // the bounding rectangle of the current line
+ wxRect rectLine;
+ rectLine.width = clientSize.x;
+
+ dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)));
+ dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+ dc.SetBackgroundMode(wxTRANSPARENT);
+
+ // iterate over all visible lines
+ const size_t lineMax = GetVisibleEnd();
+ for ( size_t line = GetFirstVisibleLine(); line < lineMax; line++ )
+ {
+ const wxCoord hLine = OnGetLineHeight(line);
+
+ rectLine.height = hLine;
+
+ // and draw the ones which intersect the update rect
+ if ( rectLine.Intersects(rectUpdate) )
+ {
+ // don't allow drawing outside of the lines rectangle
+ wxDCClipper clip(dc, rectLine);
+
+ wxRect rect = rectLine;
+ rect.Deflate(m_ptMargins.x, m_ptMargins.y);
+ OnDrawItem(dc, rect, line);
+ }
+ else // no intersection
+ {
+ if ( rectLine.GetTop() > rectUpdate.GetBottom() )
+ {
+ // we are already below the update rect, no need to continue
+ // further
+ break;
+ }
+ //else: the next line may intersect the update rect
+ }
+
+ rectLine.y += hLine;
+ }
+}
+
+// ============================================================================
+// wxSymbolListCtrl keyboard/mouse handling
+// ============================================================================
+
+void wxSymbolListCtrl::DoHandleItemClick(int item, int WXUNUSED(flags))
+{
+ if (m_current != item)
+ {
+ m_current = item;
+ Refresh();
+ SendSelectedEvent();
+ }
+}
+
+// ----------------------------------------------------------------------------
+// keyboard handling
+// ----------------------------------------------------------------------------
+
+void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event)
+{
+ // No keyboard interface for now
+ event.Skip();
+#if 0
+ // flags for DoHandleItemClick()
+ int flags = ItemClick_Kbd;
+
+ int currentLineNow = SymbolValueToLineNumber(m_current);
+
+ int currentLine;
+ switch ( event.GetKeyCode() )
+ {
+ case WXK_HOME:
+ currentLine = 0;
+ break;
+
+ case WXK_END:
+ currentLine = GetLineCount() - 1;
+ break;
+
+ case WXK_DOWN:
+ if ( currentLineNow == (int)GetLineCount() - 1 )
+ return;
+
+ currentLine = currentLineNow + 1;
+ break;
+
+ case WXK_UP:
+ if ( m_current == wxNOT_FOUND )
+ currentLine = GetLineCount() - 1;
+ else if ( currentLineNow != 0 )
+ currentLine = currentLineNow - 1;
+ else // currentLineNow == 0
+ return;
+ break;
+
+ case WXK_PAGEDOWN:
+ PageDown();
+ currentLine = GetFirstVisibleLine();
+ break;
+
+ case WXK_PAGEUP:
+ if ( currentLineNow == (int)GetFirstVisibleLine() )
+ {
+ PageUp();
+ }
+
+ currentLine = GetFirstVisibleLine();
+ break;
+
+ case WXK_SPACE:
+ // hack: pressing space should work like a mouse click rather than
+ // like a keyboard arrow press, so trick DoHandleItemClick() in
+ // thinking we were clicked
+ flags &= ~ItemClick_Kbd;
+ currentLine = currentLineNow;
+ break;
+
+#ifdef __WXMSW__
+ case WXK_TAB:
+ // Since we are using wxWANTS_CHARS we need to send navigation
+ // events for the tabs on MSW
+ {
+ wxNavigationKeyEvent ne;
+ ne.SetDirection(!event.ShiftDown());
+ ne.SetCurrentFocus(this);
+ ne.SetEventObject(this);
+ GetParent()->GetEventHandler()->ProcessEvent(ne);
+ }
+ // fall through to default
+#endif
+ default:
+ event.Skip();
+ currentLine = 0; // just to silent the stupid compiler warnings
+ wxUnusedVar(currentNow);
+ return;
+ }
+
+#if 0
+ if ( event.ShiftDown() )
+ flags |= ItemClick_Shift;
+ if ( event.ControlDown() )
+ flags |= ItemClick_Ctrl;
+
+ DoHandleItemClick(current, flags);
+#endif
+#endif
+}
+
+// ----------------------------------------------------------------------------
+// wxSymbolListCtrl mouse handling
+// ----------------------------------------------------------------------------
+
+void wxSymbolListCtrl::OnLeftDown(wxMouseEvent& event)
+{
+ SetFocus();
+
+ int item = HitTest(event.GetPosition());
+
+ if ( item != wxNOT_FOUND )
+ {
+ int flags = 0;
+ if ( event.ShiftDown() )
+ flags |= ItemClick_Shift;
+
+ // under Mac Apple-click is used in the same way as Ctrl-click
+ // elsewhere
+#ifdef __WXMAC__
+ if ( event.MetaDown() )
+#else
+ if ( event.ControlDown() )
+#endif
+ flags |= ItemClick_Ctrl;
+
+ DoHandleItemClick(item, flags);
+ }
+}
+
+void wxSymbolListCtrl::OnLeftDClick(wxMouseEvent& eventMouse)
+{
+ int item = HitTest(eventMouse.GetPosition());
+ if ( item != wxNOT_FOUND )
+ {
+
+ // if item double-clicked was not yet selected, then treat
+ // this event as a left-click instead
+ if ( item == m_current )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, GetId());
+ event.SetEventObject(this);
+ event.SetInt(item);
+
+ (void)GetEventHandler()->ProcessEvent(event);
+ }
+ else
+ {
+ OnLeftDown(eventMouse);
+ }
+
+ }
+}
+
+// calculate line number from symbol value
+int wxSymbolListCtrl::SymbolValueToLineNumber(int item)
+{
+ return (int) (item/m_symbolsPerLine);
+}
+
+// initialise control from current min/max values
+void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection)
+{
+ wxSize sz = GetClientSize();
+
+ m_symbolsPerLine = sz.x/(m_cellSize.x+m_ptMargins.x);
+ int noLines = (1 + SymbolValueToLineNumber(m_maxSymbolValue));
+
+ SetLineCount(noLines);
+ Refresh();
+
+ if (scrollToSelection && m_current != wxNOT_FOUND && m_current >= m_minSymbolValue && m_current <= m_maxSymbolValue)
+ {
+ ScrollToLine(SymbolValueToLineNumber(m_current));
+ }
+}
+
+// make this item visible
+void wxSymbolListCtrl::EnsureVisible(int item)
+{
+ if (item != wxNOT_FOUND && item >= m_minSymbolValue && item <= m_maxSymbolValue)
+ {
+ ScrollToLine(SymbolValueToLineNumber(item));
+ }
+}
+
+
+// hit testing
+int wxSymbolListCtrl::HitTest(const wxPoint& pt)
+{
+ wxCoord lineHeight = OnGetLineHeight(0);
+
+ int atLine = GetVisibleBegin() + (pt.y/lineHeight);
+ int symbol = (atLine*m_symbolsPerLine) + (pt.x/(m_cellSize.x+1));
+
+ if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue)
+ return symbol;
+ else
+ return -1;
+}
+
+// Respond to size change
+void wxSymbolListCtrl::OnSize(wxSizeEvent& event)
+{
+ SetupCtrl();
+ event.Skip();
+}
+
+// set the current font
+bool wxSymbolListCtrl::SetFont(const wxFont& font)
+{
+ wxVScrolledWindow::SetFont(font);
+
+ SetupCtrl();
+
+ return true;
+}
+
+// set Unicode/ASCII mode
+void wxSymbolListCtrl::SetUnicodeMode(bool unicodeMode)
+{
+ bool changed = false;
+ if (unicodeMode && !m_unicodeMode)
+ {
+ changed = true;
+
+ m_minSymbolValue = 0;
+ m_maxSymbolValue = 65535;
+ }
+ else if (!unicodeMode && m_unicodeMode)
+ {
+ changed = true;
+ m_minSymbolValue = 0;
+ m_maxSymbolValue = 255;
+ }
+ m_unicodeMode = unicodeMode;
+
+ if (changed)
+ SetupCtrl();
+}
+
+// ----------------------------------------------------------------------------
+// use the same default attributes as wxListBox
+// ----------------------------------------------------------------------------
+
+//static
+wxVisualAttributes
+wxSymbolListCtrl::GetClassDefaultAttributes(wxWindowVariant variant)
+{
+ return wxListBox::GetClassDefaultAttributes(variant);
+}
+
+