1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-15 13:51:40 +00:00

Improve Variant type menus in the editor

This commit is contained in:
Haoyu Qiu
2025-05-28 09:18:32 +08:00
parent 2cde9292c3
commit 19226d77ed
12 changed files with 297 additions and 100 deletions

View File

@@ -31,9 +31,9 @@
#include "add_metadata_dialog.h" #include "add_metadata_dialog.h"
#include "editor/gui/editor_validation_panel.h" #include "editor/gui/editor_validation_panel.h"
#include "editor/gui/editor_variant_type_selectors.h"
#include "editor/themes/editor_scale.h" #include "editor/themes/editor_scale.h"
#include "scene/gui/line_edit.h" #include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
AddMetadataDialog::AddMetadataDialog() { AddMetadataDialog::AddMetadataDialog() {
VBoxContainer *vbc = memnew(VBoxContainer); VBoxContainer *vbc = memnew(VBoxContainer);
@@ -49,7 +49,7 @@ AddMetadataDialog::AddMetadataDialog() {
hbc->add_child(add_meta_name); hbc->add_child(add_meta_name);
hbc->add_child(memnew(Label(TTR("Type:")))); hbc->add_child(memnew(Label(TTR("Type:"))));
add_meta_type = memnew(OptionButton); add_meta_type = memnew(EditorVariantTypeOptionButton);
add_meta_type->set_accessibility_name(TTRC("Type:")); add_meta_type->set_accessibility_name(TTRC("Type:"));
hbc->add_child(add_meta_type); hbc->add_child(add_meta_type);
@@ -76,19 +76,8 @@ void AddMetadataDialog::_complete_init(const StringName &p_title) {
set_title(vformat(TTR("Add Metadata Property for \"%s\""), p_title)); set_title(vformat(TTR("Add Metadata Property for \"%s\""), p_title));
// Skip if we already completed the initialization. if (add_meta_type->get_item_count() == 0) {
if (add_meta_type->get_item_count()) { add_meta_type->populate({ Variant::NIL }, { { Variant::OBJECT, "Resource" } });
return;
}
// Theme icons can be retrieved only the Window has been initialized.
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (i == Variant::NIL || i == Variant::RID || i == Variant::CALLABLE || i == Variant::SIGNAL) {
continue; //not editable by inspector.
}
String type = i == Variant::OBJECT ? String("Resource") : Variant::get_type_name(Variant::Type(i));
add_meta_type->add_icon_item(get_editor_theme_icon(type), type, i);
} }
} }
@@ -106,7 +95,7 @@ StringName AddMetadataDialog::get_meta_name() {
Variant AddMetadataDialog::get_meta_defval() { Variant AddMetadataDialog::get_meta_defval() {
Variant defval; Variant defval;
Callable::CallError ce; Callable::CallError ce;
Variant::construct(Variant::Type(add_meta_type->get_selected_id()), defval, nullptr, 0, ce); Variant::construct(add_meta_type->get_selected_type(), defval, nullptr, 0, ce);
return defval; return defval;
} }

View File

@@ -33,8 +33,8 @@
#include "scene/gui/dialogs.h" #include "scene/gui/dialogs.h"
class EditorValidationPanel; class EditorValidationPanel;
class EditorVariantTypeOptionButton;
class LineEdit; class LineEdit;
class OptionButton;
class AddMetadataDialog : public ConfirmationDialog { class AddMetadataDialog : public ConfirmationDialog {
GDCLASS(AddMetadataDialog, ConfirmationDialog); GDCLASS(AddMetadataDialog, ConfirmationDialog);
@@ -53,6 +53,6 @@ private:
void _complete_init(const StringName &p_label); void _complete_init(const StringName &p_label);
LineEdit *add_meta_name = nullptr; LineEdit *add_meta_name = nullptr;
OptionButton *add_meta_type = nullptr; EditorVariantTypeOptionButton *add_meta_type = nullptr;
EditorValidationPanel *validation_panel = nullptr; EditorValidationPanel *validation_panel = nullptr;
}; };

View File

@@ -39,6 +39,7 @@
#include "editor/editor_settings.h" #include "editor/editor_settings.h"
#include "editor/editor_string_names.h" #include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h" #include "editor/editor_undo_redo_manager.h"
#include "editor/gui/editor_variant_type_selectors.h"
#include "editor/gui/scene_tree_editor.h" #include "editor/gui/scene_tree_editor.h"
#include "editor/node_dock.h" #include "editor/node_dock.h"
#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h"
@@ -46,11 +47,11 @@
#include "editor/themes/editor_scale.h" #include "editor/themes/editor_scale.h"
#include "scene/gui/button.h" #include "scene/gui/button.h"
#include "scene/gui/check_box.h" #include "scene/gui/check_box.h"
#include "scene/gui/check_button.h"
#include "scene/gui/flow_container.h" #include "scene/gui/flow_container.h"
#include "scene/gui/label.h" #include "scene/gui/label.h"
#include "scene/gui/line_edit.h" #include "scene/gui/line_edit.h"
#include "scene/gui/margin_container.h" #include "scene/gui/margin_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h" #include "scene/gui/popup_menu.h"
#include "scene/gui/spin_box.h" #include "scene/gui/spin_box.h"
@@ -209,7 +210,7 @@ void ConnectDialog::_method_selected() {
* Adds a new parameter bind to connection. * Adds a new parameter bind to connection.
*/ */
void ConnectDialog::_add_bind() { void ConnectDialog::_add_bind() {
Variant::Type type = (Variant::Type)type_list->get_item_id(type_list->get_selected()); Variant::Type type = type_list->get_selected_type();
Variant value; Variant value;
Callable::CallError err; Callable::CallError err;
@@ -493,11 +494,6 @@ void ConnectDialog::_notification(int p_what) {
[[fallthrough]]; [[fallthrough]];
} }
case NOTIFICATION_THEME_CHANGED: { case NOTIFICATION_THEME_CHANGED: {
for (int i = 0; i < type_list->get_item_count(); i++) {
String type_name = Variant::get_type_name((Variant::Type)type_list->get_item_id(i));
type_list->set_item_icon(i, get_editor_theme_icon(type_name));
}
method_search->set_right_icon(get_editor_theme_icon("Search")); method_search->set_right_icon(get_editor_theme_icon("Search"));
open_method_tree->set_button_icon(get_editor_theme_icon("Edit")); open_method_tree->set_button_icon(get_editor_theme_icon("Edit"));
} break; } break;
@@ -839,18 +835,11 @@ ConnectDialog::ConnectDialog() {
HBoxContainer *add_bind_hb = memnew(HBoxContainer); HBoxContainer *add_bind_hb = memnew(HBoxContainer);
type_list = memnew(OptionButton); type_list = memnew(EditorVariantTypeOptionButton);
type_list->set_accessibility_name(TTRC("Type")); type_list->set_accessibility_name(TTRC("Type"));
type_list->set_h_size_flags(Control::SIZE_EXPAND_FILL); type_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
type_list->populate({ Variant::NIL, Variant::OBJECT });
add_bind_hb->add_child(type_list); add_bind_hb->add_child(type_list);
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (i == Variant::NIL || i == Variant::OBJECT || i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
// These types can't be constructed or serialized properly, so skip them.
continue;
}
type_list->add_item(Variant::get_type_name(Variant::Type(i)), i);
}
bind_controls.push_back(type_list); bind_controls.push_back(type_list);
Button *add_bind = memnew(Button); Button *add_bind = memnew(Button);

View File

@@ -30,14 +30,15 @@
#pragma once #pragma once
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h" #include "scene/gui/dialogs.h"
#include "scene/gui/tree.h" #include "scene/gui/tree.h"
class Button; class Button;
class CheckBox; class CheckBox;
class CheckButton;
class ConnectDialogBinds; class ConnectDialogBinds;
class EditorInspector; class EditorInspector;
class EditorVariantTypeOptionButton;
class Label; class Label;
class LineEdit; class LineEdit;
class OptionButton; class OptionButton;
@@ -133,7 +134,7 @@ private:
SpinBox *unbind_count = nullptr; SpinBox *unbind_count = nullptr;
EditorInspector *bind_editor = nullptr; EditorInspector *bind_editor = nullptr;
OptionButton *type_list = nullptr; EditorVariantTypeOptionButton *type_list = nullptr;
CheckBox *deferred = nullptr; CheckBox *deferred = nullptr;
CheckBox *one_shot = nullptr; CheckBox *one_shot = nullptr;
CheckBox *append_source = nullptr; CheckBox *append_source = nullptr;

View File

@@ -41,6 +41,7 @@
#include "editor/editor_string_names.h" #include "editor/editor_string_names.h"
#include "editor/gui/editor_file_dialog.h" #include "editor/gui/editor_file_dialog.h"
#include "editor/gui/editor_spin_slider.h" #include "editor/gui/editor_spin_slider.h"
#include "editor/gui/editor_variant_type_selectors.h"
#include "editor/gui/scene_tree_editor.h" #include "editor/gui/scene_tree_editor.h"
#include "editor/inspector_dock.h" #include "editor/inspector_dock.h"
#include "editor/plugins/script_editor_plugin.h" #include "editor/plugins/script_editor_plugin.h"
@@ -80,8 +81,20 @@ void EditorPropertyVariant::_change_type(int p_to_type) {
emit_changed(get_edited_property(), zero); emit_changed(get_edited_property(), zero);
} }
void EditorPropertyVariant::_popup_edit_menu() {
if (change_type == nullptr) {
change_type = memnew(EditorVariantTypePopupMenu(false));
change_type->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyVariant::_change_type));
content->add_child(change_type);
}
Rect2 rect = edit_button->get_screen_rect();
change_type->set_position(rect.get_end() - Vector2(change_type->get_contents_minimum_size().x, 0));
change_type->popup();
}
void EditorPropertyVariant::_set_read_only(bool p_read_only) { void EditorPropertyVariant::_set_read_only(bool p_read_only) {
change_type->set_disabled(p_read_only); edit_button->set_disabled(p_read_only);
if (sub_property) { if (sub_property) {
sub_property->set_read_only(p_read_only); sub_property->set_read_only(p_read_only);
} }
@@ -89,12 +102,7 @@ void EditorPropertyVariant::_set_read_only(bool p_read_only) {
void EditorPropertyVariant::_notification(int p_what) { void EditorPropertyVariant::_notification(int p_what) {
if (p_what == NOTIFICATION_THEME_CHANGED) { if (p_what == NOTIFICATION_THEME_CHANGED) {
change_type->set_button_icon(get_editor_theme_icon("Edit")); edit_button->set_button_icon(get_editor_theme_icon(SNAME("Edit")));
PopupMenu *popup = change_type->get_popup();
for (int i = 0; i < popup->get_item_count(); i++) {
popup->set_item_icon(i, get_editor_theme_icon(Variant::get_type_name(Variant::Type(popup->get_item_id(i)))));
}
} }
} }
@@ -139,19 +147,11 @@ EditorPropertyVariant::EditorPropertyVariant() {
content = memnew(HBoxContainer); content = memnew(HBoxContainer);
add_child(content); add_child(content);
change_type = memnew(MenuButton); edit_button = memnew(Button);
change_type->set_flat(false); edit_button->set_flat(true);
edit_button->set_accessibility_name(TTRC("Edit"));
PopupMenu *popup = change_type->get_popup(); edit_button->connect(SceneStringName(pressed), callable_mp(this, &EditorPropertyVariant::_popup_edit_menu));
for (int i = 0; i < Variant::VARIANT_MAX; i++) { content->add_child(edit_button);
if (i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
// These types can't be constructed or serialized properly, so skip them.
continue;
}
popup->add_item(Variant::get_type_name(Variant::Type(i)), i);
}
popup->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyVariant::_change_type));
content->add_child(change_type);
} }
///////////////////// TEXT ///////////////////////// ///////////////////// TEXT /////////////////////////

