Пример #1
0
    def _get_model(self, doc, root=None, parent=None, comm=None):
        if root is None:
            return self._get_root(doc, comm)

        if self.object is None:
            model = BkSpacer()
        else:
            model = self.object

        properties = {}
        for p, value in self.param.values().items():
            if (p not in Layoutable.param or p == 'name'
                    or value is self.param[p].default):
                continue
            properties[p] = value
        model.update(**properties)
        if comm:
            self._wrap_bokeh_callbacks(root, model, doc, comm)

        ref = root.ref['id']
        for js in model.select({'type': CustomJS}):
            js.code = js.code.replace(model.ref['id'], ref)

        if model._document and doc is not model._document:
            remove_root(model, doc)

        self._models[ref] = (model, parent)

        if self.theme:
            doc.theme = self.theme

        return model
Пример #2
0
    def _get_objects(self, model, old_objects, doc, root, comm=None):
        """
        Returns new child models for the layout while reusing unchanged
        models and cleaning up any dropped objects.
        """
        from .pane.base import RerenderError, panel
        new_models = []
        if len(self._names) != len(self):
            raise ValueError('Tab names do not match objects, ensure '
                             'that the Tabs.objects are not modified '
                             'directly. Found %d names, expected %d.' %
                             (len(self._names), len(self)))
        for i, (name, pane) in enumerate(zip(self._names, self)):
            pane = panel(pane, name=name)
            self.objects[i] = pane

        for obj in old_objects:
            if obj not in self.objects:
                obj._cleanup(root)

        current_objects = list(self)
        panels = self._panels[root.ref['id']]
        for i, (name, pane) in enumerate(zip(self._names, self)):
            hidden = self.dynamic and i != self.active
            if (pane in old_objects and id(pane) in panels and
                ((hidden and isinstance(panels[id(pane)].child, BkSpacer)) or
                 (not hidden
                  and not isinstance(panels[id(pane)].child, BkSpacer)))):
                panel = panels[id(pane)]
                new_models.append(panel)
                continue
            elif self.dynamic and i != self.active:
                child = BkSpacer(
                    **{
                        k: v
                        for k, v in pane.param.get_param_values()
                        if k in Layoutable.param
                    })
            else:
                try:
                    child = pane._get_model(doc, root, model, comm)
                except RerenderError:
                    return self._get_objects(model, current_objects[:i], doc,
                                             root, comm)
            panel = panels[id(pane)] = BkPanel(title=name,
                                               name=pane.name,
                                               child=child,
                                               closable=self.closable)
            new_models.append(panel)
        return new_models
Пример #3
0
    def _get_model(self, doc, root=None, parent=None, comm=None):
        model = self._bokeh_model()
        root = model if root is None else root
        objects = self._get_objects(model, [], doc, root, comm)

        # HACK ALERT: Insert Spacer if last item in Column has no height
        if (isinstance(self, Column) and objects and not has_height(objects[-1])):
            objects.append(BkSpacer(height=50))

        props = dict(self._init_properties(), objects=objects)
        model.update(**self._process_param_change(props))
        params = [p for p in self.params() if p != 'name']
        self._models[root.ref['id']] = model
        self._link_params(model, params, doc, root, comm)
        self._link_props(model, self._linked_props, doc, root, comm)
        return model
Пример #4
0
    def _get_objects(self, model, old_objects, doc, root, comm=None):
        """
        Returns new child models for the layout while reusing unchanged
        models and cleaning up any dropped objects.
        """
        from ..pane.base import RerenderError, panel
        new_models = []
        if len(self._names) != len(self):
            raise ValueError('Tab names do not match objects, ensure '
                             'that the Tabs.objects are not modified '
                             'directly. Found %d names, expected %d.' %
                             (len(self._names), len(self)))
        for i, (name, pane) in enumerate(zip(self._names, self)):
            pane = panel(pane, name=name)
            self.objects[i] = pane

        ref = root.ref['id']
        panels = self._panels[ref]
        rendered = self._rendered[ref]
        for obj in old_objects:
            if obj in self.objects:
                continue
            obj._cleanup(root)
            panels.pop(id(obj), None)
            rendered.pop(id(obj), None)

        current_objects = list(self)
        for i, (name, pane) in enumerate(zip(self._names, self)):
            pref = id(pane)
            hidden = self.dynamic and i != self.active
            panel = panels.get(pref)
            prev_hidden = (hasattr(panel, 'child')
                           and isinstance(panel.child, BkSpacer)
                           and panel.child.tags == ['hidden'])

            # If object has not changed, we have not toggled between
            # hidden and unhidden state or the tabs are not
            # dynamic then reuse the panel
            if (pane in old_objects and pref in panels
                    and (not (hidden ^ prev_hidden)
                         or not (self.dynamic or prev_hidden))):
                new_models.append(panel)
                continue

            if prev_hidden and not hidden and pref in rendered:
                child = rendered[pref]
            elif hidden:
                child = BkSpacer(
                    **{
                        k: v
                        for k, v in pane.param.values().items()
                        if k in Layoutable.param and v is not None
                    })
                child.tags = ['hidden']
            else:
                try:
                    rendered[pref] = child = pane._get_model(
                        doc, root, model, comm)
                except RerenderError:
                    return self._get_objects(model, current_objects[:i], doc,
                                             root, comm)

            panel = panels[pref] = BkPanel(title=name,
                                           name=pane.name,
                                           child=child,
                                           closable=self.closable)
            new_models.append(panel)
        return new_models
Пример #5
0
def Div(**kwargs):
    # Hack to work around issues with Div height in notebooks
    div = BkDiv(**kwargs)
    if 'height' in kwargs:
        return BkRow(div, BkSpacer(height=kwargs['height']))
    return div