From f8c251aeb8cfe5b310ff5f917bf2d9293fa4ac52 Mon Sep 17 00:00:00 2001 From: Michael Alexsander Date: Fri, 28 Nov 2025 20:17:38 -0300 Subject: [PATCH] Fix various problems with the credits roll --- editor/gui/credits_roll.cpp | 55 +++++++++++++++++++------------------ editor/gui/credits_roll.h | 9 ++++-- editor/gui/editor_about.cpp | 23 +++++++++++++--- editor/gui/editor_about.h | 1 + 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/editor/gui/credits_roll.cpp b/editor/gui/credits_roll.cpp index fa345a7115a..0e73df95e5a 100644 --- a/editor/gui/credits_roll.cpp +++ b/editor/gui/credits_roll.cpp @@ -35,6 +35,7 @@ #include "core/input/input.h" #include "core/license.gen.h" #include "core/string/string_builder.h" +#include "editor/editor_node.h" #include "editor/editor_string_names.h" #include "editor/themes/editor_scale.h" #include "scene/gui/box_container.h" @@ -88,13 +89,23 @@ String CreditsRoll::_build_string(const char *const *p_from) const { return sb.as_string(); } +void CreditsRoll::_visibility_changed() { + if (!is_visible()) { + mouse_enabled = false; + set_process_internal(false); + set_process_input(false); + } +} + +void CreditsRoll::input(const Ref &p_event) { + // Block inputs from going elsewhere while the credits roll. + get_tree()->get_root()->set_input_as_handled(); +} + void CreditsRoll::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_VISIBILITY_CHANGED: { - if (!is_visible()) { - set_process_internal(false); - mouse_enabled = false; - } + case NOTIFICATION_POSTINITIALIZE: { + connect("visibility_changed", callable_mp(this, &CreditsRoll::_visibility_changed)); } break; case NOTIFICATION_TRANSLATION_CHANGED: { @@ -103,18 +114,14 @@ void CreditsRoll::_notification(int p_what) { } } break; - case NOTIFICATION_WM_GO_BACK_REQUEST: { - hide(); - } break; - case NOTIFICATION_INTERNAL_PROCESS: { const Vector2 pos = content->get_position(); if (pos.y < -content->get_size().y - 30) { - hide(); + hide(); // No more credits left, show's over. break; } - if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::RIGHT)) { + if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::RIGHT) || Input::get_singleton()->is_action_pressed(SNAME("ui_cancel"))) { hide(); break; } @@ -136,13 +143,13 @@ void CreditsRoll::_notification(int p_what) { void CreditsRoll::roll_credits() { if (!project_manager) { - font_size_normal = get_theme_font_size("main_size", EditorStringName(EditorFonts)) * 2; + font_size_normal = EditorNode::get_singleton()->get_editor_theme()->get_font_size("main_size", EditorStringName(EditorFonts)) * 2; font_size_header = font_size_normal + 10 * EDSCALE; font_size_big_header = font_size_header + 20 * EDSCALE; - bold_font = get_theme_font("bold", EditorStringName(EditorFonts)); + bold_font = EditorNode::get_singleton()->get_editor_theme()->get_font("bold", EditorStringName(EditorFonts)); { - const Ref logo_texture = get_editor_theme_icon("Logo"); + const Ref logo_texture = EditorNode::get_singleton()->get_editor_theme()->get_icon("Logo", EditorStringName(EditorIcons)); TextureRect *logo = memnew(TextureRect); logo->set_custom_minimum_size(Vector2(0, logo_texture->get_height() * 3)); @@ -220,28 +227,22 @@ void CreditsRoll::roll_credits() { _create_nothing(400 * EDSCALE); _create_label(TTRC("Thank you for choosing Godot Engine!"), LabelSize::BIG_HEADER); } + // Needs to be set here, so it stays centered even if the window is resized. + content->set_anchors_and_offsets_preset(Control::PRESET_VCENTER_WIDE); Window *root = get_tree()->get_root(); content->set_position(Vector2(content->get_position().x, root->get_size().y + 30)); - set_position(root->get_position()); - set_size(root->get_size()); - - popup(); set_process_internal(true); + set_process_input(true); } CreditsRoll::CreditsRoll() { - set_wrap_controls(false); - - { - ColorRect *background = memnew(ColorRect); - background->set_color(Color(0, 0, 0, 1)); - background->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); - add_child(background); - } + ColorRect *background = memnew(ColorRect); + background->set_color(Color(0, 0, 0, 1)); + background->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); + add_child(background); content = memnew(VBoxContainer); - content->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT); add_child(content); } diff --git a/editor/gui/credits_roll.h b/editor/gui/credits_roll.h index dbc33715a47..1965cab7af2 100644 --- a/editor/gui/credits_roll.h +++ b/editor/gui/credits_roll.h @@ -30,14 +30,14 @@ #pragma once -#include "scene/gui/popup.h" +#include "scene/main/canvas_layer.h" class Label; class VBoxContainer; class Font; -class CreditsRoll : public Popup { - GDCLASS(CreditsRoll, Popup); +class CreditsRoll : public CanvasLayer { + GDCLASS(CreditsRoll, CanvasLayer); enum class LabelSize { NORMAL, @@ -57,6 +57,9 @@ class CreditsRoll : public Popup { Label *_create_label(const String &p_with_text, LabelSize p_size = LabelSize::NORMAL); void _create_nothing(int p_size = -1); String _build_string(const char *const *p_from) const; + void _visibility_changed(); + + virtual void input(const Ref &p_event) override; protected: void _notification(int p_what); diff --git a/editor/gui/editor_about.cpp b/editor/gui/editor_about.cpp index 1f9a2a727df..3b1debe56be 100644 --- a/editor/gui/editor_about.cpp +++ b/editor/gui/editor_about.cpp @@ -36,7 +36,9 @@ #include "editor/editor_node.h" #include "editor/editor_string_names.h" #include "editor/gui/credits_roll.h" +#include "editor/gui/editor_toaster.h" #include "editor/gui/editor_version_button.h" +#include "editor/run/editor_run_bar.h" #include "editor/themes/editor_scale.h" #include "scene/gui/item_list.h" #include "scene/gui/rich_text_label.h" @@ -103,22 +105,34 @@ void EditorAbout::_license_tree_selected() { _tpl_text->set_text(selected->get_metadata(0)); } +void EditorAbout::_credits_visibility_changed() { + if (!credits_roll->is_visible()) { + credits_roll->queue_free(); + credits_roll = nullptr; + + show(); + } +} + void EditorAbout::_item_activated(int p_idx, ItemList *p_il) { const Variant val = p_il->get_item_metadata(p_idx); if (val.get_type() == Variant::STRING) { OS::get_singleton()->shell_open(val); } else { - // Easter egg :D - if (!EditorNode::get_singleton()) { - // Don't allow in Project Manager. + // Easter egg! :D + if (EditorRunBar::get_singleton()->is_playing()) { + // Don't allow if the game is running, as it will look weird if it's embedded. + EditorToaster::get_singleton()->popup_str(TTR("No distractions for this, close that game first.")); return; } if (!credits_roll) { credits_roll = memnew(CreditsRoll); - add_child(credits_roll); + credits_roll->connect("visibility_changed", callable_mp(this, &EditorAbout::_credits_visibility_changed)); + get_tree()->get_root()->add_child(credits_roll); } credits_roll->roll_credits(); + hide(); } } @@ -140,6 +154,7 @@ Label *EditorAbout::_create_section(Control *p_parent, const String &p_name, con il->set_max_columns(p_flags.has_flag(FLAG_SINGLE_COLUMN) ? 1 : 16); il->add_theme_constant_override("h_separation", 16 * EDSCALE); + // Don't allow the Easter egg in the Project Manager. if (p_flags.has_flag(FLAG_ALLOW_WEBSITE) || (p_flags.has_flag(FLAG_EASTER_EGG) && EditorNode::get_singleton())) { Ref empty_stylebox = memnew(StyleBoxEmpty); il->add_theme_style_override("focus", empty_stylebox); diff --git a/editor/gui/editor_about.h b/editor/gui/editor_about.h index ff50e4ecb7c..f25bc121104 100644 --- a/editor/gui/editor_about.h +++ b/editor/gui/editor_about.h @@ -54,6 +54,7 @@ private: }; void _license_tree_selected(); + void _credits_visibility_changed(); void _item_activated(int p_idx, ItemList *p_il); void _item_list_resized(ItemList *p_il); Label *_create_section(Control *p_parent, const String &p_name, const char *const *p_src, BitField p_flags = 0);