mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
feat: Allow custom UIs to be drawn in the command palette
This commit is contained in:
@@ -26,6 +26,7 @@ EXPORT_MODULE namespace hex {
|
||||
std::function<void(std::string)> callback;
|
||||
};
|
||||
|
||||
using ContentDisplayCallback = std::function<void(std::string)>;
|
||||
using DisplayCallback = std::function<std::string(std::string)>;
|
||||
using ExecuteCallback = std::function<std::optional<std::string>(std::string)>;
|
||||
using QueryCallback = std::function<std::vector<QueryResult>(std::string)>;
|
||||
@@ -48,6 +49,8 @@ EXPORT_MODULE namespace hex {
|
||||
const std::vector<Entry>& getEntries();
|
||||
const std::vector<Handler>& getHandlers();
|
||||
|
||||
std::optional<ContentDisplayCallback>& getDisplayedContent();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,6 +80,12 @@ EXPORT_MODULE namespace hex {
|
||||
const std::string &command,
|
||||
const impl::QueryCallback &queryCallback,
|
||||
const impl::DisplayCallback &displayCallback);
|
||||
|
||||
/**
|
||||
* @brief Specify UI content that will be displayed inside the command palette
|
||||
* @param displayCallback Display callback that will be called to display the content
|
||||
*/
|
||||
void setDisplayedContent(const impl::ContentDisplayCallback &displayCallback);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -613,6 +613,11 @@ namespace hex {
|
||||
return *s_handlers;
|
||||
}
|
||||
|
||||
static AutoReset<std::optional<ContentDisplayCallback>> s_displayedContent;
|
||||
std::optional<ContentDisplayCallback>& getDisplayedContent() {
|
||||
return *s_displayedContent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void add(Type type, const std::string &command, const UnlocalizedString &unlocalizedDescription, const impl::DisplayCallback &displayCallback, const impl::ExecuteCallback &executeCallback) {
|
||||
@@ -627,6 +632,10 @@ namespace hex {
|
||||
impl::s_handlers->push_back(impl::Handler { type, command, queryCallback, displayCallback });
|
||||
}
|
||||
|
||||
void setDisplayedContent(const impl::ContentDisplayCallback &displayCallback) {
|
||||
impl::s_displayedContent = displayCallback;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
EventSearchBoxClicked::subscribe([this](ImGuiMouseButton button) {
|
||||
if (button == ImGuiMouseButton_Left) {
|
||||
RequestOpenPopup::post("hex.builtin.view.command_palette.name"_lang);
|
||||
m_commandPaletteOpen = true;
|
||||
m_justOpened = true;
|
||||
}
|
||||
@@ -28,14 +27,25 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewCommandPalette::drawAlwaysVisibleContent() {
|
||||
if (m_justOpened) {
|
||||
ImGui::OpenPopup("hex.builtin.view.command_palette.name"_lang);
|
||||
ContentRegistry::CommandPalette::impl::getDisplayedContent().reset();
|
||||
}
|
||||
|
||||
// If the command palette is hidden, don't draw it
|
||||
if (!m_commandPaletteOpen) return;
|
||||
|
||||
auto windowPos = ImHexApi::System::getMainWindowPosition();
|
||||
auto windowSize = ImHexApi::System::getMainWindowSize();
|
||||
|
||||
const auto &displayedContent = ContentRegistry::CommandPalette::impl::getDisplayedContent();
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(windowPos.x + windowSize.x * 0.5F, windowPos.y), ImGuiCond_Always, ImVec2(0.5F, 0.0F));
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
if (!displayedContent.has_value())
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), this->getMaxSize());
|
||||
else
|
||||
ImGui::SetNextWindowSizeConstraints(this->getMinSize(), ImVec2(FLT_MAX, FLT_MAX));
|
||||
|
||||
if (ImGui::BeginPopup("hex.builtin.view.command_palette.name"_lang)) {
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindowRead());
|
||||
ImGui::BringWindowToFocusFront(ImGui::GetCurrentWindowRead());
|
||||
@@ -118,33 +128,37 @@ namespace hex::plugin::builtin {
|
||||
ImGui::Separator();
|
||||
|
||||
// Draw the results
|
||||
if (ImGui::BeginChild("##results", ImGui::GetContentRegionAvail(), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||
u32 id = 1;
|
||||
for (const auto &[displayResult, matchedCommand, callback] : m_lastResults) {
|
||||
ImGui::PushID(id);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_NoTabStop, false);
|
||||
ON_SCOPE_EXIT {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopID();
|
||||
id += 1;
|
||||
};
|
||||
if (displayedContent.has_value()) {
|
||||
(*displayedContent)(m_commandBuffer);
|
||||
} else {
|
||||
if (ImGui::BeginChild("##results", ImGui::GetContentRegionAvail(), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||
u32 id = 1;
|
||||
for (const auto &[displayResult, matchedCommand, callback] : m_lastResults) {
|
||||
ImGui::PushID(id);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_NoTabStop, false);
|
||||
ON_SCOPE_EXIT {
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopID();
|
||||
id += 1;
|
||||
};
|
||||
|
||||
// Allow executing a command by clicking on it or selecting it with the keyboard and pressing enter
|
||||
if (ImGui::Selectable(displayResult.c_str(), false, ImGuiSelectableFlags_NoAutoClosePopups)) {
|
||||
if (auto result = callback(matchedCommand); result.has_value())
|
||||
m_commandBuffer = result.value();
|
||||
// Allow executing a command by clicking on it or selecting it with the keyboard and pressing enter
|
||||
if (ImGui::Selectable(displayResult.c_str(), false, ImGuiSelectableFlags_NoAutoClosePopups)) {
|
||||
if (auto result = callback(matchedCommand); result.has_value())
|
||||
m_commandBuffer = result.value();
|
||||
|
||||
break;
|
||||
}
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyDown(ImGuiKey_Enter) || ImGui::IsKeyDown(ImGuiKey_KeypadEnter))) {
|
||||
if (auto result = callback(matchedCommand); result.has_value())
|
||||
m_commandBuffer = result.value();
|
||||
break;
|
||||
}
|
||||
if (ImGui::IsItemFocused() && (ImGui::IsKeyDown(ImGuiKey_Enter) || ImGui::IsKeyDown(ImGuiKey_KeypadEnter))) {
|
||||
if (auto result = callback(matchedCommand); result.has_value())
|
||||
m_commandBuffer = result.value();
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndPopup();
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user