Beispiel #1
0
class FlowArea(Frame):
    """ A widget which lays out its children in flowing manner, wrapping
    around at the end of the available space.

    """
    #: The flow direction of the layout.
    direction = d_(
        Enum('left_to_right', 'right_to_left', 'top_to_bottom',
             'bottom_to_top'))

    #: The alignment of a line of items within the layout.
    align = d_(Enum('leading', 'trailing', 'center', 'justify'))

    #: The amount of horizontal space to place between items.
    horizontal_spacing = d_(Range(low=0, value=10))

    #: The amount of vertical space to place between items.
    vertical_spacing = d_(Range(low=0, value=10))

    #: The margins to use around the outside of the flow area.
    margins = d_(Coerced(Box, (10, 10, 10, 10)))

    #: A FlowArea expands freely in width and height by default.
    hug_width = set_default('ignore')
    hug_height = set_default('ignore')

    #: A reference to the ProxyFlowArea object.
    proxy = Typed(ProxyFlowArea)

    def flow_items(self):
        """ Get the flow item children defined on this area.

        """
        return [c for c in self.children if isinstance(c, FlowItem)]

    #--------------------------------------------------------------------------
    # Default Handlers
    #--------------------------------------------------------------------------
    def _default_border(self):
        """ Get the default border for the flow area.

        The default value matches the default for Qt's QScrollArea.

        """
        return Border(style='styled_panel', line_style='sunken')

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('direction', 'align', 'horizontal_spacing', 'vertical_spacing',
             'margins')
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.

        """
        # The superclass handler implementation is sufficient.
        super(FlowArea, self)._update_proxy(change)
Beispiel #2
0
class FlowItem(Widget):
    """ A widget which can be used as an item in a FlowArea.

    A FlowItem is a widget which can be used as a child of a FlowArea
    widget. It can have at most a single child widget which is an
    instance of Container.

    """
    #: The preferred size of this flow item. This size will be used as
    #: the size of the item in the layout, bounded to the computed min
    #: and max size. A size of (-1, -1) indicates to use the widget's
    #: size hint as the preferred size.
    preferred_size = d_(Coerced(Size, (-1, -1)))

    #: The alignment of this item in the direction orthogonal to the
    #: layout flow.
    align = d_(Enum('leading', 'trailing', 'center'))

    #: The stretch factor for this item in the flow direction, relative
    #: to other items in the same line. The default is zero which means
    #: that the item will not expand in the direction orthogonal to the
    #: layout flow.
    stretch = d_(Range(low=0, value=0))

    #: The stretch factor for this item in the orthogonal direction
    #: relative to other items in the layout. The default is zero
    #: which means that the item will not expand in the direction
    #: orthogonal to the layout flow.
    ortho_stretch = d_(Range(low=0, value=0))

    #: A reference to the ProxyFlowItem object.
    proxy = Typed(ProxyFlowItem)

    def flow_widget(self):
        """ Get the flow widget defined on this flow item.

        The last Container defined on the item is the flow widget.

        """
        for child in reversed(self.children):
            if isinstance(child, Container):
                return child

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe(('preferred_size', 'align', 'stretch', 'ortho_stretch'))
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.

        """
        # The superclass handler implementation is sufficient.
        super(FlowItem, self)._update_proxy(change)
Beispiel #3
0
class DefaultSpacing(Atom):
    """ A class which encapsulates the default spacing parameters for
    the various layout helper objects.

    """
    #: The space between abutted components
    ABUTMENT = Range(low=0, value=10)

    #: The space between aligned anchors
    ALIGNMENT = Range(low=0, value=0)

    #: The margins for box helpers
    BOX_MARGINS = Coerced(Box, factory=lambda: Box(0, 0, 0, 0))
Beispiel #4
0
class CalendarView(FrameLayout):
    """CalendarView is a view group that displays
    child views in relative positions.

    """

    #: Selected date
    date = d_(Instance(datetime, factory=datetime.now))

    #: Max date
    max_date = d_(Instance(datetime, factory=datetime.now))

    #: Min date
    min_date = d_(Instance(datetime, factory=datetime.now))

    #: First day of week
    first_day_of_week = d_(Range(1, 7))

    #: A reference to the ProxyLabel object.
    proxy = Typed(ProxyCalendarView)

    # -------------------------------------------------------------------------
    # Observers
    # -------------------------------------------------------------------------
    @observe("date", "max_date", "min_date", "first_day_of_week")
    def _update_proxy(self, change):

        super()._update_proxy(change)
Beispiel #5
0
class Experiment(Atom):

    coef = FloatRange(-1.0, 1.0, 0.0)

    gain = Range(0, 100, 10)

    scale = FloatRange(0.0, 2.0, 1.0, strict=True)
Beispiel #6
0
class DatePicker(FrameLayout):
    """A simple control for displaying read-only text."""

    #: Update the current year.
    date = d_(Instance(datetime, factory=datetime.now))

    #: Sets the minimal date supported by this DatePicker in milliseconds
    #: since January 1, 1970 00:00:00 in getDefault() time zone.
    min_date = d_(Instance(datetime, factory=datetime.now))

    #: Sets the maximal date supported by this DatePicker in milliseconds
    #: since January 1, 1970 00:00:00 in getDefault() time zone.
    max_date = d_(Instance(datetime, factory=datetime.now))

    #: Sets the first day of week.
    first_day_of_week = d_(Range(1, 7))

    #: A reference to the ProxyLabel object.
    proxy = Typed(ProxyDatePicker)

    # -------------------------------------------------------------------------
    # Observers
    # -------------------------------------------------------------------------
    @observe("date", "min_date", "max_date", "first_day_of_week")
    def _update_proxy(self, change):

        super()._update_proxy(change)
