]> git.saurik.com Git - wxWidgets.git/commitdiff
Add wxSpinCtrl::SetBase() to allow entering hexadecimal numbers.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 30 Aug 2012 20:24:38 +0000 (20:24 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 30 Aug 2012 20:24:38 +0000 (20:24 +0000)
Add a generic SetBase() API even though right now only bases 10 and 16 are
supported as we might support other ones (e.g. 8?) in the future. Implement it
for MSW, GTK and generic versions.

Add controls allowing to test this feature to the widgets sample.

Add "base" property support to the XRC handler for wxSpinCtrl, document it and
test it in the xrc sample.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@72414 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

14 files changed:
docs/changes.txt
docs/doxygen/overviews/xrc_format.h
include/wx/generic/spinctlg.h
include/wx/gtk/spinctrl.h
include/wx/msw/spinctrl.h
include/wx/spinctrl.h
interface/wx/spinctrl.h
samples/widgets/spinbtn.cpp
samples/xrc/rc/controls.xrc
src/common/spinctrlcmn.cpp
src/generic/spinctlg.cpp
src/gtk/spinctrl.cpp
src/msw/spinctrl.cpp
src/xrc/xh_spin.cpp

index 44482c80e6f16c33fdfa1024ad6746eb968a89e8..bf909d183e35465820a4f3494d5d1ae507b30068 100644 (file)
@@ -537,6 +537,7 @@ All:
 All (GUI):
 
 - Add new wxSimplebook class.
+- Support hexadecimal numbers in wxSpinCtrl.
 - Respect window max size in wxBoxSizer (Nathan Ridge).
 - Add support for searching in wxWebView for MSW and GTK (Allonii).
 - Add possibility to hide and show again wxRibbonBar pages (wxBen).
index dd14c10f1e608c98eeaa92a7901e28d6588f60d4..eb9f73e49b6400aa0c29ad0862e7bfaad759d03e 100644 (file)
@@ -1495,7 +1495,12 @@ HTML markup. Note that the markup has to be escaped:
 
 @subsubsection xrc_wxspinctrl wxSpinCtrl
 
-wxSpinCtrl supports the properties as @ref xrc_wxspinbutton.
+wxSpinCtrl supports the same properties as @ref xrc_wxspinbutton and, since
+wxWidgets 2.9.5, another one:
+@beginTable
+@row3col{base, integer,
+    Numeric base, currently can be only 10 or 16 (default: 10).}
+@endTable
 
 
 @subsubsection xrc_wxsplitterwindow wxSplitterWindow
index 4492bedef0b9b9f2f448ed4c4bf4c86027beebc9..61c38b6a56f7fdf116ec887494906fe48656c71e 100644 (file)
@@ -260,7 +260,7 @@ protected:
 class WXDLLIMPEXP_CORE wxSpinCtrl : public wxSpinCtrlGenericBase
 {
 public:
-    wxSpinCtrl() {}
+    wxSpinCtrl() { Init(); }
     wxSpinCtrl(wxWindow *parent,
                wxWindowID id = wxID_ANY,
                const wxString& value = wxEmptyString,
@@ -270,6 +270,8 @@ public:
                int min = 0, int max = 100, int initial = 0,
                const wxString& name = wxT("wxSpinCtrl"))
     {
+        Init();
+
         Create(parent, id, value, pos, size, style, min, max, initial, name);
     }
 
@@ -299,11 +301,24 @@ public:
     void SetRange( int minVal, int maxVal ) { DoSetRange(minVal, maxVal); }
     void SetIncrement(int inc) { DoSetIncrement(inc); }
 
+    virtual int GetBase() const { return m_base; }
+    virtual bool SetBase(int base);
+
 protected:
     virtual void DoSendEvent();
 
     virtual bool DoTextToValue(const wxString& text, double *val);
     virtual wxString DoValueToText(double val);
+
+private:
+    // Common part of all ctors.
+    void Init()
+    {
+        m_base = 10;
+    }
+
+    int m_base;
+
     DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
 };
 
@@ -363,6 +378,11 @@ public:
     void SetIncrement(double inc)               { DoSetIncrement(inc); }
     void SetDigits(unsigned digits);
 
+    // We don't implement bases support for floating point numbers, this is not
+    // very useful in practice.
+    virtual int GetBase() const { return 10; }
+    virtual bool SetBase(int WXUNUSED(base)) { return 0; }
+
 protected:
     virtual void DoSendEvent();
 
index f57976df81ae300e3b93ac31142125f18f20c858..5e50fd8a8023153c80de893675eea47f0588eb73 100644 (file)
@@ -89,7 +89,7 @@ protected:
 class WXDLLIMPEXP_CORE wxSpinCtrl : public wxSpinCtrlGTKBase
 {
 public:
-    wxSpinCtrl() {}
+    wxSpinCtrl() { Init(); }
     wxSpinCtrl(wxWindow *parent,
                wxWindowID id = wxID_ANY,
                const wxString& value = wxEmptyString,
@@ -99,6 +99,8 @@ public:
                int min = 0, int max = 100, int initial = 0,
                const wxString& name = wxS("wxSpinCtrl"))
     {
+        Init();
+
         Create(parent, id, value, pos, size, style, min, max, initial, name);
     }
 
@@ -127,6 +129,18 @@ public:
     void SetRange( int minVal, int maxVal ) { DoSetRange(minVal, maxVal); }
     void SetIncrement(int inc) { DoSetIncrement(inc); }
 
+    virtual int GetBase() const { return m_base; }
+    virtual bool SetBase(int base);
+
+private:
+    // Common part of all ctors.
+    void Init()
+    {
+        m_base = 10;
+    }
+
+    int m_base;
+
     DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
 };
 
@@ -180,6 +194,9 @@ public:
     void SetIncrement(double inc)               { DoSetIncrement(inc); }
     void SetDigits(unsigned digits);
 
+    virtual int GetBase() const { return 10; }
+    virtual bool SetBase(int WXUNUSED(base)) { return false; }
+
     DECLARE_DYNAMIC_CLASS(wxSpinCtrlDouble)
 };
 
