diff --git a/enaml/stdlib/fields.enaml b/enaml/stdlib/fields.enaml index b978c64cd..6f8f8cdb5 100644 --- a/enaml/stdlib/fields.enaml +++ b/enaml/stdlib/fields.enaml @@ -10,7 +10,7 @@ This is a library of Enaml components deriving from the builtin Field. """ -from enaml.validator import RegexValidator, IntValidator, FloatValidator +from enaml.validator import RegexValidator, IntValidator, FloatValidator, ComplexValidator from enaml.widgets.field import Field @@ -58,3 +58,19 @@ enamldef FloatField(Field): validator << FloatValidator( minimum=minimum, maximum=maximum, allow_exponent=allow_exponent ) + + +enamldef ComplexField(Field): + """ A Field that only accept complex floating point values. + + """ + attr minimum = None + attr maximum = None + attr allow_exponent : bool = True + attr value : complex = 0.0 + 0.0*1j + attr converter = unicode + text << converter(value) + text :: self.value = complex(text) + validator << ComplexValidator( + minimum=minimum, maximum=maximum, allow_exponent=allow_exponent + ) diff --git a/enaml/validator.py b/enaml/validator.py index c12c999df..f710605cc 100644 --- a/enaml/validator.py +++ b/enaml/validator.py @@ -151,6 +151,53 @@ def validate(self, text): return True +class ComplexValidator(Validator): + """ A concrete Validator which handles complex floating point input. + + This validator ensures that the text represents a complex floating point + number within a specified range. + + """ + #: The minimum value allowed for the float, inclusive, or None if + #: there is no lower bound. + minimum = Typed(complex) + + #: The maximum value allowed for the float, inclusive, or None if + #: there is no upper bound. + maximum = Typed(complex) + + #: Whether or not to allow exponents like '1e6' in the input. + allow_exponent = Bool(True) + + def validate(self, text): + """ Validates the given text matches the complex float range. + + Parameters + ---------- + text : unicode + The unicode text edited by the client widget. + + Returns + ------- + result : bool + True if the text is valid, False otherwise. + + """ + try: + value = complex(text) + except ValueError: + return False + minimum = self.minimum + if minimum is not None and (value.real < minimum or value.imag < minimum): + return False + maximum = self.maximum + if maximum is not None and (value.real > maximum or value.imag > maximum): + return False + if not self.allow_exponent and 'e' in text.lower(): + return False + return True + + class RegexValidator(Validator): """ A concrete Validator which handles text input.