/* * 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 #include 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 function); void addCommand(Window::Key k, const char* keyName, const char* group, const char* description, std::function function); void drawHelp(SkCanvas* canvas); std::vector getCommandsAsSoftkeys() const; private: struct Command { enum CommandType { kChar_CommandType, kKey_CommandType, }; Command(SkUnichar c, const char* group, const char* description, std::function 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 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 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 fCommands; HelpMode fHelpMode; }; } // namespace sk_app #endif