View File

@@ -39,6 +39,7 @@ class EditorFileDialog;
class EditorLocaleDialog; class EditorLocaleDialog;
class EditorResourcePicker; class EditorResourcePicker;
class EditorSpinSlider; class EditorSpinSlider;
class EditorVariantTypePopupMenu;
class MenuButton; class MenuButton;
class PropertySelector; class PropertySelector;
class SceneTreeDialog; class SceneTreeDialog;
@@ -59,12 +60,14 @@ class EditorPropertyVariant : public EditorProperty {
HBoxContainer *content = nullptr; HBoxContainer *content = nullptr;
EditorProperty *sub_property = nullptr; EditorProperty *sub_property = nullptr;
MenuButton *change_type = nullptr; Button *edit_button = nullptr;
EditorVariantTypePopupMenu *change_type = nullptr;
Variant::Type current_type = Variant::VARIANT_MAX; Variant::Type current_type = Variant::VARIANT_MAX;
Variant::Type new_type = Variant::VARIANT_MAX; Variant::Type new_type = Variant::VARIANT_MAX;
void _change_type(int p_to_type); void _change_type(int p_to_type);
void _popup_edit_menu();
protected: protected:
virtual void _set_read_only(bool p_read_only) override; virtual void _set_read_only(bool p_read_only) override;

View File

@@ -39,6 +39,7 @@
#include "editor/editor_settings.h" #include "editor/editor_settings.h"
#include "editor/editor_string_names.h" #include "editor/editor_string_names.h"
#include "editor/gui/editor_spin_slider.h" #include "editor/gui/editor_spin_slider.h"
#include "editor/gui/editor_variant_type_selectors.h"
#include "editor/inspector_dock.h" #include "editor/inspector_dock.h"
#include "editor/themes/editor_scale.h" #include "editor/themes/editor_scale.h"
#include "scene/gui/button.h" #include "scene/gui/button.h"
@@ -750,19 +751,6 @@ Node *EditorPropertyArray::get_base_node() {
void EditorPropertyArray::_notification(int p_what) { void EditorPropertyArray::_notification(int p_what) {
switch (p_what) { switch (p_what) {
case NOTIFICATION_THEME_CHANGED: { case NOTIFICATION_THEME_CHANGED: {
change_type->clear();
change_type->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Remove Item"), Variant::VARIANT_MAX);
change_type->add_separator();
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
// These types can't be constructed or serialized properly, so skip them.
continue;
}
String type = Variant::get_type_name(Variant::Type(i));
change_type->add_icon_item(get_editor_theme_icon(type), type, i);
}
if (button_add_item) { if (button_add_item) {
button_add_item->set_button_icon(get_editor_theme_icon(SNAME("Add"))); button_add_item->set_button_icon(get_editor_theme_icon(SNAME("Add")));
} }
@@ -977,7 +965,7 @@ EditorPropertyArray::EditorPropertyArray() {
add_child(edit); add_child(edit);
add_focusable(edit); add_focusable(edit);
change_type = memnew(PopupMenu); change_type = memnew(EditorVariantTypePopupMenu(true));
add_child(change_type); add_child(change_type);
change_type->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyArray::_change_type_menu)); change_type->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyArray::_change_type_menu));
changing_type_index = -1; changing_type_index = -1;
@@ -1465,19 +1453,6 @@ void EditorPropertyDictionary::_object_id_selected(const StringName &p_property,
void EditorPropertyDictionary::_notification(int p_what) { void EditorPropertyDictionary::_notification(int p_what) {
switch (p_what) { switch (p_what) {
case NOTIFICATION_THEME_CHANGED: { case NOTIFICATION_THEME_CHANGED: {
change_type->clear();
change_type->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Remove Item"), Variant::VARIANT_MAX);
change_type->add_separator();
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
// These types can't be constructed or serialized properly, so skip them.
continue;
}
String type = Variant::get_type_name(Variant::Type(i));
change_type->add_icon_item(get_editor_theme_icon(type), type, i);
}
if (button_add_item) { if (button_add_item) {
button_add_item->set_button_icon(get_editor_theme_icon(SNAME("Add"))); button_add_item->set_button_icon(get_editor_theme_icon(SNAME("Add")));
add_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("DictionaryAddItem"))); add_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("DictionaryAddItem")));
@@ -1532,7 +1507,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
container = nullptr; container = nullptr;
button_add_item = nullptr; button_add_item = nullptr;
paginator = nullptr; paginator = nullptr;
change_type = memnew(PopupMenu); change_type = memnew(EditorVariantTypePopupMenu(true));
add_child(change_type); add_child(change_type);
change_type->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyDictionary::_change_type_menu)); change_type->connect(SceneStringName(id_pressed), callable_mp(this, &EditorPropertyDictionary::_change_type_menu));
changing_type_index = EditorPropertyDictionaryObject::NOT_CHANGING_TYPE; changing_type_index = EditorPropertyDictionaryObject::NOT_CHANGING_TYPE;

View File

@@ -35,6 +35,7 @@
class Button; class Button;
class EditorSpinSlider; class EditorSpinSlider;
class EditorVariantTypePopupMenu;
class MarginContainer; class MarginContainer;
class EditorPropertyArrayObject : public RefCounted { class EditorPropertyArrayObject : public RefCounted {
@@ -108,7 +109,7 @@ class EditorPropertyArray : public EditorProperty {
} }
}; };
PopupMenu *change_type = nullptr; EditorVariantTypePopupMenu *change_type = nullptr;
bool preview_value = false; bool preview_value = false;
int page_length = 20; int page_length = 20;
@@ -221,7 +222,7 @@ class EditorPropertyDictionary : public EditorProperty {
} }
}; };
PopupMenu *change_type = nullptr; EditorVariantTypePopupMenu *change_type = nullptr;
bool updating = false; bool updating = false;
bool preview_value = false; bool preview_value = false;

