Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: collapsible group box #10302

Merged
merged 10 commits into from
Feb 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions mne/gui/_coreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1290,10 +1290,17 @@ def _update_fiducials_label(self):
)

def _configure_dock(self):
if self._renderer._kind == 'notebook':
collapse = True # collapsible and collapsed
else:
collapse = None # not collapsible
self._renderer._dock_initialize(
name="Input", area="left", max_width="350px"
)
mri_subject_layout = self._renderer._dock_add_group_box("MRI Subject")
mri_subject_layout = self._renderer._dock_add_group_box(
name="MRI Subject",
collapse=collapse,
)
self._widgets["subjects_dir"] = self._renderer._dock_add_file_button(
name="subjects_dir",
desc="Load",
Expand All @@ -1316,7 +1323,8 @@ def _configure_dock(self):
)

mri_fiducials_layout = self._renderer._dock_add_group_box(
"MRI Fiducials"
name="MRI Fiducials",
collapse=collapse,
)
# Add MRI fiducials I/O widgets
self._widgets['mri_fiducials_label'] = self._renderer._dock_add_label(
Expand Down Expand Up @@ -1387,8 +1395,10 @@ def _configure_dock(self):
self._renderer._layout_add_widget(
mri_fiducials_layout, fiducial_coords_layout)

dig_source_layout = \
self._renderer._dock_add_group_box("Info source with digitization")
dig_source_layout = self._renderer._dock_add_group_box(
name="Info source with digitization",
collapse=collapse,
)
self._widgets["info_file"] = self._renderer._dock_add_file_button(
name="info_file",
desc="Load",
Expand Down Expand Up @@ -1431,8 +1441,10 @@ def _configure_dock(self):
)
self._renderer._layout_add_widget(dig_source_layout, omit_hsp_layout)

view_options_layout = \
self._renderer._dock_add_group_box("View Options")
view_options_layout = self._renderer._dock_add_group_box(
name="View Options",
collapse=collapse,
)
self._widgets["helmet"] = self._renderer._dock_add_check_box(
name="Show MEG helmet",
value=self._helmet,
Expand Down Expand Up @@ -1461,8 +1473,10 @@ def _configure_dock(self):
self._renderer._dock_initialize(
name="Parameters", area="right", max_width="350px"
)
mri_scaling_layout = \
self._renderer._dock_add_group_box(name="MRI Scaling")
mri_scaling_layout = self._renderer._dock_add_group_box(
name="MRI Scaling",
collapse=collapse,
)
self._widgets["scaling_mode"] = self._renderer._dock_add_combo_box(
name="Scaling Mode",
value=self._defaults["scale_mode"],
Expand Down Expand Up @@ -1529,7 +1543,9 @@ def _configure_dock(self):
self._renderer._layout_add_widget(
mri_scaling_layout, subject_to_layout)
param_layout = self._renderer._dock_add_group_box(
"Translation (t) and Rotation (r)")
name="Translation (t) and Rotation (r)",
collapse=collapse,
)
for coord in coords:
coord_layout = self._renderer._dock_add_layout(vertical=False)
for mode, mode_name in (("t", "Translation"), ("r", "Rotation")):
Expand Down Expand Up @@ -1571,7 +1587,9 @@ def _configure_dock(self):
)
self._renderer._layout_add_widget(param_layout, fit_layout)
trans_layout = self._renderer._dock_add_group_box(
"HEAD <> MRI Transform")
name="HEAD <> MRI Transform",
collapse=collapse,
)
save_trans_layout = self._renderer._dock_add_layout(vertical=False)
self._widgets["save_trans"] = self._renderer._dock_add_file_button(
name="save_trans",
Expand Down Expand Up @@ -1602,8 +1620,10 @@ def _configure_dock(self):
)
self._renderer._layout_add_widget(trans_layout, save_trans_layout)

