Fixed command palette and added /web command
This commit is contained in:
parent
1b98afe37d
commit
179e222919
@ -22,6 +22,7 @@ namespace hex {
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
bool isAvailable() override { return true; }
|
||||
bool shouldProcess() override { return true; }
|
||||
|
||||
bool handleShortcut(int key, int mods) override;
|
||||
|
||||
@ -30,12 +31,32 @@ namespace hex {
|
||||
ImVec2 getMaxSize() override { return ImVec2(400, 100); }
|
||||
|
||||
private:
|
||||
enum class MatchType {
|
||||
NoMatch,
|
||||
InfoMatch,
|
||||
PartialMatch,
|
||||
PerfectMatch
|
||||
};
|
||||
|
||||
struct CommandResult {
|
||||
std::string displayResult;
|
||||
std::string matchedCommand;
|
||||
std::function<void(std::string)> executeCallback;
|
||||
};
|
||||
|
||||
bool m_commandPaletteOpen = false;
|
||||
bool m_justOpened = false;
|
||||
bool m_focusInputTextBox = false;
|
||||
|
||||
std::vector<char> m_commandBuffer;
|
||||
std::vector<std::string> m_lastResults;
|
||||
std::vector<CommandResult> m_lastResults;
|
||||
std::string m_exactResult;
|
||||
|
||||
std::vector<std::string> getCommandResults(std::string_view command);
|
||||
void focusInputTextBox() {
|
||||
this->m_focusInputTextBox = true;
|
||||
}
|
||||
|
||||
std::vector<CommandResult> getCommandResults(std::string_view command);
|
||||
};
|
||||
|
||||
}
|
@ -18,7 +18,8 @@ namespace hex::plugin::builtin {
|
||||
|
||||
try {
|
||||
result = evaluator.evaluate(input);
|
||||
} catch (std::runtime_error &e) {}
|
||||
} catch (std::exception &e) {}
|
||||
|
||||
|
||||
if (result.has_value())
|
||||
return hex::format("#%s = %Lf", input.data(), result.value());
|
||||
@ -26,6 +27,16 @@ namespace hex::plugin::builtin {
|
||||
return hex::format("#%s = ???", input.data());
|
||||
});
|
||||
|
||||
hex::ContentRegistry::CommandPaletteCommands::add(
|
||||
hex::ContentRegistry::CommandPaletteCommands::Type::KeywordCommand,
|
||||
"/web", "Website lookup",
|
||||
[](auto input) {
|
||||
return hex::format("Navigate to '%s'", input.data());
|
||||
},
|
||||
[](auto input) {
|
||||
hex::openWebpage(input);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -74,10 +74,11 @@ namespace hex {
|
||||
Type type;
|
||||
std::string command;
|
||||
std::string description;
|
||||
std::function<std::string(std::string)> callback;
|
||||
std::function<std::string(std::string)> displayCallback;
|
||||
std::function<void(std::string)> executeCallback;
|
||||
};
|
||||
|
||||
static void add(Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &callback);
|
||||
static void add(Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &displayCallback, const std::function<void(std::string)> &executeCallback = [](auto){});
|
||||
static std::vector<Entry>& getEntries();
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@ namespace hex {
|
||||
virtual void drawMenu();
|
||||
virtual bool handleShortcut(int key, int mods);
|
||||
virtual bool isAvailable();
|
||||
virtual bool shouldProcess() { return this->isAvailable() && this->getWindowOpenState(); }
|
||||
|
||||
static void openFileBrowser(std::string title, imgui_addons::ImGuiFileBrowser::DialogMode mode, std::string validExtensions, const std::function<void(std::string)> &callback);
|
||||
static void doLater(std::function<void()> &&function);
|
||||
|
@ -127,8 +127,8 @@ namespace hex {
|
||||
|
||||
/* Command Palette Commands */
|
||||
|
||||
void ContentRegistry::CommandPaletteCommands::add(ContentRegistry::CommandPaletteCommands::Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &callback) {
|
||||
getEntries().push_back(ContentRegistry::CommandPaletteCommands::Entry{ type, command.data(), description.data(), callback });
|
||||
void ContentRegistry::CommandPaletteCommands::add(ContentRegistry::CommandPaletteCommands::Type type, std::string_view command, std::string_view description, const std::function<std::string(std::string)> &displayCallback, const std::function<void(std::string)> &executeCallback) {
|
||||
getEntries().push_back(ContentRegistry::CommandPaletteCommands::Entry{ type, command.data(), description.data(), displayCallback, executeCallback });
|
||||
}
|
||||
|
||||
std::vector<ContentRegistry::CommandPaletteCommands::Entry>& ContentRegistry::CommandPaletteCommands::getEntries() {
|
||||
|
@ -55,7 +55,7 @@ namespace hex::crypt {
|
||||
}
|
||||
|
||||
u32 crc32(prv::Provider* &data, u64 offset, size_t size, u32 polynomial, u32 init) {
|
||||
auto table = [polynomial] {
|
||||
const auto table = [polynomial] {
|
||||
std::array<uint32_t, 256> table = {0};
|
||||
|
||||
for (uint32_t i = 0; i < 256; i++) {
|
||||
|
@ -6,7 +6,6 @@ namespace hex {
|
||||
|
||||
ViewCommandPalette::ViewCommandPalette() : View("Command Palette") {
|
||||
this->m_commandBuffer.resize(1024, 0x00);
|
||||
this->m_lastResults = this->getCommandResults("");
|
||||
}
|
||||
|
||||
ViewCommandPalette::~ViewCommandPalette() {
|
||||
@ -15,17 +14,14 @@ namespace hex {
|
||||
|
||||
void ViewCommandPalette::drawContent() {
|
||||
|
||||
if (!this->getWindowOpenState()) return;
|
||||
if (!this->m_commandPaletteOpen) return;
|
||||
|
||||
auto windowPos = SharedData::windowPos;
|
||||
auto windowSize = SharedData::windowSize;
|
||||
auto paletteSize = this->getMinSize();
|
||||
ImGui::SetNextWindowPos(ImVec2(windowPos.x + (windowSize.x - paletteSize.x) / 2.0F, windowPos.y), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(SharedData::windowPos.x + SharedData::windowSize.x * 0.5F, SharedData::windowPos.y), ImGuiCond_Always, ImVec2(0.5F,0.0F));
|
||||
if (ImGui::BeginPopup("Command Palette")) {
|
||||
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
ImGui::PushItemWidth(paletteSize.x - ImGui::GetStyle().WindowPadding.x * 2);
|
||||
ImGui::PushItemWidth(-1);
|
||||
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);
|
||||
@ -33,24 +29,36 @@ namespace hex {
|
||||
|
||||
return 0;
|
||||
}, this)) {
|
||||
if (!this->m_lastResults.empty()) {
|
||||
auto &[displayResult, matchedCommand, callback] = this->m_lastResults.front();
|
||||
callback(matchedCommand);
|
||||
}
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (this->m_justOpened) {
|
||||
ImGui::SetKeyboardFocusHere(0);
|
||||
focusInputTextBox();
|
||||
this->m_lastResults = this->getCommandResults("");
|
||||
std::memset(this->m_commandBuffer.data(), 0x00, this->m_commandBuffer.size());
|
||||
this->m_justOpened = false;
|
||||
}
|
||||
|
||||
if (this->m_focusInputTextBox) {
|
||||
ImGui::SetKeyboardFocusHere(0);
|
||||
this->m_focusInputTextBox = false;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
for (const auto &result : this->m_lastResults) {
|
||||
ImGui::TextUnformatted(result.c_str());
|
||||
for (const auto &[displayResult, matchedCommand, callback] : this->m_lastResults) {
|
||||
if (ImGui::Selectable(displayResult.c_str(), false, ImGuiSelectableFlags_DontClosePopups))
|
||||
callback(matchedCommand);
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
this->getWindowOpenState() = false;
|
||||
this->m_commandPaletteOpen = false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -62,9 +70,9 @@ namespace hex {
|
||||
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");
|
||||
this->getWindowOpenState() = true;
|
||||
this->m_commandPaletteOpen = true;
|
||||
this->m_justOpened = true;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -72,15 +80,8 @@ namespace hex {
|
||||
return false;
|
||||
}
|
||||
|
||||
enum class MatchType {
|
||||
NoMatch,
|
||||
InfoMatch,
|
||||
PartialMatch,
|
||||
PerfectMatch
|
||||
};
|
||||
|
||||
std::vector<std::string> ViewCommandPalette::getCommandResults(std::string_view input) {
|
||||
constexpr auto matchCommand = [](std::string_view currCommand, std::string_view commandToMatch) -> std::pair<MatchType, std::string_view> {
|
||||
std::vector<ViewCommandPalette::CommandResult> ViewCommandPalette::getCommandResults(std::string_view input) {
|
||||
constexpr auto MatchCommand = [](std::string_view currCommand, std::string_view commandToMatch) -> std::pair<MatchType, std::string_view> {
|
||||
if (currCommand.empty()) {
|
||||
return { MatchType::InfoMatch, "" };
|
||||
}
|
||||
@ -98,23 +99,33 @@ namespace hex {
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<std::string> results;
|
||||
std::vector<CommandResult> results;
|
||||
|
||||
for (const auto &[type, command, description, callback] : ContentRegistry::CommandPaletteCommands::getEntries()) {
|
||||
for (const auto &[type, command, description, displayCallback, executeCallback] : ContentRegistry::CommandPaletteCommands::getEntries()) {
|
||||
|
||||
auto AutoComplete = [this, &currCommand = command](auto) {
|
||||
focusInputTextBox();
|
||||
std::strncpy(this->m_commandBuffer.data(), currCommand.data(), this->m_commandBuffer.size());
|
||||
this->m_lastResults = this->getCommandResults(currCommand);
|
||||
};
|
||||
|
||||
if (type == ContentRegistry::CommandPaletteCommands::Type::SymbolCommand) {
|
||||
if (auto [match, value] = matchCommand(input, command); match != MatchType::NoMatch) {
|
||||
if (auto [match, value] = MatchCommand(input, command); match != MatchType::NoMatch) {
|
||||
if (match != MatchType::PerfectMatch)
|
||||
results.emplace_back(command + " (" + description + ")");
|
||||
else
|
||||
results.emplace_back(callback(input.substr(command.length()).data()));
|
||||
results.push_back({ command + " (" + description + ")", "", AutoComplete });
|
||||
else {
|
||||
auto matchedCommand = input.substr(command.length()).data();
|
||||
results.push_back({ displayCallback(matchedCommand), matchedCommand, executeCallback });
|
||||
}
|
||||
}
|
||||
} else if (type == ContentRegistry::CommandPaletteCommands::Type::KeywordCommand) {
|
||||
if (auto [match, value] = matchCommand(input, command + " "); match != MatchType::NoMatch) {
|
||||
if (auto [match, value] = MatchCommand(input, command + " "); match != MatchType::NoMatch) {
|
||||
if (match != MatchType::PerfectMatch)
|
||||
results.emplace_back(command + " (" + description + ")");
|
||||
else
|
||||
results.emplace_back(callback(input.substr(command.length() + 1).data()));
|
||||
results.push_back({ command + " (" + description + ")", "", AutoComplete });
|
||||
else {
|
||||
auto matchedCommand = input.substr(command.length() + 1).data();
|
||||
results.push_back({ displayCallback(matchedCommand), matchedCommand, executeCallback });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ namespace hex {
|
||||
for (auto &view : ContentRegistry::Views::getEntries()) {
|
||||
view->drawAlwaysVisible();
|
||||
|
||||
if (!view->isAvailable() || !view->getWindowOpenState())
|
||||
if (!view->shouldProcess())
|
||||
continue;
|
||||
|
||||
auto minSize = view->getMinSize();
|
||||
@ -264,7 +264,7 @@ namespace hex {
|
||||
|
||||
if (auto &[key, mods] = Window::s_currShortcut; key != -1) {
|
||||
for (auto &view : ContentRegistry::Views::getEntries()) {
|
||||
if (view->getWindowOpenState()) {
|
||||
if (view->shouldProcess()) {
|
||||
if (view->handleShortcut(key, mods))
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user