mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
Merge pull request #76389 from ajreckof/editor-property-nodepath-for-node
Fix typed array export
This commit is contained in:
commit
f77dee90a6
@ -2759,48 +2759,17 @@ void EditorPropertyNodePath::_set_read_only(bool p_read_only) {
|
|||||||
clear->set_disabled(p_read_only);
|
clear->set_disabled(p_read_only);
|
||||||
};
|
};
|
||||||
|
|
||||||
String EditorPropertyNodePath::_get_meta_pointer_property() const {
|
|
||||||
ERR_FAIL_COND_V(!pointer_mode, String());
|
|
||||||
return SceneState::get_meta_pointer_property(get_edited_property());
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant EditorPropertyNodePath::_get_cache_value(const StringName &p_prop, bool &r_valid) const {
|
Variant EditorPropertyNodePath::_get_cache_value(const StringName &p_prop, bool &r_valid) const {
|
||||||
if (p_prop == get_edited_property()) {
|
if (p_prop == get_edited_property()) {
|
||||||
r_valid = true;
|
r_valid = true;
|
||||||
return const_cast<EditorPropertyNodePath *>(this)->get_edited_object()->get(pointer_mode ? StringName(_get_meta_pointer_property()) : get_edited_property(), &r_valid);
|
return const_cast<EditorPropertyNodePath *>(this)->get_edited_object()->get(get_edited_property(), &r_valid);
|
||||||
}
|
}
|
||||||
return Variant();
|
return Variant();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName EditorPropertyNodePath::_get_revert_property() const {
|
|
||||||
if (pointer_mode) {
|
|
||||||
return _get_meta_pointer_property();
|
|
||||||
} else {
|
|
||||||
return get_edited_property();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
|
void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
|
||||||
NodePath path = p_path;
|
NodePath path = p_path;
|
||||||
Node *base_node = nullptr;
|
Node *base_node = get_base_node();
|
||||||
|
|
||||||
if (!use_path_from_scene_root) {
|
|
||||||
base_node = Object::cast_to<Node>(get_edited_object());
|
|
||||||
|
|
||||||
if (!base_node) {
|
|
||||||
//try a base node within history
|
|
||||||
if (EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() > 0) {
|
|
||||||
Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(0));
|
|
||||||
if (base) {
|
|
||||||
base_node = Object::cast_to<Node>(base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_node && get_edited_object()->has_method("get_root_path")) {
|
|
||||||
base_node = Object::cast_to<Node>(get_edited_object()->call("get_root_path"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_node && Object::cast_to<RefCounted>(get_edited_object())) {
|
if (!base_node && Object::cast_to<RefCounted>(get_edited_object())) {
|
||||||
Node *to_node = get_node(p_path);
|
Node *to_node = get_node(p_path);
|
||||||
@ -2811,8 +2780,13 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
|
|||||||
if (base_node) { // for AnimationTrackKeyEdit
|
if (base_node) { // for AnimationTrackKeyEdit
|
||||||
path = base_node->get_path().rel_path_to(p_path);
|
path = base_node->get_path().rel_path_to(p_path);
|
||||||
}
|
}
|
||||||
if (pointer_mode && base_node) {
|
|
||||||
emit_changed(_get_meta_pointer_property(), path);
|
if (editing_node) {
|
||||||
|
if (!base_node) {
|
||||||
|
emit_changed(get_edited_property(), get_tree()->get_edited_scene_root()->get_node(path));
|
||||||
|
} else {
|
||||||
|
emit_changed(get_edited_property(), base_node->get_node(path));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
emit_changed(get_edited_property(), path);
|
emit_changed(get_edited_property(), path);
|
||||||
}
|
}
|
||||||
@ -2831,11 +2805,7 @@ void EditorPropertyNodePath::_node_assign() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyNodePath::_node_clear() {
|
void EditorPropertyNodePath::_node_clear() {
|
||||||
if (pointer_mode) {
|
emit_changed(get_edited_property(), NodePath());
|
||||||
emit_changed(_get_meta_pointer_property(), NodePath());
|
|
||||||
} else {
|
|
||||||
emit_changed(get_edited_property(), NodePath());
|
|
||||||
}
|
|
||||||
update_property();
|
update_property();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2882,9 +2852,20 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyNodePath::update_property() {
|
void EditorPropertyNodePath::update_property() {
|
||||||
|
Node *base_node = get_base_node();
|
||||||
|
|
||||||
NodePath p;
|
NodePath p;
|
||||||
if (pointer_mode) {
|
Variant val = get_edited_object()->get(get_edited_property());
|
||||||
p = get_edited_object()->get(_get_meta_pointer_property());
|
Node *n = Object::cast_to<Node>(val);
|
||||||
|
if (n) {
|
||||||
|
if (!n->is_inside_tree()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (base_node) {
|
||||||
|
p = base_node->get_path_to(n);
|
||||||
|
} else {
|
||||||
|
p = get_tree()->get_edited_scene_root()->get_path_to(n);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
p = get_edited_property_value();
|
p = get_edited_property_value();
|
||||||
}
|
}
|
||||||
@ -2898,15 +2879,6 @@ void EditorPropertyNodePath::update_property() {
|
|||||||
}
|
}
|
||||||
assign->set_flat(true);
|
assign->set_flat(true);
|
||||||
|
|
||||||
Node *base_node = nullptr;
|
|
||||||
if (base_hint != NodePath()) {
|
|
||||||
if (get_tree()->get_root()->has_node(base_hint)) {
|
|
||||||
base_node = get_tree()->get_root()->get_node(base_hint);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
base_node = Object::cast_to<Node>(get_edited_object());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!base_node || !base_node->has_node(p)) {
|
if (!base_node || !base_node->has_node(p)) {
|
||||||
assign->set_icon(Ref<Texture2D>());
|
assign->set_icon(Ref<Texture2D>());
|
||||||
assign->set_text(p);
|
assign->set_text(p);
|
||||||
@ -2926,10 +2898,10 @@ void EditorPropertyNodePath::update_property() {
|
|||||||
assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node"));
|
assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root, bool p_pointer_mode) {
|
void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root, bool p_editing_node) {
|
||||||
pointer_mode = p_pointer_mode;
|
|
||||||
base_hint = p_base_hint;
|
base_hint = p_base_hint;
|
||||||
valid_types = p_valid_types;
|
valid_types = p_valid_types;
|
||||||
|
editing_node = p_editing_node;
|
||||||
use_path_from_scene_root = p_use_path_from_scene_root;
|
use_path_from_scene_root = p_use_path_from_scene_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2945,6 +2917,35 @@ void EditorPropertyNodePath::_notification(int p_what) {
|
|||||||
|
|
||||||
void EditorPropertyNodePath::_bind_methods() {
|
void EditorPropertyNodePath::_bind_methods() {
|
||||||
}
|
}
|
||||||
|
Node *EditorPropertyNodePath::get_base_node() {
|
||||||
|
if (!base_hint.is_empty() && get_tree()->get_root()->has_node(base_hint)) {
|
||||||
|
return get_tree()->get_root()->get_node(base_hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
Node *base_node = Object::cast_to<Node>(get_edited_object());
|
||||||
|
|
||||||
|
if (!base_node) {
|
||||||
|
base_node = Object::cast_to<Node>(InspectorDock::get_inspector_singleton()->get_edited_object());
|
||||||
|
}
|
||||||
|
if (!base_node) {
|
||||||
|
// Try a base node within history.
|
||||||
|
if (EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() > 0) {
|
||||||
|
Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(0));
|
||||||
|
if (base) {
|
||||||
|
base_node = Object::cast_to<Node>(base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (use_path_from_scene_root) {
|
||||||
|
if (get_edited_object()->has_method("get_root_path")) {
|
||||||
|
base_node = Object::cast_to<Node>(get_edited_object()->call("get_root_path"));
|
||||||
|
} else {
|
||||||
|
base_node = get_tree()->get_edited_scene_root();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base_node;
|
||||||
|
}
|
||||||
|
|
||||||
EditorPropertyNodePath::EditorPropertyNodePath() {
|
EditorPropertyNodePath::EditorPropertyNodePath() {
|
||||||
HBoxContainer *hbc = memnew(HBoxContainer);
|
HBoxContainer *hbc = memnew(HBoxContainer);
|
||||||
|
@ -654,20 +654,19 @@ class EditorPropertyNodePath : public EditorProperty {
|
|||||||
SceneTreeDialog *scene_tree = nullptr;
|
SceneTreeDialog *scene_tree = nullptr;
|
||||||
NodePath base_hint;
|
NodePath base_hint;
|
||||||
bool use_path_from_scene_root = false;
|
bool use_path_from_scene_root = false;
|
||||||
bool pointer_mode = false;
|
bool editing_node = false;
|
||||||
|
|
||||||
Vector<StringName> valid_types;
|
Vector<StringName> valid_types;
|
||||||
void _node_selected(const NodePath &p_path);
|
void _node_selected(const NodePath &p_path);
|
||||||
void _node_assign();
|
void _node_assign();
|
||||||
void _node_clear();
|
void _node_clear();
|
||||||
|
Node *get_base_node();
|
||||||
|
|
||||||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||||
bool is_drop_valid(const Dictionary &p_drag_data) const;
|
bool is_drop_valid(const Dictionary &p_drag_data) const;
|
||||||
|
|
||||||
String _get_meta_pointer_property() const;
|
|
||||||
virtual Variant _get_cache_value(const StringName &p_prop, bool &r_valid) const override;
|
virtual Variant _get_cache_value(const StringName &p_prop, bool &r_valid) const override;
|
||||||
virtual StringName _get_revert_property() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void _set_read_only(bool p_read_only) override;
|
virtual void _set_read_only(bool p_read_only) override;
|
||||||
@ -676,7 +675,7 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void update_property() override;
|
virtual void update_property() override;
|
||||||
void setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root = true, bool p_pointer_mode = false);
|
void setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root = true, bool p_editing_node = false);
|
||||||
EditorPropertyNodePath();
|
EditorPropertyNodePath();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
|
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
|
|
||||||
if (!name.begins_with("indices") && !name.begins_with(PackedScene::META_POINTER_PROPERTY_BASE + "indices")) {
|
if (!name.begins_with("indices")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_
|
|||||||
bool EditorPropertyArrayObject::_get(const StringName &p_name, Variant &r_ret) const {
|
bool EditorPropertyArrayObject::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
String name = p_name;
|
String name = p_name;
|
||||||
|
|
||||||
if (!name.begins_with("indices") && !name.begins_with(PackedScene::META_POINTER_PROPERTY_BASE + "indices")) {
|
if (!name.begins_with("indices")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ void EditorPropertyArray::initialize_array(Variant &p_array) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EditorPropertyArray::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
|
void EditorPropertyArray::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
|
||||||
if (!p_property.begins_with("indices") && !p_property.begins_with(PackedScene::META_POINTER_PROPERTY_BASE + "indices")) {
|
if (!p_property.begins_with("indices")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,18 +204,7 @@ void EditorPropertyArray::_property_changed(const String &p_property, Variant p_
|
|||||||
index = p_property.get_slice("/", 1).to_int();
|
index = p_property.get_slice("/", 1).to_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant array;
|
Variant array = object->get_array().duplicate();
|
||||||
const Variant &original_array = object->get_array();
|
|
||||||
|
|
||||||
if (original_array.get_type() == Variant::ARRAY) {
|
|
||||||
// Needed to preserve type of TypedArrays in meta pointer properties.
|
|
||||||
Array temp;
|
|
||||||
temp.assign(original_array.duplicate());
|
|
||||||
array = temp;
|
|
||||||
} else {
|
|
||||||
array = original_array.duplicate();
|
|
||||||
}
|
|
||||||
|
|
||||||
array.set(index, p_value);
|
array.set(index, p_value);
|
||||||
object->set_array(array);
|
object->set_array(array);
|
||||||
emit_changed(get_edited_property(), array, "", true);
|
emit_changed(get_edited_property(), array, "", true);
|
||||||
|
@ -45,8 +45,6 @@
|
|||||||
|
|
||||||
#define PACKED_SCENE_VERSION 3
|
#define PACKED_SCENE_VERSION 3
|
||||||
|
|
||||||
const String PackedScene::META_POINTER_PROPERTY_BASE = "metadata/_editor_prop_ptr_";
|
|
||||||
|
|
||||||
bool SceneState::can_instantiate() const {
|
bool SceneState::can_instantiate() const {
|
||||||
return nodes.size() > 0;
|
return nodes.size() > 0;
|
||||||
}
|
}
|
||||||
@ -246,13 +244,14 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
|||||||
const Variant &prop_variant = props[nprops[j].value];
|
const Variant &prop_variant = props[nprops[j].value];
|
||||||
|
|
||||||
if (prop_variant.get_type() == Variant::ARRAY) {
|
if (prop_variant.get_type() == Variant::ARRAY) {
|
||||||
if (Engine::get_singleton()->is_editor_hint()) {
|
|
||||||
// If editor, simply set the original array of NodePaths.
|
|
||||||
node->set(prop_name, prop_variant);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Array &array = prop_variant;
|
const Array &array = prop_variant;
|
||||||
|
if (Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
if (array.get_typed_builtin() == Variant::NODE_PATH) {
|
||||||
|
// If editor, simply set the original array of NodePaths.
|
||||||
|
node->set(prop_name, prop_variant);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int k = 0; k < array.size(); k++) {
|
for (int k = 0; k < array.size(); k++) {
|
||||||
DeferredNodePathProperties dnp;
|
DeferredNodePathProperties dnp;
|
||||||
dnp.path = array[k];
|
dnp.path = array[k];
|
||||||
@ -263,16 +262,12 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
node->set(PackedScene::META_POINTER_PROPERTY_BASE + String(prop_name), prop_variant);
|
// Do an actual deferred set of the property path.
|
||||||
|
DeferredNodePathProperties dnp;
|
||||||
if (!Engine::get_singleton()->is_editor_hint()) {
|
dnp.path = prop_variant;
|
||||||
// If not editor, do an actual deferred sed of the property path.
|
dnp.base = node;
|
||||||
DeferredNodePathProperties dnp;
|
dnp.property = prop_name;
|
||||||
dnp.path = prop_variant;
|
deferred_node_paths.push_back(dnp);
|
||||||
dnp.base = node;
|
|
||||||
dnp.property = prop_name;
|
|
||||||
deferred_node_paths.push_back(dnp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -626,9 +621,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
|
|||||||
if (E.name == META_PROPERTY_MISSING_RESOURCES) {
|
if (E.name == META_PROPERTY_MISSING_RESOURCES) {
|
||||||
continue; // Ignore this property when packing.
|
continue; // Ignore this property when packing.
|
||||||
}
|
}
|
||||||
if (E.name.begins_with(PackedScene::META_POINTER_PROPERTY_BASE)) {
|
|
||||||
continue; // do not save.
|
|
||||||
}
|
|
||||||
|
|
||||||
// If instance or inheriting, not saving if property requested so.
|
// If instance or inheriting, not saving if property requested so.
|
||||||
if (!states_stack.is_empty()) {
|
if (!states_stack.is_empty()) {
|
||||||
@ -642,11 +634,15 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
|
|||||||
bool use_deferred_node_path_bit = false;
|
bool use_deferred_node_path_bit = false;
|
||||||
|
|
||||||
if (E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_NODE_TYPE) {
|
if (E.type == Variant::OBJECT && E.hint == PROPERTY_HINT_NODE_TYPE) {
|
||||||
value = p_node->get(PackedScene::META_POINTER_PROPERTY_BASE + E.name);
|
if (value.get_type() == Variant::OBJECT) {
|
||||||
|
if (Node *n = Object::cast_to<Node>(value)) {
|
||||||
|
value = p_node->get_path_to(n);
|
||||||
|
}
|
||||||
|
use_deferred_node_path_bit = true;
|
||||||
|
}
|
||||||
if (value.get_type() != Variant::NODE_PATH) {
|
if (value.get_type() != Variant::NODE_PATH) {
|
||||||
continue; //was never set, ignore.
|
continue; //was never set, ignore.
|
||||||
}
|
}
|
||||||
use_deferred_node_path_bit = true;
|
|
||||||
} else if (E.type == Variant::OBJECT && missing_resource_properties.has(E.name)) {
|
} else if (E.type == Variant::OBJECT && missing_resource_properties.has(E.name)) {
|
||||||
// Was this missing resource overridden? If so do not save the old value.
|
// Was this missing resource overridden? If so do not save the old value.
|
||||||
Ref<Resource> ures = value;
|
Ref<Resource> ures = value;
|
||||||
@ -665,7 +661,22 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Has
|
|||||||
}
|
}
|
||||||
Variant::Type subtype = Variant::Type(subtype_string.to_int());
|
Variant::Type subtype = Variant::Type(subtype_string.to_int());
|
||||||
|
|
||||||
use_deferred_node_path_bit = subtype == Variant::OBJECT && subtype_hint == PROPERTY_HINT_NODE_TYPE;
|
if (subtype == Variant::OBJECT && subtype_hint == PROPERTY_HINT_NODE_TYPE) {
|
||||||
|
use_deferred_node_path_bit = true;
|
||||||
|
Array array = value;
|
||||||
|
Array new_array;
|
||||||
|
for (int i = 0; i < array.size(); i++) {
|
||||||
|
Variant elem = array[i];
|
||||||
|
if (elem.get_type() == Variant::OBJECT) {
|
||||||
|
if (Node *n = Object::cast_to<Node>(elem)) {
|
||||||
|
new_array.push_back(p_node->get_path_to(n));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_array.push_back(elem);
|
||||||
|
}
|
||||||
|
value = new_array;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1791,10 +1802,6 @@ void SceneState::add_editable_instance(const NodePath &p_path) {
|
|||||||
editable_instances.push_back(p_path);
|
editable_instances.push_back(p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
String SceneState::get_meta_pointer_property(const String &p_property) {
|
|
||||||
return PackedScene::META_POINTER_PROPERTY_BASE + p_property;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<String> SceneState::_get_node_groups(int p_idx) const {
|
Vector<String> SceneState::_get_node_groups(int p_idx) const {
|
||||||
Vector<StringName> groups = get_node_groups(p_idx);
|
Vector<StringName> groups = get_node_groups(p_idx);
|
||||||
Vector<String> ret;
|
Vector<String> ret;
|
||||||
|
@ -221,8 +221,6 @@ protected:
|
|||||||
virtual void reset_state() override;
|
virtual void reset_state() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const String META_POINTER_PROPERTY_BASE;
|
|
||||||
|
|
||||||
enum GenEditState {
|
enum GenEditState {
|
||||||
GEN_EDIT_STATE_DISABLED,
|
GEN_EDIT_STATE_DISABLED,
|
||||||
GEN_EDIT_STATE_INSTANCE,
|
GEN_EDIT_STATE_INSTANCE,
|
||||||
|
Loading…
Reference in New Issue
Block a user