• 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 #include "tools/sk_app/CommandSet.h"
9 
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkFont.h"
12 
13 namespace sk_app {
14 
CommandSet()15 CommandSet::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 
attach(Window * window)33 void CommandSet::attach(Window* window) {
34     fWindow = window;
35 }
36 
onKey(skui::Key key,skui::InputState state,skui::ModifierKey modifiers)37 bool CommandSet::onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers) {
38     if (skui::InputState::kDown == 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 
onChar(SkUnichar c,skui::ModifierKey modifiers)50 bool CommandSet::onChar(SkUnichar c, skui::ModifierKey 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 
onSoftkey(const SkString & softkey)61 bool 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 
addCommand(SkUnichar c,const char * group,const char * description,std::function<void (void)> function)71 void 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 
addCommand(skui::Key k,const char * keyName,const char * group,const char * description,std::function<void (void)> function)76 void CommandSet::addCommand(skui::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 
81 #if defined(SK_BUILD_FOR_WIN)
82     #define SK_strcasecmp   _stricmp
83 #else
84     #define SK_strcasecmp   strcasecmp
85 #endif
86 
compareCommandKey(const Command & first,const Command & second)87 bool CommandSet::compareCommandKey(const Command& first, const Command& second) {
88     return SK_strcasecmp(first.fKeyName.c_str(), second.fKeyName.c_str()) < 0;
89 }
90 
compareCommandGroup(const Command & first,const Command & second)91 bool CommandSet::compareCommandGroup(const Command& first, const Command& second) {
92     return SK_strcasecmp(first.fGroup.c_str(), second.fGroup.c_str()) < 0;
93 }
94 
drawHelp(SkCanvas * canvas)95 void CommandSet::drawHelp(SkCanvas* canvas) {
96     if (kNone_HelpMode == fHelpMode) {
97         return;
98     }
99 
100     // Sort commands for current mode:
101     std::stable_sort(fCommands.begin(), fCommands.end(),
102                      kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup);
103 
104     SkFont font;
105     font.setSize(16);
106 
107     SkFont groupFont;
108     groupFont.setSize(18);
109 
110     SkPaint bgPaint;
111     bgPaint.setColor(0xC0000000);
112     canvas->drawPaint(bgPaint);
113 
114     SkPaint paint;
115     paint.setAntiAlias(true);
116     paint.setColor(0xFFFFFFFF);
117 
118     SkPaint groupPaint;
119     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) {
128         keyWidth = std::max(keyWidth,
129                                font.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size(),
130                                                 SkTextEncoding::kUTF8));
131     }
132     keyWidth += font.measureText(" ", 1, SkTextEncoding::kUTF8);
133 
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) {
137         y += font.getSize();
138     }
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:
145             y += font.getSize();
146             canvas->drawSimpleText(cmd.fGroup.c_str(), cmd.fGroup.size(), SkTextEncoding::kUTF8,
147                                    x, y, groupFont, groupPaint);
148             y += groupFont.getSize() + 2;
149             lastGroup = cmd.fGroup;
150         }
151 
152         canvas->drawSimpleText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), SkTextEncoding::kUTF8,
153                                x, y, font, paint);
154         SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str());
155         canvas->drawString(text, x + keyWidth, y, font, paint);
156         y += font.getSize() + 2;
157     }
158 }
159 
getCommandsAsSoftkeys() const160 std::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 
168 }   // namespace sk_app
169