View File

@@ -0,0 +1,179 @@
/**************************************************************************/
/* editor_variant_type_selectors.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "editor_variant_type_selectors.h"
struct CompareVariantTypeNames {
bool operator()(const String &p_lhs, const String &p_rhs) const {
// Variant type names should not be empty, but just in case.
DEV_ASSERT(!p_lhs.is_empty() && !p_rhs.is_empty());
// Variant type names are ascii strings.
const bool lhs_lower = is_ascii_lower_case(p_lhs[0]);
const bool rhs_lower = is_ascii_lower_case(p_rhs[0]);
if (lhs_lower != rhs_lower) {
// Lowercase types like `int` and `float` come first.
return lhs_lower > rhs_lower;
}
return p_lhs < p_rhs;
}
};
// EditorVariantTypeOptionButton
void EditorVariantTypeOptionButton::_update_menu_icons() {
for (int i = 0; i < get_item_count(); i++) {
const Variant::Type type = Variant::Type(get_item_id(i));
const String &type_name = Variant::get_type_name(type);
set_item_icon(i, get_editor_theme_icon(type_name));
}
}
void EditorVariantTypeOptionButton::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_POSTINITIALIZE: {
set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
} break;
case NOTIFICATION_THEME_CHANGED: {
_update_menu_icons();
} break;
}
}
Variant::Type EditorVariantTypeOptionButton::get_selected_type() const {
int selected = get_selected();
if (selected == -1) {
return Variant::NIL;
}
return Variant::Type(get_item_id(selected));
}
void EditorVariantTypeOptionButton::populate(const LocalVector<Variant::Type> &p_disabled_types, const HashMap<Variant::Type, String> &p_renames) {
LocalVector<String> names;
HashMap<String, Variant::Type> name_to_type;
names.reserve(Variant::VARIANT_MAX);
name_to_type.reserve(Variant::VARIANT_MAX);
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
const Variant::Type type = Variant::Type(i);
if (p_disabled_types.has(type) || type == Variant::RID || type == Variant::CALLABLE || type == Variant::SIGNAL) {
continue;
}
const String &type_name = Variant::get_type_name(type);
const String &display_name = p_renames.has(type) ? p_renames[type] : type_name;
names.push_back(display_name);
name_to_type[display_name] = type;
}
names.sort_custom<CompareVariantTypeNames>();
for (const String &name : names) {
add_item(name, name_to_type[name]);
}
_update_menu_icons();
}
// EditorVariantTypeArrayItemMenu
void EditorVariantTypePopupMenu::_populate() {
if (remove_item) {
add_item(TTRC("Remove Item"), Variant::VARIANT_MAX);
set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_ALWAYS);
add_separator();
}
LocalVector<String> names;
names.reserve(Variant::VARIANT_MAX);
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
const Variant::Type type = Variant::Type(i);
if (type == Variant::RID || type == Variant::CALLABLE || type == Variant::SIGNAL) {
continue;
}
names.push_back(Variant::get_type_name(type));
}
names.sort_custom<CompareVariantTypeNames>();
for (const String &name : names) {
add_item(name, Variant::get_type_by_name(name));
}
}
void EditorVariantTypePopupMenu::_update_menu_icons() {
if (remove_item) {
set_item_icon(get_item_index(Variant::VARIANT_MAX), get_editor_theme_icon(SNAME("Remove")));
}
for (int i = 0; i < get_item_count(); i++) {
int id = get_item_id(i);
// Skip the Remove Item option and the separator without hardcoding the index.
if (id < 0 || id >= Variant::VARIANT_MAX) {
continue;
}
const Variant::Type type = Variant::Type(id);
const String &type_name = Variant::get_type_name(type);
set_item_icon(i, get_editor_theme_icon(type_name));
}
}
void EditorVariantTypePopupMenu::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_POSTINITIALIZE: {
set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
_populate();
} break;
case NOTIFICATION_THEME_CHANGED: {
icons_dirty = true;
} break;
}
}
void EditorVariantTypePopupMenu::popup(const Rect2i &p_bounds) {
if (icons_dirty) {
_update_menu_icons();
icons_dirty = false;
}
PopupMenu::popup(p_bounds);
}
EditorVariantTypePopupMenu::EditorVariantTypePopupMenu(bool p_remove_item) {
remove_item = p_remove_item;
}

View File

@@ -0,0 +1,67 @@
/**************************************************************************/
/* editor_variant_type_selectors.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#pragma once
#include "core/variant/variant.h"
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
class EditorVariantTypeOptionButton : public OptionButton {
GDCLASS(EditorVariantTypeOptionButton, OptionButton);
void _update_menu_icons();
protected:
void _notification(int p_what);
public:
Variant::Type get_selected_type() const;
void populate(const LocalVector<Variant::Type> &p_disabled_types, const HashMap<Variant::Type, String> &p_renames = {});
};
class EditorVariantTypePopupMenu : public PopupMenu {
GDCLASS(EditorVariantTypePopupMenu, PopupMenu);
bool remove_item = false;
bool icons_dirty = true;
void _populate();
void _update_menu_icons();
protected:
void _notification(int p_what);
public:
virtual void popup(const Rect2i &p_bounds = Rect2i()) override;
EditorVariantTypePopupMenu(bool p_remove_item);
};

View File

@@ -38,6 +38,7 @@
#include "editor/editor_string_names.h" #include "editor/editor_string_names.h"
#include "editor/editor_undo_redo_manager.h" #include "editor/editor_undo_redo_manager.h"
#include "editor/export/editor_export.h" #include "editor/export/editor_export.h"
#include "editor/gui/editor_variant_type_selectors.h"
#include "editor/themes/editor_scale.h" #include "editor/themes/editor_scale.h"
#include "scene/gui/check_button.h" #include "scene/gui/check_button.h"
#include "servers/movie_writer/movie_writer.h" #include "servers/movie_writer/movie_writer.h"
@@ -132,7 +133,7 @@ void ProjectSettingsEditor::_add_setting() {
// Initialize the property with the default value for the given type. // Initialize the property with the default value for the given type.
Callable::CallError ce; Callable::CallError ce;
Variant value; Variant value;
Variant::construct(Variant::Type(type_box->get_selected_id()), value, nullptr, 0, ce); Variant::construct(type_box->get_selected_type(), value, nullptr, 0, ce);
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(TTR("Add Project Setting")); undo_redo->create_action(TTR("Add Project Setting"));
@@ -605,16 +606,6 @@ void ProjectSettingsEditor::_update_theme() {
restart_container->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); restart_container->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
restart_icon->set_texture(get_editor_theme_icon(SNAME("StatusWarning"))); restart_icon->set_texture(get_editor_theme_icon(SNAME("StatusWarning")));
restart_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor))); restart_label->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
type_box->clear();
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (i == Variant::NIL || i == Variant::OBJECT || i == Variant::CALLABLE || i == Variant::SIGNAL || i == Variant::RID) {
// These types can't be serialized properly, so skip them.
continue;
}
String type = Variant::get_type_name(Variant::Type(i));
type_box->add_icon_item(get_editor_theme_icon(type), type, i);
}
} }
void ProjectSettingsEditor::_notification(int p_what) { void ProjectSettingsEditor::_notification(int p_what) {
@@ -699,7 +690,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
feature_box->connect(SceneStringName(item_selected), callable_mp(this, &ProjectSettingsEditor::_feature_selected)); feature_box->connect(SceneStringName(item_selected), callable_mp(this, &ProjectSettingsEditor::_feature_selected));
custom_properties->add_child(feature_box); custom_properties->add_child(feature_box);
type_box = memnew(OptionButton); type_box = memnew(EditorVariantTypeOptionButton);
type_box->populate({ Variant::NIL, Variant::OBJECT });
type_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE); type_box->set_custom_minimum_size(Size2(120, 0) * EDSCALE);
type_box->set_accessibility_name(TTRC("Type")); type_box->set_accessibility_name(TTRC("Type"));
custom_properties->add_child(type_box); custom_properties->add_child(type_box);

View File

@@ -44,6 +44,7 @@
#include "scene/gui/tab_container.h" #include "scene/gui/tab_container.h"
#include "scene/gui/texture_rect.h" #include "scene/gui/texture_rect.h"
class EditorVariantTypeOptionButton;
class FileSystemDock; class FileSystemDock;
class ProjectSettingsEditor : public AcceptDialog { class ProjectSettingsEditor : public AcceptDialog {
@@ -76,7 +77,7 @@ class ProjectSettingsEditor : public AcceptDialog {
HBoxContainer *custom_properties = nullptr; HBoxContainer *custom_properties = nullptr;
LineEdit *property_box = nullptr; LineEdit *property_box = nullptr;
OptionButton *feature_box = nullptr; OptionButton *feature_box = nullptr;
OptionButton *type_box = nullptr; EditorVariantTypeOptionButton *type_box = nullptr;
Button *add_button = nullptr; Button *add_button = nullptr;
Button *del_button = nullptr; Button *del_button = nullptr;