Added basic command palette (similar to the one in vscode)
This commit is contained in:
parent
56cca88fbd
commit
9123b21e18
@ -77,6 +77,7 @@ add_executable(ImHex
|
||||
source/views/view_disassembler.cpp
|
||||
source/views/view_bookmarks.cpp
|
||||
source/views/view_patches.cpp
|
||||
source/views/view_command_palette.cpp
|
||||
|
||||
libs/glad/source/glad.c
|
||||
|
||||
|
@ -52,7 +52,25 @@ namespace hex {
|
||||
ImGui::OpenPopup("Error");
|
||||
}
|
||||
|
||||
static void setWindowPosition(s32 x, s32 y) {
|
||||
View::s_windowPos = ImVec2(x, y);
|
||||
}
|
||||
|
||||
static const ImVec2& getWindowPosition() {
|
||||
return View::s_windowPos;
|
||||
}
|
||||
|
||||
static void setWindowSize(s32 width, s32 height) {
|
||||
View::s_windowSize = ImVec2(width, height);
|
||||
}
|
||||
|
||||
static const ImVec2& getWindowSize() {
|
||||
return View::s_windowSize;
|
||||
}
|
||||
|
||||
virtual bool hasViewMenuItemEntry() { return true; }
|
||||
virtual ImVec2 getMinSize() { return ImVec2(480, 720); }
|
||||
virtual ImVec2 getMaxSize() { return ImVec2(FLT_MAX, FLT_MAX); }
|
||||
|
||||
bool& getWindowOpenState() {
|
||||
return this->m_windowOpen;
|
||||
@ -85,6 +103,9 @@ namespace hex {
|
||||
static inline std::vector<std::function<void()>> s_deferedCalls;
|
||||
|
||||
static inline std::string s_errorMessage;
|
||||
|
||||
static inline ImVec2 s_windowPos;
|
||||
static inline ImVec2 s_windowSize;
|
||||
};
|
||||
|
||||
void confirmButtons(const char *textLeft, const char *textRight, auto leftButtonFn, auto rightButtonFn) {
|
||||
|
40
include/views/view_command_palette.hpp
Normal file
40
include/views/view_command_palette.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include "imgui.h"
|
||||
#include "views/view.hpp"
|
||||
#include "lang/pattern_data.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include <cstdio>
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace prv { class Provider; }
|
||||
|
||||
class ViewCommandPalette : public View {
|
||||
public:
|
||||
ViewCommandPalette();
|
||||
~ViewCommandPalette() override;
|
||||
|
||||
void createView() override;
|
||||
void createMenu() override;
|
||||
|
||||
bool handleShortcut(int key, int mods) override;
|
||||
|
||||
bool hasViewMenuItemEntry() override { return false; }
|
||||
ImVec2 getMinSize() override { return ImVec2(400, 100); }
|
||||
ImVec2 getMaxSize() override { return ImVec2(400, 100); }
|
||||
|
||||
private:
|
||||
bool m_justOpened = false;
|
||||
std::vector<char> m_commandBuffer;
|
||||
std::vector<std::string> m_lastResults;
|
||||
std::string m_exactResult;
|
||||
|
||||
std::vector<std::string> getCommandResults(std::string_view command);
|
||||
};
|
||||
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
#include "views/view_disassembler.hpp"
|
||||
#include "views/view_bookmarks.hpp"
|
||||
#include "views/view_patches.hpp"
|
||||
#include "views/view_command_palette.hpp"
|
||||
|
||||
#include "providers/provider.hpp"
|
||||
|
||||
@ -43,6 +44,7 @@ int main(int argc, char **argv) {
|
||||
window.addView<hex::ViewBookmarks>(dataProvider);
|
||||
window.addView<hex::ViewPatches>(dataProvider);
|
||||
window.addView<hex::ViewTools>(dataProvider);
|
||||
window.addView<hex::ViewCommandPalette>();
|
||||
window.addView<hex::ViewHelp>();
|
||||
|
||||
if (argc > 1)
|
||||
|
131
source/views/view_command_palette.cpp
Normal file
131
source/views/view_command_palette.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "views/view_command_palette.hpp"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include "helpers/math_evaluator.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewCommandPalette::ViewCommandPalette() : View("Command Palette") {
|
||||
this->getWindowOpenState() = true;
|
||||
|
||||
this->m_commandBuffer.resize(1024, 0x00);
|
||||
this->m_lastResults = this->getCommandResults("");
|
||||
}
|
||||
|
||||
ViewCommandPalette::~ViewCommandPalette() {
|
||||
|
||||
}
|
||||
|
||||
void ViewCommandPalette::createView() {
|
||||
|
||||
auto windowPos = View::getWindowPosition();
|
||||
auto windowSize = View::getWindowSize();
|
||||
auto paletteSize = this->getMinSize();
|
||||
ImGui::SetNextWindowPos(ImVec2(windowPos.x + (windowSize.x - paletteSize.x) / 2.0F, windowPos.y), ImGuiCond_Always);
|
||||
if (ImGui::BeginPopup("Command Palette")) {
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::PushItemWidth(paletteSize.x - ImGui::GetStyle().WindowPadding.x * 2);
|
||||
if (ImGui::InputText("##nolabel", this->m_commandBuffer.data(), this->m_commandBuffer.size(), ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_EnterReturnsTrue,
|
||||
[](ImGuiInputTextCallbackData *callbackData) -> int {
|
||||
auto _this = static_cast<ViewCommandPalette*>(callbackData->UserData);
|
||||
_this->m_lastResults = _this->getCommandResults(callbackData->Buf);
|
||||
|
||||
return 0;
|
||||
}, this)) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (this->m_justOpened) {
|
||||
ImGui::SetKeyboardFocusHere(0);
|
||||
this->m_justOpened = false;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
for (const auto &result : this->m_lastResults) {
|
||||
ImGui::TextUnformatted(result.c_str());
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewCommandPalette::createMenu() {
|
||||
|
||||
}
|
||||
|
||||
bool ViewCommandPalette::handleShortcut(int key, int mods) {
|
||||
if (key == GLFW_KEY_P && mods == (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL)) {
|
||||
View::doLater([this] {
|
||||
this->m_justOpened = true;
|
||||
ImGui::OpenPopup("Command Palette");
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
enum class MatchType {
|
||||
NoMatch,
|
||||
InfoMatch,
|
||||
PartialMatch,
|
||||
PerfectMatch
|
||||
};
|
||||
|
||||
std::vector<std::string> ViewCommandPalette::getCommandResults(std::string_view command) {
|
||||
constexpr auto matchCommand = [](std::string_view currCommand, std::string_view commandToMatch) -> std::pair<MatchType, std::string_view> {
|
||||
if (currCommand.empty()) {
|
||||
return { MatchType::InfoMatch, "" };
|
||||
}
|
||||
else if (currCommand.size() <= commandToMatch.size()) {
|
||||
if (commandToMatch.starts_with(currCommand))
|
||||
return { MatchType::PartialMatch, currCommand };
|
||||
else
|
||||
return { MatchType::NoMatch, { } };
|
||||
}
|
||||
else {
|
||||
if (currCommand.starts_with(commandToMatch))
|
||||
return { MatchType::PerfectMatch, currCommand.substr(commandToMatch.length()) };
|
||||
else
|
||||
return { MatchType::NoMatch, { } };
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::string> results;
|
||||
|
||||
if (auto [match, value] = matchCommand(command, "#"); match != MatchType::NoMatch) {
|
||||
if (match != MatchType::PerfectMatch)
|
||||
results.emplace_back("# (Calculator)");
|
||||
else {
|
||||
MathEvaluator evaluator;
|
||||
evaluator.registerStandardVariables();
|
||||
evaluator.registerStandardFunctions();
|
||||
|
||||
auto result = evaluator.evaluate(std::string(value));
|
||||
|
||||
if (result.has_value())
|
||||
results.emplace_back(hex::format("#%s = %Lf", value.data(), result.value()));
|
||||
else
|
||||
results.emplace_back(hex::format("#%s = ???", value.data()));
|
||||
}
|
||||
}
|
||||
if (auto [match, value] = matchCommand(command, "/find "); match != MatchType::NoMatch) {
|
||||
if (match != MatchType::PerfectMatch)
|
||||
results.emplace_back("/find (Find Command)");
|
||||
else {
|
||||
results.emplace_back(hex::format("Command: Find \"%s\"", value.data()));
|
||||
}
|
||||
}
|
||||
if (auto [match, value] = matchCommand(command, ">"); match != MatchType::NoMatch) {
|
||||
results.emplace_back("> (Command)");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -69,7 +69,7 @@ namespace hex {
|
||||
if (!view->getWindowOpenState())
|
||||
continue;
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(480, 720), ImVec2(FLT_MAX, FLT_MAX));
|
||||
ImGui::SetNextWindowSizeConstraints(view->getMinSize(), view->getMaxSize());
|
||||
view->createView();
|
||||
}
|
||||
|
||||
@ -240,6 +240,26 @@ namespace hex {
|
||||
glfwMakeContextCurrent(this->m_window);
|
||||
glfwSwapInterval(1);
|
||||
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
glfwGetWindowPos(this->m_window, &x, &y);
|
||||
View::setWindowPosition(x, y);
|
||||
}
|
||||
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
glfwGetWindowSize(this->m_window, &width, &height);
|
||||
View::setWindowSize(width, height);
|
||||
}
|
||||
|
||||
glfwSetWindowPosCallback(this->m_window, [](GLFWwindow *window, int x, int y) {
|
||||
View::setWindowPosition(x, y);
|
||||
});
|
||||
|
||||
glfwSetWindowSizeCallback(this->m_window, [](GLFWwindow *window, int width, int height) {
|
||||
View::setWindowSize(width, height);
|
||||
});
|
||||
|
||||
glfwSetKeyCallback(this->m_window, [](GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||
if (action == GLFW_PRESS)
|
||||
Window::s_currShortcut = { key, mods };
|
||||
|
Loading…
x
Reference in New Issue
Block a user