Skip to content

Commit

Permalink
Update ColorPicker, FoldableContainer and add a new ColorButton
Browse files Browse the repository at this point in the history
… node. (#248)

* Improve Editor Inspector/Theme item lookup performance

Changes to reduce the latency between changing node selection in the editor and seeing the new node reflected in the Inspector tab

- Use Vector instead of List for ThemeOwner::get_theme_type_dependencies and related functions
- Use Vector instead of List for ThemeContext::themes, set_themes(), and get_themes()
- Add ClassDB:get_inheritance_chain_nocheck to get all parent/ancestor classes at once, to avoid repeated ClassDB locking overhead
- Update BIND_THEME_ITEM macros and ThemeDB::update_class_instance_items to use provided StringNames for call to ThemeItemSetter, instead of creating a new StringName in each call

These changes reduce the time taken by EditorInspector::update_tree by around 30-35%

* Add new `ColorButton` node.

* Update `FoldableContainer`

Allow adding empty buttons.
Rename the arrow theme items.

* Update `ColorPicker`

---------

Co-authored-by: aaronp64 <aaronp.code@gmail.com>
  • Loading branch information
WhalesState and aaronp64 authored Jan 17, 2025
1 parent a6b0ca3 commit e9d3187
Show file tree
Hide file tree
Showing 34 changed files with 769 additions and 575 deletions.
23 changes: 23 additions & 0 deletions core/object/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,29 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) {
return ti->inherits;
}

bool ClassDB::get_inheritance_chain_nocheck(const StringName &p_class, Vector<StringName> &r_result) {
OBJTYPE_RLOCK;

ClassInfo *start = classes.getptr(p_class);
if (!start) {
return false;
}

int classes_to_add = 0;
for (ClassInfo *ti = start; ti; ti = ti->inherits_ptr) {
classes_to_add++;
}

int64_t old_size = r_result.size();
r_result.resize(old_size + classes_to_add);
StringName *w = r_result.ptrw() + old_size;
for (ClassInfo *ti = start; ti; ti = ti->inherits_ptr) {
*w++ = ti->name;
}

return true;
}

StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class) {
if (classes.has(p_class)) {
return p_class;
Expand Down
1 change: 1 addition & 0 deletions core/object/class_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ class ClassDB {
static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes);
static StringName get_parent_class_nocheck(const StringName &p_class);
static bool get_inheritance_chain_nocheck(const StringName &p_class, Vector<StringName> &r_result);
static StringName get_parent_class(const StringName &p_class);
static StringName get_compatibility_remapped_class(const StringName &p_class);
static bool class_exists(const StringName &p_class);
Expand Down
62 changes: 62 additions & 0 deletions doc/classes/ColorButton.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ColorButton" inherits="BaseButton" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
A Button That displays a color.
</brief_description>
<description>
A Button That displays a color.
</description>
<tutorials>
</tutorials>
<methods>
<method name="set_color">
<return type="void" />
<param index="0" name="color" type="Color" />
<description>
Changes the button's color and emits [signal color_changed].
</description>
</method>
</methods>
<members>
<member name="color" type="Color" setter="set_color_no_signal" getter="get_color" default="Color(1, 1, 1, 1)">
The button's display color.
</member>
<member name="flat" type="bool" setter="set_flat" getter="is_flat" default="false">
Draws the buttons without the styles.
</member>
</members>
<signals>
<signal name="color_changed">
<param index="0" name="color" type="Color" />
<description>
Emitted when the color is changed.
</description>
</signal>
</signals>
<theme_items>
<theme_item name="bg" data_type="icon" type="Texture2D">
The background image displayed behind the color when the color alpha is less than one.
</theme_item>
<theme_item name="overbright_indicator" data_type="icon" type="Texture2D">
The indicator used to signalize that the color value is outside the 0-1 range.
</theme_item>
<theme_item name="disabled" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is disabled.
</theme_item>
<theme_item name="focus" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is focused. The [theme_item focus] [StyleBox] is displayed [i]over[/i] the base [StyleBox], so a partially transparent [StyleBox] should be used to ensure the base [StyleBox] remains visible. A [StyleBox] that represents an outline or an underline works well for this purpose. To disable the focus visual effect, assign a [StyleBoxEmpty] resource. Note that disabling the focus visual effect will harm keyboard/controller navigation usability, so this is not recommended for accessibility reasons.
</theme_item>
<theme_item name="hover" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is being hovered.
</theme_item>
<theme_item name="hover_pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is being pressed and hovered at the same time.
</theme_item>
<theme_item name="normal" data_type="style" type="StyleBox">
Default [StyleBox] for the [Button].
</theme_item>
<theme_item name="pressed" data_type="style" type="StyleBox">
[StyleBox] used when the [Button] is being pressed.
</theme_item>
</theme_items>
</class>
22 changes: 20 additions & 2 deletions doc/classes/ColorPicker.xml
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@
<theme_item name="center_slider_grabbers" data_type="constant" type="int" default="1">
Overrides the [theme_item Slider.center_grabber] theme property of the sliders.
</theme_item>
<theme_item name="colorize_sliders" data_type="constant" type="int" default="1">
If [code]true[/code] The color mode sliders will be colorized.
</theme_item>
<theme_item name="h_width" data_type="constant" type="int" default="30">
The width of the hue selection slider.
</theme_item>
Expand All @@ -173,6 +176,12 @@
<theme_item name="margin" data_type="constant" type="int" default="4">
The margin around the [ColorPicker].
</theme_item>
<theme_item name="preset_size" data_type="constant" type="int" default="30">
Controls the size of the recent and swatches color buttons.
</theme_item>
<theme_item name="sample_height" data_type="constant" type="int" default="30">
Controls the height of the color sample.
</theme_item>
<theme_item name="sv_height" data_type="constant" type="int" default="256">
The height of the saturation-value selection box.
</theme_item>
Expand All @@ -189,10 +198,19 @@
Custom texture for the hue selection slider on the right.
</theme_item>
<theme_item name="expanded_arrow" data_type="icon" type="Texture2D">
The icon for color preset drop down menu when expanded.
The arrow used for the preset containers when expanded.
</theme_item>
<theme_item name="folded_arrow" data_type="icon" type="Texture2D">
The icon for color preset drop down menu when folded.
The arrow used for the preset containers when folded. (for left-to-right layouts).
</theme_item>
<theme_item name="folded_arrow_mirrored" data_type="icon" type="Texture2D">
The arrow used for the preset containers when folded. (for right-to-left layouts).
</theme_item>
<theme_item name="hex_code_icon" data_type="icon" type="Texture2D">
The icon displayed when the hex [LineEdit] is showing the color code.
</theme_item>
<theme_item name="hex_icon" data_type="icon" type="Texture2D">
The icon displayed when the hex [LineEdit] is showing the hex code.
</theme_item>
<theme_item name="overbright_indicator" data_type="icon" type="Texture2D">
The indicator used to signalize that the color value is outside the 0-1 range.
Expand Down
14 changes: 7 additions & 7 deletions doc/classes/FoldableContainer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -322,17 +322,17 @@
<theme_item name="font_size" data_type="font_size" type="int">
The title's font size.
</theme_item>
<theme_item name="arrow" data_type="icon" type="Texture2D">
<theme_item name="expanded_arrow" data_type="icon" type="Texture2D">
The title's icon used when expanded.
</theme_item>
<theme_item name="arrow_collapsed" data_type="icon" type="Texture2D">
The title's icon used when collapsed (for left-to-right layouts).
<theme_item name="expanded_arrow_mirrored" data_type="icon" type="Texture2D">
The title's icon used when expanded (for bottom title).
</theme_item>
<theme_item name="arrow_collapsed_mirrored" data_type="icon" type="Texture2D">
The title's icon used when collapsed (for right-to-left layouts).
<theme_item name="folded_arrow" data_type="icon" type="Texture2D">
The title's icon used when folded (for left-to-right layouts).
</theme_item>
<theme_item name="arrow_mirrored" data_type="icon" type="Texture2D">
The title's icon used when expanded (for bottom title).
<theme_item name="folded_arrow_mirrored" data_type="icon" type="Texture2D">
The title's icon used when collapsed (for right-to-left layouts).
</theme_item>
<theme_item name="button_disabled_style" data_type="style" type="StyleBox">
The title's button disabled style.
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ void EditorNode::_update_theme(bool p_skip_creation) {
DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
}

List<Ref<Theme>> editor_themes;
Vector<Ref<Theme>> editor_themes;
editor_themes.push_back(theme);
editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme());

Expand Down Expand Up @@ -589,7 +589,7 @@ void EditorNode::update_preview_themes(int p_mode) {
return; // Too early.
}

List<Ref<Theme>> preview_themes;
Vector<Ref<Theme>> preview_themes;

switch (p_mode) {
case CanvasItemEditor::THEME_PREVIEW_PROJECT:
Expand Down
1 change: 1 addition & 0 deletions editor/icons/ColorButton.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions editor/icons/PickerHex.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion editor/plugins/theme_editor_preview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void ThemeEditorPreview::_notification(int p_what) {
} break;

case NOTIFICATION_READY: {
List<Ref<Theme>> preview_themes;
Vector<Ref<Theme>> preview_themes;
preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme());
ThemeDB::get_singleton()->create_theme_context(preview_root, preview_themes);
} break;
Expand Down
2 changes: 1 addition & 1 deletion editor/project_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ void ProjectManager::_update_theme(bool p_skip_creation) {
DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor)));
}

