CommandSet.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. #include "tools/sk_app/CommandSet.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkFont.h"
  10. #include "src/core/SkTSort.h"
  11. namespace sk_app {
  12. CommandSet::CommandSet()
  13. : fHelpMode(kNone_HelpMode) {
  14. this->addCommand('h', "Overlays", "Show help screen", [this]() {
  15. switch (this->fHelpMode) {
  16. case kNone_HelpMode:
  17. this->fHelpMode = kGrouped_HelpMode;
  18. break;
  19. case kGrouped_HelpMode:
  20. this->fHelpMode = kAlphabetical_HelpMode;
  21. break;
  22. case kAlphabetical_HelpMode:
  23. this->fHelpMode = kNone_HelpMode;
  24. break;
  25. }
  26. fWindow->inval();
  27. });
  28. }
  29. void CommandSet::attach(Window* window) {
  30. fWindow = window;
  31. }
  32. bool CommandSet::onKey(Window::Key key, InputState state, ModifierKey modifiers) {
  33. if (InputState::kDown == state) {
  34. for (Command& cmd : fCommands) {
  35. if (Command::kKey_CommandType == cmd.fType && key == cmd.fKey) {
  36. cmd.fFunction();
  37. return true;
  38. }
  39. }
  40. }
  41. return false;
  42. }
  43. bool CommandSet::onChar(SkUnichar c, ModifierKey modifiers) {
  44. for (Command& cmd : fCommands) {
  45. if (Command::kChar_CommandType == cmd.fType && c == cmd.fChar) {
  46. cmd.fFunction();
  47. return true;
  48. }
  49. }
  50. return false;
  51. }
  52. bool CommandSet::onSoftkey(const SkString& softkey) {
  53. for (const Command& cmd : fCommands) {
  54. if (cmd.getSoftkeyString().equals(softkey)) {
  55. cmd.fFunction();
  56. return true;
  57. }
  58. }
  59. return false;
  60. }
  61. void CommandSet::addCommand(SkUnichar c, const char* group, const char* description,
  62. std::function<void(void)> function) {
  63. fCommands.push_back(Command(c, group, description, function));
  64. }
  65. void CommandSet::addCommand(Window::Key k, const char* keyName, const char* group,
  66. const char* description, std::function<void(void)> function) {
  67. fCommands.push_back(Command(k, keyName, group, description, function));
  68. }
  69. #if defined(SK_BUILD_FOR_WIN)
  70. #define SK_strcasecmp _stricmp
  71. #else
  72. #define SK_strcasecmp strcasecmp
  73. #endif
  74. bool CommandSet::compareCommandKey(const Command& first, const Command& second) {
  75. return SK_strcasecmp(first.fKeyName.c_str(), second.fKeyName.c_str()) < 0;
  76. }
  77. bool CommandSet::compareCommandGroup(const Command& first, const Command& second) {
  78. return SK_strcasecmp(first.fGroup.c_str(), second.fGroup.c_str()) < 0;
  79. }
  80. void CommandSet::drawHelp(SkCanvas* canvas) {
  81. if (kNone_HelpMode == fHelpMode) {
  82. return;
  83. }
  84. // Sort commands for current mode:
  85. SkTQSort(fCommands.begin(), fCommands.end() - 1,
  86. kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup);
  87. SkFont font;
  88. font.setSize(16);
  89. SkFont groupFont;
  90. groupFont.setSize(18);
  91. SkPaint bgPaint;
  92. bgPaint.setColor(0xC0000000);
  93. canvas->drawPaint(bgPaint);
  94. SkPaint paint;
  95. paint.setAntiAlias(true);
  96. paint.setColor(0xFFFFFFFF);
  97. SkPaint groupPaint;
  98. groupPaint.setAntiAlias(true);
  99. groupPaint.setColor(0xFFFFFFFF);
  100. SkScalar x = SkIntToScalar(10);
  101. SkScalar y = SkIntToScalar(10);
  102. // Measure all key strings:
  103. SkScalar keyWidth = 0;
  104. for (Command& cmd : fCommands) {
  105. keyWidth = SkMaxScalar(keyWidth,
  106. font.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size(),
  107. SkTextEncoding::kUTF8));
  108. }
  109. keyWidth += font.measureText(" ", 1, SkTextEncoding::kUTF8);
  110. // If we're grouping by category, we'll be adding text height on every new group (including the
  111. // first), so no need to do that here. Otherwise, skip down so the first line is where we want.
  112. if (kGrouped_HelpMode != fHelpMode) {
  113. y += font.getSize();
  114. }
  115. // Print everything:
  116. SkString lastGroup;
  117. for (Command& cmd : fCommands) {
  118. if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) {
  119. // Group change. Advance and print header:
  120. y += font.getSize();
  121. canvas->drawSimpleText(cmd.fGroup.c_str(), cmd.fGroup.size(), SkTextEncoding::kUTF8,
  122. x, y, groupFont, groupPaint);
  123. y += groupFont.getSize() + 2;
  124. lastGroup = cmd.fGroup;
  125. }
  126. canvas->drawSimpleText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), SkTextEncoding::kUTF8,
  127. x, y, font, paint);
  128. SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str());
  129. canvas->drawString(text, x + keyWidth, y, font, paint);
  130. y += font.getSize() + 2;
  131. }
  132. }
  133. std::vector<SkString> CommandSet::getCommandsAsSoftkeys() const {
  134. std::vector<SkString> result;
  135. for(const Command& command : fCommands) {
  136. result.push_back(command.getSoftkeyString());
  137. }
  138. return result;
  139. }
  140. } // namespace sk_app