Module albow.input.Field

Source code
import logging

from albow.widgets.Control import Control

from albow.input.TextEditor import TextEditor


class Field(Control, TextEditor):

    """
    Field is an abstract base class for controls that edit a value with a textual representation. It provides
    facilities for

    - Converting between the text and internal representations of the value,
    - For specifying minimum and maximum allowed values, and
    - Controlling whether the value is allowed to be empty and what representation to use for an empty value.

    A Field can be in two states, _editing_ and _non-editing_. In the non-editing state, the control displays
    the value to which it is linked via its `ref` attribute. When the user focuses the control and begins typing,
    it switches to the editing state. In this state, the text may be edited but the associated value is not yet
    updated. When the `Return`, `Enter` or `Tab key` is pressed, or a mouse click occurs anywhere outside the field,
    the value is updated and the control returns to the non-editing state. Updating of the value can also be
    forced by calling the `commit()` method.
    """

    DEFAULT_WIDTH = 100

    empty = NotImplemented
    """
    Internal value to use when the field is empty.  If set to NotImplemented, the user is not allowed to enter 
    an empty value.
    """
    format = "%s"
    """
    Format string to use when converting the internal representation to text. See also format_value() below.
    """
    min: int = None
    """
    Minimum allowable value.  If `None`, no minimum value will be enforced.
    """
    max: int = None
    """
    Maximum allowable value.  If `None`, no maximum value will be enforced.
    """
    type = None
    """
    A function for converting from text to the internal representation.  Typically a type object, but 
    can be any callable object.
    """
    editing: bool = None
    """
    _Read only_. A boolean which is true when the control is in the editing state.
    """
    insertion_point = None

    def __init__(self, width=None, **kwds):
        """

        Args:
            width:  The width may be an integer or a string, as for TextEditor. If no width is specified, but a
                    value for min and/or max is specified at construction time, the width will be determined from
                    the min or max value. If no other way of determining the width is available, it defaults to 100.

            **kwds:
        """
        self.logger = logging.getLogger(__name__)

        if 'format' in kwds:
            self.format = kwds.pop('format')
        if 'empty' in kwds:
            self.empty = kwds.pop('empty')
        self.editing = False

        predictedWidth = self._predictWidth(kwds, width)
        TextEditor.__init__(self, width=predictedWidth, **kwds)

    def _predictWidth(self, kwds, theWidth):

        minimum = self.predict_attr(kwds, 'min')
        maximum = self.predict_attr(kwds, 'max')

        predictedWidth = theWidth
        if theWidth is None:
            w1 = 0
            w2 = 0
            if minimum is not None:
                w1 = minimum
            if maximum is not None:
                w2 = maximum
            if w1 > w2:
                predictedWidth = w1
            else:
                predictedWidth = w2

        if predictedWidth == 0 and theWidth is None:
            predictedWidth = Field.DEFAULT_WIDTH

        self.logger.debug(f"predictedWidth: {predictedWidth}")

        return predictedWidth

    def format_value(self, theValueToFormat):
        """
        This method is called to format the value for display. By default it uses the format string specified by
        the format attribute. You can override this method to format the value in a different way.

        Args:
            theValueToFormat:  The value

        Returns:  The formatted value

        """
        if theValueToFormat == self.empty:
            return ""
        else:
            return self.format % theValueToFormat

    def get_text(self):
        if self.editing:
            return self._text
        else:
            return self.format_value(self.value)

    def set_text(self, theNewText):
        self.editing = True
        self._text = theNewText

    def enter_action(self):
        if self.editing:
            self.commit()
        return 'pass'

    def escape_action(self):
        if self.editing:
            self.editing = False
            self.insertion_point = None
        else:
            return 'pass'

    def attention_lost(self):
        self.commit()

    def commit(self):
        """
        When in the editing state, causes the control's value to be updated and places the control
        in the non-editing state.
        """
        if self.editing:
            text = self._text
            if text:
                try:
                    value = self.type(text)
                except ValueError:
                    return
                if self.min is not None:
                    value = max(self.min, value)
                if self.max is not None:
                    value = min(self.max, value)
            else:
                value = self.empty
                if value is NotImplemented:
                    return
            self.value = value
            self.editing = False
            self.insertion_point = None
        else:
            self.insertion_point = None

Classes

class Field (width=None, **kwds)

Field is an abstract base class for controls that edit a value with a textual representation. It provides facilities for

  • Converting between the text and internal representations of the value,
  • For specifying minimum and maximum allowed values, and
  • Controlling whether the value is allowed to be empty and what representation to use for an empty value.

A Field can be in two states, editing and non-editing. In the non-editing state, the control displays the value to which it is linked via its ref attribute. When the user focuses the control and begins typing, it switches to the editing state. In this state, the text may be edited but the associated value is not yet updated. When the Return, Enter or Tab key is pressed, or a mouse click occurs anywhere outside the field, the value is updated and the control returns to the non-editing state. Updating of the value can also be forced by calling the commit() method.

Args

width
The width may be an integer or a string, as for TextEditor. If no width is specified, but a value for min and/or max is specified at construction time, the width will be determined from the min or max value. If no other way of determining the width is available, it defaults to 100.

**kwds:

