mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
189 lines
No EOL
7.2 KiB
C++
189 lines
No EOL
7.2 KiB
C++
#include "handler.h"
|
|
|
|
#include "core/style.h"
|
|
#include "imgui/imgui.h"
|
|
#include "logger.h"
|
|
#include <utility>
|
|
|
|
namespace satdump
|
|
{
|
|
namespace handlers
|
|
{
|
|
inline ImGuiTreeNodeFlags nodeFlags(std::shared_ptr<Handler> &h, bool sec)
|
|
{
|
|
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_None;
|
|
// if (!h->hasSubhandlers())
|
|
flags |= ImGuiTreeNodeFlags_Leaf;
|
|
if (sec)
|
|
flags |= ImGuiTreeNodeFlags_Selected;
|
|
return flags;
|
|
}
|
|
|
|
bool Handler::isParent(const std::shared_ptr<Handler> &dragged, const std::shared_ptr<Handler> &potential_child)
|
|
{
|
|
for (auto &s : dragged->subhandlers)
|
|
{
|
|
if (s == potential_child)
|
|
return true;
|
|
if (isParent(s, potential_child))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Handler::drawTreeMenu(std::shared_ptr<Handler> &h)
|
|
{
|
|
bool handler_contained = false;
|
|
|
|
struct DragDropWip
|
|
{
|
|
std::shared_ptr<Handler> drag;
|
|
Handler *hdel;
|
|
};
|
|
|
|
tree_local.start();
|
|
for (int i = 0; i < subhandlers.size(); i++)
|
|
{
|
|
auto &handler = subhandlers[i];
|
|
ImGui::TableNextRow();
|
|
ImGui::TableSetColumnIndex(0);
|
|
|
|
bool tree_extended = ImGui::TreeNodeEx(handler->getTreeID().c_str(), nodeFlags(handler, h == handler));
|
|
handler_contained |= h == handler;
|
|
tree_local.node(handler->handler_tree_icon);
|
|
|
|
// Node-specific menu
|
|
if (handler->handler_can_be_dragged && ImGui::BeginPopupContextItem())
|
|
{
|
|
handler->drawContextMenu();
|
|
if (ImGui::MenuItem("Delete"))
|
|
subhandlers_marked_for_del.push_back(handler);
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
if (tree_extended)
|
|
{
|
|
if (handler_can_be_selected && ImGui::IsItemClicked())
|
|
{
|
|
h = handler;
|
|
handler_contained = true;
|
|
}
|
|
|
|
if (ImGui::IsItemHovered())
|
|
ImGui::SetTooltip("%s", handler->getName().c_str());
|
|
|
|
if (handler_can_subhandlers_be_dragged && handler->handler_can_be_dragged && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
|
|
{
|
|
DragDropWip d({handler, this});
|
|
ImGui::SetDragDropPayload("EXPLORER_HANDLER", &d, sizeof(DragDropWip));
|
|
|
|
ImGui::Text("%s", handler->getName().c_str());
|
|
ImGui::EndDragDropSource();
|
|
}
|
|
|
|
if (handler->handler_can_be_dragged_to && ImGui::BeginDragDropTarget())
|
|
{
|
|
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("EXPLORER_HANDLER"))
|
|
{
|
|
IM_ASSERT(payload->DataSize == sizeof(DragDropWip));
|
|
const DragDropWip *payload_n = (const DragDropWip *)payload->Data;
|
|
logger->info("Handler " + handler->getName() + " got drag of " + payload_n->drag->getName());
|
|
if (!isParent(payload_n->drag, handler))
|
|
{
|
|
handler->addSubHandler(payload_n->drag);
|
|
payload_n->hdel->delSubHandler(payload_n->drag);
|
|
}
|
|
else
|
|
{
|
|
logger->error("Can't drag parent onto child handler!");
|
|
}
|
|
}
|
|
ImGui::EndDragDropTarget();
|
|
}
|
|
|
|
if (handler_can_be_reorg)
|
|
{
|
|
float xpos = ImGui::GetWindowWidth();
|
|
// float ypos = ImGui::GetCursorPosY();
|
|
|
|
ImVec4 c = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
|
|
c.w = 1;
|
|
|
|
if (i > 0)
|
|
{
|
|
// ImGui::GetWindowDrawList()->AddRectFilled({xpos - 32 * ui_scale, ypos + 17 * ui_scale}, //
|
|
// {xpos - 10 * ui_scale, ypos + 32 * ui_scale}, //
|
|
// (ImU32)((ImColor)c));
|
|
|
|
ImGui::SameLine();
|
|
ImGui::SetCursorPosX(xpos - 35 * ui_scale);
|
|
ImGui::Text(u8"\ueaf4");
|
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
|
|
std::swap(subhandlers[i], subhandlers[i - 1]);
|
|
}
|
|
if (i != (int)subhandlers.size() - 1)
|
|
{
|
|
// ImGui::GetWindowDrawList()->AddRectFilled({xpos - 52 * ui_scale, ypos + 17 * ui_scale}, //
|
|
// {xpos - 30 * ui_scale, ypos + 32 * ui_scale}, //
|
|
// (ImU32)((ImColor)c));
|
|
|
|
ImGui::SameLine();
|
|
ImGui::SetCursorPosX(xpos - 55 * ui_scale);
|
|
ImGui::Text(u8"\ueaf3");
|
|
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
|
|
std::swap(subhandlers[i], subhandlers[i + 1]);
|
|
}
|
|
}
|
|
|
|
handler_contained |= handler->drawTreeMenu(h);
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
tree_local.end();
|
|
|
|
// Try handle deletion
|
|
delSubHandlersNow();
|
|
|
|
return handler_contained;
|
|
}
|
|
|
|
bool Handler::hasSubhandlers()
|
|
{
|
|
subhandlers_mtx.lock();
|
|
bool has = subhandlers.size();
|
|
subhandlers_mtx.unlock();
|
|
return has;
|
|
}
|
|
|
|
void Handler::addSubHandler(std::shared_ptr<Handler> handler, bool ontop)
|
|
{
|
|
subhandlers_mtx.lock();
|
|
if (ontop)
|
|
subhandlers.insert(subhandlers.begin(), &handler, &handler + 1);
|
|
else
|
|
subhandlers.push_back(handler);
|
|
subhandlers_mtx.unlock();
|
|
}
|
|
|
|
void Handler::delSubHandler(std::shared_ptr<Handler> handler, bool now)
|
|
{
|
|
subhandlers_mtx.lock();
|
|
subhandlers_marked_for_del.push_back(handler);
|
|
subhandlers_mtx.unlock();
|
|
|
|
if (now)
|
|
delSubHandlersNow();
|
|
}
|
|
|
|
std::vector<std::shared_ptr<Handler>> Handler::getAllSubHandlers()
|
|
{
|
|
std::vector<std::shared_ptr<Handler>> sh;
|
|
subhandlers_mtx.lock();
|
|
sh = subhandlers;
|
|
subhandlers_mtx.unlock();
|
|
return sh;
|
|
}
|
|
|
|
nlohmann::json Handler::getConfig() { return {}; }
|
|
} // namespace handlers
|
|
} // namespace satdump
|