You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.8 KiB
118 lines
3.8 KiB
/*
|
|
* 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>
|
|
#include <vector>
|
|
|
|
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.
|
|
* 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) Register key and char handlers with the Window, and - depending on your state - forward those
|
|
* events to the CommandSet's onKey, onChar, and onSoftKey.
|
|
* 4) 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);
|
|
bool onSoftkey(const SkString& softkey);
|
|
|
|
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);
|
|
|
|
std::vector<SkString> getCommandsAsSoftkeys() const;
|
|
|
|
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(' ' == c ? SkString("Space") : 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;
|
|
|
|
SkString getSoftkeyString() const {
|
|
return SkStringPrintf("%s (%s)", fKeyName.c_str(), fDescription.c_str());
|
|
}
|
|
};
|
|
|
|
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
|