List<Ref<Theme>> editor_themes;
Vector<Ref<Theme>> editor_themes;
editor_themes.push_back(theme);
editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme());

Expand Down
42 changes: 32 additions & 10 deletions editor/themes/editor_theme_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,10 +1309,10 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_color("button_icon_pressed", "FoldableContainer", p_config.icon_pressed_color);
p_theme->set_color("button_icon_disabled", "FoldableContainer", p_config.icon_disabled_color);

p_theme->set_icon("arrow", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
p_theme->set_icon("arrow_mirrored", "FoldableContainer", p_theme->get_icon(SNAME("GuiArrowUp"), EditorStringName(EditorIcons)));
p_theme->set_icon("arrow_collapsed", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
p_theme->set_icon("arrow_collapsed_mirrored", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons)));
p_theme->set_icon("expanded_arrow", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
p_theme->set_icon("expanded_arrow_mirrored", "FoldableContainer", p_theme->get_icon(SNAME("GuiArrowUp"), EditorStringName(EditorIcons)));
p_theme->set_icon("folded_arrow", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
p_theme->set_icon("folded_arrow_mirrored", "FoldableContainer", p_theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons)));

p_theme->set_constant("outline_size", "FoldableContainer", 0);
p_theme->set_constant("h_separation", "FoldableContainer", p_config.separation_margin);
Expand Down Expand Up @@ -1781,16 +1781,38 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
}
}

// ColorButton

int x6_scale = Math::round(6 * EDSCALE);
p_theme->set_stylebox(CoreStringName(normal), "ColorButton", make_flat_stylebox(p_config.dark_color_1, x6_scale, x6_scale, x6_scale, x6_scale, p_config.corner_radius));
p_theme->set_stylebox("hover", "ColorButton", make_flat_stylebox(p_config.mono_color * Color(1, 1, 1, 0.11), x6_scale, x6_scale, x6_scale, x6_scale, p_config.corner_radius));
p_theme->set_stylebox("disabled", "ColorButton", make_flat_stylebox(p_config.disabled_bg_color, x6_scale, x6_scale, x6_scale, x6_scale, p_config.corner_radius));
Ref<StyleBoxFlat> color_button_pressed = make_flat_stylebox(p_config.dark_color_1.darkened(0.125), x6_scale, x6_scale, x6_scale, x6_scale, p_config.corner_radius);
color_button_pressed->set_border_width_all(4 * EDSCALE);
color_button_pressed->set_border_color(p_config.extra_border_color_2);
p_theme->set_stylebox(SceneStringName(pressed), "ColorButton", color_button_pressed);
Ref<StyleBoxFlat> color_button_focus = make_flat_stylebox(p_config.dark_color_1, 0, 0, 0, 0, MAX(p_config.corner_radius - 1, 0));
color_button_focus->set_draw_center(false);
color_button_focus->set_border_width_all(2 * EDSCALE);
color_button_focus->set_border_color(p_config.accent_color);
p_theme->set_stylebox("focus", "ColorButton", color_button_focus);

