1 /* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef CommandSet_DEFINED 9 #define CommandSet_DEFINED 10 11 #include "include/core/SkString.h" 12 #include "include/core/SkTypes.h" 13 #include "include/private/base/SkTArray.h" 14 #include "tools/skui/InputState.h" 15 #include "tools/skui/Key.h" 16 #include "tools/skui/ModifierKey.h" 17 18 #include <functional> 19 #include <vector> 20 21 class SkCanvas; 22 23 namespace sk_app { 24 class Window; 25 26 /** 27 * Helper class used by applications that want to hook keypresses to trigger events. 28 * 29 * An app can simply store an instance of CommandSet and then use it as follows: 30 * 1) Attach to the Window at initialization time. 31 * 2) Register commands to be executed for characters or keys. Each command needs a Group and a 32 * description (both just strings). Commands attached to Keys (rather than characters) also need 33 * a displayable name for the Key. Finally, a function to execute when the key or character is 34 * pressed must be supplied. The easiest option to is pass in a lambda that captures [this] 35 * (your application object), and performs whatever action is desired. 36 * 3) Register key and char handlers with the Window, and - depending on your state - forward those 37 * events to the CommandSet's onKey, onChar, and onSoftKey. 38 * 4) At the end of your onPaint, call drawHelp, and pass in the application's canvas. 39 40 * The CommandSet always binds 'h' to cycle through two different help screens. The first shows 41 * all commands, organized by Group (with headings for each Group). The second shows all commands 42 * alphabetically by key/character. 43 */ 44 class CommandSet { 45 public: 46 CommandSet(); 47 48 void attach(Window* window); 49 bool onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers); 50 bool onChar(SkUnichar, skui::ModifierKey modifiers); 51 bool onSoftkey(const SkString& softkey); 52 53 void addCommand(SkUnichar c, const char* group, const char* description, 54 std::function<void(void)> function); 55 void addCommand(skui::Key k, const char* keyName, const char* group, const char* description, 56 std::function<void(void)> function); 57 58 void drawHelp(SkCanvas* canvas); 59 60 std::vector<SkString> getCommandsAsSoftkeys() const; 61 62 private: 63 struct Command { 64 enum CommandType { 65 kChar_CommandType, 66 kKey_CommandType, 67 }; 68 CommandCommand69 Command(SkUnichar c, const char* group, const char* description, 70 std::function<void(void)> function) 71 : fType(kChar_CommandType) 72 , fChar(c) 73 , fKeyName(' ' == c ? SkString("Space") : SkStringPrintf("%c", c)) 74 , fGroup(group) 75 , fDescription(description) 76 , fFunction(function) {} 77 CommandCommand78 Command(skui::Key k, const char* keyName, const char* group, const char* description, 79 std::function<void(void)> function) 80 : fType(kKey_CommandType) 81 , fKey(k) 82 , fKeyName(keyName) 83 , fGroup(group) 84 , fDescription(description) 85 , fFunction(function) {} 86 87 CommandType fType; 88 89 // For kChar_CommandType 90 SkUnichar fChar; 91 92 // For kKey_CommandType 93 skui::Key fKey; 94 95 // Common to all command types 96 SkString fKeyName; 97 SkString fGroup; 98 SkString fDescription; 99 std::function<void(void)> fFunction; 100 getSoftkeyStringCommand101 SkString getSoftkeyString() const { 102 return SkStringPrintf("%s (%s)", fKeyName.c_str(), fDescription.c_str()); 103 } 104 }; 105 106 static bool compareCommandKey(const Command& first, const Command& second); 107 static bool compareCommandGroup(const Command& first, const Command& second); 108 109 enum HelpMode { 110 kNone_HelpMode, 111 kGrouped_HelpMode, 112 kAlphabetical_HelpMode, 113 }; 114 115 Window* fWindow; 116 skia_private::TArray<Command> fCommands; 117 HelpMode fHelpMode; 118 }; 119 120 } // namespace sk_app 121 122 #endif 123