diff options
Diffstat (limited to 'tools/viewer/sk_app/CommandSet.cpp')
-rw-r--r-- | tools/viewer/sk_app/CommandSet.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/tools/viewer/sk_app/CommandSet.cpp b/tools/viewer/sk_app/CommandSet.cpp new file mode 100644 index 0000000000..e426eaab21 --- /dev/null +++ b/tools/viewer/sk_app/CommandSet.cpp @@ -0,0 +1,157 @@ +/* +* 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 "CommandSet.h" + +#include "SkCanvas.h" +#include "SkTSort.h" + +namespace sk_app { + +static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t modifiers, + void* userData) { + CommandSet* cs = reinterpret_cast<CommandSet*>(userData); + return cs->onKey(key, state, modifiers); +} + +static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) { + CommandSet* cs = reinterpret_cast<CommandSet*>(userData); + return cs->onChar(c, modifiers); +} + +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; + window->registerKeyFunc(on_key_handler, this); + window->registerCharFunc(on_char_handler, this); +} + +bool CommandSet::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) { + if (Window::kDown_InputState == 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, uint32_t modifiers) { + for (Command& cmd : fCommands) { + if (Command::kChar_CommandType == cmd.fType && c == cmd.fChar) { + 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_WIN32) + #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); + + SkPaint bgPaint; + bgPaint.setColor(0xC0000000); + canvas->drawPaint(bgPaint); + + SkPaint paint; + paint.setTextSize(16); + paint.setAntiAlias(true); + paint.setColor(0xFFFFFFFF); + + SkPaint groupPaint; + groupPaint.setTextSize(18); + groupPaint.setUnderlineText(true); + 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, + paint.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size())); + } + keyWidth += paint.measureText(" ", 1); + + // 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 += paint.getTextSize(); + } + + // Print everything: + SkString lastGroup; + for (Command& cmd : fCommands) { + if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) { + // Group change. Advance and print header: + y += paint.getTextSize(); + canvas->drawText(cmd.fGroup.c_str(), cmd.fGroup.size(), x, y, groupPaint); + y += groupPaint.getTextSize() + 2; + lastGroup = cmd.fGroup; + } + + canvas->drawText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), x, y, paint); + SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str()); + canvas->drawText(text.c_str(), text.size(), x + keyWidth, y, paint); + y += paint.getTextSize() + 2; + } +} + +} // namespace sk_app |