xref: /aosp_15_r20/external/skia/tools/sk_app/CommandSet.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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