arcade icon indicating copy to clipboard operation
arcade copied to clipboard

Enhancement: Addition of more arguments in UIInputText

Open Ibrahim2750mi opened this issue 2 years ago • 5 comments

Enhancement request:

What should be added?

In UIInputText there should be an argument to

  1. only accept numeric values i.e (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) in the input box.
  2. limit the number of characters to be entered in the input box.

What would it help with?

  1. When the game wants the user to enter its response in only numeric values.
  2. When the game wants to asks for user's name etc.

Ibrahim2750mi avatar Mar 21 '22 08:03 Ibrahim2750mi

Maybe adding a callable validator argument to labels would be a good idea?

pushfoo avatar Apr 26 '22 16:04 pushfoo

Maybe adding a callable validator argument to labels would be a good idea?

Can it not be done with just regex? like acceptable_format: re.Pattern

Ibrahim2750mi avatar Apr 29 '22 04:04 Ibrahim2750mi

Remember, beginners are one of the core audiences for arcade. Requiring them to learn regex may overwhelm them if they're still struggling with the fundamentals of Python.

pushfoo avatar Apr 29 '22 18:04 pushfoo

@Ibrahim2750mi I took some more time to think about this. I agree that we should have some form of support for regex.

However, I think callables are the best option for the validator argument. They would allow us to have a decent balance of beginner friendliness and accessibility for advanced users. Advanced users can do whatever they want, while beginners could use default helper functions to handle things like regex, integers, etc. I'm largely taking inspiration from attr's validators:

from typing import Any, Callable
import arcade
# the validators package would include reasonable presets for regex, digits, etc
from arcade.validation import validators

class ValidatedWidget:
    """
    Mock-up of how we might implement validation. 
    
    It might not align with the exact widget implementation we have now
    """
    def __init__(self, value: Any = None, validator: Callable = None):
        self._validator = validator
        self._value = None

        # use the property setter to validate and set
        self.value = value
       
    @property
    def value(self) -> Any:
        return self._value

    @value.setter
    def value(self, new: Any):
        if self._validator and not self._validator(new):
            # we'd need a much better reporting mechanism in the final version
            raise ValueError(f"Invalid value for validator {self._validator}")
        else:
            self._value = new


widget = ValidatedWidget(
    value="123",
    # this validator function would do type checking once and return a callable wrapping a regex 
    validator=validators.base_10_integer
)

# this produces an exception
widget.value = "1f4b"

pushfoo avatar May 02 '22 22:05 pushfoo

The callable approach sounds better from my point of few, so let's go into that direction, it visery flexible.

eruvanos avatar Jun 22 '22 20:06 eruvanos