Beispiel #7
0
class StatusItem(ToolkitObject):
    """ An item which holds a widget to include in a status bar.

    """
    #: The mode of a status item. A 'normal' item can be obscured by
    #: temporary status messages; a 'permanent' item cannot.
    mode = d_(Enum('normal', 'permanent'))

    #: The stretch factor to apply to this item, relative to the other
    #: items in the status bar.
    stretch = d_(Range(low=0))

    #: A reference to the ProxyStatusItem object.
    proxy = Typed(ProxyStatusItem)

    def status_widget(self):
        """ Get the status widget for the item.

        The last Widget child is used as the status widget.

        """
        for child in reversed(self.children):
            if isinstance(child, Widget):
                return child

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('mode', 'stretch')
    def _update_proxy(self, change):
        """ Update the proxy when the status item data changes.

        """
        # The superclass implementation is sufficient.
        super(StatusItem, self)._update_proxy(change)
Beispiel #8
0
class Person(Atom):
    """ A simple class representing a person object.

    """
    last_name = Str()

    first_name = Str()

    age = Range(low=0)

    dob = Value(datetime.date(1970, 1, 1))

    debug = Bool(False)

    @observe('age')
    def debug_print(self, change):
        """ Prints out a debug message whenever the person's age changes.

        """
        if self.debug:
            templ = "{first} {last} is {age} years old."
            s = templ.format(
                first=self.first_name,
                last=self.last_name,
                age=self.age,
            )
            print(s)
Beispiel #9
0
class Person(Atom):

    last_name = Unicode()
    first_name = Unicode()
    age = Range(low=0)
    dob = Value(datetime.date(1970, 1, 1))
    debug = Bool(False)

    @observe('age')
    def debug_print(self, change):
        """ Prints out a debug message whenever the person's age changes.

        """
        if self.debug:
            templ = "{first} {last} is {age} years old."
            s = templ.format(
                first=self.first_name, last=self.last_name, age=self.age,
            )
            print(s)

    @observe('dob')
    def update_age(self, change):
        """ Update the person's age whenever their date of birth changes

        """
        # grab the current date time
        now = datetime.datetime.utcnow()
        # estimate the person's age within one year accuracy
        age = now.year - self.dob.year
        # check to see if the current date is before their birthday and
        # subtract a year from their age if it is
        if now.month >= self.dob.month and now.day > self.dob.day:
            age -= 1
        # set the persons age
        self.age = age
Beispiel #10
0
class CalendarView(FrameLayout):
    """ CalendarView is a view group that displays
    child views in relative positions.

    """
    #: Selected date
    date = d_(Instance(datetime))

    #: Max date
    max_date = d_(Instance(datetime))

    #: Min date
    min_date = d_(Instance(datetime))

    #: First day of week
    first_day_of_week = d_(Range(1, 7))

    #: A reference to the ProxyLabel object.
    proxy = Typed(ProxyCalendarView)

    # -------------------------------------------------------------------------
    # Observers
    # -------------------------------------------------------------------------
    @observe('date', 'max_date', 'min_date', 'first_day_of_week')
    def _update_proxy(self, change):
        """ An observer which sends the state change to the proxy.

        """
        # The superclass implementation is sufficient.
        super(CalendarView, self)._update_proxy(change)
Beispiel #11
0
class Border(Atom):
    """ A class for defining a border on a Frame.

    Border instances should be treated as read-only once created.

    """
    #: The style of the border.
    style = Enum('box', 'panel', 'styled_panel')

    #: The shadow style applied to the border.
    line_style = Enum('plain', 'sunken', 'raised')

    #: The thickness of the outer border line.
    line_width = Range(low=0, value=1)

    #: The thickness of the inner border line. This only has an effect
    #: for the 'sunken' and 'raised' line styles.
    midline_width = Range(low=0, value=0)
Beispiel #12
0
class Image(SQLModel):
    name = Str().tag(length=100)
    path = Str().tag(length=200)
    metadata = Typed(dict).tag(nullable=True)
    alpha = Range(low=0, high=255)
    data = Instance(bytes).tag(nullable=True)

    # Maps to sa.ARRAY, must include the item_type tag
    # size = Tuple(int).tag(nullable=True)

    #: Maps to sa.JSON
    info = Instance(ImageInfo, ())
class Person(Atom):
    """ A simple class representing a person object.

    """
    last_name = Unicode()

    first_name = Unicode()

    age = Range(low=0)

    debug = Bool(False)

    def __repr__(self, *args, **kwargs):
        return "Person(first_name={p.first_name},last_name={p.last_name})".format(p=self)
Beispiel #14
0
class Polygon(Polyline):
    """ A polyline that follows points on a circle of a given inscribed or
    circumscribed radius.

    Attributes
    ----------
    radius: Float
        Radius of the polygon
    count: Int
        Number of points in the polygon, must be 3 or more.
    inscribed: Bool
        Whether the radius should be interpreted as an "inscribed" or
        "circumscribed" radius. The default is "circumscribed" meaning the
        points will be on the given radius (inside the circle). If
        `inscribed=True` then the midpoint of each segment will be on the
        circle of the given radius (outside the circle).

    Examples
    ---------

    Wire:
        Polygon: # A hexagon of radius 6
            radius = 4
            count = 6

    """
    #: This is fixed
    closed = True

    #: Radius is inscribed
    inscribed = d_(Bool())

    #: Radius of the polygon
    radius = d_(Float(1, strict=False)).tag(view=True)

    #: Number of points
    count = d_(Range(low=3)).tag(view=True)

    @observe('radius', 'inscribed', 'count')
    def _update_points(self, change):
        self.points = self._default_points()

    def _default_points(self):
        n = self.count
        r = self.radius
        a = 2 * pi / n
        if self.inscribed:
            r /= cos(pi / n)
        return [Pt(x=cos(i*a)*r, y=sin(i*a)*r) for i in range(n)]
