Skip to content

Commit

Permalink
Merge pull request #62185 from reduz/export-node-pointer-path
Browse files Browse the repository at this point in the history
Add ability to export Node pointers as NodePaths
  • Loading branch information
akien-mga authored Jun 27, 2022
2 parents 898e09e + b7c41f9 commit fbc3777
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 37 deletions.
1 change: 1 addition & 0 deletions core/core_constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALE_ID);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_LOCALIZABLE_STRING);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);

BIND_CORE_ENUM_CONSTANT(PROPERTY_USAGE_NONE);
Expand Down
1 change: 1 addition & 0 deletions core/object/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ enum PropertyHint {
PROPERTY_HINT_INT_IS_POINTER,
PROPERTY_HINT_LOCALE_ID,
PROPERTY_HINT_LOCALIZABLE_STRING,
PROPERTY_HINT_NODE_TYPE, ///< a node object type
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
Expand Down
4 changes: 3 additions & 1 deletion doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2583,7 +2583,9 @@
<constant name="PROPERTY_HINT_LOCALIZABLE_STRING" value="44" enum="PropertyHint">
Hints that a dictionary property is string translation map. Dictionary keys are locale codes and, values are translated strings.
</constant>
<constant name="PROPERTY_HINT_MAX" value="45" enum="PropertyHint">
<constant name="PROPERTY_HINT_NODE_TYPE" value="45" enum="PropertyHint">
</constant>
<constant name="PROPERTY_HINT_MAX" value="46" enum="PropertyHint">
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags">
</constant>
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/EditorProperty.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Gets the edited object.
</description>
</method>
<method name="get_edited_property">
<method name="get_edited_property" qualifiers="const">
<return type="StringName" />
<description>
Gets the edited property. If your editor is for a single property (added via [method EditorInspectorPlugin._parse_property]), then this will return the property.
Expand Down
21 changes: 15 additions & 6 deletions editor/editor_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ Object *EditorProperty::get_edited_object() {
return object;
}

StringName EditorProperty::get_edited_property() {
StringName EditorProperty::get_edited_property() const {
return property;
}

Expand Down Expand Up @@ -437,16 +437,20 @@ Variant EditorPropertyRevert::get_property_revert_value(Object *p_object, const
return PropertyUtils::get_property_default_value(p_object, p_property, r_is_valid);
}

bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property, const Variant *p_custom_current_value) {
bool is_valid_revert = false;
Variant revert_value = EditorPropertyRevert::get_property_revert_value(p_object, p_property, &is_valid_revert);
if (!is_valid_revert) {
return false;
}
Variant current_value = p_object->get(p_property);
Variant current_value = p_custom_current_value ? *p_custom_current_value : p_object->get(p_property);
return PropertyUtils::is_property_value_different(current_value, revert_value);
}

StringName EditorProperty::_get_revert_property() const {
return property;
}

void EditorProperty::update_revert_and_pin_status() {
if (property == StringName()) {
return; //no property, so nothing to do
Expand All @@ -458,7 +462,8 @@ void EditorProperty::update_revert_and_pin_status() {
CRASH_COND(!node);
new_pinned = node->is_property_pinned(property);
}
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property) && !is_read_only();
Variant current = object->get(_get_revert_property());
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property, &current) && !is_read_only();

if (new_can_revert != can_revert || new_pinned != pinned) {
can_revert = new_can_revert;
Expand Down Expand Up @@ -717,11 +722,15 @@ void EditorProperty::set_bottom_editor(Control *p_control) {
bottom_editor = p_control;
}

Variant EditorProperty::_get_cache_value(const StringName &p_prop, bool &r_valid) const {
return object->get(p_prop, &r_valid);
}

bool EditorProperty::is_cache_valid() const {
if (object) {
for (const KeyValue<StringName, Variant> &E : cache) {
bool valid;
Variant value = object->get(E.key, &valid);
Variant value = _get_cache_value(E.key, valid);
if (!valid || value != E.value) {
return false;
}
Expand All @@ -733,7 +742,7 @@ void EditorProperty::update_cache() {
cache.clear();
if (object && property != StringName()) {
bool valid;
Variant value = object->get(property, &valid);
Variant value = _get_cache_value(property, valid);
if (valid) {
cache[property] = value;
}
Expand Down
7 changes: 5 additions & 2 deletions editor/editor_inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class EditorPropertyRevert {
static bool is_property_value_different(const Variant &p_a, const Variant &p_b);
static Variant get_property_revert_value(Object *p_object, const StringName &p_property, bool *r_is_valid);

static bool can_property_revert(Object *p_object, const StringName &p_property);
static bool can_property_revert(Object *p_object, const StringName &p_property, const Variant *p_custom_current_value = nullptr);
};

class EditorProperty : public Container {
Expand Down Expand Up @@ -131,6 +131,9 @@ class EditorProperty : public Container {
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
const Color *_get_property_colors();

virtual Variant _get_cache_value(const StringName &p_prop, bool &r_valid) const;
virtual StringName _get_revert_property() const;

public:
void emit_changed(const StringName &p_property, const Variant &p_value, const StringName &p_field = StringName(), bool p_changing = false);

Expand All @@ -143,7 +146,7 @@ class EditorProperty : public Container {
bool is_read_only() const;

Object *get_edited_object();
StringName get_edited_property();
StringName get_edited_property() const;

virtual void update_property();
void update_revert_and_pin_status();
Expand Down
74 changes: 57 additions & 17 deletions editor/editor_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "scene/main/window.h"
#include "scene/resources/font.h"
#include "scene/resources/mesh.h"
#include "scene/resources/packed_scene.h"

///////////////////// Nil /////////////////////////

Expand Down Expand Up @@ -3017,6 +3018,23 @@ void EditorPropertyNodePath::_set_read_only(bool 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 {
if (p_prop == get_edited_property()) {
r_valid = true;
return const_cast<EditorPropertyNodePath *>(this)->get_edited_object()->get(_get_meta_pointer_property(), &r_valid);
}
return Variant();
}

StringName EditorPropertyNodePath::_get_revert_property() const {
return _get_meta_pointer_property();
}

void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
NodePath path = p_path;
Node *base_node = nullptr;
Expand Down Expand Up @@ -3048,7 +3066,11 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
if (base_node) { // for AnimationTrackKeyEdit
path = base_node->get_path().rel_path_to(p_path);
}
emit_changed(get_edited_property(), path);
if (pointer_mode && base_node) {
emit_changed(_get_meta_pointer_property(), path);
} else {
emit_changed(get_edited_property(), path);
}
update_property();
}

Expand All @@ -3064,7 +3086,11 @@ void EditorPropertyNodePath::_node_assign() {
}

void EditorPropertyNodePath::_node_clear() {
emit_changed(get_edited_property(), NodePath());
if (pointer_mode) {
emit_changed(_get_meta_pointer_property(), NodePath());
} else {
emit_changed(get_edited_property(), NodePath());
}
update_property();
}

Expand Down Expand Up @@ -3092,7 +3118,12 @@ bool EditorPropertyNodePath::is_drop_valid(const Dictionary &p_drag_data) const
}

void EditorPropertyNodePath::update_property() {
NodePath p = get_edited_object()->get(get_edited_property());
NodePath p;
if (pointer_mode) {
p = get_edited_object()->get(_get_meta_pointer_property());
} else {
p = get_edited_object()->get(get_edited_property());
}

assign->set_tooltip(p);
if (p == NodePath()) {
Expand Down Expand Up @@ -3131,7 +3162,8 @@ void EditorPropertyNodePath::update_property() {
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) {
void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root, bool p_pointer_mode) {
pointer_mode = p_pointer_mode;
base_hint = p_base_hint;
valid_types = p_valid_types;
use_path_from_scene_root = p_use_path_from_scene_root;
Expand Down Expand Up @@ -3927,23 +3959,31 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
return editor;
} break;
case Variant::OBJECT: {
EditorPropertyResource *editor = memnew(EditorPropertyResource);
editor->setup(p_object, p_path, p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource");

if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) {
String open_in_new = EDITOR_GET("interface/inspector/resources_to_open_in_new_inspector");
for (int i = 0; i < open_in_new.get_slice_count(","); i++) {
String type = open_in_new.get_slicec(',', i).strip_edges();
for (int j = 0; j < p_hint_text.get_slice_count(","); j++) {
String inherits = p_hint_text.get_slicec(',', j);
if (ClassDB::is_parent_class(inherits, type)) {
editor->set_use_sub_inspector(false);
if (p_hint == PROPERTY_HINT_NODE_TYPE) {
EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath);
Vector<String> types = p_hint_text.split(",", false);
Vector<StringName> sn = Variant(types); //convert via variant
editor->setup(NodePath(), sn, false, true);
return editor;
} else {
EditorPropertyResource *editor = memnew(EditorPropertyResource);
editor->setup(p_object, p_path, p_hint == PROPERTY_HINT_RESOURCE_TYPE ? p_hint_text : "Resource");

if (p_hint == PROPERTY_HINT_RESOURCE_TYPE) {
String open_in_new = EDITOR_GET("interface/inspector/resources_to_open_in_new_inspector");
for (int i = 0; i < open_in_new.get_slice_count(","); i++) {
String type = open_in_new.get_slicec(',', i).strip_edges();
for (int j = 0; j < p_hint_text.get_slice_count(","); j++) {
String inherits = p_hint_text.get_slicec(',', j);
if (ClassDB::is_parent_class(inherits, type)) {
editor->set_use_sub_inspector(false);
}
}
}
}
}

return editor;
return editor;
}

} break;
case Variant::DICTIONARY: {
Expand Down
7 changes: 6 additions & 1 deletion editor/editor_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ class EditorPropertyNodePath : public EditorProperty {
SceneTreeDialog *scene_tree = nullptr;
NodePath base_hint;
bool use_path_from_scene_root = false;
bool pointer_mode = false;

Vector<StringName> valid_types;
void _node_selected(const NodePath &p_path);
Expand All @@ -714,14 +715,18 @@ class EditorPropertyNodePath : public EditorProperty {
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;

String _get_meta_pointer_property() const;
virtual Variant _get_cache_value(const StringName &p_prop, bool &r_valid) const override;
virtual StringName _get_revert_property() const override;

protected:
virtual void _set_read_only(bool p_read_only) override;
static void _bind_methods();
void _notification(int p_what);

public:
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);
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);
EditorPropertyNodePath();
};

Expand Down
Loading

0 comments on commit fbc3777

Please sign in to comment.