Add type variations to Theme
This commit is contained in:
parent
30d4732623
commit
4ee0e6ddf5
18 changed files with 757 additions and 199 deletions
|
@ -509,6 +509,7 @@ void register_global_constants() {
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NONE);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NONE);
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM);
|
||||||
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ENUM_SUGGESTION);
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_EXP_EASING);
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LENGTH);
|
||||||
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL);
|
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_KEY_ACCEL);
|
||||||
|
|
|
@ -60,6 +60,7 @@ enum PropertyHint {
|
||||||
PROPERTY_HINT_NONE, ///< no hint provided.
|
PROPERTY_HINT_NONE, ///< no hint provided.
|
||||||
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range.
|
PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range.
|
||||||
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
|
PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
|
||||||
|
PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc"
|
||||||
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
|
PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "full" to also include in/out. (ie: "attenuation,inout")
|
||||||
PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
|
PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
|
||||||
PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
|
PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
|
||||||
|
|
|
@ -2415,67 +2415,71 @@
|
||||||
<constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_ENUM" value="2" enum="PropertyHint">
|
||||||
Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
|
Hints that an integer, float or string property is an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_EXP_EASING" value="3" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_ENUM_SUGGESTION" value="3" enum="PropertyHint">
|
||||||
|
Hints that a string property is can be an enumerated value to pick in a list specified via a hint string such as [code]"Hello,Something,Else"[/code].
|
||||||
|
Unlike [constant PROPERTY_HINT_ENUM] a property with this hint still accepts arbitrary values and can be empty. The list of values serves to suggest possible values.
|
||||||
|
</constant>
|
||||||
|
<constant name="PROPERTY_HINT_EXP_EASING" value="4" enum="PropertyHint">
|
||||||
Hints that a float property should be edited via an exponential easing function. The hint string can include [code]"attenuation"[/code] to flip the curve horizontally and/or [code]"inout"[/code] to also include in/out easing.
|
Hints that a float property should be edited via an exponential easing function. The hint string can include [code]"attenuation"[/code] to flip the curve horizontally and/or [code]"inout"[/code] to also include in/out easing.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LENGTH" value="4" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint">
|
||||||
Deprecated hint, unused.
|
Deprecated hint, unused.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_KEY_ACCEL" value="5" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint">
|
||||||
Deprecated hint, unused.
|
Deprecated hint, unused.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_FLAGS" value="6" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
|
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="7" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 2D render layers.
|
Hints that an integer property is a bitmask using the optionally named 2D render layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="8" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
|
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="9" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_2D_NAVIGATION" value="10" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
|
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 3D render layers.
|
Hints that an integer property is a bitmask using the optionally named 3D render layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
|
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="12" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_LAYERS_3D_NAVIGATION" value="13" enum="PropertyHint">
|
||||||
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
|
Hints that an integer property is a bitmask using the optionally named 2D navigation layers.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_FILE" value="14" enum="PropertyHint">
|
||||||
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
|
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_DIR" value="15" enum="PropertyHint">
|
||||||
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
|
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_GLOBAL_FILE" value="16" enum="PropertyHint">
|
||||||
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
|
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_GLOBAL_DIR" value="17" enum="PropertyHint">
|
||||||
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
|
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_RESOURCE_TYPE" value="18" enum="PropertyHint">
|
||||||
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
|
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_MULTILINE_TEXT" value="19" enum="PropertyHint">
|
||||||
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
|
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="20" enum="PropertyHint">
|
||||||
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
|
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="21" enum="PropertyHint">
|
||||||
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
|
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="22" enum="PropertyHint">
|
||||||
Hints that an image is compressed using lossy compression.
|
Hints that an image is compressed using lossy compression.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="23" enum="PropertyHint">
|
||||||
Hints that an image is compressed using lossless compression.
|
Hints that an image is compressed using lossless compression.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="PROPERTY_HINT_TYPE_STRING" value="24" enum="PropertyHint">
|
<constant name="PROPERTY_HINT_TYPE_STRING" value="25" enum="PropertyHint">
|
||||||
Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance:
|
Hint that a property represents a particular type. If a property is [constant TYPE_STRING], allows to set a type from the create dialog. If you need to create an [Array] to contain elements of a specific type, the [code]hint_string[/code] must encode nested types using [code]":"[/code] and [code]"/"[/code] for specifying [Resource] types. For instance:
|
||||||
[codeblock]
|
[codeblock]
|
||||||
hint_string = "%s:" % [TYPE_INT] # Array of inteters.
|
hint_string = "%s:" % [TYPE_INT] # Array of inteters.
|
||||||
|
|
|
@ -1164,8 +1164,9 @@
|
||||||
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
|
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
|
||||||
The [Theme] resource this node and all its [Control] children use. If a child node has its own [Theme] resource set, theme items are merged with child's definitions having higher priority.
|
The [Theme] resource this node and all its [Control] children use. If a child node has its own [Theme] resource set, theme items are merged with child's definitions having higher priority.
|
||||||
</member>
|
</member>
|
||||||
<member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="&""">
|
<member name="theme_type_variation" type="StringName" setter="set_theme_type_variation" getter="get_theme_type_variation" default="&""">
|
||||||
The type name used by this [Control] to look up its own theme items. By default, the class name of the node is used (e.g. [code]Button[/code] for the [Button] control), as well as the class names of all parent classes (in order of inheritance). Setting this property gives the highest priority to the type of the specified name, then falls back on the class names.
|
The name of a theme type variation used by this [Control] to look up its own theme items. When empty, the class name of the node is used (e.g. [code]Button[/code] for the [Button] control), as well as the class names of all parent classes (in order of inheritance).
|
||||||
|
When set, this property gives the highest priority to the type of the specified name. This type can in turn extend another type, forming a dependency chain. See [method Theme.set_type_variation]. If the theme item cannot be found using this type or its base types, lookup falls back on the class names.
|
||||||
[b]Note:[/b] To look up [Control]'s own items use various [code]get_theme_*[/code] methods without specifying [code]theme_type[/code].
|
[b]Note:[/b] To look up [Control]'s own items use various [code]get_theme_*[/code] methods without specifying [code]theme_type[/code].
|
||||||
[b]Note:[/b] Theme items are looked for in the tree order, from branch to root, where each [Control] node is checked for its [member theme] property. The earliest match against any type/class name is returned. The project-level Theme and the default Theme are checked last.
|
[b]Note:[/b] Theme items are looked for in the tree order, from branch to root, where each [Control] node is checked for its [member theme] property. The earliest match against any type/class name is returned. The project-level Theme and the default Theme are checked last.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -97,6 +97,15 @@
|
||||||
Clears the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]theme_type[/code].
|
Clears the theme item of [code]data_type[/code] at [code]name[/code] if the theme has [code]theme_type[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="clear_type_variation">
|
||||||
|
<return type="void">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="theme_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Unmarks [code]theme_type[/code] as being a variation of any other type.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="copy_default_theme">
|
<method name="copy_default_theme">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
@ -319,6 +328,24 @@
|
||||||
Returns all the theme types as a [PackedStringArray] filled with unique type names, for use in other [code]get_*[/code] functions of this theme.
|
Returns all the theme types as a [PackedStringArray] filled with unique type names, for use in other [code]get_*[/code] functions of this theme.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_type_variation_base" qualifiers="const">
|
||||||
|
<return type="StringName">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="theme_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Returns the base theme type if [code]theme_type[/code] is a valid variation type. Returns an empty string otherwise.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="get_type_variation_list" qualifiers="const">
|
||||||
|
<return type="PackedStringArray">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="base_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Returns a list of all variation for the given [code]base_type[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="has_color" qualifiers="const">
|
<method name="has_color" qualifiers="const">
|
||||||
<return type="bool">
|
<return type="bool">
|
||||||
</return>
|
</return>
|
||||||
|
@ -405,6 +432,17 @@
|
||||||
Returns [code]false[/code] if the theme does not have [code]theme_type[/code].
|
Returns [code]false[/code] if the theme does not have [code]theme_type[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="is_type_variation" qualifiers="const">
|
||||||
|
<return type="bool">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="theme_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<argument index="1" name="base_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if [code]theme_type[/code] is marked as a variation of [code]base_type[/code] in this theme.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="rename_color">
|
<method name="rename_color">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
@ -599,6 +637,20 @@
|
||||||
Creates [code]theme_type[/code] if the theme does not have it.
|
Creates [code]theme_type[/code] if the theme does not have it.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="set_type_variation">
|
||||||
|
<return type="void">
|
||||||
|
</return>
|
||||||
|
<argument index="0" name="theme_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<argument index="1" name="base_type" type="StringName">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Marks [code]theme_type[/code] as being a variation of [code]base_type[/code].
|
||||||
|
This adds [code]theme_type[/code] as a suggested option for [member Control.theme_type_variation] on a [Control] that is of the [code]base_type[/code] class.
|
||||||
|
Variations can also be nested, i.e. [code]base_type[/code] can be another variation. If a chain of variations ends with a [code]base_type[/code] matching a class of a [Control], the whole chain is going to be suggested as options.
|
||||||
|
Note: Suggestions only show up if this [Theme] is set as the project default theme. See [member ProjectSettings.gui/theme/custom].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
<members>
|
<members>
|
||||||
<member name="default_font" type="Font" setter="set_default_font" getter="get_default_font">
|
<member name="default_font" type="Font" setter="set_default_font" getter="get_default_font">
|
||||||
|
|
|
@ -347,7 +347,7 @@
|
||||||
</member>
|
</member>
|
||||||
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
|
<member name="theme" type="Theme" setter="set_theme" getter="get_theme">
|
||||||
</member>
|
</member>
|
||||||
<member name="theme_custom_type" type="StringName" setter="set_theme_custom_type" getter="get_theme_custom_type" default="&""">
|
<member name="theme_type_variation" type="StringName" setter="set_theme_type_variation" getter="get_theme_type_variation" default="&""">
|
||||||
</member>
|
</member>
|
||||||
<member name="title" type="String" setter="set_title" getter="get_title" default="""">
|
<member name="title" type="String" setter="set_title" getter="get_title" default="""">
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -180,44 +180,150 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() {
|
||||||
|
|
||||||
///////////////////// TEXT ENUM /////////////////////////
|
///////////////////// TEXT ENUM /////////////////////////
|
||||||
|
|
||||||
void EditorPropertyTextEnum::_option_selected(int p_which) {
|
void EditorPropertyTextEnum::_emit_changed_value(String p_string) {
|
||||||
if (string_name) {
|
if (string_name) {
|
||||||
emit_changed(get_edited_property(), StringName(options->get_item_text(p_which)));
|
emit_changed(get_edited_property(), StringName(p_string));
|
||||||
} else {
|
} else {
|
||||||
emit_changed(get_edited_property(), options->get_item_text(p_which));
|
emit_changed(get_edited_property(), p_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorPropertyTextEnum::_option_selected(int p_which) {
|
||||||
|
_emit_changed_value(option_button->get_item_text(p_which));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyTextEnum::_edit_custom_value() {
|
||||||
|
default_layout->hide();
|
||||||
|
edit_custom_layout->show();
|
||||||
|
custom_value_edit->grab_focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyTextEnum::_custom_value_submitted(String p_value) {
|
||||||
|
edit_custom_layout->hide();
|
||||||
|
default_layout->show();
|
||||||
|
|
||||||
|
_emit_changed_value(p_value.strip_edges());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyTextEnum::_custom_value_accepted() {
|
||||||
|
String new_value = custom_value_edit->get_text().strip_edges();
|
||||||
|
_custom_value_submitted(new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorPropertyTextEnum::_custom_value_cancelled() {
|
||||||
|
custom_value_edit->set_text(get_edited_object()->get(get_edited_property()));
|
||||||
|
|
||||||
|
edit_custom_layout->hide();
|
||||||
|
default_layout->show();
|
||||||
|
}
|
||||||
|
|
||||||
void EditorPropertyTextEnum::update_property() {
|
void EditorPropertyTextEnum::update_property() {
|
||||||
String which = get_edited_object()->get(get_edited_property());
|
String current_value = get_edited_object()->get(get_edited_property());
|
||||||
for (int i = 0; i < options->get_item_count(); i++) {
|
int default_option = options.find(current_value);
|
||||||
String t = options->get_item_text(i);
|
|
||||||
if (t == which) {
|
// The list can change in the loose mode.
|
||||||
options->select(i);
|
if (loose_mode) {
|
||||||
return;
|
custom_value_edit->set_text(current_value);
|
||||||
|
option_button->clear();
|
||||||
|
|
||||||
|
// Manually entered value.
|
||||||
|
if (default_option < 0 && !current_value.is_empty()) {
|
||||||
|
option_button->add_item(current_value, options.size() + 1001);
|
||||||
|
option_button->select(0);
|
||||||
|
|
||||||
|
option_button->add_separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add an explicit empty value for clearing the property.
|
||||||
|
option_button->add_item("", options.size() + 1000);
|
||||||
|
|
||||||
|
for (int i = 0; i < options.size(); i++) {
|
||||||
|
option_button->add_item(options[i], i);
|
||||||
|
if (options[i] == current_value) {
|
||||||
|
option_button->select(option_button->get_item_count() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
option_button->select(default_option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyTextEnum::setup(const Vector<String> &p_options, bool p_string_name) {
|
void EditorPropertyTextEnum::setup(const Vector<String> &p_options, bool p_string_name, bool p_loose_mode) {
|
||||||
for (int i = 0; i < p_options.size(); i++) {
|
|
||||||
options->add_item(p_options[i], i);
|
|
||||||
}
|
|
||||||
string_name = p_string_name;
|
string_name = p_string_name;
|
||||||
|
loose_mode = p_loose_mode;
|
||||||
|
|
||||||
|
options.clear();
|
||||||
|
|
||||||
|
if (loose_mode) {
|
||||||
|
// Add an explicit empty value for clearing the property in the loose mode.
|
||||||
|
option_button->add_item("", options.size() + 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < p_options.size(); i++) {
|
||||||
|
options.append(p_options[i]);
|
||||||
|
option_button->add_item(p_options[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loose_mode) {
|
||||||
|
edit_button->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyTextEnum::_bind_methods() {
|
void EditorPropertyTextEnum::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorPropertyTextEnum::EditorPropertyTextEnum() {
|
void EditorPropertyTextEnum::_notification(int p_what) {
|
||||||
options = memnew(OptionButton);
|
switch (p_what) {
|
||||||
options->set_clip_text(true);
|
case NOTIFICATION_ENTER_TREE:
|
||||||
options->set_flat(true);
|
case NOTIFICATION_THEME_CHANGED:
|
||||||
string_name = false;
|
edit_button->set_icon(get_theme_icon("Edit", "EditorIcons"));
|
||||||
|
accept_button->set_icon(get_theme_icon("ImportCheck", "EditorIcons"));
|
||||||
|
cancel_button->set_icon(get_theme_icon("ImportFail", "EditorIcons"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
add_child(options);
|
EditorPropertyTextEnum::EditorPropertyTextEnum() {
|
||||||
add_focusable(options);
|
default_layout = memnew(HBoxContainer);
|
||||||
options->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
|
add_child(default_layout);
|
||||||
|
|
||||||
|
edit_custom_layout = memnew(HBoxContainer);
|
||||||
|
edit_custom_layout->hide();
|
||||||
|
add_child(edit_custom_layout);
|
||||||
|
|
||||||
|
option_button = memnew(OptionButton);
|
||||||
|
option_button->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
option_button->set_clip_text(true);
|
||||||
|
option_button->set_flat(true);
|
||||||
|
default_layout->add_child(option_button);
|
||||||
|
option_button->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
|
||||||
|
|
||||||
|
edit_button = memnew(Button);
|
||||||
|
edit_button->set_flat(true);
|
||||||
|
edit_button->hide();
|
||||||
|
default_layout->add_child(edit_button);
|
||||||
|
edit_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_edit_custom_value));
|
||||||
|
|
||||||
|
custom_value_edit = memnew(LineEdit);
|
||||||
|
custom_value_edit->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
edit_custom_layout->add_child(custom_value_edit);
|
||||||
|
custom_value_edit->connect("text_submitted", callable_mp(this, &EditorPropertyTextEnum::_custom_value_submitted));
|
||||||
|
|
||||||
|
accept_button = memnew(Button);
|
||||||
|
accept_button->set_flat(true);
|
||||||
|
edit_custom_layout->add_child(accept_button);
|
||||||
|
accept_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_custom_value_accepted));
|
||||||
|
|
||||||
|
cancel_button = memnew(Button);
|
||||||
|
cancel_button->set_flat(true);
|
||||||
|
edit_custom_layout->add_child(cancel_button);
|
||||||
|
cancel_button->connect("pressed", callable_mp(this, &EditorPropertyTextEnum::_custom_value_cancelled));
|
||||||
|
|
||||||
|
add_focusable(option_button);
|
||||||
|
add_focusable(edit_button);
|
||||||
|
add_focusable(custom_value_edit);
|
||||||
|
add_focusable(accept_button);
|
||||||
|
add_focusable(cancel_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////// PATH /////////////////////////
|
///////////////////// PATH /////////////////////////
|
||||||
|
@ -2902,10 +3008,10 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Variant::STRING: {
|
case Variant::STRING: {
|
||||||
if (p_hint == PROPERTY_HINT_ENUM) {
|
if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
|
||||||
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
|
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
|
||||||
Vector<String> options = p_hint_text.split(",");
|
Vector<String> options = p_hint_text.split(",", false);
|
||||||
editor->setup(options);
|
editor->setup(options, false, (p_hint == PROPERTY_HINT_ENUM_SUGGESTION));
|
||||||
return editor;
|
return editor;
|
||||||
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
|
} else if (p_hint == PROPERTY_HINT_MULTILINE_TEXT) {
|
||||||
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
|
EditorPropertyMultilineText *editor = memnew(EditorPropertyMultilineText);
|
||||||
|
@ -3063,10 +3169,10 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
|
||||||
return editor;
|
return editor;
|
||||||
} break;
|
} break;
|
||||||
case Variant::STRING_NAME: {
|
case Variant::STRING_NAME: {
|
||||||
if (p_hint == PROPERTY_HINT_ENUM) {
|
if (p_hint == PROPERTY_HINT_ENUM || p_hint == PROPERTY_HINT_ENUM_SUGGESTION) {
|
||||||
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
|
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
|
||||||
Vector<String> options = p_hint_text.split(",");
|
Vector<String> options = p_hint_text.split(",", false);
|
||||||
editor->setup(options, true);
|
editor->setup(options, true, (p_hint == PROPERTY_HINT_ENUM_SUGGESTION));
|
||||||
return editor;
|
return editor;
|
||||||
} else {
|
} else {
|
||||||
EditorPropertyText *editor = memnew(EditorPropertyText);
|
EditorPropertyText *editor = memnew(EditorPropertyText);
|
||||||
|
|
|
@ -91,16 +91,35 @@ public:
|
||||||
|
|
||||||
class EditorPropertyTextEnum : public EditorProperty {
|
class EditorPropertyTextEnum : public EditorProperty {
|
||||||
GDCLASS(EditorPropertyTextEnum, EditorProperty);
|
GDCLASS(EditorPropertyTextEnum, EditorProperty);
|
||||||
OptionButton *options;
|
|
||||||
|
|
||||||
|
HBoxContainer *default_layout;
|
||||||
|
HBoxContainer *edit_custom_layout;
|
||||||
|
|
||||||
|
OptionButton *option_button;
|
||||||
|
Button *edit_button;
|
||||||
|
|
||||||
|
LineEdit *custom_value_edit;
|
||||||
|
Button *accept_button;
|
||||||
|
Button *cancel_button;
|
||||||
|
|
||||||
|
Vector<String> options;
|
||||||
|
bool string_name = false;
|
||||||
|
bool loose_mode = false;
|
||||||
|
|
||||||
|
void _emit_changed_value(String p_string);
|
||||||
void _option_selected(int p_which);
|
void _option_selected(int p_which);
|
||||||
bool string_name;
|
|
||||||
|
void _edit_custom_value();
|
||||||
|
void _custom_value_submitted(String p_value);
|
||||||
|
void _custom_value_accepted();
|
||||||
|
void _custom_value_cancelled();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setup(const Vector<String> &p_options, bool p_string_name = false);
|
void setup(const Vector<String> &p_options, bool p_string_name = false, bool p_loose_mode = false);
|
||||||
virtual void update_property() override;
|
virtual void update_property() override;
|
||||||
EditorPropertyTextEnum();
|
EditorPropertyTextEnum();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1004,6 +1004,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
|
||||||
// LineEdit
|
// LineEdit
|
||||||
|
|
||||||
Ref<StyleBoxFlat> style_line_edit = style_widget->duplicate();
|
Ref<StyleBoxFlat> style_line_edit = style_widget->duplicate();
|
||||||
|
// The original style_widget style has an extra 1 pixel offset that makes LineEdits not align with Buttons,
|
||||||
|
// so this compensates for that.
|
||||||
|
style_line_edit->set_default_margin(SIDE_TOP, style_line_edit->get_default_margin(SIDE_TOP) - 1 * EDSCALE);
|
||||||
// Add a bottom line to make LineEdits more visible, especially in sectioned inspectors
|
// Add a bottom line to make LineEdits more visible, especially in sectioned inspectors
|
||||||
// such as the Project Settings.
|
// such as the Project Settings.
|
||||||
style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
|
style_line_edit->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE));
|
||||||
|
|
|
@ -1943,6 +1943,117 @@ ThemeItemEditorDialog::ThemeItemEditorDialog() {
|
||||||
confirm_closing_dialog->connect("confirmed", callable_mp(this, &ThemeItemEditorDialog::_close_dialog));
|
confirm_closing_dialog->connect("confirmed", callable_mp(this, &ThemeItemEditorDialog::_close_dialog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_dialog_about_to_show() {
|
||||||
|
add_type_filter->set_text("");
|
||||||
|
add_type_filter->grab_focus();
|
||||||
|
|
||||||
|
_update_add_type_options();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::ok_pressed() {
|
||||||
|
emit_signal("type_selected", add_type_filter->get_text().strip_edges());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_update_add_type_options(const String &p_filter) {
|
||||||
|
add_type_options->clear();
|
||||||
|
|
||||||
|
List<StringName> names;
|
||||||
|
Theme::get_default()->get_type_list(&names);
|
||||||
|
if (include_own_types) {
|
||||||
|
edited_theme->get_type_list(&names);
|
||||||
|
}
|
||||||
|
names.sort_custom<StringName::AlphCompare>();
|
||||||
|
|
||||||
|
Vector<StringName> unique_names;
|
||||||
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
|
// Filter out undesired values.
|
||||||
|
if (!p_filter.is_subsequence_ofi(String(E->get()))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip duplicate values.
|
||||||
|
if (unique_names.has(E->get())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
unique_names.append(E->get());
|
||||||
|
|
||||||
|
Ref<Texture2D> item_icon;
|
||||||
|
if (E->get() == "") {
|
||||||
|
item_icon = get_theme_icon("NodeDisabled", "EditorIcons");
|
||||||
|
} else {
|
||||||
|
item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_type_options->add_item(E->get(), item_icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_add_type_filter_cbk(const String &p_value) {
|
||||||
|
_update_add_type_options(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_add_type_options_cbk(int p_index) {
|
||||||
|
add_type_filter->set_text(add_type_options->get_item_text(p_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_add_type_dialog_entered(const String &p_value) {
|
||||||
|
emit_signal("type_selected", p_value.strip_edges());
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_add_type_dialog_activated(int p_index) {
|
||||||
|
emit_signal("type_selected", add_type_options->get_item_text(p_index));
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_notification(int p_what) {
|
||||||
|
switch (p_what) {
|
||||||
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
connect("about_to_popup", callable_mp(this, &ThemeTypeDialog::_dialog_about_to_show));
|
||||||
|
[[fallthrough]];
|
||||||
|
}
|
||||||
|
case NOTIFICATION_THEME_CHANGED: {
|
||||||
|
_update_add_type_options();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::_bind_methods() {
|
||||||
|
ADD_SIGNAL(MethodInfo("type_selected", PropertyInfo(Variant::STRING, "type_name")));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::set_edited_theme(const Ref<Theme> &p_theme) {
|
||||||
|
edited_theme = p_theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeDialog::set_include_own_types(bool p_enable) {
|
||||||
|
include_own_types = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeTypeDialog::ThemeTypeDialog() {
|
||||||
|
VBoxContainer *add_type_vb = memnew(VBoxContainer);
|
||||||
|
add_child(add_type_vb);
|
||||||
|
|
||||||
|
Label *add_type_filter_label = memnew(Label);
|
||||||
|
add_type_filter_label->set_text(TTR("Name:"));
|
||||||
|
add_type_vb->add_child(add_type_filter_label);
|
||||||
|
|
||||||
|
add_type_filter = memnew(LineEdit);
|
||||||
|
add_type_vb->add_child(add_type_filter);
|
||||||
|
add_type_filter->connect("text_changed", callable_mp(this, &ThemeTypeDialog::_add_type_filter_cbk));
|
||||||
|
add_type_filter->connect("text_submitted", callable_mp(this, &ThemeTypeDialog::_add_type_dialog_entered));
|
||||||
|
|
||||||
|
Label *add_type_options_label = memnew(Label);
|
||||||
|
add_type_options_label->set_text(TTR("Node Types:"));
|
||||||
|
add_type_vb->add_child(add_type_options_label);
|
||||||
|
|
||||||
|
add_type_options = memnew(ItemList);
|
||||||
|
add_type_options->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
add_type_vb->add_child(add_type_options);
|
||||||
|
add_type_options->connect("item_selected", callable_mp(this, &ThemeTypeDialog::_add_type_options_cbk));
|
||||||
|
add_type_options->connect("item_activated", callable_mp(this, &ThemeTypeDialog::_add_type_dialog_activated));
|
||||||
|
}
|
||||||
|
|
||||||
VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
|
VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
|
||||||
VBoxContainer *items_tab = memnew(VBoxContainer);
|
VBoxContainer *items_tab = memnew(VBoxContainer);
|
||||||
items_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
|
items_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
|
||||||
|
@ -2048,36 +2159,18 @@ void ThemeTypeEditor::_update_type_list_debounced() {
|
||||||
update_debounce_timer->start();
|
update_debounce_timer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::_update_add_type_options(const String &p_filter) {
|
|
||||||
add_type_options->clear();
|
|
||||||
|
|
||||||
List<StringName> names;
|
|
||||||
Theme::get_default()->get_type_list(&names);
|
|
||||||
names.sort_custom<StringName::AlphCompare>();
|
|
||||||
|
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
|
||||||
if (!p_filter.is_subsequence_ofi(String(E->get()))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<Texture2D> item_icon;
|
|
||||||
if (E->get() == "") {
|
|
||||||
item_icon = get_theme_icon("NodeDisabled", "EditorIcons");
|
|
||||||
} else {
|
|
||||||
item_icon = EditorNode::get_singleton()->get_class_icon(E->get(), "NodeDisabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
add_type_options->add_item(E->get(), item_icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default) {
|
OrderedHashMap<StringName, bool> ThemeTypeEditor::_get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default) {
|
||||||
OrderedHashMap<StringName, bool> items;
|
OrderedHashMap<StringName, bool> items;
|
||||||
List<StringName> names;
|
List<StringName> names;
|
||||||
|
|
||||||
if (include_default) {
|
if (include_default) {
|
||||||
names.clear();
|
names.clear();
|
||||||
(Theme::get_default().operator->()->*get_list_func)(p_type_name, &names);
|
String default_type = p_type_name;
|
||||||
|
if (edited_theme->get_type_variation_base(p_type_name) != StringName()) {
|
||||||
|
default_type = edited_theme->get_type_variation_base(p_type_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
(Theme::get_default().operator->()->*get_list_func)(default_type, &names);
|
||||||
names.sort_custom<StringName::AlphCompare>();
|
names.sort_custom<StringName::AlphCompare>();
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
items[E->get()] = false;
|
items[E->get()] = false;
|
||||||
|
@ -2435,6 +2528,20 @@ void ThemeTypeEditor::_update_type_items() {
|
||||||
stylebox_items_list->add_child(item_control);
|
stylebox_items_list->add_child(item_control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Various type settings.
|
||||||
|
if (ClassDB::class_exists(edited_type)) {
|
||||||
|
type_variation_edit->set_editable(false);
|
||||||
|
type_variation_edit->set_tooltip(TTR("A type associated with a built-in class cannot be marked as a variation of another type."));
|
||||||
|
type_variation_edit->set_text("");
|
||||||
|
type_variation_button->hide();
|
||||||
|
} else {
|
||||||
|
type_variation_edit->set_editable(true);
|
||||||
|
type_variation_edit->set_tooltip("");
|
||||||
|
type_variation_edit->set_text(edited_theme->get_type_variation_base(edited_type));
|
||||||
|
_add_focusable(type_variation_edit);
|
||||||
|
type_variation_button->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::_list_type_selected(int p_index) {
|
void ThemeTypeEditor::_list_type_selected(int p_index) {
|
||||||
|
@ -2443,34 +2550,18 @@ void ThemeTypeEditor::_list_type_selected(int p_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_button_cbk() {
|
void ThemeTypeEditor::_add_type_button_cbk() {
|
||||||
|
add_type_mode = ADD_THEME_TYPE;
|
||||||
|
add_type_dialog->set_title(TTR("Add Item Type"));
|
||||||
|
add_type_dialog->set_include_own_types(false);
|
||||||
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
|
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
|
||||||
add_type_filter->grab_focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_filter_cbk(const String &p_value) {
|
|
||||||
_update_add_type_options(p_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_options_cbk(int p_index) {
|
|
||||||
add_type_filter->set_text(add_type_options->get_item_text(p_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_dialog_confirmed() {
|
|
||||||
select_type(add_type_filter->get_text().strip_edges());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_dialog_entered(const String &p_value) {
|
|
||||||
select_type(p_value.strip_edges());
|
|
||||||
add_type_dialog->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_type_dialog_activated(int p_index) {
|
|
||||||
select_type(add_type_options->get_item_text(p_index));
|
|
||||||
add_type_dialog->hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::_add_default_type_items() {
|
void ThemeTypeEditor::_add_default_type_items() {
|
||||||
List<StringName> names;
|
List<StringName> names;
|
||||||
|
String default_type = edited_type;
|
||||||
|
if (edited_theme->get_type_variation_base(edited_type) != StringName()) {
|
||||||
|
default_type = edited_theme->get_type_variation_base(edited_type);
|
||||||
|
}
|
||||||
|
|
||||||
updating = true;
|
updating = true;
|
||||||
// Prevent changes from immediatelly being reported while the operation is still ongoing.
|
// Prevent changes from immediatelly being reported while the operation is still ongoing.
|
||||||
|
@ -2478,7 +2569,7 @@ void ThemeTypeEditor::_add_default_type_items() {
|
||||||
|
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_icon_list(edited_type, &names);
|
Theme::get_default()->get_icon_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_icon(E->get(), edited_type)) {
|
if (!edited_theme->has_icon(E->get(), edited_type)) {
|
||||||
edited_theme->set_icon(E->get(), edited_type, Ref<Texture2D>());
|
edited_theme->set_icon(E->get(), edited_type, Ref<Texture2D>());
|
||||||
|
@ -2487,7 +2578,7 @@ void ThemeTypeEditor::_add_default_type_items() {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_stylebox_list(edited_type, &names);
|
Theme::get_default()->get_stylebox_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_stylebox(E->get(), edited_type)) {
|
if (!edited_theme->has_stylebox(E->get(), edited_type)) {
|
||||||
edited_theme->set_stylebox(E->get(), edited_type, Ref<StyleBox>());
|
edited_theme->set_stylebox(E->get(), edited_type, Ref<StyleBox>());
|
||||||
|
@ -2496,7 +2587,7 @@ void ThemeTypeEditor::_add_default_type_items() {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_font_list(edited_type, &names);
|
Theme::get_default()->get_font_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_font(E->get(), edited_type)) {
|
if (!edited_theme->has_font(E->get(), edited_type)) {
|
||||||
edited_theme->set_font(E->get(), edited_type, Ref<Font>());
|
edited_theme->set_font(E->get(), edited_type, Ref<Font>());
|
||||||
|
@ -2505,28 +2596,28 @@ void ThemeTypeEditor::_add_default_type_items() {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_font_size_list(edited_type, &names);
|
Theme::get_default()->get_font_size_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_font_size(E->get(), edited_type)) {
|
if (!edited_theme->has_font_size(E->get(), edited_type)) {
|
||||||
edited_theme->set_font_size(E->get(), edited_type, Theme::get_default()->get_font_size(E->get(), edited_type));
|
edited_theme->set_font_size(E->get(), edited_type, Theme::get_default()->get_font_size(E->get(), default_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_color_list(edited_type, &names);
|
Theme::get_default()->get_color_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_color(E->get(), edited_type)) {
|
if (!edited_theme->has_color(E->get(), edited_type)) {
|
||||||
edited_theme->set_color(E->get(), edited_type, Theme::get_default()->get_color(E->get(), edited_type));
|
edited_theme->set_color(E->get(), edited_type, Theme::get_default()->get_color(E->get(), default_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
names.clear();
|
names.clear();
|
||||||
Theme::get_default()->get_constant_list(edited_type, &names);
|
Theme::get_default()->get_constant_list(default_type, &names);
|
||||||
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
if (!edited_theme->has_constant(E->get(), edited_type)) {
|
if (!edited_theme->has_constant(E->get(), edited_type)) {
|
||||||
edited_theme->set_constant(E->get(), edited_type, Theme::get_default()->get_constant(E->get(), edited_type));
|
edited_theme->set_constant(E->get(), edited_type, Theme::get_default()->get_constant(E->get(), default_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2817,6 +2908,30 @@ void ThemeTypeEditor::_update_stylebox_from_leading() {
|
||||||
edited_theme->_unfreeze_and_propagate_changes();
|
edited_theme->_unfreeze_and_propagate_changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThemeTypeEditor::_type_variation_changed(const String p_value) {
|
||||||
|
if (p_value.is_empty()) {
|
||||||
|
edited_theme->clear_type_variation(edited_type);
|
||||||
|
} else {
|
||||||
|
edited_theme->set_type_variation(edited_type, StringName(p_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeEditor::_add_type_variation_cbk() {
|
||||||
|
add_type_mode = ADD_VARIATION_BASE;
|
||||||
|
add_type_dialog->set_title(TTR("Add Variation Base Type"));
|
||||||
|
add_type_dialog->set_include_own_types(true);
|
||||||
|
add_type_dialog->popup_centered(Size2(560, 420) * EDSCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeTypeEditor::_add_type_dialog_selected(const String p_type_name) {
|
||||||
|
if (add_type_mode == ADD_THEME_TYPE) {
|
||||||
|
select_type(p_type_name);
|
||||||
|
} else if (add_type_mode == ADD_VARIATION_BASE) {
|
||||||
|
_type_variation_changed(p_type_name);
|
||||||
|
_update_type_items();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::_notification(int p_what) {
|
void ThemeTypeEditor::_notification(int p_what) {
|
||||||
switch (p_what) {
|
switch (p_what) {
|
||||||
case NOTIFICATION_ENTER_TREE:
|
case NOTIFICATION_ENTER_TREE:
|
||||||
|
@ -2829,11 +2944,12 @@ void ThemeTypeEditor::_notification(int p_what) {
|
||||||
data_type_tabs->set_tab_icon(3, get_theme_icon("FontSize", "EditorIcons"));
|
data_type_tabs->set_tab_icon(3, get_theme_icon("FontSize", "EditorIcons"));
|
||||||
data_type_tabs->set_tab_icon(4, get_theme_icon("ImageTexture", "EditorIcons"));
|
data_type_tabs->set_tab_icon(4, get_theme_icon("ImageTexture", "EditorIcons"));
|
||||||
data_type_tabs->set_tab_icon(5, get_theme_icon("StyleBoxFlat", "EditorIcons"));
|
data_type_tabs->set_tab_icon(5, get_theme_icon("StyleBoxFlat", "EditorIcons"));
|
||||||
|
data_type_tabs->set_tab_icon(6, get_theme_icon("Tools", "EditorIcons"));
|
||||||
|
|
||||||
data_type_tabs->add_theme_style_override("tab_selected", get_theme_stylebox("tab_selected_odd", "TabContainer"));
|
data_type_tabs->add_theme_style_override("tab_selected", get_theme_stylebox("tab_selected_odd", "TabContainer"));
|
||||||
data_type_tabs->add_theme_style_override("panel", get_theme_stylebox("panel_odd", "TabContainer"));
|
data_type_tabs->add_theme_style_override("panel", get_theme_stylebox("panel_odd", "TabContainer"));
|
||||||
|
|
||||||
_update_add_type_options();
|
type_variation_button->set_icon(get_theme_icon("Add", "EditorIcons"));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2846,6 +2962,8 @@ void ThemeTypeEditor::set_edited_theme(const Ref<Theme> &p_theme) {
|
||||||
edited_theme = p_theme;
|
edited_theme = p_theme;
|
||||||
edited_theme->connect("changed", callable_mp(this, &ThemeTypeEditor::_update_type_list_debounced));
|
edited_theme->connect("changed", callable_mp(this, &ThemeTypeEditor::_update_type_list_debounced));
|
||||||
_update_type_list();
|
_update_type_list();
|
||||||
|
|
||||||
|
add_type_dialog->set_edited_theme(edited_theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeTypeEditor::select_type(String p_type_name) {
|
void ThemeTypeEditor::select_type(String p_type_name) {
|
||||||
|
@ -2892,34 +3010,10 @@ ThemeTypeEditor::ThemeTypeEditor() {
|
||||||
theme_type_list->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_list_type_selected));
|
theme_type_list->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_list_type_selected));
|
||||||
|
|
||||||
add_type_button = memnew(Button);
|
add_type_button = memnew(Button);
|
||||||
add_type_button->set_tooltip(TTR("Add Type"));
|
add_type_button->set_tooltip(TTR("Add a type from a list of available types or create a new one."));
|
||||||
type_list_hb->add_child(add_type_button);
|
type_list_hb->add_child(add_type_button);
|
||||||
add_type_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_button_cbk));
|
add_type_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_button_cbk));
|
||||||
|
|
||||||
add_type_dialog = memnew(ConfirmationDialog);
|
|
||||||
add_type_dialog->set_title(TTR("Add Item Type"));
|
|
||||||
type_list_hb->add_child(add_type_dialog);
|
|
||||||
add_type_dialog->connect("confirmed", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_confirmed));
|
|
||||||
|
|
||||||
VBoxContainer *add_type_vb = memnew(VBoxContainer);
|
|
||||||
add_type_dialog->add_child(add_type_vb);
|
|
||||||
|
|
||||||
Label *add_type_filter_label = memnew(Label);
|
|
||||||
add_type_filter_label->set_text(TTR("Name:"));
|
|
||||||
add_type_vb->add_child(add_type_filter_label);
|
|
||||||
add_type_filter = memnew(LineEdit);
|
|
||||||
add_type_vb->add_child(add_type_filter);
|
|
||||||
add_type_filter->connect("text_changed", callable_mp(this, &ThemeTypeEditor::_add_type_filter_cbk));
|
|
||||||
add_type_filter->connect("text_submitted", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_entered));
|
|
||||||
Label *add_type_options_label = memnew(Label);
|
|
||||||
add_type_options_label->set_text(TTR("Node Types:"));
|
|
||||||
add_type_vb->add_child(add_type_options_label);
|
|
||||||
add_type_options = memnew(ItemList);
|
|
||||||
add_type_options->set_v_size_flags(SIZE_EXPAND_FILL);
|
|
||||||
add_type_vb->add_child(add_type_options);
|
|
||||||
add_type_options->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_add_type_options_cbk));
|
|
||||||
add_type_options->connect("item_activated", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_activated));
|
|
||||||
|
|
||||||
HBoxContainer *type_controls = memnew(HBoxContainer);
|
HBoxContainer *type_controls = memnew(HBoxContainer);
|
||||||
main_vb->add_child(type_controls);
|
main_vb->add_child(type_controls);
|
||||||
|
|
||||||
|
@ -2950,6 +3044,39 @@ ThemeTypeEditor::ThemeTypeEditor() {
|
||||||
icon_items_list = _create_item_list(Theme::DATA_TYPE_ICON);
|
icon_items_list = _create_item_list(Theme::DATA_TYPE_ICON);
|
||||||
stylebox_items_list = _create_item_list(Theme::DATA_TYPE_STYLEBOX);
|
stylebox_items_list = _create_item_list(Theme::DATA_TYPE_STYLEBOX);
|
||||||
|
|
||||||
|
VBoxContainer *type_settings_tab = memnew(VBoxContainer);
|
||||||
|
type_settings_tab->set_custom_minimum_size(Size2(0, 160) * EDSCALE);
|
||||||
|
data_type_tabs->add_child(type_settings_tab);
|
||||||
|
data_type_tabs->set_tab_title(data_type_tabs->get_tab_count() - 1, "");
|
||||||
|
|
||||||
|
ScrollContainer *type_settings_sc = memnew(ScrollContainer);
|
||||||
|
type_settings_sc->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
type_settings_sc->set_enable_h_scroll(false);
|
||||||
|
type_settings_tab->add_child(type_settings_sc);
|
||||||
|
VBoxContainer *type_settings_list = memnew(VBoxContainer);
|
||||||
|
type_settings_list->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||||
|
type_settings_sc->add_child(type_settings_list);
|
||||||
|
|
||||||
|
HBoxContainer *type_variation_hb = memnew(HBoxContainer);
|
||||||
|
type_settings_list->add_child(type_variation_hb);
|
||||||
|
Label *type_variation_label = memnew(Label);
|
||||||
|
type_variation_hb->add_child(type_variation_label);
|
||||||
|
type_variation_label->set_text(TTR("Base Type"));
|
||||||
|
type_variation_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
type_variation_edit = memnew(LineEdit);
|
||||||
|
type_variation_hb->add_child(type_variation_edit);
|
||||||
|
type_variation_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||||
|
type_variation_edit->connect("text_changed", callable_mp(this, &ThemeTypeEditor::_type_variation_changed));
|
||||||
|
type_variation_edit->connect("focus_exited", callable_mp(this, &ThemeTypeEditor::_update_type_items));
|
||||||
|
type_variation_button = memnew(Button);
|
||||||
|
type_variation_hb->add_child(type_variation_button);
|
||||||
|
type_variation_button->set_tooltip(TTR("Select the variation base type from a list of available types."));
|
||||||
|
type_variation_button->connect("pressed", callable_mp(this, &ThemeTypeEditor::_add_type_variation_cbk));
|
||||||
|
|
||||||
|
add_type_dialog = memnew(ThemeTypeDialog);
|
||||||
|
add_child(add_type_dialog);
|
||||||
|
add_type_dialog->connect("type_selected", callable_mp(this, &ThemeTypeEditor::_add_type_dialog_selected));
|
||||||
|
|
||||||
update_debounce_timer = memnew(Timer);
|
update_debounce_timer = memnew(Timer);
|
||||||
update_debounce_timer->set_one_shot(true);
|
update_debounce_timer->set_one_shot(true);
|
||||||
update_debounce_timer->set_wait_time(0.5);
|
update_debounce_timer->set_wait_time(0.5);
|
||||||
|
|
|
@ -263,6 +263,36 @@ public:
|
||||||
ThemeItemEditorDialog();
|
ThemeItemEditorDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ThemeTypeDialog : public ConfirmationDialog {
|
||||||
|
GDCLASS(ThemeTypeDialog, ConfirmationDialog);
|
||||||
|
|
||||||
|
Ref<Theme> edited_theme;
|
||||||
|
bool include_own_types = false;
|
||||||
|
|
||||||
|
LineEdit *add_type_filter;
|
||||||
|
ItemList *add_type_options;
|
||||||
|
|
||||||
|
void _dialog_about_to_show();
|
||||||
|
void ok_pressed() override;
|
||||||
|
|
||||||
|
void _update_add_type_options(const String &p_filter = "");
|
||||||
|
|
||||||
|
void _add_type_filter_cbk(const String &p_value);
|
||||||
|
void _add_type_options_cbk(int p_index);
|
||||||
|
void _add_type_dialog_entered(const String &p_value);
|
||||||
|
void _add_type_dialog_activated(int p_index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set_edited_theme(const Ref<Theme> &p_theme);
|
||||||
|
void set_include_own_types(bool p_enable);
|
||||||
|
|
||||||
|
ThemeTypeDialog();
|
||||||
|
};
|
||||||
|
|
||||||
class ThemeTypeEditor : public MarginContainer {
|
class ThemeTypeEditor : public MarginContainer {
|
||||||
GDCLASS(ThemeTypeEditor, MarginContainer);
|
GDCLASS(ThemeTypeEditor, MarginContainer);
|
||||||
|
|
||||||
|
@ -281,9 +311,6 @@ class ThemeTypeEditor : public MarginContainer {
|
||||||
|
|
||||||
OptionButton *theme_type_list;
|
OptionButton *theme_type_list;
|
||||||
Button *add_type_button;
|
Button *add_type_button;
|
||||||
ConfirmationDialog *add_type_dialog;
|
|
||||||
LineEdit *add_type_filter;
|
|
||||||
ItemList *add_type_options;
|
|
||||||
|
|
||||||
CheckButton *show_default_items_button;
|
CheckButton *show_default_items_button;
|
||||||
|
|
||||||
|
@ -295,13 +322,23 @@ class ThemeTypeEditor : public MarginContainer {
|
||||||
VBoxContainer *icon_items_list;
|
VBoxContainer *icon_items_list;
|
||||||
VBoxContainer *stylebox_items_list;
|
VBoxContainer *stylebox_items_list;
|
||||||
|
|
||||||
|
LineEdit *type_variation_edit;
|
||||||
|
Button *type_variation_button;
|
||||||
|
|
||||||
|
enum TypeDialogMode {
|
||||||
|
ADD_THEME_TYPE,
|
||||||
|
ADD_VARIATION_BASE,
|
||||||
|
};
|
||||||
|
|
||||||
|
TypeDialogMode add_type_mode = ADD_THEME_TYPE;
|
||||||
|
ThemeTypeDialog *add_type_dialog;
|
||||||
|
|
||||||
Vector<Control *> focusables;
|
Vector<Control *> focusables;
|
||||||
Timer *update_debounce_timer;
|
Timer *update_debounce_timer;
|
||||||
|
|
||||||
VBoxContainer *_create_item_list(Theme::DataType p_data_type);
|
VBoxContainer *_create_item_list(Theme::DataType p_data_type);
|
||||||
void _update_type_list();
|
void _update_type_list();
|
||||||
void _update_type_list_debounced();
|
void _update_type_list_debounced();
|
||||||
void _update_add_type_options(const String &p_filter = "");
|
|
||||||
OrderedHashMap<StringName, bool> _get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default);
|
OrderedHashMap<StringName, bool> _get_type_items(String p_type_name, void (Theme::*get_list_func)(StringName, List<StringName> *) const, bool include_default);
|
||||||
HBoxContainer *_create_property_control(Theme::DataType p_data_type, String p_item_name, bool p_editable);
|
HBoxContainer *_create_property_control(Theme::DataType p_data_type, String p_item_name, bool p_editable);
|
||||||
void _add_focusable(Control *p_control);
|
void _add_focusable(Control *p_control);
|
||||||
|
@ -310,11 +347,6 @@ class ThemeTypeEditor : public MarginContainer {
|
||||||
void _list_type_selected(int p_index);
|
void _list_type_selected(int p_index);
|
||||||
void _select_type(String p_type_name);
|
void _select_type(String p_type_name);
|
||||||
void _add_type_button_cbk();
|
void _add_type_button_cbk();
|
||||||
void _add_type_filter_cbk(const String &p_value);
|
|
||||||
void _add_type_options_cbk(int p_index);
|
|
||||||
void _add_type_dialog_confirmed();
|
|
||||||
void _add_type_dialog_entered(const String &p_value);
|
|
||||||
void _add_type_dialog_activated(int p_index);
|
|
||||||
void _add_default_type_items();
|
void _add_default_type_items();
|
||||||
|
|
||||||
void _item_add_cbk(int p_data_type, Control *p_control);
|
void _item_add_cbk(int p_data_type, Control *p_control);
|
||||||
|
@ -337,6 +369,11 @@ class ThemeTypeEditor : public MarginContainer {
|
||||||
void _unpin_leading_stylebox();
|
void _unpin_leading_stylebox();
|
||||||
void _update_stylebox_from_leading();
|
void _update_stylebox_from_leading();
|
||||||
|
|
||||||
|
void _type_variation_changed(const String p_value);
|
||||||
|
void _add_type_variation_cbk();
|
||||||
|
|
||||||
|
void _add_type_dialog_selected(const String p_type_name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
|
||||||
|
|
||||||
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
|
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
|
||||||
if (hovered_control) {
|
if (hovered_control) {
|
||||||
StringName theme_type = hovered_control->get_theme_custom_type();
|
StringName theme_type = hovered_control->get_theme_type_variation();
|
||||||
if (theme_type == StringName()) {
|
if (theme_type == StringName()) {
|
||||||
theme_type = hovered_control->get_class_name();
|
theme_type = hovered_control->get_class_name();
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,13 +339,6 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
|
|
||||||
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
|
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
Ref<Theme> theme = Theme::get_default();
|
Ref<Theme> theme = Theme::get_default();
|
||||||
/* Using the default theme since the properties below are meant for editor only
|
|
||||||
if (data.theme.is_valid()) {
|
|
||||||
theme = data.theme;
|
|
||||||
} else {
|
|
||||||
theme = Theme::get_default();
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
||||||
{
|
{
|
||||||
List<StringName> names;
|
List<StringName> names;
|
||||||
|
@ -421,6 +414,34 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
|
// Skip duplicate values.
|
||||||
|
if (unique_names.has(E->get())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hint_string += String(E->get()) + ",";
|
||||||
|
unique_names.append(E->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
property.hint_string = hint_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Control *Control::get_parent_control() const {
|
Control *Control::get_parent_control() const {
|
||||||
return data.parent;
|
return data.parent;
|
||||||
}
|
}
|
||||||
|
@ -867,18 +888,19 @@ bool Control::has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_ow
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
|
void Control::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (data.theme_custom_type != StringName()) {
|
if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(data.theme_type_variation) != StringName()) {
|
||||||
p_list->push_back(data.theme_custom_type);
|
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);
|
||||||
}
|
}
|
||||||
Theme::get_type_dependencies(get_class_name(), p_list);
|
|
||||||
} else {
|
} else {
|
||||||
Theme::get_type_dependencies(p_theme_type, p_list);
|
Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
|
Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
|
const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
|
||||||
if (tex) {
|
if (tex) {
|
||||||
return *tex;
|
return *tex;
|
||||||
|
@ -891,7 +913,7 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
|
Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
|
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
|
||||||
if (style) {
|
if (style) {
|
||||||
return *style;
|
return *style;
|
||||||
|
@ -904,7 +926,7 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
|
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const Ref<Font> *font = data.font_override.getptr(p_name);
|
const Ref<Font> *font = data.font_override.getptr(p_name);
|
||||||
if (font) {
|
if (font) {
|
||||||
return *font;
|
return *font;
|
||||||
|
@ -917,7 +939,7 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_
|
||||||
}
|
}
|
||||||
|
|
||||||
int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
|
int Control::get_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const int *font_size = data.font_size_override.getptr(p_name);
|
const int *font_size = data.font_size_override.getptr(p_name);
|
||||||
if (font_size) {
|
if (font_size) {
|
||||||
return *font_size;
|
return *font_size;
|
||||||
|
@ -930,7 +952,7 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t
|
||||||
}
|
}
|
||||||
|
|
||||||
Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
|
Color Control::get_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const Color *color = data.color_override.getptr(p_name);
|
const Color *color = data.color_override.getptr(p_name);
|
||||||
if (color) {
|
if (color) {
|
||||||
return *color;
|
return *color;
|
||||||
|
@ -943,7 +965,7 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the
|
||||||
}
|
}
|
||||||
|
|
||||||
int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
|
int Control::get_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
const int *constant = data.constant_override.getptr(p_name);
|
const int *constant = data.constant_override.getptr(p_name);
|
||||||
if (constant) {
|
if (constant) {
|
||||||
return *constant;
|
return *constant;
|
||||||
|
@ -986,7 +1008,7 @@ bool Control::has_theme_constant_override(const StringName &p_name) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_icon_override(p_name)) {
|
if (has_theme_icon_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -998,7 +1020,7 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_stylebox_override(p_name)) {
|
if (has_theme_stylebox_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1010,7 +1032,7 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_font_override(p_name)) {
|
if (has_theme_font_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1022,7 +1044,7 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_font_size_override(p_name)) {
|
if (has_theme_font_size_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1034,7 +1056,7 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_color(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_color_override(p_name)) {
|
if (has_theme_color_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1046,7 +1068,7 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
|
bool Control::has_theme_constant(const StringName &p_name, const StringName &p_theme_type) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == data.theme_type_variation) {
|
||||||
if (has_theme_constant_override(p_name)) {
|
if (has_theme_constant_override(p_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2031,13 +2053,13 @@ Ref<Theme> Control::get_theme() const {
|
||||||
return data.theme;
|
return data.theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control::set_theme_custom_type(const StringName &p_theme_type) {
|
void Control::set_theme_type_variation(const StringName &p_theme_type) {
|
||||||
data.theme_custom_type = p_theme_type;
|
data.theme_type_variation = p_theme_type;
|
||||||
_propagate_theme_changed(this, data.theme_owner, data.theme_owner_window);
|
_propagate_theme_changed(this, data.theme_owner, data.theme_owner_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName Control::get_theme_custom_type() const {
|
StringName Control::get_theme_type_variation() const {
|
||||||
return data.theme_custom_type;
|
return data.theme_type_variation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control::set_tooltip(const String &p_tooltip) {
|
void Control::set_tooltip(const String &p_tooltip) {
|
||||||
|
@ -2660,8 +2682,8 @@ void Control::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Control::set_theme);
|
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Control::set_theme);
|
||||||
ClassDB::bind_method(D_METHOD("get_theme"), &Control::get_theme);
|
ClassDB::bind_method(D_METHOD("get_theme"), &Control::get_theme);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Control::set_theme_custom_type);
|
ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Control::set_theme_type_variation);
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Control::get_theme_custom_type);
|
ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Control::get_theme_type_variation);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override);
|
ClassDB::bind_method(D_METHOD("add_theme_icon_override", "name", "texture"), &Control::add_theme_icon_override);
|
||||||
ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override);
|
ClassDB::bind_method(D_METHOD("add_theme_stylebox_override", "name", "stylebox"), &Control::add_theme_style_override);
|
||||||
|
@ -2810,7 +2832,7 @@ void Control::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");
|
||||||
ADD_GROUP("Theme", "theme_");
|
ADD_GROUP("Theme", "theme_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation");
|
||||||
ADD_GROUP("", "");
|
ADD_GROUP("", "");
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(FOCUS_NONE);
|
BIND_ENUM_CONSTANT(FOCUS_NONE);
|
||||||
|
|
|
@ -202,7 +202,7 @@ private:
|
||||||
Ref<Theme> theme;
|
Ref<Theme> theme;
|
||||||
Control *theme_owner = nullptr;
|
Control *theme_owner = nullptr;
|
||||||
Window *theme_owner_window = nullptr;
|
Window *theme_owner_window = nullptr;
|
||||||
StringName theme_custom_type;
|
StringName theme_type_variation;
|
||||||
|
|
||||||
String tooltip;
|
String tooltip;
|
||||||
CursorShape default_cursor = CURSOR_ARROW;
|
CursorShape default_cursor = CURSOR_ARROW;
|
||||||
|
@ -279,8 +279,8 @@ protected:
|
||||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||||
|
|
||||||
void _notification(int p_notification);
|
void _notification(int p_notification);
|
||||||
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
virtual void _validate_property(PropertyInfo &property) const override;
|
||||||
|
|
||||||
//bind helpers
|
//bind helpers
|
||||||
|
|
||||||
|
@ -402,8 +402,8 @@ public:
|
||||||
void set_theme(const Ref<Theme> &p_theme);
|
void set_theme(const Ref<Theme> &p_theme);
|
||||||
Ref<Theme> get_theme() const;
|
Ref<Theme> get_theme() const;
|
||||||
|
|
||||||
void set_theme_custom_type(const StringName &p_theme_type);
|
void set_theme_type_variation(const StringName &p_theme_type);
|
||||||
StringName get_theme_custom_type() const;
|
StringName get_theme_type_variation() const;
|
||||||
|
|
||||||
void set_h_size_flags(int p_flags);
|
void set_h_size_flags(int p_flags);
|
||||||
int get_h_size_flags() const;
|
int get_h_size_flags() const;
|
||||||
|
|
|
@ -1170,23 +1170,24 @@ Ref<Theme> Window::get_theme() const {
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_theme_custom_type(const StringName &p_theme_type) {
|
void Window::set_theme_type_variation(const StringName &p_theme_type) {
|
||||||
theme_custom_type = p_theme_type;
|
theme_type_variation = p_theme_type;
|
||||||
Control::_propagate_theme_changed(this, theme_owner, theme_owner_window);
|
Control::_propagate_theme_changed(this, theme_owner, theme_owner_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName Window::get_theme_custom_type() const {
|
StringName Window::get_theme_type_variation() const {
|
||||||
return theme_custom_type;
|
return theme_type_variation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
|
void Window::_get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const {
|
||||||
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_custom_type) {
|
if (p_theme_type == StringName() || p_theme_type == get_class_name() || p_theme_type == theme_type_variation) {
|
||||||
if (theme_custom_type != StringName()) {
|
if (Theme::get_project_default().is_valid() && Theme::get_project_default()->get_type_variation_base(theme_type_variation) != StringName()) {
|
||||||
p_list->push_back(theme_custom_type);
|
Theme::get_project_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
|
||||||
|
} else {
|
||||||
|
Theme::get_default()->get_type_dependencies(get_class_name(), theme_type_variation, p_list);
|
||||||
}
|
}
|
||||||
Theme::get_type_dependencies(get_class_name(), p_list);
|
|
||||||
} else {
|
} else {
|
||||||
Theme::get_type_dependencies(p_theme_type, p_list);
|
Theme::get_default()->get_type_dependencies(p_theme_type, StringName(), p_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1340,6 +1341,34 @@ bool Window::is_layout_rtl() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::_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 (List<StringName>::Element *E = names.front(); E; E = E->next()) {
|
||||||
|
// Skip duplicate values.
|
||||||
|
if (unique_names.has(E->get())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
hint_string += String(E->get()) + ",";
|
||||||
|
unique_names.append(E->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
property.hint_string = hint_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Window::_bind_methods() {
|
void Window::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
|
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
|
||||||
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
|
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
|
||||||
|
@ -1417,8 +1446,8 @@ void Window::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme);
|
ClassDB::bind_method(D_METHOD("set_theme", "theme"), &Window::set_theme);
|
||||||
ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme);
|
ClassDB::bind_method(D_METHOD("get_theme"), &Window::get_theme);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_theme_custom_type", "theme_type"), &Window::set_theme_custom_type);
|
ClassDB::bind_method(D_METHOD("set_theme_type_variation", "theme_type"), &Window::set_theme_type_variation);
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_custom_type"), &Window::get_theme_custom_type);
|
ClassDB::bind_method(D_METHOD("get_theme_type_variation"), &Window::get_theme_type_variation);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Window::get_theme_icon, DEFVAL(""));
|
ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "theme_type"), &Window::get_theme_icon, DEFVAL(""));
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Window::get_theme_stylebox, DEFVAL(""));
|
ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "theme_type"), &Window::get_theme_stylebox, DEFVAL(""));
|
||||||
|
@ -1468,7 +1497,7 @@ void Window::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect");
|
||||||
ADD_GROUP("Theme", "theme_");
|
ADD_GROUP("Theme", "theme_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type");
|
ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation");
|
||||||
|
|
||||||
ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
|
ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
|
||||||
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
|
ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
|
||||||
|
|
|
@ -130,7 +130,7 @@ private:
|
||||||
Ref<Theme> theme;
|
Ref<Theme> theme;
|
||||||
Control *theme_owner = nullptr;
|
Control *theme_owner = nullptr;
|
||||||
Window *theme_owner_window = nullptr;
|
Window *theme_owner_window = nullptr;
|
||||||
StringName theme_custom_type;
|
StringName theme_type_variation;
|
||||||
|
|
||||||
Viewport *embedder = nullptr;
|
Viewport *embedder = nullptr;
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ protected:
|
||||||
virtual Size2 _get_contents_minimum_size() const;
|
virtual Size2 _get_contents_minimum_size() const;
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
virtual void _validate_property(PropertyInfo &property) const override;
|
||||||
|
|
||||||
virtual void add_child_notify(Node *p_child) override;
|
virtual void add_child_notify(Node *p_child) override;
|
||||||
virtual void remove_child_notify(Node *p_child) override;
|
virtual void remove_child_notify(Node *p_child) override;
|
||||||
|
@ -242,8 +243,8 @@ public:
|
||||||
void set_theme(const Ref<Theme> &p_theme);
|
void set_theme(const Ref<Theme> &p_theme);
|
||||||
Ref<Theme> get_theme() const;
|
Ref<Theme> get_theme() const;
|
||||||
|
|
||||||
void set_theme_custom_type(const StringName &p_theme_type);
|
void set_theme_type_variation(const StringName &p_theme_type);
|
||||||
StringName get_theme_custom_type() const;
|
StringName get_theme_type_variation() const;
|
||||||
_FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const;
|
_FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const;
|
||||||
|
|
||||||
Size2 get_contents_minimum_size() const;
|
Size2 get_contents_minimum_size() const;
|
||||||
|
|
|
@ -263,6 +263,21 @@ Vector<String> Theme::_get_theme_item_type_list(DataType p_data_type) const {
|
||||||
return Vector<String>();
|
return Vector<String>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vector<String> Theme::_get_type_variation_list(const StringName &p_theme_type) const {
|
||||||
|
Vector<String> ilret;
|
||||||
|
List<StringName> il;
|
||||||
|
|
||||||
|
get_type_variation_list(p_theme_type, &il);
|
||||||
|
ilret.resize(il.size());
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
String *w = ilret.ptrw();
|
||||||
|
for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) {
|
||||||
|
w[i] = E->get();
|
||||||
|
}
|
||||||
|
return ilret;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<String> Theme::_get_type_list() const {
|
Vector<String> Theme::_get_type_list() const {
|
||||||
Vector<String> ilret;
|
Vector<String> ilret;
|
||||||
List<StringName> il;
|
List<StringName> il;
|
||||||
|
@ -292,10 +307,14 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
set_stylebox(name, theme_type, p_value);
|
set_stylebox(name, theme_type, p_value);
|
||||||
} else if (type == "fonts") {
|
} else if (type == "fonts") {
|
||||||
set_font(name, theme_type, p_value);
|
set_font(name, theme_type, p_value);
|
||||||
|
} else if (type == "font_sizes") {
|
||||||
|
set_font_size(name, theme_type, p_value);
|
||||||
} else if (type == "colors") {
|
} else if (type == "colors") {
|
||||||
set_color(name, theme_type, p_value);
|
set_color(name, theme_type, p_value);
|
||||||
} else if (type == "constants") {
|
} else if (type == "constants") {
|
||||||
set_constant(name, theme_type, p_value);
|
set_constant(name, theme_type, p_value);
|
||||||
|
} else if (type == "base_type") {
|
||||||
|
set_type_variation(theme_type, p_value);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -332,10 +351,14 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
} else {
|
} else {
|
||||||
r_ret = get_font(name, theme_type);
|
r_ret = get_font(name, theme_type);
|
||||||
}
|
}
|
||||||
|
} else if (type == "font_sizes") {
|
||||||
|
r_ret = get_font_size(name, theme_type);
|
||||||
} else if (type == "colors") {
|
} else if (type == "colors") {
|
||||||
r_ret = get_color(name, theme_type);
|
r_ret = get_color(name, theme_type);
|
||||||
} else if (type == "constants") {
|
} else if (type == "constants") {
|
||||||
r_ret = get_constant(name, theme_type);
|
r_ret = get_constant(name, theme_type);
|
||||||
|
} else if (type == "base_type") {
|
||||||
|
r_ret = get_type_variation_base(theme_type);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +374,14 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
const StringName *key = nullptr;
|
const StringName *key = nullptr;
|
||||||
|
|
||||||
|
// Type variations.
|
||||||
|
while ((key = variation_map.next(key))) {
|
||||||
|
list.push_back(PropertyInfo(Variant::STRING_NAME, String() + *key + "/base_type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
key = nullptr;
|
||||||
|
|
||||||
|
// Icons.
|
||||||
while ((key = icon_map.next(key))) {
|
while ((key = icon_map.next(key))) {
|
||||||
const StringName *key2 = nullptr;
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
@ -361,6 +392,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Styles.
|
||||||
while ((key = style_map.next(key))) {
|
while ((key = style_map.next(key))) {
|
||||||
const StringName *key2 = nullptr;
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
@ -371,6 +403,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Fonts.
|
||||||
while ((key = font_map.next(key))) {
|
while ((key = font_map.next(key))) {
|
||||||
const StringName *key2 = nullptr;
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
@ -381,6 +414,18 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Font sizes.
|
||||||
|
while ((key = font_size_map.next(key))) {
|
||||||
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
while ((key2 = font_size_map[*key].next(key2))) {
|
||||||
|
list.push_back(PropertyInfo(Variant::INT, String() + *key + "/font_sizes/" + *key2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
key = nullptr;
|
||||||
|
|
||||||
|
// Colors.
|
||||||
while ((key = color_map.next(key))) {
|
while ((key = color_map.next(key))) {
|
||||||
const StringName *key2 = nullptr;
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
@ -391,6 +436,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Constants.
|
||||||
while ((key = constant_map.next(key))) {
|
while ((key = constant_map.next(key))) {
|
||||||
const StringName *key2 = nullptr;
|
const StringName *key2 = nullptr;
|
||||||
|
|
||||||
|
@ -399,6 +445,7 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort and store properties.
|
||||||
list.sort();
|
list.sort();
|
||||||
for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) {
|
for (List<PropertyInfo>::Element *E = list.front(); E; E = E->next()) {
|
||||||
p_list->push_back(E->get());
|
p_list->push_back(E->get());
|
||||||
|
@ -1183,6 +1230,63 @@ void Theme::get_theme_item_type_list(DataType p_data_type, List<StringName> *p_l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Theme::set_type_variation(const StringName &p_theme_type, const StringName &p_base_type) {
|
||||||
|
ERR_FAIL_COND_MSG(p_theme_type == StringName(), "An empty theme type cannot be marked as a variation of another type.");
|
||||||
|
ERR_FAIL_COND_MSG(ClassDB::class_exists(p_theme_type), "A type associated with a built-in class cannot be marked as a variation of another type.");
|
||||||
|
ERR_FAIL_COND_MSG(p_base_type == StringName(), "An empty theme type cannot be the base type of a variation. Use clear_type_variation() instead if you want to unmark '" + String(p_theme_type) + "' as a variation.");
|
||||||
|
|
||||||
|
if (variation_map.has(p_theme_type)) {
|
||||||
|
StringName old_base = variation_map[p_theme_type];
|
||||||
|
variation_base_map[old_base].erase(p_theme_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
variation_map[p_theme_type] = p_base_type;
|
||||||
|
variation_base_map[p_base_type].push_back(p_theme_type);
|
||||||
|
|
||||||
|
_emit_theme_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Theme::is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const {
|
||||||
|
return (variation_map.has(p_theme_type) && variation_map[p_theme_type] == p_base_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::clear_type_variation(const StringName &p_theme_type) {
|
||||||
|
ERR_FAIL_COND_MSG(!variation_map.has(p_theme_type), "Cannot clear the type variation '" + String(p_theme_type) + "' because it does not exist.");
|
||||||
|
|
||||||
|
StringName base_type = variation_map[p_theme_type];
|
||||||
|
variation_base_map[base_type].erase(p_theme_type);
|
||||||
|
variation_map.erase(p_theme_type);
|
||||||
|
|
||||||
|
_emit_theme_changed();
|
||||||
|
}
|
||||||
|
|
||||||
|
StringName Theme::get_type_variation_base(const StringName &p_theme_type) const {
|
||||||
|
if (!variation_map.has(p_theme_type)) {
|
||||||
|
return StringName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return variation_map[p_theme_type];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Theme::get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const {
|
||||||
|
ERR_FAIL_NULL(p_list);
|
||||||
|
|
||||||
|
if (!variation_base_map.has(p_base_type)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const List<StringName>::Element *E = variation_base_map[p_base_type].front(); E; E = E->next()) {
|
||||||
|
// Prevent infinite loops if variants were set to be cross-dependent (that's still invalid usage, but handling for stability sake).
|
||||||
|
if (p_list->find(E->get())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_list->push_back(E->get());
|
||||||
|
// Continue looking for sub-variations.
|
||||||
|
get_type_variation_list(E->get(), p_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Theme::_freeze_change_propagation() {
|
void Theme::_freeze_change_propagation() {
|
||||||
no_change_propagation = true;
|
no_change_propagation = true;
|
||||||
}
|
}
|
||||||
|
@ -1236,9 +1340,13 @@ void Theme::clear() {
|
||||||
icon_map.clear();
|
icon_map.clear();
|
||||||
style_map.clear();
|
style_map.clear();
|
||||||
font_map.clear();
|
font_map.clear();
|
||||||
|
font_size_map.clear();
|
||||||
color_map.clear();
|
color_map.clear();
|
||||||
constant_map.clear();
|
constant_map.clear();
|
||||||
|
|
||||||
|
variation_map.clear();
|
||||||
|
variation_base_map.clear();
|
||||||
|
|
||||||
_emit_theme_changed();
|
_emit_theme_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1291,6 +1399,9 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
|
||||||
color_map = p_other->color_map;
|
color_map = p_other->color_map;
|
||||||
constant_map = p_other->constant_map;
|
constant_map = p_other->constant_map;
|
||||||
|
|
||||||
|
variation_map = p_other->variation_map;
|
||||||
|
variation_base_map = p_other->variation_base_map;
|
||||||
|
|
||||||
_unfreeze_and_propagate_changes();
|
_unfreeze_and_propagate_changes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,30 +1411,42 @@ void Theme::get_type_list(List<StringName> *p_list) const {
|
||||||
Set<StringName> types;
|
Set<StringName> types;
|
||||||
const StringName *key = nullptr;
|
const StringName *key = nullptr;
|
||||||
|
|
||||||
|
// Icons.
|
||||||
while ((key = icon_map.next(key))) {
|
while ((key = icon_map.next(key))) {
|
||||||
types.insert(*key);
|
types.insert(*key);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// StyleBoxes.
|
||||||
while ((key = style_map.next(key))) {
|
while ((key = style_map.next(key))) {
|
||||||
types.insert(*key);
|
types.insert(*key);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Fonts.
|
||||||
while ((key = font_map.next(key))) {
|
while ((key = font_map.next(key))) {
|
||||||
types.insert(*key);
|
types.insert(*key);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Font sizes.
|
||||||
|
while ((key = font_size_map.next(key))) {
|
||||||
|
types.insert(*key);
|
||||||
|
}
|
||||||
|
|
||||||
|
key = nullptr;
|
||||||
|
|
||||||
|
// Colors.
|
||||||
while ((key = color_map.next(key))) {
|
while ((key = color_map.next(key))) {
|
||||||
types.insert(*key);
|
types.insert(*key);
|
||||||
}
|
}
|
||||||
|
|
||||||
key = nullptr;
|
key = nullptr;
|
||||||
|
|
||||||
|
// Constants.
|
||||||
while ((key = constant_map.next(key))) {
|
while ((key = constant_map.next(key))) {
|
||||||
types.insert(*key);
|
types.insert(*key);
|
||||||
}
|
}
|
||||||
|
@ -1333,10 +1456,25 @@ void Theme::get_type_list(List<StringName> *p_list) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) {
|
void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List<StringName> *p_list) {
|
||||||
ERR_FAIL_NULL(p_list);
|
ERR_FAIL_NULL(p_list);
|
||||||
|
|
||||||
StringName class_name = p_theme_type;
|
// Build the dependency chain for type variations.
|
||||||
|
if (p_type_variation != StringName()) {
|
||||||
|
StringName variation_name = p_type_variation;
|
||||||
|
while (variation_name != StringName()) {
|
||||||
|
p_list->push_back(variation_name);
|
||||||
|
variation_name = get_type_variation_base(variation_name);
|
||||||
|
|
||||||
|
// If we have reached the base type dependency, it's safe to stop (assuming no funny business was done to the Theme).
|
||||||
|
if (variation_name == p_base_type) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue building the chain using native class hierarchy.
|
||||||
|
StringName class_name = p_base_type;
|
||||||
while (class_name != StringName()) {
|
while (class_name != StringName()) {
|
||||||
p_list->push_back(class_name);
|
p_list->push_back(class_name);
|
||||||
class_name = ClassDB::get_parent_class_nocheck(class_name);
|
class_name = ClassDB::get_parent_class_nocheck(class_name);
|
||||||
|
@ -1346,6 +1484,7 @@ void Theme::get_type_dependencies(const StringName &p_theme_type, List<StringNam
|
||||||
void Theme::reset_state() {
|
void Theme::reset_state() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::_bind_methods() {
|
void Theme::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_icon", "name", "theme_type", "texture"), &Theme::set_icon);
|
ClassDB::bind_method(D_METHOD("set_icon", "name", "theme_type", "texture"), &Theme::set_icon);
|
||||||
ClassDB::bind_method(D_METHOD("get_icon", "name", "theme_type"), &Theme::get_icon);
|
ClassDB::bind_method(D_METHOD("get_icon", "name", "theme_type"), &Theme::get_icon);
|
||||||
|
@ -1411,6 +1550,12 @@ void Theme::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "theme_type"), &Theme::_get_theme_item_list);
|
ClassDB::bind_method(D_METHOD("get_theme_item_list", "data_type", "theme_type"), &Theme::_get_theme_item_list);
|
||||||
ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list);
|
ClassDB::bind_method(D_METHOD("get_theme_item_type_list", "data_type"), &Theme::_get_theme_item_type_list);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_type_variation", "theme_type", "base_type"), &Theme::set_type_variation);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_type_variation", "theme_type", "base_type"), &Theme::is_type_variation);
|
||||||
|
ClassDB::bind_method(D_METHOD("clear_type_variation", "theme_type"), &Theme::clear_type_variation);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_type_variation_base", "theme_type"), &Theme::get_type_variation_base);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_type_variation_list", "base_type"), &Theme::_get_type_variation_list);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list);
|
ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list);
|
||||||
|
|
||||||
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
|
ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme);
|
||||||
|
|
|
@ -69,6 +69,8 @@ private:
|
||||||
HashMap<StringName, HashMap<StringName, int>> font_size_map;
|
HashMap<StringName, HashMap<StringName, int>> font_size_map;
|
||||||
HashMap<StringName, HashMap<StringName, Color>> color_map;
|
HashMap<StringName, HashMap<StringName, Color>> color_map;
|
||||||
HashMap<StringName, HashMap<StringName, int>> constant_map;
|
HashMap<StringName, HashMap<StringName, int>> constant_map;
|
||||||
|
HashMap<StringName, StringName> variation_map;
|
||||||
|
HashMap<StringName, List<StringName>> variation_base_map;
|
||||||
|
|
||||||
Vector<String> _get_icon_list(const String &p_theme_type) const;
|
Vector<String> _get_icon_list(const String &p_theme_type) const;
|
||||||
Vector<String> _get_icon_type_list() const;
|
Vector<String> _get_icon_type_list() const;
|
||||||
|
@ -85,6 +87,8 @@ private:
|
||||||
|
|
||||||
Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_theme_type) const;
|
Vector<String> _get_theme_item_list(DataType p_data_type, const String &p_theme_type) const;
|
||||||
Vector<String> _get_theme_item_type_list(DataType p_data_type) const;
|
Vector<String> _get_theme_item_type_list(DataType p_data_type) const;
|
||||||
|
|
||||||
|
Vector<String> _get_type_variation_list(const StringName &p_theme_type) const;
|
||||||
Vector<String> _get_type_list() const;
|
Vector<String> _get_type_list() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -197,8 +201,14 @@ public:
|
||||||
void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type);
|
void add_theme_item_type(DataType p_data_type, const StringName &p_theme_type);
|
||||||
void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const;
|
void get_theme_item_type_list(DataType p_data_type, List<StringName> *p_list) const;
|
||||||
|
|
||||||
|
void set_type_variation(const StringName &p_theme_type, const StringName &p_base_type);
|
||||||
|
bool is_type_variation(const StringName &p_theme_type, const StringName &p_base_type) const;
|
||||||
|
void clear_type_variation(const StringName &p_theme_type);
|
||||||
|
StringName get_type_variation_base(const StringName &p_theme_type) const;
|
||||||
|
void get_type_variation_list(const StringName &p_base_type, List<StringName> *p_list) const;
|
||||||
|
|
||||||
void get_type_list(List<StringName> *p_list) const;
|
void get_type_list(List<StringName> *p_list) const;
|
||||||
static void get_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list);
|
void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, List<StringName> *p_list);
|
||||||
|
|
||||||
void copy_default_theme();
|
void copy_default_theme();
|
||||||
void copy_theme(const Ref<Theme> &p_other);
|
void copy_theme(const Ref<Theme> &p_other);
|
||||||
|
|
Loading…
Reference in a new issue