Add ThemeCache to EditorProperty

This commit is contained in:
kobewi
2025-09-16 01:00:49 +02:00
parent 5950fca36c
commit 4dcb5cf721
2 changed files with 188 additions and 98 deletions

View File

@ -215,12 +215,14 @@ String EditorProperty::get_tooltip_string(const String &p_string) const {
}
Size2 EditorProperty::get_minimum_size() const {
if (theme_cache.font.is_null()) {
// Too early.
return Vector2();
}
Size2 ms;
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Tree"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Tree"));
int separation = 4 * EDSCALE;
ms.height = label.is_empty() ? 0 : font->get_height(font_size) + separation;
int padding = int(EDITOR_GET("interface/theme/base_spacing")) * 2;
ms.height = label.is_empty() ? 0 : theme_cache.font->get_height(theme_cache.font_size) + separation;
for (int i = 0; i < get_child_count(); i++) {
Control *c = as_sortable_control(get_child(i));
@ -236,22 +238,19 @@ Size2 EditorProperty::get_minimum_size() const {
}
if (keying) {
Ref<Texture2D> key = get_editor_theme_icon(SNAME("Key"));
ms.width += key->get_width() + padding + separation + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
ms.width += theme_cache.key_icon->get_width() + theme_cache.padding + theme_cache.horizontal_separation;
}
if (deletable) {
Ref<Texture2D> key = get_editor_theme_icon(SNAME("Close"));
ms.width += key->get_width() + padding + separation + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
ms.width += theme_cache.delete_icon->get_width() + theme_cache.padding + theme_cache.horizontal_separation;
}
if (checkable) {
Ref<Texture2D> check = get_theme_icon(SNAME("checked"), SNAME("CheckBox"));
ms.width += check->get_width() + padding + separation + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
ms.width += theme_cache.checked_icon->get_width() + theme_cache.padding + theme_cache.horizontal_separation;
}
if (bottom_editor != nullptr && bottom_editor->is_visible()) {
ms.height += label.is_empty() ? 0 : get_theme_constant(SNAME("v_separation"));
ms.height += label.is_empty() ? 0 : _get_v_separation();
Size2 bems = bottom_editor->get_combined_minimum_size();
ms.height += bems.height;
ms.width = MAX(ms.width, bems.width);
@ -270,6 +269,10 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p
void EditorProperty::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
EditorInspector::initialize_property_theme(theme_cache, this);
} break;
case NOTIFICATION_ACCESSIBILITY_UPDATE: {
RID ae = get_accessibility_element();
ERR_FAIL_COND(ae.is_null());
@ -299,11 +302,9 @@ void EditorProperty::_notification(int p_what) {
{
int child_room = size.width * (1.0 - split_ratio);
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Tree"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Tree"));
int separation = 4 * EDSCALE;
int height = label.is_empty() ? 0 : font->get_height(font_size) + separation;
int half_padding = EDITOR_GET("interface/theme/base_spacing");
int height = label.is_empty() ? 0 : theme_cache.font->get_height(theme_cache.font_size) + separation;
int half_padding = theme_cache.padding / 2;
bool no_children = true;
//compute room needed
@ -338,7 +339,7 @@ void EditorProperty::_notification(int p_what) {
}
if (bottom_editor) {
int v_offset = label.is_empty() ? 0 : get_theme_constant(SNAME("v_separation"));
int v_offset = label.is_empty() ? 0 : _get_v_separation();
bottom_rect = Rect2(0, rect.size.height + v_offset, size.width, bottom_editor->get_combined_minimum_size().height);
}
@ -346,14 +347,14 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> key;
if (use_keying_next()) {
key = get_editor_theme_icon(SNAME("KeyNext"));
key = theme_cache.key_next_icon;
} else {
key = get_editor_theme_icon(SNAME("Key"));
key = theme_cache.key_icon;
}
rect.size.x -= key->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
rect.size.x -= key->get_width() + half_padding + theme_cache.horizontal_separation;
if (is_layout_rtl()) {
rect.position.x += key->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
rect.position.x += key->get_width() + half_padding + theme_cache.horizontal_separation;
}
if (no_children) {
@ -363,25 +364,21 @@ void EditorProperty::_notification(int p_what) {
}
if (deletable) {
Ref<Texture2D> close;
close = get_editor_theme_icon(SNAME("Close"));
rect.size.x -= close->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
rect.size.x -= theme_cache.delete_icon->get_width() + half_padding + theme_cache.horizontal_separation;
if (is_layout_rtl()) {
rect.position.x += close->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
rect.position.x += theme_cache.delete_icon->get_width() + half_padding + theme_cache.horizontal_separation;
}
if (no_children) {
text_size -= close->get_width() + half_padding + separation;
text_size -= theme_cache.delete_icon->get_width() + half_padding + separation;
}
}
// Account for the space needed on the outer side
// when any of the icons are visible.
if (keying || deletable) {
separation = get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
separation = theme_cache.horizontal_separation;
rect.size.x -= separation;
if (is_layout_rtl()) {
@ -413,13 +410,13 @@ void EditorProperty::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
Ref<Font> font = get_theme_font(SceneStringName(font), SNAME("Tree"));
int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Tree"));
Ref<Font> font = theme_cache.font;
int font_size = theme_cache.font_size;
bool rtl = is_layout_rtl();
Size2 size = get_size();
if (bottom_editor) {
size.height = bottom_editor->get_offset(SIDE_TOP) - get_theme_constant(SNAME("v_separation"));
size.height = bottom_editor->get_offset(SIDE_TOP) - _get_v_separation();
} else if (label_reference) {
size.height = label_reference->get_size().height;
}
@ -427,24 +424,26 @@ void EditorProperty::_notification(int p_what) {
// Only draw the label if it's not empty.
if (label.is_empty()) {
size.height = 0;
} else if (sub_inspector_color_level >= 0) {
draw_style_box(theme_cache.sub_inspector_background[sub_inspector_color_level], Rect2(Vector2(), size));
} else {
Ref<StyleBox> sb = get_theme_stylebox(selected ? SNAME("bg_selected") : SNAME("bg"));
draw_style_box(sb, Rect2(Vector2(), size));
draw_style_box(selected ? theme_cache.background_selected : theme_cache.background, Rect2(Vector2(), size));
}
Ref<StyleBox> bg_stylebox = get_theme_stylebox(SNAME("child_bg"));
if (draw_top_bg && right_child_rect != Rect2() && draw_background) {
draw_style_box(bg_stylebox, right_child_rect);
draw_style_box(theme_cache.child_background, right_child_rect);
}
if (bottom_child_rect != Rect2() && draw_background) {
draw_style_box(bg_stylebox, bottom_child_rect);
draw_style_box(theme_cache.child_background, bottom_child_rect);
}
Color color;
if (draw_warning || draw_prop_warning) {
color = get_theme_color(is_read_only() ? SNAME("readonly_warning_color") : SNAME("warning_color"));
color = is_read_only() ? theme_cache.readonly_warning_color : theme_cache.warning_color;
} else if (is_read_only()) {
color = (sub_inspector_color_level >= 0) ? theme_cache.sub_inspector_property_color : theme_cache.readonly_property_color;
} else {
color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color"));
color = (sub_inspector_color_level >= 0) ? theme_cache.sub_inspector_property_color : theme_cache.property_color;
}
if (label.contains_char('.')) {
// FIXME: Move this to the project settings editor, as this is only used
@ -452,7 +451,7 @@ void EditorProperty::_notification(int p_what) {
color.a = 0.5;
}
int ofs = get_theme_constant(SNAME("font_offset"));
int ofs = theme_cache.font_offset;
int text_limit = text_size - ofs;
int half_padding = EDITOR_GET("interface/theme/base_spacing");
int padding = half_padding * 2;
@ -460,9 +459,9 @@ void EditorProperty::_notification(int p_what) {
if (checkable) {
Ref<Texture2D> checkbox;
if (checked) {
checkbox = get_editor_theme_icon(SNAME("GuiChecked"));
checkbox = theme_cache.checked_icon;
} else {
checkbox = get_editor_theme_icon(SNAME("GuiUnchecked"));
checkbox = theme_cache.unchecked_icon;
}
check_rect = Rect2(ofs, 0, checkbox->get_width() + padding, size.height);
@ -478,11 +477,10 @@ void EditorProperty::_notification(int p_what) {
color2.g *= 1.2;
color2.b *= 1.2;
Ref<StyleBox> sb_hover = get_theme_stylebox(SceneStringName(hover), SceneStringName(FlatButton));
if (rtl) {
draw_style_box(sb_hover, Rect2(rtl_pos, check_rect.size));
draw_style_box(theme_cache.hover, Rect2(rtl_pos, check_rect.size));
} else {
draw_style_box(sb_hover, check_rect);
draw_style_box(theme_cache.hover, check_rect);
}
}
if (rtl) {
@ -490,7 +488,7 @@ void EditorProperty::_notification(int p_what) {
} else {
draw_texture(checkbox, check_rect.position + Point2(padding, size.height - checkbox->get_height()) / 2, color2);
}
int check_ofs = checkbox->get_width() + padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
int check_ofs = checkbox->get_width() + padding + theme_cache.horizontal_separation;
ofs += check_ofs;
text_limit -= check_ofs;
} else {
@ -498,8 +496,8 @@ void EditorProperty::_notification(int p_what) {
}
if (can_revert && !is_read_only()) {
Ref<Texture2D> reload_icon = get_editor_theme_icon(SNAME("ReloadSmall"));
text_limit -= reload_icon->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
const Ref<Texture2D> &reload_icon = theme_cache.revert_icon;
text_limit -= reload_icon->get_width() + half_padding + theme_cache.horizontal_separation;
revert_rect = Rect2(ofs + text_limit, 0, reload_icon->get_width() + padding + (1 * EDSCALE), size.height);
Point2 rtl_pos;
@ -513,11 +511,10 @@ void EditorProperty::_notification(int p_what) {
color2.g *= 1.2;
color2.b *= 1.2;
Ref<StyleBox> sb_hover = get_theme_stylebox(SceneStringName(hover), SceneStringName(FlatButton));
if (rtl) {
draw_style_box(sb_hover, Rect2(rtl_pos, revert_rect.size));
draw_style_box(theme_cache.hover, Rect2(rtl_pos, revert_rect.size));
} else {
draw_style_box(sb_hover, revert_rect);
draw_style_box(theme_cache.hover, revert_rect);
}
}
if (rtl) {
@ -531,8 +528,8 @@ void EditorProperty::_notification(int p_what) {
}
if (!pin_hidden && pinned) {
Ref<Texture2D> pinned_icon = get_editor_theme_icon(SNAME("Pin"));
int margin_w = get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
const Ref<Texture2D> &pinned_icon = theme_cache.pin_icon;
int margin_w = theme_cache.horizontal_separation;
int total_icon_w = margin_w + pinned_icon->get_width();
int text_w = font->get_string_size(label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w, font_size).x;
int y = (size.height - pinned_icon->get_height()) / 2;
@ -557,12 +554,12 @@ void EditorProperty::_notification(int p_what) {
Ref<Texture2D> key;
if (use_keying_next()) {
key = get_editor_theme_icon(SNAME("KeyNext"));
key = theme_cache.key_next_icon;
} else {
key = get_editor_theme_icon(SNAME("Key"));
key = theme_cache.key_icon;
}
ofs -= key->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
ofs -= key->get_width() + half_padding + theme_cache.horizontal_separation;
keying_rect = Rect2(ofs, 0, key->get_width() + padding, size.height);
Point2 rtl_pos;
@ -576,11 +573,10 @@ void EditorProperty::_notification(int p_what) {
color2.g *= 1.2;
color2.b *= 1.2;
Ref<StyleBox> sb_hover = get_theme_stylebox(SceneStringName(hover), SceneStringName(FlatButton));
if (rtl) {
draw_style_box(sb_hover, Rect2(rtl_pos, keying_rect.size));
draw_style_box(theme_cache.hover, Rect2(rtl_pos, keying_rect.size));
} else {
draw_style_box(sb_hover, keying_rect);
draw_style_box(theme_cache.hover, keying_rect);
}
}
@ -595,11 +591,9 @@ void EditorProperty::_notification(int p_what) {
}
if (deletable) {
Ref<Texture2D> close;
const Ref<Texture2D> &close = theme_cache.delete_icon;
close = get_editor_theme_icon(SNAME("Close"));
ofs -= close->get_width() + half_padding + get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
ofs -= close->get_width() + half_padding + theme_cache.horizontal_separation;
delete_rect = Rect2(ofs, 0, close->get_width() + padding, size.height);
Point2 rtl_pos;
@ -613,11 +607,10 @@ void EditorProperty::_notification(int p_what) {
color2.g *= 1.2;
color2.b *= 1.2;
Ref<StyleBox> sb_hover = get_theme_stylebox(SceneStringName(hover), SceneStringName(FlatButton));
if (rtl) {
draw_style_box(sb_hover, Rect2(rtl_pos, delete_rect.size));
draw_style_box(theme_cache.hover, Rect2(rtl_pos, delete_rect.size));
} else {
draw_style_box(sb_hover, delete_rect);
draw_style_box(theme_cache.hover, delete_rect);
}
}
@ -758,41 +751,34 @@ void EditorProperty::_update_property_bg() {
return;
}
begin_bulk_theme_override();
if (bottom_editor) {
ColorationMode nested_color_mode = (ColorationMode)(int)EDITOR_GET("interface/inspector/nested_color_mode");
bool delimitate_all_container_and_resources = EDITOR_GET("interface/inspector/delimitate_all_container_and_resources");
int count_subinspectors = 0;
sub_inspector_color_level = 0;
if (is_colored(nested_color_mode)) {
Node *n = this;
while (n) {
EditorProperty *ep = Object::cast_to<EditorProperty>(n);
if (ep && ep->is_colored(nested_color_mode)) {
count_subinspectors++;
sub_inspector_color_level++;
if (sub_inspector_color_level == 16) {
break;
}
}
n = n->get_parent();
}
count_subinspectors = MIN(16, count_subinspectors);
}
add_theme_style_override(SNAME("DictionaryAddItem"), get_theme_stylebox("DictionaryAddItem" + itos(count_subinspectors), EditorStringName(EditorStyles)));
add_theme_constant_override("v_separation", 0);
add_theme_style_override(SNAME("DictionaryAddItem"), get_theme_stylebox("DictionaryAddItem" + itos(sub_inspector_color_level), EditorStringName(EditorStyles)));
if (delimitate_all_container_and_resources || is_colored(nested_color_mode)) {
add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), EditorStringName(EditorStyles)));
add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), EditorStringName(EditorStyles)));
add_theme_color_override("property_color", get_theme_color(SNAME("sub_inspector_property_color"), EditorStringName(EditorStyles)));
add_theme_color_override("readonly_color", get_theme_color(SNAME("sub_inspector_property_color"), EditorStringName(EditorStyles)));
bottom_editor->add_theme_style_override(SceneStringName(panel), get_theme_stylebox("sub_inspector_bg" + itos(count_subinspectors), EditorStringName(EditorStyles)));
bottom_editor->add_theme_style_override(SceneStringName(panel), get_theme_stylebox("sub_inspector_bg" + itos(sub_inspector_color_level), EditorStringName(EditorStyles)));
} else {
bottom_editor->add_theme_style_override(SceneStringName(panel), get_theme_stylebox("sub_inspector_bg_no_border", EditorStringName(EditorStyles)));
sub_inspector_color_level = -1;
}
} else {
remove_theme_style_override("bg_selected");
remove_theme_style_override("bg");
remove_theme_color_override("property_color");
remove_theme_color_override("readonly_color");
sub_inspector_color_level = -1;
}
end_bulk_theme_override();
queue_redraw();
}
@ -1146,10 +1132,10 @@ void EditorProperty::shortcut_input(const Ref<InputEvent> &p_event) {
const Color *EditorProperty::_get_property_colors() {
static Color c[4];
c[0] = get_theme_color(SNAME("property_color_x"), EditorStringName(Editor));
c[1] = get_theme_color(SNAME("property_color_y"), EditorStringName(Editor));
c[2] = get_theme_color(SNAME("property_color_z"), EditorStringName(Editor));
c[3] = get_theme_color(SNAME("property_color_w"), EditorStringName(Editor));
c[0] = theme_cache.property_color_x;
c[1] = theme_cache.property_color_y;
c[2] = theme_cache.property_color_z;
c[3] = theme_cache.property_color_w;
return c;
}
@ -1316,7 +1302,7 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
if (object->has_method("_get_property_warning")) {
const String custom_warning = object->call("_get_property_warning", property);
if (!custom_warning.is_empty()) {
prologue = "[b][color=" + get_theme_color(SNAME("warning_color")).to_html(false) + "]" + custom_warning + "[/color][/b]";
prologue = "[b][color=" + theme_cache.warning_color.to_html(false) + "]" + custom_warning + "[/color][/b]";
}
}
@ -1492,9 +1478,9 @@ void EditorProperty::_update_popup() {
add_child(menu);
menu->connect(SceneStringName(id_pressed), callable_mp(this, &EditorProperty::menu_option));
}
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionCopy")), ED_GET_SHORTCUT("property_editor/copy_value"), MENU_COPY_VALUE);
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("ActionPaste")), ED_GET_SHORTCUT("property_editor/paste_value"), MENU_PASTE_VALUE);
menu->add_icon_shortcut(get_editor_theme_icon(SNAME("CopyNodePath")), ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
menu->add_icon_shortcut(theme_cache.copy_icon, ED_GET_SHORTCUT("property_editor/copy_value"), MENU_COPY_VALUE);
menu->add_icon_shortcut(theme_cache.paste_icon, ED_GET_SHORTCUT("property_editor/paste_value"), MENU_PASTE_VALUE);
menu->add_icon_shortcut(theme_cache.copy_node_path_icon, ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
menu->set_item_disabled(MENU_PASTE_VALUE, is_read_only());
menu->set_item_disabled(MENU_COPY_PROPERTY_PATH, internal);
@ -1504,21 +1490,21 @@ void EditorProperty::_update_popup() {
if (can_favorite) {
if (favorited) {
menu->add_icon_item(get_editor_theme_icon(SNAME("Unfavorite")), TTR("Unfavorite Property"), MENU_FAVORITE_PROPERTY);
menu->add_icon_item(theme_cache.unfavorite_icon, TTR("Unfavorite Property"), MENU_FAVORITE_PROPERTY);
menu->set_item_tooltip(menu->get_item_index(MENU_FAVORITE_PROPERTY), TTR("Make this property be put back at its original place."));
} else {
// TRANSLATORS: This is a menu item to add a property to the favorites.
menu->add_icon_item(get_editor_theme_icon(SNAME("Favorites")), TTR("Favorite Property"), MENU_FAVORITE_PROPERTY);
menu->add_icon_item(theme_cache.favorite_icon, TTR("Favorite Property"), MENU_FAVORITE_PROPERTY);
menu->set_item_tooltip(menu->get_item_index(MENU_FAVORITE_PROPERTY), TTR("Make this property be placed at the top for all objects of this class."));
}
}
if (!pin_hidden) {
if (can_pin) {
menu->add_icon_check_item(get_editor_theme_icon(SNAME("Pin")), TTR("Pin Value"), MENU_PIN_VALUE);
menu->add_icon_check_item(theme_cache.pin_icon, TTR("Pin Value"), MENU_PIN_VALUE);
menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned);
} else {
menu->add_icon_check_item(get_editor_theme_icon(SNAME("Pin")), vformat(TTR("Pin Value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
menu->add_icon_check_item(theme_cache.pin_icon, vformat(TTR("Pin Value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
menu->set_item_disabled(menu->get_item_index(MENU_PIN_VALUE), true);
}
menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
@ -1526,18 +1512,18 @@ void EditorProperty::_update_popup() {
if (deletable || can_revert || can_override) {
menu->add_separator();
if (can_override) {
menu->add_icon_item(get_editor_theme_icon(SNAME("Override")), TTRC("Override for Project"), MENU_OVERRIDE_FOR_PROJECT);
menu->add_icon_item(theme_cache.override_icon, TTRC("Override for Project"), MENU_OVERRIDE_FOR_PROJECT);
}
if (deletable) {
menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Property"), MENU_DELETE);
menu->add_icon_item(theme_cache.remove_icon, TTR("Delete Property"), MENU_DELETE);
}
if (can_revert) {
menu->add_icon_item(get_editor_theme_icon(SNAME("Reload")), TTR("Revert Value"), MENU_REVERT_VALUE);
menu->add_icon_item(theme_cache.revert_icon, TTR("Revert Value"), MENU_REVERT_VALUE);
}
}
if (!doc_path.is_empty()) {
menu->add_separator();
menu->add_icon_item(get_editor_theme_icon(SNAME("Help")), TTR("Open Documentation"), MENU_OPEN_DOCUMENTATION);
menu->add_icon_item(theme_cache.help_icon, TTR("Open Documentation"), MENU_OPEN_DOCUMENTATION);
}
}
@ -3535,6 +3521,60 @@ void EditorInspector::initialize_category_theme(EditorInspectorCategory::ThemeCa
p_cache.background = p_control->get_theme_stylebox(SNAME("bg"), SNAME("EditorInspectorCategory"));
}
void EditorInspector::initialize_property_theme(EditorProperty::ThemeCache &p_cache, Control *p_control) {
EditorInspector *parent_inspector = _get_control_parent_inspector(p_control);
if (parent_inspector && parent_inspector != p_control) {
p_cache = parent_inspector->property_theme_cache;
return;
}
p_cache.font = p_control->get_theme_font(SceneStringName(font), SNAME("Tree"));
p_cache.background = p_control->get_theme_stylebox(SNAME("bg"), SNAME("EditorProperty"));
p_cache.background_selected = p_control->get_theme_stylebox(SNAME("bg_selected"), SNAME("EditorProperty"));
p_cache.child_background = p_control->get_theme_stylebox(SNAME("child_bg"), SNAME("EditorProperty"));
p_cache.hover = p_control->get_theme_stylebox(SceneStringName(hover), SceneStringName(FlatButton));
p_cache.key_icon = p_control->get_editor_theme_icon(SNAME("Key"));
p_cache.key_next_icon = p_control->get_editor_theme_icon(SNAME("KeyNext"));
p_cache.delete_icon = p_control->get_editor_theme_icon(SNAME("Close"));
p_cache.checked_icon = p_control->get_editor_theme_icon(SNAME("GuiChecked"));
p_cache.unchecked_icon = p_control->get_editor_theme_icon(SNAME("GuiUnchecked"));
p_cache.revert_icon = p_control->get_editor_theme_icon(SNAME("ReloadSmall"));
p_cache.pin_icon = p_control->get_editor_theme_icon(SNAME("Pin"));
p_cache.copy_icon = p_control->get_editor_theme_icon(SNAME("ActionCopy"));
p_cache.copy_node_path_icon = p_control->get_editor_theme_icon(SNAME("CopyNodePath"));
p_cache.paste_icon = p_control->get_editor_theme_icon(SNAME("ActionPaste"));
p_cache.unfavorite_icon = p_control->get_editor_theme_icon(SNAME("Unfavorite"));
p_cache.favorite_icon = p_control->get_editor_theme_icon(SNAME("Favorites"));
p_cache.override_icon = p_control->get_editor_theme_icon(SNAME("Override"));
p_cache.remove_icon = p_control->get_editor_theme_icon(SNAME("Remove"));
p_cache.help_icon = p_control->get_editor_theme_icon(SNAME("Help"));
p_cache.font_size = p_control->get_theme_font_size(SceneStringName(font_size), SNAME("Tree"));
p_cache.font_offset = p_control->get_theme_constant(SNAME("font_offset"), SNAME("EditorProperty"));
p_cache.horizontal_separation = p_control->get_theme_constant(SNAME("h_separation"), SNAME("Tree"));
p_cache.vertical_separation = p_control->get_theme_constant(SNAME("v_separation"), SNAME("EditorProperty"));
p_cache.padding = int(EDITOR_GET("interface/theme/base_spacing")) * 2;
p_cache.property_color = p_control->get_theme_color(SNAME("property_color"), SNAME("EditorProperty"));
p_cache.readonly_property_color = p_control->get_theme_color(SNAME("readonly_color"), SNAME("EditorProperty"));
p_cache.warning_color = p_control->get_theme_color(SNAME("warning_color"), SNAME("EditorProperty"));
p_cache.readonly_warning_color = p_control->get_theme_color(SNAME("readonly_warning_color"), SNAME("EditorProperty"));
p_cache.property_color_x = p_control->get_theme_color(SNAME("property_color_x"), EditorStringName(Editor));
p_cache.property_color_y = p_control->get_theme_color(SNAME("property_color_y"), EditorStringName(Editor));
p_cache.property_color_z = p_control->get_theme_color(SNAME("property_color_z"), EditorStringName(Editor));
p_cache.property_color_w = p_control->get_theme_color(SNAME("property_color_w"), EditorStringName(Editor));
p_cache.sub_inspector_property_color = p_control->get_theme_color(SNAME("sub_inspector_property_color"), EditorStringName(EditorStyles));
if (p_control == parent_inspector) {
// Only initialize for the inspector, as stand-alone properties won't need it.
for (int i = 0; i <= 16; i++) {
p_cache.sub_inspector_background[i] = p_control->get_theme_stylebox("sub_inspector_property_bg" + itos(i), EditorStringName(EditorStyles));
}
}
}
void EditorInspector::add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin) {
ERR_FAIL_COND(inspector_plugin_count == MAX_PLUGINS);
@ -5499,6 +5539,7 @@ void EditorInspector::_notification(int p_what) {
initialize_section_theme(section_theme_cache, this);
initialize_category_theme(category_theme_cache, this);
initialize_property_theme(property_theme_cache, this);
base_vbox->add_theme_constant_override("separation", theme_cache.vertical_separation);
begin_vbox->add_theme_constant_override("separation", theme_cache.vertical_separation);

View File

@ -73,6 +73,50 @@ public:
class EditorProperty : public Container {
GDCLASS(EditorProperty, Container);
friend class EditorInspector;
struct ThemeCache {
Ref<Font> font;
Ref<StyleBox> background;
Ref<StyleBox> background_selected;
Ref<StyleBox> child_background;
Ref<StyleBox> hover;
Ref<StyleBox> sub_inspector_background[17];
Ref<Texture2D> key_icon;
Ref<Texture2D> key_next_icon;
Ref<Texture2D> delete_icon;
Ref<Texture2D> checked_icon;
Ref<Texture2D> unchecked_icon;
Ref<Texture2D> revert_icon;
Ref<Texture2D> pin_icon;
Ref<Texture2D> copy_icon;
Ref<Texture2D> copy_node_path_icon;
Ref<Texture2D> paste_icon;
Ref<Texture2D> unfavorite_icon;
Ref<Texture2D> favorite_icon;
Ref<Texture2D> override_icon;
Ref<Texture2D> remove_icon;
Ref<Texture2D> help_icon;
int font_size = 0;
int font_offset = 0;
int horizontal_separation = 0;
int vertical_separation = 0;
int padding = 0;
Color property_color;
Color readonly_property_color;
Color warning_color;
Color readonly_warning_color;
Color property_color_x;
Color property_color_y;
Color property_color_z;
Color property_color_w;
Color sub_inspector_property_color;
} theme_cache;
public:
enum MenuItems {
MENU_COPY_VALUE,
@ -138,8 +182,11 @@ private:
bool use_folding = false;
bool draw_top_bg = true;
int sub_inspector_color_level = -1;
void _update_popup();
void _focusable_focused(int p_index);
int _get_v_separation() const { return bottom_editor ? 0 : theme_cache.vertical_separation; }
bool selectable = true;
bool selected = false;
@ -651,6 +698,7 @@ class EditorInspector : public ScrollContainer {
EditorInspectorSection::ThemeCache section_theme_cache;
EditorInspectorCategory::ThemeCache category_theme_cache;
EditorProperty::ThemeCache property_theme_cache;
bool can_favorite = false;
PackedStringArray current_favorites;
@ -787,6 +835,7 @@ public:
static void initialize_section_theme(EditorInspectorSection::ThemeCache &p_cache, Control *p_control);
static void initialize_category_theme(EditorInspectorCategory::ThemeCache &p_cache, Control *p_control);
static void initialize_property_theme(EditorProperty::ThemeCache &p_cache, Control *p_control);
bool is_main_editor_inspector() const;
String get_selected_path() const;