From 82e7bd648a730ed1ee4d7e1c9f4d2730ef33786a Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Mon, 10 Feb 2020 16:30:36 +0100 Subject: [PATCH 01/10] Add help window --- mne/viz/_brain/_timeviewer.py | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index d512c0b3955..fdb084428d7 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -6,6 +6,7 @@ import time import numpy as np +from ..utils import plt_show, figure_nobar class IntSlider(object): @@ -409,6 +410,12 @@ def __init__(self, brain): # 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 h to show help window" + ) + self.plotter.add_key_event('h', self.help) + # set the slider style self.set_slider_style(smoothing_slider) self.set_slider_style(fmin_slider) @@ -420,6 +427,13 @@ def __init__(self, brain): 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() @@ -491,6 +505,37 @@ def set_slider_style(self, slider, show_label=True): if not show_label: slider_rep.ShowSliderLabelOff() + def help(self): + shortcuts = { + 'h': 'Display help window', + 'y': 'Toggle interface', + 't': 'Apply auto-scaling', + 'u': 'Restore original clim', + 'Space': 'Start/Pause playback' + } + text = [str(s) + " : \n" for s in shortcuts.keys()] + text2 = [str(s) + "\n" for s in shortcuts.values()] + text, text2 = ''.join(text), ''.join(text2) + width, height = 9, 5 + + fig_help = figure_nobar(figsize=(width, height), dpi=80) + fig_help.canvas.set_window_title('Help') + + ax = fig_help.add_subplot(111) + celltext = [[c1, c2] for c1, c2 in zip(text.strip().split("\n"), + text2.strip().split("\n"))] + table = ax.table(cellText=celltext, loc="center", cellLoc="left") + table.auto_set_font_size(False) + table.set_fontsize(12) + ax.set_axis_off() + for (row, col), cell in table.get_celld().items(): + cell.set_edgecolor(None) # remove cell borders + if col == 0: + cell._loc = 'right' + + fig_help.canvas.draw() + plt_show(fig=fig_help, warn=False) + class _LinkViewer(object): """Class to link multiple _TimeViewer objects.""" From 711d75c9fd0297c474b935f80fb7972cb46da92a Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Tue, 11 Feb 2020 14:56:15 +0100 Subject: [PATCH 02/10] Update window size and refactor _show_help() --- mne/viz/_brain/_timeviewer.py | 27 +++++++-------------------- mne/viz/utils.py | 23 ++++++++++++++--------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index fdb084428d7..9dd5de5714d 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -6,7 +6,7 @@ import time import numpy as np -from ..utils import plt_show, figure_nobar +from ..utils import _show_help class IntSlider(object): @@ -516,25 +516,12 @@ def help(self): text = [str(s) + " : \n" for s in shortcuts.keys()] text2 = [str(s) + "\n" for s in shortcuts.values()] text, text2 = ''.join(text), ''.join(text2) - width, height = 9, 5 - - fig_help = figure_nobar(figsize=(width, height), dpi=80) - fig_help.canvas.set_window_title('Help') - - ax = fig_help.add_subplot(111) - celltext = [[c1, c2] for c1, c2 in zip(text.strip().split("\n"), - text2.strip().split("\n"))] - table = ax.table(cellText=celltext, loc="center", cellLoc="left") - table.auto_set_font_size(False) - table.set_fontsize(12) - ax.set_axis_off() - for (row, col), cell in table.get_celld().items(): - cell.set_edgecolor(None) # remove cell borders - if col == 0: - cell._loc = 'right' - - fig_help.canvas.draw() - plt_show(fig=fig_help, warn=False) + _show_help( + col1=text, + col2=text2, + width=5, + height=2, + ) class _LinkViewer(object): diff --git a/mne/viz/utils.py b/mne/viz/utils.py index 644c5106ab1..5328cfbb1cf 100644 --- a/mne/viz/utils.py +++ b/mne/viz/utils.py @@ -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) @@ -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 From c81964bd9f0225dddc8848c06e40d97041405e03 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Tue, 11 Feb 2020 15:28:17 +0100 Subject: [PATCH 03/10] Use tuple instead of dict --- mne/viz/_brain/_timeviewer.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index 9dd5de5714d..b2353c30083 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -506,18 +506,18 @@ def set_slider_style(self, slider, show_label=True): slider_rep.ShowSliderLabelOff() def help(self): - shortcuts = { - 'h': 'Display help window', - 'y': 'Toggle interface', - 't': 'Apply auto-scaling', - 'u': 'Restore original clim', - 'Space': 'Start/Pause playback' - } - text = [str(s) + " : \n" for s in shortcuts.keys()] - text2 = [str(s) + "\n" for s in shortcuts.values()] - text, text2 = ''.join(text), ''.join(text2) + pairs = [ + ('h', '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=text, + col1=text1, col2=text2, width=5, height=2, From b1e4db1daa5268851a58de9dbb79da1a4d34e8a5 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Wed, 12 Feb 2020 13:52:43 +0100 Subject: [PATCH 04/10] Refactor key bindings --- mne/viz/_brain/_timeviewer.py | 37 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index b2353c30083..f41a72fcd60 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -210,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 = [ @@ -398,23 +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 h to show help window" + text="Press ? to show help window" ) - self.plotter.add_key_event('h', self.help) # set the slider style self.set_slider_style(smoothing_slider) @@ -425,6 +418,24 @@ 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): + from PyQt5 import QtCore + if event.key() == QtCore.Qt.Key_Question: + self.help() + else: + callback = self.key_bindings.get(event.text()) + if callback is not None: + callback() + def toggle_interface(self): self.visibility = not self.visibility @@ -507,7 +518,7 @@ def set_slider_style(self, slider, show_label=True): def help(self): pairs = [ - ('h', 'Display help window'), + ('?', 'Display help window'), ('y', 'Toggle interface'), ('t', 'Apply auto-scaling'), ('u', 'Restore original clim'), @@ -547,9 +558,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: From f7339c5026778bd738597a439c8e34c6d267542f Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Wed, 12 Feb 2020 14:38:46 +0100 Subject: [PATCH 05/10] Refactor keyPressEvent --- mne/viz/_brain/_timeviewer.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index f41a72fcd60..e1a47cb8f44 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -428,13 +428,9 @@ def __init__(self, brain): } def keyPressEvent(self, event): - from PyQt5 import QtCore - if event.key() == QtCore.Qt.Key_Question: - self.help() - else: - callback = self.key_bindings.get(event.text()) - if callback is not None: - callback() + callback = self.key_bindings.get(event.text()) + if callback is not None: + callback() def toggle_interface(self): self.visibility = not self.visibility From f8e472ff068a9d0276a692eab02ed911ad7e80d6 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Wed, 12 Feb 2020 15:02:09 +0100 Subject: [PATCH 06/10] Revert "Refactor keyPressEvent" This reverts commit f7339c5026778bd738597a439c8e34c6d267542f. --- mne/viz/_brain/_timeviewer.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index e1a47cb8f44..f41a72fcd60 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -428,9 +428,13 @@ def __init__(self, brain): } def keyPressEvent(self, event): - callback = self.key_bindings.get(event.text()) - if callback is not None: - callback() + from PyQt5 import QtCore + if event.key() == QtCore.Qt.Key_Question: + self.help() + else: + callback = self.key_bindings.get(event.text()) + if callback is not None: + callback() def toggle_interface(self): self.visibility = not self.visibility From 440d92a9a77a91570fe9ef85ee1f7ae520796033 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Wed, 12 Feb 2020 15:16:48 +0100 Subject: [PATCH 07/10] TST: try Key_questiondown --- mne/viz/_brain/_timeviewer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index f41a72fcd60..a954fe60d79 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -429,7 +429,7 @@ def __init__(self, brain): def keyPressEvent(self, event): from PyQt5 import QtCore - if event.key() == QtCore.Qt.Key_Question: + if event.key() == QtCore.Qt.Key_questiondown: self.help() else: callback = self.key_bindings.get(event.text()) From e7ea1b321f0d3f4bf205b824a26e29b28ed618f6 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Thu, 13 Feb 2020 14:05:31 +0100 Subject: [PATCH 08/10] Refactor keyPressEvent --- mne/viz/_brain/_timeviewer.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index a954fe60d79..e1a47cb8f44 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -428,13 +428,9 @@ def __init__(self, brain): } def keyPressEvent(self, event): - from PyQt5 import QtCore - if event.key() == QtCore.Qt.Key_questiondown: - self.help() - else: - callback = self.key_bindings.get(event.text()) - if callback is not None: - callback() + callback = self.key_bindings.get(event.text()) + if callback is not None: + callback() def toggle_interface(self): self.visibility = not self.visibility From 1cbcb440eddbee5a0c1fd78e7f35eec57ca3efb7 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Thu, 13 Feb 2020 15:57:12 +0100 Subject: [PATCH 09/10] Use help menu instead of help label --- mne/viz/_brain/_timeviewer.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index e1a47cb8f44..b2f25edfb6d 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -404,11 +404,6 @@ def __init__(self, brain): # add toggle to show/hide interface self.visibility = True - # display help - self.help_actor = self.plotter.add_text( - text="Press ? to show help window" - ) - # set the slider style self.set_slider_style(smoothing_slider) self.set_slider_style(fmin_slider) @@ -426,6 +421,8 @@ def __init__(self, brain): 'u': self.restore_user_scaling, ' ': self.toggle_playback, } + menu = self.plotter.main_menu.addMenu('Help') + menu.addAction('Show MNE key bindings\t?', self.help) def keyPressEvent(self, event): callback = self.key_bindings.get(event.text()) @@ -435,12 +432,6 @@ def keyPressEvent(self, event): 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() From 717ec4ce0e8a08593844a60b37589c752d158521 Mon Sep 17 00:00:00 2001 From: Guillaume Favelier Date: Thu, 13 Feb 2020 17:44:19 +0100 Subject: [PATCH 10/10] Update shortcuts --- mne/viz/_brain/_timeviewer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mne/viz/_brain/_timeviewer.py b/mne/viz/_brain/_timeviewer.py index b2f25edfb6d..cbaaa53b08a 100644 --- a/mne/viz/_brain/_timeviewer.py +++ b/mne/viz/_brain/_timeviewer.py @@ -416,9 +416,9 @@ def __init__(self, brain): # setup key bindings self.key_bindings = { '?': self.help, - 'y': self.toggle_interface, - 't': self.apply_auto_scaling, - 'u': self.restore_user_scaling, + 'i': self.toggle_interface, + 's': self.apply_auto_scaling, + 'r': self.restore_user_scaling, ' ': self.toggle_playback, } menu = self.plotter.main_menu.addMenu('Help') @@ -506,9 +506,9 @@ def set_slider_style(self, slider, show_label=True): def help(self): pairs = [ ('?', 'Display help window'), - ('y', 'Toggle interface'), - ('t', 'Apply auto-scaling'), - ('u', 'Restore original clim'), + ('i', 'Toggle interface'), + ('s', 'Apply auto-scaling'), + ('r', 'Restore original clim'), ('Space', 'Start/Pause playback'), ] text1, text2 = zip(*pairs)