@@ -847,14 +847,81 @@ def trigger(self, sender, event, data=None):
847
847
848
848
849
849
class HelpGTK3 (backend_tools .ToolHelpBase ):
850
- def trigger (self , * args ):
850
+ def _normalize_shortcut (self , key ):
851
+ """
852
+ Convert Matplotlib key presses to GTK+ accelerator identifiers.
853
+
854
+ Related to `FigureCanvasGTK3._get_key`.
855
+ """
856
+ special = {
857
+ 'backspace' : 'BackSpace' ,
858
+ 'pagedown' : 'Page_Down' ,
859
+ 'pageup' : 'Page_Up' ,
860
+ 'scroll_lock' : 'Scroll_Lock' ,
861
+ }
862
+
863
+ parts = key .split ('+' )
864
+ mods = ['<' + mod + '>' for mod in parts [:- 1 ]]
865
+ key = parts [- 1 ]
866
+
867
+ if key in special :
868
+ key = special [key ]
869
+ elif len (key ) > 1 :
870
+ key = key .capitalize ()
871
+ elif key .isupper ():
872
+ mods += ['<shift>' ]
873
+
874
+ return '' .join (mods ) + key
875
+
876
+ def _show_shortcuts_window (self ):
877
+ section = Gtk .ShortcutsSection ()
878
+
879
+ for name , tool in sorted (self .toolmanager .tools .items ()):
880
+ if not tool .description :
881
+ continue
882
+
883
+ # Putting everything in a separate group allows GTK to
884
+ # automatically split them into separate columns/pages, which is
885
+ # useful because we have lots of shortcuts, some with many keys
886
+ # that are very wide.
887
+ group = Gtk .ShortcutsGroup ()
888
+ section .add (group )
889
+ # A hack to remove the title since we have no group naming.
890
+ group .forall (lambda widget , data : widget .set_visible (False ), None )
891
+
892
+ shortcut = Gtk .ShortcutsShortcut (
893
+ accelerator = ' ' .join (
894
+ self ._normalize_shortcut (key )
895
+ for key in self .toolmanager .get_tool_keymap (name )
896
+ # Will never be sent:
897
+ if 'cmd+' not in key ),
898
+ title = tool .name ,
899
+ subtitle = tool .description )
900
+ group .add (shortcut )
901
+
902
+ window = Gtk .ShortcutsWindow (
903
+ title = 'Help' ,
904
+ modal = True ,
905
+ transient_for = self ._figure .canvas .get_toplevel ())
906
+ section .show () # Must be done explicitly before add!
907
+ window .add (section )
908
+
909
+ window .show_all ()
910
+
911
+ def _show_shortcuts_dialog (self ):
851
912
dialog = Gtk .MessageDialog (
852
913
self ._figure .canvas .get_toplevel (),
853
914
0 , Gtk .MessageType .INFO , Gtk .ButtonsType .OK , self ._get_help_text (),
854
915
title = "Help" )
855
916
dialog .run ()
856
917
dialog .destroy ()
857
918
919
+ def trigger (self , * args ):
920
+ if Gtk .check_version (3 , 20 , 0 ) is None :
921
+ self ._show_shortcuts_window ()
922
+ else :
923
+ self ._show_shortcuts_dialog ()
924
+
858
925
859
926
# Define the file to use as the GTk icon
860
927
if sys .platform == 'win32' :
0 commit comments