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:
Vadim Zeitlin
2012-08-30 20:24:38 +00:00
parent 36090ae57e
commit 9e565667d0
14 changed files with 328 additions and 23 deletions

View 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;