Centralize retained menu popup attachment

This commit is contained in:
2026-06-06 10:37:14 +02:00
parent 65c7716d62
commit 5ff2992c0e
7 changed files with 128 additions and 63 deletions

View File

@@ -24,6 +24,7 @@
#include "legacy_canvas_tool_services.h"
#include "legacy_document_layer_services.h"
#include "legacy_history_services.h"
#include "legacy_ui_overlay_services.h"
#include "settings.h"
#include "serializer.h"
#include "font.h"
@@ -59,6 +60,25 @@ void apply_file_menu_plan(App& app, pp::app::FileMenuCommand command)
pp::panopainter::apply_legacy_file_menu_command(app, command);
}
std::shared_ptr<NodePopupMenu> add_menu_popup(
App& app,
const char* template_id,
glm::vec2 position,
float rtl_anchor_width)
{
const auto popup = pp::panopainter::add_legacy_popup_menu(
app,
template_id,
position.x,
position.y,
rtl_anchor_width);
if (!popup) {
LOG("Popup menu '%s' failed: %s", template_id ? template_id : "<null>", popup.status().message);
return nullptr;
}
return popup.value();
}
pp::app::DocumentLayerMenuPlan make_layer_menu_plan(
pp::app::DocumentLayerMenuCommand command,
App& app)
@@ -655,13 +675,9 @@ void App::init_menu_file()
{
menu_file->on_click = [=](Node*) {
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
auto popup = layout[const_hash("file-menu")]->m_children[0]->clone<NodePopupMenu>();
popup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup);
auto popup = add_menu_popup(*this, "file-menu", pos, menu_file->m_size.x);
if (!popup)
return;
if (auto b = popup->find<NodeButtonCustom>("file-newdoc"))
b->on_click = [this, popup](Node*) {
@@ -714,13 +730,9 @@ void App::init_menu_file()
if (auto b = popup->find<NodeButtonCustom>("file-export-tick"))
b->on_click = [this, b, popup](Node*) {
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
auto subpopup = layout[const_hash("file-submenu-export")]->m_children[0]->clone<NodePopupMenu>();
subpopup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - subpopup->m_size.x + b->m_size.x;
subpopup->SetPositioning(YGPositionTypeAbsolute);
subpopup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(subpopup);
auto subpopup = add_menu_popup(*this, "file-submenu-export", pos, b->m_size.x);
if (!subpopup)
return;
subpopup->find<NodeButtonCustom>("file-submenu-export-png")->on_click = [this, subpopup, popup](Node*) {
apply_document_export_menu_plan(*this, pp::app::DocumentExportMenuKind::png);
popup->mouse_release();
@@ -805,13 +817,9 @@ void App::init_menu_edit()
{
menu_file->on_click = [=](Node*) {
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
auto popup = layout[const_hash("edit-menu")]->m_children[0]->clone<NodePopupMenu>();
popup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup);
auto popup = add_menu_popup(*this, "edit-menu", pos, menu_file->m_size.x);
if (!popup)
return;
};
}
}
@@ -824,13 +832,9 @@ void App::init_menu_tools()
{
menu_exp->on_click = [this, menu_exp, main](Node*) {
glm::vec2 pos = menu_exp->m_pos + glm::vec2(0, menu_exp->m_size.y);
auto popup_exp = layout[const_hash("tools-menu")]->m_children[0]->clone<NodePopupMenu>();
popup_exp->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup_exp->m_size.x + menu_exp->m_size.x;
popup_exp->SetPositioning(YGPositionTypeAbsolute);
popup_exp->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup_exp);
auto popup_exp = add_menu_popup(*this, "tools-menu", pos, menu_exp->m_size.x);
if (!popup_exp)
return;
if (auto tick = popup_exp->find<NodeButtonCustom>("tools-panels")) tick->on_click = [this, popup_exp](Node* b)
{
@@ -839,13 +843,9 @@ void App::init_menu_tools()
return;
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
auto popup_time = layout[const_hash("panels-menu")]->m_children[0]->clone<NodePopupMenu>();
popup_time->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup_time->m_size.x + b->m_size.x;
popup_time->SetPositioning(YGPositionTypeAbsolute);
popup_time->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup_time);
auto popup_time = add_menu_popup(*this, "panels-menu", pos, b->m_size.x);
if (!popup_time)
return;
auto visible = [this](Node* panel) {
if (!panel)
@@ -1030,13 +1030,9 @@ void App::init_menu_tools()
return;
glm::vec2 pos = b->m_pos + glm::vec2(b->m_size.x, 0);
auto popup_time = layout[const_hash("options-menu")]->m_children[0]->clone<NodePopupMenu>();
popup_time->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup_time->m_size.x + b->m_size.x;
popup_time->SetPositioning(YGPositionTypeAbsolute);
popup_time->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup_time);
auto popup_time = add_menu_popup(*this, "options-menu", pos, b->m_size.x);
if (!popup_time)
return;
if (auto ui_scale = popup_time->find<NodeComboBox>("tools-ui-scale"))
{
@@ -1244,13 +1240,9 @@ void App::init_menu_about()
{
menu_file->on_click = [=](Node*) {
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
auto popup = layout[const_hash("about-menu")]->m_children[0]->clone<NodePopupMenu>();
popup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup);
auto popup = add_menu_popup(*this, "about-menu", pos, menu_file->m_size.x);
if (!popup)
return;
popup->find<NodeButtonCustom>("about-app")->on_click = [this, popup](Node*) {
const auto plan = pp::app::plan_about_menu_command(
@@ -1411,13 +1403,9 @@ void App::init_menu_layer()
{
menu_file->on_click = [=](Node*) {
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
auto popup = layout[const_hash("layers-menu")]->m_children[0]->clone<NodePopupMenu>();
popup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup);
auto popup = add_menu_popup(*this, "layers-menu", pos, menu_file->m_size.x);
if (!popup)
return;
popup->find<NodeButtonCustom>("layer-clear")->on_click = [this, popup](Node*) {
const auto plan = make_layer_menu_plan(pp::app::DocumentLayerMenuCommand::clear, *this);