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