summaryrefslogtreecommitdiff
path: root/editor/editor_inspector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/editor_inspector.cpp')
-rw-r--r--editor/editor_inspector.cpp145
1 files changed, 103 insertions, 42 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 9de8b0451a..fee27dae58 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -31,11 +31,13 @@
#include "editor_inspector.h"
#include "array_property_edit.h"
+#include "core/os/keyboard.h"
#include "dictionary_property_edit.h"
#include "editor/doc_tools.h"
#include "editor_feature_profile.h"
#include "editor_node.h"
#include "editor_scale.h"
+#include "editor_settings.h"
#include "multi_node_edit.h"
#include "scene/resources/packed_scene.h"
@@ -379,9 +381,7 @@ StringName EditorProperty::get_edited_property() {
}
void EditorProperty::update_property() {
- if (get_script_instance()) {
- get_script_instance()->call("_update_property");
- }
+ GDVIRTUAL_CALL(_update_property);
}
void EditorProperty::set_read_only(bool p_read_only) {
@@ -694,7 +694,7 @@ bool EditorProperty::is_selected() const {
return selected;
}
-void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (property == StringName()) {
@@ -766,7 +766,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
call_deferred(SNAME("emit_changed"), property, object->get(property).operator int64_t() + 1, "", false);
}
- call_deferred(SNAME("_update_property"));
+ call_deferred(SNAME("update_property"));
}
}
if (delete_rect.has_point(mpos)) {
@@ -784,6 +784,30 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
update();
emit_signal(SNAME("property_checked"), property, checked);
}
+ } else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
+ _ensure_popup();
+ menu->set_position(get_screen_position() + get_local_mouse_position());
+ menu->set_size(Vector2(1, 1));
+ menu->popup();
+ select();
+ return;
+ }
+}
+
+void EditorProperty::unhandled_key_input(const Ref<InputEvent> &p_event) {
+ if (!selected) {
+ return;
+ }
+
+ if (ED_IS_SHORTCUT("property_editor/copy_property", p_event)) {
+ menu_option(MENU_COPY_PROPERTY);
+ accept_event();
+ } else if (ED_IS_SHORTCUT("property_editor/paste_property", p_event) && !is_read_only()) {
+ menu_option(MENU_PASTE_PROPERTY);
+ accept_event();
+ } else if (ED_IS_SHORTCUT("property_editor/copy_property_path", p_event)) {
+ menu_option(MENU_COPY_PROPERTY_PATH);
+ accept_event();
}
}
@@ -897,6 +921,20 @@ String EditorProperty::get_tooltip_text() const {
return tooltip_text;
}
+void EditorProperty::menu_option(int p_option) {
+ switch (p_option) {
+ case MENU_COPY_PROPERTY: {
+ EditorNode::get_singleton()->get_inspector()->set_property_clipboard(object->get(property));
+ } break;
+ case MENU_PASTE_PROPERTY: {
+ emit_changed(property, EditorNode::get_singleton()->get_inspector()->get_property_clipboard());
+ } break;
+ case MENU_COPY_PROPERTY_PATH: {
+ DisplayServer::get_singleton()->clipboard_set(property);
+ } break;
+ }
+}
+
void EditorProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_label", "text"), &EditorProperty::set_label);
ClassDB::bind_method(D_METHOD("get_label"), &EditorProperty::get_label);
@@ -922,9 +960,8 @@ void EditorProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_edited_property"), &EditorProperty::get_edited_property);
ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object);
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorProperty::_gui_input);
-
ClassDB::bind_method(D_METHOD("get_tooltip_text"), &EditorProperty::get_tooltip_text);
+ ClassDB::bind_method(D_METHOD("update_property"), &EditorProperty::update_property);
ClassDB::bind_method(D_METHOD("add_focusable", "control"), &EditorProperty::add_focusable);
ClassDB::bind_method(D_METHOD("set_bottom_editor", "editor"), &EditorProperty::set_bottom_editor);
@@ -948,7 +985,7 @@ void EditorProperty::_bind_methods() {
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
- BIND_VMETHOD(MethodInfo("_update_property"));
+ GDVIRTUAL_BIND(_update_property)
}
EditorProperty::EditorProperty() {
@@ -974,6 +1011,21 @@ EditorProperty::EditorProperty() {
label_reference = nullptr;
bottom_editor = nullptr;
delete_hover = false;
+ menu = nullptr;
+ set_process_unhandled_key_input(true);
+}
+
+void EditorProperty::_ensure_popup() {
+ if (menu) {
+ return;
+ }
+ menu = memnew(PopupMenu);
+ menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY);
+ menu->add_shortcut(ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY);
+ menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
+ menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
+ menu->set_item_disabled(MENU_PASTE_PROPERTY, is_read_only());
+ add_child(menu);
}
////////////////////////////////////////////////
@@ -1003,43 +1055,31 @@ void EditorInspectorPlugin::add_property_editor_for_multiple_properties(const St
}
bool EditorInspectorPlugin::can_handle(Object *p_object) {
- if (get_script_instance()) {
- return get_script_instance()->call("_can_handle", p_object);
+ bool success;
+ if (GDVIRTUAL_CALL(_can_handle, p_object, success)) {
+ return success;
}
return false;
}
void EditorInspectorPlugin::parse_begin(Object *p_object) {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_begin", p_object);
- }
+ GDVIRTUAL_CALL(_parse_begin);
}
void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_parse_category) {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_category", p_object, p_parse_category);
- }
+ GDVIRTUAL_CALL(_parse_category, p_object, p_parse_category);
}
bool EditorInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
- if (get_script_instance()) {
- Variant arg[6] = {
- p_object, p_type, p_path, p_hint, p_hint_text, p_usage
- };
- const Variant *argptr[6] = {
- &arg[0], &arg[1], &arg[2], &arg[3], &arg[4], &arg[5]
- };
-
- Callable::CallError err;
- return get_script_instance()->call("_parse_property", (const Variant **)&argptr, 6, err);
+ bool ret;
+ if (GDVIRTUAL_CALL(_parse_property, p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide, ret)) {
+ return ret;
}
return false;
}
void EditorInspectorPlugin::parse_end() {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_end");
- }
+ GDVIRTUAL_CALL(_parse_end);
}
void EditorInspectorPlugin::_bind_methods() {
@@ -1047,11 +1087,11 @@ void EditorInspectorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor"), &EditorInspectorPlugin::add_property_editor);
ClassDB::bind_method(D_METHOD("add_property_editor_for_multiple_properties", "label", "properties", "editor"), &EditorInspectorPlugin::add_property_editor_for_multiple_properties);
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_handle", PropertyInfo(Variant::OBJECT, "object")));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_begin"));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_category", PropertyInfo(Variant::STRING, "category")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_parse_property", PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "hint"), PropertyInfo(Variant::STRING, "hint_text"), PropertyInfo(Variant::INT, "usage")));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_end"));
+ GDVIRTUAL_BIND(_can_handle, "object")
+ GDVIRTUAL_BIND(_parse_begin)
+ GDVIRTUAL_BIND(_parse_category, "object", "category")
+ GDVIRTUAL_BIND(_parse_property, "object", "type", "name", "hint_type", "hint_string", "usage_flags", "wide");
+ GDVIRTUAL_BIND(_parse_end)
}
////////////////////////////////////////////////
@@ -1332,7 +1372,7 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
}
}
-void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorInspectorSection::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!foldable) {
@@ -1391,7 +1431,6 @@ void EditorInspectorSection::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vbox"), &EditorInspectorSection::get_vbox);
ClassDB::bind_method(D_METHOD("unfold"), &EditorInspectorSection::unfold);
ClassDB::bind_method(D_METHOD("fold"), &EditorInspectorSection::fold);
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorInspectorSection::_gui_input);
}
EditorInspectorSection::EditorInspectorSection() {
@@ -2243,6 +2282,13 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
undo_redo->add_do_property(object, p_name, p_value);
undo_redo->add_undo_property(object, p_name, object->get(p_name));
+ PropertyInfo prop_info;
+ if (ClassDB::get_property_info(object->get_class_name(), p_name, &prop_info)) {
+ for (const String &linked_prop : prop_info.linked_properties) {
+ undo_redo->add_undo_property(object, linked_prop, object->get(linked_prop));
+ }
+ }
+
Variant v_undo_redo = (Object *)undo_redo;
Variant v_object = object;
Variant v_name = p_name;
@@ -2610,13 +2656,15 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
}
// NodeC -> C props... -> NodeB..C..
- r_list.erase(script_variables);
- List<PropertyInfo>::Element *to_delete = bottom->next();
- while (to_delete && !(to_delete->get().usage & PROPERTY_USAGE_CATEGORY)) {
- r_list.erase(to_delete);
- to_delete = bottom->next();
+ if (script_variables) {
+ r_list.erase(script_variables);
+ List<PropertyInfo>::Element *to_delete = bottom->next();
+ while (to_delete && !(to_delete->get().usage & PROPERTY_USAGE_CATEGORY)) {
+ r_list.erase(to_delete);
+ to_delete = bottom->next();
+ }
+ r_list.erase(bottom);
}
- r_list.erase(bottom);
}
void EditorInspector::set_restrict_to_basic_settings(bool p_restrict) {
@@ -2624,6 +2672,14 @@ void EditorInspector::set_restrict_to_basic_settings(bool p_restrict) {
update_tree();
}
+void EditorInspector::set_property_clipboard(const Variant &p_value) {
+ property_clipboard = p_value;
+}
+
+Variant EditorInspector::get_property_clipboard() const {
+ return property_clipboard;
+}
+
void EditorInspector::_bind_methods() {
ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change);
@@ -2666,6 +2722,7 @@ EditorInspector::EditorInspector() {
property_focusable = -1;
sub_inspector = false;
deletable_properties = false;
+ property_clipboard = Variant();
get_v_scrollbar()->connect("value_changed", callable_mp(this, &EditorInspector::_vscroll_changed));
update_scroll_request = -1;
@@ -2675,4 +2732,8 @@ EditorInspector::EditorInspector() {
//used when class is created by the docgen to dump default values of everything bindable, editorsettings may not be created
refresh_countdown = 0.33;
}
+
+ ED_SHORTCUT("property_editor/copy_property", TTR("Copy Property"), KEY_MASK_CMD | KEY_C);
+ ED_SHORTCUT("property_editor/paste_property", TTR("Paste Property"), KEY_MASK_CMD | KEY_V);
+ ED_SHORTCUT("property_editor/copy_property_path", TTR("Copy Property Path"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_C);
}