2014-02-09 22:10:30 -03:00
/**************************************************************************/
/* popup.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-09 22:10:30 -03:00
# include "popup.h"
2017-08-19 01:02:56 +02:00
2025-01-08 20:00:20 -03:00
# ifdef TOOLS_ENABLED
# include "core/config/project_settings.h"
# endif
2020-03-12 09:37:40 -03:00
# include "scene/gui/panel.h"
2024-04-29 01:09:58 -03:00
# include "scene/resources/style_box_flat.h"
2023-09-08 21:00:10 +02:00
# include "scene/theme/theme_db.h"
2014-02-09 22:10:30 -03:00
2020-03-12 09:37:40 -03:00
void Popup : : _input_from_window ( const Ref < InputEvent > & p_event ) {
2025-07-28 11:27:43 +03:00
if ( get_flag ( FLAG_POPUP ) & & p_event - > is_action_pressed ( SNAME ( " ui_cancel " ) , false , true ) ) {
2024-05-17 10:03:52 +03:00
hide_reason = HIDE_REASON_CANCELED ; // ESC pressed, mark as canceled unconditionally.
2020-03-12 09:37:40 -03:00
_close_pressed ( ) ;
2015-12-29 09:26:17 -03:00
}
2023-09-01 08:40:35 +02:00
Window : : _input_from_window ( p_event ) ;
2014-02-09 22:10:30 -03:00
}
2020-08-21 16:11:20 +02:00
void Popup : : _initialize_visible_parents ( ) {
2022-02-24 11:21:23 +02:00
if ( is_embedded ( ) ) {
visible_parents . clear ( ) ;
Window * parent_window = this ;
while ( parent_window ) {
parent_window = parent_window - > get_parent_visible_window ( ) ;
if ( parent_window ) {
visible_parents . push_back ( parent_window ) ;
2024-05-13 16:56:03 +02:00
parent_window - > connect ( SceneStringName ( focus_entered ) , callable_mp ( this , & Popup : : _parent_focused ) ) ;
parent_window - > connect ( SceneStringName ( tree_exited ) , callable_mp ( this , & Popup : : _deinitialize_visible_parents ) ) ;
2022-02-24 11:21:23 +02:00
}
2020-08-21 16:11:20 +02:00
}
}
}
void Popup : : _deinitialize_visible_parents ( ) {
2022-02-24 11:21:23 +02:00
if ( is_embedded ( ) ) {
2022-12-29 01:24:45 +01:00
for ( Window * parent_window : visible_parents ) {
2024-05-13 16:56:03 +02:00
parent_window - > disconnect ( SceneStringName ( focus_entered ) , callable_mp ( this , & Popup : : _parent_focused ) ) ;
parent_window - > disconnect ( SceneStringName ( tree_exited ) , callable_mp ( this , & Popup : : _deinitialize_visible_parents ) ) ;
2022-02-24 11:21:23 +02:00
}
2020-08-21 16:11:20 +02:00
2022-02-24 11:21:23 +02:00
visible_parents . clear ( ) ;
}
2014-02-09 22:10:30 -03:00
}
2020-05-14 14:29:06 +02:00
2020-03-12 09:37:40 -03:00
void Popup : : _notification ( int p_what ) {
switch ( p_what ) {
case NOTIFICATION_VISIBILITY_CHANGED : {
2022-10-11 08:39:36 +03:00
if ( ! is_in_edited_scene_root ( ) ) {
if ( is_visible ( ) ) {
_initialize_visible_parents ( ) ;
} else {
_deinitialize_visible_parents ( ) ;
2024-05-01 13:39:54 +02:00
if ( hide_reason = = HIDE_REASON_NONE ) {
hide_reason = HIDE_REASON_CANCELED ;
}
2022-10-11 08:39:36 +03:00
emit_signal ( SNAME ( " popup_hide " ) ) ;
popped_up = false ;
}
2020-03-12 09:37:40 -03:00
}
} break ;
2022-02-15 18:06:48 +01:00
2020-08-21 16:11:20 +02:00
case NOTIFICATION_WM_WINDOW_FOCUS_IN : {
2022-10-11 08:39:36 +03:00
if ( ! is_in_edited_scene_root ( ) ) {
if ( has_focus ( ) ) {
popped_up = true ;
2024-05-01 13:39:54 +02:00
hide_reason = HIDE_REASON_NONE ;
2022-10-11 08:39:36 +03:00
}
2020-03-12 09:37:40 -03:00
}
} break ;
2022-02-15 18:06:48 +01:00
2023-05-29 17:00:09 +02:00
case NOTIFICATION_UNPARENTED :
2020-08-21 16:11:20 +02:00
case NOTIFICATION_EXIT_TREE : {
2022-10-11 08:39:36 +03:00
if ( ! is_in_edited_scene_root ( ) ) {
_deinitialize_visible_parents ( ) ;
}
2020-08-21 16:11:20 +02:00
} break ;
2022-02-15 18:06:48 +01:00
2023-02-14 09:23:40 +02:00
case NOTIFICATION_WM_CLOSE_REQUEST : {
2022-10-11 08:39:36 +03:00
if ( ! is_in_edited_scene_root ( ) ) {
2024-05-17 10:03:52 +03:00
if ( hide_reason = = HIDE_REASON_NONE ) {
hide_reason = HIDE_REASON_UNFOCUSED ;
}
2022-10-11 08:39:36 +03:00
_close_pressed ( ) ;
}
2020-03-12 09:37:40 -03:00
} break ;
2023-02-14 09:23:40 +02:00
case NOTIFICATION_APPLICATION_FOCUS_OUT : {
2025-07-28 11:27:43 +03:00
if ( ! is_in_edited_scene_root ( ) & & get_flag ( FLAG_POPUP ) ) {
2024-05-17 10:03:52 +03:00
if ( hide_reason = = HIDE_REASON_NONE ) {
hide_reason = HIDE_REASON_UNFOCUSED ;
}
2023-02-14 09:23:40 +02:00
_close_pressed ( ) ;
}
} break ;
2015-06-13 22:12:53 -03:00
}
2014-02-09 22:10:30 -03:00
}
2020-08-21 16:11:20 +02:00
void Popup : : _parent_focused ( ) {
2025-07-28 11:27:43 +03:00
if ( popped_up & & get_flag ( FLAG_POPUP ) ) {
2024-05-17 10:03:52 +03:00
if ( hide_reason = = HIDE_REASON_NONE ) {
hide_reason = HIDE_REASON_UNFOCUSED ;
}
2020-08-21 16:11:20 +02:00
_close_pressed ( ) ;
2017-03-02 22:43:56 +01:00
}
2020-08-21 16:11:20 +02:00
}
void Popup : : _close_pressed ( ) {
popped_up = false ;
_deinitialize_visible_parents ( ) ;
2014-02-09 22:10:30 -03:00
2023-12-18 15:46:56 +01:00
callable_mp ( ( Window * ) this , & Window : : hide ) . call_deferred ( ) ;
2022-05-13 08:22:29 -04:00
}
void Popup : : _post_popup ( ) {
Window : : _post_popup ( ) ;
popped_up = true ;
}
2022-10-11 08:39:36 +03:00
void Popup : : _validate_property ( PropertyInfo & p_property ) const {
2025-06-12 12:54:19 +08:00
if ( ! Engine : : get_singleton ( ) - > is_editor_hint ( ) ) {
return ;
}
2022-10-11 08:39:36 +03:00
if (
p_property . name = = " transient " | |
p_property . name = = " exclusive " | |
p_property . name = = " popup_window " | |
p_property . name = = " unfocusable " ) {
p_property . usage = PROPERTY_USAGE_NO_EDITOR ;
}
}
2020-03-19 23:32:09 -03:00
Rect2i Popup : : _popup_adjust_rect ( ) const {
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , Rect2 ( ) ) ;
2022-09-29 12:53:28 +03:00
Rect2i parent_rect = get_usable_parent_rect ( ) ;
2020-03-19 23:32:09 -03:00
2022-09-29 12:53:28 +03:00
if ( parent_rect = = Rect2i ( ) ) {
2020-03-19 23:32:09 -03:00
return Rect2i ( ) ;
}
Rect2i current ( get_position ( ) , get_size ( ) ) ;
2025-05-20 23:54:56 +02:00
if ( ! is_embedded ( ) & & DisplayServer : : get_singleton ( ) - > has_feature ( DisplayServer : : FEATURE_SELF_FITTING_WINDOWS ) ) {
2024-09-27 13:59:48 +02:00
// We're fine as is, the Display Server will take care of that for us.
return current ;
}
2022-09-29 12:53:28 +03:00
if ( current . position . x + current . size . x > parent_rect . position . x + parent_rect . size . x ) {
current . position . x = parent_rect . position . x + parent_rect . size . x - current . size . x ;
2020-03-19 23:32:09 -03:00
}
2022-09-29 12:53:28 +03:00
if ( current . position . x < parent_rect . position . x ) {
current . position . x = parent_rect . position . x ;
2020-03-19 23:32:09 -03:00
}
2022-09-29 12:53:28 +03:00
if ( current . position . y + current . size . y > parent_rect . position . y + parent_rect . size . y ) {
current . position . y = parent_rect . position . y + parent_rect . size . y - current . size . y ;
2020-03-19 23:32:09 -03:00
}
2022-09-29 12:53:28 +03:00
if ( current . position . y < parent_rect . position . y ) {
current . position . y = parent_rect . position . y ;
2020-03-19 23:32:09 -03:00
}
2022-09-29 12:53:28 +03:00
if ( current . size . y > parent_rect . size . y ) {
current . size . y = parent_rect . size . y ;
2020-08-29 22:05:59 +10:00
}
2022-09-29 12:53:28 +03:00
if ( current . size . x > parent_rect . size . x ) {
current . size . x = parent_rect . size . x ;
2020-08-29 22:05:59 +10:00
}
// Early out if max size not set.
2022-09-29 12:53:28 +03:00
Size2i popup_max_size = get_max_size ( ) ;
if ( popup_max_size < = Size2 ( ) ) {
2020-08-29 22:05:59 +10:00
return current ;
}
2022-09-29 12:53:28 +03:00
if ( current . size . x > popup_max_size . x ) {
current . size . x = popup_max_size . x ;
2020-08-29 22:05:59 +10:00
}
2022-09-29 12:53:28 +03:00
if ( current . size . y > popup_max_size . y ) {
current . size . y = popup_max_size . y ;
2020-08-29 22:05:59 +10:00
}
2020-03-19 23:32:09 -03:00
return current ;
}
2023-09-08 21:00:10 +02:00
void Popup : : _bind_methods ( ) {
ADD_SIGNAL ( MethodInfo ( " popup_hide " ) ) ;
}
2014-02-09 22:10:30 -03:00
Popup : : Popup ( ) {
2020-03-12 09:37:40 -03:00
set_wrap_controls ( true ) ;
set_visible ( false ) ;
set_transient ( true ) ;
set_flag ( FLAG_BORDERLESS , true ) ;
set_flag ( FLAG_RESIZE_DISABLED , true ) ;
2025-04-06 17:38:00 +03:00
set_flag ( FLAG_MINIMIZE_DISABLED , true ) ;
set_flag ( FLAG_MAXIMIZE_DISABLED , true ) ;
2022-02-24 11:21:23 +02:00
set_flag ( FLAG_POPUP , true ) ;
2024-09-27 13:59:48 +02:00
set_flag ( FLAG_POPUP_WM_HINT , true ) ;
2016-05-17 18:27:15 -03:00
}
2014-02-09 22:10:30 -03:00
Popup : : ~ Popup ( ) {
}
2025-01-08 20:00:20 -03:00
# ifdef TOOLS_ENABLED
PackedStringArray PopupPanel : : get_configuration_warnings ( ) const {
PackedStringArray warnings = Popup : : get_configuration_warnings ( ) ;
2025-04-29 14:48:52 +01:00
if ( ! DisplayServer : : get_singleton ( ) - > is_window_transparency_available ( ) & & ! GLOBAL_GET_CACHED ( bool , " display/window/subwindows/embed_subwindows " ) ) {
2025-01-08 20:00:20 -03:00
Ref < StyleBoxFlat > sb = theme_cache . panel_style ;
if ( sb . is_valid ( ) & & ( sb - > get_shadow_size ( ) > 0 | | sb - > get_corner_radius ( CORNER_TOP_LEFT ) > 0 | | sb - > get_corner_radius ( CORNER_TOP_RIGHT ) > 0 | | sb - > get_corner_radius ( CORNER_BOTTOM_LEFT ) > 0 | | sb - > get_corner_radius ( CORNER_BOTTOM_RIGHT ) > 0 ) ) {
warnings . push_back ( RTR ( " The current theme style has shadows and/or rounded corners for popups, but those won't display correctly if \" display/window/per_pixel_transparency/allowed \" isn't enabled in the Project Settings, nor if it isn't supported. " ) ) ;
}
}
return warnings ;
}
# endif
2024-04-29 01:09:58 -03:00
void PopupPanel : : _input_from_window ( const Ref < InputEvent > & p_event ) {
if ( p_event . is_valid ( ) ) {
if ( ! get_flag ( FLAG_POPUP ) ) {
return ;
}
Ref < InputEventMouseButton > b = p_event ;
// Hide it if the shadows have been clicked.
2025-02-09 14:50:47 -03:00
if ( b . is_valid ( ) & & b - > is_pressed ( ) & & b - > get_button_index ( ) = = MouseButton : : LEFT ) {
Rect2 panel_area = panel - > get_global_rect ( ) ;
float win_scale = get_content_scale_factor ( ) ;
panel_area . position * = win_scale ;
panel_area . size * = win_scale ;
if ( ! panel_area . has_point ( b - > get_position ( ) ) ) {
_close_pressed ( ) ;
}
2024-04-29 01:09:58 -03:00
}
} else {
WARN_PRINT_ONCE ( " PopupPanel has received an invalid InputEvent. Consider filtering out invalid events. " ) ;
}
Popup : : _input_from_window ( p_event ) ;
}
2020-03-12 09:37:40 -03:00
Size2 PopupPanel : : _get_contents_minimum_size ( ) const {
2018-09-07 13:49:10 -03:00
Size2 ms ;
for ( int i = 0 ; i < get_child_count ( ) ; i + + ) {
Control * c = Object : : cast_to < Control > ( get_child ( i ) ) ;
2020-05-14 16:41:43 +02:00
if ( ! c | | c = = panel ) {
2018-09-07 13:49:10 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2018-09-07 13:49:10 -03:00
2020-10-01 03:17:33 -04:00
if ( c - > is_set_as_top_level ( ) ) {
2018-09-07 13:49:10 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2018-09-07 13:49:10 -03:00
Size2 cms = c - > get_combined_minimum_size ( ) ;
2024-03-03 12:49:08 +01:00
ms = cms . max ( ms ) ;
2018-09-07 13:49:10 -03:00
}
2024-04-29 01:09:58 -03:00
// Take shadows into account.
ms . width + = panel - > get_offset ( SIDE_LEFT ) - panel - > get_offset ( SIDE_RIGHT ) ;
ms . height + = panel - > get_offset ( SIDE_TOP ) - panel - > get_offset ( SIDE_BOTTOM ) ;
2022-09-01 13:38:08 +03:00
return ms + theme_cache . panel_style - > get_minimum_size ( ) ;
2018-09-07 13:49:10 -03:00
}
2024-04-29 01:09:58 -03:00
Rect2i PopupPanel : : _popup_adjust_rect ( ) const {
Rect2i current = Popup : : _popup_adjust_rect ( ) ;
if ( current = = Rect2i ( ) ) {
return current ;
}
pre_popup_rect = current ;
_update_shadow_offsets ( ) ;
_update_child_rects ( ) ;
if ( is_layout_rtl ( ) ) {
2025-04-10 12:31:06 +01:00
current . position - = Vector2 ( - panel - > get_offset ( SIDE_RIGHT ) , panel - > get_offset ( SIDE_TOP ) ) * get_content_scale_factor ( ) ;
2024-04-29 01:09:58 -03:00
} else {
current . position - = Vector2 ( panel - > get_offset ( SIDE_LEFT ) , panel - > get_offset ( SIDE_TOP ) ) * get_content_scale_factor ( ) ;
}
current . size + = Vector2 ( panel - > get_offset ( SIDE_LEFT ) - panel - > get_offset ( SIDE_RIGHT ) , panel - > get_offset ( SIDE_TOP ) - panel - > get_offset ( SIDE_BOTTOM ) ) * get_content_scale_factor ( ) ;
return current ;
}
void PopupPanel : : _update_shadow_offsets ( ) const {
if ( ! DisplayServer : : get_singleton ( ) - > is_window_transparency_available ( ) & & ! is_embedded ( ) ) {
panel - > set_offsets_preset ( Control : : PRESET_FULL_RECT , Control : : PRESET_MODE_MINSIZE , 0 ) ;
return ;
}
const Ref < StyleBoxFlat > sb = theme_cache . panel_style ;
if ( sb . is_null ( ) ) {
panel - > set_offsets_preset ( Control : : PRESET_FULL_RECT , Control : : PRESET_MODE_MINSIZE , 0 ) ;
return ;
}
const int shadow_size = sb - > get_shadow_size ( ) ;
if ( shadow_size = = 0 ) {
panel - > set_offsets_preset ( Control : : PRESET_FULL_RECT , Control : : PRESET_MODE_MINSIZE , 0 ) ;
return ;
}
// Offset the background panel so it leaves space inside the window for the shadows to be drawn.
const Point2 shadow_offset = sb - > get_shadow_offset ( ) ;
if ( is_layout_rtl ( ) ) {
2025-04-10 12:31:06 +01:00
panel - > set_offset ( SIDE_LEFT , MAX ( 0 , shadow_size + shadow_offset . x ) ) ;
panel - > set_offset ( SIDE_RIGHT , MIN ( 0 , - shadow_size + shadow_offset . x ) ) ;
2024-04-29 01:09:58 -03:00
} else {
2025-04-10 12:31:06 +01:00
panel - > set_offset ( SIDE_LEFT , MAX ( 0 , shadow_size - shadow_offset . x ) ) ;
panel - > set_offset ( SIDE_RIGHT , MIN ( 0 , - shadow_size - shadow_offset . x ) ) ;
2024-04-29 01:09:58 -03:00
}
2025-04-10 12:31:06 +01:00
panel - > set_offset ( SIDE_TOP , MAX ( 0 , shadow_size - shadow_offset . y ) ) ;
panel - > set_offset ( SIDE_BOTTOM , MIN ( 0 , - shadow_size - shadow_offset . y ) ) ;
2024-04-29 01:09:58 -03:00
}
void PopupPanel : : _update_child_rects ( ) const {
2022-09-01 13:38:08 +03:00
Vector2 cpos ( theme_cache . panel_style - > get_offset ( ) ) ;
2024-04-29 01:09:58 -03:00
cpos + = Vector2 ( is_layout_rtl ( ) ? - panel - > get_offset ( SIDE_RIGHT ) : panel - > get_offset ( SIDE_LEFT ) , panel - > get_offset ( SIDE_TOP ) ) ;
Vector2 csize = Vector2 ( get_size ( ) ) / get_content_scale_factor ( ) - theme_cache . panel_style - > get_minimum_size ( ) ;
// Trim shadows.
csize . width - = panel - > get_offset ( SIDE_LEFT ) - panel - > get_offset ( SIDE_RIGHT ) ;
csize . height - = panel - > get_offset ( SIDE_TOP ) - panel - > get_offset ( SIDE_BOTTOM ) ;
2018-09-07 13:49:10 -03:00
for ( int i = 0 ; i < get_child_count ( ) ; i + + ) {
Control * c = Object : : cast_to < Control > ( get_child ( i ) ) ;
2024-04-29 01:09:58 -03:00
if ( ! c | | c = = panel ) {
2018-09-07 13:49:10 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2018-09-07 13:49:10 -03:00
2020-10-01 03:17:33 -04:00
if ( c - > is_set_as_top_level ( ) ) {
2018-09-07 13:49:10 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2018-09-07 13:49:10 -03:00
2024-04-29 01:09:58 -03:00
c - > set_position ( cpos ) ;
c - > set_size ( csize ) ;
2018-09-07 13:49:10 -03:00
}
2014-02-09 22:10:30 -03:00
}
void PopupPanel : : _notification ( int p_what ) {
2022-02-15 18:06:48 +01:00
switch ( p_what ) {
case NOTIFICATION_THEME_CHANGED : {
2024-05-14 15:50:53 +02:00
panel - > add_theme_style_override ( SceneStringName ( panel ) , theme_cache . panel_style ) ;
2024-04-29 01:09:58 -03:00
if ( is_visible ( ) ) {
_update_shadow_offsets ( ) ;
}
2022-02-15 18:06:48 +01:00
_update_child_rects ( ) ;
2025-01-08 20:00:20 -03:00
# ifdef TOOLS_ENABLED
update_configuration_warnings ( ) ;
# endif
2022-02-15 18:06:48 +01:00
} break ;
2025-05-26 07:52:07 +03:00
case Control : : NOTIFICATION_TRANSLATION_CHANGED :
2024-04-29 01:09:58 -03:00
case Control : : NOTIFICATION_LAYOUT_DIRECTION_CHANGED : {
if ( is_visible ( ) ) {
_update_shadow_offsets ( ) ;
}
} break ;
case NOTIFICATION_VISIBILITY_CHANGED : {
if ( ! is_visible ( ) ) {
// Remove the extra space used by the shadows, so they can be ignored when the popup is hidden.
panel - > set_offsets_preset ( Control : : PRESET_FULL_RECT , Control : : PRESET_MODE_MINSIZE , 0 ) ;
_update_child_rects ( ) ;
if ( pre_popup_rect ! = Rect2i ( ) ) {
set_position ( pre_popup_rect . position ) ;
set_size ( pre_popup_rect . size ) ;
pre_popup_rect = Rect2i ( ) ;
}
} else if ( pre_popup_rect = = Rect2i ( ) ) {
// The popup was made visible directly (without `popup_*()`), so just update the offsets without touching the rect.
_update_shadow_offsets ( ) ;
_update_child_rects ( ) ;
}
} break ;
2022-02-15 18:06:48 +01:00
case NOTIFICATION_WM_SIZE_CHANGED : {
_update_child_rects ( ) ;
2024-04-29 01:09:58 -03:00
if ( is_visible ( ) ) {
const Vector2i offsets = Vector2i ( panel - > get_offset ( SIDE_LEFT ) - panel - > get_offset ( SIDE_RIGHT ) , panel - > get_offset ( SIDE_TOP ) - panel - > get_offset ( SIDE_BOTTOM ) ) ;
// Check if the size actually changed.
if ( pre_popup_rect . size + offsets ! = get_size ( ) ) {
// Play safe, and stick with the new size.
pre_popup_rect = Rect2i ( ) ;
}
}
2022-02-15 18:06:48 +01:00
} break ;
2014-02-09 22:10:30 -03:00
}
}
2023-09-08 21:00:10 +02:00
void PopupPanel : : _bind_methods ( ) {
BIND_THEME_ITEM_CUSTOM ( Theme : : DATA_TYPE_STYLEBOX , PopupPanel , panel_style , " panel " ) ;
}
2014-02-09 22:10:30 -03:00
PopupPanel : : PopupPanel ( ) {
2024-04-29 01:09:58 -03:00
set_flag ( FLAG_TRANSPARENT , true ) ;
2020-03-12 09:37:40 -03:00
panel = memnew ( Panel ) ;
2024-04-29 01:09:58 -03:00
panel - > set_anchors_and_offsets_preset ( Control : : PRESET_FULL_RECT ) ;
2021-08-25 15:49:30 +02:00
add_child ( panel , false , INTERNAL_MODE_FRONT ) ;
2025-01-08 20:00:20 -03:00
# ifdef TOOLS_ENABLED
ProjectSettings : : get_singleton ( ) - > connect ( " settings_changed " , callable_mp ( ( Node * ) this , & Node : : update_configuration_warnings ) ) ;
# endif
2014-02-09 22:10:30 -03:00
}