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

WIP: Add help window to the _TimeViewer #7305

Merged
merged 12 commits into from
Feb 13, 2020
57 changes: 47 additions & 10 deletions mne/viz/_brain/_timeviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import time
import numpy as np
from ..utils import _show_help


class IntSlider(object):
Expand Down Expand Up @@ -209,6 +210,8 @@ def __init__(self, brain):
self.brain = brain
self.brain.time_viewer = self
self.plotter = brain._renderer.plotter
self.interactor = self.plotter.interactor
self.interactor.keyPressEvent = self.keyPressEvent

# orientation slider
orientation = [
Expand Down Expand Up @@ -397,17 +400,14 @@ def __init__(self, brain):
self.playback_speed = default_playback_speed
self.refresh_rate_ms = max(int(round(1000. / 60.)), 1)
self.plotter.add_callback(self.play, self.refresh_rate_ms)
self.plotter.add_key_event('space', self.toggle_playback)

# add toggle to show/hide interface
self.visibility = True
self.plotter.add_key_event('y', self.toggle_interface)

# apply auto-scaling action
self.plotter.add_key_event('t', self.apply_auto_scaling)

# restore user scaling action
self.plotter.add_key_event('u', self.restore_user_scaling)
# display help
self.help_actor = self.plotter.add_text(
text="Press ? to show help window"
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather not sacrifice this much (or really any) screen real estate for this:

Screenshot from 2020-02-13 09-33-22

If it's always ? in all of our plotters we can just document it in a tutorial and in docstrings.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... actually the intuitive way to do it without eating up screen real estate would be to add a Help->Show MNE key bindings... menu option at the top. If it's not too hard to do it it's a nice option

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or more completely / standardly, Help-> Show MNE key bindings... ? (with the ? in the right column of the menu item to indicate it's the shortcut)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion @larsoner. I'm on it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just need to find this code snippet I did not so long ago...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found it: #7200 (comment)


# set the slider style
self.set_slider_style(smoothing_slider)
Expand All @@ -418,8 +418,29 @@ def __init__(self, brain):
self.set_slider_style(playback_speed_slider)
self.set_slider_style(time_slider)

# setup key bindings
self.key_bindings = {
'?': self.help,
'y': self.toggle_interface,
't': self.apply_auto_scaling,
'u': self.restore_user_scaling,
' ': self.toggle_playback,
}

def keyPressEvent(self, event):
callback = self.key_bindings.get(event.text())
if callback is not None:
callback()

def toggle_interface(self):
self.visibility = not self.visibility

# manage help text
if self.visibility:
self.help_actor.VisibilityOn()
else:
self.help_actor.VisibilityOff()

# manage sliders
for slider in self.plotter.slider_widgets:
slider_rep = slider.GetRepresentation()
Expand Down Expand Up @@ -491,6 +512,24 @@ def set_slider_style(self, slider, show_label=True):
if not show_label:
slider_rep.ShowSliderLabelOff()

def help(self):
pairs = [
('?', 'Display help window'),
('y', 'Toggle interface'),
('t', 'Apply auto-scaling'),
('u', 'Restore original clim'),
('Space', 'Start/Pause playback'),
]
text1, text2 = zip(*pairs)
text1 = '\n'.join(text1)
text2 = '\n'.join(text2)
_show_help(
col1=text1,
col2=text2,
width=5,
height=2,
)


class _LinkViewer(object):
"""Class to link multiple _TimeViewer objects."""
Expand All @@ -515,9 +554,7 @@ def __init__(self, brains):

# link toggle to start/pause playback
for time_viewer in self.time_viewers:
plotter = time_viewer.plotter
plotter.clear_events_for_key('space')
plotter.add_key_event('space', self.toggle_playback)
time_viewer.key_bindings[' '] = self.toggle_playback

def set_time_point(self, value):
for time_viewer in self.time_viewers:
Expand Down
23 changes: 14 additions & 9 deletions mne/viz/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,19 +1235,13 @@ def _select_bads(event, params, bads):
return bads


def _onclick_help(event, params):
"""Draw help window."""
text, text2 = _get_help_text(params)

width, height = 9, 5

def _show_help(col1, col2, width, height):
fig_help = figure_nobar(figsize=(width, height), dpi=80)
fig_help.canvas.set_window_title('Help')
params['fig_help'] = fig_help

ax = fig_help.add_subplot(111)
celltext = [[c1, c2] for c1, c2 in zip(text.strip().split("\n"),
text2.strip().split("\n"))]
celltext = [[c1, c2] for c1, c2 in zip(col1.strip().split("\n"),
col2.strip().split("\n"))]
table = ax.table(cellText=celltext, loc="center", cellLoc="left")
table.auto_set_font_size(False)
table.set_fontsize(12)
Expand All @@ -1269,6 +1263,17 @@ def _onclick_help(event, params):
pass


def _onclick_help(event, params):
"""Draw help window."""
col1, col2 = _get_help_text(params)
params['fig_help'] = _show_help(
col1=col1,
col2=col2,
width=9,
height=5,
)


def _key_press(event):
"""Handle key press in dialog."""
import matplotlib.pyplot as plt
Expand Down