summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkobewi <kobewi4e@gmail.com>2021-07-16 16:27:59 +0200
committerkobewi <kobewi4e@gmail.com>2021-07-19 16:16:50 +0200
commit5faf51a5aa5e6f4e90f5a3423783d72dc00d00b0 (patch)
tree256578eee24dbe954fccc845326b2fc95f7725c3
parent60add98a4cff0d27c6aa2f52042555eccb86ed70 (diff)
Assign value to property by dropping to scene tree
-rw-r--r--editor/editor_inspector.cpp2
-rw-r--r--editor/scene_tree_dock.cpp65
-rw-r--r--editor/scene_tree_dock.h6
-rw-r--r--editor/scene_tree_editor.cpp13
4 files changed, 80 insertions, 6 deletions
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 4dd57cb1a8..e93f5f6690 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -2261,7 +2261,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
_edit_request_change(object, p_name);
emit_signal(_prop_edited, p_name);
} else {
- undo_redo->create_action(TTR("Set") + " " + p_name, UndoRedo::MERGE_ENDS);
+ undo_redo->create_action(vformat(TTR("Set %s"), p_name), UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(object, p_name, p_value);
undo_redo->add_undo_property(object, p_name, object->get(p_name));
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 166b82d744..2737bd13c5 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -1157,6 +1157,19 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
+void SceneTreeDock::_property_selected(int p_idx) {
+ ERR_FAIL_NULL(property_drop_node);
+ _perform_property_drop(property_drop_node, menu_properties->get_item_metadata(p_idx), ResourceLoader::load(resource_drop_path));
+ property_drop_node = nullptr;
+}
+
+void SceneTreeDock::_perform_property_drop(Node *p_node, String p_property, RES p_res) {
+ editor_data->get_undo_redo().create_action(vformat(TTR("Set %s"), p_property));
+ editor_data->get_undo_redo().add_do_property(p_node, p_property, p_res);
+ editor_data->get_undo_redo().add_undo_property(p_node, p_property, p_node->get(p_property));
+ editor_data->get_undo_redo().commit_action();
+}
+
void SceneTreeDock::add_root_node(Node *p_node) {
editor_data->get_undo_redo().create_action(TTR("New Scene Root"));
editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", p_node);
@@ -2515,9 +2528,51 @@ void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_
Node *node = get_node(p_to);
ERR_FAIL_COND(!node);
- int to_pos = -1;
- _normalize_drop(node, to_pos, p_type);
- _perform_instantiate_scenes(p_files, node, to_pos);
+ if (scene_tree->get_scene_tree()->get_drop_mode_flags() & Tree::DROP_MODE_INBETWEEN) {
+ // Dropped PackedScene, instance it.
+ int to_pos = -1;
+ _normalize_drop(node, to_pos, p_type);
+ _perform_instantiate_scenes(p_files, node, to_pos);
+ } else {
+ String res_path = p_files[0];
+ StringName res_type = EditorFileSystem::get_singleton()->get_file_type(res_path);
+ List<String> valid_properties;
+
+ List<PropertyInfo> pinfo;
+ node->get_property_list(&pinfo);
+
+ for (PropertyInfo &p : pinfo) {
+ if (!(p.usage & PROPERTY_USAGE_EDITOR) || !(p.usage & PROPERTY_USAGE_STORAGE) || p.hint != PROPERTY_HINT_RESOURCE_TYPE) {
+ continue;
+ }
+ Vector<String> valid_types = p.hint_string.split(",");
+
+ for (String &prop_type : valid_types) {
+ if (res_type == prop_type || ClassDB::is_parent_class(res_type, prop_type) || EditorNode::get_editor_data().script_class_is_parent(res_type, prop_type)) {
+ valid_properties.push_back(p.name);
+ break;
+ }
+ }
+ }
+
+ if (valid_properties.size() > 1) {
+ property_drop_node = node;
+ resource_drop_path = res_path;
+
+ bool capitalize = bool(EDITOR_GET("interface/inspector/capitalize_properties"));
+ menu_properties->clear();
+ for (String &p : valid_properties) {
+ menu_properties->add_item(capitalize ? p.capitalize() : p);
+ menu_properties->set_item_metadata(menu_properties->get_item_count() - 1, p);
+ }
+
+ menu_properties->set_size(Size2(1, 1));
+ menu_properties->set_position(get_screen_position() + get_local_mouse_position());
+ menu_properties->popup();
+ } else if (!valid_properties.is_empty()) {
+ _perform_property_drop(node, valid_properties[0], ResourceLoader::load(res_path));
+ }
+ }
}
void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
@@ -3276,6 +3331,10 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
first_enter = true;
restore_script_editor_on_drag = false;
+ menu_properties = memnew(PopupMenu);
+ add_child(menu_properties);
+ menu_properties->connect("id_pressed", callable_mp(this, &SceneTreeDock::_property_selected));
+
clear_inherit_confirm = memnew(ConfirmationDialog);
clear_inherit_confirm->set_text(TTR("Clear Inheritance? (No Undo!)"));
clear_inherit_confirm->get_ok_button()->set_text(TTR("Clear"));
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 08d992d465..fd9299fb2b 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -123,8 +123,13 @@ class SceneTreeDock : public VBoxContainer {
HBoxContainer *tool_hbc;
void _tool_selected(int p_tool, bool p_confirm_override = false);
+ void _property_selected(int p_idx);
void _node_collapsed(Object *p_obj);
+ Node *property_drop_node = nullptr;
+ String resource_drop_path;
+ void _perform_property_drop(Node *p_node, String p_property, RES p_res);
+
EditorData *editor_data;
EditorSelection *editor_selection;
@@ -147,6 +152,7 @@ class SceneTreeDock : public VBoxContainer {
PopupMenu *menu;
PopupMenu *menu_subresources;
+ PopupMenu *menu_properties;
ConfirmationDialog *clear_inherit_confirm;
bool first_enter;
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 5958a09169..f2af6b4262 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -1037,15 +1037,24 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
return true;
}
+ bool scene_drop = true;
for (int i = 0; i < files.size(); i++) {
String file = files[i];
String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
if (ftype != "PackedScene") {
- return false;
+ scene_drop = false;
+ break;
}
}
- tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM); //so it works..
+ if (scene_drop) {
+ tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM);
+ } else {
+ if (files.size() > 1) {
+ return false;
+ }
+ tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
+ }
return true;
}