blob: 9684ef262419b6034f26d6bee920b1631406311c [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#include "CommandSet.h"
9
10#include "SkCanvas.h"
11#include "SkTSort.h"
12
13namespace sk_app {
14
brianosman622c8d52016-05-10 06:50:49 -070015CommandSet::CommandSet()
16 : fHelpMode(kNone_HelpMode) {
17 this->addCommand('h', "Overlays", "Show help screen", [this]() {
18 switch (this->fHelpMode) {
19 case kNone_HelpMode:
20 this->fHelpMode = kGrouped_HelpMode;
21 break;
22 case kGrouped_HelpMode:
23 this->fHelpMode = kAlphabetical_HelpMode;
24 break;
25 case kAlphabetical_HelpMode:
26 this->fHelpMode = kNone_HelpMode;
27 break;
28 }
29 fWindow->inval();
30 });
31}
32
33void CommandSet::attach(Window* window) {
34 fWindow = window;
brianosman622c8d52016-05-10 06:50:49 -070035}
36
37bool CommandSet::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
38 if (Window::kDown_InputState == state) {
39 for (Command& cmd : fCommands) {
40 if (Command::kKey_CommandType == cmd.fType && key == cmd.fKey) {
41 cmd.fFunction();
42 return true;
43 }
44 }
45 }
46
47 return false;
48}
49
50bool CommandSet::onChar(SkUnichar c, uint32_t modifiers) {
51 for (Command& cmd : fCommands) {
52 if (Command::kChar_CommandType == cmd.fType && c == cmd.fChar) {
53 cmd.fFunction();
54 return true;
55 }
56 }
57
58 return false;
59}
60
liyuqianb73c24b2016-06-03 08:47:23 -070061bool CommandSet::onSoftkey(const SkString& softkey) {
62 for (const Command& cmd : fCommands) {
63 if (cmd.getSoftkeyString().equals(softkey)) {
64 cmd.fFunction();
65 return true;
66 }
67 }
68 return false;
69}
70
brianosman622c8d52016-05-10 06:50:49 -070071void CommandSet::addCommand(SkUnichar c, const char* group, const char* description,
72 std::function<void(void)> function) {
73 fCommands.push_back(Command(c, group, description, function));
74}
75
76void CommandSet::addCommand(Window::Key k, const char* keyName, const char* group,
77 const char* description, std::function<void(void)> function) {
78 fCommands.push_back(Command(k, keyName, group, description, function));
79}
80
Mike Klein8f11d4d2018-01-24 12:42:55 -050081#if defined(SK_BUILD_FOR_WIN)
brianosman622c8d52016-05-10 06:50:49 -070082 #define SK_strcasecmp _stricmp
83#else
84 #define SK_strcasecmp strcasecmp
85#endif
86
87bool CommandSet::compareCommandKey(const Command& first, const Command& second) {
88 return SK_strcasecmp(first.fKeyName.c_str(), second.fKeyName.c_str()) < 0;
89}
90
91bool CommandSet::compareCommandGroup(const Command& first, const Command& second) {
92 return SK_strcasecmp(first.fGroup.c_str(), second.fGroup.c_str()) < 0;
93}
94
95void CommandSet::drawHelp(SkCanvas* canvas) {
96 if (kNone_HelpMode == fHelpMode) {
97 return;
98 }
99
100 // Sort commands for current mode:
101 SkTQSort(fCommands.begin(), fCommands.end() - 1,
102 kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup);
103
104 SkPaint bgPaint;
105 bgPaint.setColor(0xC0000000);
106 canvas->drawPaint(bgPaint);
107
108 SkPaint paint;
109 paint.setTextSize(16);
110 paint.setAntiAlias(true);
111 paint.setColor(0xFFFFFFFF);
112
113 SkPaint groupPaint;
114 groupPaint.setTextSize(18);
brianosman622c8d52016-05-10 06:50:49 -0700115 groupPaint.setAntiAlias(true);
116 groupPaint.setColor(0xFFFFFFFF);
117
118 SkScalar x = SkIntToScalar(10);
119 SkScalar y = SkIntToScalar(10);
120
121 // Measure all key strings:
122 SkScalar keyWidth = 0;
123 for (Command& cmd : fCommands) {
124 keyWidth = SkMaxScalar(keyWidth,
125 paint.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size()));
126 }
127 keyWidth += paint.measureText(" ", 1);
128
129 // If we're grouping by category, we'll be adding text height on every new group (including the
130 // first), so no need to do that here. Otherwise, skip down so the first line is where we want.
131 if (kGrouped_HelpMode != fHelpMode) {
132 y += paint.getTextSize();
133 }
134
135 // Print everything:
136 SkString lastGroup;
137 for (Command& cmd : fCommands) {
138 if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) {
139 // Group change. Advance and print header:
140 y += paint.getTextSize();
Cary Clark2a475ea2017-04-28 15:35:12 -0400141 canvas->drawString(cmd.fGroup, x, y, groupPaint);
brianosman622c8d52016-05-10 06:50:49 -0700142 y += groupPaint.getTextSize() + 2;
143 lastGroup = cmd.fGroup;
144 }
145
Cary Clark2a475ea2017-04-28 15:35:12 -0400146 canvas->drawString(cmd.fKeyName, x, y, paint);
brianosman622c8d52016-05-10 06:50:49 -0700147 SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str());
Cary Clark2a475ea2017-04-28 15:35:12 -0400148 canvas->drawString(text, x + keyWidth, y, paint);
brianosman622c8d52016-05-10 06:50:49 -0700149 y += paint.getTextSize() + 2;
150 }
151}
152
liyuqianb73c24b2016-06-03 08:47:23 -0700153std::vector<SkString> CommandSet::getCommandsAsSoftkeys() const {
154 std::vector<SkString> result;
155 for(const Command& command : fCommands) {
156 result.push_back(command.getSoftkeyString());
157 }
158 return result;
159}
160
brianosman622c8d52016-05-10 06:50:49 -0700161} // namespace sk_app