fitting_options_layout = \
self._renderer._dock_add_group_box("Fitting Options")
fitting_options_layout = self._renderer._dock_add_group_box(
name="Fitting Options",
collapse=collapse,
)
self._widgets["fit_label"] = self._renderer._dock_add_label(
value="",
layout=fitting_options_layout,
Expand Down
3 changes: 2 additions & 1 deletion mne/gui/tests/test_gui_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ def _check_widget_trigger(widget, mock, before, after, call_count=True,

renderer._dock_initialize(name='', area='right')
renderer._dock_named_layout(name='')
renderer._dock_add_group_box(name='')
for collapse in (None, True, False):
renderer._dock_add_group_box(name='', collapse=collapse)
renderer._dock_add_stretch()
renderer._dock_add_layout()
renderer._dock_finalize()
Expand Down
2 changes: 1 addition & 1 deletion mne/viz/backends/_abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ def _dock_add_radio_buttons(self, value, rng, callback, *, vertical=True,
pass

@abstractmethod
def _dock_add_group_box(self, name, *, layout=None):
def _dock_add_group_box(self, name, *, collapse=None, layout=None):
pass

@abstractmethod
Expand Down
29 changes: 22 additions & 7 deletions mne/viz/backends/_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from IPython.display import display
from ipywidgets import (Button, Dropdown, FloatSlider, BoundedFloatText, HBox,
IntSlider, IntText, Text, VBox, IntProgress, Play,
Checkbox, RadioButtons, HTML, jsdlink)
Checkbox, RadioButtons, HTML, Accordion, jsdlink)

from ._abstract import (_AbstractDock, _AbstractToolBar, _AbstractMenuBar,
_AbstractStatusBar, _AbstractLayout, _AbstractWidget,
Expand All @@ -27,9 +27,13 @@ def _layout_add_widget(self, layout, widget, stretch=0):
widget.layout.margin = "2px 0px 2px 0px"
if not isinstance(widget, Play):
widget.layout.min_width = "0px"
children = list(layout.children)
if isinstance(layout, Accordion):
box = layout.children[0]
else:
box = layout
children = list(box.children)
children.append(widget)
layout.children = tuple(children)
box.children = tuple(children)
# Fix columns
if self._layout_max_width is not None and isinstance(widget, HBox):
children = widget.children
Expand Down Expand Up @@ -165,9 +169,19 @@ def _dock_add_radio_buttons(self, value, rng, callback, *, vertical=True,
self._layout_add_widget(layout, widget)
return _IpyWidgetList(widget)

def _dock_add_group_box(self, name, *, layout=None):
def _dock_add_group_box(self, name, *, collapse=None, layout=None):
layout = self._dock_layout if layout is None else layout
hlayout = VBox()
if collapse is None:
hlayout = VBox([HTML("<strong>" + name + "</strong>")])
else:
assert isinstance(collapse, bool)
vbox = VBox()
hlayout = Accordion([vbox])
hlayout.set_title(0, name)
if collapse:
hlayout.selected_index = None
else:
hlayout.selected_index = 0
self._layout_add_widget(layout, hlayout)
return hlayout

Expand Down Expand Up @@ -502,14 +516,15 @@ def _update(self):
if self.figure.display is not None:
self.figure.display.update_canvas()

def _create_default_tool_bar(self):
def _display_default_tool_bar(self):
self._tool_bar_load_icons()
self._tool_bar_initialize()
self._tool_bar_add_file_button(
name="screenshot",
desc="Take a screenshot",
func=self.screenshot,
)
display(self._tool_bar)

def show(self):
# menu bar
Expand All @@ -519,7 +534,7 @@ def show(self):
if self._tool_bar is not None:
display(self._tool_bar)
else:
self._create_default_tool_bar()
self._display_default_tool_bar()
# viewer
viewer = self.plotter.show(
jupyter_backend="ipyvtklink", return_viewer=True)
Expand Down
2 changes: 1 addition & 1 deletion mne/viz/backends/_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def func(button):
self._layout_add_widget(layout, group_layout)
return _QtWidgetList(group)

def _dock_add_group_box(self, name, *, layout=None):
def _dock_add_group_box(self, name, *, collapse=None, layout=None):
layout = self._dock_layout if layout is None else layout
hlayout = QVBoxLayout()
widget = QGroupBox(name)
Expand Down