mirror of https://github.com/odrling/Aegisub
Make the hotkey code a bit less bloated
This commit is contained in:
parent
c0c05e982a
commit
518342b919
|
@ -12,36 +12,33 @@
|
|||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/// @file hotkey.cpp
|
||||
/// @brief Hotkey handler
|
||||
/// @ingroup hotkey menu event window
|
||||
|
||||
#include "libaegisub/hotkey.h"
|
||||
|
||||
#include "libaegisub/cajun/writer.h"
|
||||
#include "libaegisub/io.h"
|
||||
#include "libaegisub/json.h"
|
||||
#include "libaegisub/log.h"
|
||||
#include "libaegisub/split.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/range/algorithm/equal_range.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace agi {
|
||||
namespace hotkey {
|
||||
namespace agi { namespace hotkey {
|
||||
namespace {
|
||||
struct combo_cmp {
|
||||
bool operator()(const Combo *a, const Combo *b) {
|
||||
return a->Str() < b->Str();
|
||||
}
|
||||
|
||||
std::string Combo::Str() const {
|
||||
return boost::algorithm::join(key_map, "-");
|
||||
}
|
||||
bool operator()(const Combo *a, std::string const& b) {
|
||||
return a->Str() < b;
|
||||
}
|
||||
|
||||
std::string Combo::StrMenu() const {
|
||||
return Str();
|
||||
}
|
||||
|
||||
void Hotkey::ComboInsert(Combo const& combo) {
|
||||
str_map.insert(make_pair(combo.Str(), combo));
|
||||
cmd_map.insert(make_pair(combo.CmdName(), combo));
|
||||
bool operator()(std::string const& a, const Combo *b) {
|
||||
return a < b->Str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Hotkey::Hotkey(fs::path const& file, std::pair<const char *, size_t> default_config)
|
||||
|
@ -52,85 +49,84 @@ Hotkey::Hotkey(fs::path const& file, std::pair<const char *, size_t> default_con
|
|||
auto root = json_util::file(config_file, default_config);
|
||||
for (auto const& hotkey_context : static_cast<json::Object const&>(root))
|
||||
BuildHotkey(hotkey_context.first, hotkey_context.second);
|
||||
UpdateStrMap();
|
||||
}
|
||||
|
||||
void Hotkey::BuildHotkey(std::string const& context, json::Object const& hotkeys) {
|
||||
for (auto const& command : hotkeys) {
|
||||
const json::Array& command_hotkeys = command.second;
|
||||
json::Array const& command_hotkeys = command.second;
|
||||
|
||||
for (json::Object const& hotkey : command_hotkeys) {
|
||||
std::vector<std::string> keys;
|
||||
|
||||
auto it = hotkey.find("modifiers");
|
||||
if (it == end(hotkey)) {
|
||||
auto mod_it = hotkey.find("modifiers");
|
||||
if (mod_it == end(hotkey)) {
|
||||
LOG_E("agi/hotkey/load") << "Hotkey for command '" << command.first << "' is missing modifiers";
|
||||
continue;
|
||||
}
|
||||
|
||||
json::Array const& arr_mod = it->second;
|
||||
keys.reserve(arr_mod.size() + 1);
|
||||
copy(arr_mod.begin(), arr_mod.end(), back_inserter(keys));
|
||||
|
||||
it = hotkey.find("key");
|
||||
if (it == end(hotkey)) {
|
||||
auto key_it = hotkey.find("key");
|
||||
if (key_it == end(hotkey)) {
|
||||
LOG_E("agi/hotkey/load") << "Hotkey for command '" << command.first << "' is missing the key";
|
||||
continue;
|
||||
}
|
||||
|
||||
keys.push_back(it->second);
|
||||
ComboInsert(Combo(context, command.first, keys));
|
||||
std::string key_str;
|
||||
json::Array const& arr_mod = mod_it->second;
|
||||
for (std::string const& mod : arr_mod) {
|
||||
key_str += mod;
|
||||
key_str += '-';
|
||||
}
|
||||
key_str += static_cast<std::string const&>(key_it->second);
|
||||
|
||||
cmd_map.insert(make_pair(command.first, Combo(context, command.first, std::move(key_str))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Hotkey::Scan(const std::string &context, const std::string &str, bool always) const {
|
||||
std::string local, dfault;
|
||||
std::string Hotkey::Scan(std::string const& context, std::string const& str, bool always) const {
|
||||
const std::string *local = nullptr, *dfault = nullptr;
|
||||
|
||||
HotkeyMap::const_iterator index, end;
|
||||
for (std::tie(index, end) = str_map.equal_range(str); index != end; ++index) {
|
||||
std::string const& ctext = index->second.Context();
|
||||
std::vector<const Combo *>::const_iterator index, end;
|
||||
for (std::tie(index, end) = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) {
|
||||
std::string const& ctext = (*index)->Context();
|
||||
|
||||
if (always && ctext == "Always") {
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Always Command: " << index->second.CmdName();
|
||||
return index->second.CmdName();
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Always Command: " << (*index)->CmdName();
|
||||
return (*index)->CmdName();
|
||||
}
|
||||
if (ctext == "Default")
|
||||
dfault = index->second.CmdName();
|
||||
dfault = &(*index)->CmdName();
|
||||
else if (ctext == context)
|
||||
local = index->second.CmdName();
|
||||
local = &(*index)->CmdName();
|
||||
}
|
||||
|
||||
if (!local.empty()) {
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context: " << context << " Command: " << local;
|
||||
return local;
|
||||
if (local) {
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context: " << context << " Command: " << *local;
|
||||
return *local;
|
||||
}
|
||||
if (!dfault.empty()) {
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Default Command: " << dfault;
|
||||
return dfault;
|
||||
if (dfault) {
|
||||
LOG_D("agi/hotkey/found") << "Found: " << str << " Context (req/found): " << context << "/Default Command: " << *dfault;
|
||||
return *dfault;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Hotkey::HasHotkey(const std::string &context, const std::string &str) const {
|
||||
HotkeyMap::const_iterator index, end;
|
||||
for (std::tie(index, end) = str_map.equal_range(str); index != end; ++index) {
|
||||
std::string const& ctext = index->second.Context();
|
||||
|
||||
if (ctext == context)
|
||||
bool Hotkey::HasHotkey(std::string const& context, std::string const& str) const {
|
||||
std::vector<const Combo *>::const_iterator index, end;
|
||||
for (std::tie(index, end) = boost::equal_range(str_map, str, combo_cmp()); index != end; ++index) {
|
||||
if (context == (*index)->Context())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> Hotkey::GetHotkeys(const std::string &context, const std::string &command) const {
|
||||
std::vector<std::string> Hotkey::GetHotkeys(std::string const& context, std::string const& command) const {
|
||||
std::vector<std::string> ret;
|
||||
|
||||
HotkeyMap::const_iterator it, end;
|
||||
for (std::tie(it, end) = cmd_map.equal_range(command); it != end; ++it) {
|
||||
std::string ctext = it->second.Context();
|
||||
std::string const& ctext = it->second.Context();
|
||||
if (ctext == "Always" || ctext == "Default" || ctext == context)
|
||||
ret.emplace_back(it->second.StrMenu());
|
||||
ret.emplace_back(it->second.Str());
|
||||
}
|
||||
|
||||
sort(ret.begin(), ret.end());
|
||||
|
@ -139,16 +135,16 @@ std::vector<std::string> Hotkey::GetHotkeys(const std::string &context, const st
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string Hotkey::GetHotkey(const std::string &context, const std::string &command) const {
|
||||
std::string Hotkey::GetHotkey(std::string const& context, std::string const& command) const {
|
||||
std::string ret;
|
||||
HotkeyMap::const_iterator it, end;
|
||||
for (std::tie(it, end) = cmd_map.equal_range(command); it != end; ++it) {
|
||||
std::string ctext = it->second.Context();
|
||||
if (ctext == context) return it->second.StrMenu();
|
||||
std::string const& ctext = it->second.Context();
|
||||
if (ctext == context) return it->second.Str();
|
||||
if (ctext == "Default")
|
||||
ret = it->second.StrMenu();
|
||||
ret = it->second.Str();
|
||||
else if (ret.empty() && ctext == "Always")
|
||||
ret = it->second.StrMenu();
|
||||
ret = it->second.Str();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -156,16 +152,21 @@ std::string Hotkey::GetHotkey(const std::string &context, const std::string &com
|
|||
void Hotkey::Flush() {
|
||||
json::Object root;
|
||||
|
||||
for (auto const& combo : str_map | boost::adaptors::map_values) {
|
||||
for (auto const& combo : str_map) {
|
||||
auto keys = combo->Str();
|
||||
if (keys.empty()) continue;
|
||||
|
||||
json::Object hotkey;
|
||||
if (combo.Get().size()) {
|
||||
hotkey["key"] = combo.Get().back();
|
||||
json::Array& modifiers = hotkey["modifiers"];
|
||||
modifiers.insert(modifiers.end(), combo.Get().begin(), combo.Get().end() - 1);
|
||||
json::Array& modifiers = hotkey["modifiers"];
|
||||
for (auto tok : agi::Split(keys, '-')) {
|
||||
if (end(tok) == end(keys))
|
||||
hotkey.insert(make_pair("key", agi::str(tok)));
|
||||
else
|
||||
modifiers.push_back(agi::str(tok));
|
||||
}
|
||||
|
||||
json::Object& context = root[combo.Context()];
|
||||
json::Array& combo_array = context[combo.CmdName()];
|
||||
json::Object& context = root[combo->Context()];
|
||||
json::Array& combo_array = context[combo->CmdName()];
|
||||
combo_array.push_back(std::move(hotkey));
|
||||
}
|
||||
|
||||
|
@ -173,16 +174,20 @@ void Hotkey::Flush() {
|
|||
JsonWriter::Write(root, file.Get());
|
||||
}
|
||||
|
||||
void Hotkey::SetHotkeyMap(HotkeyMap const& new_map) {
|
||||
cmd_map = new_map;
|
||||
|
||||
void Hotkey::UpdateStrMap() {
|
||||
str_map.clear();
|
||||
for (auto const& combo : cmd_map | boost::adaptors::map_values)
|
||||
str_map.insert(make_pair(combo.Str(), combo));
|
||||
str_map.reserve(cmd_map.size());
|
||||
for (auto const& combo : cmd_map)
|
||||
str_map.push_back(&combo.second);
|
||||
|
||||
sort(begin(str_map), end(str_map), combo_cmp());
|
||||
}
|
||||
|
||||
void Hotkey::SetHotkeyMap(HotkeyMap new_map) {
|
||||
cmd_map = std::move(new_map);
|
||||
UpdateStrMap();
|
||||
Flush();
|
||||
HotkeysChanged();
|
||||
}
|
||||
|
||||
} // namespace toolbar
|
||||
} // namespace agi
|
||||
} }
|
||||
|
|
|
@ -12,10 +12,6 @@
|
|||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/// @file hotkey.h
|
||||
/// @brief Hotkey handler
|
||||
/// @ingroup hotkey menu event window
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
@ -36,39 +32,31 @@ namespace agi {
|
|||
/// A Combo represents a linear sequence of characters set in an std::vector.
|
||||
/// This makes up a single combination, or "Hotkey".
|
||||
class Combo {
|
||||
std::vector<std::string> key_map;
|
||||
std::string keys;
|
||||
std::string cmd_name;
|
||||
std::string context;
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param ctx Context
|
||||
/// @param cmd Command name
|
||||
Combo(std::string ctx, std::string cmd, std::vector<std::string> keys)
|
||||
: key_map(std::move(keys))
|
||||
Combo(std::string ctx, std::string cmd, std::string keys)
|
||||
: keys(std::move(keys))
|
||||
, cmd_name(std::move(cmd))
|
||||
, context(std::move(ctx))
|
||||
{
|
||||
}
|
||||
|
||||
/// String representation of the Combo
|
||||
std::string Str() const;
|
||||
|
||||
/// String suitable for usage in a menu.
|
||||
std::string StrMenu() const;
|
||||
|
||||
/// Get the literal combo map.
|
||||
/// @return ComboMap (std::vector) of linear key sequence.
|
||||
const std::vector<std::string>& Get() const { return key_map; }
|
||||
std::string Str() const { return keys; }
|
||||
|
||||
/// Command name triggered by the combination.
|
||||
/// @return Command name
|
||||
const std::string& CmdName() const { return cmd_name; }
|
||||
std::string const& CmdName() const { return cmd_name; }
|
||||
|
||||
/// Context this Combo is triggered in.
|
||||
const std::string& Context() const { return context; }
|
||||
std::string const& Context() const { return context; }
|
||||
};
|
||||
|
||||
|
||||
/// @class Hotkey
|
||||
/// Holds the map of Combo instances and handles searching for matching key sequences.
|
||||
class Hotkey {
|
||||
|
@ -76,22 +64,20 @@ public:
|
|||
/// Map to hold Combo instances
|
||||
typedef std::multimap<std::string, Combo> HotkeyMap;
|
||||
private:
|
||||
HotkeyMap str_map; ///< String representation -> Combo
|
||||
HotkeyMap cmd_map; ///< Command name -> Combo
|
||||
const agi::fs::path config_file; ///< Default user config location.
|
||||
HotkeyMap cmd_map; ///< Command name -> Combo
|
||||
std::vector<const Combo *> str_map; ///< Sorted by string representation
|
||||
const agi::fs::path config_file; ///< Default user config location.
|
||||
|
||||
/// Build hotkey map.
|
||||
/// @param context Context being parsed.
|
||||
/// @param object json::Object holding items for context being parsed.
|
||||
void BuildHotkey(std::string const& context, const json::Object& object);
|
||||
|
||||
/// Insert Combo into HotkeyMap instance.
|
||||
/// @param combo Combo to insert.
|
||||
void ComboInsert(Combo const& combo);
|
||||
|
||||
/// Write active Hotkey configuration to disk.
|
||||
void Flush();
|
||||
|
||||
void UpdateStrMap();
|
||||
|
||||
/// Announce that the loaded hotkeys have been changed
|
||||
agi::signal::Signal<> HotkeysChanged;
|
||||
public:
|
||||
|
@ -129,7 +115,7 @@ public:
|
|||
HotkeyMap const& GetHotkeyMap() const { return cmd_map; }
|
||||
|
||||
/// Replace the loaded hotkeys with a new set
|
||||
void SetHotkeyMap(HotkeyMap const& new_map);
|
||||
void SetHotkeyMap(HotkeyMap new_map);
|
||||
|
||||
DEFINE_SIGNAL_ADDERS(HotkeysChanged, AddHotkeyChangeListener)
|
||||
};
|
||||
|
|
256
src/hotkey.cpp
256
src/hotkey.cpp
|
@ -12,10 +12,6 @@
|
|||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
/// @file hotkey.cpp
|
||||
/// @brief Hotkey handler
|
||||
/// @ingroup hotkey menu event window
|
||||
|
||||
#include <libaegisub/hotkey.h>
|
||||
|
||||
#include "include/aegisub/hotkey.h"
|
||||
|
@ -33,42 +29,40 @@
|
|||
#include <wx/msgdlg.h>
|
||||
|
||||
namespace {
|
||||
const char *added_hotkeys_7035[][5] = {
|
||||
{ "audio/play/line", "Audio", "R", nullptr, nullptr },
|
||||
{ nullptr }
|
||||
const char *added_hotkeys_7035[][3] = {
|
||||
{"audio/play/line", "Audio", "R"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
const char *added_hotkeys_7070[][5] = {
|
||||
{ "edit/color/primary", "Subtitle Edit Box", "Alt", "1", nullptr },
|
||||
{ "edit/color/secondary", "Subtitle Edit Box", "Alt", "2", nullptr },
|
||||
{ "edit/color/outline", "Subtitle Edit Box", "Alt", "3", nullptr },
|
||||
{ "edit/color/shadow", "Subtitle Edit Box", "Alt", "4", nullptr },
|
||||
{ nullptr }
|
||||
const char *added_hotkeys_7070[][3] = {
|
||||
{"edit/color/primary", "Subtitle Edit Box", "Alt-1"},
|
||||
{"edit/color/secondary", "Subtitle Edit Box", "Alt-2"},
|
||||
{"edit/color/outline", "Subtitle Edit Box", "Alt-3"},
|
||||
{"edit/color/shadow", "Subtitle Edit Box", "Alt-4"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
const char *added_hotkeys_shift_back[][5] = {
|
||||
{ "edit/line/duplicate/shift_back", "Default", "Ctrl", "Shift", "D" },
|
||||
{ nullptr }
|
||||
const char *added_hotkeys_shift_back[][3] = {
|
||||
{"edit/line/duplicate/shift_back", "Default", "Ctrl-Shift-D"},
|
||||
{nullptr}
|
||||
};
|
||||
|
||||
void migrate_hotkeys(const char *added[][5]) {
|
||||
agi::hotkey::Hotkey::HotkeyMap hk_map = hotkey::inst->GetHotkeyMap();
|
||||
void migrate_hotkeys(const char *added[][3]) {
|
||||
auto hk_map = hotkey::inst->GetHotkeyMap();
|
||||
bool changed = false;
|
||||
|
||||
for (size_t i = 0; added[i] && added[i][0]; ++i) {
|
||||
std::vector<std::string> keys;
|
||||
for (size_t j = 2; j < 5; ++j) {
|
||||
if (added[i][j])
|
||||
keys.emplace_back(added[i][j]);
|
||||
}
|
||||
agi::hotkey::Combo combo(added[i][1], added[i][0], keys);
|
||||
agi::hotkey::Combo combo(added[i][1], added[i][0], added[i][2]);
|
||||
|
||||
if (hotkey::inst->HasHotkey(combo.Context(), combo.Str()))
|
||||
continue;
|
||||
|
||||
hk_map.insert(make_pair(std::string(added[i][0]), combo));
|
||||
hk_map.insert(make_pair(std::string(added[i][0]), std::move(combo)));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
hotkey::inst->SetHotkeyMap(hk_map);
|
||||
if (changed)
|
||||
hotkey::inst->SetHotkeyMap(std::move(hk_map));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,18 +94,18 @@ void init() {
|
|||
if (boost::find(migrations, "duplicate -> split") == end(migrations)) {
|
||||
auto hk_map = hotkey::inst->GetHotkeyMap();
|
||||
for (auto const& hotkey : boost::make_iterator_range(hk_map.equal_range("edit/line/duplicate/shift"))) {
|
||||
auto combo = agi::hotkey::Combo(hotkey.second.Context(), "edit/line/split/before", hotkey.second.Get());
|
||||
auto combo = agi::hotkey::Combo(hotkey.second.Context(), "edit/line/split/before", hotkey.second.Str());
|
||||
hk_map.insert({combo.CmdName(), combo});
|
||||
}
|
||||
for (auto const& hotkey : boost::make_iterator_range(hk_map.equal_range("edit/line/duplicate/shift_back"))) {
|
||||
auto combo = agi::hotkey::Combo(hotkey.second.Context(), "edit/line/split/after", hotkey.second.Get());
|
||||
auto combo = agi::hotkey::Combo(hotkey.second.Context(), "edit/line/split/after", hotkey.second.Str());
|
||||
hk_map.insert({combo.CmdName(), combo});
|
||||
}
|
||||
|
||||
hk_map.erase("edit/line/duplicate/shift");
|
||||
hk_map.erase("edit/line/duplicate/shift_back");
|
||||
|
||||
hotkey::inst->SetHotkeyMap(hk_map);
|
||||
hotkey::inst->SetHotkeyMap(std::move(hk_map));
|
||||
migrations.emplace_back("duplicate -> split");
|
||||
}
|
||||
|
||||
|
@ -122,20 +116,95 @@ void clear() {
|
|||
delete inst;
|
||||
}
|
||||
|
||||
static std::vector<std::string> keycode_names;
|
||||
|
||||
static void init_keycode_names();
|
||||
|
||||
static std::string const& keycode_name(int code) {
|
||||
if (keycode_names.empty())
|
||||
init_keycode_names();
|
||||
|
||||
if (static_cast<size_t>(code) > keycode_names.size()) {
|
||||
static std::string str;
|
||||
return str;
|
||||
static const char *keycode_name(int code) {
|
||||
switch (code) {
|
||||
case WXK_BACK: return "Backspace";
|
||||
case WXK_TAB: return "Tab";
|
||||
case WXK_RETURN: return "Enter";
|
||||
case WXK_ESCAPE: return "Escape";
|
||||
case WXK_SPACE: return "Space";
|
||||
case WXK_DELETE: return "Delete";
|
||||
case WXK_SHIFT: return "Shift";
|
||||
case WXK_ALT: return "Alt";
|
||||
case WXK_CONTROL: return "Control";
|
||||
case WXK_PAUSE: return "Pause";
|
||||
case WXK_END: return "End";
|
||||
case WXK_HOME: return "Home";
|
||||
case WXK_LEFT: return "Left";
|
||||
case WXK_UP: return "Up";
|
||||
case WXK_RIGHT: return "Right";
|
||||
case WXK_DOWN: return "Down";
|
||||
case WXK_PRINT: return "Print";
|
||||
case WXK_INSERT: return "Insert";
|
||||
case WXK_NUMPAD0: return "KP_0";
|
||||
case WXK_NUMPAD1: return "KP_1";
|
||||
case WXK_NUMPAD2: return "KP_2";
|
||||
case WXK_NUMPAD3: return "KP_3";
|
||||
case WXK_NUMPAD4: return "KP_4";
|
||||
case WXK_NUMPAD5: return "KP_5";
|
||||
case WXK_NUMPAD6: return "KP_6";
|
||||
case WXK_NUMPAD7: return "KP_7";
|
||||
case WXK_NUMPAD8: return "KP_8";
|
||||
case WXK_NUMPAD9: return "KP_9";
|
||||
case WXK_MULTIPLY: return "Asterisk";
|
||||
case WXK_ADD: return "Plus";
|
||||
case WXK_SUBTRACT: return "Hyphen";
|
||||
case WXK_DECIMAL: return "Period";
|
||||
case WXK_DIVIDE: return "Slash";
|
||||
case WXK_F1: return "F1";
|
||||
case WXK_F2: return "F2";
|
||||
case WXK_F3: return "F3";
|
||||
case WXK_F4: return "F4";
|
||||
case WXK_F5: return "F5";
|
||||
case WXK_F6: return "F6";
|
||||
case WXK_F7: return "F7";
|
||||
case WXK_F8: return "F8";
|
||||
case WXK_F9: return "F9";
|
||||
case WXK_F10: return "F10";
|
||||
case WXK_F11: return "F11";
|
||||
case WXK_F12: return "F12";
|
||||
case WXK_F13: return "F13";
|
||||
case WXK_F14: return "F14";
|
||||
case WXK_F15: return "F15";
|
||||
case WXK_F16: return "F16";
|
||||
case WXK_F17: return "F17";
|
||||
case WXK_F18: return "F18";
|
||||
case WXK_F19: return "F19";
|
||||
case WXK_F20: return "F20";
|
||||
case WXK_F21: return "F21";
|
||||
case WXK_F22: return "F22";
|
||||
case WXK_F23: return "F23";
|
||||
case WXK_F24: return "F24";
|
||||
case WXK_NUMLOCK: return "Num_Lock";
|
||||
case WXK_SCROLL: return "Scroll_Lock";
|
||||
case WXK_PAGEUP: return "PageUp";
|
||||
case WXK_PAGEDOWN: return "PageDown";
|
||||
case WXK_NUMPAD_SPACE: return "KP_Space";
|
||||
case WXK_NUMPAD_TAB: return "KP_Tab";
|
||||
case WXK_NUMPAD_ENTER: return "KP_Enter";
|
||||
case WXK_NUMPAD_F1: return "KP_F1";
|
||||
case WXK_NUMPAD_F2: return "KP_F2";
|
||||
case WXK_NUMPAD_F3: return "KP_F3";
|
||||
case WXK_NUMPAD_F4: return "KP_F4";
|
||||
case WXK_NUMPAD_HOME: return "KP_Home";
|
||||
case WXK_NUMPAD_LEFT: return "KP_Left";
|
||||
case WXK_NUMPAD_UP: return "KP_Up";
|
||||
case WXK_NUMPAD_RIGHT: return "KP_Right";
|
||||
case WXK_NUMPAD_DOWN: return "KP_Down";
|
||||
case WXK_NUMPAD_PAGEUP: return "KP_PageUp";
|
||||
case WXK_NUMPAD_PAGEDOWN: return "KP_PageDown";
|
||||
case WXK_NUMPAD_END: return "KP_End";
|
||||
case WXK_NUMPAD_BEGIN: return "KP_Begin";
|
||||
case WXK_NUMPAD_INSERT: return "KP_insert";
|
||||
case WXK_NUMPAD_DELETE: return "KP_Delete";
|
||||
case WXK_NUMPAD_EQUAL: return "KP_Equal";
|
||||
case WXK_NUMPAD_MULTIPLY: return "KP_Multiply";
|
||||
case WXK_NUMPAD_ADD: return "KP_Add";
|
||||
case WXK_NUMPAD_SUBTRACT: return "KP_Subtract";
|
||||
case WXK_NUMPAD_DECIMAL: return "KP_Decimal";
|
||||
case WXK_NUMPAD_DIVIDE: return "KP_Divide";
|
||||
default: return "";
|
||||
}
|
||||
|
||||
return keycode_names[code];
|
||||
}
|
||||
|
||||
std::string keypress_to_str(int key_code, int modifier) {
|
||||
|
@ -146,7 +215,10 @@ std::string keypress_to_str(int key_code, int modifier) {
|
|||
if ((modifier & wxMOD_SHIFT) != 0) combo.append("Shift-");
|
||||
}
|
||||
|
||||
combo += keycode_name(key_code);
|
||||
if (key_code < 127)
|
||||
combo += (char)key_code;
|
||||
else
|
||||
combo += keycode_name(key_code);
|
||||
|
||||
return combo;
|
||||
}
|
||||
|
@ -186,102 +258,4 @@ std::string get_hotkey_str_first(std::string const& context, std::string const&
|
|||
return inst->GetHotkey(context, command);
|
||||
}
|
||||
|
||||
static inline void set_kc(std::vector<std::string> &vec, int code, std::string const& str) {
|
||||
if (static_cast<size_t>(code) >= vec.size()) vec.resize(code * 2, "");
|
||||
vec[code] = str;
|
||||
}
|
||||
|
||||
static void init_keycode_names() {
|
||||
char str[] = { 0, 0 };
|
||||
for (char i = 33; i < 127; ++i) {
|
||||
str[0] = i;
|
||||
set_kc(keycode_names, i, str);
|
||||
}
|
||||
set_kc(keycode_names, WXK_BACK, "Backspace");
|
||||
set_kc(keycode_names, WXK_TAB, "Tab");
|
||||
set_kc(keycode_names, WXK_RETURN, "Enter");
|
||||
set_kc(keycode_names, WXK_ESCAPE, "Escape");
|
||||
set_kc(keycode_names, WXK_SPACE, "Space");
|
||||
set_kc(keycode_names, WXK_DELETE, "Delete");
|
||||
set_kc(keycode_names, WXK_SHIFT, "Shift");
|
||||
set_kc(keycode_names, WXK_ALT, "Alt");
|
||||
set_kc(keycode_names, WXK_CONTROL, "Control");
|
||||
set_kc(keycode_names, WXK_PAUSE, "Pause");
|
||||
set_kc(keycode_names, WXK_END, "End");
|
||||
set_kc(keycode_names, WXK_HOME, "Home");
|
||||
set_kc(keycode_names, WXK_LEFT, "Left");
|
||||
set_kc(keycode_names, WXK_UP, "Up");
|
||||
set_kc(keycode_names, WXK_RIGHT, "Right");
|
||||
set_kc(keycode_names, WXK_DOWN, "Down");
|
||||
set_kc(keycode_names, WXK_PRINT, "Print");
|
||||
set_kc(keycode_names, WXK_INSERT, "Insert");
|
||||
set_kc(keycode_names, WXK_NUMPAD0, "KP_0");
|
||||
set_kc(keycode_names, WXK_NUMPAD1, "KP_1");
|
||||
set_kc(keycode_names, WXK_NUMPAD2, "KP_2");
|
||||
set_kc(keycode_names, WXK_NUMPAD3, "KP_3");
|
||||
set_kc(keycode_names, WXK_NUMPAD4, "KP_4");
|
||||
set_kc(keycode_names, WXK_NUMPAD5, "KP_5");
|
||||
set_kc(keycode_names, WXK_NUMPAD6, "KP_6");
|
||||
set_kc(keycode_names, WXK_NUMPAD7, "KP_7");
|
||||
set_kc(keycode_names, WXK_NUMPAD8, "KP_8");
|
||||
set_kc(keycode_names, WXK_NUMPAD9, "KP_9");
|
||||
set_kc(keycode_names, WXK_MULTIPLY, "Asterisk");
|
||||
set_kc(keycode_names, WXK_ADD, "Plus");
|
||||
set_kc(keycode_names, WXK_SUBTRACT, "Hyphen");
|
||||
set_kc(keycode_names, WXK_DECIMAL, "Period");
|
||||
set_kc(keycode_names, WXK_DIVIDE, "Slash");
|
||||
set_kc(keycode_names, WXK_F1, "F1");
|
||||
set_kc(keycode_names, WXK_F2, "F2");
|
||||
set_kc(keycode_names, WXK_F3, "F3");
|
||||
set_kc(keycode_names, WXK_F4, "F4");
|
||||
set_kc(keycode_names, WXK_F5, "F5");
|
||||
set_kc(keycode_names, WXK_F6, "F6");
|
||||
set_kc(keycode_names, WXK_F7, "F7");
|
||||
set_kc(keycode_names, WXK_F8, "F8");
|
||||
set_kc(keycode_names, WXK_F9, "F9");
|
||||
set_kc(keycode_names, WXK_F10, "F10");
|
||||
set_kc(keycode_names, WXK_F11, "F11");
|
||||
set_kc(keycode_names, WXK_F12, "F12");
|
||||
set_kc(keycode_names, WXK_F13, "F13");
|
||||
set_kc(keycode_names, WXK_F14, "F14");
|
||||
set_kc(keycode_names, WXK_F15, "F15");
|
||||
set_kc(keycode_names, WXK_F16, "F16");
|
||||
set_kc(keycode_names, WXK_F17, "F17");
|
||||
set_kc(keycode_names, WXK_F18, "F18");
|
||||
set_kc(keycode_names, WXK_F19, "F19");
|
||||
set_kc(keycode_names, WXK_F20, "F20");
|
||||
set_kc(keycode_names, WXK_F21, "F21");
|
||||
set_kc(keycode_names, WXK_F22, "F22");
|
||||
set_kc(keycode_names, WXK_F23, "F23");
|
||||
set_kc(keycode_names, WXK_F24, "F24");
|
||||
set_kc(keycode_names, WXK_NUMLOCK, "Num_Lock");
|
||||
set_kc(keycode_names, WXK_SCROLL, "Scroll_Lock");
|
||||
set_kc(keycode_names, WXK_PAGEUP, "PageUp");
|
||||
set_kc(keycode_names, WXK_PAGEDOWN, "PageDown");
|
||||
set_kc(keycode_names, WXK_NUMPAD_SPACE, "KP_Space");
|
||||
set_kc(keycode_names, WXK_NUMPAD_TAB, "KP_Tab");
|
||||
set_kc(keycode_names, WXK_NUMPAD_ENTER, "KP_Enter");
|
||||
set_kc(keycode_names, WXK_NUMPAD_F1, "KP_F1");
|
||||
set_kc(keycode_names, WXK_NUMPAD_F2, "KP_F2");
|
||||
set_kc(keycode_names, WXK_NUMPAD_F3, "KP_F3");
|
||||
set_kc(keycode_names, WXK_NUMPAD_F4, "KP_F4");
|
||||
set_kc(keycode_names, WXK_NUMPAD_HOME, "KP_Home");
|
||||
set_kc(keycode_names, WXK_NUMPAD_LEFT, "KP_Left");
|
||||
set_kc(keycode_names, WXK_NUMPAD_UP, "KP_Up");
|
||||
set_kc(keycode_names, WXK_NUMPAD_RIGHT, "KP_Right");
|
||||
set_kc(keycode_names, WXK_NUMPAD_DOWN, "KP_Down");
|
||||
set_kc(keycode_names, WXK_NUMPAD_PAGEUP, "KP_PageUp");
|
||||
set_kc(keycode_names, WXK_NUMPAD_PAGEDOWN, "KP_PageDown");
|
||||
set_kc(keycode_names, WXK_NUMPAD_END, "KP_End");
|
||||
set_kc(keycode_names, WXK_NUMPAD_BEGIN, "KP_Begin");
|
||||
set_kc(keycode_names, WXK_NUMPAD_INSERT, "KP_insert");
|
||||
set_kc(keycode_names, WXK_NUMPAD_DELETE, "KP_Delete");
|
||||
set_kc(keycode_names, WXK_NUMPAD_EQUAL, "KP_Equal");
|
||||
set_kc(keycode_names, WXK_NUMPAD_MULTIPLY, "KP_Multiply");
|
||||
set_kc(keycode_names, WXK_NUMPAD_ADD, "KP_Add");
|
||||
set_kc(keycode_names, WXK_NUMPAD_SUBTRACT, "KP_Subtract");
|
||||
set_kc(keycode_names, WXK_NUMPAD_DECIMAL, "KP_Decimal");
|
||||
set_kc(keycode_names, WXK_NUMPAD_DIVIDE, "KP_Divide");
|
||||
}
|
||||
|
||||
} // namespace hotkey
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <libaegisub/exception.h>
|
||||
#include <libaegisub/hotkey.h>
|
||||
#include <libaegisub/make_unique.h>
|
||||
#include <libaegisub/split.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
|
@ -111,11 +110,7 @@ public:
|
|||
|
||||
bool SetValue(wxVariant const& variant, unsigned int col) override {
|
||||
if (col == 0) {
|
||||
std::vector<std::string> keys;
|
||||
auto str = from_wx(variant.GetString());
|
||||
for (auto tok : agi::Split(str, '-'))
|
||||
keys.emplace_back(begin(tok), end(tok));
|
||||
combo = Combo(combo.Context(), combo.CmdName(), keys);
|
||||
combo = Combo(combo.Context(), combo.CmdName(), from_wx(variant.GetString()));
|
||||
cmd_str = combo.Str();
|
||||
return true;
|
||||
}
|
||||
|
@ -123,7 +118,7 @@ public:
|
|||
wxDataViewIconText text;
|
||||
text << variant;
|
||||
cmd_name = from_wx(text.GetText());
|
||||
combo = Combo(combo.Context(), cmd_name, combo.Get());
|
||||
combo = Combo(combo.Context(), cmd_name, combo.Str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -307,7 +302,7 @@ wxDataViewItem HotkeyDataViewModel::New(wxDataViewItem item) {
|
|||
HotkeyModelCategory *ctx = static_cast<HotkeyModelCategory*>(item.GetID());
|
||||
wxVariant name;
|
||||
ctx->GetValue(name, 0);
|
||||
return ctx->AddChild(Combo(from_wx(name.GetString()), "", std::vector<std::string>()));
|
||||
return ctx->AddChild(Combo(from_wx(name.GetString()), "", ""));
|
||||
}
|
||||
|
||||
void HotkeyDataViewModel::Delete(wxDataViewItem const& item) {
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
#include <libaegisub/fs.h>
|
||||
#include <libaegisub/hotkey.h>
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
using namespace agi::hotkey;
|
||||
|
||||
static const char simple_valid[] = "{"
|
||||
"\"Always\":{\"cmd1\":[{\"modifiers\":[\"Ctrl\"], \"key\":\"C\"}]},"
|
||||
"\"Default\":{\"cmd1\":[{\"modifiers\":[\"Alt\"], \"key\":\"C\"}], \"cmd2\":[{\"modifiers\":[\"Ctrl\"], \"key\":\"C\"}]},"
|
||||
"\"Other\":{\"cmd1\":[{\"modifiers\":[\"Shift\"], \"key\":\"C\"}], \"cmd3\":[{\"modifiers\":[], \"key\":\"Q\"}]}"
|
||||
"}";
|
||||
static const char simple_valid[] = R"raw({
|
||||
"Always":{"cmd1":[{"modifiers":["Ctrl"], "key":"C"}]},
|
||||
"Default":{"cmd1":[{"modifiers":["Alt"], "key":"C"}], "cmd2":[{"modifiers":["Ctrl"], "key":"C"}]},
|
||||
"Other":{"cmd1":[{"modifiers":["Shift"], "key":"C"}], "cmd3":[{"modifiers":[], "key":"Q"}]}
|
||||
})raw";
|
||||
|
||||
TEST(lagi_hotkey, simple_valid_default) {
|
||||
EXPECT_NO_THROW(Hotkey("", simple_valid));
|
||||
|
@ -137,20 +135,18 @@ TEST(lagi_hotkey, get_hotkeys) {
|
|||
EXPECT_EQ(0, h.GetHotkeys("Nonexistent", "cmd4").size());
|
||||
}
|
||||
|
||||
TEST(lagi_hotkey, has_hotkey) {
|
||||
Hotkey h("", simple_valid);
|
||||
EXPECT_TRUE(h.HasHotkey("Always", "Ctrl-C"));
|
||||
EXPECT_FALSE(h.HasHotkey("Always", "Alt-C"));
|
||||
}
|
||||
|
||||
TEST(lagi_hotkey, get_hotkeys_dedups) {
|
||||
Hotkey h("", "{\"Always\":{\"cmd1\":[{\"modifiers\":[\"Ctrl\"], \"key\":\"C\"}]},\"Default\":{\"cmd1\":[{\"modifiers\":[\"Ctrl\"], \"key\":\"C\"}]}}");
|
||||
EXPECT_EQ(1, h.GetHotkeys("Always", "cmd1").size());
|
||||
}
|
||||
|
||||
static void insert_combo(Hotkey::HotkeyMap &hm, const char *ctx, const char *cmd, int N, ...) {
|
||||
std::vector<std::string> keys(N);
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, N);
|
||||
for (int i = 0; i < N; ++i)
|
||||
keys[i] = va_arg(argp, const char *);
|
||||
va_end(argp);
|
||||
|
||||
static void insert_combo(Hotkey::HotkeyMap &hm, const char *ctx, const char *cmd, const char *keys) {
|
||||
hm.insert(make_pair(std::string(cmd), Combo(ctx, cmd, keys)));
|
||||
}
|
||||
|
||||
|
@ -162,8 +158,8 @@ TEST(lagi_hotkey, set_hotkey_map) {
|
|||
Hotkey::HotkeyMap hm = h.GetHotkeyMap();
|
||||
EXPECT_EQ(0, hm.size());
|
||||
|
||||
insert_combo(hm, "Always", "cmd1", 1, "C");
|
||||
insert_combo(hm, "Default", "cmd2", 2, "Shift", "C");
|
||||
insert_combo(hm, "Always", "cmd1", "C");
|
||||
insert_combo(hm, "Default", "cmd2", "Shift-C");
|
||||
|
||||
bool listener_called = false;
|
||||
h.AddHotkeyChangeListener([&] { listener_called = true; });
|
||||
|
@ -189,8 +185,7 @@ TEST(lagi_hotkey, combo_stuff) {
|
|||
ASSERT_EQ(1, std::distance(it, end));
|
||||
|
||||
Combo c = it->second;
|
||||
EXPECT_STREQ("Ctrl-C", c.StrMenu().c_str());
|
||||
EXPECT_STREQ("Ctrl-C", c.Str().c_str());
|
||||
EXPECT_STREQ("cmd2", c.CmdName().c_str());
|
||||
EXPECT_STREQ("Default", c.Context().c_str());
|
||||
EXPECT_EQ(2, c.Get().size());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue