tgui::EditBox rule for checking text validity

Started by Djer, 07 January 2016, 15:13:44

Djer

Hello (again, today) Texus,

That would be great to add a way to define a rule for checking the text in a tgui::EditBox.
I have create my own way to do that, so it's not urgent, but that would be great to add it to you library when you have some time :)

I saw an old post on that where you said that :

Re: Limiting Type of Input Edit Box/Text Box Accepts
« Reply #1 on: November 23, 2015, 04:56:05 pm »


1) You can call editBox->setNumbersOnly() to disallow text in it, but there is currently no way to limit the edit box to integers only (e.g. the following can be written in a numbers only edit box: "-1.235e6"). There are a lot of different uses for limiting characters (some would want only positive integers, others would want floats but without the optional 'e' behind it, ...) and I have not yet found a way to provide a proper way to allow all these possibilities.

2) An edit box is a single line of text without newlines, a text box is a multi-lined text field.



Maybe you can just add a function to the tgui::TextBox:

void setTextRule(std::unique_ptr<TextRule> rule)


The TextRule class would have a virtual bool check(std::string textEntered) function

And so we can create our own rules by creating a class inherited by TextRule

You can just check if the text entered correspond to our expactations by calling the check() function on the event lostFocus

The constructor of TextRule would take a default value (string) who can be used when the user enter a bad text.

and why not too a description of the expected value (used for the tooltip)? ...And the possibility to put a messageBox with this description when the user enter a bad value.


I don't think it would take a lot of time :)


texus

QuoteMaybe you can just add a function to the tgui::TextBox:
void setTextRule(std::unique_ptr<TextRule> rule)
The TextRule class would have a virtual bool check(std::string textEntered) function
I'd probably just let you pass a function like this:
Code (cpp) Select
void setTextRule(std::function<bool(const std::string&)> checkFunction)

But I think the rules only make sense for an EditBox, do you really need it for the multi-line TextBox?

I'll consider this at the end of the month, after my exams.

Quoteand why not too a description of the expected value (used for the tooltip)? ...And the possibility to put a messageBox with this description when the user enter a bad value.
These things are becoming too specific to a specific application and will most likely not be added. It isn't even possible for the text box to know what the expected value is. And they are easy to add in user code (e.g. open message box inside the check function).

Djer

I made a mistake, I want to say tgui::EditBox indeed.

Yes, just pass it a function seems good and will keep it simple :)

You're right, the behavior that I explained is too specific.

Good luck for your exams (I'm too in exams for the moment...)

texus

#3
I decided to go with a string representing a regex as parameter to set how the text in the edit box should look because they can be saved and loaded from text files unlike the text rule functions.

Do you have any preference for a name of such function: setTextRule, setTextFormat, setTextRegex or do you have a better idea?

Djer

I didn't know what a regex is. I just learn it from google. It's very interesting !

I think setTextRule will be easier to understand that setTextRegex for people who don't know what a regex is... (like me  ::) )
and I think the word "rule" is quite representative

Or maybe setInputRule?

:)

texus

I find setInputRule better than setTextRule, but no matter if it contains regex in the name or not you will still need to know regular expressions to use it (unless you only use the predefined regexes).
What about setValidator? Qt uses that name although the parameter is a QValidator class and not a string like here.

So currently this would be how it looks:
Code (cpp) Select
//////////////////////////////////////////////////////////////////////////////////////////
/// @brief Define how the text input should look
///
/// @param regex  Valid regular expression for std::regex to match on text changes
///
/// When the regex does not match when calling the setText function then the edit box
/// contents will be cleared. When it does not match when the user types a character in the edit box,
/// then the input character is rejected.
///
//////////////////////////////////////////////////////////////////////////////////////////
void setInputRule(const std::string& regex = ".*");


You could call it like:
Code (cpp) Select
editBox->setInputRule(tgui::EditBox::InputRule::Int); // using pre-defined regex
editBox->setInputRule("[-+]?[0-9]*"); // using custom regex


These regexes are a lot easier than writing check functions. For checking floating point numbers I needed to loop over all characters making sure that they could only be numbers or a dot, but there could not be more than one dot and the first character also needed an extra check because it could be + or -. With a regex I just have to provide "[-+]?[0-9]*\\.[0-9]*" as input (the only tricky thing is escaping the dot which matches any character when not escaped).

Djer

It looks great!

setValidator seems good to. So it's your choice :)

And thanks for your availability for the users !


texus

#7
I'll go with setInputValidator. When I add options for validation other than regexes then I can remain backwards compatible instead of having to rename the function.

The implementation is already done, I just need to write tests for it, so it should be pushed online later today.

texus

The setInputValidator function has been added in the latest version on github.