blob: 0784a3875e82b1b53d65295d2c87050341c91a5b [file] [log] [blame]
brianosman622c8d52016-05-10 06:50:49 -07001/*
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>
liyuqianb73c24b2016-06-03 08:47:23 -070015#include <vector>
brianosman622c8d52016-05-10 06:50:49 -070016
17class SkCanvas;
18
19namespace 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:
Brian Osman79086b92017-02-10 13:36:16 -050025 * 1) Attach to the Window at initialization time.
brianosman622c8d52016-05-10 06:50:49 -070026 * 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.
Brian Osman79086b92017-02-10 13:36:16 -050031 * 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.
brianosman622c8d52016-05-10 06:50:49 -070034
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 */
39class CommandSet {
40public:
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);
liyuqianb73c24b2016-06-03 08:47:23 -070046 bool onSoftkey(const SkString& softkey);
brianosman622c8d52016-05-10 06:50:49 -070047
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
liyuqianb73c24b2016-06-03 08:47:23 -070055 std::vector<SkString> getCommandsAsSoftkeys() const;
56
brianosman622c8d52016-05-10 06:50:49 -070057private:
58 struct Command {
59 enum CommandType {
60 kChar_CommandType,
61 kKey_CommandType,
62 };
63
64 Command(SkUnichar c, const char* group, const char* description,
65 std::function<void(void)> function)
66 : fType(kChar_CommandType)
67 , fChar(c)
Brian Osman79086b92017-02-10 13:36:16 -050068 , fKeyName(' ' == c ? SkString("Space") : SkStringPrintf("%c", c))
brianosman622c8d52016-05-10 06:50:49 -070069 , fGroup(group)
70 , fDescription(description)
71 , fFunction(function) {}
72
73 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;
liyuqianb73c24b2016-06-03 08:47:23 -070095
96 SkString getSoftkeyString() const {
97 return SkStringPrintf("%s (%s)", fKeyName.c_str(), fDescription.c_str());
98 }
brianosman622c8d52016-05-10 06:50:49 -070099 };
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