From a5e66419a1a1c6265676ba7ebda98d47a562fac6 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 21 Jan 2020 16:34:29 -0800 Subject: [PATCH 1/3] Make selection container titles more transparent and easier to work with. --- .../widgets/widget_selectioncontainer.py | 25 ++++++------------- .../controls/src/widget_selectioncontainer.ts | 14 +++++------ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/ipywidgets/widgets/widget_selectioncontainer.py b/ipywidgets/widgets/widget_selectioncontainer.py index d8642a8cde..9857616387 100644 --- a/ipywidgets/widgets/widget_selectioncontainer.py +++ b/ipywidgets/widgets/widget_selectioncontainer.py @@ -11,11 +11,12 @@ from .widget import register from .widget_core import CoreWidget from traitlets import Unicode, Dict, CInt, TraitError, validate +from .trait_types import TypedTuple class _SelectionContainer(Box, CoreWidget): """Base class used to display multiple child widgets.""" - _titles = Dict(help="Titles of the pages").tag(sync=True) + titles = TypedTuple(trait=Unicode(), help="Titles of the pages").tag(sync=True) selected_index = CInt( help="""The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected.""", allow_none=True @@ -39,33 +40,23 @@ def set_title(self, index, title): title : unicode New title """ - # JSON dictionaries have string keys, so we convert index to a string - index = str(int(index)) - self._titles[index] = title - self.send_state('_titles') + titles = list(self.titles) + titles[index] = title + self.titles = titles def get_title(self, index): - """Gets the title of a container pages. + """Gets the title of a container page. Parameters ---------- index : int Index of the container page """ - # JSON dictionaries have string keys, so we convert index to a string - index = str(int(index)) - if index in self._titles: - return self._titles[index] + if 0<=index this.update_selected_index() ); - this.listenTo(this.model, 'change:_titles', () => this.update_titles()); + this.listenTo(this.model, 'change:titles', () => this.update_titles()); } /** @@ -158,7 +158,7 @@ export class AccordionView extends DOMWidgetView { */ update_titles(): void { const collapsed = this.pWidget.collapseWidgets; - const titles = this.model.get('_titles'); + const titles = this.model.get('titles'); for (let i = 0; i < collapsed.length; i++) { if (titles[i] !== void 0) { collapsed[i].widget.title.label = titles[i]; @@ -188,7 +188,7 @@ export class AccordionView extends DOMWidgetView { // Placeholder widget to keep our position in the tab panel while we create the view. const accordion = this.pWidget; const placeholder = new Widget(); - placeholder.title.label = this.model.get('_titles')[index] || ''; + placeholder.title.label = this.model.get('titles')[index] || ''; accordion.addWidget(placeholder); return this.create_child_view(model) .then((view: DOMWidgetView) => { @@ -293,7 +293,7 @@ export class TabView extends DOMWidgetView { this ); this.listenTo(this.model, 'change:children', () => this.updateTabs()); - this.listenTo(this.model, 'change:_titles', () => this.updateTitles()); + this.listenTo(this.model, 'change:titles', () => this.updateTitles()); } /** @@ -339,7 +339,7 @@ export class TabView extends DOMWidgetView { */ addChildView(model: WidgetModel, index: number): Promise { // Placeholder widget to keep our position in the tab panel while we create the view. - const label = this.model.get('_titles')[index] || ''; + const label = this.model.get('titles')[index] || ''; const tabs = this.pWidget; const placeholder = new Widget(); placeholder.title.label = label; @@ -379,7 +379,7 @@ export class TabView extends DOMWidgetView { * Updates the tab page titles. */ updateTitles(): void { - const titles = this.model.get('_titles') || {}; + const titles = this.model.get('titles') || []; each(this.pWidget.widgets, (widget, i) => { widget.title.label = titles[i] || ''; }); From a392a3116b64ee00304052d63c6d91b302704614 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 21 Jan 2020 16:35:57 -0800 Subject: [PATCH 2/3] Update data spec for selection containers to reflect the new titles attribute --- packages/schema/jupyterwidgetmodels.latest.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/schema/jupyterwidgetmodels.latest.md b/packages/schema/jupyterwidgetmodels.latest.md index 4b75dd3c52..e8bda74fea 100644 --- a/packages/schema/jupyterwidgetmodels.latest.md +++ b/packages/schema/jupyterwidgetmodels.latest.md @@ -71,7 +71,6 @@ Attribute | Type | Default | Help `_model_module` | string | `'@jupyter-widgets/controls'` | `_model_module_version` | string | `'1.5.0'` | `_model_name` | string | `'AccordionModel'` | -`_titles` | object | `{}` | Titles of the pages `_view_module` | string | `'@jupyter-widgets/controls'` | `_view_module_version` | string | `'1.5.0'` | `_view_name` | string | `'AccordionView'` | @@ -80,6 +79,7 @@ Attribute | Type | Default | Help `layout` | reference to Layout widget | reference to new instance | `selected_index` | `null` or number (integer) | `0` | The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected. `tabbable` | `null` or boolean | `null` | Is widget tabbable? +`titles` | array of string | `[]` | Titles of the pages `tooltip` | `null` or string | `null` | A tooltip caption. ### AudioModel (@jupyter-widgets/controls, 1.5.0); AudioView (@jupyter-widgets/controls, 1.5.0) @@ -949,7 +949,6 @@ Attribute | Type | Default | Help `_model_module` | string | `'@jupyter-widgets/controls'` | `_model_module_version` | string | `'1.5.0'` | `_model_name` | string | `'StackedModel'` | -`_titles` | object | `{}` | Titles of the pages `_view_module` | string | `'@jupyter-widgets/controls'` | `_view_module_version` | string | `'1.5.0'` | `_view_name` | string | `'StackedView'` | @@ -958,6 +957,7 @@ Attribute | Type | Default | Help `layout` | reference to Layout widget | reference to new instance | `selected_index` | `null` or number (integer) | `0` | The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected. `tabbable` | `null` or boolean | `null` | Is widget tabbable? +`titles` | array of string | `[]` | Titles of the pages `tooltip` | `null` or string | `null` | A tooltip caption. ### TabModel (@jupyter-widgets/controls, 1.5.0); TabView (@jupyter-widgets/controls, 1.5.0) @@ -968,7 +968,6 @@ Attribute | Type | Default | Help `_model_module` | string | `'@jupyter-widgets/controls'` | `_model_module_version` | string | `'1.5.0'` | `_model_name` | string | `'TabModel'` | -`_titles` | object | `{}` | Titles of the pages `_view_module` | string | `'@jupyter-widgets/controls'` | `_view_module_version` | string | `'1.5.0'` | `_view_name` | string | `'TabView'` | @@ -977,6 +976,7 @@ Attribute | Type | Default | Help `layout` | reference to Layout widget | reference to new instance | `selected_index` | `null` or number (integer) | `0` | The index of the selected page. This is either an integer selecting a particular sub-widget, or None to have no widgets selected. `tabbable` | `null` or boolean | `null` | Is widget tabbable? +`titles` | array of string | `[]` | Titles of the pages `tooltip` | `null` or string | `null` | A tooltip caption. ### TextModel (@jupyter-widgets/controls, 1.5.0); TextView (@jupyter-widgets/controls, 1.5.0) From 91ba29df65b57a51dbd3cfefa195b78834aaff63 Mon Sep 17 00:00:00 2001 From: Jason Grout Date: Tue, 21 Jan 2020 16:59:01 -0800 Subject: [PATCH 3/3] Remove selection container set_title and get_title --- docs/source/examples/Widget List.ipynb | 10 ++----- .../widgets/widget_selectioncontainer.py | 28 ------------------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/docs/source/examples/Widget List.ipynb b/docs/source/examples/Widget List.ipynb index f28e03f1ba..e63cbe4cec 100644 --- a/docs/source/examples/Widget List.ipynb +++ b/docs/source/examples/Widget List.ipynb @@ -1223,9 +1223,7 @@ "metadata": {}, "outputs": [], "source": [ - "accordion = widgets.Accordion(children=[widgets.IntSlider(), widgets.Text()])\n", - "accordion.set_title(0, 'Slider')\n", - "accordion.set_title(1, 'Text')\n", + "accordion = widgets.Accordion(children=[widgets.IntSlider(), widgets.Text()], titles=('Slider', 'Text'))\n", "accordion" ] }, @@ -1248,8 +1246,7 @@ "children = [widgets.Text(description=name) for name in tab_contents]\n", "tab = widgets.Tab()\n", "tab.children = children\n", - "for i in range(len(children)):\n", - " tab.set_title(i, str(i))\n", + "tab.titles = [str(i) for i in range(len(children))]\n", "tab" ] }, @@ -1347,8 +1344,7 @@ "source": [ "tab_nest = widgets.Tab()\n", "tab_nest.children = [accordion, accordion]\n", - "tab_nest.set_title(0, 'An accordion')\n", - "tab_nest.set_title(1, 'Copy of the accordion')\n", + "tab_nest.titles = ('An accordion', 'Copy of the accordion')\n", "tab_nest" ] }, diff --git a/ipywidgets/widgets/widget_selectioncontainer.py b/ipywidgets/widgets/widget_selectioncontainer.py index 9857616387..385a3457ed 100644 --- a/ipywidgets/widgets/widget_selectioncontainer.py +++ b/ipywidgets/widgets/widget_selectioncontainer.py @@ -29,34 +29,6 @@ def _validated_index(self, proposal): else: raise TraitError('Invalid selection: index out of bounds') - # Public methods - def set_title(self, index, title): - """Sets the title of a container page. - - Parameters - ---------- - index : int - Index of the container page - title : unicode - New title - """ - titles = list(self.titles) - titles[index] = title - self.titles = titles - - def get_title(self, index): - """Gets the title of a container page. - - Parameters - ---------- - index : int - Index of the container page - """ - if 0<=index