2023-01-10 15:26:54 +01:00
/**************************************************************************/
/* control.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-10 02:10:30 +01:00
# include "control.h"
2018-09-11 18:13:45 +02:00
# include "core/message_queue.h"
# include "core/os/keyboard.h"
# include "core/os/os.h"
# include "core/print_string.h"
2019-06-12 22:35:35 +02:00
# include "core/project_settings.h"
2014-02-10 02:10:30 +01:00
# include "scene/gui/label.h"
2017-03-05 16:44:50 +01:00
# include "scene/gui/panel.h"
2019-06-12 22:35:35 +02:00
# include "scene/main/canvas_layer.h"
# include "scene/main/viewport.h"
2017-03-05 16:44:50 +01:00
# include "scene/scene_string_names.h"
2019-06-12 22:35:35 +02:00
# include "servers/visual_server.h"
2016-03-09 17:59:35 +01:00
# ifdef TOOLS_ENABLED
2017-03-05 14:21:25 +01:00
# include "editor/editor_settings.h"
2019-03-31 18:53:24 +02:00
# include "editor/plugins/canvas_item_editor_plugin.h"
2016-03-09 17:59:35 +01:00
# endif
2014-02-10 02:10:30 +01:00
2019-10-21 23:37:07 +02:00
# ifdef TOOLS_ENABLED
2017-11-15 23:03:25 +01:00
Dictionary Control : : _edit_get_state ( ) const {
2016-06-27 15:47:51 +02:00
Dictionary s ;
2017-09-10 15:37:49 +02:00
s [ " rotation " ] = get_rotation ( ) ;
2017-03-05 16:44:50 +01:00
s [ " scale " ] = get_scale ( ) ;
2017-11-07 08:58:35 +01:00
s [ " pivot " ] = get_pivot_offset ( ) ;
2017-08-05 01:55:03 +02:00
Array anchors ;
anchors . push_back ( get_anchor ( MARGIN_LEFT ) ) ;
anchors . push_back ( get_anchor ( MARGIN_TOP ) ) ;
anchors . push_back ( get_anchor ( MARGIN_RIGHT ) ) ;
anchors . push_back ( get_anchor ( MARGIN_BOTTOM ) ) ;
s [ " anchors " ] = anchors ;
2017-11-07 08:58:35 +01:00
Array margins ;
margins . push_back ( get_margin ( MARGIN_LEFT ) ) ;
margins . push_back ( get_margin ( MARGIN_TOP ) ) ;
margins . push_back ( get_margin ( MARGIN_RIGHT ) ) ;
margins . push_back ( get_margin ( MARGIN_BOTTOM ) ) ;
s [ " margins " ] = margins ;
2016-06-27 15:47:51 +02:00
return s ;
2014-02-10 02:10:30 +01:00
}
2019-03-31 18:53:24 +02:00
2017-11-15 23:03:25 +01:00
void Control : : _edit_set_state ( const Dictionary & p_state ) {
2021-03-05 17:17:22 +01:00
ERR_FAIL_COND ( ( p_state . size ( ) < = 0 ) | |
2021-10-28 13:23:24 +02:00
! p_state . has ( " rotation " ) | | ! p_state . has ( " scale " ) | |
! p_state . has ( " pivot " ) | | ! p_state . has ( " anchors " ) | | ! p_state . has ( " margins " ) ) ;
2017-11-15 23:03:25 +01:00
Dictionary state = p_state ;
2016-06-27 15:47:51 +02:00
2017-11-15 23:03:25 +01:00
set_rotation ( state [ " rotation " ] ) ;
set_scale ( state [ " scale " ] ) ;
2017-11-07 08:58:35 +01:00
set_pivot_offset ( state [ " pivot " ] ) ;
2017-11-15 23:03:25 +01:00
Array anchors = state [ " anchors " ] ;
2017-11-07 08:58:35 +01:00
data . anchor [ MARGIN_LEFT ] = anchors [ 0 ] ;
data . anchor [ MARGIN_TOP ] = anchors [ 1 ] ;
data . anchor [ MARGIN_RIGHT ] = anchors [ 2 ] ;
data . anchor [ MARGIN_BOTTOM ] = anchors [ 3 ] ;
Array margins = state [ " margins " ] ;
data . margin [ MARGIN_LEFT ] = margins [ 0 ] ;
data . margin [ MARGIN_TOP ] = margins [ 1 ] ;
data . margin [ MARGIN_RIGHT ] = margins [ 2 ] ;
data . margin [ MARGIN_BOTTOM ] = margins [ 3 ] ;
_size_changed ( ) ;
2021-05-28 14:50:13 +02:00
_change_notify ( " anchor_left " ) ;
_change_notify ( " anchor_right " ) ;
_change_notify ( " anchor_top " ) ;
_change_notify ( " anchor_bottom " ) ;
2014-02-10 02:10:30 +01:00
}
2017-11-15 23:03:25 +01:00
void Control : : _edit_set_position ( const Point2 & p_position ) {
2019-03-31 18:53:24 +02:00
# ifdef TOOLS_ENABLED
2021-03-14 12:35:29 +01:00
ERR_FAIL_COND_MSG ( ! Engine : : get_singleton ( ) - > is_editor_hint ( ) , " This function can only be used from editor plugins. " ) ;
2021-07-07 13:19:59 +02:00
set_position ( p_position , CanvasItemEditor : : get_singleton ( ) - > is_anchors_mode_enabled ( ) & & Object : : cast_to < Control > ( data . parent ) ) ;
2019-03-31 18:53:24 +02:00
# else
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
2017-11-15 23:03:25 +01:00
set_position ( p_position ) ;
2019-03-31 18:53:24 +02:00
# endif
2021-10-28 14:15:02 +02:00
}
2017-11-15 23:03:25 +01:00
Point2 Control : : _edit_get_position ( ) const {
return get_position ( ) ;
2021-10-28 14:15:02 +02:00
}
2017-11-15 23:03:25 +01:00
2018-03-08 21:35:41 +01:00
void Control : : _edit_set_scale ( const Size2 & p_scale ) {
set_scale ( p_scale ) ;
}
Size2 Control : : _edit_get_scale ( ) const {
return data . scale ;
}
2017-11-15 23:03:25 +01:00
void Control : : _edit_set_rect ( const Rect2 & p_edit_rect ) {
2019-03-31 18:53:24 +02:00
# ifdef TOOLS_ENABLED
2021-03-14 12:35:29 +01:00
ERR_FAIL_COND_MSG ( ! Engine : : get_singleton ( ) - > is_editor_hint ( ) , " This function can only be used from editor plugins. " ) ;
2019-03-31 18:53:24 +02:00
set_position ( ( get_position ( ) + get_transform ( ) . basis_xform ( p_edit_rect . position ) ) . snapped ( Vector2 ( 1 , 1 ) ) , CanvasItemEditor : : get_singleton ( ) - > is_anchors_mode_enabled ( ) ) ;
set_size ( p_edit_rect . size . snapped ( Vector2 ( 1 , 1 ) ) , CanvasItemEditor : : get_singleton ( ) - > is_anchors_mode_enabled ( ) ) ;
# else
// Unlikely to happen. TODO: enclose all _edit_ functions into TOOLS_ENABLED
2017-11-07 08:58:35 +01:00
set_position ( ( get_position ( ) + get_transform ( ) . basis_xform ( p_edit_rect . position ) ) . snapped ( Vector2 ( 1 , 1 ) ) ) ;
set_size ( p_edit_rect . size . snapped ( Vector2 ( 1 , 1 ) ) ) ;
2019-03-31 18:53:24 +02:00
# endif
2017-11-15 23:03:25 +01:00
}
Rect2 Control : : _edit_get_rect ( ) const {
return Rect2 ( Point2 ( ) , get_size ( ) ) ;
}
bool Control : : _edit_use_rect ( ) const {
return true ;
}
void Control : : _edit_set_rotation ( float p_rotation ) {
set_rotation ( p_rotation ) ;
}
float Control : : _edit_get_rotation ( ) const {
return get_rotation ( ) ;
}
bool Control : : _edit_use_rotation ( ) const {
return true ;
}
void Control : : _edit_set_pivot ( const Point2 & p_pivot ) {
2017-11-07 08:58:35 +01:00
Vector2 delta_pivot = p_pivot - get_pivot_offset ( ) ;
Vector2 move = Vector2 ( ( cos ( data . rotation ) - 1.0 ) * delta_pivot . x - sin ( data . rotation ) * delta_pivot . y , sin ( data . rotation ) * delta_pivot . x + ( cos ( data . rotation ) - 1.0 ) * delta_pivot . y ) ;
set_position ( get_position ( ) + move ) ;
2017-11-15 23:03:25 +01:00
set_pivot_offset ( p_pivot ) ;
}
Point2 Control : : _edit_get_pivot ( ) const {
return get_pivot_offset ( ) ;
}
bool Control : : _edit_use_pivot ( ) const {
return true ;
}
2019-10-21 23:37:07 +02:00
Size2 Control : : _edit_get_minimum_size ( ) const {
return get_combined_minimum_size ( ) ;
}
# endif
2017-03-05 16:44:50 +01:00
void Control : : set_custom_minimum_size ( const Size2 & p_custom ) {
2021-05-05 12:44:11 +02:00
if ( p_custom = = data . custom_minimum_size ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2022-06-09 20:19:27 +02:00
if ( isnan ( p_custom . x ) | | isnan ( p_custom . y ) ) {
// Prevent infinite loop.
return ;
}
2017-03-05 16:44:50 +01:00
data . custom_minimum_size = p_custom ;
2014-02-10 02:10:30 +01:00
minimum_size_changed ( ) ;
}
2017-03-05 16:44:50 +01:00
Size2 Control : : get_custom_minimum_size ( ) const {
2014-02-10 02:10:30 +01:00
return data . custom_minimum_size ;
}
2018-05-15 22:12:35 +02:00
void Control : : _update_minimum_size_cache ( ) {
2014-02-10 02:10:30 +01:00
Size2 minsize = get_minimum_size ( ) ;
2017-03-05 16:44:50 +01:00
minsize . x = MAX ( minsize . x , data . custom_minimum_size . x ) ;
minsize . y = MAX ( minsize . y , data . custom_minimum_size . y ) ;
2018-07-01 02:36:54 +02:00
bool size_changed = false ;
2021-05-05 12:44:11 +02:00
if ( data . minimum_size_cache ! = minsize ) {
2018-07-01 02:36:54 +02:00
size_changed = true ;
2021-05-05 12:44:11 +02:00
}
2018-07-01 02:36:54 +02:00
2018-05-15 22:12:35 +02:00
data . minimum_size_cache = minsize ;
data . minimum_size_valid = true ;
2018-07-01 02:36:54 +02:00
2021-05-05 12:44:11 +02:00
if ( size_changed ) {
2018-07-01 02:36:54 +02:00
minimum_size_changed ( ) ;
2021-05-05 12:44:11 +02:00
}
2018-05-15 22:12:35 +02:00
}
Size2 Control : : get_combined_minimum_size ( ) const {
if ( ! data . minimum_size_valid ) {
const_cast < Control * > ( this ) - > _update_minimum_size_cache ( ) ;
}
return data . minimum_size_cache ;
2014-02-10 02:10:30 +01:00
}
2017-07-06 22:42:44 +02:00
Transform2D Control : : _get_internal_transform ( ) const {
Transform2D rot_scale ;
rot_scale . set_rotation_and_scale ( data . rotation , data . scale ) ;
Transform2D offset ;
offset . set_origin ( - data . pivot_offset ) ;
return offset . affine_inverse ( ) * ( rot_scale * offset ) ;
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool Control : : _set ( const StringName & p_name , const Variant & p_value ) {
String name = p_name ;
2016-03-20 06:25:05 +01:00
if ( ! name . begins_with ( " custom " ) ) {
2017-01-08 23:11:35 +01:00
return false ;
2016-03-20 06:25:05 +01:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p_value . get_type ( ) = = Variant : : NIL ) {
2014-02-10 02:10:30 +01:00
if ( name . begins_with ( " custom_icons/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_icon_override ( dname ) ;
2015-12-20 22:21:53 +01:00
} else if ( name . begins_with ( " custom_shaders/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_shader_override ( dname ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_styles/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_stylebox_override ( dname ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_fonts/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_font_override ( dname ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_colors/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_color_override ( dname ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_constants/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
2021-11-11 11:23:37 +01:00
remove_constant_override ( dname ) ;
2021-05-05 12:44:11 +02:00
} else {
2014-02-10 02:10:30 +01:00
return false ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
} else {
if ( name . begins_with ( " custom_icons/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_icon_override ( dname , p_value ) ;
2015-12-20 22:21:53 +01:00
} else if ( name . begins_with ( " custom_shaders/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_shader_override ( dname , p_value ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_styles/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_style_override ( dname , p_value ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_fonts/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_font_override ( dname , p_value ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_colors/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_color_override ( dname , p_value ) ;
2014-02-10 02:10:30 +01:00
} else if ( name . begins_with ( " custom_constants/ " ) ) {
2017-03-05 16:44:50 +01:00
String dname = name . get_slicec ( ' / ' , 1 ) ;
add_constant_override ( dname , p_value ) ;
2021-05-05 12:44:11 +02:00
} else {
2014-02-10 02:10:30 +01:00
return false ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
return true ;
}
void Control : : _update_minimum_size ( ) {
2021-05-05 12:44:11 +02:00
if ( ! is_inside_tree ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
Size2 minsize = get_combined_minimum_size ( ) ;
2018-05-15 22:12:35 +02:00
data . updating_last_minimum_size = false ;
if ( minsize ! = data . last_minimum_size ) {
2018-05-17 23:02:16 +02:00
data . last_minimum_size = minsize ;
2021-03-05 18:24:06 +01:00
_size_changed ( ) ;
2018-05-15 22:12:35 +02:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > minimum_size_changed ) ;
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
bool Control : : _get ( const StringName & p_name , Variant & r_ret ) const {
String sname = p_name ;
2014-02-10 02:10:30 +01:00
2016-06-12 20:31:38 +02:00
if ( ! sname . begins_with ( " custom " ) ) {
2017-01-08 23:11:35 +01:00
return false ;
2016-06-12 20:31:38 +02:00
}
2014-02-10 02:10:30 +01:00
if ( sname . begins_with ( " custom_icons/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
r_ret = data . icon_override . has ( name ) ? Variant ( data . icon_override [ name ] ) : Variant ( ) ;
2015-12-20 22:21:53 +01:00
} else if ( sname . begins_with ( " custom_shaders/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
2015-12-20 22:21:53 +01:00
2017-03-05 16:44:50 +01:00
r_ret = data . shader_override . has ( name ) ? Variant ( data . shader_override [ name ] ) : Variant ( ) ;
2014-02-10 02:10:30 +01:00
} else if ( sname . begins_with ( " custom_styles/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
r_ret = data . style_override . has ( name ) ? Variant ( data . style_override [ name ] ) : Variant ( ) ;
2014-02-10 02:10:30 +01:00
} else if ( sname . begins_with ( " custom_fonts/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
r_ret = data . font_override . has ( name ) ? Variant ( data . font_override [ name ] ) : Variant ( ) ;
2014-02-10 02:10:30 +01:00
} else if ( sname . begins_with ( " custom_colors/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
r_ret = data . color_override . has ( name ) ? Variant ( data . color_override [ name ] ) : Variant ( ) ;
2014-02-10 02:10:30 +01:00
} else if ( sname . begins_with ( " custom_constants/ " ) ) {
2017-03-05 16:44:50 +01:00
String name = sname . get_slicec ( ' / ' , 1 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
r_ret = data . constant_override . has ( name ) ? Variant ( data . constant_override [ name ] ) : Variant ( ) ;
2021-05-05 12:44:11 +02:00
} else {
2014-02-10 02:10:30 +01:00
return false ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
return true ;
}
2021-08-04 16:02:00 +02:00
2017-03-05 16:44:50 +01:00
void Control : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2018-11-14 18:02:21 +01:00
Ref < Theme > theme = Theme : : get_default ( ) ;
2018-11-14 16:23:47 +01:00
2022-04-01 05:04:25 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : NIL , TTRC ( " Theme Overrides " ) , PROPERTY_HINT_NONE , " custom_ " , PROPERTY_USAGE_GROUP ) ) ;
2014-02-10 02:10:30 +01:00
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_color_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . color_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : COLOR , " custom_colors/ " + E - > get ( ) , PROPERTY_HINT_NONE , " " , hint ) ) ;
2014-02-10 02:10:30 +01:00
}
}
2015-12-20 22:21:53 +01:00
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_constant_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . constant_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2015-12-20 22:21:53 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : INT , " custom_constants/ " + E - > get ( ) , PROPERTY_HINT_RANGE , " -16384,16384 " , hint ) ) ;
2015-12-20 22:21:53 +01:00
}
}
2014-02-10 02:10:30 +01:00
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_font_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . font_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , " custom_fonts/ " + E - > get ( ) , PROPERTY_HINT_RESOURCE_TYPE , " Font " , hint ) ) ;
2014-02-10 02:10:30 +01:00
}
}
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_icon_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . icon_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , " custom_icons/ " + E - > get ( ) , PROPERTY_HINT_RESOURCE_TYPE , " Texture " , hint ) ) ;
2014-02-10 02:10:30 +01:00
}
}
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_shader_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . shader_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , " custom_shaders/ " + E - > get ( ) , PROPERTY_HINT_RESOURCE_TYPE , " Shader,VisualShader " , hint ) ) ;
2014-02-10 02:10:30 +01:00
}
}
{
List < StringName > names ;
2021-08-04 16:02:00 +02:00
theme - > get_stylebox_list ( get_class_name ( ) , & names ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE ;
2021-08-04 16:02:00 +02:00
if ( data . style_override . has ( E - > get ( ) ) ) {
2017-03-05 16:44:50 +01:00
hint | = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-04 16:02:00 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , " custom_styles/ " + E - > get ( ) , PROPERTY_HINT_RESOURCE_TYPE , " StyleBox " , hint ) ) ;
2014-02-10 02:10:30 +01:00
}
}
}
2022-02-10 22:26:09 +01:00
void Control : : _validate_property ( PropertyInfo & property ) const {
if ( property . name = = " theme_type_variation " ) {
List < StringName > names ;
// Only the default theme and the project theme are used for the list of options.
// This is an imposed limitation to simplify the logic needed to leverage those options.
Theme : : get_default ( ) - > get_type_variation_list ( get_class_name ( ) , & names ) ;
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
Theme : : get_project_default ( ) - > get_type_variation_list ( get_class_name ( ) , & names ) ;
}
names . sort_custom < StringName : : AlphCompare > ( ) ;
Vector < StringName > unique_names ;
String hint_string ;
for ( const List < StringName > : : Element * E = names . front ( ) ; E ; E = E - > next ( ) ) {
// Skip duplicate values.
if ( unique_names . find ( E - > get ( ) ) ! = - 1 ) {
continue ;
}
hint_string + = String ( E - > get ( ) ) + " , " ;
unique_names . push_back ( E - > get ( ) ) ;
}
property . hint_string = hint_string ;
}
2022-04-05 02:58:21 +02:00
if ( property . name = = " rect_scale " ) {
property . hint = PROPERTY_HINT_LINK ;
}
2022-02-10 22:26:09 +01:00
}
2014-02-10 02:10:30 +01:00
Control * Control : : get_parent_control ( ) const {
return data . parent ;
}
2017-03-05 16:44:50 +01:00
void Control : : _resize ( const Size2 & p_size ) {
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
2016-08-06 03:46:45 +02:00
//moved theme configuration here, so controls can set up even if still not inside active scene
void Control : : add_child_notify ( Node * p_child ) {
2017-08-24 22:58:51 +02:00
Control * child_c = Object : : cast_to < Control > ( p_child ) ;
2021-05-05 12:44:11 +02:00
if ( ! child_c ) {
2016-08-06 03:46:45 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2016-08-06 03:46:45 +02:00
if ( child_c - > data . theme . is_null ( ) & & data . theme_owner ) {
2017-03-05 16:44:50 +01:00
_propagate_theme_changed ( child_c , data . theme_owner ) ; //need to propagate here, since many controls may require setting up stuff
2016-08-06 03:46:45 +02:00
}
}
void Control : : remove_child_notify ( Node * p_child ) {
2017-08-24 22:58:51 +02:00
Control * child_c = Object : : cast_to < Control > ( p_child ) ;
2021-05-05 12:44:11 +02:00
if ( ! child_c ) {
2016-08-06 03:46:45 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2016-08-06 03:46:45 +02:00
if ( child_c - > data . theme_owner & & child_c - > data . theme . is_null ( ) ) {
2021-05-04 16:00:45 +02:00
_propagate_theme_changed ( child_c , nullptr ) ;
2016-08-06 03:46:45 +02:00
}
}
2014-02-10 02:10:30 +01:00
2016-08-31 04:44:14 +02:00
void Control : : _update_canvas_item_transform ( ) {
2017-07-06 22:42:44 +02:00
Transform2D xform = _get_internal_transform ( ) ;
xform [ 2 ] + = get_position ( ) ;
2021-03-11 11:01:48 +01:00
// We use a little workaround to avoid flickering when moving the pivot with _edit_set_pivot()
if ( is_inside_tree ( ) & & Math : : abs ( Math : : sin ( data . rotation * 4.0f ) ) < 0.00001f & & get_viewport ( ) - > is_snap_controls_to_pixels_enabled ( ) ) {
xform [ 2 ] = xform [ 2 ] . round ( ) ;
}
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > canvas_item_set_transform ( get_canvas_item ( ) , xform ) ;
2016-08-31 04:44:14 +02:00
}
2014-02-10 02:10:30 +01:00
void Control : : _notification ( int p_notification ) {
2017-03-05 16:44:50 +01:00
switch ( p_notification ) {
2014-11-06 01:20:42 +01:00
case NOTIFICATION_ENTER_TREE : {
2022-08-12 13:36:06 +02:00
_invalidate_theme_cache ( ) ;
2018-05-15 22:12:35 +02:00
} break ;
case NOTIFICATION_POST_ENTER_TREE : {
2018-06-02 02:28:49 +02:00
data . minimum_size_valid = false ;
_size_changed ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
2014-11-06 01:20:42 +01:00
case NOTIFICATION_EXIT_TREE : {
2021-10-28 01:26:57 +02:00
ERR_FAIL_COND ( ! get_viewport ( ) ) ;
2021-12-26 17:53:07 +01:00
release_focus ( ) ;
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_remove_control ( this ) ;
2021-02-25 15:00:49 +01:00
2014-02-10 02:10:30 +01:00
} break ;
case NOTIFICATION_ENTER_CANVAS : {
2017-08-24 22:58:51 +02:00
data . parent = Object : : cast_to < Control > ( get_parent ( ) ) ;
2014-02-10 02:10:30 +01:00
2022-06-01 02:56:51 +02:00
if ( data . theme . is_null ( ) & & data . parent & & data . parent - > data . theme_owner ) {
data . theme_owner = data . parent - > data . theme_owner ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2016-01-17 02:41:10 +01:00
if ( is_set_as_toplevel ( ) ) {
2017-03-05 16:44:50 +01:00
data . SI = get_viewport ( ) - > _gui_add_subwindow_control ( this ) ;
2016-01-17 02:41:10 +01:00
} else {
2022-06-01 02:56:51 +02:00
Node * parent = get_parent ( ) ;
bool is_subwindow = false ;
bool has_parent_control = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
while ( parent ) {
2017-08-24 22:58:51 +02:00
CanvasItem * ci = Object : : cast_to < CanvasItem > ( parent ) ;
2016-01-17 02:41:10 +01:00
if ( ci & & ci - > is_set_as_toplevel ( ) ) {
2022-06-01 02:56:51 +02:00
is_subwindow = true ;
2016-01-17 02:41:10 +01:00
break ;
2014-02-10 02:10:30 +01:00
}
2022-06-01 02:56:51 +02:00
Control * parent_control = Object : : cast_to < Control > ( parent ) ;
2016-06-14 02:37:04 +02:00
if ( parent_control ) {
2022-06-01 02:56:51 +02:00
has_parent_control = true ;
2016-01-17 02:41:10 +01:00
break ;
} else if ( ci ) {
2022-06-01 02:56:51 +02:00
// Continue.
2016-01-17 02:41:10 +01:00
} else {
break ;
}
2022-06-01 02:56:51 +02:00
parent = parent - > get_parent ( ) ;
2014-02-10 02:10:30 +01:00
}
2022-06-01 02:56:51 +02:00
if ( has_parent_control ) {
// Do nothing, has a parent control.
} else if ( is_subwindow ) {
// Is a subwindow (process input before other controls for that canvas).
2017-03-05 16:44:50 +01:00
data . SI = get_viewport ( ) - > _gui_add_subwindow_control ( this ) ;
2016-01-17 02:41:10 +01:00
} else {
2022-06-01 02:56:51 +02:00
// Is a regular root control.
2021-10-24 00:42:19 +02:00
Viewport * viewport = get_viewport ( ) ;
ERR_FAIL_COND ( ! viewport ) ;
data . RI = viewport - > _gui_add_root_control ( this ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
data . parent_canvas_item = get_parent_item ( ) ;
2014-02-10 02:10:30 +01:00
2016-01-17 02:41:10 +01:00
if ( data . parent_canvas_item ) {
2017-03-05 16:44:50 +01:00
data . parent_canvas_item - > connect ( " item_rect_changed " , this , " _size_changed " ) ;
} else {
2022-06-01 02:56:51 +02:00
// Connect viewport.
2021-10-24 00:42:19 +02:00
Viewport * viewport = get_viewport ( ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > connect ( " size_changed " , this , " _size_changed " ) ;
2016-01-17 02:41:10 +01:00
}
2014-02-10 02:10:30 +01:00
}
} break ;
case NOTIFICATION_EXIT_CANVAS : {
if ( data . parent_canvas_item ) {
2017-03-05 16:44:50 +01:00
data . parent_canvas_item - > disconnect ( " item_rect_changed " , this , " _size_changed " ) ;
2021-05-04 16:00:45 +02:00
data . parent_canvas_item = nullptr ;
2016-01-18 00:03:57 +01:00
} else if ( ! is_set_as_toplevel ( ) ) {
2016-01-17 02:41:10 +01:00
//disconnect viewport
2021-10-24 00:42:19 +02:00
Viewport * viewport = get_viewport ( ) ;
ERR_FAIL_COND ( ! viewport ) ;
viewport - > disconnect ( " size_changed " , this , " _size_changed " ) ;
2014-02-10 02:10:30 +01:00
}
if ( data . MI ) {
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_remove_modal_control ( data . MI ) ;
2021-05-04 16:00:45 +02:00
data . MI = nullptr ;
2014-02-10 02:10:30 +01:00
}
if ( data . SI ) {
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_remove_subwindow_control ( data . SI ) ;
2021-05-04 16:00:45 +02:00
data . SI = nullptr ;
2014-02-10 02:10:30 +01:00
}
2016-01-17 02:41:10 +01:00
if ( data . RI ) {
get_viewport ( ) - > _gui_remove_root_control ( data . RI ) ;
2021-05-04 16:00:45 +02:00
data . RI = nullptr ;
2016-01-17 02:41:10 +01:00
}
2021-05-04 16:00:45 +02:00
data . parent = nullptr ;
data . parent_canvas_item = nullptr ;
2017-01-14 12:26:56 +01:00
/*
if ( data . theme_owner & & data . theme . is_null ( ) ) {
data . theme_owner = NULL ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
*/
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
} break ;
2014-02-10 02:10:30 +01:00
case NOTIFICATION_RESIZED : {
emit_signal ( SceneStringNames : : get_singleton ( ) - > resized ) ;
} break ;
case NOTIFICATION_DRAW : {
2016-08-31 04:44:14 +02:00
_update_canvas_item_transform ( ) ;
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > canvas_item_set_custom_rect ( get_canvas_item ( ) , ! data . disable_visibility_clip , Rect2 ( Point2 ( ) , get_size ( ) ) ) ;
VisualServer : : get_singleton ( ) - > canvas_item_set_clip ( get_canvas_item ( ) , data . clip_contents ) ;
2014-02-10 02:10:30 +01:00
//emit_signal(SceneStringNames::get_singleton()->draw);
} break ;
case NOTIFICATION_MOUSE_ENTER : {
2017-01-12 04:51:08 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > mouse_entered ) ;
2014-02-10 02:10:30 +01:00
} break ;
case NOTIFICATION_MOUSE_EXIT : {
2017-01-12 04:51:08 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > mouse_exited ) ;
2014-02-10 02:10:30 +01:00
} break ;
case NOTIFICATION_FOCUS_ENTER : {
2017-01-12 04:51:08 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > focus_entered ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
} break ;
case NOTIFICATION_FOCUS_EXIT : {
2017-01-12 04:51:08 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > focus_exited ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
} break ;
case NOTIFICATION_THEME_CHANGED : {
2022-08-12 13:36:06 +02:00
_invalidate_theme_cache ( ) ;
2019-09-03 20:48:47 +02:00
minimum_size_changed ( ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
} break ;
2016-01-23 15:45:36 +01:00
case NOTIFICATION_MODAL_CLOSE : {
2017-01-12 04:51:08 +01:00
emit_signal ( " modal_closed " ) ;
2016-01-23 15:45:36 +01:00
} break ;
2014-02-10 02:10:30 +01:00
case NOTIFICATION_VISIBILITY_CHANGED : {
2017-01-13 14:45:50 +01:00
if ( ! is_visible_in_tree ( ) ) {
2021-05-05 12:44:11 +02:00
if ( get_viewport ( ) ! = nullptr ) {
2016-03-22 05:46:33 +01:00
get_viewport ( ) - > _gui_hid_control ( this ) ;
2021-05-05 12:44:11 +02:00
}
2016-04-07 09:46:38 +02:00
2017-03-05 16:44:50 +01:00
if ( is_inside_tree ( ) ) {
2016-04-07 09:46:38 +02:00
_modal_stack_remove ( ) ;
}
2014-02-10 02:10:30 +01:00
//remove key focus
//remove modalness
} else {
2018-05-15 22:12:35 +02:00
data . minimum_size_valid = false ;
2022-05-22 09:49:42 +02:00
_update_minimum_size ( ) ;
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
} break ;
2014-11-06 01:20:42 +01:00
case SceneTree : : NOTIFICATION_WM_UNFOCUS_REQUEST : {
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_unfocus_control ( this ) ;
2014-02-10 02:10:30 +01:00
} break ;
}
}
bool Control : : clips_input ( ) const {
2018-07-29 17:46:53 +02:00
if ( get_script_instance ( ) ) {
return get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > _clips_input ) ;
}
2014-02-10 02:10:30 +01:00
return false ;
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
bool Control : : has_point ( const Point2 & p_point ) const {
2014-02-10 02:10:30 +01:00
if ( get_script_instance ( ) ) {
2017-03-05 16:44:50 +01:00
Variant v = p_point ;
const Variant * p = & v ;
2014-02-10 02:10:30 +01:00
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
Variant ret = get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > has_point , & p , 1 , ce ) ;
if ( ce . error = = Variant : : CallError : : CALL_OK ) {
2014-02-10 02:10:30 +01:00
return ret ;
}
}
2017-03-05 16:44:50 +01:00
return Rect2 ( Point2 ( ) , get_size ( ) ) . has_point ( p_point ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void Control : : set_drag_forwarding ( Control * p_target ) {
2021-05-05 12:44:11 +02:00
if ( p_target ) {
2017-08-07 12:17:31 +02:00
data . drag_owner = p_target - > get_instance_id ( ) ;
2021-05-05 12:44:11 +02:00
} else {
2017-03-05 16:44:50 +01:00
data . drag_owner = 0 ;
2021-05-05 12:44:11 +02:00
}
2016-05-03 16:10:28 +02:00
}
2017-03-05 16:44:50 +01:00
Variant Control : : get_drag_data ( const Point2 & p_point ) {
2016-05-03 16:10:28 +02:00
if ( data . drag_owner ) {
Object * obj = ObjectDB : : get_instance ( data . drag_owner ) ;
if ( obj ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( obj ) ;
2017-03-05 16:44:50 +01:00
return c - > call ( " get_drag_data_fw " , p_point , this ) ;
2016-05-03 16:10:28 +02:00
}
}
2014-02-10 02:10:30 +01:00
if ( get_script_instance ( ) ) {
2017-03-05 16:44:50 +01:00
Variant v = p_point ;
const Variant * p = & v ;
2014-02-10 02:10:30 +01:00
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
Variant ret = get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > get_drag_data , & p , 1 , ce ) ;
2021-05-05 12:44:11 +02:00
if ( ce . error = = Variant : : CallError : : CALL_OK ) {
2014-02-10 02:10:30 +01:00
return ret ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
return Variant ( ) ;
}
2017-03-05 16:44:50 +01:00
bool Control : : can_drop_data ( const Point2 & p_point , const Variant & p_data ) const {
2016-05-03 16:10:28 +02:00
if ( data . drag_owner ) {
Object * obj = ObjectDB : : get_instance ( data . drag_owner ) ;
if ( obj ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( obj ) ;
2017-03-05 16:44:50 +01:00
return c - > call ( " can_drop_data_fw " , p_point , p_data , this ) ;
2016-05-03 16:10:28 +02:00
}
}
2014-02-10 02:10:30 +01:00
if ( get_script_instance ( ) ) {
2017-03-05 16:44:50 +01:00
Variant v = p_point ;
const Variant * p [ 2 ] = { & v , & p_data } ;
2014-02-10 02:10:30 +01:00
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
Variant ret = get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > can_drop_data , p , 2 , ce ) ;
2021-05-05 12:44:11 +02:00
if ( ce . error = = Variant : : CallError : : CALL_OK ) {
2014-02-10 02:10:30 +01:00
return ret ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2020-12-13 20:16:56 +01:00
return false ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
void Control : : drop_data ( const Point2 & p_point , const Variant & p_data ) {
2016-05-03 16:10:28 +02:00
if ( data . drag_owner ) {
Object * obj = ObjectDB : : get_instance ( data . drag_owner ) ;
if ( obj ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( obj ) ;
2017-03-05 16:44:50 +01:00
c - > call ( " drop_data_fw " , p_point , p_data , this ) ;
2016-05-03 16:10:28 +02:00
return ;
}
}
2014-02-10 02:10:30 +01:00
if ( get_script_instance ( ) ) {
2017-03-05 16:44:50 +01:00
Variant v = p_point ;
const Variant * p [ 2 ] = { & v , & p_data } ;
2014-02-10 02:10:30 +01:00
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
Variant ret = get_script_instance ( ) - > call ( SceneStringNames : : get_singleton ( ) - > drop_data , p , 2 , ce ) ;
2021-05-05 12:44:11 +02:00
if ( ce . error = = Variant : : CallError : : CALL_OK ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
void Control : : force_drag ( const Variant & p_data , Control * p_control ) {
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_data . get_type ( ) = = Variant : : NIL ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
get_viewport ( ) - > _gui_force_drag ( this , p_data , p_control ) ;
2014-02-10 02:10:30 +01:00
}
void Control : : set_drag_preview ( Control * p_control ) {
2016-01-17 02:41:10 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2018-10-07 23:50:42 +02:00
ERR_FAIL_COND ( ! get_viewport ( ) - > gui_is_dragging ( ) ) ;
2017-03-05 16:44:50 +01:00
get_viewport ( ) - > _gui_set_drag_preview ( this , p_control ) ;
2014-02-10 02:10:30 +01:00
}
2021-11-26 16:11:01 +01:00
bool Control : : is_drag_successful ( ) const {
return is_inside_tree ( ) & & get_viewport ( ) - > gui_is_drag_successful ( ) ;
}
2015-12-29 00:36:48 +01:00
bool Control : : is_window_modal_on_top ( ) const {
2021-05-05 12:44:11 +02:00
if ( ! is_inside_tree ( ) ) {
2016-01-17 02:41:10 +01:00
return false ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2016-01-17 02:41:10 +01:00
return get_viewport ( ) - > _gui_is_modal_on_top ( this ) ;
2014-02-10 02:10:30 +01:00
}
2016-06-27 16:22:13 +02:00
uint64_t Control : : get_modal_frame ( ) const {
return data . modal_frame ;
}
2014-02-10 02:10:30 +01:00
Size2 Control : : get_minimum_size ( ) const {
2017-03-05 16:44:50 +01:00
ScriptInstance * si = const_cast < Control * > ( this ) - > get_script_instance ( ) ;
2014-02-10 02:10:30 +01:00
if ( si ) {
Variant : : CallError ce ;
2021-05-04 16:00:45 +02:00
Variant s = si - > call ( SceneStringNames : : get_singleton ( ) - > _get_minimum_size , nullptr , 0 , ce ) ;
2021-05-05 12:44:11 +02:00
if ( ce . error = = Variant : : CallError : : CALL_OK ) {
2014-02-10 02:10:30 +01:00
return s ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
return Size2 ( ) ;
}
2021-11-30 21:29:18 +01:00
template < class T >
T Control : : get_theme_item_in_types ( Control * p_theme_owner , Theme : : DataType p_data_type , const StringName & p_name , List < StringName > p_theme_types ) {
ERR_FAIL_COND_V_MSG ( p_theme_types . size ( ) = = 0 , T ( ) , " At least one theme type must be specified. " ) ;
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
// First, look through each control node in the branch, until no valid parent can be found.
// Only nodes with a theme resource attached are considered.
Control * theme_owner = p_theme_owner ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
while ( theme_owner ) {
2021-11-30 21:29:18 +01:00
// For each theme resource check the theme types provided and see if p_name exists with any of them.
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( theme_owner & & theme_owner - > data . theme - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return theme_owner - > data . theme - > get_theme_item ( p_data_type , p_name , E - > get ( ) ) ;
}
}
2017-01-11 22:29:59 +01:00
2021-11-30 21:29:18 +01:00
Control * parent_c = Object : : cast_to < Control > ( theme_owner - > get_parent ( ) ) ;
if ( parent_c ) {
theme_owner = parent_c - > data . theme_owner ;
} else {
theme_owner = nullptr ;
}
}
// Secondly, check the project-defined Theme resource.
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( Theme : : get_project_default ( ) - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return Theme : : get_project_default ( ) - > get_theme_item ( p_data_type , p_name , E - > get ( ) ) ;
2017-01-11 22:29:59 +01:00
}
2021-11-30 21:29:18 +01:00
}
}
2017-01-11 22:29:59 +01:00
2021-11-30 21:29:18 +01:00
// Lastly, fall back on the items defined in the default Theme, if they exist.
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( Theme : : get_default ( ) - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return Theme : : get_default ( ) - > get_theme_item ( p_data_type , p_name , E - > get ( ) ) ;
2017-01-11 22:29:59 +01:00
}
2021-11-30 21:29:18 +01:00
}
// If they don't exist, use any type to return the default/empty value.
return Theme : : get_default ( ) - > get_theme_item ( p_data_type , p_name , p_theme_types [ 0 ] ) ;
}
2017-01-11 22:29:59 +01:00
2021-11-30 21:29:18 +01:00
bool Control : : has_theme_item_in_types ( Control * p_theme_owner , Theme : : DataType p_data_type , const StringName & p_name , List < StringName > p_theme_types ) {
ERR_FAIL_COND_V_MSG ( p_theme_types . size ( ) = = 0 , false , " At least one theme type must be specified. " ) ;
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
// First, look through each control node in the branch, until no valid parent can be found.
// Only nodes with a theme resource attached are considered.
Control * theme_owner = p_theme_owner ;
while ( theme_owner ) {
// For each theme resource check the theme types provided and see if p_name exists with any of them.
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( theme_owner & & theme_owner - > data . theme - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return true ;
}
}
Control * parent_c = Object : : cast_to < Control > ( theme_owner - > get_parent ( ) ) ;
if ( parent_c ) {
theme_owner = parent_c - > data . theme_owner ;
2021-05-05 12:44:11 +02:00
} else {
2021-05-04 16:00:45 +02:00
theme_owner = nullptr ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
// Secondly, check the project-defined Theme resource.
2019-07-05 22:32:52 +02:00
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
2021-11-30 21:29:18 +01:00
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( Theme : : get_project_default ( ) - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return true ;
}
}
}
// Lastly, fall back on the items defined in the default Theme, if they exist.
for ( List < StringName > : : Element * E = p_theme_types . front ( ) ; E ; E = E - > next ( ) ) {
if ( Theme : : get_default ( ) - > has_theme_item ( p_data_type , p_name , E - > get ( ) ) ) {
return true ;
}
}
return false ;
}
void Control : : _get_theme_type_dependencies ( const StringName & p_theme_type , List < StringName > * p_list ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
if ( Theme : : get_project_default ( ) . is_valid ( ) & & Theme : : get_project_default ( ) - > get_type_variation_base ( data . theme_type_variation ) ! = StringName ( ) ) {
Theme : : get_project_default ( ) - > get_type_dependencies ( get_class_name ( ) , data . theme_type_variation , p_list ) ;
} else {
Theme : : get_default ( ) - > get_type_dependencies ( get_class_name ( ) , data . theme_type_variation , p_list ) ;
}
2021-11-30 21:29:18 +01:00
} else {
2022-02-10 22:26:09 +01:00
Theme : : get_default ( ) - > get_type_dependencies ( p_theme_type , StringName ( ) , p_list ) ;
2021-11-30 21:29:18 +01:00
}
}
Ref < Texture > Control : : get_icon ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-11-30 21:29:18 +01:00
const Ref < Texture > * tex = data . icon_override . getptr ( p_name ) ;
if ( tex ) {
return * tex ;
2019-07-05 22:32:52 +02:00
}
}
2022-08-12 13:36:06 +02:00
if ( data . theme_icon_cache . has ( p_theme_type ) & & data . theme_icon_cache [ p_theme_type ] . has ( p_name ) ) {
return data . theme_icon_cache [ p_theme_type ] [ p_name ] ;
}
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
2022-08-12 13:36:06 +02:00
Ref < Texture > icon = get_theme_item_in_types < Ref < Texture > > ( data . theme_owner , Theme : : DATA_TYPE_ICON , p_name , theme_types ) ;
data . theme_icon_cache [ p_theme_type ] [ p_name ] = icon ;
return icon ;
2014-02-10 02:10:30 +01:00
}
2021-08-06 21:30:34 +02:00
Ref < Shader > Control : : get_shader ( const StringName & p_name , const StringName & p_theme_type ) const {
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) ) {
2017-03-05 16:44:50 +01:00
const Ref < Shader > * sdr = data . shader_override . getptr ( p_name ) ;
2021-05-05 12:44:11 +02:00
if ( sdr ) {
2015-12-20 22:21:53 +01:00
return * sdr ;
2021-05-05 12:44:11 +02:00
}
2015-12-20 22:21:53 +01:00
}
2021-08-06 21:30:34 +02:00
StringName type = p_theme_type ? p_theme_type : get_class_name ( ) ;
2015-12-20 22:21:53 +01:00
// try with custom themes
Control * theme_owner = data . theme_owner ;
2017-03-05 16:44:50 +01:00
while ( theme_owner ) {
2017-01-11 22:29:59 +01:00
StringName class_name = type ;
2017-03-05 16:44:50 +01:00
while ( class_name ! = StringName ( ) ) {
if ( theme_owner - > data . theme - > has_shader ( p_name , class_name ) ) {
return theme_owner - > data . theme - > get_shader ( p_name , class_name ) ;
2017-01-11 22:29:59 +01:00
}
class_name = ClassDB : : get_parent_class_nocheck ( class_name ) ;
}
2017-08-24 22:58:51 +02:00
Control * parent = Object : : cast_to < Control > ( theme_owner - > get_parent ( ) ) ;
2015-12-20 22:21:53 +01:00
2021-05-05 12:44:11 +02:00
if ( parent ) {
2017-03-05 16:44:50 +01:00
theme_owner = parent - > data . theme_owner ;
2021-05-05 12:44:11 +02:00
} else {
2021-05-04 16:00:45 +02:00
theme_owner = nullptr ;
2021-05-05 12:44:11 +02:00
}
2015-12-20 22:21:53 +01:00
}
2019-07-05 22:32:52 +02:00
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
if ( Theme : : get_project_default ( ) - > has_shader ( p_name , type ) ) {
return Theme : : get_project_default ( ) - > get_shader ( p_name , type ) ;
}
}
2017-03-05 16:44:50 +01:00
return Theme : : get_default ( ) - > get_shader ( p_name , type ) ;
2015-12-20 22:21:53 +01:00
}
2021-08-06 21:30:34 +02:00
Ref < StyleBox > Control : : get_stylebox ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2017-03-05 16:44:50 +01:00
const Ref < StyleBox > * style = data . style_override . getptr ( p_name ) ;
2021-05-05 12:44:11 +02:00
if ( style ) {
2014-12-17 02:31:57 +01:00
return * style ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2022-08-12 13:36:06 +02:00
if ( data . theme_style_cache . has ( p_theme_type ) & & data . theme_style_cache [ p_theme_type ] . has ( p_name ) ) {
return data . theme_style_cache [ p_theme_type ] [ p_name ] ;
}
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
2022-08-12 13:36:06 +02:00
Ref < StyleBox > style = get_theme_item_in_types < Ref < StyleBox > > ( data . theme_owner , Theme : : DATA_TYPE_STYLEBOX , p_name , theme_types ) ;
data . theme_style_cache [ p_theme_type ] [ p_name ] = style ;
return style ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2021-08-06 21:30:34 +02:00
Ref < Font > Control : : get_font ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2017-03-05 16:44:50 +01:00
const Ref < Font > * font = data . font_override . getptr ( p_name ) ;
2021-05-05 12:44:11 +02:00
if ( font ) {
2014-12-17 02:31:57 +01:00
return * font ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2022-08-12 13:36:06 +02:00
if ( data . theme_font_cache . has ( p_theme_type ) & & data . theme_font_cache [ p_theme_type ] . has ( p_name ) ) {
return data . theme_font_cache [ p_theme_type ] [ p_name ] ;
}
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
2022-08-12 13:36:06 +02:00
Ref < Font > font = get_theme_item_in_types < Ref < Font > > ( data . theme_owner , Theme : : DATA_TYPE_FONT , p_name , theme_types ) ;
data . theme_font_cache [ p_theme_type ] [ p_name ] = font ;
return font ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2021-08-06 21:30:34 +02:00
Color Control : : get_color ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2017-03-05 16:44:50 +01:00
const Color * color = data . color_override . getptr ( p_name ) ;
2021-05-05 12:44:11 +02:00
if ( color ) {
2014-12-17 02:31:57 +01:00
return * color ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2022-08-12 13:36:06 +02:00
if ( data . theme_color_cache . has ( p_theme_type ) & & data . theme_color_cache [ p_theme_type ] . has ( p_name ) ) {
return data . theme_color_cache [ p_theme_type ] [ p_name ] ;
}
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
2022-08-12 13:36:06 +02:00
Color color = get_theme_item_in_types < Color > ( data . theme_owner , Theme : : DATA_TYPE_COLOR , p_name , theme_types ) ;
data . theme_color_cache [ p_theme_type ] [ p_name ] = color ;
return color ;
2014-02-10 02:10:30 +01:00
}
2021-08-06 21:30:34 +02:00
int Control : : get_constant ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2017-03-05 16:44:50 +01:00
const int * constant = data . constant_override . getptr ( p_name ) ;
2021-05-05 12:44:11 +02:00
if ( constant ) {
2014-12-17 02:31:57 +01:00
return * constant ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2022-08-12 13:36:06 +02:00
if ( data . theme_constant_cache . has ( p_theme_type ) & & data . theme_constant_cache [ p_theme_type ] . has ( p_name ) ) {
return data . theme_constant_cache [ p_theme_type ] [ p_name ] ;
}
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
2022-08-12 13:36:06 +02:00
int constant = get_theme_item_in_types < int > ( data . theme_owner , Theme : : DATA_TYPE_CONSTANT , p_name , theme_types ) ;
data . theme_constant_cache [ p_theme_type ] [ p_name ] = constant ;
return constant ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
bool Control : : has_icon_override ( const StringName & p_name ) const {
const Ref < Texture > * tex = data . icon_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return tex ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
bool Control : : has_shader_override ( const StringName & p_name ) const {
2017-03-05 16:44:50 +01:00
const Ref < Shader > * sdr = data . shader_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return sdr ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
2017-03-05 16:44:50 +01:00
bool Control : : has_stylebox_override ( const StringName & p_name ) const {
const Ref < StyleBox > * style = data . style_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return style ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
2017-03-05 16:44:50 +01:00
bool Control : : has_font_override ( const StringName & p_name ) const {
const Ref < Font > * font = data . font_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return font ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
2017-03-05 16:44:50 +01:00
bool Control : : has_color_override ( const StringName & p_name ) const {
const Color * color = data . color_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return color ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
2017-03-05 16:44:50 +01:00
bool Control : : has_constant_override ( const StringName & p_name ) const {
const int * constant = data . constant_override . getptr ( p_name ) ;
2021-05-04 16:00:45 +02:00
return constant ! = nullptr ;
2016-06-01 16:41:25 +02:00
}
2014-02-10 02:10:30 +01:00
2021-08-06 21:30:34 +02:00
bool Control : : has_icon ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-05-05 12:44:11 +02:00
if ( has_icon_override ( p_name ) ) {
2014-12-17 02:31:57 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
return has_theme_item_in_types ( data . theme_owner , Theme : : DATA_TYPE_ICON , p_name , theme_types ) ;
2015-12-20 22:21:53 +01:00
}
2021-08-06 21:30:34 +02:00
bool Control : : has_shader ( const StringName & p_name , const StringName & p_theme_type ) const {
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) ) {
2021-05-05 12:44:11 +02:00
if ( has_shader_override ( p_name ) ) {
2015-12-20 22:21:53 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2015-12-20 22:21:53 +01:00
}
2021-08-06 21:30:34 +02:00
StringName type = p_theme_type ? p_theme_type : get_class_name ( ) ;
2015-12-20 22:21:53 +01:00
// try with custom themes
Control * theme_owner = data . theme_owner ;
2017-03-05 16:44:50 +01:00
while ( theme_owner ) {
2017-01-11 22:29:59 +01:00
StringName class_name = type ;
2017-03-05 16:44:50 +01:00
while ( class_name ! = StringName ( ) ) {
if ( theme_owner - > data . theme - > has_shader ( p_name , class_name ) ) {
2017-01-11 22:29:59 +01:00
return true ;
}
class_name = ClassDB : : get_parent_class_nocheck ( class_name ) ;
}
2017-08-24 22:58:51 +02:00
Control * parent = Object : : cast_to < Control > ( theme_owner - > get_parent ( ) ) ;
2015-12-20 22:21:53 +01:00
2021-05-05 12:44:11 +02:00
if ( parent ) {
2017-03-05 16:44:50 +01:00
theme_owner = parent - > data . theme_owner ;
2021-05-05 12:44:11 +02:00
} else {
2021-05-04 16:00:45 +02:00
theme_owner = nullptr ;
2021-05-05 12:44:11 +02:00
}
2015-12-20 22:21:53 +01:00
}
2019-07-05 22:32:52 +02:00
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
if ( Theme : : get_project_default ( ) - > has_shader ( p_name , type ) ) {
return true ;
}
}
2017-03-05 16:44:50 +01:00
return Theme : : get_default ( ) - > has_shader ( p_name , type ) ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2021-08-06 21:30:34 +02:00
bool Control : : has_stylebox ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-05-05 12:44:11 +02:00
if ( has_stylebox_override ( p_name ) ) {
2014-12-17 02:31:57 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
return has_theme_item_in_types ( data . theme_owner , Theme : : DATA_TYPE_STYLEBOX , p_name , theme_types ) ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2021-08-06 21:30:34 +02:00
bool Control : : has_font ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-05-05 12:44:11 +02:00
if ( has_font_override ( p_name ) ) {
2014-12-17 02:31:57 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
return has_theme_item_in_types ( data . theme_owner , Theme : : DATA_TYPE_FONT , p_name , theme_types ) ;
2014-02-10 02:10:30 +01:00
}
2016-03-09 00:00:52 +01:00
2021-08-06 21:30:34 +02:00
bool Control : : has_color ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-05-05 12:44:11 +02:00
if ( has_color_override ( p_name ) ) {
2014-12-17 02:31:57 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
return has_theme_item_in_types ( data . theme_owner , Theme : : DATA_TYPE_COLOR , p_name , theme_types ) ;
2014-02-10 02:10:30 +01:00
}
2021-08-06 21:30:34 +02:00
bool Control : : has_constant ( const StringName & p_name , const StringName & p_theme_type ) const {
2022-02-10 22:26:09 +01:00
if ( p_theme_type = = StringName ( ) | | p_theme_type = = get_class_name ( ) | | p_theme_type = = data . theme_type_variation ) {
2021-05-05 12:44:11 +02:00
if ( has_constant_override ( p_name ) ) {
2014-12-17 02:31:57 +01:00
return true ;
2021-05-05 12:44:11 +02:00
}
2014-12-17 02:31:57 +01:00
}
2014-02-10 02:10:30 +01:00
2021-11-30 21:29:18 +01:00
List < StringName > theme_types ;
_get_theme_type_dependencies ( p_theme_type , & theme_types ) ;
return has_theme_item_in_types ( data . theme_owner , Theme : : DATA_TYPE_CONSTANT , p_name , theme_types ) ;
2014-02-10 02:10:30 +01:00
}
2021-10-04 16:44:53 +02:00
Ref < Font > Control : : get_theme_default_font ( ) const {
2021-11-30 21:29:18 +01:00
// First, look through each control node in the branch, until no valid parent can be found.
2021-10-04 16:44:53 +02:00
// Only nodes with a theme resource attached are considered.
// For each theme resource see if their assigned theme has the default value defined and valid.
Control * theme_owner = data . theme_owner ;
while ( theme_owner ) {
if ( theme_owner & & theme_owner - > data . theme - > has_default_theme_font ( ) ) {
return theme_owner - > data . theme - > get_default_theme_font ( ) ;
}
2021-11-30 21:29:18 +01:00
Control * parent_c = Object : : cast_to < Control > ( theme_owner - > get_parent ( ) ) ;
2021-10-04 16:44:53 +02:00
if ( parent_c ) {
theme_owner = parent_c - > data . theme_owner ;
} else {
theme_owner = nullptr ;
}
}
// Secondly, check the project-defined Theme resource.
if ( Theme : : get_project_default ( ) . is_valid ( ) ) {
if ( Theme : : get_project_default ( ) - > has_default_theme_font ( ) ) {
return Theme : : get_project_default ( ) - > get_default_theme_font ( ) ;
}
}
// Lastly, fall back on the default Theme.
return Theme : : get_default ( ) - > get_default_theme_font ( ) ;
}
2018-05-05 16:59:00 +02:00
Rect2 Control : : get_parent_anchorable_rect ( ) const {
2021-05-05 12:44:11 +02:00
if ( ! is_inside_tree ( ) ) {
2018-05-05 16:59:00 +02:00
return Rect2 ( ) ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2018-05-05 16:59:00 +02:00
Rect2 parent_rect ;
2014-02-10 02:10:30 +01:00
if ( data . parent_canvas_item ) {
2018-05-05 16:59:00 +02:00
parent_rect = data . parent_canvas_item - > get_anchorable_rect ( ) ;
2016-01-17 02:41:10 +01:00
} else {
2018-05-05 16:59:00 +02:00
parent_rect = get_viewport ( ) - > get_visible_rect ( ) ;
2016-03-09 00:00:52 +01:00
}
2017-06-12 21:18:17 +02:00
2018-05-05 16:59:00 +02:00
return parent_rect ;
}
Size2 Control : : get_parent_area_size ( ) const {
return get_parent_anchorable_rect ( ) . size ;
2014-02-10 02:10:30 +01:00
}
void Control : : _size_changed ( ) {
2018-05-05 16:59:00 +02:00
Rect2 parent_rect = get_parent_anchorable_rect ( ) ;
2014-02-10 02:10:30 +01:00
float margin_pos [ 4 ] ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2018-05-05 16:59:00 +02:00
float area = parent_rect . size [ i & 1 ] ;
2017-07-06 09:16:27 +02:00
margin_pos [ i ] = data . margin [ i ] + ( data . anchor [ i ] * area ) ;
2014-02-10 02:10:30 +01:00
}
2017-07-05 23:01:26 +02:00
Point2 new_pos_cache = Point2 ( margin_pos [ 0 ] , margin_pos [ 1 ] ) ;
Size2 new_size_cache = Point2 ( margin_pos [ 2 ] , margin_pos [ 3 ] ) - new_pos_cache ;
2017-07-06 18:26:39 +02:00
2017-03-05 16:44:50 +01:00
Size2 minimum_size = get_combined_minimum_size ( ) ;
2014-02-10 02:10:30 +01:00
2018-02-12 04:58:39 +01:00
if ( minimum_size . width > new_size_cache . width ) {
if ( data . h_grow = = GROW_DIRECTION_BEGIN ) {
new_pos_cache . x + = new_size_cache . width - minimum_size . width ;
} else if ( data . h_grow = = GROW_DIRECTION_BOTH ) {
new_pos_cache . x + = 0.5 * ( new_size_cache . width - minimum_size . width ) ;
2017-07-06 18:26:39 +02:00
}
2018-02-12 04:58:39 +01:00
new_size_cache . width = minimum_size . width ;
2017-07-06 18:26:39 +02:00
}
2018-02-12 04:58:39 +01:00
if ( minimum_size . height > new_size_cache . height ) {
if ( data . v_grow = = GROW_DIRECTION_BEGIN ) {
new_pos_cache . y + = new_size_cache . height - minimum_size . height ;
} else if ( data . v_grow = = GROW_DIRECTION_BOTH ) {
new_pos_cache . y + = 0.5 * ( new_size_cache . height - minimum_size . height ) ;
2017-07-06 18:26:39 +02:00
}
2018-02-12 04:58:39 +01:00
new_size_cache . height = minimum_size . height ;
2017-07-06 18:26:39 +02:00
}
2014-02-10 02:10:30 +01:00
2016-08-31 04:44:14 +02:00
bool pos_changed = new_pos_cache ! = data . pos_cache ;
bool size_changed = new_size_cache ! = data . size_cache ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
data . pos_cache = new_pos_cache ;
data . size_cache = new_size_cache ;
2014-02-10 02:10:30 +01:00
2018-07-04 14:29:29 +02:00
if ( is_inside_tree ( ) ) {
if ( size_changed ) {
notification ( NOTIFICATION_RESIZED ) ;
}
if ( pos_changed | | size_changed ) {
item_rect_changed ( size_changed ) ;
_change_notify_margins ( ) ;
_notify_transform ( ) ;
}
2016-08-31 04:44:14 +02:00
2018-07-04 14:29:29 +02:00
if ( pos_changed & & ! size_changed ) {
_update_canvas_item_transform ( ) ; //move because it won't be updated
}
2016-08-31 04:44:14 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-08-11 19:25:26 +02:00
void Control : : set_anchor ( Margin p_margin , float p_anchor , bool p_keep_margin , bool p_push_opposite_anchor ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_margin , 4 ) ;
2018-05-05 16:59:00 +02:00
Rect2 parent_rect = get_parent_anchorable_rect ( ) ;
float parent_range = ( p_margin = = MARGIN_LEFT | | p_margin = = MARGIN_RIGHT ) ? parent_rect . size . x : parent_rect . size . y ;
2018-01-11 23:21:04 +01:00
float previous_margin_pos = data . margin [ p_margin ] + data . anchor [ p_margin ] * parent_range ;
float previous_opposite_margin_pos = data . margin [ ( p_margin + 2 ) % 4 ] + data . anchor [ ( p_margin + 2 ) % 4 ] * parent_range ;
2019-03-31 18:53:24 +02:00
data . anchor [ p_margin ] = p_anchor ;
2017-08-11 19:25:26 +02:00
if ( ( ( p_margin = = MARGIN_LEFT | | p_margin = = MARGIN_TOP ) & & data . anchor [ p_margin ] > data . anchor [ ( p_margin + 2 ) % 4 ] ) | |
( ( p_margin = = MARGIN_RIGHT | | p_margin = = MARGIN_BOTTOM ) & & data . anchor [ p_margin ] < data . anchor [ ( p_margin + 2 ) % 4 ] ) ) {
if ( p_push_opposite_anchor ) {
data . anchor [ ( p_margin + 2 ) % 4 ] = data . anchor [ p_margin ] ;
2017-07-06 09:16:27 +02:00
} else {
2017-08-11 19:25:26 +02:00
data . anchor [ p_margin ] = data . anchor [ ( p_margin + 2 ) % 4 ] ;
}
}
2018-01-11 23:21:04 +01:00
if ( ! p_keep_margin ) {
2018-05-05 16:59:00 +02:00
data . margin [ p_margin ] = previous_margin_pos - data . anchor [ p_margin ] * parent_range ;
2018-01-11 23:21:04 +01:00
if ( p_push_opposite_anchor ) {
2018-05-05 16:59:00 +02:00
data . margin [ ( p_margin + 2 ) % 4 ] = previous_opposite_margin_pos - data . anchor [ ( p_margin + 2 ) % 4 ] * parent_range ;
2017-07-06 09:16:27 +02:00
}
2014-02-10 02:10:30 +01:00
}
2018-01-11 23:21:04 +01:00
if ( is_inside_tree ( ) ) {
_size_changed ( ) ;
}
2017-07-11 00:14:22 +02:00
update ( ) ;
2019-03-19 18:37:28 +01:00
_change_notify ( " anchor_left " ) ;
_change_notify ( " anchor_right " ) ;
_change_notify ( " anchor_top " ) ;
_change_notify ( " anchor_bottom " ) ;
2014-02-10 02:10:30 +01:00
}
2017-07-06 09:16:27 +02:00
void Control : : _set_anchor ( Margin p_margin , float p_anchor ) {
2019-03-31 18:53:24 +02:00
set_anchor ( p_margin , p_anchor ) ;
2016-03-09 17:59:35 +01:00
}
2017-08-11 19:25:26 +02:00
void Control : : set_anchor_and_margin ( Margin p_margin , float p_anchor , float p_pos , bool p_push_opposite_anchor ) {
set_anchor ( p_margin , p_anchor , false , p_push_opposite_anchor ) ;
2017-03-05 16:44:50 +01:00
set_margin ( p_margin , p_pos ) ;
2014-02-10 02:10:30 +01:00
}
2019-03-31 18:53:24 +02:00
void Control : : set_anchors_preset ( LayoutPreset p_preset , bool p_keep_margins ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_preset , 16 ) ;
2017-08-11 18:16:28 +02:00
//Left
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_BOTTOM_LEFT :
case PRESET_CENTER_LEFT :
case PRESET_TOP_WIDE :
case PRESET_BOTTOM_WIDE :
case PRESET_LEFT_WIDE :
case PRESET_HCENTER_WIDE :
case PRESET_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_LEFT , ANCHOR_BEGIN , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_CENTER_TOP :
case PRESET_CENTER_BOTTOM :
case PRESET_CENTER :
case PRESET_VCENTER_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_LEFT , 0.5 , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_TOP_RIGHT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_RIGHT :
case PRESET_RIGHT_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_LEFT , ANCHOR_END , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
}
// Top
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_TOP_RIGHT :
case PRESET_CENTER_TOP :
case PRESET_LEFT_WIDE :
case PRESET_RIGHT_WIDE :
case PRESET_TOP_WIDE :
case PRESET_VCENTER_WIDE :
case PRESET_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_TOP , ANCHOR_BEGIN , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_CENTER_LEFT :
case PRESET_CENTER_RIGHT :
case PRESET_CENTER :
case PRESET_HCENTER_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_TOP , 0.5 , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_BOTTOM_LEFT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_BOTTOM :
case PRESET_BOTTOM_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_TOP , ANCHOR_END , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
}
// Right
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_BOTTOM_LEFT :
case PRESET_CENTER_LEFT :
case PRESET_LEFT_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_RIGHT , ANCHOR_BEGIN , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_CENTER_TOP :
case PRESET_CENTER_BOTTOM :
case PRESET_CENTER :
case PRESET_VCENTER_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_RIGHT , 0.5 , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_TOP_RIGHT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_RIGHT :
case PRESET_TOP_WIDE :
case PRESET_RIGHT_WIDE :
case PRESET_BOTTOM_WIDE :
case PRESET_HCENTER_WIDE :
case PRESET_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_RIGHT , ANCHOR_END , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
}
// Bottom
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_TOP_RIGHT :
case PRESET_CENTER_TOP :
case PRESET_TOP_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_BOTTOM , ANCHOR_BEGIN , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_CENTER_LEFT :
case PRESET_CENTER_RIGHT :
case PRESET_CENTER :
case PRESET_HCENTER_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_BOTTOM , 0.5 , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
case PRESET_BOTTOM_LEFT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_BOTTOM :
case PRESET_LEFT_WIDE :
case PRESET_RIGHT_WIDE :
case PRESET_BOTTOM_WIDE :
case PRESET_VCENTER_WIDE :
case PRESET_WIDE :
2019-03-31 18:53:24 +02:00
set_anchor ( MARGIN_BOTTOM , ANCHOR_END , p_keep_margins ) ;
2017-08-11 18:16:28 +02:00
break ;
}
}
2017-09-19 22:39:19 +02:00
void Control : : set_margins_preset ( LayoutPreset p_preset , LayoutPresetMode p_resize_mode , int p_margin ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_preset , 16 ) ;
ERR_FAIL_INDEX ( ( int ) p_resize_mode , 4 ) ;
2017-09-27 00:31:05 +02:00
// Calculate the size if the node is not resized
2017-09-19 22:39:19 +02:00
Size2 min_size = get_minimum_size ( ) ;
Size2 new_size = get_size ( ) ;
2017-09-27 00:31:05 +02:00
if ( p_resize_mode = = PRESET_MODE_MINSIZE | | p_resize_mode = = PRESET_MODE_KEEP_HEIGHT ) {
new_size . x = min_size . x ;
}
if ( p_resize_mode = = PRESET_MODE_MINSIZE | | p_resize_mode = = PRESET_MODE_KEEP_WIDTH ) {
new_size . y = min_size . y ;
}
2017-09-19 22:39:19 +02:00
2018-05-05 16:59:00 +02:00
Rect2 parent_rect = get_parent_anchorable_rect ( ) ;
2017-09-27 00:31:05 +02:00
//Left
2017-09-19 22:39:19 +02:00
switch ( p_preset ) {
2017-09-27 00:31:05 +02:00
case PRESET_TOP_LEFT :
case PRESET_BOTTOM_LEFT :
case PRESET_CENTER_LEFT :
2017-09-19 22:39:19 +02:00
case PRESET_TOP_WIDE :
case PRESET_BOTTOM_WIDE :
2017-09-27 00:31:05 +02:00
case PRESET_LEFT_WIDE :
2017-09-19 22:39:19 +02:00
case PRESET_HCENTER_WIDE :
case PRESET_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 0 ] = parent_rect . size . x * ( 0.0 - data . anchor [ 0 ] ) + p_margin + parent_rect . position . x ;
2017-09-19 22:39:19 +02:00
break ;
2017-09-27 00:31:05 +02:00
case PRESET_CENTER_TOP :
case PRESET_CENTER_BOTTOM :
case PRESET_CENTER :
case PRESET_VCENTER_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 0 ] = parent_rect . size . x * ( 0.5 - data . anchor [ 0 ] ) - new_size . x / 2 + parent_rect . position . x ;
2017-09-27 00:31:05 +02:00
break ;
case PRESET_TOP_RIGHT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_RIGHT :
case PRESET_RIGHT_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 0 ] = parent_rect . size . x * ( 1.0 - data . anchor [ 0 ] ) - new_size . x - p_margin + parent_rect . position . x ;
2017-09-19 22:39:19 +02:00
break ;
}
2017-09-27 00:31:05 +02:00
// Top
2017-09-19 22:39:19 +02:00
switch ( p_preset ) {
2017-09-27 00:31:05 +02:00
case PRESET_TOP_LEFT :
case PRESET_TOP_RIGHT :
case PRESET_CENTER_TOP :
2017-09-19 22:39:19 +02:00
case PRESET_LEFT_WIDE :
case PRESET_RIGHT_WIDE :
2017-09-27 00:31:05 +02:00
case PRESET_TOP_WIDE :
2017-09-19 22:39:19 +02:00
case PRESET_VCENTER_WIDE :
case PRESET_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 1 ] = parent_rect . size . y * ( 0.0 - data . anchor [ 1 ] ) + p_margin + parent_rect . position . y ;
2017-09-19 22:39:19 +02:00
break ;
2017-09-27 00:31:05 +02:00
case PRESET_CENTER_LEFT :
case PRESET_CENTER_RIGHT :
case PRESET_CENTER :
case PRESET_HCENTER_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 1 ] = parent_rect . size . y * ( 0.5 - data . anchor [ 1 ] ) - new_size . y / 2 + parent_rect . position . y ;
2017-09-27 00:31:05 +02:00
break ;
case PRESET_BOTTOM_LEFT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_BOTTOM :
case PRESET_BOTTOM_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 1 ] = parent_rect . size . y * ( 1.0 - data . anchor [ 1 ] ) - new_size . y - p_margin + parent_rect . position . y ;
2017-09-19 22:39:19 +02:00
break ;
}
2017-09-27 00:31:05 +02:00
// Right
2017-09-19 22:39:19 +02:00
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_BOTTOM_LEFT :
case PRESET_CENTER_LEFT :
case PRESET_LEFT_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 2 ] = parent_rect . size . x * ( 0.0 - data . anchor [ 2 ] ) + new_size . x + p_margin + parent_rect . position . x ;
2017-09-19 22:39:19 +02:00
break ;
case PRESET_CENTER_TOP :
case PRESET_CENTER_BOTTOM :
case PRESET_CENTER :
case PRESET_VCENTER_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 2 ] = parent_rect . size . x * ( 0.5 - data . anchor [ 2 ] ) + new_size . x / 2 + parent_rect . position . x ;
2017-09-19 22:39:19 +02:00
break ;
case PRESET_TOP_RIGHT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_RIGHT :
2017-09-27 00:31:05 +02:00
case PRESET_TOP_WIDE :
2017-09-19 22:39:19 +02:00
case PRESET_RIGHT_WIDE :
2017-09-27 00:31:05 +02:00
case PRESET_BOTTOM_WIDE :
case PRESET_HCENTER_WIDE :
case PRESET_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 2 ] = parent_rect . size . x * ( 1.0 - data . anchor [ 2 ] ) - p_margin + parent_rect . position . x ;
2017-09-19 22:39:19 +02:00
break ;
}
2017-09-27 00:31:05 +02:00
// Bottom
2017-09-19 22:39:19 +02:00
switch ( p_preset ) {
case PRESET_TOP_LEFT :
case PRESET_TOP_RIGHT :
case PRESET_CENTER_TOP :
case PRESET_TOP_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 3 ] = parent_rect . size . y * ( 0.0 - data . anchor [ 3 ] ) + new_size . y + p_margin + parent_rect . position . y ;
2017-09-19 22:39:19 +02:00
break ;
case PRESET_CENTER_LEFT :
case PRESET_CENTER_RIGHT :
case PRESET_CENTER :
case PRESET_HCENTER_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 3 ] = parent_rect . size . y * ( 0.5 - data . anchor [ 3 ] ) + new_size . y / 2 + parent_rect . position . y ;
2017-09-19 22:39:19 +02:00
break ;
case PRESET_BOTTOM_LEFT :
case PRESET_BOTTOM_RIGHT :
case PRESET_CENTER_BOTTOM :
2017-09-27 00:31:05 +02:00
case PRESET_LEFT_WIDE :
case PRESET_RIGHT_WIDE :
2017-09-19 22:39:19 +02:00
case PRESET_BOTTOM_WIDE :
2017-09-27 00:31:05 +02:00
case PRESET_VCENTER_WIDE :
case PRESET_WIDE :
2018-05-05 16:59:00 +02:00
data . margin [ 3 ] = parent_rect . size . y * ( 1.0 - data . anchor [ 3 ] ) - p_margin + parent_rect . position . y ;
2017-09-19 22:39:19 +02:00
break ;
}
2017-09-27 00:31:05 +02:00
_size_changed ( ) ;
2017-09-19 22:39:19 +02:00
}
void Control : : set_anchors_and_margins_preset ( LayoutPreset p_preset , LayoutPresetMode p_resize_mode , int p_margin ) {
set_anchors_preset ( p_preset ) ;
set_margins_preset ( p_preset , p_resize_mode , p_margin ) ;
}
2017-07-06 09:16:27 +02:00
float Control : : get_anchor ( Margin p_margin ) const {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX_V ( int ( p_margin ) , 4 , 0.0 ) ;
2016-03-09 00:00:52 +01:00
return data . anchor [ p_margin ] ;
2014-02-10 02:10:30 +01:00
}
void Control : : _change_notify_margins ( ) {
// this avoids sending the whole object data again on a change
2017-04-01 06:07:35 +02:00
_change_notify ( " margin_left " ) ;
_change_notify ( " margin_top " ) ;
_change_notify ( " margin_right " ) ;
_change_notify ( " margin_bottom " ) ;
2017-05-28 15:38:22 +02:00
_change_notify ( " rect_position " ) ;
2017-04-01 06:07:35 +02:00
_change_notify ( " rect_size " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void Control : : set_margin ( Margin p_margin , float p_value ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_margin , 4 ) ;
2017-03-05 16:44:50 +01:00
data . margin [ p_margin ] = p_value ;
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
2017-03-05 16:44:50 +01:00
void Control : : set_begin ( const Size2 & p_point ) {
data . margin [ 0 ] = p_point . x ;
data . margin [ 1 ] = p_point . y ;
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
2017-03-05 16:44:50 +01:00
void Control : : set_end ( const Size2 & p_point ) {
data . margin [ 2 ] = p_point . x ;
data . margin [ 3 ] = p_point . y ;
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
float Control : : get_margin ( Margin p_margin ) const {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX_V ( ( int ) p_margin , 4 , 0 ) ;
2014-02-10 02:10:30 +01:00
return data . margin [ p_margin ] ;
}
Size2 Control : : get_begin ( ) const {
2017-03-05 16:44:50 +01:00
return Size2 ( data . margin [ 0 ] , data . margin [ 1 ] ) ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2014-02-10 02:10:30 +01:00
Size2 Control : : get_end ( ) const {
2017-03-05 16:44:50 +01:00
return Size2 ( data . margin [ 2 ] , data . margin [ 3 ] ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-29 17:29:38 +02:00
Point2 Control : : get_global_position ( ) const {
2014-02-10 02:10:30 +01:00
return get_global_transform ( ) . get_origin ( ) ;
}
2019-03-31 18:53:24 +02:00
void Control : : _set_global_position ( const Point2 & p_point ) {
set_global_position ( p_point ) ;
}
void Control : : set_global_position ( const Point2 & p_point , bool p_keep_margins ) {
2017-01-11 04:52:51 +01:00
Transform2D inv ;
2014-02-10 02:10:30 +01:00
if ( data . parent_canvas_item ) {
inv = data . parent_canvas_item - > get_global_transform ( ) . affine_inverse ( ) ;
}
2019-03-31 18:53:24 +02:00
set_position ( inv . xform ( p_point ) , p_keep_margins ) ;
2014-02-10 02:10:30 +01:00
}
2019-03-31 18:53:24 +02:00
void Control : : _compute_anchors ( Rect2 p_rect , const float p_margins [ 4 ] , float ( & r_anchors ) [ 4 ] ) {
Size2 parent_rect_size = get_parent_anchorable_rect ( ) . size ;
2019-06-04 21:58:21 +02:00
ERR_FAIL_COND ( parent_rect_size . x = = 0.0 ) ;
ERR_FAIL_COND ( parent_rect_size . y = = 0.0 ) ;
2019-03-31 18:53:24 +02:00
r_anchors [ 0 ] = ( p_rect . position . x - p_margins [ 0 ] ) / parent_rect_size . x ;
r_anchors [ 1 ] = ( p_rect . position . y - p_margins [ 1 ] ) / parent_rect_size . y ;
r_anchors [ 2 ] = ( p_rect . position . x + p_rect . size . x - p_margins [ 2 ] ) / parent_rect_size . x ;
r_anchors [ 3 ] = ( p_rect . position . y + p_rect . size . y - p_margins [ 3 ] ) / parent_rect_size . y ;
}
2018-05-05 16:59:00 +02:00
void Control : : _compute_margins ( Rect2 p_rect , const float p_anchors [ 4 ] , float ( & r_margins ) [ 4 ] ) {
Size2 parent_rect_size = get_parent_anchorable_rect ( ) . size ;
2018-09-25 20:14:40 +02:00
r_margins [ 0 ] = p_rect . position . x - ( p_anchors [ 0 ] * parent_rect_size . x ) ;
r_margins [ 1 ] = p_rect . position . y - ( p_anchors [ 1 ] * parent_rect_size . y ) ;
r_margins [ 2 ] = p_rect . position . x + p_rect . size . x - ( p_anchors [ 2 ] * parent_rect_size . x ) ;
r_margins [ 3 ] = p_rect . position . y + p_rect . size . y - ( p_anchors [ 3 ] * parent_rect_size . y ) ;
2018-05-05 16:59:00 +02:00
}
2016-03-09 00:00:52 +01:00
2019-03-31 18:53:24 +02:00
void Control : : _set_position ( const Size2 & p_point ) {
set_position ( p_point ) ;
}
2014-02-10 02:10:30 +01:00
2019-03-31 18:53:24 +02:00
void Control : : set_position ( const Size2 & p_point , bool p_keep_margins ) {
if ( p_keep_margins ) {
_compute_anchors ( Rect2 ( p_point , data . size_cache ) , data . margin , data . anchor ) ;
_change_notify ( " anchor_left " ) ;
_change_notify ( " anchor_right " ) ;
_change_notify ( " anchor_top " ) ;
_change_notify ( " anchor_bottom " ) ;
} else {
_compute_margins ( Rect2 ( p_point , data . size_cache ) , data . anchor , data . margin ) ;
}
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
2019-03-31 18:53:24 +02:00
void Control : : _set_size ( const Size2 & p_size ) {
set_size ( p_size ) ;
}
void Control : : set_size ( const Size2 & p_size , bool p_keep_margins ) {
2017-03-05 16:44:50 +01:00
Size2 new_size = p_size ;
Size2 min = get_combined_minimum_size ( ) ;
2021-05-05 12:44:11 +02:00
if ( new_size . x < min . x ) {
2017-03-05 16:44:50 +01:00
new_size . x = min . x ;
2021-05-05 12:44:11 +02:00
}
if ( new_size . y < min . y ) {
2017-03-05 16:44:50 +01:00
new_size . y = min . y ;
2021-05-05 12:44:11 +02:00
}
2016-03-09 00:00:52 +01:00
2019-03-31 18:53:24 +02:00
if ( p_keep_margins ) {
_compute_anchors ( Rect2 ( data . pos_cache , new_size ) , data . margin , data . anchor ) ;
_change_notify ( " anchor_left " ) ;
_change_notify ( " anchor_right " ) ;
_change_notify ( " anchor_top " ) ;
_change_notify ( " anchor_bottom " ) ;
} else {
_compute_margins ( Rect2 ( data . pos_cache , new_size ) , data . anchor , data . margin ) ;
}
2014-02-10 02:10:30 +01:00
_size_changed ( ) ;
}
2017-03-29 17:29:38 +02:00
Size2 Control : : get_position ( ) const {
2014-02-10 02:10:30 +01:00
return data . pos_cache ;
}
Size2 Control : : get_size ( ) const {
return data . size_cache ;
}
Rect2 Control : : get_global_rect ( ) const {
2017-03-29 17:29:38 +02:00
return Rect2 ( get_global_position ( ) , get_size ( ) ) ;
2014-02-10 02:10:30 +01:00
}
Rect2 Control : : get_window_rect ( ) const {
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , Rect2 ( ) ) ;
2014-02-10 02:10:30 +01:00
Rect2 gr = get_global_rect ( ) ;
2017-06-04 00:25:13 +02:00
gr . position + = get_viewport ( ) - > get_visible_rect ( ) . position ;
2014-02-10 02:10:30 +01:00
return gr ;
}
Rect2 Control : : get_rect ( ) const {
2017-03-29 17:29:38 +02:00
return Rect2 ( get_position ( ) , get_size ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2018-05-05 16:59:00 +02:00
Rect2 Control : : get_anchorable_rect ( ) const {
return Rect2 ( Point2 ( ) , get_size ( ) ) ;
}
2017-03-05 16:44:50 +01:00
void Control : : add_icon_override ( const StringName & p_name , const Ref < Texture > & p_icon ) {
2019-02-25 16:13:25 +01:00
if ( data . icon_override . has ( p_name ) ) {
data . icon_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
2019-05-20 19:32:31 +02:00
// clear if "null" is passed instead of a icon
if ( p_icon . is_null ( ) ) {
data . icon_override . erase ( p_name ) ;
} else {
data . icon_override [ p_name ] = p_icon ;
if ( data . icon_override [ p_name ] . is_valid ( ) ) {
data . icon_override [ p_name ] - > connect ( " changed " , this , " _override_changed " , Vector < Variant > ( ) , CONNECT_REFERENCE_COUNTED ) ;
}
2019-02-25 16:13:25 +01:00
}
2014-02-10 02:10:30 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
2015-12-20 22:21:53 +01:00
}
2014-02-10 02:10:30 +01:00
2015-12-20 22:21:53 +01:00
void Control : : add_shader_override ( const StringName & p_name , const Ref < Shader > & p_shader ) {
2019-02-25 16:13:25 +01:00
if ( data . shader_override . has ( p_name ) ) {
data . shader_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
2019-05-20 19:32:31 +02:00
// clear if "null" is passed instead of a shader
if ( p_shader . is_null ( ) ) {
data . shader_override . erase ( p_name ) ;
} else {
data . shader_override [ p_name ] = p_shader ;
if ( data . shader_override [ p_name ] . is_valid ( ) ) {
data . shader_override [ p_name ] - > connect ( " changed " , this , " _override_changed " , Vector < Variant > ( ) , CONNECT_REFERENCE_COUNTED ) ;
}
2019-02-25 16:13:25 +01:00
}
2015-12-20 22:21:53 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
2014-02-10 02:10:30 +01:00
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
void Control : : add_style_override ( const StringName & p_name , const Ref < StyleBox > & p_style ) {
2019-02-25 16:13:25 +01:00
if ( data . style_override . has ( p_name ) ) {
data . style_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
2019-05-20 19:32:31 +02:00
// clear if "null" is passed instead of a style
if ( p_style . is_null ( ) ) {
data . style_override . erase ( p_name ) ;
} else {
data . style_override [ p_name ] = p_style ;
if ( data . style_override [ p_name ] . is_valid ( ) ) {
data . style_override [ p_name ] - > connect ( " changed " , this , " _override_changed " , Vector < Variant > ( ) , CONNECT_REFERENCE_COUNTED ) ;
}
}
2014-02-10 02:10:30 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2017-03-05 16:44:50 +01:00
void Control : : add_font_override ( const StringName & p_name , const Ref < Font > & p_font ) {
2016-06-17 21:00:27 +02:00
if ( data . font_override . has ( p_name ) ) {
2019-02-25 16:13:25 +01:00
data . font_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
2016-06-17 21:00:27 +02:00
}
2019-05-20 19:32:31 +02:00
// clear if "null" is passed instead of a font
if ( p_font . is_null ( ) ) {
data . font_override . erase ( p_name ) ;
} else {
data . font_override [ p_name ] = p_font ;
if ( data . font_override [ p_name ] . is_valid ( ) ) {
data . font_override [ p_name ] - > connect ( " changed " , this , " _override_changed " , Vector < Variant > ( ) , CONNECT_REFERENCE_COUNTED ) ;
}
}
2014-02-10 02:10:30 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
void Control : : add_color_override ( const StringName & p_name , const Color & p_color ) {
data . color_override [ p_name ] = p_color ;
2014-02-10 02:10:30 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
void Control : : add_constant_override ( const StringName & p_name , int p_constant ) {
data . constant_override [ p_name ] = p_constant ;
2014-02-10 02:10:30 +01:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2021-11-11 11:23:37 +01:00
void Control : : remove_icon_override ( const StringName & p_name ) {
if ( data . icon_override . has ( p_name ) ) {
data . icon_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
data . icon_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
void Control : : remove_shader_override ( const StringName & p_name ) {
if ( data . shader_override . has ( p_name ) ) {
data . shader_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
data . shader_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
void Control : : remove_stylebox_override ( const StringName & p_name ) {
if ( data . style_override . has ( p_name ) ) {
data . style_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
data . style_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
void Control : : remove_font_override ( const StringName & p_name ) {
if ( data . font_override . has ( p_name ) ) {
data . font_override [ p_name ] - > disconnect ( " changed " , this , " _override_changed " ) ;
}
data . font_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
void Control : : remove_color_override ( const StringName & p_name ) {
data . color_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
void Control : : remove_constant_override ( const StringName & p_name ) {
data . constant_override . erase ( p_name ) ;
notification ( NOTIFICATION_THEME_CHANGED ) ;
}
2014-02-10 02:10:30 +01:00
void Control : : set_focus_mode ( FocusMode p_focus_mode ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_focus_mode , 3 ) ;
2021-05-05 12:44:11 +02:00
if ( is_inside_tree ( ) & & p_focus_mode = = FOCUS_NONE & & data . focus_mode ! = FOCUS_NONE & & has_focus ( ) ) {
2014-02-10 02:10:30 +01:00
release_focus ( ) ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
data . focus_mode = p_focus_mode ;
2014-02-10 02:10:30 +01:00
}
static Control * _next_control ( Control * p_from ) {
2021-05-05 12:44:11 +02:00
if ( p_from - > is_set_as_toplevel ( ) ) {
2022-06-30 16:22:40 +02:00
return nullptr ; // Can't go above.
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Control * parent = Object : : cast_to < Control > ( p_from - > get_parent ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( ! parent ) {
2021-05-04 16:00:45 +02:00
return nullptr ;
2014-02-10 02:10:30 +01:00
}
int next = p_from - > get_position_in_parent ( ) ;
2021-05-04 16:00:45 +02:00
ERR_FAIL_INDEX_V ( next , parent - > get_child_count ( ) , nullptr ) ;
2017-03-05 16:44:50 +01:00
for ( int i = ( next + 1 ) ; i < parent - > get_child_count ( ) ; i + + ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( parent - > get_child ( i ) ) ;
2021-05-05 12:44:11 +02:00
if ( ! c | | ! c - > is_visible_in_tree ( ) | | c - > is_set_as_toplevel ( ) ) {
2014-02-10 02:10:30 +01:00
continue ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
return c ;
}
2022-06-30 16:22:40 +02:00
// No next in parent, try the same in parent.
2014-02-10 02:10:30 +01:00
return _next_control ( parent ) ;
}
Control * Control : : find_next_valid_focus ( ) const {
2017-03-05 16:44:50 +01:00
Control * from = const_cast < Control * > ( this ) ;
2016-03-09 00:00:52 +01:00
2017-03-05 16:44:50 +01:00
while ( true ) {
2017-11-16 10:45:52 +01:00
// If the focus property is manually overwritten, attempt to use it.
if ( ! data . focus_next . is_empty ( ) ) {
Node * n = get_node ( data . focus_next ) ;
2019-12-16 01:33:25 +01:00
Control * c ;
2017-11-16 10:45:52 +01:00
if ( n ) {
2019-12-16 01:33:25 +01:00
c = Object : : cast_to < Control > ( n ) ;
2021-05-04 16:00:45 +02:00
ERR_FAIL_COND_V_MSG ( ! c , nullptr , " Next focus node is not a control: " + n - > get_name ( ) + " . " ) ;
2017-11-16 10:45:52 +01:00
} else {
2021-05-04 16:00:45 +02:00
return nullptr ;
2017-11-16 10:45:52 +01:00
}
2021-05-05 12:44:11 +02:00
if ( c - > is_visible ( ) & & c - > get_focus_mode ( ) ! = FOCUS_NONE ) {
2019-12-16 01:33:25 +01:00
return c ;
2021-05-05 12:44:11 +02:00
}
2017-11-16 10:45:52 +01:00
}
2022-06-30 16:22:40 +02:00
// Find next child.
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
Control * next_child = nullptr ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < from - > get_child_count ( ) ; i + + ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( from - > get_child ( i ) ) ;
2017-01-13 14:45:50 +01:00
if ( ! c | | ! c - > is_visible_in_tree ( ) | | c - > is_set_as_toplevel ( ) ) {
2014-02-10 02:10:30 +01:00
continue ;
}
2017-03-05 16:44:50 +01:00
next_child = c ;
2014-02-10 02:10:30 +01:00
break ;
}
2019-06-26 15:08:25 +02:00
if ( ! next_child ) {
2017-03-05 16:44:50 +01:00
next_child = _next_control ( from ) ;
2022-06-30 16:22:40 +02:00
if ( ! next_child ) { // Nothing else. Go up and find either window or subwindow.
2017-03-05 16:44:50 +01:00
next_child = const_cast < Control * > ( this ) ;
while ( next_child & & ! next_child - > is_set_as_toplevel ( ) ) {
2017-08-24 22:58:51 +02:00
next_child = cast_to < Control > ( next_child - > get_parent ( ) ) ;
2014-02-10 02:10:30 +01:00
}
if ( ! next_child ) {
2017-03-05 16:44:50 +01:00
next_child = const_cast < Control * > ( this ) ;
while ( next_child ) {
2021-05-05 12:44:11 +02:00
if ( next_child - > data . SI | | next_child - > data . RI ) {
2016-01-17 02:41:10 +01:00
break ;
2021-05-05 12:44:11 +02:00
}
2017-03-05 16:44:50 +01:00
next_child = next_child - > get_parent_control ( ) ;
2016-01-17 02:41:10 +01:00
}
2014-02-10 02:10:30 +01:00
}
}
}
2022-07-01 00:25:10 +02:00
if ( next_child = = from | | next_child = = this ) { // No next control.
2021-05-04 16:00:45 +02:00
return ( get_focus_mode ( ) = = FOCUS_ALL ) ? next_child : nullptr ;
2021-05-05 12:44:11 +02:00
}
2016-10-05 08:56:58 +02:00
if ( next_child ) {
2021-05-05 12:44:11 +02:00
if ( next_child - > get_focus_mode ( ) = = FOCUS_ALL ) {
2016-10-05 08:56:58 +02:00
return next_child ;
2021-05-05 12:44:11 +02:00
}
2016-10-05 08:56:58 +02:00
from = next_child ;
2021-05-05 12:44:11 +02:00
} else {
2017-03-05 16:44:50 +01:00
break ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2016-03-09 00:00:52 +01:00
2021-05-04 16:00:45 +02:00
return nullptr ;
2014-02-10 02:10:30 +01:00
}
static Control * _prev_control ( Control * p_from ) {
2021-05-04 16:00:45 +02:00
Control * child = nullptr ;
2017-03-05 16:44:50 +01:00
for ( int i = p_from - > get_child_count ( ) - 1 ; i > = 0 ; i - - ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( p_from - > get_child ( i ) ) ;
2021-05-05 12:44:11 +02:00
if ( ! c | | ! c - > is_visible_in_tree ( ) | | c - > is_set_as_toplevel ( ) ) {
2014-02-10 02:10:30 +01:00
continue ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
child = c ;
2014-02-10 02:10:30 +01:00
break ;
}
2021-05-05 12:44:11 +02:00
if ( ! child ) {
2014-02-10 02:10:30 +01:00
return p_from ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2022-06-30 16:22:40 +02:00
// No prev in parent, try the same in parent.
2014-02-10 02:10:30 +01:00
return _prev_control ( child ) ;
}
Control * Control : : find_prev_valid_focus ( ) const {
2017-03-05 16:44:50 +01:00
Control * from = const_cast < Control * > ( this ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
while ( true ) {
2017-11-16 10:45:52 +01:00
// If the focus property is manually overwritten, attempt to use it.
if ( ! data . focus_prev . is_empty ( ) ) {
Node * n = get_node ( data . focus_prev ) ;
2019-12-16 01:33:25 +01:00
Control * c ;
2017-11-16 10:45:52 +01:00
if ( n ) {
2019-12-16 01:33:25 +01:00
c = Object : : cast_to < Control > ( n ) ;
2021-05-04 16:00:45 +02:00
ERR_FAIL_COND_V_MSG ( ! c , nullptr , " Previous focus node is not a control: " + n - > get_name ( ) + " . " ) ;
2017-11-16 10:45:52 +01:00
} else {
2021-05-04 16:00:45 +02:00
return nullptr ;
2017-11-16 10:45:52 +01:00
}
2021-05-05 12:44:11 +02:00
if ( c - > is_visible ( ) & & c - > get_focus_mode ( ) ! = FOCUS_NONE ) {
2019-12-16 01:33:25 +01:00
return c ;
2021-05-05 12:44:11 +02:00
}
2017-11-16 10:45:52 +01:00
}
2022-06-30 16:22:40 +02:00
// Find prev child.
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
Control * prev_child = nullptr ;
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
if ( from - > is_set_as_toplevel ( ) | | ! Object : : cast_to < Control > ( from - > get_parent ( ) ) ) {
2022-06-30 16:22:40 +02:00
// Find last of the children.
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
prev_child = _prev_control ( from ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
} else {
for ( int i = ( from - > get_position_in_parent ( ) - 1 ) ; i > = 0 ; i - - ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( from - > get_parent ( ) - > get_child ( i ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( ! c | | ! c - > is_visible_in_tree ( ) | | c - > is_set_as_toplevel ( ) ) {
continue ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
prev_child = c ;
break ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( ! prev_child ) {
2017-08-24 22:58:51 +02:00
prev_child = Object : : cast_to < Control > ( from - > get_parent ( ) ) ;
2017-03-05 16:44:50 +01:00
} else {
prev_child = _prev_control ( prev_child ) ;
}
}
2014-02-10 02:10:30 +01:00
2022-07-01 00:25:10 +02:00
if ( prev_child = = from | | prev_child = = this ) { // No prev control.
2021-05-04 16:00:45 +02:00
return ( get_focus_mode ( ) = = FOCUS_ALL ) ? prev_child : nullptr ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-05-05 12:44:11 +02:00
if ( prev_child - > get_focus_mode ( ) = = FOCUS_ALL ) {
2017-03-05 16:44:50 +01:00
return prev_child ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
from = prev_child ;
}
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
return nullptr ;
2014-02-10 02:10:30 +01:00
}
Control : : FocusMode Control : : get_focus_mode ( ) const {
return data . focus_mode ;
}
2021-11-30 21:29:18 +01:00
2014-02-10 02:10:30 +01:00
bool Control : : has_focus ( ) const {
2016-01-17 02:41:10 +01:00
return is_inside_tree ( ) & & get_viewport ( ) - > _gui_control_has_focus ( this ) ;
2014-02-10 02:10:30 +01:00
}
void Control : : grab_focus ( ) {
2019-09-01 01:25:22 +02:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2018-09-06 18:32:34 +02:00
if ( data . focus_mode = = FOCUS_NONE ) {
WARN_PRINT ( " This control can't grab focus. Use set_focus_mode() to allow a control to get focus. " ) ;
2014-02-10 02:10:30 +01:00
return ;
2018-09-06 18:32:34 +02:00
}
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_control_grab_focus ( this ) ;
2016-03-09 00:00:52 +01:00
}
2014-02-10 02:10:30 +01:00
void Control : : release_focus ( ) {
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2014-02-10 02:10:30 +01:00
2021-05-05 12:44:11 +02:00
if ( ! has_focus ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_remove_focus ( ) ;
2014-02-10 02:10:30 +01:00
update ( ) ;
}
bool Control : : is_toplevel_control ( ) const {
2016-01-17 02:41:10 +01:00
return is_inside_tree ( ) & & ( ! data . parent_canvas_item & & ! data . RI & & is_set_as_toplevel ( ) ) ;
2014-02-10 02:10:30 +01:00
}
void Control : : show_modal ( bool p_exclusive ) {
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2016-01-17 02:41:10 +01:00
ERR_FAIL_COND ( ! data . SI ) ;
2014-02-10 02:10:30 +01:00
2021-05-05 12:44:11 +02:00
if ( is_visible_in_tree ( ) ) {
2014-02-10 02:10:30 +01:00
hide ( ) ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
ERR_FAIL_COND ( data . MI ! = nullptr ) ;
2014-02-10 02:10:30 +01:00
show ( ) ;
raise ( ) ;
2017-03-05 16:44:50 +01:00
data . modal_exclusive = p_exclusive ;
data . MI = get_viewport ( ) - > _gui_show_modal ( this ) ;
data . modal_frame = Engine : : get_singleton ( ) - > get_frames_drawn ( ) ;
2014-02-10 02:10:30 +01:00
}
2022-05-28 01:10:48 +02:00
void Control : : set_modal_exclusive ( bool p_exclusive ) {
ERR_FAIL_NULL_MSG ( data . MI , " Modal exclusive can be set only if the Control is already shown as modal. " ) ;
data . modal_exclusive = p_exclusive ;
}
2016-01-17 02:41:10 +01:00
void Control : : _modal_set_prev_focus_owner ( ObjectID p_prev ) {
2017-03-05 16:44:50 +01:00
data . modal_prev_focus_owner = p_prev ;
2014-02-10 02:10:30 +01:00
}
void Control : : _modal_stack_remove ( ) {
2016-01-17 02:41:10 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2014-02-10 02:10:30 +01:00
2021-05-05 12:44:11 +02:00
if ( ! data . MI ) {
2016-01-17 02:41:10 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2019-10-22 16:28:11 +02:00
List < Control * > : : Element * element = data . MI ;
2021-05-04 16:00:45 +02:00
data . MI = nullptr ;
2019-10-22 16:28:11 +02:00
get_viewport ( ) - > _gui_remove_from_modal_stack ( element , data . modal_prev_focus_owner ) ;
2017-03-05 16:44:50 +01:00
data . modal_prev_focus_owner = 0 ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void Control : : _propagate_theme_changed ( CanvasItem * p_at , Control * p_owner , bool p_assign ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( p_at ) ;
2016-06-14 02:10:45 +02:00
2021-05-05 12:44:11 +02:00
if ( c & & c ! = p_owner & & c - > data . theme . is_valid ( ) ) { // has a theme, this can't be propagated
2016-06-14 02:10:45 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < p_at - > get_child_count ( ) ; i + + ) {
2017-08-24 22:58:51 +02:00
CanvasItem * child = Object : : cast_to < CanvasItem > ( p_at - > get_child ( i ) ) ;
2016-06-14 02:10:45 +02:00
if ( child ) {
2017-03-05 16:44:50 +01:00
_propagate_theme_changed ( child , p_owner , p_assign ) ;
2016-06-14 02:10:45 +02:00
}
2014-02-10 02:10:30 +01:00
}
2016-06-14 02:10:45 +02:00
if ( c ) {
2016-07-18 21:41:28 +02:00
if ( p_assign ) {
2017-03-05 16:44:50 +01:00
c - > data . theme_owner = p_owner ;
2016-07-18 21:41:28 +02:00
}
2016-09-11 16:28:01 +02:00
c - > notification ( NOTIFICATION_THEME_CHANGED ) ;
2016-06-14 02:10:45 +02:00
}
2014-02-10 02:10:30 +01:00
}
2016-07-18 21:41:28 +02:00
void Control : : _theme_changed ( ) {
2017-03-05 16:44:50 +01:00
_propagate_theme_changed ( this , this , false ) ;
2016-07-18 21:41:28 +02:00
}
2022-08-12 13:36:06 +02:00
void Control : : _invalidate_theme_cache ( ) {
data . theme_icon_cache . clear ( ) ;
data . theme_style_cache . clear ( ) ;
data . theme_font_cache . clear ( ) ;
data . theme_color_cache . clear ( ) ;
data . theme_constant_cache . clear ( ) ;
}
2017-03-05 16:44:50 +01:00
void Control : : set_theme ( const Ref < Theme > & p_theme ) {
2021-05-05 12:44:11 +02:00
if ( data . theme = = p_theme ) {
2016-07-18 21:41:28 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2016-07-18 21:41:28 +02:00
if ( data . theme . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
data . theme - > disconnect ( " changed " , this , " _theme_changed " ) ;
2016-07-18 21:41:28 +02:00
}
2017-03-05 16:44:50 +01:00
data . theme = p_theme ;
2014-02-10 02:10:30 +01:00
if ( ! p_theme . is_null ( ) ) {
2018-01-05 04:22:06 +01:00
data . theme_owner = this ;
2017-03-05 16:44:50 +01:00
_propagate_theme_changed ( this , this ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-08-24 22:58:51 +02:00
Control * parent = cast_to < Control > ( get_parent ( ) ) ;
2014-02-10 02:10:30 +01:00
if ( parent & & parent - > data . theme_owner ) {
2017-03-05 16:44:50 +01:00
_propagate_theme_changed ( this , parent - > data . theme_owner ) ;
2014-02-10 02:10:30 +01:00
} else {
2021-05-04 16:00:45 +02:00
_propagate_theme_changed ( this , nullptr ) ;
2014-02-10 02:10:30 +01:00
}
}
2016-07-18 21:41:28 +02:00
if ( data . theme . is_valid ( ) ) {
2019-12-23 13:12:16 +01:00
data . theme - > connect ( " changed " , this , " _theme_changed " , varray ( ) , CONNECT_DEFERRED ) ;
2016-07-18 21:41:28 +02:00
}
2014-02-10 02:10:30 +01:00
}
2022-02-10 22:26:09 +01:00
Ref < Theme > Control : : get_theme ( ) const {
return data . theme ;
}
void Control : : set_theme_type_variation ( const StringName & p_theme_type ) {
data . theme_type_variation = p_theme_type ;
_propagate_theme_changed ( this , data . theme_owner ) ;
}
StringName Control : : get_theme_type_variation ( ) const {
return data . theme_type_variation ;
}
2016-01-17 02:41:10 +01:00
void Control : : accept_event ( ) {
2021-05-05 12:44:11 +02:00
if ( is_inside_tree ( ) ) {
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_accept_event ( ) ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void Control : : set_tooltip ( const String & p_tooltip ) {
data . tooltip = p_tooltip ;
2019-06-28 18:38:57 +02:00
update_configuration_warning ( ) ;
2014-02-10 02:10:30 +01:00
}
2018-07-20 23:14:33 +02:00
2017-03-05 16:44:50 +01:00
String Control : : get_tooltip ( const Point2 & p_pos ) const {
2014-02-10 02:10:30 +01:00
return data . tooltip ;
}
2021-11-30 21:29:18 +01:00
2018-07-20 23:14:33 +02:00
Control * Control : : make_custom_tooltip ( const String & p_text ) const {
if ( get_script_instance ( ) ) {
return const_cast < Control * > ( this ) - > call ( " _make_custom_tooltip " , p_text ) ;
}
2021-05-04 16:00:45 +02:00
return nullptr ;
2018-07-20 23:14:33 +02:00
}
2014-02-10 02:10:30 +01:00
void Control : : set_default_cursor_shape ( CursorShape p_shape ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( int ( p_shape ) , CURSOR_MAX ) ;
2017-03-05 16:44:50 +01:00
data . default_cursor = p_shape ;
2014-02-10 02:10:30 +01:00
}
Control : : CursorShape Control : : get_default_cursor_shape ( ) const {
return data . default_cursor ;
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
Control : : CursorShape Control : : get_cursor_shape ( const Point2 & p_pos ) const {
2014-02-10 02:10:30 +01:00
return data . default_cursor ;
}
2017-01-11 04:52:51 +01:00
Transform2D Control : : get_transform ( ) const {
2017-07-06 22:42:44 +02:00
Transform2D xform = _get_internal_transform ( ) ;
xform [ 2 ] + = get_position ( ) ;
2015-12-12 17:54:26 +01:00
return xform ;
2014-02-10 02:10:30 +01:00
}
String Control : : _get_tooltip ( ) const {
return data . tooltip ;
}
void Control : : set_focus_neighbour ( Margin p_margin , const NodePath & p_neighbour ) {
2018-10-04 09:17:59 +02:00
ERR_FAIL_INDEX ( ( int ) p_margin , 4 ) ;
2017-03-05 16:44:50 +01:00
data . focus_neighbour [ p_margin ] = p_neighbour ;
2014-02-10 02:10:30 +01:00
}
NodePath Control : : get_focus_neighbour ( Margin p_margin ) const {
2018-10-04 09:17:59 +02:00
ERR_FAIL_INDEX_V ( ( int ) p_margin , 4 , NodePath ( ) ) ;
2014-02-10 02:10:30 +01:00
return data . focus_neighbour [ p_margin ] ;
}
2017-11-16 10:45:52 +01:00
void Control : : set_focus_next ( const NodePath & p_next ) {
data . focus_next = p_next ;
}
NodePath Control : : get_focus_next ( ) const {
return data . focus_next ;
}
void Control : : set_focus_previous ( const NodePath & p_prev ) {
data . focus_prev = p_prev ;
}
NodePath Control : : get_focus_previous ( ) const {
return data . focus_prev ;
}
2014-02-10 02:10:30 +01:00
# define MAX_NEIGHBOUR_SEARCH_COUNT 512
2017-03-05 16:44:50 +01:00
Control * Control : : _get_focus_neighbour ( Margin p_margin , int p_count ) {
2021-05-04 16:00:45 +02:00
ERR_FAIL_INDEX_V ( ( int ) p_margin , 4 , nullptr ) ;
2019-10-05 19:17:07 +02:00
2021-05-05 12:44:11 +02:00
if ( p_count > = MAX_NEIGHBOUR_SEARCH_COUNT ) {
2021-05-04 16:00:45 +02:00
return nullptr ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
if ( ! data . focus_neighbour [ p_margin ] . is_empty ( ) ) {
2021-05-04 16:00:45 +02:00
Control * c = nullptr ;
2017-03-05 16:44:50 +01:00
Node * n = get_node ( data . focus_neighbour [ p_margin ] ) ;
2014-02-10 02:10:30 +01:00
if ( n ) {
2017-08-24 22:58:51 +02:00
c = Object : : cast_to < Control > ( n ) ;
2021-05-04 16:00:45 +02:00
ERR_FAIL_COND_V_MSG ( ! c , nullptr , " Neighbor focus node is not a control: " + n - > get_name ( ) + " . " ) ;
2014-02-10 02:10:30 +01:00
} else {
2021-05-04 16:00:45 +02:00
return nullptr ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
bool valid = true ;
2021-05-05 12:44:11 +02:00
if ( ! c - > is_visible ( ) ) {
2017-03-05 16:44:50 +01:00
valid = false ;
2021-05-05 12:44:11 +02:00
}
if ( c - > get_focus_mode ( ) = = FOCUS_NONE ) {
2017-03-05 16:44:50 +01:00
valid = false ;
2021-05-05 12:44:11 +02:00
}
if ( valid ) {
2014-02-10 02:10:30 +01:00
return c ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
c = c - > _get_focus_neighbour ( p_margin , p_count + 1 ) ;
2014-02-10 02:10:30 +01:00
return c ;
}
2017-03-05 16:44:50 +01:00
float dist = 1e7 ;
2021-05-04 16:00:45 +02:00
Control * result = nullptr ;
2014-02-10 02:10:30 +01:00
Point2 points [ 4 ] ;
2017-01-11 04:52:51 +01:00
Transform2D xform = get_global_transform ( ) ;
2014-02-10 02:10:30 +01:00
2018-05-05 16:59:00 +02:00
points [ 0 ] = xform . xform ( Point2 ( ) ) ;
points [ 1 ] = xform . xform ( Point2 ( get_size ( ) . x , 0 ) ) ;
points [ 2 ] = xform . xform ( get_size ( ) ) ;
points [ 3 ] = xform . xform ( Point2 ( 0 , get_size ( ) . y ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
const Vector2 dir [ 4 ] = {
Vector2 ( - 1 , 0 ) ,
Vector2 ( 0 , - 1 ) ,
Vector2 ( 1 , 0 ) ,
Vector2 ( 0 , 1 )
2014-02-10 02:10:30 +01:00
} ;
2017-03-05 16:44:50 +01:00
Vector2 vdir = dir [ p_margin ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
float maxd = - 1e7 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 02:10:30 +01:00
float d = vdir . dot ( points [ i ] ) ;
2021-05-05 12:44:11 +02:00
if ( d > maxd ) {
2017-03-05 16:44:50 +01:00
maxd = d ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Node * base = this ;
2014-02-10 02:10:30 +01:00
while ( base ) {
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( base ) ;
2014-02-10 02:10:30 +01:00
if ( c ) {
2021-05-05 12:44:11 +02:00
if ( c - > data . SI ) {
2014-02-10 02:10:30 +01:00
break ;
2021-05-05 12:44:11 +02:00
}
if ( c - > data . RI ) {
2014-02-10 02:10:30 +01:00
break ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
base = base - > get_parent ( ) ;
2014-02-10 02:10:30 +01:00
}
2021-05-05 12:44:11 +02:00
if ( ! base ) {
2021-05-04 16:00:45 +02:00
return nullptr ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_window_find_focus_neighbour ( vdir , base , points , maxd , dist , & result ) ;
2014-02-10 02:10:30 +01:00
return result ;
}
2017-03-05 16:44:50 +01:00
void Control : : _window_find_focus_neighbour ( const Vector2 & p_dir , Node * p_at , const Point2 * p_points , float p_min , float & r_closest_dist , Control * * r_closest ) {
2021-05-05 12:44:11 +02:00
if ( Object : : cast_to < Viewport > ( p_at ) ) {
2014-02-10 02:10:30 +01:00
return ; //bye
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Control * c = Object : : cast_to < Control > ( p_at ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( c & & c ! = this & & c - > get_focus_mode ( ) = = FOCUS_ALL & & c - > is_visible_in_tree ( ) ) {
2014-02-10 02:10:30 +01:00
Point2 points [ 4 ] ;
2017-01-11 04:52:51 +01:00
Transform2D xform = c - > get_global_transform ( ) ;
2014-02-10 02:10:30 +01:00
2018-05-05 16:59:00 +02:00
points [ 0 ] = xform . xform ( Point2 ( ) ) ;
2020-01-19 23:38:50 +01:00
points [ 1 ] = xform . xform ( Point2 ( c - > get_size ( ) . x , 0 ) ) ;
points [ 2 ] = xform . xform ( c - > get_size ( ) ) ;
points [ 3 ] = xform . xform ( Point2 ( 0 , c - > get_size ( ) . y ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
float min = 1e7 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2014-02-10 02:10:30 +01:00
float d = p_dir . dot ( points [ i ] ) ;
2021-05-05 12:44:11 +02:00
if ( d < min ) {
2017-03-05 16:44:50 +01:00
min = d ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( min > ( p_min - CMP_EPSILON ) ) {
for ( int i = 0 ; i < 4 ; i + + ) {
Vector2 la = p_points [ i ] ;
Vector2 lb = p_points [ ( i + 1 ) % 4 ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int j = 0 ; j < 4 ; j + + ) {
Vector2 fa = points [ j ] ;
Vector2 fb = points [ ( j + 1 ) % 4 ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Vector2 pa , pb ;
float d = Geometry : : get_closest_points_between_segments ( la , lb , fa , fb , pa , pb ) ;
2014-02-10 02:10:30 +01:00
//float d = Geometry::get_closest_distance_between_segments(Vector3(la.x,la.y,0),Vector3(lb.x,lb.y,0),Vector3(fa.x,fa.y,0),Vector3(fb.x,fb.y,0));
2017-03-05 16:44:50 +01:00
if ( d < r_closest_dist ) {
r_closest_dist = d ;
* r_closest = c ;
2014-02-10 02:10:30 +01:00
}
}
}
}
}
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < p_at - > get_child_count ( ) ; i + + ) {
Node * child = p_at - > get_child ( i ) ;
2017-08-24 22:58:51 +02:00
Control * childc = Object : : cast_to < Control > ( child ) ;
2021-05-05 12:44:11 +02:00
if ( childc & & childc - > data . SI ) {
2014-02-10 02:10:30 +01:00
continue ; //subwindow, ignore
2021-05-05 12:44:11 +02:00
}
2017-03-05 16:44:50 +01:00
_window_find_focus_neighbour ( p_dir , p_at - > get_child ( i ) , p_points , p_min , r_closest_dist , r_closest ) ;
2014-02-10 02:10:30 +01:00
}
}
void Control : : set_h_size_flags ( int p_flags ) {
2021-05-05 12:44:11 +02:00
if ( data . h_size_flags = = p_flags ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2017-03-05 16:44:50 +01:00
data . h_size_flags = p_flags ;
2014-02-10 02:10:30 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > size_flags_changed ) ;
}
2017-03-05 16:44:50 +01:00
int Control : : get_h_size_flags ( ) const {
2014-02-10 02:10:30 +01:00
return data . h_size_flags ;
}
2021-11-30 21:29:18 +01:00
2014-02-10 02:10:30 +01:00
void Control : : set_v_size_flags ( int p_flags ) {
2021-05-05 12:44:11 +02:00
if ( data . v_size_flags = = p_flags ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2017-03-05 16:44:50 +01:00
data . v_size_flags = p_flags ;
2014-02-10 02:10:30 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > size_flags_changed ) ;
}
void Control : : set_stretch_ratio ( float p_ratio ) {
2021-05-05 12:44:11 +02:00
if ( data . expand = = p_ratio ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
data . expand = p_ratio ;
2014-02-10 02:10:30 +01:00
emit_signal ( SceneStringNames : : get_singleton ( ) - > size_flags_changed ) ;
}
float Control : : get_stretch_ratio ( ) const {
return data . expand ;
}
void Control : : grab_click_focus ( ) {
2014-11-06 01:20:42 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
2014-02-10 02:10:30 +01:00
2016-01-17 02:41:10 +01:00
get_viewport ( ) - > _gui_grab_click_focus ( this ) ;
2014-02-10 02:10:30 +01:00
}
void Control : : minimum_size_changed ( ) {
2021-05-05 12:44:11 +02:00
if ( ! is_inside_tree ( ) | | data . block_minimum_size_adjust ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2018-05-15 22:12:35 +02:00
Control * invalidate = this ;
//invalidate cache upwards
while ( invalidate & & invalidate - > data . minimum_size_valid ) {
invalidate - > data . minimum_size_valid = false ;
2021-05-05 12:44:11 +02:00
if ( invalidate - > is_set_as_toplevel ( ) ) {
2018-05-15 22:12:35 +02:00
break ; // do not go further up
2021-05-05 12:44:11 +02:00
}
2018-05-15 22:12:35 +02:00
invalidate = invalidate - > data . parent ;
}
2021-05-05 12:44:11 +02:00
if ( ! is_visible_in_tree ( ) ) {
2018-05-15 22:12:35 +02:00
return ;
2021-05-05 12:44:11 +02:00
}
2018-05-15 22:12:35 +02:00
2021-05-05 12:44:11 +02:00
if ( data . updating_last_minimum_size ) {
2014-02-10 02:10:30 +01:00
return ;
2021-05-05 12:44:11 +02:00
}
2014-02-10 02:10:30 +01:00
2018-05-15 22:12:35 +02:00
data . updating_last_minimum_size = true ;
2014-02-10 02:10:30 +01:00
2018-05-15 22:12:35 +02:00
MessageQueue : : get_singleton ( ) - > push_call ( this , " _update_minimum_size " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
int Control : : get_v_size_flags ( ) const {
2014-02-10 02:10:30 +01:00
return data . v_size_flags ;
}
2017-01-08 23:54:19 +01:00
void Control : : set_mouse_filter ( MouseFilter p_filter ) {
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_filter , 3 ) ;
data . mouse_filter = p_filter ;
2019-06-28 18:38:57 +02:00
update_configuration_warning ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
Control : : MouseFilter Control : : get_mouse_filter ( ) const {
2017-01-08 23:54:19 +01:00
return data . mouse_filter ;
2014-02-10 02:10:30 +01:00
}
2017-11-22 09:43:40 +01:00
void Control : : set_pass_on_modal_close_click ( bool p_pass_on ) {
data . pass_on_modal_close_click = p_pass_on ;
}
2021-03-25 14:02:26 +01:00
bool Control : : get_pass_on_modal_close_click ( ) const {
2017-11-22 09:43:40 +01:00
return data . pass_on_modal_close_click ;
}
2014-02-10 02:10:30 +01:00
Control * Control : : get_focus_owner ( ) const {
2021-05-04 16:00:45 +02:00
ERR_FAIL_COND_V ( ! is_inside_tree ( ) , nullptr ) ;
2016-01-17 02:41:10 +01:00
return get_viewport ( ) - > _gui_get_focus_owner ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void Control : : warp_mouse ( const Point2 & p_to_pos ) {
2015-02-14 23:22:06 +01:00
ERR_FAIL_COND ( ! is_inside_tree ( ) ) ;
get_viewport ( ) - > warp_mouse ( get_global_transform ( ) . xform ( p_to_pos ) ) ;
}
2015-10-17 15:29:54 +02:00
bool Control : : is_text_field ( ) const {
2017-03-05 16:44:50 +01:00
return false ;
2015-10-17 15:29:54 +02:00
}
2016-05-06 23:38:08 +02:00
void Control : : set_rotation ( float p_radians ) {
2017-03-05 16:44:50 +01:00
data . rotation = p_radians ;
2015-12-12 17:54:26 +01:00
update ( ) ;
_notify_transform ( ) ;
2017-04-03 18:34:44 +02:00
_change_notify ( " rect_rotation " ) ;
2015-12-12 17:54:26 +01:00
}
2017-03-05 16:44:50 +01:00
float Control : : get_rotation ( ) const {
2015-12-12 17:54:26 +01:00
return data . rotation ;
}
2017-11-10 11:07:52 +01:00
void Control : : set_rotation_degrees ( float p_degrees ) {
2016-05-06 23:38:08 +02:00
set_rotation ( Math : : deg2rad ( p_degrees ) ) ;
}
2017-11-10 11:07:52 +01:00
float Control : : get_rotation_degrees ( ) const {
2016-05-06 23:38:08 +02:00
return Math : : rad2deg ( get_rotation ( ) ) ;
}
2019-02-25 16:13:25 +01:00
void Control : : _override_changed ( ) {
2016-06-17 21:00:27 +02:00
notification ( NOTIFICATION_THEME_CHANGED ) ;
2019-02-25 16:13:25 +01:00
minimum_size_changed ( ) ; // overrides are likely to affect minimum size
2016-06-17 21:00:27 +02:00
}
2016-05-06 23:38:08 +02:00
2017-07-06 22:42:44 +02:00
void Control : : set_pivot_offset ( const Vector2 & p_pivot ) {
data . pivot_offset = p_pivot ;
update ( ) ;
_notify_transform ( ) ;
_change_notify ( " rect_pivot_offset " ) ;
}
Vector2 Control : : get_pivot_offset ( ) const {
return data . pivot_offset ;
}
2017-03-05 16:44:50 +01:00
void Control : : set_scale ( const Vector2 & p_scale ) {
data . scale = p_scale ;
2020-01-13 12:13:45 +01:00
// Avoid having 0 scale values, can lead to errors in physics and rendering.
2021-05-05 12:44:11 +02:00
if ( data . scale . x = = 0 ) {
2020-01-13 12:13:45 +01:00
data . scale . x = CMP_EPSILON ;
2021-05-05 12:44:11 +02:00
}
if ( data . scale . y = = 0 ) {
2020-01-13 12:13:45 +01:00
data . scale . y = CMP_EPSILON ;
2021-05-05 12:44:11 +02:00
}
2015-12-12 17:54:26 +01:00
update ( ) ;
_notify_transform ( ) ;
2021-05-22 07:12:53 +02:00
_change_notify ( " rect_scale " ) ;
2015-12-12 17:54:26 +01:00
}
2021-11-30 21:29:18 +01:00
2017-03-05 16:44:50 +01:00
Vector2 Control : : get_scale ( ) const {
2015-12-12 17:54:26 +01:00
return data . scale ;
}
2016-01-20 00:27:27 +01:00
Control * Control : : get_root_parent_control ( ) const {
2017-03-05 16:44:50 +01:00
const CanvasItem * ci = this ;
const Control * root = this ;
2016-01-20 00:27:27 +01:00
2017-03-05 16:44:50 +01:00
while ( ci ) {
2017-08-24 22:58:51 +02:00
const Control * c = Object : : cast_to < Control > ( ci ) ;
2016-01-20 00:27:27 +01:00
if ( c ) {
2017-03-05 16:44:50 +01:00
root = c ;
2016-01-20 00:27:27 +01:00
2021-05-05 12:44:11 +02:00
if ( c - > data . RI | | c - > data . MI | | c - > is_toplevel_control ( ) ) {
2016-01-20 00:27:27 +01:00
break ;
2021-05-05 12:44:11 +02:00
}
2016-01-20 00:27:27 +01:00
}
2017-03-05 16:44:50 +01:00
ci = ci - > get_parent_item ( ) ;
2016-01-20 00:27:27 +01:00
}
2017-03-05 16:44:50 +01:00
return const_cast < Control * > ( root ) ;
2016-01-20 00:27:27 +01:00
}
2015-12-12 17:54:26 +01:00
2016-08-25 22:45:20 +02:00
void Control : : set_block_minimum_size_adjust ( bool p_block ) {
2017-03-05 16:44:50 +01:00
data . block_minimum_size_adjust = p_block ;
2016-08-25 22:45:20 +02:00
}
2016-01-24 14:57:42 +01:00
2016-08-25 22:45:20 +02:00
bool Control : : is_minimum_size_adjust_blocked ( ) const {
return data . block_minimum_size_adjust ;
}
2016-08-31 04:44:14 +02:00
void Control : : set_disable_visibility_clip ( bool p_ignore ) {
2017-03-05 16:44:50 +01:00
data . disable_visibility_clip = p_ignore ;
2016-08-31 04:44:14 +02:00
update ( ) ;
}
bool Control : : is_visibility_clip_disabled ( ) const {
return data . disable_visibility_clip ;
}
2017-03-05 16:44:50 +01:00
void Control : : get_argument_options ( const StringName & p_function , int p_idx , List < String > * r_options ) const {
2018-12-18 02:53:54 +01:00
# ifdef TOOLS_ENABLED
2022-04-27 09:26:46 +02:00
const String quote_style = EDITOR_GET ( " text_editor/completion/use_single_quotes " ) ? " ' " : " \" " ;
2018-12-18 02:53:54 +01:00
# else
const String quote_style = " \" " ;
# endif
2017-03-05 16:44:50 +01:00
Node : : get_argument_options ( p_function , p_idx , r_options ) ;
2016-09-11 16:48:31 +02:00
2017-03-05 16:44:50 +01:00
if ( p_idx = = 0 ) {
2016-09-11 16:48:31 +02:00
List < StringName > sn ;
String pf = p_function ;
2024-05-25 04:28:40 +02:00
if ( pf = = " add_color_override " | | pf = = " has_color " | | pf = = " has_color_override " | | pf = = " get_color " | | pf = = " remove_color_override " ) {
2017-03-05 16:44:50 +01:00
Theme : : get_default ( ) - > get_color_list ( get_class ( ) , & sn ) ;
2024-05-25 04:28:40 +02:00
} else if ( pf = = " add_stylebox_override " | | pf = = " has_stylebox " | | pf = = " has_stylebox_override " | | pf = = " get_stylebox " | | pf = = " remove_stylebox_override " ) {
2017-03-05 16:44:50 +01:00
Theme : : get_default ( ) - > get_stylebox_list ( get_class ( ) , & sn ) ;
2024-05-25 04:28:40 +02:00
} else if ( pf = = " add_font_override " | | pf = = " has_font " | | pf = = " has_font_override " | | pf = = " get_font " | | pf = = " remove_font_override " ) {
2017-03-05 16:44:50 +01:00
Theme : : get_default ( ) - > get_font_list ( get_class ( ) , & sn ) ;
2024-05-25 04:28:40 +02:00
} else if ( pf = = " add_constant_override " | | pf = = " has_constant " | | pf = = " has_constant_override " | | pf = = " get_constant " | | pf = = " remove_constant_override " ) {
2017-03-05 16:44:50 +01:00
Theme : : get_default ( ) - > get_constant_list ( get_class ( ) , & sn ) ;
2024-05-25 04:28:40 +02:00
} else if ( pf = = " add_icon_override " | | pf = = " has_icon " | | pf = = " has_icon_override " | | pf = = " get_icon " | | pf = = " remove_icon_override " ) {
Theme : : get_default ( ) - > get_icon_list ( get_class ( ) , & sn ) ;
2016-09-11 16:48:31 +02:00
}
sn . sort_custom < StringName : : AlphCompare > ( ) ;
2017-03-05 16:44:50 +01:00
for ( List < StringName > : : Element * E = sn . front ( ) ; E ; E = E - > next ( ) ) {
2018-12-18 02:53:54 +01:00
r_options - > push_back ( quote_style + E - > get ( ) + quote_style ) ;
2016-09-11 16:48:31 +02:00
}
}
}
2019-06-28 18:38:57 +02:00
String Control : : get_configuration_warning ( ) const {
String warning = CanvasItem : : get_configuration_warning ( ) ;
if ( data . mouse_filter = = MOUSE_FILTER_IGNORE & & data . tooltip ! = " " ) {
if ( warning ! = String ( ) ) {
2019-07-09 00:17:04 +02:00
warning + = " \n \n " ;
2019-06-28 18:38:57 +02:00
}
warning + = TTR ( " The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \" Ignore \" . To solve this, set the Mouse Filter to \" Stop \" or \" Pass \" . " ) ;
}
return warning ;
}
2017-01-09 19:50:08 +01:00
void Control : : set_clip_contents ( bool p_clip ) {
2017-03-05 16:44:50 +01:00
data . clip_contents = p_clip ;
2017-01-09 19:50:08 +01:00
update ( ) ;
}
bool Control : : is_clipping_contents ( ) {
return data . clip_contents ;
}
2016-09-11 16:48:31 +02:00
2017-07-06 18:26:39 +02:00
void Control : : set_h_grow_direction ( GrowDirection p_direction ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_direction , 3 ) ;
2017-07-06 18:26:39 +02:00
data . h_grow = p_direction ;
_size_changed ( ) ;
}
Control : : GrowDirection Control : : get_h_grow_direction ( ) const {
return data . h_grow ;
}
void Control : : set_v_grow_direction ( GrowDirection p_direction ) {
2019-10-05 19:17:07 +02:00
ERR_FAIL_INDEX ( ( int ) p_direction , 3 ) ;
2017-07-06 18:26:39 +02:00
data . v_grow = p_direction ;
_size_changed ( ) ;
}
2021-11-30 21:29:18 +01:00
2017-07-06 18:26:39 +02:00
Control : : GrowDirection Control : : get_v_grow_direction ( ) const {
return data . v_grow ;
}
2024-04-19 10:53:06 +02:00
void Control : : _query_order_update ( bool & r_subwindow_order_dirty , bool & r_root_order_dirty ) const {
if ( data . SI ) {
r_subwindow_order_dirty = true ;
}
if ( data . RI ) {
r_root_order_dirty = true ;
}
}
2014-02-10 02:10:30 +01:00
void Control : : _bind_methods ( ) {
2017-02-13 12:47:24 +01:00
//ClassDB::bind_method(D_METHOD("_window_resize_event"),&Control::_window_resize_event);
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _size_changed " ) , & Control : : _size_changed ) ;
ClassDB : : bind_method ( D_METHOD ( " _update_minimum_size " ) , & Control : : _update_minimum_size ) ;
ClassDB : : bind_method ( D_METHOD ( " accept_event " ) , & Control : : accept_event ) ;
ClassDB : : bind_method ( D_METHOD ( " get_minimum_size " ) , & Control : : get_minimum_size ) ;
ClassDB : : bind_method ( D_METHOD ( " get_combined_minimum_size " ) , & Control : : get_combined_minimum_size ) ;
2019-03-31 18:53:24 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_anchors_preset " , " preset " , " keep_margins " ) , & Control : : set_anchors_preset , DEFVAL ( false ) ) ;
2017-09-19 22:39:19 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_margins_preset " , " preset " , " resize_mode " , " margin " ) , & Control : : set_margins_preset , DEFVAL ( PRESET_MODE_MINSIZE ) , DEFVAL ( 0 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " set_anchors_and_margins_preset " , " preset " , " resize_mode " , " margin " ) , & Control : : set_anchors_and_margins_preset , DEFVAL ( PRESET_MODE_MINSIZE ) , DEFVAL ( 0 ) ) ;
2017-07-06 09:16:27 +02:00
ClassDB : : bind_method ( D_METHOD ( " _set_anchor " , " margin " , " anchor " ) , & Control : : _set_anchor ) ;
2019-03-31 18:53:24 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_anchor " , " margin " , " anchor " , " keep_margin " , " push_opposite_anchor " ) , & Control : : set_anchor , DEFVAL ( false ) , DEFVAL ( true ) ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_anchor " , " margin " ) , & Control : : get_anchor ) ;
ClassDB : : bind_method ( D_METHOD ( " set_margin " , " margin " , " offset " ) , & Control : : set_margin ) ;
2017-08-11 19:25:26 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_anchor_and_margin " , " margin " , " anchor " , " offset " , " push_opposite_anchor " ) , & Control : : set_anchor_and_margin , DEFVAL ( false ) ) ;
2017-09-10 15:37:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_begin " , " position " ) , & Control : : set_begin ) ;
ClassDB : : bind_method ( D_METHOD ( " set_end " , " position " ) , & Control : : set_end ) ;
2019-03-31 18:53:24 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_position " , " position " , " keep_margins " ) , & Control : : set_position , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " _set_position " , " margin " ) , & Control : : _set_position ) ;
ClassDB : : bind_method ( D_METHOD ( " set_size " , " size " , " keep_margins " ) , & Control : : set_size , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " _set_size " , " size " ) , & Control : : _set_size ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_custom_minimum_size " , " size " ) , & Control : : set_custom_minimum_size ) ;
2019-03-31 18:53:24 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_global_position " , " position " , " keep_margins " ) , & Control : : set_global_position , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " _set_global_position " , " position " ) , & Control : : _set_global_position ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_rotation " , " radians " ) , & Control : : set_rotation ) ;
2017-11-10 11:07:52 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_rotation_degrees " , " degrees " ) , & Control : : set_rotation_degrees ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_scale " , " scale " ) , & Control : : set_scale ) ;
2017-07-06 22:42:44 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_pivot_offset " , " pivot_offset " ) , & Control : : set_pivot_offset ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_margin " , " margin " ) , & Control : : get_margin ) ;
ClassDB : : bind_method ( D_METHOD ( " get_begin " ) , & Control : : get_begin ) ;
ClassDB : : bind_method ( D_METHOD ( " get_end " ) , & Control : : get_end ) ;
2017-03-29 17:29:38 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_position " ) , & Control : : get_position ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_size " ) , & Control : : get_size ) ;
ClassDB : : bind_method ( D_METHOD ( " get_rotation " ) , & Control : : get_rotation ) ;
2017-11-10 11:07:52 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_rotation_degrees " ) , & Control : : get_rotation_degrees ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_scale " ) , & Control : : get_scale ) ;
2017-07-06 22:42:44 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_pivot_offset " ) , & Control : : get_pivot_offset ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_custom_minimum_size " ) , & Control : : get_custom_minimum_size ) ;
2019-03-01 14:16:19 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_parent_area_size " ) , & Control : : get_parent_area_size ) ;
2017-03-29 17:29:38 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_global_position " ) , & Control : : get_global_position ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_rect " ) , & Control : : get_rect ) ;
ClassDB : : bind_method ( D_METHOD ( " get_global_rect " ) , & Control : : get_global_rect ) ;
ClassDB : : bind_method ( D_METHOD ( " show_modal " , " exclusive " ) , & Control : : show_modal , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " set_focus_mode " , " mode " ) , & Control : : set_focus_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " get_focus_mode " ) , & Control : : get_focus_mode ) ;
ClassDB : : bind_method ( D_METHOD ( " has_focus " ) , & Control : : has_focus ) ;
ClassDB : : bind_method ( D_METHOD ( " grab_focus " ) , & Control : : grab_focus ) ;
ClassDB : : bind_method ( D_METHOD ( " release_focus " ) , & Control : : release_focus ) ;
2021-01-23 23:34:44 +01:00
ClassDB : : bind_method ( D_METHOD ( " find_prev_valid_focus " ) , & Control : : find_prev_valid_focus ) ;
ClassDB : : bind_method ( D_METHOD ( " find_next_valid_focus " ) , & Control : : find_next_valid_focus ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_focus_owner " ) , & Control : : get_focus_owner ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_h_size_flags " , " flags " ) , & Control : : set_h_size_flags ) ;
ClassDB : : bind_method ( D_METHOD ( " get_h_size_flags " ) , & Control : : get_h_size_flags ) ;
ClassDB : : bind_method ( D_METHOD ( " set_stretch_ratio " , " ratio " ) , & Control : : set_stretch_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " get_stretch_ratio " ) , & Control : : get_stretch_ratio ) ;
ClassDB : : bind_method ( D_METHOD ( " set_v_size_flags " , " flags " ) , & Control : : set_v_size_flags ) ;
ClassDB : : bind_method ( D_METHOD ( " get_v_size_flags " ) , & Control : : get_v_size_flags ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_theme " , " theme " ) , & Control : : set_theme ) ;
ClassDB : : bind_method ( D_METHOD ( " get_theme " ) , & Control : : get_theme ) ;
2017-03-05 16:44:50 +01:00
2022-02-10 22:26:09 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_theme_type_variation " , " theme_type " ) , & Control : : set_theme_type_variation ) ;
ClassDB : : bind_method ( D_METHOD ( " get_theme_type_variation " ) , & Control : : get_theme_type_variation ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_icon_override " , " name " , " texture " ) , & Control : : add_icon_override ) ;
ClassDB : : bind_method ( D_METHOD ( " add_shader_override " , " name " , " shader " ) , & Control : : add_shader_override ) ;
2018-01-13 08:58:45 +01:00
ClassDB : : bind_method ( D_METHOD ( " add_stylebox_override " , " name " , " stylebox " ) , & Control : : add_style_override ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_font_override " , " name " , " font " ) , & Control : : add_font_override ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " add_color_override " , " name " , " color " ) , & Control : : add_color_override ) ;
ClassDB : : bind_method ( D_METHOD ( " add_constant_override " , " name " , " constant " ) , & Control : : add_constant_override ) ;
2021-11-11 11:23:37 +01:00
ClassDB : : bind_method ( D_METHOD ( " remove_icon_override " , " name " ) , & Control : : remove_icon_override ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_shader_override " , " name " ) , & Control : : remove_shader_override ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_stylebox_override " , " name " ) , & Control : : remove_stylebox_override ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_font_override " , " name " ) , & Control : : remove_font_override ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_color_override " , " name " ) , & Control : : remove_color_override ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_constant_override " , " name " ) , & Control : : remove_constant_override ) ;
2021-08-06 21:30:34 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_icon " , " name " , " theme_type " ) , & Control : : get_icon , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_stylebox " , " name " , " theme_type " ) , & Control : : get_stylebox , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_font " , " name " , " theme_type " ) , & Control : : get_font , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_color " , " name " , " theme_type " ) , & Control : : get_color , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_constant " , " name " , " theme_type " ) , & Control : : get_constant , DEFVAL ( " " ) ) ;
2014-02-10 02:10:30 +01:00
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " has_icon_override " , " name " ) , & Control : : has_icon_override ) ;
2018-01-13 08:58:45 +01:00
ClassDB : : bind_method ( D_METHOD ( " has_shader_override " , " name " ) , & Control : : has_shader_override ) ;
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " has_stylebox_override " , " name " ) , & Control : : has_stylebox_override ) ;
ClassDB : : bind_method ( D_METHOD ( " has_font_override " , " name " ) , & Control : : has_font_override ) ;
ClassDB : : bind_method ( D_METHOD ( " has_color_override " , " name " ) , & Control : : has_color_override ) ;
ClassDB : : bind_method ( D_METHOD ( " has_constant_override " , " name " ) , & Control : : has_constant_override ) ;
2016-06-01 16:41:25 +02:00
2021-08-06 21:30:34 +02:00
ClassDB : : bind_method ( D_METHOD ( " has_icon " , " name " , " theme_type " ) , & Control : : has_icon , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " has_stylebox " , " name " , " theme_type " ) , & Control : : has_stylebox , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " has_font " , " name " , " theme_type " ) , & Control : : has_font , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " has_color " , " name " , " theme_type " ) , & Control : : has_color , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( D_METHOD ( " has_constant " , " name " , " theme_type " ) , & Control : : has_constant , DEFVAL ( " " ) ) ;
2014-02-10 02:10:30 +01:00
2021-10-04 16:44:53 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_theme_default_font " ) , & Control : : get_theme_default_font ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_parent_control " ) , & Control : : get_parent_control ) ;
2014-02-10 02:10:30 +01:00
2017-07-06 18:26:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_h_grow_direction " , " direction " ) , & Control : : set_h_grow_direction ) ;
ClassDB : : bind_method ( D_METHOD ( " get_h_grow_direction " ) , & Control : : get_h_grow_direction ) ;
ClassDB : : bind_method ( D_METHOD ( " set_v_grow_direction " , " direction " ) , & Control : : set_v_grow_direction ) ;
ClassDB : : bind_method ( D_METHOD ( " get_v_grow_direction " ) , & Control : : get_v_grow_direction ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_tooltip " , " tooltip " ) , & Control : : set_tooltip ) ;
2017-09-10 15:37:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_tooltip " , " at_position " ) , & Control : : get_tooltip , DEFVAL ( Point2 ( ) ) ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " _get_tooltip " ) , & Control : : _get_tooltip ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_default_cursor_shape " , " shape " ) , & Control : : set_default_cursor_shape ) ;
ClassDB : : bind_method ( D_METHOD ( " get_default_cursor_shape " ) , & Control : : get_default_cursor_shape ) ;
2017-09-10 15:37:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_cursor_shape " , " position " ) , & Control : : get_cursor_shape , DEFVAL ( Point2 ( ) ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_focus_neighbour " , " margin " , " neighbour " ) , & Control : : set_focus_neighbour ) ;
ClassDB : : bind_method ( D_METHOD ( " get_focus_neighbour " , " margin " ) , & Control : : get_focus_neighbour ) ;
2014-02-10 02:10:30 +01:00
2017-11-16 10:45:52 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_focus_next " , " next " ) , & Control : : set_focus_next ) ;
ClassDB : : bind_method ( D_METHOD ( " get_focus_next " ) , & Control : : get_focus_next ) ;
ClassDB : : bind_method ( D_METHOD ( " set_focus_previous " , " previous " ) , & Control : : set_focus_previous ) ;
ClassDB : : bind_method ( D_METHOD ( " get_focus_previous " ) , & Control : : get_focus_previous ) ;
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " force_drag " , " data " , " preview " ) , & Control : : force_drag ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_mouse_filter " , " filter " ) , & Control : : set_mouse_filter ) ;
ClassDB : : bind_method ( D_METHOD ( " get_mouse_filter " ) , & Control : : get_mouse_filter ) ;
2014-02-10 02:10:30 +01:00
2021-03-25 14:02:26 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_pass_on_modal_close_click " , " enabled " ) , & Control : : set_pass_on_modal_close_click ) ;
ClassDB : : bind_method ( D_METHOD ( " get_pass_on_modal_close_click " ) , & Control : : get_pass_on_modal_close_click ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_clip_contents " , " enable " ) , & Control : : set_clip_contents ) ;
ClassDB : : bind_method ( D_METHOD ( " is_clipping_contents " ) , & Control : : is_clipping_contents ) ;
2017-01-09 19:50:08 +01:00
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " grab_click_focus " ) , & Control : : grab_click_focus ) ;
2014-02-10 02:10:30 +01:00
2017-08-09 13:19:41 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_drag_forwarding " , " target " ) , & Control : : set_drag_forwarding ) ;
ClassDB : : bind_method ( D_METHOD ( " set_drag_preview " , " control " ) , & Control : : set_drag_preview ) ;
2021-11-26 16:11:01 +01:00
ClassDB : : bind_method ( D_METHOD ( " is_drag_successful " ) , & Control : : is_drag_successful ) ;
2014-02-10 02:10:30 +01:00
2017-09-10 15:37:49 +02:00
ClassDB : : bind_method ( D_METHOD ( " warp_mouse " , " to_position " ) , & Control : : warp_mouse ) ;
2015-02-14 23:22:06 +01:00
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " minimum_size_changed " ) , & Control : : minimum_size_changed ) ;
2015-02-14 23:22:06 +01:00
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " _theme_changed " ) , & Control : : _theme_changed ) ;
2016-07-18 21:41:28 +02:00
2019-02-25 16:13:25 +01:00
ClassDB : : bind_method ( D_METHOD ( " _override_changed " ) , & Control : : _override_changed ) ;
2016-06-17 21:00:27 +02:00
2017-05-20 17:38:03 +02:00
BIND_VMETHOD ( MethodInfo ( " _gui_input " , PropertyInfo ( Variant : : OBJECT , " event " , PROPERTY_HINT_RESOURCE_TYPE , " InputEvent " ) ) ) ;
2017-03-13 16:45:27 +01:00
BIND_VMETHOD ( MethodInfo ( Variant : : VECTOR2 , " _get_minimum_size " ) ) ;
2019-08-26 18:38:16 +02:00
MethodInfo get_drag_data = MethodInfo ( " get_drag_data " , PropertyInfo ( Variant : : VECTOR2 , " position " ) ) ;
get_drag_data . return_val . usage | = PROPERTY_USAGE_NIL_IS_VARIANT ;
BIND_VMETHOD ( get_drag_data ) ;
2017-09-10 15:37:49 +02:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " can_drop_data " , PropertyInfo ( Variant : : VECTOR2 , " position " ) , PropertyInfo ( Variant : : NIL , " data " ) ) ) ;
BIND_VMETHOD ( MethodInfo ( " drop_data " , PropertyInfo ( Variant : : VECTOR2 , " position " ) , PropertyInfo ( Variant : : NIL , " data " ) ) ) ;
2020-11-02 17:18:29 +01:00
BIND_VMETHOD ( MethodInfo (
PropertyInfo ( Variant : : OBJECT , " control " , PROPERTY_HINT_RESOURCE_TYPE , " Control " ) ,
" _make_custom_tooltip " , PropertyInfo ( Variant : : STRING , " for_text " ) ) ) ;
2018-07-29 17:46:53 +02:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " _clips_input " ) ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Anchor " , " anchor_ " ) ;
2019-08-22 20:04:24 +02:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anchor_left " , PROPERTY_HINT_RANGE , " 0,1,0.001,or_lesser,or_greater " ) , " _set_anchor " , " get_anchor " , MARGIN_LEFT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anchor_top " , PROPERTY_HINT_RANGE , " 0,1,0.001,or_lesser,or_greater " ) , " _set_anchor " , " get_anchor " , MARGIN_TOP ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anchor_right " , PROPERTY_HINT_RANGE , " 0,1,0.001,or_lesser,or_greater " ) , " _set_anchor " , " get_anchor " , MARGIN_RIGHT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : REAL , " anchor_bottom " , PROPERTY_HINT_RANGE , " 0,1,0.001,or_lesser,or_greater " ) , " _set_anchor " , " get_anchor " , MARGIN_BOTTOM ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Margin " , " margin_ " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : INT , " margin_left " , PROPERTY_HINT_RANGE , " -4096,4096 " ) , " set_margin " , " get_margin " , MARGIN_LEFT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : INT , " margin_top " , PROPERTY_HINT_RANGE , " -4096,4096 " ) , " set_margin " , " get_margin " , MARGIN_TOP ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : INT , " margin_right " , PROPERTY_HINT_RANGE , " -4096,4096 " ) , " set_margin " , " get_margin " , MARGIN_RIGHT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : INT , " margin_bottom " , PROPERTY_HINT_RANGE , " -4096,4096 " ) , " set_margin " , " get_margin " , MARGIN_BOTTOM ) ;
2017-03-05 16:44:50 +01:00
2017-07-06 18:26:39 +02:00
ADD_GROUP ( " Grow Direction " , " grow_ " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " grow_horizontal " , PROPERTY_HINT_ENUM , " Begin,End,Both " ) , " set_h_grow_direction " , " get_h_grow_direction " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " grow_vertical " , PROPERTY_HINT_ENUM , " Begin,End,Both " ) , " set_v_grow_direction " , " get_v_grow_direction " ) ;
2017-07-06 18:26:39 +02:00
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Rect " , " rect_ " ) ;
2019-03-31 18:53:24 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_position " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " _set_position " , " get_position " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_global_position " , PROPERTY_HINT_NONE , " " , 0 ) , " _set_global_position " , " get_global_position " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_size " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_EDITOR ) , " _set_size " , " get_size " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_min_size " ) , " set_custom_minimum_size " , " get_custom_minimum_size " ) ;
2019-09-30 17:13:57 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " rect_rotation " , PROPERTY_HINT_RANGE , " -360,360,0.1,or_lesser,or_greater " ) , " set_rotation_degrees " , " get_rotation_degrees " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_scale " ) , " set_scale " , " get_scale " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : VECTOR2 , " rect_pivot_offset " ) , " set_pivot_offset " , " get_pivot_offset " ) ;
2018-02-19 04:24:05 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " rect_clip_content " ) , " set_clip_contents " , " is_clipping_contents " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Hint " , " hint_ " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " hint_tooltip " , PROPERTY_HINT_MULTILINE_TEXT ) , " set_tooltip " , " _get_tooltip " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Focus " , " focus_ " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTYI ( PropertyInfo ( Variant : : NODE_PATH , " focus_neighbour_left " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_neighbour " , " get_focus_neighbour " , MARGIN_LEFT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : NODE_PATH , " focus_neighbour_top " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_neighbour " , " get_focus_neighbour " , MARGIN_TOP ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : NODE_PATH , " focus_neighbour_right " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_neighbour " , " get_focus_neighbour " , MARGIN_RIGHT ) ;
ADD_PROPERTYI ( PropertyInfo ( Variant : : NODE_PATH , " focus_neighbour_bottom " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_neighbour " , " get_focus_neighbour " , MARGIN_BOTTOM ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : NODE_PATH , " focus_next " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_next " , " get_focus_next " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : NODE_PATH , " focus_previous " , PROPERTY_HINT_NODE_PATH_VALID_TYPES , " Control " ) , " set_focus_previous " , " get_focus_previous " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " focus_mode " , PROPERTY_HINT_ENUM , " None,Click,All " ) , " set_focus_mode " , " get_focus_mode " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Mouse " , " mouse_ " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " mouse_filter " , PROPERTY_HINT_ENUM , " Stop,Pass,Ignore " ) , " set_mouse_filter " , " get_mouse_filter " ) ;
2018-09-13 03:38:39 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " mouse_default_cursor_shape " , PROPERTY_HINT_ENUM , " Arrow,Ibeam,Pointing hand,Cross,Wait,Busy,Drag,Can drop,Forbidden,Vertical resize,Horizontal resize,Secondary diagonal resize,Main diagonal resize,Move,Vertical split,Horizontal split,Help " ) , " set_default_cursor_shape " , " get_default_cursor_shape " ) ;
2017-03-05 16:44:50 +01:00
2021-10-26 18:48:47 +02:00
ADD_GROUP ( " Input " , " input_ " ) ;
2021-03-25 14:02:26 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " input_pass_on_modal_close_click " ) , " set_pass_on_modal_close_click " , " get_pass_on_modal_close_click " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Size Flags " , " size_flags_ " ) ;
2017-07-13 08:50:15 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " size_flags_horizontal " , PROPERTY_HINT_FLAGS , " Fill,Expand,Shrink Center,Shrink End " ) , " set_h_size_flags " , " get_h_size_flags " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " size_flags_vertical " , PROPERTY_HINT_FLAGS , " Fill,Expand,Shrink Center,Shrink End " ) , " set_v_size_flags " , " get_v_size_flags " ) ;
2020-05-06 02:38:15 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : REAL , " size_flags_stretch_ratio " , PROPERTY_HINT_RANGE , " 0,20,0.01,or_greater " ) , " set_stretch_ratio " , " get_stretch_ratio " ) ;
2017-03-05 16:44:50 +01:00
ADD_GROUP ( " Theme " , " " ) ;
2018-11-08 15:30:02 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " theme " , PROPERTY_HINT_RESOURCE_TYPE , " Theme " ) , " set_theme " , " get_theme " ) ;
2022-02-10 22:26:09 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : STRING , " theme_type_variation " , PROPERTY_HINT_ENUM_SUGGESTION ) , " set_theme_type_variation " , " get_theme_type_variation " ) ;
2017-03-05 16:44:50 +01:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( FOCUS_NONE ) ;
BIND_ENUM_CONSTANT ( FOCUS_CLICK ) ;
BIND_ENUM_CONSTANT ( FOCUS_ALL ) ;
2017-03-05 16:44:50 +01:00
BIND_CONSTANT ( NOTIFICATION_RESIZED ) ;
BIND_CONSTANT ( NOTIFICATION_MOUSE_ENTER ) ;
BIND_CONSTANT ( NOTIFICATION_MOUSE_EXIT ) ;
BIND_CONSTANT ( NOTIFICATION_FOCUS_ENTER ) ;
BIND_CONSTANT ( NOTIFICATION_FOCUS_EXIT ) ;
BIND_CONSTANT ( NOTIFICATION_THEME_CHANGED ) ;
BIND_CONSTANT ( NOTIFICATION_MODAL_CLOSE ) ;
2018-02-27 16:37:20 +01:00
BIND_CONSTANT ( NOTIFICATION_SCROLL_BEGIN ) ;
BIND_CONSTANT ( NOTIFICATION_SCROLL_END ) ;
2017-03-05 16:44:50 +01:00
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( CURSOR_ARROW ) ;
BIND_ENUM_CONSTANT ( CURSOR_IBEAM ) ;
BIND_ENUM_CONSTANT ( CURSOR_POINTING_HAND ) ;
BIND_ENUM_CONSTANT ( CURSOR_CROSS ) ;
BIND_ENUM_CONSTANT ( CURSOR_WAIT ) ;
BIND_ENUM_CONSTANT ( CURSOR_BUSY ) ;
BIND_ENUM_CONSTANT ( CURSOR_DRAG ) ;
BIND_ENUM_CONSTANT ( CURSOR_CAN_DROP ) ;
BIND_ENUM_CONSTANT ( CURSOR_FORBIDDEN ) ;
BIND_ENUM_CONSTANT ( CURSOR_VSIZE ) ;
BIND_ENUM_CONSTANT ( CURSOR_HSIZE ) ;
BIND_ENUM_CONSTANT ( CURSOR_BDIAGSIZE ) ;
BIND_ENUM_CONSTANT ( CURSOR_FDIAGSIZE ) ;
BIND_ENUM_CONSTANT ( CURSOR_MOVE ) ;
BIND_ENUM_CONSTANT ( CURSOR_VSPLIT ) ;
BIND_ENUM_CONSTANT ( CURSOR_HSPLIT ) ;
BIND_ENUM_CONSTANT ( CURSOR_HELP ) ;
BIND_ENUM_CONSTANT ( PRESET_TOP_LEFT ) ;
BIND_ENUM_CONSTANT ( PRESET_TOP_RIGHT ) ;
BIND_ENUM_CONSTANT ( PRESET_BOTTOM_LEFT ) ;
BIND_ENUM_CONSTANT ( PRESET_BOTTOM_RIGHT ) ;
BIND_ENUM_CONSTANT ( PRESET_CENTER_LEFT ) ;
BIND_ENUM_CONSTANT ( PRESET_CENTER_TOP ) ;
BIND_ENUM_CONSTANT ( PRESET_CENTER_RIGHT ) ;
BIND_ENUM_CONSTANT ( PRESET_CENTER_BOTTOM ) ;
BIND_ENUM_CONSTANT ( PRESET_CENTER ) ;
BIND_ENUM_CONSTANT ( PRESET_LEFT_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_TOP_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_RIGHT_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_BOTTOM_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_VCENTER_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_HCENTER_WIDE ) ;
BIND_ENUM_CONSTANT ( PRESET_WIDE ) ;
2017-09-19 22:39:19 +02:00
BIND_ENUM_CONSTANT ( PRESET_MODE_MINSIZE ) ;
BIND_ENUM_CONSTANT ( PRESET_MODE_KEEP_WIDTH ) ;
2017-10-21 20:58:02 +02:00
BIND_ENUM_CONSTANT ( PRESET_MODE_KEEP_HEIGHT ) ;
2017-09-19 22:39:19 +02:00
BIND_ENUM_CONSTANT ( PRESET_MODE_KEEP_SIZE ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( SIZE_FILL ) ;
2017-10-21 20:58:02 +02:00
BIND_ENUM_CONSTANT ( SIZE_EXPAND ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( SIZE_EXPAND_FILL ) ;
BIND_ENUM_CONSTANT ( SIZE_SHRINK_CENTER ) ;
BIND_ENUM_CONSTANT ( SIZE_SHRINK_END ) ;
BIND_ENUM_CONSTANT ( MOUSE_FILTER_STOP ) ;
BIND_ENUM_CONSTANT ( MOUSE_FILTER_PASS ) ;
BIND_ENUM_CONSTANT ( MOUSE_FILTER_IGNORE ) ;
BIND_ENUM_CONSTANT ( GROW_DIRECTION_BEGIN ) ;
BIND_ENUM_CONSTANT ( GROW_DIRECTION_END ) ;
2018-02-12 04:58:39 +01:00
BIND_ENUM_CONSTANT ( GROW_DIRECTION_BOTH ) ;
2017-08-20 17:45:01 +02:00
BIND_ENUM_CONSTANT ( ANCHOR_BEGIN ) ;
BIND_ENUM_CONSTANT ( ANCHOR_END ) ;
2017-08-16 00:48:38 +02:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " resized " ) ) ;
2018-09-01 22:03:28 +02:00
ADD_SIGNAL ( MethodInfo ( " gui_input " , PropertyInfo ( Variant : : OBJECT , " event " , PROPERTY_HINT_RESOURCE_TYPE , " InputEvent " ) ) ) ;
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " mouse_entered " ) ) ;
ADD_SIGNAL ( MethodInfo ( " mouse_exited " ) ) ;
ADD_SIGNAL ( MethodInfo ( " focus_entered " ) ) ;
ADD_SIGNAL ( MethodInfo ( " focus_exited " ) ) ;
ADD_SIGNAL ( MethodInfo ( " size_flags_changed " ) ) ;
ADD_SIGNAL ( MethodInfo ( " minimum_size_changed " ) ) ;
ADD_SIGNAL ( MethodInfo ( " modal_closed " ) ) ;
2017-03-14 00:30:40 +01:00
2017-08-29 07:15:46 +02:00
BIND_VMETHOD ( MethodInfo ( Variant : : BOOL , " has_point " , PropertyInfo ( Variant : : VECTOR2 , " point " ) ) ) ;
2014-02-10 02:10:30 +01:00
}
2021-10-04 16:44:53 +02:00
2014-02-10 02:10:30 +01:00
Control : : Control ( ) {
2021-05-04 16:00:45 +02:00
data . parent = nullptr ;
2016-01-17 02:41:10 +01:00
2017-03-05 16:44:50 +01:00
data . mouse_filter = MOUSE_FILTER_STOP ;
2017-11-22 09:43:40 +01:00
data . pass_on_modal_close_click = true ;
2014-02-10 02:10:30 +01:00
2021-05-04 16:00:45 +02:00
data . SI = nullptr ;
data . MI = nullptr ;
data . RI = nullptr ;
data . theme_owner = nullptr ;
2017-03-05 16:44:50 +01:00
data . modal_exclusive = false ;
2014-02-10 02:10:30 +01:00
data . default_cursor = CURSOR_ARROW ;
2017-03-05 16:44:50 +01:00
data . h_size_flags = SIZE_FILL ;
data . v_size_flags = SIZE_FILL ;
data . expand = 1 ;
data . rotation = 0 ;
2021-05-04 16:00:45 +02:00
data . parent_canvas_item = nullptr ;
2017-03-05 16:44:50 +01:00
data . scale = Vector2 ( 1 , 1 ) ;
data . drag_owner = 0 ;
data . modal_frame = 0 ;
data . block_minimum_size_adjust = false ;
data . disable_visibility_clip = false ;
2017-07-06 18:26:39 +02:00
data . h_grow = GROW_DIRECTION_END ;
data . v_grow = GROW_DIRECTION_END ;
2018-05-15 22:12:35 +02:00
data . minimum_size_valid = false ;
data . updating_last_minimum_size = false ;
2017-03-05 16:44:50 +01:00
data . clip_contents = false ;
for ( int i = 0 ; i < 4 ; i + + ) {
data . anchor [ i ] = ANCHOR_BEGIN ;
data . margin [ i ] = 0 ;
}
data . focus_mode = FOCUS_NONE ;
data . modal_prev_focus_owner = 0 ;
2022-11-09 16:53:23 +01:00
set_physics_interpolation_mode ( Node : : PHYSICS_INTERPOLATION_MODE_OFF ) ;
2017-03-05 16:44:50 +01:00
}
Control : : ~ Control ( ) {
2014-02-10 02:10:30 +01:00
}