#include "pch.h" #include "app.h" #include "app_core/app_preferences.h" #include "legacy_brush_ui_services.h" #include "legacy_ui_overlay_services.h" #include "legacy_preference_storage.h" #include "node_dialog_picker.h" #include "node_panel_brush.h" #include "node_panel_color.h" #include "node_panel_grid.h" #include "node_panel_floating.h" #include "serializer.h" namespace { bool apply_brush_color_plan(App& app, glm::vec4 color, bool update_quick, bool update_color_panel) { return pp::panopainter::apply_legacy_brush_color_plan(app, color, update_quick, update_color_panel); } bool apply_brush_preset_plan(App& app, const std::shared_ptr& brush) { return pp::panopainter::apply_legacy_brush_preset_plan(app, brush); } void save_floating_panel_state(Serializer::List& list, const std::shared_ptr& child) { if (auto const& f = std::dynamic_pointer_cast(child)) { auto fd = list.add(); fd->class_id = "ui-flt"; fd->set("pos", Serializer::Vec2(f->GetPosition())); fd->set("size", Serializer::Vec2(f->m_size)); fd->set("class", Serializer::Integer((int)f->m_class)); fd->set("title", Serializer::CString(f->m_title->m_text)); } } void save_docked_panel_state(Serializer::List& list, const std::shared_ptr& child, const char* class_id) { if (auto const& f = std::dynamic_pointer_cast(child)) { auto fd = list.add(); fd->class_id = class_id; fd->set("size", Serializer::Vec2(f->m_size)); fd->set("class", Serializer::Integer((int)f->m_class)); fd->set("title", Serializer::CString(f->m_title->m_text)); } } template void restore_panel_children( App& app, std::shared_ptr container, const TList& items, bool docked) { for (auto const& l : items) { auto ld = std::static_pointer_cast(l); auto size = ld->value("size"); auto cls = static_cast(ld->value("class")); auto f = container->add_child(); std::string title = "Floating Panel"; ld->value("title", title); f->m_title->set_text(title.c_str()); switch (cls) { case NodePanelFloating::kClass::Presets: { auto floating_presets = f->m_container->add_child_ref(); if (!docked) app.floating_presets = floating_presets; floating_presets->SetHeightP(100); floating_presets->on_brush_changed = [&app](Node*, std::shared_ptr& b) { apply_brush_preset_plan(app, b); }; break; } case NodePanelFloating::kClass::Color: { auto floating_color = f->m_container->add_child_ref(); if (!docked) app.floating_color = floating_color; floating_color->SetHeightP(100); if (docked) pp::panopainter::destroy_legacy_node(*floating_color->find("title")); else floating_color->find("title")->SetVisibility(false); floating_color->on_color_changed = [&app](Node*, glm::vec4 color) { apply_brush_color_plan(app, color, false, false); }; break; } case NodePanelFloating::kClass::ColorAdv: { app.floating_picker = f->m_container->add_child_ref(); app.floating_picker->m_autohide = false; app.floating_picker->on_color_change = [&app](Node*, glm::vec3 color) { apply_brush_color_plan(app, glm::vec4(color, 1.f), false, false); }; break; } case NodePanelFloating::kClass::Layers: f->m_container->add_child(app.layers); if (!docked) f->SetMinHeight(100); if (!docked) f->SetHeight(300); if (!docked) app.layers->find("title")->SetVisibility(false); app.layers->SetPositioning(YGPositionTypeRelative); app.layers->SetPosition(0, 0); app.layers->SetWidthP(100); app.layers->SetHeightP(100); app.layers->SetFlexShrink(0); break; case NodePanelFloating::kClass::Brush: f->m_container->add_child(app.stroke); if (!docked) app.stroke->find("title")->SetVisibility(false); app.stroke->SetPositioning(YGPositionTypeRelative); app.stroke->SetPosition(0, 0); app.stroke->SetWidthP(100); app.stroke->SetHeightP(100); break; case NodePanelFloating::kClass::Grids: f->m_container->add_child(app.grid); if (!docked) app.grid->find("title")->SetVisibility(false); app.grid->SetPositioning(YGPositionTypeRelative); app.grid->SetPosition(0, 0); app.grid->SetWidthP(100); app.grid->SetHeightP(100); break; case NodePanelFloating::kClass::Animation: f->m_container->add_child(app.animation); f->m_droppable = false; app.animation->SetPositioning(YGPositionTypeRelative); app.animation->SetPosition(0, 0); app.animation->SetWidthP(100); app.animation->SetHeightP(100); break; case NodePanelFloating::kClass::Generic: default: f->m_container->add_child(); break; } f->m_class = cls; if (docked) f->m_dock = container; f->SetPositioning(docked ? YGPositionTypeRelative : YGPositionTypeAbsolute); f->SetPosition(0, 0); f->SetSize(size); } } } // namespace void App::set_ui_rtl(bool rtl) { const auto plan = pp::app::plan_interface_direction(rtl); ui_rtl = plan.direction == pp::app::InterfaceDirection::right_to_left; layout[main_id]->find("central-row")->SetRTL( ui_rtl ? YGDirectionRTL : YGDirectionLTR); } bool App::get_ui_rtl() const { return ui_rtl; } void App::ui_save() { Serializer::Descriptor d; d.class_id = "ui-state"; Serializer::List list_floatings; for (auto const& c : layout[main_id]->find("floatings")->m_children) save_floating_panel_state(list_floatings, c); d.set("floatings", list_floatings); Serializer::List list_drop_left; for (auto const& c : layout[main_id]->find("drop-left")->m_children) save_docked_panel_state(list_drop_left, c, "ui-dpl"); d.set("drop-left", list_drop_left); Serializer::List list_drop_right; for (auto const& c : layout[main_id]->find("drop-right")->m_children) save_docked_panel_state(list_drop_right, c, "ui-dpr"); d.set("drop-right", list_drop_right); pp::panopainter::set_legacy_ui_state_preferences(d, ui_rtl); save_platform_ui_state(); pp::panopainter::save_legacy_preferences(); } void App::ui_restore() { const auto preferences = pp::panopainter::read_legacy_ui_preferences(); if (preferences.has_rtl) set_ui_rtl(preferences.rtl); if (!preferences.state) return; auto floatings = layout[main_id]->find_ref("floatings"); auto drop_left = layout[main_id]->find_ref("drop-left"); auto drop_right = layout[main_id]->find_ref("drop-right"); auto d = preferences.state; restore_panel_children(*this, floatings, d->get("floatings")->items, false); restore_panel_children(*this, drop_left, d->get("drop-left")->items, true); restore_panel_children(*this, drop_right, d->get("drop-right")->items, true); }