mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 13:37:42 -05:00
feat: Initial work rework current project system
This commit is contained in:
145
plugins/builtin/source/content/sidebar/project_explorer.cpp
Normal file
145
plugins/builtin/source/content/sidebar/project_explorer.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
|
||||
#include <hex/project/project.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
namespace {
|
||||
|
||||
void drawContent(proj::Content &content) {
|
||||
static proj::Content *rightClickedContent = nullptr;
|
||||
static proj::Content *renamingContent = nullptr;
|
||||
static std::string renameText;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (renamingContent != &content) {
|
||||
ImGui::Selectable(content.getName().c_str(), content.isOpen(), ImGuiSelectableFlags_SpanAllColumns);
|
||||
} else {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2());
|
||||
if (ImGui::InputText("##ContentName", renameText)) {
|
||||
renamingContent->setName(renameText);
|
||||
}
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter)) {
|
||||
renamingContent->setName(renameText);
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
proj::ProjectManager::loadContent(content);
|
||||
}
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) {
|
||||
rightClickedContent = &content;
|
||||
ImGui::OpenPopup("ContentContextMenu");
|
||||
}
|
||||
} else {
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && renamingContent == &content)
|
||||
renamingContent = nullptr;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(Lang(content.getType()));
|
||||
|
||||
if (rightClickedContent == &content) {
|
||||
if (ImGui::BeginPopup("ContentContextMenu")) {
|
||||
if (ImGui::MenuItemEx("Open", ICON_VS_OPEN_PREVIEW)) {
|
||||
proj::ProjectManager::loadContent(content);
|
||||
}
|
||||
if (ImGui::MenuItemEx("Rename", ICON_VS_DIFF_RENAMED)) {
|
||||
renamingContent = &content;
|
||||
renameText = content.getName();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawProject(proj::Project &project) {
|
||||
static proj::Project *rightClickedProject = nullptr;
|
||||
|
||||
bool open = ImGui::TreeNodeEx(project.getName().c_str(), ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
|
||||
if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
|
||||
rightClickedProject = &project;
|
||||
ImGui::OpenPopup("ProjectContextMenu");
|
||||
}
|
||||
if (rightClickedProject == &project) {
|
||||
if (ImGui::BeginPopup("ProjectContextMenu")) {
|
||||
if (ImGui::BeginMenuEx("Add", ICON_VS_FILE_ADD)) {
|
||||
for (const auto &handler : proj::ProjectManager::getContentHandlers()) {
|
||||
if (ImGui::MenuItem(Lang(handler.type))) {
|
||||
rightClickedProject->addContent(handler.type);
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::MenuItemEx("Close", ICON_VS_CLOSE)) {
|
||||
TaskManager::doLater([project = rightClickedProject] {
|
||||
proj::ProjectManager::removeProject(*project);
|
||||
});
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
if (open) {
|
||||
for (const auto &content : project.getContents()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(content.get());
|
||||
|
||||
drawContent(*content);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void registerProjectExplorer() {
|
||||
ContentRegistry::Interface::addSidebarItem(ICON_VS_PROJECT, [] {
|
||||
if (ImGui::BeginTable("Projects", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
ImGui::TableSetupColumn("##Icon", ImGuiTableColumnFlags_WidthFixed, 20_scaled);
|
||||
ImGui::TableSetupColumn("##Name", ImGuiTableColumnFlags_WidthStretch, 20_scaled);
|
||||
ImGui::TableSetupColumn("##Type", ImGuiTableColumnFlags_WidthFixed, 100_scaled);
|
||||
for (auto &project : proj::ProjectManager::getProjects()) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(project.get());
|
||||
drawProject(*project);
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::NewLine();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
});
|
||||
|
||||
proj::ProjectManager::createProject("Project 1");
|
||||
proj::ProjectManager::createProject("Project 2");
|
||||
proj::ProjectManager::createProject("Free Items");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <content/providers/view_provider.hpp>
|
||||
|
||||
#include <fonts/vscode_icons.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
@@ -45,16 +46,16 @@ namespace hex::plugin::builtin {
|
||||
bookmarkId
|
||||
};
|
||||
|
||||
m_bookmarks->emplace_back(std::move(bookmark), true);
|
||||
m_bookmarks.emplace_back(std::move(bookmark), true);
|
||||
|
||||
ImHexApi::Provider::markDirty();
|
||||
|
||||
EventBookmarkCreated::post(m_bookmarks->back().entry);
|
||||
EventBookmarkCreated::post(m_bookmarks.back().entry);
|
||||
EventHighlightingChanged::post();
|
||||
});
|
||||
|
||||
RequestRemoveBookmark::subscribe([this](u64 id) {
|
||||
std::erase_if(m_bookmarks.get(), [id](const auto &bookmark) {
|
||||
std::erase_if(m_bookmarks, [id](const auto &bookmark) {
|
||||
return bookmark.entry.id == id;
|
||||
});
|
||||
});
|
||||
@@ -65,7 +66,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Check all bookmarks for potential overlaps with the current address
|
||||
std::optional<ImColor> color;
|
||||
for (const auto &bookmark : *m_bookmarks) {
|
||||
for (const auto &bookmark : m_bookmarks) {
|
||||
if (!bookmark.highlightVisible)
|
||||
continue;
|
||||
|
||||
@@ -82,7 +83,7 @@ namespace hex::plugin::builtin {
|
||||
std::ignore = data;
|
||||
|
||||
// Loop over all bookmarks
|
||||
for (const auto &[bookmark, highlightVisible] : *m_bookmarks) {
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks) {
|
||||
if (!highlightVisible)
|
||||
continue;
|
||||
|
||||
@@ -158,7 +159,7 @@ namespace hex::plugin::builtin {
|
||||
return true;
|
||||
|
||||
auto data = nlohmann::json::parse(fileContent.begin(), fileContent.end());
|
||||
m_bookmarks.get(provider).clear();
|
||||
m_bookmarks.clear();
|
||||
return this->importBookmarks(provider, data);
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) -> bool {
|
||||
@@ -170,11 +171,26 @@ namespace hex::plugin::builtin {
|
||||
return result;
|
||||
}
|
||||
});
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.bookmarks",
|
||||
.load = [this](const proj::Content &content) {
|
||||
m_bookmarks.clear();
|
||||
|
||||
const auto data = content.isEmpty() ? nlohmann::json() : nlohmann::json::parse(content.getData());
|
||||
this->importBookmarks(ImHexApi::Provider::get(), data);
|
||||
EventHighlightingChanged::post();
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
nlohmann::json data;
|
||||
this->exportBookmarks(ImHexApi::Provider::get(), data);
|
||||
content.setData(data.dump(4));
|
||||
}
|
||||
});
|
||||
|
||||
ContentRegistry::Reports::addReportProvider([this](prv::Provider *provider) -> std::string {
|
||||
std::string result;
|
||||
|
||||
const auto &bookmarks = m_bookmarks.get(provider);
|
||||
const auto &bookmarks = m_bookmarks;
|
||||
if (bookmarks.empty())
|
||||
return "";
|
||||
|
||||
@@ -252,7 +268,7 @@ namespace hex::plugin::builtin {
|
||||
void ViewBookmarks::drawDropTarget(std::list<Bookmark>::iterator it, float height) {
|
||||
height = std::max(height, 1.0F);
|
||||
|
||||
if (it != m_bookmarks->begin()) {
|
||||
if (it != m_bookmarks.begin()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - height);
|
||||
} else {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + height);
|
||||
@@ -261,7 +277,7 @@ namespace hex::plugin::builtin {
|
||||
ImGui::InvisibleButton("##DropTarget", ImVec2(ImGui::GetContentRegionAvail().x, height * 2.0F));
|
||||
const auto dropTarget = ImRect(ImGui::GetItemRectMin(), ImVec2(ImGui::GetItemRectMax().x, ImGui::GetItemRectMin().y + 2_scaled));
|
||||
|
||||
if (it == m_bookmarks->begin()) {
|
||||
if (it == m_bookmarks.begin()) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - height);
|
||||
}
|
||||
|
||||
@@ -274,13 +290,13 @@ namespace hex::plugin::builtin {
|
||||
u64 droppedBookmarkId = *static_cast<const u64*>(payload->Data);
|
||||
|
||||
// Find the correct bookmark with that id
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks->begin(), m_bookmarks->end(), [droppedBookmarkId](const auto &bookmarkItem) {
|
||||
auto droppedIter = std::ranges::find_if(m_bookmarks.begin(), m_bookmarks.end(), [droppedBookmarkId](const auto &bookmarkItem) {
|
||||
return bookmarkItem.entry.id == droppedBookmarkId;
|
||||
});
|
||||
|
||||
// Swap the two bookmarks
|
||||
if (droppedIter != m_bookmarks->end()) {
|
||||
m_bookmarks->splice(it, m_bookmarks, droppedIter);
|
||||
if (droppedIter != m_bookmarks.end()) {
|
||||
m_bookmarks.splice(it, m_bookmarks, droppedIter);
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
@@ -298,18 +314,18 @@ namespace hex::plugin::builtin {
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (ImGui::BeginChild("##bookmarks")) {
|
||||
if (m_bookmarks->empty()) {
|
||||
if (m_bookmarks.empty()) {
|
||||
ImGuiExt::TextOverlay("hex.builtin.view.bookmarks.no_bookmarks"_lang, ImGui::GetWindowPos() + ImGui::GetWindowSize() / 2, ImGui::GetWindowWidth() * 0.7);
|
||||
}
|
||||
|
||||
auto bookmarkToRemove = m_bookmarks->end();
|
||||
auto bookmarkToRemove = m_bookmarks.end();
|
||||
const auto defaultItemSpacing = ImGui::GetStyle().ItemSpacing.y;
|
||||
|
||||
ImGui::Dummy({ ImGui::GetContentRegionAvail().x, 0 });
|
||||
drawDropTarget(m_bookmarks->begin(), defaultItemSpacing);
|
||||
drawDropTarget(m_bookmarks.begin(), defaultItemSpacing);
|
||||
|
||||
// Draw all bookmarks
|
||||
for (auto it = m_bookmarks->begin(); it != m_bookmarks->end(); ++it) {
|
||||
for (auto it = m_bookmarks.begin(); it != m_bookmarks.end(); ++it) {
|
||||
auto &[bookmark, highlightVisible] = *it;
|
||||
auto &[region, name, comment, color, locked, bookmarkId] = bookmark;
|
||||
|
||||
@@ -529,15 +545,15 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
// Remove the bookmark that was marked for removal
|
||||
if (bookmarkToRemove != m_bookmarks->end()) {
|
||||
m_bookmarks->erase(bookmarkToRemove);
|
||||
if (bookmarkToRemove != m_bookmarks.end()) {
|
||||
m_bookmarks.erase(bookmarkToRemove);
|
||||
EventHighlightingChanged::post();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
bool ViewBookmarks::importBookmarks(prv::Provider *provider, const nlohmann::json &json) {
|
||||
bool ViewBookmarks::importBookmarks(prv::Provider *, const nlohmann::json &json) {
|
||||
if (!json.contains("bookmarks"))
|
||||
return false;
|
||||
|
||||
@@ -549,30 +565,32 @@ namespace hex::plugin::builtin {
|
||||
if (!region.contains("address") || !region.contains("size"))
|
||||
continue;
|
||||
|
||||
m_bookmarks.get(provider).push_back({
|
||||
m_bookmarks.push_back({
|
||||
{
|
||||
.region = { region["address"], region["size"] },
|
||||
.name = bookmark["name"],
|
||||
.comment = bookmark["comment"],
|
||||
.color = bookmark["color"],
|
||||
.locked = bookmark["locked"],
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : m_currBookmarkId.get(provider),
|
||||
.id = bookmark.contains("id") ? bookmark["id"].get<u64>() : m_currBookmarkId,
|
||||
},
|
||||
bookmark.contains("highlightVisible") ? bookmark["highlightVisible"].get<bool>() : true,
|
||||
});
|
||||
if (bookmark.contains("id"))
|
||||
m_currBookmarkId.get(provider) = std::max<u64>(m_currBookmarkId.get(provider), bookmark["id"].get<i64>() + 1);
|
||||
m_currBookmarkId = std::max<u64>(m_currBookmarkId, bookmark["id"].get<i64>() + 1);
|
||||
else
|
||||
m_currBookmarkId.get(provider) += 1;
|
||||
m_currBookmarkId += 1;
|
||||
}
|
||||
|
||||
EventHighlightingChanged::post();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ViewBookmarks::exportBookmarks(prv::Provider *provider, nlohmann::json &json) {
|
||||
bool ViewBookmarks::exportBookmarks(prv::Provider *, nlohmann::json &json) {
|
||||
json["bookmarks"] = nlohmann::json::array();
|
||||
size_t index = 0;
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks.get(provider)) {
|
||||
for (const auto &[bookmark, highlightVisible] : m_bookmarks) {
|
||||
json["bookmarks"][index] = {
|
||||
{ "name", bookmark.name },
|
||||
{ "comment", bookmark.comment },
|
||||
@@ -627,7 +645,7 @@ namespace hex::plugin::builtin {
|
||||
wolv::io::File(path, wolv::io::File::Mode::Create).writeString(json.dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return ImHexApi::Provider::isValid() && !m_bookmarks->empty();
|
||||
return ImHexApi::Provider::isValid() && !m_bookmarks.empty();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <imnodes.h>
|
||||
#include <imnodes_internal.h>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <wolv/io/file.hpp>
|
||||
@@ -361,28 +362,39 @@ namespace hex::plugin::builtin {
|
||||
ProjectFile::registerPerProviderHandler({
|
||||
.basePath = "data_processor.json",
|
||||
.required = false,
|
||||
.load = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) {
|
||||
.load = [this](prv::Provider *, const std::fs::path &basePath, const Tar &tar) {
|
||||
std::string save = tar.readString(basePath);
|
||||
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace.get(provider), nlohmann::json::parse(save));
|
||||
this->loadNodes(m_mainWorkspace, nlohmann::json::parse(save));
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
.store = [this](prv::Provider *provider, const std::fs::path &basePath, const Tar &tar) {
|
||||
tar.writeString(basePath, ViewDataProcessor::saveNodes(m_mainWorkspace.get(provider)).dump(4));
|
||||
.store = [this](prv::Provider *, const std::fs::path &basePath, const Tar &tar) {
|
||||
tar.writeString(basePath, this->saveNodes(m_mainWorkspace).dump(4));
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.data_processor",
|
||||
.load = [this](const proj::Content &content) {
|
||||
const nlohmann::json data = content.isEmpty() ? nlohmann::json() : nlohmann::json::parse(content.getData());
|
||||
this->loadNodes(m_mainWorkspace, data);
|
||||
m_updateNodePositions = true;
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
content.setData(this->saveNodes(m_mainWorkspace).dump(4));
|
||||
}
|
||||
});
|
||||
|
||||
EventProviderOpened::subscribe(this, [this](auto *provider) {
|
||||
m_mainWorkspace.get(provider) = { };
|
||||
m_workspaceStack.get(provider).push_back(&m_mainWorkspace.get(provider));
|
||||
EventProviderOpened::subscribe(this, [this](auto *) {
|
||||
m_mainWorkspace = { };
|
||||
m_workspaceStack.push_back(&m_mainWorkspace);
|
||||
});
|
||||
|
||||
EventProviderChanged::subscribe(this, [this](const auto *, const auto *) {
|
||||
for (auto *workspace : *m_workspaceStack) {
|
||||
for (auto *workspace : m_workspaceStack) {
|
||||
for (auto &node : workspace->nodes) {
|
||||
node->setCurrentOverlay(nullptr);
|
||||
}
|
||||
@@ -399,7 +411,7 @@ namespace hex::plugin::builtin {
|
||||
[&](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (file.isValid()) {
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace, nlohmann::json::parse(file.readString()));
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
});
|
||||
@@ -411,17 +423,17 @@ namespace hex::plugin::builtin {
|
||||
[&, this](const std::fs::path &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Create);
|
||||
if (file.isValid())
|
||||
file.writeString(ViewDataProcessor::saveNodes(*m_mainWorkspace).dump(4));
|
||||
file.writeString(ViewDataProcessor::saveNodes(m_mainWorkspace).dump(4));
|
||||
});
|
||||
}, [this]{
|
||||
return !m_workspaceStack->empty() && !m_workspaceStack->back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
return !m_workspaceStack.empty() && !m_workspaceStack.back()->nodes.empty() && ImHexApi::Provider::isValid();
|
||||
});
|
||||
|
||||
ContentRegistry::FileHandler::add({ ".hexnode" }, [this](const auto &path) {
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
if (!file.isValid()) return false;
|
||||
|
||||
ViewDataProcessor::loadNodes(*m_mainWorkspace, file.readString());
|
||||
ViewDataProcessor::loadNodes(m_mainWorkspace, file.readString());
|
||||
m_updateNodePositions = true;
|
||||
|
||||
return true;
|
||||
@@ -884,7 +896,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewDataProcessor::drawContent() {
|
||||
auto &workspace = *m_workspaceStack->back();
|
||||
auto &workspace = *m_workspaceStack.back();
|
||||
|
||||
ImGui::BeginDisabled(m_evaluationTask.isRunning());
|
||||
|
||||
@@ -962,7 +974,7 @@ namespace hex::plugin::builtin {
|
||||
ImGuiExt::TextFormattedCentered("{}", "hex.builtin.view.data_processor.help_text"_lang);
|
||||
|
||||
// Draw a close button if there is more than one workspace on the stack
|
||||
if (m_workspaceStack->size() > 1) {
|
||||
if (m_workspaceStack.size() > 1) {
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetContentRegionAvail().x - ImGui::GetTextLineHeightWithSpacing() * 1.5F, ImGui::GetTextLineHeightWithSpacing() * 0.2F));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0F, 4.0F));
|
||||
if (ImGuiExt::DimmedIconButton(ICON_VS_CLOSE, ImGuiExt::GetCustomColorVec4(ImGuiCustomCol_ToolbarRed))) {
|
||||
@@ -1079,7 +1091,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Remove the top-most workspace from the stack if requested
|
||||
if (popWorkspace) {
|
||||
m_workspaceStack->pop_back();
|
||||
m_workspaceStack.pop_back();
|
||||
m_updateNodePositions = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#include <content/global_actions.hpp>
|
||||
#include <fonts/fonts.hpp>
|
||||
#include <hex/project/project.hpp>
|
||||
#include <hex/project/project_manager.hpp>
|
||||
#include <ui/menu_items.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
@@ -333,9 +335,9 @@ namespace hex::plugin::builtin {
|
||||
const auto availableSize = g.CurrentWindow->Size;
|
||||
const auto windowPosition = ImGui::GetCursorScreenPos();
|
||||
auto textEditorSize = availableSize;
|
||||
textEditorSize.y *= 3.5 / 5.0;
|
||||
textEditorSize.y *= 3.5F / 5.0F;
|
||||
textEditorSize.y -= ImGui::GetTextLineHeightWithSpacing();
|
||||
textEditorSize.y = std::clamp(textEditorSize.y + height,200.0F, availableSize.y-200.0F);
|
||||
textEditorSize.y = std::clamp(textEditorSize.y + height, 200.0F, availableSize.y - 200.0F);
|
||||
|
||||
if (g.NavWindow != nullptr) {
|
||||
std::string name = g.NavWindow->Name;
|
||||
@@ -1425,7 +1427,7 @@ namespace hex::plugin::builtin {
|
||||
const auto &currScope = evaluator->getScope(-m_debuggerScopeIndex);
|
||||
if (ImGui::BeginCombo("##scope", displayValue(currScope.parent, m_debuggerScopeIndex).c_str())) {
|
||||
for (size_t i = 0; i < evaluator->getScopeCount(); i++) {
|
||||
auto &scope = evaluator->getScope(-i);
|
||||
auto &scope = evaluator->getScope(-i32(i));
|
||||
|
||||
if (ImGui::Selectable(displayValue(scope.parent, i).c_str(), i == size_t(m_debuggerScopeIndex))) {
|
||||
m_debuggerScopeIndex = i;
|
||||
@@ -2299,6 +2301,16 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
proj::ProjectManager::registerContentHandler({
|
||||
.type = "hex.builtin.project.content_type.pattern",
|
||||
.load = [this](const proj::Content &content) {
|
||||
m_textEditor.SetText(content.getData());
|
||||
},
|
||||
.store = [this](proj::Content &content) {
|
||||
content.setData(wolv::util::trim(m_textEditor.GetText()));
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRLCMD + Keys::G + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.goto_line", [this] {
|
||||
m_openGotoLinePopUp = true;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user