Home | History | Annotate | Download | only in sk_app
      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 "CommandSet.h"
      9 
     10 #include "SkCanvas.h"
     11 #include "SkTSort.h"
     12 
     13 namespace sk_app {
     14 
     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 
     33 void CommandSet::attach(Window* window) {
     34     fWindow = window;
     35 }
     36 
     37 bool CommandSet::onKey(Window::Key key, Window::InputState state, uint32_t modifiers) {
     38     if (Window::kDown_InputState == 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 
     50 bool CommandSet::onChar(SkUnichar c, uint32_t 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 
     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 
     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 
     76 void CommandSet::addCommand(Window::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 
     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 
     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 
     95 void CommandSet::drawHelp(SkCanvas* canvas) {
     96     if (kNone_HelpMode == fHelpMode) {
     97         return;
     98     }
     99 
    100     // Sort commands for current mode:
    101     SkTQSort(fCommands.begin(), fCommands.end() - 1,
    102              kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup);
    103 
    104     SkPaint bgPaint;
    105     bgPaint.setColor(0xC0000000);
    106     canvas->drawPaint(bgPaint);
    107 
    108     SkPaint paint;
    109     paint.setTextSize(16);
    110     paint.setAntiAlias(true);
    111     paint.setColor(0xFFFFFFFF);
    112 
    113     SkPaint groupPaint;
    114     groupPaint.setTextSize(18);
    115     groupPaint.setAntiAlias(true);
    116     groupPaint.setColor(0xFFFFFFFF);
    117 
    118     SkScalar x = SkIntToScalar(10);
    119     SkScalar y = SkIntToScalar(10);
    120 
    121     // Measure all key strings:
    122     SkScalar keyWidth = 0;
    123     for (Command& cmd : fCommands) {
    124         keyWidth = SkMaxScalar(keyWidth,
    125                                paint.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size()));
    126     }
    127     keyWidth += paint.measureText(" ", 1);
    128 
    129     // If we're grouping by category, we'll be adding text height on every new group (including the
    130     // first), so no need to do that here. Otherwise, skip down so the first line is where we want.
    131     if (kGrouped_HelpMode != fHelpMode) {
    132         y += paint.getTextSize();
    133     }
    134 
    135     // Print everything:
    136     SkString lastGroup;
    137     for (Command& cmd : fCommands) {
    138         if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) {
    139             // Group change. Advance and print header:
    140             y += paint.getTextSize();
    141             canvas->drawString(cmd.fGroup, x, y, groupPaint);
    142             y += groupPaint.getTextSize() + 2;
    143             lastGroup = cmd.fGroup;
    144         }
    145 
    146         canvas->drawString(cmd.fKeyName, x, y, paint);
    147         SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str());
    148         canvas->drawString(text, x + keyWidth, y, paint);
    149         y += paint.getTextSize() + 2;
    150     }
    151 }
    152 
    153 std::vector<SkString> CommandSet::getCommandsAsSoftkeys() const {
    154     std::vector<SkString> result;
    155     for(const Command& command : fCommands) {
    156         result.push_back(command.getSoftkeyString());
    157     }
    158     return result;
    159 }
    160 
    161 }   // namespace sk_app
    162