• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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