diff options
Diffstat (limited to 'tools/viewer')
-rw-r--r-- | tools/viewer/Viewer.cpp | 116 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 4 | ||||
-rw-r--r-- | tools/viewer/sk_app/CommandSet.cpp | 157 | ||||
-rw-r--r-- | tools/viewer/sk_app/CommandSet.h | 107 | ||||
-rw-r--r-- | tools/viewer/sk_app/Window.h | 76 | ||||
-rw-r--r-- | tools/viewer/sk_app/win/Window_win.cpp | 16 |
6 files changed, 352 insertions, 124 deletions
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 62c3048d91..7dd265e6e2 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -22,19 +22,6 @@ Application* Application::Create(int argc, char** argv, void* platformData) { return new Viewer(argc, argv, platformData); } -static bool on_key_handler(Window::Key key, Window::InputState state, uint32_t modifiers, - void* userData) { - Viewer* vv = reinterpret_cast<Viewer*>(userData); - - return vv->onKey(key, state, modifiers); -} - -static bool on_char_handler(SkUnichar c, uint32_t modifiers, void* userData) { - Viewer* vv = reinterpret_cast<Viewer*>(userData); - - return vv->onChar(c, modifiers); -} - static void on_paint_handler(SkCanvas* canvas, void* userData) { Viewer* vv = reinterpret_cast<Viewer*>(userData); @@ -76,10 +63,47 @@ Viewer::Viewer(int argc, char** argv, void* platformData) fWindow->attach(Window::kVulkan_BackendType, DisplayParams()); // register callbacks - fWindow->registerKeyFunc(on_key_handler, this); - fWindow->registerCharFunc(on_char_handler, this); + fCommands.attach(fWindow); fWindow->registerPaintFunc(on_paint_handler, this); + // add key-bindings + fCommands.addCommand('s', "Overlays", "Toggle stats display", [this]() { + this->fDisplayStats = !this->fDisplayStats; + fWindow->inval(); + }); + fCommands.addCommand('c', "Modes", "Toggle sRGB color mode", [this]() { + DisplayParams params = fWindow->getDisplayParams(); + params.fProfileType = (kLinear_SkColorProfileType == params.fProfileType) + ? kSRGB_SkColorProfileType : kLinear_SkColorProfileType; + fWindow->setDisplayParams(params); + this->updateTitle(); + fWindow->inval(); + }); + fCommands.addCommand(Window::Key::kRight, "Right", "Navigation", "Next slide", [this]() { + int previousSlide = fCurrentSlide; + fCurrentSlide++; + if (fCurrentSlide >= fSlides.count()) { + fCurrentSlide = 0; + } + this->setupCurrentSlide(previousSlide); + }); + fCommands.addCommand(Window::Key::kLeft, "Left", "Navigation", "Previous slide", [this]() { + int previousSlide = fCurrentSlide; + fCurrentSlide--; + if (fCurrentSlide < 0) { + fCurrentSlide = fSlides.count() - 1; + } + this->setupCurrentSlide(previousSlide); + }); + fCommands.addCommand(Window::Key::kUp, "Up", "Transform", "Zoom in", [this]() { + this->changeZoomLevel(1.f / 32.f); + fWindow->inval(); + }); + fCommands.addCommand(Window::Key::kDown, "Down", "Transform", "Zoom out", [this]() { + this->changeZoomLevel(-1.f / 32.f); + fWindow->inval(); + }); + // set up slides this->initSlides(); @@ -208,67 +232,6 @@ void Viewer::updateMatrix(){ fLocalMatrix = m; } -bool Viewer::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) { - if (Window::kDown_InputState == state) { - switch (key) { - case Window::kRight_Key: { - int previousSlide = fCurrentSlide; - fCurrentSlide++; - if (fCurrentSlide >= fSlides.count()) { - fCurrentSlide = 0; - } - setupCurrentSlide(previousSlide); - return true; - } - - case Window::kLeft_Key: { - int previousSlide = fCurrentSlide; - fCurrentSlide--; - if (fCurrentSlide < 0) { - fCurrentSlide = fSlides.count() - 1; - } - setupCurrentSlide(previousSlide); - return true; - } - - case Window::kUp_Key: { - this->changeZoomLevel(1.f / 32.f); - fWindow->inval(); - return true; - } - - case Window::kDown_Key: { - this->changeZoomLevel(-1.f / 32.f); - fWindow->inval(); - return true; - } - - default: - break; - } - } - - return false; -} - -bool Viewer::onChar(SkUnichar c, uint32_t modifiers) { - switch (c) { - case 's': - fDisplayStats = !fDisplayStats; - return true; - case 'c': - DisplayParams params = fWindow->getDisplayParams(); - params.fProfileType = (kLinear_SkColorProfileType == params.fProfileType) - ? kSRGB_SkColorProfileType : kLinear_SkColorProfileType; - fWindow->setDisplayParams(params); - this->updateTitle(); - fWindow->inval(); - return true; - } - - return false; -} - void Viewer::onPaint(SkCanvas* canvas) { int count = canvas->save(); @@ -296,6 +259,7 @@ void Viewer::onPaint(SkCanvas* canvas) { if (fDisplayStats) { drawStats(canvas); } + fCommands.drawHelp(canvas); } void Viewer::drawStats(SkCanvas* canvas) { diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index 2e9650a846..033bd6969b 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -9,6 +9,7 @@ #define Viewer_DEFINED #include "sk_app/Application.h" +#include "sk_app/CommandSet.h" #include "sk_app/Window.h" #include "gm.h" #include "SkAnimTimer.h" @@ -21,8 +22,6 @@ public: Viewer(int argc, char** argv, void* platformData); ~Viewer() override; - bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers); - bool onChar(SkUnichar, uint32_t modifiers); void onPaint(SkCanvas* canvas); void onIdle(double ms) override; @@ -55,6 +54,7 @@ private: SkScalar fZoomLevel; SkScalar fZoomScale; + sk_app::CommandSet fCommands; }; 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 diff --git a/tools/viewer/sk_app/CommandSet.h b/tools/viewer/sk_app/CommandSet.h new file mode 100644 index 0000000000..5e6373c935 --- /dev/null +++ b/tools/viewer/sk_app/CommandSet.h @@ -0,0 +1,107 @@ +/* +* Copyright 2016 Google Inc. +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ + +#ifndef CommandSet_DEFINED +#define CommandSet_DEFINED + +#include "SkString.h" +#include "Window.h" + +#include <functional> + +class SkCanvas; + +namespace sk_app { + +/** + * Helper class used by applications that want to hook keypresses to trigger events. + * + * An app can simply store an instance of CommandSet and then use it as follows: + * 1) Attach to the Window at initialization time. This registers key handlers on the window. + * 2) Register commands to be executed for characters or keys. Each command needs a Group and a + * description (both just strings). Commands attached to Keys (rather than characters) also need + * a displayable name for the Key. Finally, a function to execute when the key or character is + * pressed must be supplied. The easiest option to is pass in a lambda that captures [this] + * (your application object), and performs whatever action is desired. + * 3) At the end of your onPaint, call drawHelp, and pass in the application's canvas. + + * The CommandSet always binds 'h' to cycle through two different help screens. The first shows + * all commands, organized by Group (with headings for each Group). The second shows all commands + * alphabetically by key/character. + */ +class CommandSet { +public: + CommandSet(); + + void attach(Window* window); + bool onKey(sk_app::Window::Key key, sk_app::Window::InputState state, uint32_t modifiers); + bool onChar(SkUnichar, uint32_t modifiers); + + void addCommand(SkUnichar c, const char* group, const char* description, + std::function<void(void)> function); + void addCommand(Window::Key k, const char* keyName, const char* group, const char* description, + std::function<void(void)> function); + + void drawHelp(SkCanvas* canvas); + +private: + struct Command { + enum CommandType { + kChar_CommandType, + kKey_CommandType, + }; + + Command(SkUnichar c, const char* group, const char* description, + std::function<void(void)> function) + : fType(kChar_CommandType) + , fChar(c) + , fKeyName(SkStringPrintf("%c", c)) + , fGroup(group) + , fDescription(description) + , fFunction(function) {} + + Command(Window::Key k, const char* keyName, const char* group, const char* description, + std::function<void(void)> function) + : fType(kKey_CommandType) + , fKey(k) + , fKeyName(keyName) + , fGroup(group) + , fDescription(description) + , fFunction(function) {} + + CommandType fType; + + // For kChar_CommandType + SkUnichar fChar; + + // For kKey_CommandType + Window::Key fKey; + + // Common to all command types + SkString fKeyName; + SkString fGroup; + SkString fDescription; + std::function<void(void)> fFunction; + }; + + static bool compareCommandKey(const Command& first, const Command& second); + static bool compareCommandGroup(const Command& first, const Command& second); + + enum HelpMode { + kNone_HelpMode, + kGrouped_HelpMode, + kAlphabetical_HelpMode, + }; + + Window* fWindow; + SkTArray<Command> fCommands; + HelpMode fHelpMode; +}; + +} // namespace sk_app + +#endif diff --git a/tools/viewer/sk_app/Window.h b/tools/viewer/sk_app/Window.h index 56444a67b7..5a7c9b8360 100644 --- a/tools/viewer/sk_app/Window.h +++ b/tools/viewer/sk_app/Window.h @@ -41,45 +41,45 @@ public: void detach(); // input handling - enum Key { - kNONE_Key, //corresponds to android's UNKNOWN - - kLeftSoftKey_Key, - kRightSoftKey_Key, - - kHome_Key, //!< the home key - added to match android - kBack_Key, //!< (CLR) - kSend_Key, //!< the green (talk) key - kEnd_Key, //!< the red key - - k0_Key, - k1_Key, - k2_Key, - k3_Key, - k4_Key, - k5_Key, - k6_Key, - k7_Key, - k8_Key, - k9_Key, - kStar_Key, //!< the * key - kHash_Key, //!< the # key - - kUp_Key, - kDown_Key, - kLeft_Key, - kRight_Key, - - kOK_Key, //!< the center key - - kVolUp_Key, //!< volume up - match android - kVolDown_Key, //!< volume down - same - kPower_Key, //!< power button - same - kCamera_Key, //!< camera - same - - kLast_Key = kCamera_Key + enum class Key { + kNONE, //corresponds to android's UNKNOWN + + kLeftSoftKey, + kRightSoftKey, + + kHome, //!< the home key - added to match android + kBack, //!< (CLR) + kSend, //!< the green (talk) key + kEnd, //!< the red key + + k0, + k1, + k2, + k3, + k4, + k5, + k6, + k7, + k8, + k9, + kStar, //!< the * key + kHash, //!< the # key + + kUp, + kDown, + kLeft, + kRight, + + kOK, //!< the center key + + kVolUp, //!< volume up - match android + kVolDown, //!< volume down - same + kPower, //!< power button - same + kCamera, //!< camera - same + + kLast = kCamera }; - static const int kKeyCount = kLast_Key + 1; + static const int kKeyCount = static_cast<int>(Key::kLast) + 1; enum ModifierKeys { kShift_ModifierKey = 1 << 0, diff --git a/tools/viewer/sk_app/win/Window_win.cpp b/tools/viewer/sk_app/win/Window_win.cpp index 16afcc7275..241a41caba 100644 --- a/tools/viewer/sk_app/win/Window_win.cpp +++ b/tools/viewer/sk_app/win/Window_win.cpp @@ -93,20 +93,20 @@ static Window::Key get_key(WPARAM vk) { WPARAM fVK; Window::Key fKey; } gPair[] = { - { VK_BACK, Window::kBack_Key }, - { VK_CLEAR, Window::kBack_Key }, - { VK_RETURN, Window::kOK_Key }, - { VK_UP, Window::kUp_Key }, - { VK_DOWN, Window::kDown_Key }, - { VK_LEFT, Window::kLeft_Key }, - { VK_RIGHT, Window::kRight_Key } + { VK_BACK, Window::Key::kBack }, + { VK_CLEAR, Window::Key::kBack }, + { VK_RETURN, Window::Key::kOK }, + { VK_UP, Window::Key::kUp }, + { VK_DOWN, Window::Key::kDown }, + { VK_LEFT, Window::Key::kLeft }, + { VK_RIGHT, Window::Key::kRight } }; for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) { if (gPair[i].fVK == vk) { return gPair[i].fKey; } } - return Window::kNONE_Key; + return Window::Key::kNONE; } static uint32_t get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) { |