blob: 10985760163d09236ce629235a0b7fb724d905a4 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "tools/sk_app/CommandSet.h"
brianosman622c8d52016-05-10 06:50:49 -07009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkCanvas.h"
11#include "include/core/SkFont.h"
brianosman622c8d52016-05-10 06:50:49 -070012
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
Hal Canaryb1f411a2019-08-29 10:39:22 -040037bool CommandSet::onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers) {
38 if (skui::InputState::kDown == state) {
brianosman622c8d52016-05-10 06:50:49 -070039 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
Hal Canaryb1f411a2019-08-29 10:39:22 -040050bool CommandSet::onChar(SkUnichar c, skui::ModifierKey modifiers) {
brianosman622c8d52016-05-10 06:50:49 -070051 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
Hal Canaryb1f411a2019-08-29 10:39:22 -040076void CommandSet::addCommand(skui::Key k, const char* keyName, const char* group,
brianosman622c8d52016-05-10 06:50:49 -070077 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:
Brian Osman3b5a4fa2020-07-13 12:50:43 -0400101 std::stable_sort(fCommands.begin(), fCommands.end(),
102 kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup);
brianosman622c8d52016-05-10 06:50:49 -0700103
Mike Reed91919132019-01-02 12:21:01 -0500104 SkFont font;
105 font.setSize(16);
106
107 SkFont groupFont;
108 groupFont.setSize(18);
109
brianosman622c8d52016-05-10 06:50:49 -0700110 SkPaint bgPaint;
111 bgPaint.setColor(0xC0000000);
112 canvas->drawPaint(bgPaint);
113
114 SkPaint paint;
brianosman622c8d52016-05-10 06:50:49 -0700115 paint.setAntiAlias(true);
116 paint.setColor(0xFFFFFFFF);
117
118 SkPaint groupPaint;
brianosman622c8d52016-05-10 06:50:49 -0700119 groupPaint.setAntiAlias(true);
120 groupPaint.setColor(0xFFFFFFFF);
121
122 SkScalar x = SkIntToScalar(10);
123 SkScalar y = SkIntToScalar(10);
124
125 // Measure all key strings:
126 SkScalar keyWidth = 0;
127 for (Command& cmd : fCommands) {
Brian Osman116b33e2020-02-05 13:34:09 -0500128 keyWidth = std::max(keyWidth,
Mike Reed91919132019-01-02 12:21:01 -0500129 font.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size(),
Ben Wagner51e15a62019-05-07 15:38:46 -0400130 SkTextEncoding::kUTF8));
brianosman622c8d52016-05-10 06:50:49 -0700131 }
Ben Wagner51e15a62019-05-07 15:38:46 -0400132 keyWidth += font.measureText(" ", 1, SkTextEncoding::kUTF8);
brianosman622c8d52016-05-10 06:50:49 -0700133
134 // If we're grouping by category, we'll be adding text height on every new group (including the
135 // first), so no need to do that here. Otherwise, skip down so the first line is where we want.
136 if (kGrouped_HelpMode != fHelpMode) {
Mike Reed91919132019-01-02 12:21:01 -0500137 y += font.getSize();
brianosman622c8d52016-05-10 06:50:49 -0700138 }
139
140 // Print everything:
141 SkString lastGroup;
142 for (Command& cmd : fCommands) {
143 if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) {
144 // Group change. Advance and print header:
Mike Reed91919132019-01-02 12:21:01 -0500145 y += font.getSize();
Ben Wagner51e15a62019-05-07 15:38:46 -0400146 canvas->drawSimpleText(cmd.fGroup.c_str(), cmd.fGroup.size(), SkTextEncoding::kUTF8,
Mike Reed91919132019-01-02 12:21:01 -0500147 x, y, groupFont, groupPaint);
148 y += groupFont.getSize() + 2;
brianosman622c8d52016-05-10 06:50:49 -0700149 lastGroup = cmd.fGroup;
150 }
151
Ben Wagner51e15a62019-05-07 15:38:46 -0400152 canvas->drawSimpleText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), SkTextEncoding::kUTF8,
Mike Reed91919132019-01-02 12:21:01 -0500153 x, y, font, paint);
brianosman622c8d52016-05-10 06:50:49 -0700154 SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str());
Hal Canary89a644b2019-01-07 09:36:09 -0500155 canvas->drawString(text, x + keyWidth, y, font, paint);
Mike Reed91919132019-01-02 12:21:01 -0500156 y += font.getSize() + 2;
brianosman622c8d52016-05-10 06:50:49 -0700157 }
158}
159
liyuqianb73c24b2016-06-03 08:47:23 -0700160std::vector<SkString> CommandSet::getCommandsAsSoftkeys() const {
161 std::vector<SkString> result;
162 for(const Command& command : fCommands) {
163 result.push_back(command.getSoftkeyString());
164 }
165 return result;
166}
167
brianosman622c8d52016-05-10 06:50:49 -0700168} // namespace sk_app