#pragma once #include "app_core/app_dialog.h" #include "foundation/result.h" #include "ui_core/overlay_lifetime.h" #include "node.h" #include "node_image.h" #include "shader.h" #include #include class App; class NodeInputBox; class NodeMessageBox; class NodePopupMenu; class NodeProgressBar; class NodeSettings; class NodeDialogCloud; namespace pp::panopainter { inline void configure_legacy_slider_color_shader(const glm::mat4& mvp) noexcept { ShaderManager::use(kShader::Color); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 }); } inline void configure_legacy_slider_hue_shader(const glm::mat4& mvp, int direction) noexcept { ShaderManager::use(kShader::ColorHue); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_int(kShaderUniform::Direction, direction); } inline void configure_legacy_ui_color_shader( const glm::mat4& mvp, const glm::vec4& color) noexcept { ShaderManager::use(kShader::Color); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec4(kShaderUniform::Col, color); } inline void configure_legacy_ui_color_shader( const glm::mat4& mvp) noexcept { configure_legacy_ui_color_shader(mvp, { 0, 0, 0, 1 }); } inline void configure_legacy_grid_lambert_shader( const glm::mat4& mvp, const glm::vec3& light_dir, float ambient) noexcept { ShaderManager::use(kShader::Lambert); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec3(kShaderUniform::LightDir, light_dir); ShaderManager::u_float(kShaderUniform::Ambient, ambient); } inline void configure_legacy_grid_lambert_lightmap_shader( const glm::mat4& mvp, const glm::vec3& light_dir, float ambient, int texture_slot) noexcept { ShaderManager::use(kShader::LambertLightmap); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec3(kShaderUniform::LightDir, light_dir); ShaderManager::u_float(kShaderUniform::Ambient, ambient); ShaderManager::u_int(kShaderUniform::Tex, texture_slot); } inline void configure_legacy_grid_bake_uv_shader( const glm::mat4& mvp) noexcept { ShaderManager::use(kShader::BakeUV); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); } inline void configure_legacy_ui_color_quad_shader( const glm::mat4& mvp, const glm::vec4& color) noexcept { ShaderManager::use(kShader::ColorQuad); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec4(kShaderUniform::Col, color); } inline void configure_legacy_ui_font_shader( const glm::mat4& mvp, const glm::vec4& color) noexcept { ShaderManager::use(kShader::Font); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_mat4(kShaderUniform::MVP, mvp); ShaderManager::u_vec4(kShaderUniform::Col, color); } void initialize_legacy_overlay_node(App& app, Node& node); void destroy_legacy_node(Node& node); void detach_legacy_node_from_parent(Node& node); void close_legacy_dialog_node(Node& node); void release_legacy_mouse_capture(Node& node) noexcept; void configure_legacy_popup_overlay(Node& node) noexcept; void activate_legacy_popup_overlay(Node& node) noexcept; void close_legacy_popup_overlay(Node& node) noexcept; void close_legacy_overlay_handle_ignoring_status( Node& anchor, pp::ui::NodeHandle overlay) noexcept; void close_legacy_overlay_handles_if_open( Node& anchor, const pp::foundation::Result& popup_overlay, const pp::foundation::Result& tick_overlay) noexcept; void close_legacy_dialog_and_hide_keyboard(App& app, Node& node); void close_legacy_popup_panel( Node& node, const std::function& on_close); [[nodiscard]] pp::foundation::Status attach_legacy_overlay_node( App& app, const std::shared_ptr& node) noexcept; [[nodiscard]] pp::foundation::Status attach_legacy_overlay_node_to_root( Node& anchor, const std::shared_ptr& node) noexcept; [[nodiscard]] pp::foundation::Result open_legacy_overlay_node_with_handle( Node& anchor, const std::shared_ptr& node, bool modal = true) noexcept; [[nodiscard]] pp::foundation::Status close_legacy_overlay_node( Node& anchor, pp::ui::NodeHandle overlay) noexcept; [[nodiscard]] pp::foundation::Result> add_legacy_popup_menu( App& app, const char* template_id, float x, float y, float rtl_anchor_width) noexcept; [[nodiscard]] std::shared_ptr create_legacy_progress_dialog_overlay( App& app, const pp::app::AppProgressDialogPlan& plan); [[nodiscard]] std::shared_ptr create_legacy_message_dialog_overlay( App& app, const pp::app::AppMessageDialogPlan& plan); [[nodiscard]] std::shared_ptr create_legacy_input_dialog_overlay( App& app, const pp::app::AppInputDialogPlan& plan); [[nodiscard]] std::shared_ptr create_legacy_settings_dialog_overlay( App& app); [[nodiscard]] std::shared_ptr create_legacy_cloud_browser_dialog_overlay( App& app); template std::shared_ptr make_legacy_overlay_node(App& app) { auto node = std::make_shared(); initialize_legacy_overlay_node(app, *node); return node; } template std::shared_ptr make_legacy_overlay_node_for_anchor(Node& anchor) { auto node = std::make_shared(); node->set_manager(anchor.m_manager); node->init(); node->create(); node->loaded(); return node; } template std::shared_ptr add_legacy_overlay_node(App& app) { auto node = make_legacy_overlay_node(app); (void)attach_legacy_overlay_node(app, node); return node; } template concept LegacyPopupOverlay = requires(PopupT& popup, const std::function& close_cb) { popup.on_popup_close = close_cb; }; template bool open_popup_and_tick_overlay( Node& anchor, const std::shared_ptr& popup, const glm::vec2& tick_pos, float button_height) noexcept { if (!popup) { return false; } auto tick = make_legacy_overlay_node_for_anchor(anchor); tick->SetPositioning(YGPositionTypeAbsolute); tick->SetSize(16, 32); tick->SetPosition(tick_pos.x, tick_pos.y + (button_height - 32) * 0.5f); tick->set_image("data/ui/popup-tick.png"); tick->m_scale = { 1, 1 }; const auto popup_overlay = open_legacy_overlay_node_with_handle(anchor, popup); const auto tick_overlay = open_legacy_overlay_node_with_handle(anchor, tick); if (!popup_overlay || !tick_overlay) { close_legacy_overlay_handles_if_open(anchor, popup_overlay, tick_overlay); return false; } const auto popup_handle = popup_overlay.value(); const auto tick_handle = tick_overlay.value(); popup->on_popup_close = [&anchor, popup_handle, tick_handle](Node*) { close_legacy_overlay_handle_ignoring_status(anchor, popup_handle); close_legacy_overlay_handle_ignoring_status(anchor, tick_handle); }; return true; } template void bind_legacy_popup_close_destroys_overlay( PopupT& popup, const std::shared_ptr& overlay) noexcept { popup.on_popup_close = [overlay](Node*) { if (overlay) { destroy_legacy_node(*overlay); } }; } template void bind_legacy_click_destroys_node(ButtonT& button, Node& target) noexcept { button.on_click = [&target](Node*) { close_legacy_dialog_node(target); }; } inline std::function legacy_destroy_node_callback(Node& target) { return [&target](Node*) { close_legacy_dialog_node(target); }; } } // namespace pp::panopainter