2021-12-07 22:47:41 +01:00
|
|
|
#include "content/views/view_tools.hpp"
|
2022-10-13 10:47:35 +02:00
|
|
|
#include <imgui_internal.h>
|
2020-11-15 00:46:38 +01:00
|
|
|
|
2022-02-01 18:09:40 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
2024-02-10 23:31:05 +01:00
|
|
|
#include <hex/api/layout_manager.hpp>
|
2022-02-01 18:09:40 +01:00
|
|
|
|
2024-01-28 22:14:59 +01:00
|
|
|
#include <fonts/codicons_font.h>
|
|
|
|
|
2021-12-07 22:47:41 +01:00
|
|
|
namespace hex::plugin::builtin {
|
2020-11-15 00:46:38 +01:00
|
|
|
|
2024-01-08 21:51:48 +01:00
|
|
|
ViewTools::ViewTools() : View::Window("hex.builtin.view.tools.name", ICON_VS_TOOLS) {
|
2023-12-19 13:10:25 +01:00
|
|
|
m_dragStartIterator = ContentRegistry::Tools::impl::getEntries().end();
|
2024-02-10 23:31:05 +01:00
|
|
|
|
|
|
|
LayoutManager::registerLoadCallback([this](std::string_view line) {
|
|
|
|
auto parts = wolv::util::splitString(std::string(line), "=");
|
|
|
|
if (parts.size() != 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_detachedTools[parts[0]] = parts[1] == "1";
|
|
|
|
});
|
|
|
|
|
|
|
|
LayoutManager::registerStoreCallback([this](ImGuiTextBuffer *buffer) {
|
|
|
|
for (auto &[unlocalizedName, function] : ContentRegistry::Tools::impl::getEntries()) {
|
|
|
|
auto detached = m_detachedTools[unlocalizedName];
|
|
|
|
buffer->appendf("%s=%d\n", unlocalizedName.get().c_str(), detached);
|
|
|
|
}
|
|
|
|
});
|
2023-06-05 09:08:41 +02:00
|
|
|
}
|
2020-11-15 21:31:04 +01:00
|
|
|
|
2020-12-22 18:10:01 +01:00
|
|
|
void ViewTools::drawContent() {
|
2023-03-21 15:33:43 +01:00
|
|
|
auto &tools = ContentRegistry::Tools::impl::getEntries();
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Draw all tools
|
|
|
|
for (auto iter = tools.begin(); iter != tools.end(); ++iter) {
|
2024-02-10 23:31:05 +01:00
|
|
|
auto &[unlocalizedName, function] = *iter;
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// If the tool has been detached from the main window, don't draw it here anymore
|
2024-02-10 23:31:05 +01:00
|
|
|
if (m_detachedTools[unlocalizedName]) continue;
|
2023-08-29 12:14:12 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Draw the tool
|
2024-02-10 23:31:05 +01:00
|
|
|
if (ImGui::CollapsingHeader(Lang(unlocalizedName))) {
|
2023-11-21 13:47:50 +01:00
|
|
|
function();
|
|
|
|
ImGui::NewLine();
|
|
|
|
} else {
|
|
|
|
// Handle dragging the tool out of the main window
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// If the user clicks on the header, start dragging the tool remember the iterator
|
2023-12-19 13:10:25 +01:00
|
|
|
if (ImGui::IsMouseClicked(0) && ImGui::IsItemActivated() && m_dragStartIterator == tools.end())
|
|
|
|
m_dragStartIterator = iter;
|
2023-01-01 01:01:24 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// If the user released the mouse button, stop dragging the tool
|
|
|
|
if (!ImGui::IsMouseDown(0))
|
2023-12-19 13:10:25 +01:00
|
|
|
m_dragStartIterator = tools.end();
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Detach the tool if the user dragged it out of the main window
|
2023-12-19 13:10:25 +01:00
|
|
|
if (!ImGui::IsItemHovered() && m_dragStartIterator == iter) {
|
2024-02-10 23:31:05 +01:00
|
|
|
m_detachedTools[unlocalizedName] = true;
|
2021-01-13 13:18:03 +01:00
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
|
2021-01-13 13:18:03 +01:00
|
|
|
}
|
2020-11-15 00:46:38 +01:00
|
|
|
}
|
2023-06-05 09:08:41 +02:00
|
|
|
}
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
void ViewTools::drawAlwaysVisibleContent() {
|
2023-10-12 15:15:05 +02:00
|
|
|
// Make sure the tool windows never get drawn over the welcome screen
|
|
|
|
if (!ImHexApi::Provider::isValid())
|
|
|
|
return;
|
|
|
|
|
2023-06-05 09:08:41 +02:00
|
|
|
auto &tools = ContentRegistry::Tools::impl::getEntries();
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-11-10 20:47:08 +01:00
|
|
|
for (auto iter = tools.begin(); iter != tools.end(); ++iter) {
|
2024-02-10 23:31:05 +01:00
|
|
|
auto &[unlocalizedName, function] = *iter;
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2023-08-29 12:14:12 +02:00
|
|
|
// If the tool is still attached to the main window, don't draw it here
|
2024-02-10 23:31:05 +01:00
|
|
|
if (!m_detachedTools[unlocalizedName]) continue;
|
2022-10-13 10:47:35 +02:00
|
|
|
|
2024-01-03 18:26:25 +01:00
|
|
|
// Load the window height that is dependent on the tool content
|
2024-02-10 23:31:05 +01:00
|
|
|
const auto windowName = View::toWindowName(unlocalizedName);
|
2024-01-03 18:26:25 +01:00
|
|
|
const auto height = m_windowHeights[ImGui::FindWindowByName(windowName.c_str())];
|
|
|
|
if (height > 0)
|
|
|
|
ImGui::SetNextWindowSizeConstraints(ImVec2(400_scaled, height), ImVec2(FLT_MAX, height));
|
|
|
|
|
2023-08-29 12:14:12 +02:00
|
|
|
// Create a new window for the tool
|
2024-02-10 23:31:05 +01:00
|
|
|
if (ImGui::Begin(windowName.c_str(), &m_detachedTools[unlocalizedName], ImGuiWindowFlags_NoCollapse)) {
|
2024-01-03 18:26:25 +01:00
|
|
|
// Draw the tool content
|
2022-10-13 10:47:35 +02:00
|
|
|
function();
|
|
|
|
|
2023-08-29 12:14:12 +02:00
|
|
|
// Handle the first frame after the tool has been detached
|
2023-12-19 13:10:25 +01:00
|
|
|
if (ImGui::IsWindowAppearing() && m_dragStartIterator == iter) {
|
|
|
|
m_dragStartIterator = tools.end();
|
2022-10-13 10:47:35 +02:00
|
|
|
|
|
|
|
// Attach the newly created window to the cursor, so it gets dragged around
|
2023-12-18 10:14:07 +01:00
|
|
|
GImGui->MovingWindow = ImGui::GetCurrentWindowRead();
|
2022-10-13 10:47:35 +02:00
|
|
|
GImGui->ActiveId = GImGui->MovingWindow->MoveId;
|
|
|
|
}
|
2024-01-03 18:26:25 +01:00
|
|
|
|
|
|
|
const auto window = ImGui::GetCurrentWindowRead();
|
|
|
|
m_windowHeights[ImGui::GetCurrentWindowRead()] = ImGui::CalcWindowNextAutoFitSize(window).y;
|
2022-10-13 10:47:35 +02:00
|
|
|
}
|
|
|
|
ImGui::End();
|
|
|
|
}
|
2020-11-15 00:46:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|