Add wxSpinCtrl::SetBase() to allow entering hexadecimal numbers.
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
This commit is contained in:
@@ -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).
|
||||
|
@@ -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
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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)
|
||||
};
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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_
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
// ------------
|
||||
|
||||
@@ -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() ||
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
{
|
||||
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
|
||||
|
@@ -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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user