# .../Plugins/shortcuts.rb - makes and pops up a web page showing your keyboard shortcuts # Appendix AR (All Ruby) in Edges to Rubies - the Complete SketchUp Tutorial # Copyright 2010, Martin Rinehart # Version 1.0, March 10-11, 2010 require 'sketchup' unless file_loaded?( 'shortcuts.rb' ) pathname = Sketchup.find_support_file( 'shortcuts.rb', 'Plugins' ) UI.menu( "Plugins" ).add_item( "Keyboard Shortcuts" ) { load( pathname ) } file_loaded( 'shortcuts.rb' ) else # this else ends at the bottom of the file html_top = "

SketchUp (and My Own) Keyboard Shortcuts

" html_middle = '' html_extra = '
Key Shift+Key Ctrl+Key Alt+Key

Also:
' # for Ctrl+Shift+... html_bottom = " " $Google_shortcuts = [ "Ctrl+A\tEdit/Select All", "Ctrl+C\tEdit/Copy", "Ctrl+X\tEdit/Cut", "Ctrl+Y\tEdit/Redo", "Ctrl+Z\tEdit/Undo", "Ctrl+V\tEdit/Paste", "Ctrl+Shift+E\tCamera/Zoom Extents", "Ctrl+N\tFile/New", "Ctrl+O\tFile/Open...", "Ctrl+P\tFile/Print...", "Ctrl+S\tFile/Save", "Ctrl+T\tEdit/Select None", "Alt+Backspace\tEdit/Undo", "Delete\tEdit/Delete", "Shift+Delete\tEdit/Cut", "Shift+F1\tSketchUp/Context Help", "Ctrl+Insert\tEdit/Copy", "Shift+Insert\tEdit/Paste", "PageDown\tView/Animation/Next Scene", "PageUp\tView/Animation/Previous Scene", "Ctrl+Shift+W\tCamera/Zoom Window", "Space\tTools/Select", "G\tEdit/Make Component...", "L\tDraw/Line", "E\tTools/Eraser", "T\tTools/Tape Measure", "B\tTools/Paint Bucket", "R\tDraw/Rectangle", "C\tDraw/Circle", "A\tDraw/Arc", "P\tTools/Push/Pull", "M\tTools/Move", "Q\tTools/Rotate", "S\tTools/Scale", "F\tTools/Offset", "O\tCamera/Orbit", "H\tCamera/Pan", "Z\tCamera/Zoom", "Shift+Z\tCamera/Zoom Extents" ] def find( scuts, modi ) # in array of Shortcuts, find the one that has # the given modifier (and no others) for s in scuts kc = s.keycombo() case modi when '' then return s unless kc.shift || kc.ctrl || kc.alt when 'Shift' then return s if kc.shift && (!kc.ctrl) && (!kc.alt) when 'Ctrl' then return s if kc.ctrl && (!kc.shift) && (!kc.alt) when 'Alt' then return s if kc.alt && (!kc.shift) && (!kc.ctrl) end # of case end # of for loop return nil end # of find() def not_google( s ) # sets (or not) class for non-Google keyboard shortcut s return s.google ? '' : " class='not_google'" end # of not_google() def write_extra( s ) # footnotes for complex modifier combinations kc = s.keycombo html = '' html += 'Shift+' if kc.shift() html += 'Ctrl+' if kc.ctrl() html += 'Alt+' if kc.alt() html += kc.key() html += ': ' + s.description() html += '
' end def write_html( shortcuts_arr, line ) mod6 = (line-1) % 6 # first group is empty color = mod6 < 3 ? '#ffffff' : '#f0f0ff' return '' if shortcuts_arr.length() == 0 html = '' html += '' + shortcuts_arr[0].keycombo.key + '' html += write_html_cell( shortcuts_arr, '' ) html += write_html_cell( shortcuts_arr, 'Shift' ) html += write_html_cell( shortcuts_arr, 'Ctrl' ) html += write_html_cell( shortcuts_arr, 'Alt' ) html += '' return html end # of write_html() def write_html_cell( scuts, modi ) s = find( scuts, modi ) return ' ' if s == nil return '' + s.description() + '' end class Keycombo attr_reader :key, :shift, :ctrl, :alt # distillation: removing "modifier+" from the left of the key combo until # no modifiers remain. def initialize( str ) @string = str @key = @string @shift = false @ctrl = false @alt = false while !distilled() distill() end end # of initialize def complex?() # complex == more than one modifier modis = 0 modis += 1 if @shift modis += 1 if @ctrl modis += 1 if @alt return modis > 1 end # of complex() def distill() # $1 (from beginning up to, but not including first '+') # $2 (all chars after first '+') /(^[^+]*)\+(.*)/.match( @key ) qualifier = $1 @key = $2 case qualifier when 'Shift' then @shift = true when 'Ctrl' then @ctrl = true when 'Alt' then @alt = true end end def distilled() return @key.index( '+' ) == nil end def to_s() ret = "{Keycombo: " + @key ret += ' Shift' if @shift ret += ' Ctrl' if @ctrl ret += ' Alt' if @alt return ret + '}' end end # of class Keycombo class Shortcut # a Keycombo plus its description attr_reader :google, :keycombo, :description def initialize( str ) @string = str @google = $Google_shortcuts.include?( str ) # $1 (from beginning up to, but not including a tab), # $2 (then any number of chars after the first tab) /^([^\t]*)\t(.*)/.match( str ) @keycombo = Keycombo.new( $1 ) @description = $2 end def <=>( other ) @keycombo.key <=> other.keycombo.key end def to_s() return '{Shortcut: @keycombo=' + ( @keycombo.to_s() ) + ', @description=' + @description + '}' end end # of class Shortcut # mainline ------------------------------------------------------- scuts = Sketchup.get_shortcuts() shortcuts = [] for s in scuts do shortcuts.push( Shortcut.new(s) ) end shortcuts.sort!() # sorted array of Shortcut objects now ready group_key = '' group_arr = [] i = 0 for s in shortcuts if s.keycombo.key != group_key html_middle += write_html( group_arr, i ) i += 1 group_key = s.keycombo.key group_arr = [] end group_arr.push( s ) end html_middle += write_html( group_arr, i ) # final group not written until this # individual rows written for each Key for s in shortcuts html_extra += write_extra( s ) if s.keycombo().complex?() end # extras (Ctrl+Shift+...) written as footnotes # time to rock and roll! wd = UI::WebDialog.new( "Keyboard Shortcuts", true, 'keyboard_shortcuts', 640, 480, 0, 0, true ) wd.set_html( html_top + html_middle + html_extra + html_bottom ) wd.add_action_callback( "done" ) { | dlg, msg | wd.close() } wd.show() end # of unless file_loaded?() (from top of file) # end of .../Plugins/shortcuts.rb