Rationalize property reversion
This commit is contained in:
parent
d272464e6e
commit
c4811747cc
2 changed files with 62 additions and 77 deletions
|
@ -343,7 +343,7 @@ bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) {
|
||||||
return might_be; // or might not be
|
return might_be; // or might not be
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value) {
|
bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value, bool p_check_class_default) {
|
||||||
Node *node = p_node;
|
Node *node = p_node;
|
||||||
Node *orig = node;
|
Node *orig = node;
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
|
||||||
node = node->get_owner();
|
node = node->get_owner();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found && p_node) {
|
if (p_check_class_default && !found && p_node) {
|
||||||
//if not found, try default class value
|
//if not found, try default class value
|
||||||
Variant attempt = ClassDB::class_get_default_property_value(p_node->get_class_name(), p_prop);
|
Variant attempt = ClassDB::class_get_default_property_value(p_node->get_class_name(), p_prop);
|
||||||
if (attempt.get_type() != Variant::NIL) {
|
if (attempt.get_type() != Variant::NIL) {
|
||||||
|
@ -419,6 +419,7 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
|
||||||
|
|
||||||
if (ss.is_valid()) {
|
if (ss.is_valid()) {
|
||||||
found_state = true;
|
found_state = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (node == edited_scene) {
|
if (node == edited_scene) {
|
||||||
//just in case
|
//just in case
|
||||||
|
@ -432,59 +433,71 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_current.get_type() == Variant::REAL && p_orig.get_type() == Variant::REAL) {
|
return is_property_value_different(p_current, p_orig);
|
||||||
float a = p_current;
|
|
||||||
float b = p_orig;
|
|
||||||
|
|
||||||
return !Math::is_equal_approx(a, b); //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
|
|
||||||
}
|
|
||||||
|
|
||||||
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL, p_current, p_orig));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
|
bool EditorPropertyRevert::is_property_value_different(const Variant &p_a, const Variant &p_b) {
|
||||||
bool has_revert = false;
|
if (p_a.get_type() == Variant::REAL && p_b.get_type() == Variant::REAL) {
|
||||||
|
//this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
|
||||||
Node *node = Object::cast_to<Node>(p_object);
|
return !Math::is_equal_approx((float)p_a, (float)p_b);
|
||||||
|
|
||||||
if (node && EditorPropertyRevert::may_node_be_in_instance(node)) {
|
|
||||||
//check for difference including instantiation
|
|
||||||
Variant vorig;
|
|
||||||
if (EditorPropertyRevert::get_instanced_node_original_property(node, p_property, vorig)) {
|
|
||||||
Variant v = p_object->get(p_property);
|
|
||||||
|
|
||||||
if (EditorPropertyRevert::is_node_property_different(node, v, vorig)) {
|
|
||||||
has_revert = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//check for difference against default class value instead
|
return p_a != p_b;
|
||||||
Variant default_value = ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property);
|
|
||||||
if (default_value != Variant() && default_value != p_object->get(p_property)) {
|
|
||||||
has_revert = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant EditorPropertyRevert::get_property_revert_value(Object *p_object, const StringName &p_property) {
|
||||||
// If the object implements property_can_revert, rely on that completely
|
// If the object implements property_can_revert, rely on that completely
|
||||||
// (i.e. don't then try to revert to default value - the property_get_revert implementation
|
// (i.e. don't then try to revert to default value - the property_get_revert implementation
|
||||||
// can do that if so desired)
|
// can do that if so desired)
|
||||||
if (p_object->has_method("property_can_revert")) {
|
if (p_object->has_method("property_can_revert") && p_object->call("property_can_revert", p_property)) {
|
||||||
has_revert = p_object->call("property_can_revert", p_property).operator bool();
|
return p_object->call("property_get_revert", p_property);
|
||||||
} else {
|
}
|
||||||
if (!has_revert && !p_object->get_script().is_null()) {
|
|
||||||
Ref<Script> scr = p_object->get_script();
|
Ref<Script> scr = p_object->get_script();
|
||||||
if (scr.is_valid()) {
|
Node *node = Object::cast_to<Node>(p_object);
|
||||||
Variant orig_value;
|
if (node && EditorPropertyRevert::may_node_be_in_instance(node)) {
|
||||||
if (scr->get_property_default_value(p_property, orig_value)) {
|
//if this node is an instance or inherits, but it has a script attached which is unrelated
|
||||||
if (orig_value != p_object->get(p_property)) {
|
//to the one set for the parent and also has a default value for the property, consider that
|
||||||
has_revert = true;
|
//has precedence over the value from the parent, because that is an explicit source of defaults
|
||||||
}
|
//closer in the tree to the current node
|
||||||
|
bool ignore_parent = false;
|
||||||
|
if (scr.is_valid()) {
|
||||||
|
Variant sorig;
|
||||||
|
if (EditorPropertyRevert::get_instanced_node_original_property(node, "script", sorig) && !scr->inherits_script(sorig)) {
|
||||||
|
Variant dummy;
|
||||||
|
if (scr->get_property_default_value(p_property, dummy)) {
|
||||||
|
ignore_parent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ignore_parent) {
|
||||||
|
//check for difference including instantiation
|
||||||
|
Variant vorig;
|
||||||
|
if (EditorPropertyRevert::get_instanced_node_original_property(node, p_property, vorig, false)) {
|
||||||
|
return vorig;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return has_revert;
|
if (scr.is_valid()) {
|
||||||
|
Variant orig_value;
|
||||||
|
if (scr->get_property_default_value(p_property, orig_value)) {
|
||||||
|
return orig_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//report default class value instead
|
||||||
|
return ClassDB::class_get_default_property_value(p_object->get_class_name(), p_property);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
|
||||||
|
Variant revert_value = EditorPropertyRevert::get_property_revert_value(p_object, p_property);
|
||||||
|
if (revert_value.get_type() == Variant::NIL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Variant current_value = p_object->get(p_property);
|
||||||
|
return EditorPropertyRevert::is_property_value_different(current_value, revert_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorProperty::update_reload_status() {
|
void EditorProperty::update_reload_status() {
|
||||||
|
@ -656,41 +669,11 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revert_rect.has_point(mb->get_position())) {
|
if (revert_rect.has_point(mb->get_position())) {
|
||||||
Variant vorig;
|
Variant revert_value = EditorPropertyRevert::get_property_revert_value(object, property);
|
||||||
|
emit_changed(property, revert_value);
|
||||||
Node *node = Object::cast_to<Node>(object);
|
update_property();
|
||||||
if (node && EditorPropertyRevert::may_node_be_in_instance(node) && EditorPropertyRevert::get_instanced_node_original_property(node, property, vorig)) {
|
|
||||||
emit_changed(property, vorig.duplicate(true));
|
|
||||||
update_property();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (object->call("property_can_revert", property).operator bool()) {
|
|
||||||
Variant rev = object->call("property_get_revert", property);
|
|
||||||
emit_changed(property, rev);
|
|
||||||
update_property();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!object->get_script().is_null()) {
|
|
||||||
Ref<Script> scr = object->get_script();
|
|
||||||
if (scr.is_valid()) {
|
|
||||||
Variant orig_value;
|
|
||||||
if (scr->get_property_default_value(property, orig_value)) {
|
|
||||||
emit_changed(property, orig_value);
|
|
||||||
update_property();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variant default_value = ClassDB::class_get_default_property_value(object->get_class_name(), property);
|
|
||||||
if (default_value != Variant()) {
|
|
||||||
emit_changed(property, default_value);
|
|
||||||
update_property();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_rect.has_point(mb->get_position())) {
|
if (check_rect.has_point(mb->get_position())) {
|
||||||
checked = !checked;
|
checked = !checked;
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -40,8 +40,10 @@ class UndoRedo;
|
||||||
class EditorPropertyRevert {
|
class EditorPropertyRevert {
|
||||||
public:
|
public:
|
||||||
static bool may_node_be_in_instance(Node *p_node);
|
static bool may_node_be_in_instance(Node *p_node);
|
||||||
static bool get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value);
|
static bool get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value, bool p_check_class_default = true);
|
||||||
static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig);
|
static bool is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig);
|
||||||
|
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);
|
||||||
|
|
||||||
static bool can_property_revert(Object *p_object, const StringName &p_property);
|
static bool can_property_revert(Object *p_object, const StringName &p_property);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue