Hi guys,
Can I somehow restrict an editbox to accept only numbers ? I mean like the one from the spinner ? How does the spinner do this ?
Text filter in editbox
Moderators: CEGUI MVP, CEGUI Team
From CEGUISpinner.cpp:
That's the simple case, where you can input numbers. However it's be fun to have formatted input, something like: ">>>,>>9.99" to input a decimal number. Or inputting a credit card number: "999 999 999 999" (I think that's the format).
Have a look at Formatted_Numeric_Data, at the ICU::formatText function. It may be useful.
Code: Select all
void Spinner::onValueChanged(WindowEventArgs& e)
{
Editbox* editbox = getEditbox();
// mute to save doing unnecessary events work.
bool wasMuted = editbox->isMuted();
editbox->setMutedState(true);
// Update text with new value.
// (allow empty and '-' cases to equal 0 with no text change required)
if (!(d_currentValue == 0 &&
(editbox->getText().empty() || editbox->getText() == "-")))
{
editbox->setText(getTextFromValue());
}
// restore previous mute state.
editbox->setMutedState(wasMuted);
fireEvent(EventValueChanged, e, EventNamespace);
}
String Spinner::getTextFromValue(void) const
{
std::stringstream tmp;
switch (d_inputMode)
{
case FloatingPoint:
tmp << d_currentValue;
break;
case Integer:
tmp << static_cast<int>(d_currentValue);
break;
case Hexadecimal:
tmp << std::hex << std::uppercase << static_cast<int>(d_currentValue);
break;
case Octal:
tmp << std::oct << static_cast<int>(d_currentValue);
break;
default:
throw InvalidRequestException("Spinner::getValueFromText - An unknown TextInputMode was encountered.");
}
return String(tmp.str());
}
That's the simple case, where you can input numbers. However it's be fun to have formatted input, something like: ">>>,>>9.99" to input a decimal number. Or inputting a credit card number: "999 999 999 999" (I think that's the format).
Have a look at Formatted_Numeric_Data, at the ICU::formatText function. It may be useful.
ICU is great to display test in various locales. Most people (and by most I mean the people near where _I_ live) use the comma to separate thousands and a period to separate decimals: 123,456.78. However I wonder if most (and by that I mean the actual meaning of the word, the greatest amount of) people do not instead use the period to separate thousands and a comma to separate decimals: 123.456,78.
By limiting an application to a particular type of data (numeric, date) we alianate those people that do not use the same locale as us. Concretely that translates to lost sales, lost revenues. With my version of ICU I showed that it wasn't too difficult to present values in a locale-independant manner within Cegui. However I have only done the easy part; the display of data. The input of formatted data is more difficult. But once you have it working for one locale of data then it shouldn't be too difficult to make it work for other locales.
I recommend at least using IBM's ICU formatting rules, so that should anyone wish to use ICU to easily retrieve a localised format string, it could plug in easily into your solution.
By limiting an application to a particular type of data (numeric, date) we alianate those people that do not use the same locale as us. Concretely that translates to lost sales, lost revenues. With my version of ICU I showed that it wasn't too difficult to present values in a locale-independant manner within Cegui. However I have only done the easy part; the display of data. The input of formatted data is more difficult. But once you have it working for one locale of data then it shouldn't be too difficult to make it work for other locales.
I recommend at least using IBM's ICU formatting rules, so that should anyone wish to use ICU to easily retrieve a localised format string, it could plug in easily into your solution.
I'm not sure how to actually implement this feature but this idea may provide a research direction.
Trick the user. Yup, fool him/her into believing that the EditBox contains a mask when in fact it does not.
Let's say my mask is "999 999" and I type "123". On the "text changed" event I retrieve the typed value and determine that a space should be inserted. So I mute the "text changed" event, retrieve the current text, add a space, set that as the new text and unmute the "text changed" event, and make sure the cursor is after the space.
That's one approach. Hopefully it isn't too bad, or you can find a better one. I wonder how the big boys (MFC, .Net, Java) actually implement this feature.
Trick the user. Yup, fool him/her into believing that the EditBox contains a mask when in fact it does not.
Let's say my mask is "999 999" and I type "123". On the "text changed" event I retrieve the typed value and determine that a space should be inserted. So I mute the "text changed" event, retrieve the current text, add a space, set that as the new text and unmute the "text changed" event, and make sure the cursor is after the space.
That's one approach. Hopefully it isn't too bad, or you can find a better one. I wonder how the big boys (MFC, .Net, Java) actually implement this feature.
- lindquist
- CEGUI Team (Retired)
- Posts: 770
- Joined: Mon Jan 24, 2005 21:20
- Location: Copenhagen, Denmark
I believe the Editbox::setValidationString member can solve you problem. It takes a perl compatible regular expression and rejects input if the result would not pass the regex.
to restrict the user to '123 456 789' type strings you could use something like this: (written as a C string literal)
this will still allow entering just 2 spaces, but my regex is somewhat rusty and I'm not sure how to work around this.
it's important that the regex will match all possible inputs and not just the final result. fx:
would make it impossible to enter anything into a empty box as one char would never match.
Hope it gives some ideas.
to restrict the user to '123 456 789' type strings you could use something like this: (written as a C string literal)
Code: Select all
"\\d{0,3} ?\\d{0,3} ?\\d{0,3}"
this will still allow entering just 2 spaces, but my regex is somewhat rusty and I'm not sure how to work around this.
it's important that the regex will match all possible inputs and not just the final result. fx:
Code: Select all
"\\d{3} \\d{3} \\d{3}"
would make it impossible to enter anything into a empty box as one char would never match.
Hope it gives some ideas.
Yeah, I don#t know much about regex. I tried this member by setting the property just to "a" and hoping this would allow only an "a" to be enterd ... didn't seem to work I go try your regexp and I'll tell you.
Edit: Great ! it actually works very good thank you for your regexp !
And btw ... setting the regexp to just "a" DOES work ! I just tried it and it worked.
I was thinking of an approach like rackle, but now ... no more need ! That's what i call a powerful GUI
Edit: Great ! it actually works very good thank you for your regexp !
And btw ... setting the regexp to just "a" DOES work ! I just tried it and it worked.
I was thinking of an approach like rackle, but now ... no more need ! That's what i call a powerful GUI
Who is online
Users browsing this forum: No registered users and 9 guests