| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "tools/sk_app/CommandSet.h" |
| |
| #include "include/core/SkCanvas.h" |
| #include "include/core/SkFont.h" |
| #include "src/core/SkTSort.h" |
| |
| namespace sk_app { |
| |
| CommandSet::CommandSet() |
| : fHelpMode(kNone_HelpMode) { |
| this->addCommand('h', "Overlays", "Show help screen", [this]() { |
| switch (this->fHelpMode) { |
| case kNone_HelpMode: |
| this->fHelpMode = kGrouped_HelpMode; |
| break; |
| case kGrouped_HelpMode: |
| this->fHelpMode = kAlphabetical_HelpMode; |
| break; |
| case kAlphabetical_HelpMode: |
| this->fHelpMode = kNone_HelpMode; |
| break; |
| } |
| fWindow->inval(); |
| }); |
| } |
| |
| void CommandSet::attach(Window* window) { |
| fWindow = window; |
| } |
| |
| bool CommandSet::onKey(Window::Key key, InputState state, ModifierKey modifiers) { |
| if (InputState::kDown == state) { |
| for (Command& cmd : fCommands) { |
| if (Command::kKey_CommandType == cmd.fType && key == cmd.fKey) { |
| cmd.fFunction(); |
| return true; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| bool CommandSet::onChar(SkUnichar c, ModifierKey modifiers) { |
| for (Command& cmd : fCommands) { |
| if (Command::kChar_CommandType == cmd.fType && c == cmd.fChar) { |
| cmd.fFunction(); |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| bool CommandSet::onSoftkey(const SkString& softkey) { |
| for (const Command& cmd : fCommands) { |
| if (cmd.getSoftkeyString().equals(softkey)) { |
| cmd.fFunction(); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void CommandSet::addCommand(SkUnichar c, const char* group, const char* description, |
| std::function<void(void)> function) { |
| fCommands.push_back(Command(c, group, description, function)); |
| } |
| |
| void CommandSet::addCommand(Window::Key k, const char* keyName, const char* group, |
| const char* description, std::function<void(void)> function) { |
| fCommands.push_back(Command(k, keyName, group, description, function)); |
| } |
| |
| #if defined(SK_BUILD_FOR_WIN) |
| #define SK_strcasecmp _stricmp |
| #else |
| #define SK_strcasecmp strcasecmp |
| #endif |
| |
| bool CommandSet::compareCommandKey(const Command& first, const Command& second) { |
| return SK_strcasecmp(first.fKeyName.c_str(), second.fKeyName.c_str()) < 0; |
| } |
| |
| bool CommandSet::compareCommandGroup(const Command& first, const Command& second) { |
| return SK_strcasecmp(first.fGroup.c_str(), second.fGroup.c_str()) < 0; |
| } |
| |
| void CommandSet::drawHelp(SkCanvas* canvas) { |
| if (kNone_HelpMode == fHelpMode) { |
| return; |
| } |
| |
| // Sort commands for current mode: |
| SkTQSort(fCommands.begin(), fCommands.end() - 1, |
| kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup); |
| |
| SkFont font; |
| font.setSize(16); |
| |
| SkFont groupFont; |
| groupFont.setSize(18); |
| |
| SkPaint bgPaint; |
| bgPaint.setColor(0xC0000000); |
| canvas->drawPaint(bgPaint); |
| |
| SkPaint paint; |
| paint.setAntiAlias(true); |
| paint.setColor(0xFFFFFFFF); |
| |
| SkPaint groupPaint; |
| groupPaint.setAntiAlias(true); |
| groupPaint.setColor(0xFFFFFFFF); |
| |
| SkScalar x = SkIntToScalar(10); |
| SkScalar y = SkIntToScalar(10); |
| |
| // Measure all key strings: |
| SkScalar keyWidth = 0; |
| for (Command& cmd : fCommands) { |
| keyWidth = SkMaxScalar(keyWidth, |
| font.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), |
| SkTextEncoding::kUTF8)); |
| } |
| keyWidth += font.measureText(" ", 1, SkTextEncoding::kUTF8); |
| |
| // If we're grouping by category, we'll be adding text height on every new group (including the |
| // first), so no need to do that here. Otherwise, skip down so the first line is where we want. |
| if (kGrouped_HelpMode != fHelpMode) { |
| y += font.getSize(); |
| } |
| |
| // Print everything: |
| SkString lastGroup; |
| for (Command& cmd : fCommands) { |
| if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) { |
| // Group change. Advance and print header: |
| y += font.getSize(); |
| canvas->drawSimpleText(cmd.fGroup.c_str(), cmd.fGroup.size(), SkTextEncoding::kUTF8, |
| x, y, groupFont, groupPaint); |
| y += groupFont.getSize() + 2; |
| lastGroup = cmd.fGroup; |
| } |
| |
| canvas->drawSimpleText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), SkTextEncoding::kUTF8, |
| x, y, font, paint); |
| SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str()); |
| canvas->drawString(text, x + keyWidth, y, font, paint); |
| y += font.getSize() + 2; |
| } |
| } |
| |
| std::vector<SkString> CommandSet::getCommandsAsSoftkeys() const { |
| std::vector<SkString> result; |
| for(const Command& command : fCommands) { |
| result.push_back(command.getSoftkeyString()); |
| } |
| return result; |
| } |
| |
| } // namespace sk_app |