Add property value pinning
This commit is contained in:
parent
1806ec7c14
commit
8d6f80d367
10 changed files with 289 additions and 30 deletions
|
|
@ -1894,6 +1894,56 @@ Node *Node::get_deepest_editable_node(Node *p_start_node) const {
|
|||
return node;
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void Node::set_property_pinned(const String &p_property, bool p_pinned) {
|
||||
bool current_pinned = false;
|
||||
bool has_pinned = has_meta("_edit_pinned_properties_");
|
||||
Array pinned;
|
||||
String psa = get_property_store_alias(p_property);
|
||||
if (has_pinned) {
|
||||
pinned = get_meta("_edit_pinned_properties_");
|
||||
current_pinned = pinned.has(psa);
|
||||
}
|
||||
|
||||
if (current_pinned != p_pinned) {
|
||||
if (p_pinned) {
|
||||
pinned.append(psa);
|
||||
if (!has_pinned) {
|
||||
set_meta("_edit_pinned_properties_", pinned);
|
||||
}
|
||||
} else {
|
||||
pinned.erase(psa);
|
||||
if (pinned.is_empty()) {
|
||||
remove_meta("_edit_pinned_properties_");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Node::is_property_pinned(const StringName &p_property) const {
|
||||
if (!has_meta("_edit_pinned_properties_")) {
|
||||
return false;
|
||||
}
|
||||
Array pinned = get_meta("_edit_pinned_properties_");
|
||||
String psa = get_property_store_alias(p_property);
|
||||
return pinned.has(psa);
|
||||
}
|
||||
|
||||
StringName Node::get_property_store_alias(const StringName &p_property) const {
|
||||
return p_property;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Node::get_storable_properties(Set<StringName> &r_storable_properties) const {
|
||||
List<PropertyInfo> pi;
|
||||
get_property_list(&pi);
|
||||
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
|
||||
if ((E->get().usage & PROPERTY_USAGE_STORAGE)) {
|
||||
r_storable_properties.insert(E->get().name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String Node::to_string() {
|
||||
if (get_script_instance()) {
|
||||
bool valid;
|
||||
|
|
@ -2745,6 +2795,10 @@ void Node::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("_set_import_path", "import_path"), &Node::set_import_path);
|
||||
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned);
|
||||
#endif
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -363,6 +363,13 @@ public:
|
|||
bool is_editable_instance(const Node *p_node) const;
|
||||
Node *get_deepest_editable_node(Node *p_start_node) const;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void set_property_pinned(const String &p_property, bool p_pinned);
|
||||
bool is_property_pinned(const StringName &p_property) const;
|
||||
virtual StringName get_property_store_alias(const StringName &p_property) const;
|
||||
#endif
|
||||
void get_storable_properties(Set<StringName> &r_storable_properties) const;
|
||||
|
||||
virtual String to_string() override;
|
||||
|
||||
/* NOTIFICATIONS */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,30 @@ bool SceneState::can_instantiate() const {
|
|||
return nodes.size() > 0;
|
||||
}
|
||||
|
||||
static Array _sanitize_node_pinned_properties(Node *p_node) {
|
||||
if (!p_node->has_meta("_edit_pinned_properties_")) {
|
||||
return Array();
|
||||
}
|
||||
Array pinned = p_node->get_meta("_edit_pinned_properties_");
|
||||
if (pinned.is_empty()) {
|
||||
return Array();
|
||||
}
|
||||
Set<StringName> storable_properties;
|
||||
p_node->get_storable_properties(storable_properties);
|
||||
int i = 0;
|
||||
do {
|
||||
if (storable_properties.has(pinned[i])) {
|
||||
i++;
|
||||
} else {
|
||||
pinned.remove(i);
|
||||
}
|
||||
} while (i < pinned.size());
|
||||
if (pinned.is_empty()) {
|
||||
p_node->remove_meta("_edit_pinned_properties_");
|
||||
}
|
||||
return pinned;
|
||||
}
|
||||
|
||||
Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
||||
// nodes where instancing failed (because something is missing)
|
||||
List<Node *> stray_instances;
|
||||
|
|
@ -229,7 +253,7 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
|||
} else {
|
||||
Node *base = i == 0 ? node : ret_nodes[0];
|
||||
|
||||
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
|
||||
if (p_edit_state == GEN_EDIT_STATE_MAIN || p_edit_state == GEN_EDIT_STATE_MAIN_INHERITED) {
|
||||
//for the main scene, use the resource as is
|
||||
res->configure_for_local_scene(base, resources_local_to_scene);
|
||||
resources_local_to_scene[res] = res;
|
||||
|
|
@ -293,6 +317,13 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
|
|||
}
|
||||
}
|
||||
|
||||
// we only want to deal with pinned flag if instancing as pure main (no instance, no inheriting)
|
||||
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
|
||||
_sanitize_node_pinned_properties(node);
|
||||
} else {
|
||||
node->remove_meta("_edit_pinned_properties_");
|
||||
}
|
||||
|
||||
ret_nodes[i] = node;
|
||||
|
||||
if (node && gen_node_path_cache && ret_nodes[0]) {
|
||||
|
|
@ -442,22 +473,38 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
|
|||
List<PropertyInfo> plist;
|
||||
p_node->get_property_list(&plist);
|
||||
|
||||
Array pinned_props = _sanitize_node_pinned_properties(p_node);
|
||||
|
||||
for (const PropertyInfo &E : plist) {
|
||||
if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Variant forced_value;
|
||||
|
||||
// If instance or inheriting, not saving if property requested so, or it's meta
|
||||
if (states_stack.size() && ((E.usage & PROPERTY_USAGE_NO_INSTANCE_STATE) || E.name == "__meta__")) {
|
||||
continue;
|
||||
if (states_stack.size()) {
|
||||
if ((E.usage & PROPERTY_USAGE_NO_INSTANCE_STATE)) {
|
||||
continue;
|
||||
}
|
||||
// Meta is normally not saved in instances/inherited (see GH-12838), but we need to save the pinned list
|
||||
if (E.name == "__meta__") {
|
||||
if (pinned_props.size()) {
|
||||
Dictionary meta_override;
|
||||
meta_override["_edit_pinned_properties_"] = pinned_props;
|
||||
forced_value = meta_override;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String name = E.name;
|
||||
Variant value = p_node->get(name);
|
||||
StringName name = E.name;
|
||||
Variant value = forced_value.get_type() == Variant::NIL ? p_node->get(name) : forced_value;
|
||||
|
||||
Variant default_value = PropertyUtils::get_property_default_value(p_node, name, &states_stack, true);
|
||||
if (!PropertyUtils::is_property_value_different(value, default_value)) {
|
||||
continue;
|
||||
if (!pinned_props.has(name) && forced_value.get_type() == Variant::NIL) {
|
||||
Variant default_value = PropertyUtils::get_property_default_value(p_node, name, &states_stack, true);
|
||||
if (!PropertyUtils::is_property_value_different(value, default_value)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
NodeData::Property prop;
|
||||
|
|
@ -1505,6 +1552,7 @@ void SceneState::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN_INHERITED);
|
||||
}
|
||||
|
||||
SceneState::SceneState() {
|
||||
|
|
@ -1596,6 +1644,7 @@ void PackedScene::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN_INHERITED);
|
||||
}
|
||||
|
||||
PackedScene::PackedScene() {
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ public:
|
|||
GEN_EDIT_STATE_DISABLED,
|
||||
GEN_EDIT_STATE_INSTANCE,
|
||||
GEN_EDIT_STATE_MAIN,
|
||||
GEN_EDIT_STATE_MAIN_INHERITED,
|
||||
};
|
||||
|
||||
struct PackState {
|
||||
|
|
@ -207,6 +208,7 @@ public:
|
|||
GEN_EDIT_STATE_DISABLED,
|
||||
GEN_EDIT_STATE_INSTANCE,
|
||||
GEN_EDIT_STATE_MAIN,
|
||||
GEN_EDIT_STATE_MAIN_INHERITED,
|
||||
};
|
||||
|
||||
Error pack(Node *p_scene);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue