Exemplo n.º 1
0
 def _calculate(self, a, b, t):
     _calculate = self._calculate
     if isinstance(a, list) or isinstance(a, tuple):
         if isinstance(a, list):
             tp = list
         else:
             tp = tuple
         return tp([_calculate(a[x], b[x], t) for x in range(len(a))])
     elif isinstance(a, dict):
         d = {}
         for x in iterkeys(a):
             if x not in b:
                 # User requested to animate only part of the dict.
                 # Copy the rest
                 d[x] = a[x]
             else:
                 d[x] = _calculate(a[x], b[x], t)
         return d
     else:
         return (a * (1. - t)) + (b * t)
Exemplo n.º 2
0
 def _calculate(self, a, b, t):
     _calculate = self._calculate
     if isinstance(a, list) or isinstance(a, tuple):
         if isinstance(a, list):
             tp = list
         else:
             tp = tuple
         return tp([_calculate(a[x], b[x], t) for x in range(len(a))])
     elif isinstance(a, dict):
         d = {}
         for x in iterkeys(a):
             if x not in b:
                 # User requested to animate only part of the dict.
                 # Copy the rest
                 d[x] = a[x]
             else:
                 d[x] = _calculate(a[x], b[x], t)
         return d
     else:
         return (a * (1. - t)) + (b * t)
Exemplo n.º 3
0
    def _apply_rule(self, widget, rule, rootrule, template_ctx=None,
                    ignored_consts=set()):
        # widget: the current instantiated widget
        # rule: the current rule
        # rootrule: the current root rule (for children of a rule)

        # will collect reference to all the id in children
        assert(rule not in self.rulectx)
        self.rulectx[rule] = rctx = {
            'ids': {'root': widget.proxy_ref},
            'set': [], 'hdl': []}

        # extract the context of the rootrule (not rule!)
        assert(rootrule in self.rulectx)
        rctx = self.rulectx[rootrule]

        # if a template context is passed, put it as "ctx"
        if template_ctx is not None:
            rctx['ids']['ctx'] = QueryDict(template_ctx)

        # if we got an id, put it in the root rule for a later global usage
        if rule.id:
            # use only the first word as `id` discard the rest.
            rule.id = rule.id.split('#', 1)[0].strip()
            rctx['ids'][rule.id] = widget.proxy_ref
            # set id name as a attribute for root widget so one can in python
            # code simply access root_widget.id_name
            _ids = dict(rctx['ids'])
            _root = _ids.pop('root')
            _new_ids = _root.ids
            for _key in iterkeys(_ids):
                if _ids[_key] == _root:
                    # skip on self
                    continue
                _new_ids[_key] = _ids[_key]
            _root.ids = _new_ids

        # first, ensure that the widget have all the properties used in
        # the rule if not, they will be created as ObjectProperty.
        rule.create_missing(widget)

        # build the widget canvas
        if rule.canvas_before:
            with widget.canvas.before:
                self._build_canvas(widget.canvas.before, widget,
                                   rule.canvas_before, rootrule)
        if rule.canvas_root:
            with widget.canvas:
                self._build_canvas(widget.canvas, widget,
                                   rule.canvas_root, rootrule)
        if rule.canvas_after:
            with widget.canvas.after:
                self._build_canvas(widget.canvas.after, widget,
                                   rule.canvas_after, rootrule)

        # create children tree
        Factory_get = Factory.get
        Factory_is_template = Factory.is_template
        for crule in rule.children:
            cname = crule.name

            if cname in ('canvas', 'canvas.before', 'canvas.after'):
                raise ParserException(
                    crule.ctx, crule.line,
                    'Canvas instructions added in kv must '
                    'be declared before child widgets.')

            # depending if the child rule is a template or not, we are not
            # having the same approach
            cls = Factory_get(cname)

            if Factory_is_template(cname):
                # we got a template, so extract all the properties and
                # handlers, and push them in a "ctx" dictionary.
                ctx = {}
                idmap = copy(global_idmap)
                idmap.update({'root': rctx['ids']['root']})
                if 'ctx' in rctx['ids']:
                    idmap.update({'ctx': rctx['ids']['ctx']})
                try:
                    for prule in crule.properties.values():
                        value = prule.co_value
                        if type(value) is CodeType:
                            value = eval(value, idmap)
                        ctx[prule.name] = value
                    for prule in crule.handlers:
                        value = eval(prule.value, idmap)
                        ctx[prule.name] = value
                except Exception as e:
                    tb = sys.exc_info()[2]
                    raise BuilderException(
                        prule.ctx, prule.line,
                        '{}: {}'.format(e.__class__.__name__, e), cause=tb)

                # create the template with an explicit ctx
                child = cls(**ctx)
                widget.add_widget(child)

                # reference it on our root rule context
                if crule.id:
                    rctx['ids'][crule.id] = child

            else:
                # we got a "normal" rule, construct it manually
                # we can't construct it without __no_builder=True, because the
                # previous implementation was doing the add_widget() before
                # apply(), and so, we could use "self.parent".
                child = cls(__no_builder=True)
                widget.add_widget(child)
                self.apply(child)
                self._apply_rule(child, crule, rootrule)

        # append the properties and handlers to our final resolution task
        if rule.properties:
            rctx['set'].append((widget.proxy_ref,
                                list(rule.properties.values())))
            for key, crule in rule.properties.items():
                # clear previously applied rules if asked
                if crule.ignore_prev:
                    Builder.unbind_property(widget, key)
        if rule.handlers:
            rctx['hdl'].append((widget.proxy_ref, rule.handlers))

        # if we are applying another rule that the root one, then it's done for
        # us!
        if rootrule is not rule:
            del self.rulectx[rule]
            return

        # normally, we can apply a list of properties with a proper context
        try:
            rule = None
            for widget_set, rules in reversed(rctx['set']):
                for rule in rules:
                    assert(isinstance(rule, ParserRuleProperty))
                    key = rule.name
                    value = rule.co_value
                    if type(value) is CodeType:
                        value, bound = create_handler(
                            widget_set, widget_set, key, value, rule,
                            rctx['ids'])
                        # if there's a rule
                        if (widget_set != widget or bound or
                                key not in ignored_consts):
                            setattr(widget_set, key, value)
                    else:
                        if (widget_set != widget or
                                key not in ignored_consts):
                            setattr(widget_set, key, value)

        except Exception as e:
            if rule is not None:
                tb = sys.exc_info()[2]
                raise BuilderException(rule.ctx, rule.line,
                                       '{}: {}'.format(e.__class__.__name__,
                                                       e), cause=tb)
            raise e

        # build handlers
        try:
            crule = None
            for widget_set, rules in rctx['hdl']:
                for crule in rules:
                    assert(isinstance(crule, ParserRuleProperty))
                    assert(crule.name.startswith('on_'))
                    key = crule.name
                    if not widget_set.is_event_type(key):
                        key = key[3:]
                    idmap = copy(global_idmap)
                    idmap.update(rctx['ids'])
                    idmap['self'] = widget_set.proxy_ref
                    if not widget_set.fbind(key, custom_callback, crule,
                                            idmap):
                        raise AttributeError(key)
                    # hack for on_parent
                    if crule.name == 'on_parent':
                        Factory.Widget.parent.dispatch(widget_set.__self__)
        except Exception as e:
            if crule is not None:
                tb = sys.exc_info()[2]
                raise BuilderException(
                    crule.ctx, crule.line,
                    '{}: {}'.format(e.__class__.__name__, e), cause=tb)
            raise e

        # rule finished, forget it
        del self.rulectx[rootrule]
