#include "handler.h" #include "imgui/imgui.h" #include "logger.h" //// TODOREWORK? #include "product/image_product_handler.h" #include namespace satdump { namespace viewer { inline ImGuiTreeNodeFlags nodeFlags(std::shared_ptr &h, bool sec) { ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_None; // if (!h->hasSubhandlers()) flags |= ImGuiTreeNodeFlags_Leaf; // TODOREWORK? if (sec) flags |= ImGuiTreeNodeFlags_Selected; return flags; } bool Handler::isParent(const std::shared_ptr &dragged, const std::shared_ptr &potential_child) { for (auto &s : dragged->subhandlers) { if (s == potential_child) return true; if (isParent(s, potential_child)) return true; } return false; } void Handler::drawTreeMenu(std::shared_ptr &h) { // TODOREWORK CLEANUP struct DragDropWip { std::shared_ptr drag; Handler *hdel; }; tree_local.start(); for (int i = 0; i < subhandlers.size(); i++) { auto &handler = subhandlers[i]; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); bool clicked = ImGui::TreeNodeEx(handler->getTreeID().c_str(), nodeFlags(handler, h == handler)); tree_local.node(handler->handler_tree_icon); auto arrow_pos = ImGui::GetCursorPos(); if (clicked) { if (ImGui::IsItemClicked()) h = handler; if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", handler->getName().c_str()); // TODOREWORK CLEANUP if (handler_can_subhandlers_be_dragged && handler->handler_can_be_dragged && ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID)) { DragDropWip d({handler, this}); ImGui::SetDragDropPayload("VIEWER_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("VIEWER_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(); } // TODOREWORK CLEANUP handler->drawTreeMenu(h); ImGui::TreePop(); } if (handler_can_be_reorg) { ImGui::SetCursorPos({arrow_pos.x - 100, arrow_pos.y}); if (i > 0) { ImGui::SameLine(); if (ImGui::SmallButton((u8"\ueaf4##" + handler->getTreeID()).c_str())) { logger->trace("Up"); std::swap(subhandlers[i], subhandlers[i - 1]); } } if (i != subhandlers.size() - 1) { ImGui::SameLine(); if (ImGui::SmallButton((u8"\ueaf3##" + handler->getTreeID()).c_str())) { logger->trace("Down"); std::swap(subhandlers[i], subhandlers[i + 1]); } } ImGui::SetCursorPos(arrow_pos); } } tree_local.end(); // Try handle deletion delSubHandlersNow(); } bool Handler::hasSubhandlers() { subhandlers_mtx.lock(); bool has = subhandlers.size(); subhandlers_mtx.unlock(); return has; } void Handler::addSubHandler(std::shared_ptr handler) { subhandlers_mtx.lock(); subhandlers.push_back(handler); subhandlers_mtx.unlock(); } void Handler::delSubHandler(std::shared_ptr handler, bool now) { subhandlers_mtx.lock(); subhandlers_marked_for_del.push_back(handler); subhandlers_mtx.unlock(); if (now) delSubHandlersNow(); } nlohmann::json Handler::getConfig() { return {}; } } // namespace viewer } // namespace satdump