Beispiel #15
0
class Transition(Atom):
    """ An object representing an animated transition.

    Once a transition is created, it should be considered read-only.

    """
    #: The type of transition effect to use.
    type = Enum('slide', 'wipe', 'iris', 'fade', 'crossfade')

    #: The direction of the transition effect. Some transition types
    #: will ignore the direction if it doesn't apply to the effect.
    direction = Enum('left_to_right', 'right_to_left', 'top_to_bottom',
                     'bottom_to_top')

    #: The duration of the transition, in milliseconds.
    duration = Range(low=0, value=250)
Beispiel #16
0
class Person(Atom):

    last_name = Unicode()
    first_name = Unicode()
    age = Range(low=0)
    debug = Bool(False)

    @observe('age')
    def debug_print(self, change):
        """ Prints out a debug message whenever the person's age changes.

        """
        if self.debug:
            templ = "{first} {last} is {age} years old."
            s = templ.format(
                first=self.first_name, last=self.last_name, age=self.age,
            )
            print(s)
Beispiel #17
0
class SplitItem(Widget):
    """ A widget which can be used as an item in a Splitter.

    A SplitItem is a widget which can be used as a child of a Splitter
    widget. It can have at most a single child widget which is an
    instance of Container.

    """
    #: The stretch factor for this item. The stretch factor determines
    #: how much an item is resized relative to its neighbors when the
    #: splitter space is allocated.
    stretch = d_(Range(low=0, value=1))

    #: Whether or not the item can be collapsed to zero width by the
    #: user. This holds regardless of the minimum size of the item.
    collapsible = d_(Bool(True))

    #: This is a deprecated attribute. It should no longer be used.
    preferred_size = d_(Value())

    #: A reference to the ProxySplitItem object.
    proxy = Typed(ProxySplitItem)

    def split_widget(self):
        """ Get the split widget defined on the item.

        The split widget is the last child Container.

        """
        for child in reversed(self.children):
            if isinstance(child, Container):
                return child

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('stretch', 'collapsible')
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.

        """
        # The superclass handler implementation is sufficient.
        super(SplitItem, self)._update_proxy(change)
Beispiel #18
0
class Person(Atom):
    """A simple class representing a person object."""

    name = Str()

    age = Range(low=0)

    dog = Typed(Dog, ())

    def _observe_age(self, change):
        print("Age changed: {0}".format(change["value"]))

    @observe("name")
    def any_name_i_want(self, change):
        print("Name changed: {0}".format(change["value"]))

    @observe("dog.name")
    def another_random_name(self, change):
        print("Dog name changed: {0}".format(change["value"]))
Beispiel #19
0
class Person(Atom):
    """ A simple class representing a person object.

    """
    name = Unicode()

    age = Range(low=0)

    dog = Typed(Dog, ())

    def _observe_age(self, change):
        print('Age changed: {0}'.format(change['value']))

    @observe('name')
    def any_name_i_want(self, change):
        print('Name changed: {0}'.format(change['value']))

    @observe('dog.name')
    def another_random_name(self, change):
        print('Dog name changed: {0}'.format(change['value']))
Beispiel #20
0
class GetLastModel(Atom):
    """Class that defines the model for the 'get last N datasets view'

    Attributes
    ----------
    num_to_retrieve : range, min=1
    headers : list
    selected : metadatastore.api.Document
    """
    num_to_retrieve = Range(low=1)
    search_info = Str()
    headers = List()
    connection_is_active = Bool(False)
    summary_visible = Bool(False)
    header = Typed(Document)

    def __init__(self):
        with self.suppress_notifications():
            self.header = None

    @observe('num_to_retrieve')
    def num_changed(self, changed):
        try:
            self.headers = DataBroker[-self.num_to_retrieve:]
        except ConnectionError:
            self.search_info = "Database [[{}]] not available on [[{}]]".format(
                metadatastore.conf.mds_config['database'],
                metadatastore.conf.mds_config['host'])
            self.connection_is_active = False
            return
        except AutoReconnect:
            self.search_info = (
                "Connection to database [[{}]] on [[{}]] was lost".format(
                    metadatastore.conf.mds_config['database'],
                    metadatastore.conf.mds_config['host']))
            self.connection_is_active = False
            return
        self.search_info = "Requested: {}. Found: {}".format(
            self.num_to_retrieve, len(self.headers))
Beispiel #21
0
class Spacer(Atom):
    """ A base class for creating constraint spacers.

    """
    #: The amount of space to apply for this spacer, in pixels.
    size = Range(low=0)

    #: The optional strength to apply to the spacer constraints.
    strength = StrengthMember()

    def __init__(self, size, strength=None):
        """ Initialize a Spacer.

        Parameters
        ----------
        size : int
            The basic size of the spacer, in pixels >= 0.

        strength : strength-like, optional
            A strength to apply to the generated spacer constraints.

        """
        self.size = size
        self.strength = strength

    def __or__(self, strength):
        """ Override the strength of the generated constraints.

        Parameters
        ----------
        strength : strength-like
            The strength to apply to the generated constraints.

        Returns
        -------
        result : self
            The current spacer instance.

        """
        self.strength = strength
        return self

    def when(self, switch):
        """ A simple switch method to toggle a spacer.

        Parameters
        ----------
        switch : bool
            Whether or not the spacer should be active.

        Returns
        -------
        result : self or None
            The current instance if the switch is True, None otherwise.

        """
        return self if switch else None

    def create_constraints(self, first, second):
        """ Generate the spacer constraints for the given anchors.

        Parameters
        ----------
        first : LinearSymbolic
            A linear symbolic representing the first constraint anchor.

        second : LinearSymbolic
            A linear symbolic representing the second constraint anchor.

        Returns
        -------
        result : list
            The list of constraints for the spacer.

        """
        cns = self.constraints(first, second)
        strength = self.strength
        if strength is not None:
            cns = [cn | strength for cn in cns]
        return cns

    def constraints(self, first, second):
        """ Generate the spacer constraints for the given anchors.

        This abstract method which must be implemented by subclasses.

        Parameters
        ----------
        first : LinearSymbolic
            A linear symbolic representing the first constraint anchor.

        second : LinearSymbolic
            A linear symbolic representing the second constraint anchor.

        Returns
        -------
        result : list
            The list of constraints for the spacer.

        """
        raise NotImplementedError
Beispiel #22
0

def test_no_op_handler():
    """Test the NoOp handler."""
    class A(Atom):
        v = Member()

    assert A.v.default_value_mode[0] == DefaultValue.NoOp
    assert A().v is None


@pytest.mark.parametrize(
    "member, expected",
    [
        (Value(1), 1),
        (Range(0), 0),
        (Range(high=0), 0),
        (Range(0, value=1), 1),
        (FloatRange(0.0), 0.0),
        (FloatRange(high=0.0), 0.0),
        (FloatRange(0.0, value=1.0), 1.0),
        (Subclass(float), float),
        (ForwardSubclass(lambda: float), float),
    ],
)
def test_static_handler(member, expected):
    """Test a static handler."""
    class StaticTest(Atom):
        v = member

    mode = (DefaultValue.MemberMethod_Object if isinstance(
Beispiel #23
0
class GridHelper(BoxHelper):
    """ A box helper for creating a traditional grid layout.

    A grid helper is constrainable and can be nested in other grid
    and box helpers to build up complex layouts.

    """
    #: The tuple of row items for the grid.
    rows = Tuple()

    #: The name of constraint variable to align items in a row.
    row_align = Str()

    #: The spacing between consecutive rows in the grid.
    row_spacing = Range(low=0)

    #: The name of constraint variable to align items in a column.
    column_align = Str()

    #: The spacing between consecutive columns in the grid.
    column_spacing = Range(low=0)

    #: The margins to add around boundary of the grid.
    margins = Coerced(Box)

    class _Cell(Atom):
        """ A private class used by a GridHelper to track item cells.

        """
        #: The item contained in the cell.
        item = Value()

        #: The starting row of the cell, inclusive.
        start_row = Int()

        #: The starting column of the cell, inclusive.
        start_column = Int()

        #: The ending row of the cell, inclusive.
        end_row = Int()

        #: The ending column of the cell, inclusive.
        end_column = Int()

        def __init__(self, item, row, column):
            """ Initialize a Cell.

            Parameters
            ----------
            item : object
                The item contained in the cell.

            row : int
                The row index of the cell.

            column : int
                The column index of the cell.

            """
            self.item = item
            self.start_row = row
            self.start_column = column
            self.end_row = row
            self.end_column = column

        def expand_to(self, row, column):
            """ Expand the cell to enclose the given row and column.

            """
            self.start_row = min(row, self.start_row)
            self.end_row = max(row, self.end_row)
            self.start_column = min(column, self.start_column)
            self.end_column = max(column, self.end_column)

    def __init__(self, rows, **config):
        """ Initialize a GridHelper.

        Parameters
        ----------
        rows: iterable of iterable
            The rows to layout in the grid. A row must be composed of
            constrainable objects and None. An item will be expanded
            to span all of the cells in which it appears.

        **config
            Configuration options for how this helper should behave.
            The following options are currently supported:

            row_align
                A string which is the name of a constraint variable on
                an item. If given, it is used to add constraints on the
                alignment of items in a row. The constraints will only
                be applied to items that do not span rows.

            row_spacing
                An integer >= 0 which indicates how many pixels of
                space should be placed between rows in the grid. The
                default value is 10 pixels.

            column_align
                A string which is the name of a constraint variable on
                a item. If given, it is used to add constraints on the
                alignment of items in a column. The constraints will
                only be applied to items that do not span columns.

            column_spacing
                An integer >= 0 which indicates how many pixels of
                space should be placed between columns in the grid.
                The default is the value is 10 pixels.

            margins
                A int, tuple of ints, or Box of ints >= 0 which
                indicate how many pixels of margin to add around
                the bounds of the grid. The default value is 0
                pixels on all sides.

        """
        self.rows = self.validate(rows)
        self.row_align = config.get('row_align', '')
        self.column_align = config.get('col_align', '')  # backwards compat
        self.column_align = config.get('column_align', '')
        self.row_spacing = config.get('row_spacing', 10)
        self.column_spacing = config.get('column_spacing', 10)
        self.margins = config.get('margins', 0)

    @staticmethod
    def validate(rows):
        """ Validate the rows for the grid helper.

        This method asserts that the rows are composed entirely of
        Constrainable objects and None.

        Parameters
        ----------
        rows : iterable of iterable
            The iterable of row items to validate.

        Returns
        -------
        result : tuple of tuple
            The tuple of validated rows.

        """
        valid_rows = []
        for row in rows:
            for item in row:
                if item is not None and not isinstance(item, Constrainable):
                    msg = 'Grid items must be Constrainable or None. '
                    msg += 'Got %r instead.'
                    raise TypeError(msg % item)
            valid_rows.append(tuple(row))
        return tuple(valid_rows)

    def constraints(self, component):
        """ Generate the grid constraints for the given component.

        Parameters
        ----------
        component : Constrainable or None
            The constrainable object which represents the conceptual
            owner of the generated constraints.

        Returns
        -------
        result : list
            The list of Constraint objects for the given component.

        """
        # Create the outer boundary box constraints.
        cns = self.box_constraints(component)

        # Compute the cell spans for the items in the grid.
        cells = []
        cell_map = {}
        num_cols = 0
        num_rows = len(self.rows)
        for row_idx, row in enumerate(self.rows):
            num_cols = max(num_cols, len(row))
            for col_idx, item in enumerate(row):
                if item is None:
                    continue
                elif item in cell_map:
                    cell_map[item].expand_to(row_idx, col_idx)
                else:
                    cell = self._Cell(item, row_idx, col_idx)
                    cell_map[item] = cell
                    cells.append(cell)

        # Create the row and column variables and their default limits.
        row_vars = []
        col_vars = []
        for idx in xrange(num_rows + 1):
            var = kiwi.Variable('row%d' % idx)
            row_vars.append(var)
            cns.append(var >= 0)
        for idx in xrange(num_cols + 1):
            var = kiwi.Variable('col%d' % idx)
            col_vars.append(var)
            cns.append(var >= 0)

        # Add the neighbor constraints for the row and column vars.
        for r1, r2 in zip(row_vars[:-1], row_vars[1:]):
            cns.append(r1 <= r2)
        for c1, c2 in zip(col_vars[:-1], col_vars[1:]):
            cns.append(c1 <= c2)

        # Setup the initial interior bounding box for the grid.
        firsts = (self.top, col_vars[-1], row_vars[-1], self.left)
        seconds = (row_vars[0], self.right, self.bottom, col_vars[0])
        for size, first, second in zip(self.margins, firsts, seconds):
            cns.extend(EqSpacer(size).create_constraints(first, second))

        # Setup the spacer lists for constraining the cell items
        row_spacer = FlexSpacer(self.row_spacing / 2)  # floor division
        col_spacer = FlexSpacer(self.column_spacing / 2)
        rspace = [row_spacer] * len(row_vars)
        cspace = [col_spacer] * len(col_vars)
        rspace[0] = rspace[-1] = cspace[0] = cspace[-1] = 0

        # Create the helpers for each constrainable grid cell item. The
        # helper validation is bypassed since the items are known-valid.
        helpers = []
        for cell in cells:
            sr = cell.start_row
            er = cell.end_row + 1
            sc = cell.start_column
            ec = cell.end_column + 1
            item = cell.item
            ritems = (row_vars[sr], rspace[sr], item, rspace[er], row_vars[er])
            citems = (col_vars[sc], cspace[sc], item, cspace[ec], col_vars[ec])
            rhelper = SequenceHelper('bottom', 'top', ())
            chelper = SequenceHelper('right', 'left', ())
            rhelper.items = ritems
            chelper.items = citems
            helpers.extend((rhelper, chelper))
            if isinstance(item, ConstraintHelper):
                helpers.append(item)

        # Add the row alignment helpers if needed. This will only create
        # the helpers for items which do not span multiple rows.
        anchor = self.row_align
        if anchor:
            row_map = defaultdict(list)
            for cell in cells:
                if cell.start_row == cell.end_row:
                    row_map[cell.start_row].append(cell.item)
            for items in row_map.itervalues():
                if len(items) > 1:
                    helper = SequenceHelper(anchor, anchor, (), 0)
                    helper.items = tuple(items)
                    helpers.append(helper)

        # Add the column alignment helpers if needed. This will only
        # create the helpers for items which do not span multiple rows.
        anchor = self.column_align
        if anchor:
            col_map = defaultdict(list)
            for cell in cells:
                if cell.start_column == cell.end_column:
                    col_map[cell.start_column].append(cell.item)
            for items in col_map.itervalues():
                if len(items) > 1:
                    helper = SequenceHelper(anchor, anchor, (), 0)
                    helper.items = tuple(items)
                    helpers.append(helper)

        # Generate the constraints from the helpers.
        for helper in helpers:
            cns.extend(helper.create_constraints(None))

        return cns
Beispiel #24
0
class JobInfo(Model):
    """ Job metadata """
    #: Controls
    done = Bool()
    cancelled = Bool()
    paused = Bool()

    #: Flags
    status = Enum('staged', 'waiting', 'running', 'error', 'approved',
                  'cancelled', 'complete').tag(config=True)

    #: Stats
    started = Instance(datetime).tag(config=True)
    ended = Instance(datetime).tag(config=True)
    progress = Range(0, 100, 0).tag(config=True)
    data = Unicode().tag(config=True)
    count = Int().tag(config=True)

    #: Device speed in px/s
    speed = Float(strict=False).tag(config=True)
    #: Length in px
    length = Float(strict=False).tag(config=True)

    #: Estimates based on length and speed
    duration = Instance(timedelta, ()).tag(config=True)

    #: Units
    units = Enum('in', 'cm', 'm', 'ft').tag(config=True)

    #: Callback to open the approval dialog
    auto_approve = Bool().tag(config=True)
    request_approval = Callable()

    def _default_request_approval(self):
        """ Request approval using the current job """
        from inkcut.core.workbench import InkcutWorkbench
        workbench = InkcutWorkbench.instance()
        plugin = workbench.get_plugin("inkcut.job")
        return lambda: plugin.request_approval(plugin.job)

    def reset(self):
        """ Reset to initial states"""
        #: TODO: This is a stupid design
        self.progress = 0
        self.paused = False
        self.cancelled = False
        self.done = False
        self.status = 'staged'

    def _observe_done(self, change):
        if change['type'] == 'update':
            #: Increment count every time it's completed
            if self.done:
                self.count += 1

    @observe('length', 'speed')
    def _update_duration(self, change):
        if not self.length or not self.speed:
            self.duration = timedelta()
            return
        dt = self.length / self.speed
        self.duration = timedelta(seconds=dt)
Beispiel #25
0
    for value in (1, 1.0, '', [], {}):
        assert m.do_validate(a, None, value) == value


@pytest.mark.parametrize("member, set_values, values, raising_values", [
    (Value(), ['a', 1, None], ['a', 1, None], []),
    (Bool(), [True, False], [True, False], 'r'),
    (Int(strict=True), [1], [1], [1.0, long(1)] if sys.version_info <
     (3, ) else [1.0]),
    (Int(strict=False), [1, 1.0, long(1)
                         ], 3 * [1], ['a'] + [] if sys.version_info >=
     (3, ) else [1.0e35]),
    (Long(strict=True), [long(1)], [long(1)], [1.0, 1] if sys.version_info <
     (3, ) else [0.1]),
    (Long(strict=False), [1, 1.0, int(1)], 3 * [1], ['a']),
    (Range(0, 2), [0, 2], [0, 2], [-1, 3, '']),
    (Range(2, 0), [0, 2], [0, 2], [-1, 3]),
    (Range(0), [0, 3], [0, 3], [-1]),
    (Range(high=2), [-1, 2], [-1, 2], [3]),
    (Float(), [1, int(1), 1.1], [1.0, 1.0, 1.1], ['']),
    (Float(strict=True), [1.1], [1.1], [1]),
    (FloatRange(0.0, 0.5), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]),
    (FloatRange(0.5, 0.0), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]),
    (FloatRange(0.0), [0.0, 0.6], [0.0, 0.6], [-0.1, '']),
    (FloatRange(high=0.5), [-0.3, 0.5], [-0.3, 0.5], [0.6]),
    (Bytes(), [b'a', u'a'], [b'a'] * 2, [1]),
    (Bytes(strict=True), [b'a'], [b'a'], [u'a']),
    (Str(), [b'a', u'a'], ['a'] * 2, [1]),
    (Str(strict=True), [b'a'] if sys.version_info <
     (3, ) else [u'a'], ['a'], [u'a'] if sys.version_info < (3, ) else [b'a']),
    (Unicode(), [b'a', u'a'], [u'a'] * 2, [1]),
Beispiel #26
0
class Slider(Control):
    """ A simple slider widget that can be used to select from a range
    of integral values.

    A `SliderTransform` can be used to transform the integer range
    of the slider into another data space. For more details, see
    `enaml.stdlib.slider_transform`.

    """
    #: The minimum slider value. If the minimum value is changed such
    #: that it becomes greater than the current value or the maximum
    #: value, then those values will be adjusted. The default is 0.
    minimum = d_(Int(0))

    #: The maximum slider value. If the maximum value is changed such
    #: that it becomes smaller than the current value or the minimum
    #: value, then those values will be adjusted. The default is 100.
    maximum = d_(Int(100))

    #: The position value of the Slider. The value will be clipped to
    #: always fall between the minimum and maximum.
    value = d_(Int(0))

    #: Defines the number of steps that the slider will move when the
    #: user presses the arrow keys. The default is 1. An upper limit
    #: may be imposed according the limits of the client widget.
    single_step = d_(Range(low=1))

    #: Defines the number of steps that the slider will move when the
    #: user presses the page_up/page_down keys. The Default is 10. An
    #: upper limit may be imposed on this value according to the limits
    #: of the client widget.
    page_step = d_(Range(low=1, value=10))

    #: A TickPosition enum value indicating how to display the tick
    #: marks. Note that the orientation takes precedence over the tick
    #: mark position and an incompatible tick position will be adapted
    #: according to the current orientation. The default tick position
    #: is 'bottom'.
    tick_position = d_(TickPosition('bottom'))

    #: The interval to place between slider tick marks in units of
    #: value (as opposed to pixels). The minimum value is 0, which
    #: indicates that the choice is left up to the client.
    tick_interval = d_(Range(low=0))

    #: The orientation of the slider. The default orientation is
    #: horizontal. When the orientation is flipped the tick positions
    #: (if set) also adapt to reflect the changes  (e.g. the LEFT
    #: becomes TOP when the orientation becomes horizontal).
    orientation = d_(Enum('horizontal', 'vertical'))

    #: If True, the value is updated while sliding. Otherwise, it is
    #: only updated when the slider is released. Defaults to True.
    tracking = d_(Bool(True))

    #: Whether or not to automatically adjust the 'hug_width' and
    #: 'hug_height' values based on the value of 'orientation'.
    auto_hug = d_(Bool(True))

    #: A reference to the ProxySlider object.
    proxy = Typed(ProxySlider)

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('minimum', 'maximum', 'value', 'single_step', 'page_step',
             'tick_position', 'tick_interval', 'orientation', 'tracking')
    def _update_proxy(self, change):
        """ An observer which sends state change to the proxy.

        """
        # The superclass handler implementation is sufficient.
        super(Slider, self)._update_proxy(change)

    #--------------------------------------------------------------------------
    # DefaultValue Handlers
    #--------------------------------------------------------------------------
    def _default_hug_width(self):
        """ Get the default hug width for the separator.

        The default hug width is computed based on the orientation.

        """
        if self.orientation == 'horizontal':
            return 'ignore'
        return 'strong'

    def _default_hug_height(self):
        """ Get the default hug height for the separator.

        The default hug height is computed based on the orientation.

        """
        if self.orientation == 'vertical':
            return 'ignore'
        return 'strong'

    #--------------------------------------------------------------------------
    # PostSetAttr Handlers
    #--------------------------------------------------------------------------
    def _post_setattr_orientation(self, old, new):
        """ Post setattr the orientation for the tool bar.

        If auto hug is enabled, the hug values will be updated.

        """
        if self.auto_hug:
            if new == 'vertical':
                self.hug_width = 'strong'
                self.hug_height = 'ignore'
            else:
                self.hug_width = 'ignore'
                self.hug_height = 'strong'

    def _post_setattr_minimum(self, old, new):
        """ Post setattr the minimum value for the slider.

        If the new minimum is greater than the current value or maximum,
        those values are adjusted up.

        """
        if new > self.maximum:
            self.maximum = new
        if new > self.value:
            self.value = new

    def _post_setattr_maximum(self, old, new):
        """ Post setattr the maximum value for the slider.

        If the new maximum is less than the current value or the minimum,
        those values are adjusted down.

        """
        if new < self.minimum:
            self.minimum = new
        if new < self.value:
            self.value = new

    #--------------------------------------------------------------------------
    # Post Validation Handlers
    #--------------------------------------------------------------------------
    def _post_validate_value(self, old, new):
        """ Post validate the value for the slider.

        The value is clipped to minimum and maximum bounds.

        """
        return max(self.minimum, min(new, self.maximum))
Beispiel #27
0
class DockItem(Widget):
    """ A widget which can be docked in a DockArea.

    A DockItem is a widget which can be docked inside of a DockArea. It
    can have at most a single Container child widget.

    """
    #: The title to use in the title bar.
    title = d_(Unicode())

    #: Whether or the not the title is user editable.
    title_editable = d_(Bool(False))

    #: Whether or not the title bar is visible.
    title_bar_visible = d_(Bool(True))

    #: The icon to use in the title bar.
    icon = d_(Typed(Icon))

    #: The size to use for the icon in the title bar.
    icon_size = d_(Coerced(Size, (-1, -1)))

    #: The stretch factor for the item when docked in a splitter.
    stretch = d_(Range(low=0, value=1))

    #: Whether or not the dock item is closable via a close button.
    closable = d_(Bool(True))

    #: An event emitted when the title bar is right clicked.
    title_bar_right_clicked = d_(Event(), writable=False)

    #: An event emitted when the dock item is closed. The item will be
    #: destroyed after this event has completed.
    closed = d_(Event(), writable=False)

    #: A reference to the ProxyDockItem object.
    proxy = Typed(ProxyDockItem)

    def dock_widget(self):
        """ Get the dock widget defined for the dock pane.

        The last child Container is considered the dock widget.

        """
        for child in reversed(self.children):
            if isinstance(child, Container):
                return child

    if os.environ.get('ENAML_DEPRECATED_DOCK_LAYOUT'):

        def split(self, direction, *names):
            """ This method is deprecated.

            """
            args = ('split_item', direction, self.name) + names
            self._call_parent('apply_layout_op', *args)

        def tabify(self, direction, *names):
            """ This method is deprecated.

            """
            args = ('tabify_item', direction, self.name) + names
            self._call_parent('apply_layout_op', *args)

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe(('title', 'title_editable', 'title_bar_visible', 'icon',
              'icon_size', 'stretch', 'closable'))
    def _update_proxy(self, change):
        """ Update the proxy when the item state changes.

        """
        # The superclass implementation is sufficient.
        super(DockItem, self)._update_proxy(change)

    #--------------------------------------------------------------------------
    # Private API
    #--------------------------------------------------------------------------
    def _item_closed(self):
        """ Called by the proxy when the toolkit item is closed.

        """
        # TODO allow the user to veto the close request
        self.closed()
        deferred_call(self.destroy)

    def _call_parent(self, name, *args, **kwargs):
        """ Call a parent method with the given name and arguments.

        """
        # Avoid a circular import
        from .dock_area import DockArea
        parent = self.parent
        if isinstance(parent, DockArea):
            getattr(parent, name)(*args, **kwargs)
Beispiel #28
0
class test(Atom):
    #Ints can have units, show_value, unit_factor and low/high limits
    t_int = Int().tag(unit="um",
                      show_value=True,
                      unit_factor=20,
                      low=0,
                      high=5)
    #Ints can be shown as spin boxes or int fields
    t_int_intfield = Int().tag(unit="um",
                               show_value=True,
                               unit_factor=20,
                               low=0,
                               high=5,
                               spec="intfield")
    #Coerced of basic types have same behavior as basic type, e.g. this coerced int acts like the Int above
    t_coerced_int = Coerced(int).tag(unit="um",
                                     show_value=True,
                                     unit_factor=20,
                                     low=0,
                                     high=5,
                                     spec="intfield")

    #ranges are represented with sliders
    t_range = Range(0, 5, 1)
    t_floatrange = FloatRange(0.0, 5.0, 1.0)
    #You can include other classes
    t_typed = Typed(subtest, ())
    t_instance = Instance(subtest, ())

    #lists
    t_list = List(default=[1.2, 1.3, 1.4])
    t_containerlist = ContainerList(default=[1.2, 1.3, 1.4]).tag(unit="um")

    #how to do a numpy array
    t_coerced_arr = Coerced(ndarray, coercer=array)  #.tag(private=7)

    #Floats can have units, show_value, unit_factor and low/high limits
    t_float = Float().tag(unit="GHz",
                          show_value=True,
                          unit_factor=0.2,
                          low=-1.0,
                          high=1)
    #A Bool demostrating the label functionality
    t_bool = Bool().tag(label="MY BOOL")

    #Unicode Field display
    t_unicode = Unicode("blah")

    #Unicode Multiline Field disply
    t_unicode_multiline = Unicode("blah").tag(spec="multiline")

    #unmapped Enum
    t_enum = Enum("one", "two", "three")

    #mapped Enum
    @property
    def t_enum_map_mapping(self):
        return dict(one=1, two=2, three=3)

    t_enum_map = Enum("one", "two", "three")

    #attribute mapped enum
    @property
    def t_enum_attr_mapping(self):
        return dict(t_int=self.t_int, t_float=self.t_float, t_bool=self.t_bool)

    t_enum_attr = Enum("t_int", "t_float", "t_bool").tag(map_type="attribute")

    #Note: extra run features (extra args, run lockout, abort) only function if chief is defined
    @Callable
    def a(self):
        from time import sleep
        log_debug("a_called")
        for n in range(5):
            log_debug(n)
            if self.abort:
                break
            sleep(0.4)
        log_debug("a_endded")

    @property
    def chief(self):
        return testchief

    @property
    def busy(self):
        return testchief.busy

    @property
    def abort(self):
        return testchief.abort
class StartingCondition(Atom):
    initial_capital_usd = Range(low=0)
    sell_threshold_percent = FloatRange(0.0, 100.0, 75.0)
    buy_momentum_days = Range(low=1)
Beispiel #30
0
class DockItem(Widget):
    """ A widget which can be docked in a DockArea.

    A DockItem is a widget which can be docked inside of a DockArea. It
    can have at most a single Container child widget.

    """
    #: The title to use in the title bar.
    title = d_(Unicode())

    #: Whether or the not the title is user editable.
    title_editable = d_(Bool(False))

    #: Whether or not the title bar is visible.
    title_bar_visible = d_(Bool(True))

    #: The icon to use in the title bar.
    icon = d_(Typed(Icon))

    #: The size to use for the icon in the title bar.
    icon_size = d_(Coerced(Size, (-1, -1)))

    #: The stretch factor for the item when docked in a splitter.
    stretch = d_(Range(low=0, value=1))

    #: Whether or not the dock item is closable via a close button.
    closable = d_(Bool(True))

    #: An event emitted when the title bar is right clicked.
    title_bar_right_clicked = d_(Event(), writable=False)

    #: An event fired when the user request the dock item to be closed.
    #: This will happen when the user clicks on the "X" button in the
    #: title bar button, or when the 'close' method is called. The
    #: payload will be a CloseEvent object which will allow code to
    #: veto the close event and prevent the item from closing.
    closing = d_(Event(CloseEvent), writable=False)

    #: An event emitted when the dock item is closed. The item will be
    #: destroyed after this event has completed.
    closed = d_(Event(), writable=False)

    #: A reference to the ProxyDockItem object.
    proxy = Typed(ProxyDockItem)

    def dock_widget(self):
        """ Get the dock widget defined for the dock pane.

        The last child Container is considered the dock widget.

        """
        for child in reversed(self.children):
            if isinstance(child, Container):
                return child

    def alert(self, level, on=250, off=250, repeat=4, persist=False):
        """ Set the alert level on the dock item.

        This will override any currently applied alert level.

        Parameters
        ----------
        level : unicode
            The alert level token to apply to the dock item.

        on : int
            The duration of the 'on' cycle, in ms. A value of -1 means
            always on.

        off : int
            The duration of the 'off' cycle, in ms. If 'on' is -1, this
            value is ignored.

        repeat : int
            The number of times to repeat the on-off cycle. If 'on' is
            -1, this value is ignored.

        persist : bool
            Whether to leave the alert in the 'on' state when the cycles
            finish. If 'on' is -1, this value is ignored.

        """
        if self.proxy_is_active:
            self.proxy.alert(level, on, off, repeat, persist)

    #--------------------------------------------------------------------------
    # Observers
    #--------------------------------------------------------------------------
    @observe('title', 'title_editable', 'title_bar_visible', 'icon',
             'icon_size', 'stretch', 'closable')
    def _update_proxy(self, change):
        """ Update the proxy when the item state changes.

        """
        # The superclass implementation is sufficient.
        super(DockItem, self)._update_proxy(change)

    #--------------------------------------------------------------------------
    # Private API
    #--------------------------------------------------------------------------
    def _item_closed(self):
        """ Called by the proxy when the toolkit item is closed.

        """
        # TODO allow the user to veto the close request
        self.closed()
        deferred_call(self.destroy)