Exemplo n.º 4
0
    def _apply_rule(self,
                    widget,
                    rule,
                    rootrule,
                    template_ctx=None,
                    ignored_consts=set()):
        # widget: the current instantiated widget
        # rule: the current rule
        # rootrule: the current root rule (for children of a rule)

        # will collect reference to all the id in children
        assert (rule not in self.rulectx)
        self.rulectx[rule] = rctx = {
            'ids': {
                'root': widget.proxy_ref
            },
            'set': [],
            'hdl': []
        }

        # extract the context of the rootrule (not rule!)
        assert (rootrule in self.rulectx)
        rctx = self.rulectx[rootrule]

        # if a template context is passed, put it as "ctx"
        if template_ctx is not None:
            rctx['ids']['ctx'] = QueryDict(template_ctx)

        # if we got an id, put it in the root rule for a later global usage
        if rule.id:
            # use only the first word as `id` discard the rest.
            rule.id = rule.id.split('#', 1)[0].strip()
            rctx['ids'][rule.id] = widget.proxy_ref
            # set id name as a attribute for root widget so one can in python
            # code simply access root_widget.id_name
            _ids = dict(rctx['ids'])
            _root = _ids.pop('root')
            _new_ids = _root.ids
            for _key in iterkeys(_ids):
                if _ids[_key] == _root:
                    # skip on self
                    continue
                _new_ids[_key] = _ids[_key]
            _root.ids = _new_ids

        # first, ensure that the widget have all the properties used in
        # the rule if not, they will be created as ObjectProperty.
        rule.create_missing(widget)

        # build the widget canvas
        if rule.canvas_before:
            with widget.canvas.before:
                self._build_canvas(widget.canvas.before, widget,
                                   rule.canvas_before, rootrule)
        if rule.canvas_root:
            with widget.canvas:
                self._build_canvas(widget.canvas, widget, rule.canvas_root,
                                   rootrule)
        if rule.canvas_after:
            with widget.canvas.after:
                self._build_canvas(widget.canvas.after, widget,
                                   rule.canvas_after, rootrule)

        # create children tree
        Factory_get = Factory.get
        Factory_is_template = Factory.is_template
        for crule in rule.children:
            cname = crule.name

            if cname in ('canvas', 'canvas.before', 'canvas.after'):
                raise ParserException(
                    crule.ctx, crule.line,
                    'Canvas instructions added in kv must '
                    'be declared before child widgets.')

            # depending if the child rule is a template or not, we are not
            # having the same approach
            cls = Factory_get(cname)

            if Factory_is_template(cname):
                # we got a template, so extract all the properties and
                # handlers, and push them in a "ctx" dictionary.
                ctx = {}
                idmap = copy(global_idmap)
                idmap.update({'root': rctx['ids']['root']})
                if 'ctx' in rctx['ids']:
                    idmap.update({'ctx': rctx['ids']['ctx']})
                try:
                    for prule in crule.properties.values():
                        value = prule.co_value
                        if type(value) is CodeType:
                            value = eval(value, idmap)
                        ctx[prule.name] = value
                    for prule in crule.handlers:
                        value = eval(prule.value, idmap)
                        ctx[prule.name] = value
                except Exception as e:
                    tb = sys.exc_info()[2]
                    raise BuilderException(prule.ctx,
                                           prule.line,
                                           '{}: {}'.format(
                                               e.__class__.__name__, e),
                                           cause=tb)

                # create the template with an explicit ctx
                child = cls(**ctx)
                widget.add_widget(child)

                # reference it on our root rule context
                if crule.id:
                    rctx['ids'][crule.id] = child

            else:
                # we got a "normal" rule, construct it manually
                # we can't construct it without __no_builder=True, because the
                # previous implementation was doing the add_widget() before
                # apply(), and so, we could use "self.parent".
                child = cls(__no_builder=True)
                widget.add_widget(child)
                self.apply(child)
                self._apply_rule(child, crule, rootrule)

        # append the properties and handlers to our final resolution task
        if rule.properties:
            rctx['set'].append(
                (widget.proxy_ref, list(rule.properties.values())))
            for key, crule in rule.properties.items():
                # clear previously applied rules if asked
                if crule.ignore_prev:
                    Builder.unbind_property(widget, key)
        if rule.handlers:
            rctx['hdl'].append((widget.proxy_ref, rule.handlers))

        # if we are applying another rule that the root one, then it's done for
        # us!
        if rootrule is not rule:
            del self.rulectx[rule]
            return

        # normally, we can apply a list of properties with a proper context
        try:
            rule = None
            for widget_set, rules in reversed(rctx['set']):
                for rule in rules:
                    assert (isinstance(rule, ParserRuleProperty))
                    key = rule.name
                    value = rule.co_value
                    if type(value) is CodeType:
                        value, bound = create_handler(widget_set, widget_set,
                                                      key, value, rule,
                                                      rctx['ids'])
                        # if there's a rule
                        if (widget_set != widget or bound
                                or key not in ignored_consts):
                            setattr(widget_set, key, value)
                    else:
                        if (widget_set != widget or key not in ignored_consts):
                            setattr(widget_set, key, value)

        except Exception as e:
            if rule is not None:
                tb = sys.exc_info()[2]
                raise BuilderException(rule.ctx,
                                       rule.line,
                                       '{}: {}'.format(e.__class__.__name__,
                                                       e),
                                       cause=tb)
            raise e

        # build handlers
        try:
            crule = None
            for widget_set, rules in rctx['hdl']:
                for crule in rules:
                    assert (isinstance(crule, ParserRuleProperty))
                    assert (crule.name.startswith('on_'))
                    key = crule.name
                    if not widget_set.is_event_type(key):
                        key = key[3:]
                    idmap = copy(global_idmap)
                    idmap.update(rctx['ids'])
                    idmap['self'] = widget_set.proxy_ref
                    if not widget_set.fbind(key, custom_callback, crule,
                                            idmap):
                        raise AttributeError(key)
                    #hack for on_parent
                    if crule.name == 'on_parent':
                        Factory.Widget.parent.dispatch(widget_set.__self__)
        except Exception as e:
            if crule is not None:
                tb = sys.exc_info()[2]
                raise BuilderException(crule.ctx,
                                       crule.line,
                                       '{}: {}'.format(e.__class__.__name__,
                                                       e),
                                       cause=tb)
            raise e

        # rule finished, forget it
        del self.rulectx[rootrule]