| /* | 
 | * 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(skui::Key key, skui::InputState state, skui::ModifierKey modifiers) { | 
 |     if (skui::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, skui::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(skui::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 |