| /* | 
 | * Copyright 2016 Google Inc. | 
 | * | 
 | * Use of this source code is governed by a BSD-style license that can be | 
 | * found in the LICENSE file. | 
 | */ | 
 |  | 
 | #ifndef CommandSet_DEFINED | 
 | #define CommandSet_DEFINED | 
 |  | 
 | #include "SkString.h" | 
 | #include "Window.h" | 
 |  | 
 | #include <functional> | 
 | #include <vector> | 
 |  | 
 | class SkCanvas; | 
 |  | 
 | namespace sk_app { | 
 |  | 
 | /** | 
 |  * Helper class used by applications that want to hook keypresses to trigger events. | 
 |  * | 
 |  * An app can simply store an instance of CommandSet and then use it as follows: | 
 |  * 1) Attach to the Window at initialization time. | 
 |  * 2) Register commands to be executed for characters or keys. Each command needs a Group and a | 
 |  *    description (both just strings). Commands attached to Keys (rather than characters) also need | 
 |  *    a displayable name for the Key. Finally, a function to execute when the key or character is | 
 |  *    pressed must be supplied. The easiest option to is pass in a lambda that captures [this] | 
 |  *    (your application object), and performs whatever action is desired. | 
 |  * 3) Register key and char handlers with the Window, and - depending on your state - forward those | 
 |  *    events to the CommandSet's onKey, onChar, and onSoftKey. | 
 |  * 4) At the end of your onPaint, call drawHelp, and pass in the application's canvas. | 
 |  | 
 |  * The CommandSet always binds 'h' to cycle through two different help screens. The first shows | 
 |  * all commands, organized by Group (with headings for each Group). The second shows all commands | 
 |  * alphabetically by key/character. | 
 |  */ | 
 | class CommandSet { | 
 | public: | 
 |     CommandSet(); | 
 |  | 
 |     void attach(Window* window); | 
 |     bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers); | 
 |     bool onChar(SkUnichar, uint32_t modifiers); | 
 |     bool onSoftkey(const SkString& softkey); | 
 |  | 
 |     void addCommand(SkUnichar c, const char* group, const char* description, | 
 |                     std::function<void(void)> function); | 
 |     void addCommand(Window::Key k, const char* keyName, const char* group, const char* description, | 
 |                     std::function<void(void)> function); | 
 |  | 
 |     void drawHelp(SkCanvas* canvas); | 
 |  | 
 |     std::vector<SkString> getCommandsAsSoftkeys() const; | 
 |  | 
 | private: | 
 |     struct Command { | 
 |         enum CommandType { | 
 |             kChar_CommandType, | 
 |             kKey_CommandType, | 
 |         }; | 
 |  | 
 |         Command(SkUnichar c, const char* group, const char* description, | 
 |                 std::function<void(void)> function) | 
 |             : fType(kChar_CommandType) | 
 |             , fChar(c) | 
 |             , fKeyName(' ' == c ? SkString("Space") : SkStringPrintf("%c", c)) | 
 |             , fGroup(group) | 
 |             , fDescription(description) | 
 |             , fFunction(function) {} | 
 |  | 
 |         Command(Window::Key k, const char* keyName, const char* group, const char* description, | 
 |                 std::function<void(void)> function) | 
 |             : fType(kKey_CommandType) | 
 |             , fKey(k) | 
 |             , fKeyName(keyName) | 
 |             , fGroup(group) | 
 |             , fDescription(description) | 
 |             , fFunction(function) {} | 
 |  | 
 |         CommandType fType; | 
 |  | 
 |         // For kChar_CommandType | 
 |         SkUnichar fChar; | 
 |  | 
 |         // For kKey_CommandType | 
 |         Window::Key fKey; | 
 |  | 
 |         // Common to all command types | 
 |         SkString fKeyName; | 
 |         SkString fGroup; | 
 |         SkString fDescription; | 
 |         std::function<void(void)> fFunction; | 
 |  | 
 |         SkString getSoftkeyString() const { | 
 |             return SkStringPrintf("%s (%s)", fKeyName.c_str(), fDescription.c_str()); | 
 |         } | 
 |     }; | 
 |  | 
 |     static bool compareCommandKey(const Command& first, const Command& second); | 
 |     static bool compareCommandGroup(const Command& first, const Command& second); | 
 |  | 
 |     enum HelpMode { | 
 |         kNone_HelpMode, | 
 |         kGrouped_HelpMode, | 
 |         kAlphabetical_HelpMode, | 
 |     }; | 
 |  | 
 |     Window*           fWindow; | 
 |     SkTArray<Command> fCommands; | 
 |     HelpMode          fHelpMode; | 
 | }; | 
 |  | 
 | }   // namespace sk_app | 
 |  | 
 | #endif |