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)
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)
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))
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)
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)
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)
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)
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)
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
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)
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)
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)
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)]
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)
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)
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)
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"]))
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']))
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))
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
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(
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
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)
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]),
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))
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)
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)
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)