p_theme->set_icon("bg", "ColorButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
p_theme->set_icon("overbright_indicator", "ColorButton", p_theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons)));

// ColorPicker and related nodes.
{
// ColorPicker.

p_theme->set_constant("margin", "ColorPicker", p_config.base_margin);
p_theme->set_constant("sv_width", "ColorPicker", 256 * EDSCALE);
p_theme->set_constant("sv_height", "ColorPicker", 256 * EDSCALE);
p_theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE);
p_theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE);
p_theme->set_constant("sample_height", "ColorPicker", 30 * EDSCALE);
p_theme->set_constant("h_width", "ColorPicker", 30 * EDSCALE);
p_theme->set_constant("preset_size", "ColorPicker", Math::round(30 * EDSCALE));
p_theme->set_constant("center_slider_grabbers", "ColorPicker", 1);
p_theme->set_constant("colorize_sliders", "ColorPicker", 1);

p_theme->set_icon("screen_picker", "ColorPicker", p_theme->get_icon(SNAME("ColorPick"), EditorStringName(EditorIcons)));
p_theme->set_icon("shape_circle", "ColorPicker", p_theme->get_icon(SNAME("PickerShapeCircle"), EditorStringName(EditorIcons)));
Expand All @@ -1803,14 +1825,14 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
p_theme->set_icon("bar_arrow", "ColorPicker", p_theme->get_icon(SNAME("ColorPickerBarArrow"), EditorStringName(EditorIcons)));
p_theme->set_icon("picker_cursor", "ColorPicker", p_theme->get_icon(SNAME("PickerCursor"), EditorStringName(EditorIcons)));
p_theme->set_icon("picker_cursor_bg", "ColorPicker", p_theme->get_icon(SNAME("PickerCursorBg"), EditorStringName(EditorIcons)));
p_theme->set_icon("hex_icon", "ColorPicker", p_theme->get_icon(SNAME("PickerHex"), EditorStringName(EditorIcons)));
p_theme->set_icon("hex_code_icon", "ColorPicker", p_theme->get_icon(SNAME("Script"), EditorStringName(EditorIcons)));
p_theme->set_icon("expanded_arrow", "ColorPicker", p_theme->get_icon(SNAME("GuiTreeArrowDown"), EditorStringName(EditorIcons)));
p_theme->set_icon("folded_arrow", "ColorPicker", p_theme->get_icon(SNAME("GuiTreeArrowRight"), EditorStringName(EditorIcons)));
p_theme->set_icon("folded_arrow_mirrored", "ColorPicker", p_theme->get_icon(SNAME("GuiTreeArrowLeft"), EditorStringName(EditorIcons)));

// ColorPickerButton.
p_theme->set_icon("bg", "ColorPickerButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));

// ColorPresetButton.
p_theme->set_stylebox("preset_fg", "ColorPresetButton", make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2));
p_theme->set_icon("preset_bg", "ColorPresetButton", p_theme->get_icon(SNAME("GuiMiniCheckerboard"), EditorStringName(EditorIcons)));
p_theme->set_icon("overbright_indicator", "ColorPresetButton", p_theme->get_icon(SNAME("OverbrightIndicator"), EditorStringName(EditorIcons)));
}
}

Expand Down
8 changes: 4 additions & 4 deletions scene/3d/label_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -797,13 +797,13 @@ Ref<Font> Label3D::_get_font_or_default() const {
}

const StringName theme_name = SceneStringName(font);
List<StringName> theme_types;
ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types);
Vector<StringName> theme_types;
ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), theme_types);

ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context();
List<Ref<Theme>> themes = global_context->get_themes();
Vector<Ref<Theme>> themes = global_context->get_themes();
if (Engine::get_singleton()->is_editor_hint()) {
themes.push_front(ThemeDB::get_singleton()->get_project_theme());
themes.insert(0, ThemeDB::get_singleton()->get_project_theme());
}

for (const Ref<Theme> &theme : themes) {
Expand Down
Loading

0 comments on commit e9d3187

Please sign in to comment.