Source code
class Field(Control, TextEditor):

    """
    Field is an abstract base class for controls that edit a value with a textual representation. It provides
    facilities for

    - Converting between the text and internal representations of the value,
    - For specifying minimum and maximum allowed values, and
    - Controlling whether the value is allowed to be empty and what representation to use for an empty value.

    A Field can be in two states, _editing_ and _non-editing_. In the non-editing state, the control displays
    the value to which it is linked via its `ref` attribute. When the user focuses the control and begins typing,
    it switches to the editing state. In this state, the text may be edited but the associated value is not yet
    updated. When the `Return`, `Enter` or `Tab key` is pressed, or a mouse click occurs anywhere outside the field,
    the value is updated and the control returns to the non-editing state. Updating of the value can also be
    forced by calling the `commit()` method.
    """

    DEFAULT_WIDTH = 100

    empty = NotImplemented
    """
    Internal value to use when the field is empty.  If set to NotImplemented, the user is not allowed to enter 
    an empty value.
    """
    format = "%s"
    """
    Format string to use when converting the internal representation to text. See also format_value() below.
    """
    min: int = None
    """
    Minimum allowable value.  If `None`, no minimum value will be enforced.
    """
    max: int = None
    """
    Maximum allowable value.  If `None`, no maximum value will be enforced.
    """
    type = None
    """
    A function for converting from text to the internal representation.  Typically a type object, but 
    can be any callable object.
    """
    editing: bool = None
    """
    _Read only_. A boolean which is true when the control is in the editing state.
    """
    insertion_point = None

    def __init__(self, width=None, **kwds):
        """

        Args:
            width:  The width may be an integer or a string, as for TextEditor. If no width is specified, but a
                    value for min and/or max is specified at construction time, the width will be determined from
                    the min or max value. If no other way of determining the width is available, it defaults to 100.

            **kwds:
        """
        self.logger = logging.getLogger(__name__)

        if 'format' in kwds:
            self.format = kwds.pop('format')
        if 'empty' in kwds:
            self.empty = kwds.pop('empty')
        self.editing = False

        predictedWidth = self._predictWidth(kwds, width)
        TextEditor.__init__(self, width=predictedWidth, **kwds)

    def _predictWidth(self, kwds, theWidth):

        minimum = self.predict_attr(kwds, 'min')
        maximum = self.predict_attr(kwds, 'max')

        predictedWidth = theWidth
        if theWidth is None:
            w1 = 0
            w2 = 0
            if minimum is not None:
                w1 = minimum
            if maximum is not None:
                w2 = maximum
            if w1 > w2:
                predictedWidth = w1
            else:
                predictedWidth = w2

        if predictedWidth == 0 and theWidth is None:
            predictedWidth = Field.DEFAULT_WIDTH

        self.logger.debug(f"predictedWidth: {predictedWidth}")

        return predictedWidth

    def format_value(self, theValueToFormat):
        """
        This method is called to format the value for display. By default it uses the format string specified by
        the format attribute. You can override this method to format the value in a different way.

        Args:
            theValueToFormat:  The value

        Returns:  The formatted value

        """
        if theValueToFormat == self.empty:
            return ""
        else:
            return self.format % theValueToFormat

    def get_text(self):
        if self.editing:
            return self._text
        else:
            return self.format_value(self.value)

    def set_text(self, theNewText):
        self.editing = True
        self._text = theNewText

    def enter_action(self):
        if self.editing:
            self.commit()
        return 'pass'

    def escape_action(self):
        if self.editing:
            self.editing = False
            self.insertion_point = None
        else:
            return 'pass'

    def attention_lost(self):
        self.commit()

    def commit(self):
        """
        When in the editing state, causes the control's value to be updated and places the control
        in the non-editing state.
        """
        if self.editing:
            text = self._text
            if text:
                try:
                    value = self.type(text)
                except ValueError:
                    return
                if self.min is not None:
                    value = max(self.min, value)
                if self.max is not None:
                    value = min(self.max, value)
            else:
                value = self.empty
                if value is NotImplemented:
                    return
            self.value = value
            self.editing = False
            self.insertion_point = None
        else:
            self.insertion_point = None

Ancestors

Subclasses

Class variables

var DEFAULT_WIDTH
var editing

Read only. A boolean which is true when the control is in the editing state.

var empty

Internal value to use when the field is empty. If set to NotImplemented, the user is not allowed to enter an empty value.

var format

Format string to use when converting the internal representation to text. See also format_value() below.

var insertion_point
var max

Maximum allowable value. If None, no maximum value will be enforced.

var min

Minimum allowable value. If None, no minimum value will be enforced.

var type

A function for converting from text to the internal representation. Typically a type object, but can be any callable object.

Methods

def commit(self)

When in the editing state, causes the control's value to be updated and places the control in the non-editing state.

Source code
def commit(self):
    """
    When in the editing state, causes the control's value to be updated and places the control
    in the non-editing state.
    """
    if self.editing:
        text = self._text
        if text:
            try:
                value = self.type(text)
            except ValueError:
                return
            if self.min is not None:
                value = max(self.min, value)
            if self.max is not None:
                value = min(self.max, value)
        else:
            value = self.empty
            if value is NotImplemented:
                return
        self.value = value
        self.editing = False
        self.insertion_point = None
    else:
        self.insertion_point = None
def enter_action(self)
Source code
def enter_action(self):
    if self.editing:
        self.commit()
    return 'pass'
def escape_action(self)
Source code
def escape_action(self):
    if self.editing:
        self.editing = False
        self.insertion_point = None
    else:
        return 'pass'
def format_value(self, theValueToFormat)

This method is called to format the value for display. By default it uses the format string specified by the format attribute. You can override this method to format the value in a different way.

Args

theValueToFormat
The value
Returns :  The formatted value
 
Source code
def format_value(self, theValueToFormat):
    """
    This method is called to format the value for display. By default it uses the format string specified by
    the format attribute. You can override this method to format the value in a different way.

    Args:
        theValueToFormat:  The value

    Returns:  The formatted value

    """
    if theValueToFormat == self.empty:
        return ""
    else:
        return self.format % theValueToFormat
def get_text(self)
Source code
def get_text(self):
    if self.editing:
        return self._text
    else:
        return self.format_value(self.value)

Inherited members