index fd8c7ab1d8e00a95f18ef8ccb64aaa5093904a1e..dd74f556490ef69d92f1c3e46550b2ba9d5c4665 100644 (file)
@@ -62,6 +62,11 @@ public:
     // another wxTextCtrl-like method
     void SetSelection(long from, long to);
 
+    // wxSpinCtrlBase methods
+    virtual int GetBase() const;
+    virtual bool SetBase(int base);
+
+
     // implementation only from now on
     // -------------------------------
 
@@ -148,6 +153,12 @@ private:
     // Common part of all ctors.
     void Init();
 
+    // Adjust the text control style depending on whether we need to enter only
+    // digits or may need to enter something else (e.g. "-" sign, "x"
+    // hexadecimal prefix, ...) in it.
+    void UpdateBuddyStyle();
+
+
     DECLARE_DYNAMIC_CLASS(wxSpinCtrl)
     DECLARE_EVENT_TABLE()
     wxDECLARE_NO_COPY_CLASS(wxSpinCtrl);
index 8a2ef4d90b78662730f3facc1d30edb6bb0f49c0..cf93212a66156168514e3c34be252f872e5cff86 100644 (file)
@@ -51,6 +51,10 @@ public:
     virtual void SetSnapToTicks(bool snap_to_ticks) = 0;
     // void SetDigits(unsigned digits)              - wxSpinCtrlDouble only
 
+    // The base for numbers display, e.g. 10 or 16.
+    virtual int GetBase() const = 0;
+    virtual bool SetBase(int base) = 0;
+
     // Select text in the textctrl
     virtual void SetSelection(long from, long to) = 0;
 
@@ -134,6 +138,15 @@ typedef void (wxEvtHandler::*wxSpinDoubleEventFunction)(wxSpinDoubleEvent&);
     #include "wx/generic/spinctlg.h"
 #endif
 
+namespace wxPrivate
+{
+
+// This is an internal helper function currently used by all ports: return the
+// string containing hexadecimal representation of the given number.
+extern wxString wxSpinCtrlFormatAsHex(long val, long maxVal);
+
+} // namespace wxPrivate
+
 #endif // wxUSE_SPINCTRL
 
 #endif // _WX_SPINCTRL_H_
index 3e2c6926c4a2d39a99d022db1ff7ff88bd5a45a4..44ed624a7ce1119420c6c7c2fd835f5a04f86f57 100644 (file)
@@ -114,6 +114,15 @@ public:
                 long style = wxSP_ARROW_KEYS, int min = 0, int max = 100,
                 int initial = 0, const wxString& name = "wxSpinCtrl");
 
+    /**
+        Returns the numerical base being currently used, 10 by default.
+
+        @see SetBase()
+
+        @since 2.9.5
+     */
+    int GetBase() const;
+
     /**
         Gets maximal allowable value.
     */
