feat: Add shortcut editor to settings

This commit is contained in:
WerWolv
2023-11-17 14:46:21 +01:00
parent 3bd779a607
commit cec925bcdc
12 changed files with 289 additions and 55 deletions

View File

@@ -568,6 +568,10 @@
"hex.builtin.setting.proxy.enable": "Enable Proxy",
"hex.builtin.setting.proxy.url": "Proxy URL",
"hex.builtin.setting.proxy.url.tooltip": "http(s):// or socks5:// (e.g., http://127.0.0.1:1080)",
"hex.builtin.setting.shortcuts": "Shortcuts",
"hex.builtin.setting.shortcuts.global": "Global Shortcuts",
"hex.builtin.shortcut.next_provider": "Select next provider",
"hex.builtin.shortcut.prev_provider": "Select previous provider",
"hex.builtin.title_bar_button.debug_build": "Debug build",
"hex.builtin.title_bar_button.feedback": "Leave Feedback",
"hex.builtin.tools.ascii_table": "ASCII table",
@@ -818,6 +822,7 @@
"hex.builtin.view.find.search.reset": "Reset",
"hex.builtin.view.find.searching": "Searching...",
"hex.builtin.view.find.sequences": "Sequences",
"hex.builtin.view.find.shortcut.select_all": "Select All Occurrences",
"hex.builtin.view.find.strings": "Strings",
"hex.builtin.view.find.strings.chars": "Characters",
"hex.builtin.view.find.strings.line_feeds": "Line Feeds",
@@ -909,6 +914,20 @@
"hex.builtin.view.hex_editor.select.offset.region": "Region",
"hex.builtin.view.hex_editor.select.offset.size": "Size",
"hex.builtin.view.hex_editor.select.select": "Select",
"hex.builtin.view.hex_editor.shortcut.remove_selection": "Remove selection",
"hex.builtin.view.hex_editor.shortcut.enter_editing": "Enter editing mode",
"hex.builtin.view.hex_editor.shortcut.selection_right": "Move selection to the right",
"hex.builtin.view.hex_editor.shortcut.cursor_right": "Move cursor to the right",
"hex.builtin.view.hex_editor.shortcut.selection_left": "Move cursor to the left",
"hex.builtin.view.hex_editor.shortcut.cursor_left": "Move cursor to the left",
"hex.builtin.view.hex_editor.shortcut.selection_up": "Move selection up",
"hex.builtin.view.hex_editor.shortcut.cursor_up": "Move cursor up",
"hex.builtin.view.hex_editor.shortcut.selection_down": "Move selection down",
"hex.builtin.view.hex_editor.shortcut.cursor_down": "Move cursor down",
"hex.builtin.view.hex_editor.shortcut.selection_page_up": "Move selection up one page",
"hex.builtin.view.hex_editor.shortcut.cursor_page_up": "Move cursor up one page",
"hex.builtin.view.hex_editor.shortcut.selection_page_down": "Move selection down one page",
"hex.builtin.view.hex_editor.shortcut.cursor_page_down": "Move cursor down one page",
"hex.builtin.view.information.analyze": "Analyze page",
"hex.builtin.view.information.analyzing": "Analyzing...",
"hex.builtin.view.information.block_size": "Block size",
@@ -975,6 +994,10 @@
"hex.builtin.view.pattern_editor.section_popup": "Section",
"hex.builtin.view.pattern_editor.sections": "Sections",
"hex.builtin.view.pattern_editor.settings": "Settings",
"hex.builtin.view.pattern_editor.shortcut.run_pattern": "Run Pattern",
"hex.builtin.view.pattern_editor.shortcut.step_debugger": "Step Debugger",
"hex.builtin.view.pattern_editor.shortcut.continue_debugger": "Continue Debugger",
"hex.builtin.view.pattern_editor.shortcut.add_breakpoint": "Add Breakpoint",
"hex.builtin.view.provider_settings.load_error": "An error occurred while trying to open this provider!",
"hex.builtin.view.provider_settings.load_error_details": "An error occurred while trying to open this provider!\nDetails: {}",
"hex.builtin.view.provider_settings.load_popup": "Open Provider",

View File

@@ -12,6 +12,7 @@
#include <nlohmann/json.hpp>
#include <utility>
#include <wolv/utils/string.hpp>
namespace hex::plugin::builtin {
@@ -187,6 +188,107 @@ namespace hex::plugin::builtin {
float m_value = 0;
};
class KeybindingWidget : public ContentRegistry::Settings::Widgets::Widget {
public:
KeybindingWidget(View *view, Shortcut shortcut) : m_view(view), m_shortcut(std::move(shortcut)) {}
bool draw(const std::string &name) override {
std::string label;
if (!this->m_editing)
label = this->m_shortcut.toString();
else
label = "...";
if (label.empty())
label = "???";
ImGui::PushID(this);
if (ImGui::Button(label.c_str(), ImVec2(150_scaled, 0))) {
this->m_editing = !this->m_editing;
if (this->m_editing)
ShortcutManager::pauseShortcuts();
else
ShortcutManager::resumeShortcuts();
}
ImGui::PopID();
if (!ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
this->m_editing = false;
ShortcutManager::resumeShortcuts();
}
ImGui::SameLine();
ImGuiExt::TextFormatted("{}", name);
if (this->m_editing) {
if (this->detectShortcut()) {
this->m_editing = false;
ShortcutManager::resumeShortcuts();
return true;
}
}
return false;
}
void load(const nlohmann::json &data) override {
std::set<Key> keys;
for (const auto &key : data.get<std::vector<u32>>())
keys.insert(Key(Keys(key)));
if (keys.empty())
return;
auto newShortcut = Shortcut(keys);
ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
this->m_shortcut = std::move(newShortcut);
}
nlohmann::json store() override {
std::vector<u32> keys;
for (const auto &key : this->m_shortcut.getKeys()) {
if (key != CurrentView)
keys.push_back(key.getKeyCode());
}
return keys;
}
private:
bool detectShortcut() {
if (auto shortcut = ShortcutManager::getPreviousShortcut(); shortcut.has_value()) {
log::info("Changed shortcut to {}", shortcut->toString());
auto keys = this->m_shortcut.getKeys();
std::erase_if(keys, [](Key key) {
return key != AllowWhileTyping && key != CurrentView;
});
for (const auto &key : shortcut->getKeys()) {
keys.insert(key);
}
auto newShortcut = Shortcut(std::move(keys));
ShortcutManager::updateShortcut(this->m_shortcut, newShortcut, this->m_view);
this->m_shortcut = std::move(newShortcut);
return true;
}
return false;
}
private:
View *m_view = nullptr;
Shortcut m_shortcut;
bool m_editing = false;
};
}
void registerSettings() {
@@ -314,6 +416,19 @@ namespace hex::plugin::builtin {
}
});
/* Shorcuts */
EventManager::subscribe<EventImHexStartupFinished>([]{
for (const auto &shortcutEntry : ShortcutManager::getGlobalShortcuts()) {
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", "hex.builtin.setting.shortcuts.global", shortcutEntry.unlocalizedName, nullptr, shortcutEntry.shortcut);
}
for (auto &[viewName, view] : ContentRegistry::Views::impl::getEntries()) {
for (const auto &shortcutEntry : ShortcutManager::getViewShortcuts(view.get())) {
ContentRegistry::Settings::add<KeybindingWidget>("hex.builtin.setting.shortcuts", viewName, shortcutEntry.unlocalizedName, view.get(), shortcutEntry.shortcut);
}
}
});
}
static void loadThemeSettings() {

View File

@@ -141,14 +141,14 @@ namespace hex::plugin::builtin {
}
void addToolbarItems() {
ShortcutManager::addGlobalShortcut(AllowWhileTyping + ALT + CTRLCMD + Keys::Left, []{
ShortcutManager::addGlobalShortcut(AllowWhileTyping + ALT + CTRLCMD + Keys::Left, "hex.builtin.shortcut.prev_provider", []{
auto currIndex = ImHexApi::Provider::getCurrentProviderIndex();
if (currIndex > 0)
ImHexApi::Provider::setCurrentProvider(currIndex - 1);
});
ShortcutManager::addGlobalShortcut(AllowWhileTyping + ALT + CTRLCMD + Keys::Right, []{
ShortcutManager::addGlobalShortcut(AllowWhileTyping + ALT + CTRLCMD + Keys::Right, "hex.builtin.shortcut.next_provider", []{
auto currIndex = ImHexApi::Provider::getCurrentProviderIndex();
const auto &providers = ImHexApi::Provider::getProviders();

View File

@@ -7,7 +7,7 @@ namespace hex::plugin::builtin {
ViewCommandPalette::ViewCommandPalette() : View("hex.builtin.view.command_palette.name") {
// Add global shortcut to open the command palette
ShortcutManager::addGlobalShortcut(CTRLCMD + SHIFT + Keys::P, [this] {
ShortcutManager::addGlobalShortcut(CTRLCMD + SHIFT + Keys::P, "hex.builtin.view.command_palette.name", [this] {
EventManager::post<RequestOpenPopup>("hex.builtin.view.command_palette.name"_lang);
this->m_commandPaletteOpen = true;
this->m_justOpened = true;

View File

@@ -93,7 +93,7 @@ namespace hex::plugin::builtin {
ImGui::EndTooltip();
});
ShortcutManager::addShortcut(this, CTRLCMD + Keys::A, [this] {
ShortcutManager::addShortcut(this, CTRLCMD + Keys::A, "hex.builtin.view.find.shortcut.select_all", [this] {
if (this->m_filterTask.isRunning())
return;
if (this->m_searchTask.isRunning())

View File

@@ -764,7 +764,7 @@ namespace hex::plugin::builtin {
void ViewHexEditor::registerShortcuts() {
// Remove selection
ShortcutManager::addShortcut(this, Keys::Escape, [this] {
ShortcutManager::addShortcut(this, Keys::Escape, "hex.builtin.view.hex_editor.shortcut.remove_selection", [this] {
auto provider = ImHexApi::Provider::get();
this->m_selectionStart->reset();
this->m_selectionEnd->reset();
@@ -772,13 +772,13 @@ namespace hex::plugin::builtin {
EventManager::post<EventRegionSelected>(ImHexApi::HexEditor::ProviderRegion{ this->getSelection(), provider });
});
ShortcutManager::addShortcut(this, Keys::Enter, [this] {
ShortcutManager::addShortcut(this, Keys::Enter, "hex.builtin.view.hex_editor.shortcut.enter_editing", [this] {
if (auto cursor = this->m_hexEditor.getCursorPosition(); cursor.has_value())
this->m_hexEditor.setEditingAddress(cursor.value());
});
// Move cursor around
ShortcutManager::addShortcut(this, Keys::Up, [this] {
ShortcutManager::addShortcut(this, Keys::Up, "hex.builtin.view.hex_editor.shortcut.cursor_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -789,7 +789,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::Down, [this] {
ShortcutManager::addShortcut(this, Keys::Down, "hex.builtin.view.hex_editor.shortcut.cursor_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -798,7 +798,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, Keys::Left, [this] {
ShortcutManager::addShortcut(this, Keys::Left, "hex.builtin.view.hex_editor.shortcut.cursor_left", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -809,7 +809,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::Right, [this] {
ShortcutManager::addShortcut(this, Keys::Right, "hex.builtin.view.hex_editor.shortcut.cursor_right", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -819,7 +819,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, Keys::PageUp, [this] {
ShortcutManager::addShortcut(this, Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.cursor_page_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -831,7 +831,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.jumpIfOffScreen();
}
});
ShortcutManager::addShortcut(this, Keys::PageDown, [this] {
ShortcutManager::addShortcut(this, Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.cursor_page_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -842,7 +842,7 @@ namespace hex::plugin::builtin {
});
// Move selection around
ShortcutManager::addShortcut(this, SHIFT + Keys::Up, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::Up, "hex.builtin.view.hex_editor.shortcut.selection_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
@@ -859,7 +859,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Down, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::Down, "hex.builtin.view.hex_editor.shortcut.selection_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
@@ -876,7 +876,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Left, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::Left, "hex.builtin.view.hex_editor.shortcut.selection_left", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
@@ -893,7 +893,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::Right, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::Right, "hex.builtin.view.hex_editor.shortcut.selection_right", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition();
@@ -910,7 +910,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::PageUp, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::PageUp, "hex.builtin.view.hex_editor.shortcut.selection_page_up", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -927,7 +927,7 @@ namespace hex::plugin::builtin {
this->m_hexEditor.scrollToSelection();
this->m_hexEditor.jumpIfOffScreen();
});
ShortcutManager::addShortcut(this, SHIFT + Keys::PageDown, [this] {
ShortcutManager::addShortcut(this, SHIFT + Keys::PageDown, "hex.builtin.view.hex_editor.shortcut.selection_page_down", [this] {
auto selection = getSelection();
auto cursor = this->m_hexEditor.getCursorPosition().value_or(selection.getEndAddress());
@@ -945,11 +945,6 @@ namespace hex::plugin::builtin {
this->m_hexEditor.jumpIfOffScreen();
});
// Redo shortcut alternative
ShortcutManager::addShortcut(this, CTRLCMD + SHIFT + Keys::Z, [] {
if (ImHexApi::Provider::isValid())
ImHexApi::Provider::get()->redo();
});
}
void ViewHexEditor::registerEvents() {
@@ -1064,8 +1059,7 @@ namespace hex::plugin::builtin {
});
/* Load Encoding File */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.custom_encoding" }, 5050,
Shortcut::None,
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.custom_encoding" }, 5050, Shortcut::None,
[this]{
const auto basePaths = fs::getDefaultPaths(fs::ImHexPath::Encodings);
std::vector<std::fs::path> paths;

View File

@@ -1345,7 +1345,7 @@ namespace hex::plugin::builtin {
}
});
ShortcutManager::addShortcut(this, Keys::F8 + AllowWhileTyping, [this] {
ShortcutManager::addShortcut(this, Keys::F8 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.add_breakpoint", [this] {
auto line = this->m_textEditor.GetCursorPosition().mLine + 1;
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
@@ -1362,19 +1362,19 @@ namespace hex::plugin::builtin {
});
/* Trigger evaluation */
ShortcutManager::addGlobalShortcut(Keys::F5 + AllowWhileTyping, [this] {
ShortcutManager::addGlobalShortcut(Keys::F5 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.run_pattern", [this] {
this->m_triggerAutoEvaluate = true;
});
/* Continue debugger */
ShortcutManager::addGlobalShortcut(SHIFT + Keys::F9 + AllowWhileTyping, [this] {
ShortcutManager::addGlobalShortcut(SHIFT + Keys::F9 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.continue_debugger", [this] {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning())
this->m_breakpointHit = false;
});
/* Step debugger */
ShortcutManager::addGlobalShortcut(SHIFT + Keys::F7 + AllowWhileTyping, [this] {
ShortcutManager::addGlobalShortcut(SHIFT + Keys::F7 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.step_debugger", [this] {
auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
if (runtime.isRunning()) {
runtime.getInternals().evaluator->pauseNextLine();