@@ -129,6 +138,27 @@ public:
     */
     int GetValue() const;
 
+    /**
+        Sets the base to use for the numbers in this control.
+
+        Currently the only supported values are 10 (which is the default) and
+        16.
+
+        Changing the base allows the user to enter the numbers in the specified
+        base, e.g. with "0x" prefix for hexadecimal numbers, and also displays
+        the numbers in the specified base when they are changed using the spin
+        control arrows.
+
+        @param base
+            Numeric base, currently only 10 and 16 are supported.
+        @return
+            @true if the base was successfully changed or @false if it failed,
+            usually meaning that either the base is not 10 or 16.
+
+        @since 2.9.5
+     */
+    bool SetBase(int base);
+
     /**
         Sets range of allowable values.
 
index 821c2a7e858fe34b317ca3e20e77d8e1527c082b..8639747e111fad70c8efc46ee2293db3b96f77db 100644 (file)
@@ -58,10 +58,12 @@ enum
     SpinBtnPage_Clear,
     SpinBtnPage_SetValue,
     SpinBtnPage_SetMinAndMax,
+    SpinBtnPage_SetBase,
     SpinBtnPage_CurValueText,
     SpinBtnPage_ValueText,
     SpinBtnPage_MinText,
     SpinBtnPage_MaxText,
+    SpinBtnPage_BaseText,
     SpinBtnPage_SpinBtn,
     SpinBtnPage_SpinCtrl,
     SpinBtnPage_SpinCtrlDouble
@@ -105,6 +107,7 @@ protected:
     void OnButtonClear(wxCommandEvent& event);
     void OnButtonSetValue(wxCommandEvent& event);
     void OnButtonSetMinAndMax(wxCommandEvent& event);
+    void OnButtonSetBase(wxCommandEvent& event);
 
     void OnCheckOrRadioBox(wxCommandEvent& event);
 
@@ -118,6 +121,7 @@ protected:
 
     void OnUpdateUIValueButton(wxUpdateUIEvent& event);
     void OnUpdateUIMinMaxButton(wxUpdateUIEvent& event);
+    void OnUpdateUIBaseButton(wxUpdateUIEvent& event);
 
     void OnUpdateUIResetButton(wxUpdateUIEvent& event);
 
@@ -136,6 +140,9 @@ protected:
     // the spinbtn range
     int m_min, m_max;
 
+    // and numeric base
+    int m_base;
+
     // the controls
     // ------------
 
@@ -144,7 +151,7 @@ protected:
                *m_chkArrowKeys,
                *m_chkWrap,
                *m_chkProcessEnter;
-   wxRadioBox *m_radioAlign;
+    wxRadioBox *m_radioAlign;
 
     // the spinbtn and the spinctrl and the sizer containing them
     wxSpinButton *m_spinbtn;
@@ -156,7 +163,8 @@ protected:
     // the text entries for set value/range
     wxTextCtrl *m_textValue,
                *m_textMin,
-               *m_textMax;
+               *m_textMax,
+               *m_textBase;
 
 private:
     DECLARE_EVENT_TABLE()
@@ -171,9 +179,11 @@ BEGIN_EVENT_TABLE(SpinBtnWidgetsPage, WidgetsPage)
     EVT_BUTTON(SpinBtnPage_Reset, SpinBtnWidgetsPage::OnButtonReset)
     EVT_BUTTON(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnButtonSetValue)
     EVT_BUTTON(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnButtonSetMinAndMax)
+    EVT_BUTTON(SpinBtnPage_SetBase, SpinBtnWidgetsPage::OnButtonSetBase)
 
     EVT_UPDATE_UI(SpinBtnPage_SetValue, SpinBtnWidgetsPage::OnUpdateUIValueButton)
     EVT_UPDATE_UI(SpinBtnPage_SetMinAndMax, SpinBtnWidgetsPage::OnUpdateUIMinMaxButton)
+    EVT_UPDATE_UI(SpinBtnPage_SetBase, SpinBtnWidgetsPage::OnUpdateUIBaseButton)
 
     EVT_UPDATE_UI(SpinBtnPage_Reset, SpinBtnWidgetsPage::OnUpdateUIResetButton)
 
@@ -218,13 +228,16 @@ SpinBtnWidgetsPage::SpinBtnWidgetsPage(WidgetsBookCtrl *book,
     m_spinbtn = NULL;
     m_spinctrl = NULL;
     m_spinctrldbl = NULL;
-    m_textValue = NULL;
-    m_textMin = NULL;
-    m_textMax = NULL;
+    m_textValue =
+    m_textMin =
+    m_textMax =
+    m_textBase = NULL;
 
     m_min = 0;
     m_max = 10;
 
+    m_base = 10;
+
     m_sizerSpin = NULL;
 }
 
@@ -295,6 +308,13 @@ void SpinBtnWidgetsPage::CreateContent()
 
     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
 
+    sizerRow = CreateSizerWithTextAndButton(SpinBtnPage_SetBase,
+                                            "Set &base",
+                                            SpinBtnPage_BaseText,
+                                            &m_textBase);
+    m_textBase->SetValue("10");
+    sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
+
     // right pane
     wxSizer *sizerRight = new wxBoxSizer(wxVERTICAL);
     sizerRight->SetMinSize(150, 0);
@@ -445,6 +465,22 @@ void SpinBtnWidgetsPage::OnButtonSetMinAndMax(wxCommandEvent& WXUNUSED(event))
     m_spinctrldbl->SetRange(minNew, maxNew);
 }
 
+void SpinBtnWidgetsPage::OnButtonSetBase(wxCommandEvent& WXUNUSED(event))
+{
+    unsigned long base;
+    if ( !m_textBase->GetValue().ToULong(&base) || !base )
+    {
+        wxLogWarning("Invalid base value.");
+        return;
+    }
+
+    m_base = base;
+    if ( !m_spinctrl->SetBase(m_base) )
+    {
+        wxLogWarning("Setting base %d failed.", m_base);
+    }
+}
+
 void SpinBtnWidgetsPage::OnButtonSetValue(wxCommandEvent& WXUNUSED(event))
 {
     long val;
@@ -474,6 +510,12 @@ void SpinBtnWidgetsPage::OnUpdateUIMinMaxButton(wxUpdateUIEvent& event)
                   mn <= mx);
 }
 
+void SpinBtnWidgetsPage::OnUpdateUIBaseButton(wxUpdateUIEvent& event)
+{
+    unsigned long base;
+    event.Enable( m_textBase->GetValue().ToULong(&base) && base );
+}
+
 void SpinBtnWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
 {
     event.Enable( !m_chkVert->GetValue() ||
index f0ad8ffac1137ce9f464e1a23e2469c6447f3fb0..0a7306146e692be680351fe5429488a80dd4709d 100644 (file)
@@ -854,7 +854,8 @@ lay them out using wxSizers, absolute positioning, everything you like!
                                 <object class="wxSpinCtrl" name="controls_spinctrl">
                                     <size>100,-1</size>
                                     <max>100</max>
-                                    <value>0</value>
+                                    <value>17</value>
+                                    <base>16</base>
                                 </object>
                             </object>
                         </object>
index 9ed3f6c3db52b6daa56ea9ddbef5984dc6f6f27e..5da05418d7f9d5de718016b6d7c02be6c4b677e9 100644 (file)
@@ -103,4 +103,17 @@ wxCONSTRUCTOR_6( wxSpinCtrl, wxWindow*, Parent, wxWindowID, Id, \
                 wxSize, Size, long, WindowStyle )
 
 
+wxString wxPrivate::wxSpinCtrlFormatAsHex(long val, long maxVal)
+{
+    // We format the value like this is for compatibility with (native
+    // behaviour of) wxMSW
+    wxString text;
+    if ( maxVal < 0x10000 )
+        text.Printf(wxS("0x%04lx"), val);
+    else
+        text.Printf(wxS("0x%08lx"), val);
+
+    return text;
+}
+
 #endif // wxUSE_SPINCTRL
index 5f6bc425122e1dc6779d52e660a3217b2e87659f..52e28ff5f7aac10912da9b0cc7e640e5df1a7f65 100644 (file)
@@ -562,6 +562,30 @@ void wxSpinCtrlGenericBase::SetSelection(long from, long to)
 // wxSpinCtrl
 //-----------------------------------------------------------------------------
 
+bool wxSpinCtrl::SetBase(int base)
+{
+    // Currently we only support base 10 and 16. We could add support for base
+    // 8 quite easily but wxMSW doesn't support it natively so don't bother.
+    if ( base != 10 && base != 16 )
+        return false;
+
+    if ( base == m_base )
+        return true;
+
+    // Update the current control contents to show in the new base: be careful
+    // to call DoTextToValue() before changing the base...
+    double val;
+    const bool hasValidVal = DoTextToValue(m_textCtrl->GetValue(), &val);
+
+    m_base = base;
+
+    // ... but DoValueToText() after doing it.
+    if ( hasValidVal )
+        m_textCtrl->SetValue(DoValueToText(val));
+
+    return true;
+}
+
 void wxSpinCtrl::DoSendEvent()
 {
     wxSpinEvent event( wxEVT_COMMAND_SPINCTRL_UPDATED, GetId());
@@ -574,7 +598,7 @@ void wxSpinCtrl::DoSendEvent()
 bool wxSpinCtrl::DoTextToValue(const wxString& text, double *val)
 {
     long lval;
-    if ( !text.ToLong(&lval) )
+    if ( !text.ToLong(&lval, GetBase()) )
         return false;
 
     *val = static_cast<double>(lval);
@@ -584,7 +608,19 @@ bool wxSpinCtrl::DoTextToValue(const wxString& text, double *val)
 
 wxString wxSpinCtrl::DoValueToText(double val)
 {
-    return wxString::Format("%ld", static_cast<long>(val));
+    switch ( GetBase() )
+    {
+        case 16:
+            return wxPrivate::wxSpinCtrlFormatAsHex(static_cast<long>(val),
+                                                    GetMax());
+
+        default:
+            wxFAIL_MSG( wxS("Unsupported spin control base") );
+            // Fall through
+
+        case 10:
+            return wxString::Format("%ld", static_cast<long>(val));
+    }
 }
 
 #endif // !wxHAS_NATIVE_SPINCTRL
index 205cbc61a9e7f37f3f3e96a09363c8c31549703f..e28cc7a686f895d41983b86813b965136e9244b4 100644 (file)
@@ -359,6 +359,78 @@ wxSpinCtrlGTKBase::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 // wxSpinCtrl
 //-----------------------------------------------------------------------------
 
+extern "C"
+{
+
+static gboolean
+wx_gtk_spin_input(GtkSpinButton* spin, gdouble* val, wxSpinCtrl* win)
+{
+    // We might use g_ascii_strtoll() here but it's 2.12+ only, so use our own
+    // wxString function even if this requires an extra conversion.
+    const wxString
+        text(wxString::FromUTF8(gtk_entry_get_text(GTK_ENTRY(spin))));
+
+    long lval;
+    if ( !text.ToLong(&lval, win->GetBase()) )
+        return FALSE;
+
+    *val = lval;
+
+    return TRUE;
+}
+
+static gint
+wx_gtk_spin_output(GtkSpinButton* spin, wxSpinCtrl* win)
+{
+    const gint val = gtk_spin_button_get_value_as_int(spin);
+
+    gtk_entry_set_text
+    (
+        GTK_ENTRY(spin),
+        wxPrivate::wxSpinCtrlFormatAsHex(val, win->GetMax()).utf8_str()
+    );
+
+    return TRUE;
+}
+
+} // extern "C"
+
+bool wxSpinCtrl::SetBase(int base)
+{
+    // Currently we only support base 10 and 16. We could add support for base
+    // 8 quite easily but wxMSW doesn't support it natively so don't bother
+    // with doing something wxGTK-specific here.
+    if ( base != 10 && base != 16 )
+        return false;
+
+    if ( base == m_base )
+        return true;
+
+    m_base = base;
+
+    // We need to be able to enter letters for any base greater than 10.
+    gtk_spin_button_set_numeric( GTK_SPIN_BUTTON(m_widget), m_base <= 10 );
+
+    if ( m_base != 10 )
+    {
+        g_signal_connect( GTK_SPIN_BUTTON(m_widget), "input",
+                              G_CALLBACK(wx_gtk_spin_input), this);
+        g_signal_connect( GTK_SPIN_BUTTON(m_widget), "output",
+                              G_CALLBACK(wx_gtk_spin_output), this);
+    }
+    else
+    {
+        g_signal_handlers_disconnect_by_func(GTK_SPIN_BUTTON(m_widget),
+                                             (gpointer)wx_gtk_spin_input,
+                                             this);
+        g_signal_handlers_disconnect_by_func(GTK_SPIN_BUTTON(m_widget),
+                                             (gpointer)wx_gtk_spin_output,
+                                             this);
+    }
+
+    return true;
+}
+
 //-----------------------------------------------------------------------------
 // wxSpinCtrlDouble
 //-----------------------------------------------------------------------------
index 95c63204e0009c87a0840d0a87533822c7f156df..ea503b4c41f2f4483258d79d3452ecbf3350f4c0 100644 (file)
@@ -425,6 +425,27 @@ wxSpinCtrl::~wxSpinCtrl()
     gs_spinForTextCtrl.erase(GetBuddyHwnd());
 }
 
+// ----------------------------------------------------------------------------
+// wxSpinCtrl-specific methods
+// ----------------------------------------------------------------------------
+
+int wxSpinCtrl::GetBase() const
+{
+    return ::SendMessage(GetHwnd(), UDM_GETBASE, 0, 0);
+}
+
+bool wxSpinCtrl::SetBase(int base)
+{
+    if ( !::SendMessage(GetHwnd(), UDM_SETBASE, base, 0) )
+        return false;
+
+    // Whether we need to be able enter "x" or not influences whether we should
+    // use ES_NUMBER for the buddy control.
+    UpdateBuddyStyle();
+
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 // wxTextCtrl-like methods
 // ----------------------------------------------------------------------------
@@ -443,16 +464,28 @@ void  wxSpinCtrl::SetValue(int val)
 
     wxSpinButton::SetValue(val);
 
-    // normally setting the value of the spin button is enough as it updates
-    // its buddy control automatically ...
-    if ( wxGetWindowText(m_hwndBuddy).empty() )
+    // Normally setting the value of the spin button is enough as it updates
+    // its buddy control automatically but in a couple of situations it doesn't
+    // do it, for whatever reason, do it explicitly then:
+    const wxString text = wxGetWindowText(m_hwndBuddy);
+
+    // First case is when the text control is empty and the value is 0: the
+    // spin button just leaves it empty in this case, while we want to show 0
+    // in it.
+    if ( text.empty() && !val )
+    {
+        ::SetWindowText(GetBuddyHwnd(), wxT("0"));
+    }
+
+    // Another one is when we're using hexadecimal base but the user input
+    // doesn't start with "0x" -- we prefer to show it to avoid ambiguity
+    // between decimal and hexadecimal.
+    if ( GetBase() == 16 &&
+            (text.length() < 3 || text[0] != '0' ||
+                (text[1] != 'x' && text[1] != 'X')) )
     {
-        // ... but sometimes it doesn't, notably when the value is 0 and the
-        // text control is currently empty, the spin button seems to be happy
-        // to leave it like this, while we really want to always show the
-        // current value in the control, so do it manually
         ::SetWindowText(GetBuddyHwnd(),
-                        wxString::Format(wxT("%d"), val).t_str());
+                        wxPrivate::wxSpinCtrlFormatAsHex(val, m_max).t_str());
     }
 
     m_oldValue = GetValue();
@@ -462,10 +495,10 @@ void  wxSpinCtrl::SetValue(int val)
 
 int wxSpinCtrl::GetValue() const
 {
-    wxString val = wxGetWindowText(m_hwndBuddy);
+    const wxString val = wxGetWindowText(m_hwndBuddy);
 
     long n;
-    if ( (wxSscanf(val, wxT("%ld"), &n) != 1) )
+    if ( !val.ToLong(&n, GetBase()) )
         n = INT_MIN;
 
     if ( n < m_min )
@@ -504,12 +537,19 @@ void wxSpinCtrl::SetRange(int minVal, int maxVal)
 
     wxSpinButton::SetRange(minVal, maxVal);
 
+    UpdateBuddyStyle();
+}
+
+void wxSpinCtrl::UpdateBuddyStyle()
+{
     // this control is used for numeric entry so restrict the input to numeric
     // keys only -- but only if we don't need to be able to enter "-" in it as
-    // otherwise this would become impossible
+    // otherwise this would become impossible and also if we don't use
+    // hexadecimal as entering "x" of the "0x" prefix wouldn't be allowed
+    // neither then
     const DWORD styleOld = ::GetWindowLong(GetBuddyHwnd(), GWL_STYLE);
     DWORD styleNew;
-    if ( minVal < 0 )
+    if ( m_min < 0 || GetBase() != 10 )
         styleNew = styleOld & ~ES_NUMBER;
     else
         styleNew = styleOld | ES_NUMBER;
index 01b0a057b0cd2d109ecb4ad276246628dde74c79..d9b1f4ef77b69aa0f41fe867b785ce2ecaa0248a 100644 (file)
@@ -96,6 +96,10 @@ wxObject *wxSpinCtrlXmlHandler::DoCreateResource()
                     GetLong(wxT("value"), DEFAULT_VALUE),
                     GetName());
 
+    const long base = GetLong(wxS("base"), 10);
+    if ( base != 10 )
+        control->SetBase(base);
+
     SetupWindow(control);
 
     return control;