Add property value pinning

This commit is contained in:
Pedro J. Estébanez 2021-10-26 21:12:25 +02:00
parent 1806ec7c14
commit 8d6f80d367
10 changed files with 289 additions and 30 deletions

View File

@ -110,7 +110,7 @@
</signal>
<signal name="property_checked">
<argument index="0" name="property" type="StringName" />
<argument index="1" name="bool" type="String" />
<argument index="1" name="checked" type="bool" />
<description>
Emitted when a property was checked. Used internally.
</description>
@ -134,6 +134,14 @@
Emit it if you want to key a property with a single value.
</description>
</signal>
<signal name="property_pinned">
<argument index="0" name="property" type="StringName" />
<argument index="1" name="pinned" type="bool" />
<description>
Emit it if you want to mark (or unmark) the value of a property for being saved regardless of being equal to the default value.
The default value is the one the property will get when the node is just instantiated and can come from an ancestor scene in the inheritance/instancing chain, a script or a builtin class.
</description>
</signal>
<signal name="resource_selected">
<argument index="0" name="path" type="String" />
<argument index="1" name="resource" type="Resource" />

View File

@ -121,5 +121,9 @@
If passed to [method instantiate], provides local scene resources to the local scene. Only the main scene should receive the main edit state.
[b]Note:[/b] Only available in editor builds.
</constant>
<constant name="GEN_EDIT_STATE_MAIN_INHERITED" value="3" enum="GenEditState">
It's similar to [constant GEN_EDIT_STATE_MAIN], but for the case where the scene is being instantiated to be the base of another one.
[b]Note:[/b] Only available in editor builds.
</constant>
</constants>
</class>

View File

@ -168,5 +168,9 @@
If passed to [method PackedScene.instantiate], provides local scene resources to the local scene. Only the main scene should receive the main edit state.
[b]Note:[/b] Only available in editor builds.
</constant>
<constant name="GEN_EDIT_STATE_MAIN_INHERITED" value="3" enum="GenEditState">
If passed to [method PackedScene.instantiate], it's similar to [constant GEN_EDIT_STATE_MAIN], but for the case where the scene is being instantiated to be the base of another one.
[b]Note:[/b] Only available in editor builds.
</constant>
</constants>
</class>

View File

@ -306,6 +306,20 @@ void EditorProperty::_notification(int p_what) {
revert_rect = Rect2();
}
if (!pin_hidden && pinned) {
Ref<Texture2D> pinned_icon = get_theme_icon(SNAME("Pin"), SNAME("EditorIcons"));
int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2;
int total_icon_w = margin_w + pinned_icon->get_width();
int text_w = font->get_string_size(label, font_size, rtl ? HALIGN_RIGHT : HALIGN_LEFT, text_limit - total_icon_w).x;
int y = (size.height - pinned_icon->get_height()) / 2;
if (rtl) {
draw_texture(pinned_icon, Vector2(size.width - ofs - text_w - total_icon_w, y), color);
} else {
draw_texture(pinned_icon, Vector2(ofs + text_w + margin_w, y), color);
}
text_limit -= total_icon_w;
}
int v_ofs = (size.height - font->get_height(font_size)) / 2;
if (rtl) {
draw_string(font, Point2(size.width - ofs - text_limit, v_ofs + font->get_ascent(font_size)), label, HALIGN_RIGHT, text_limit, font_size, color);
@ -416,15 +430,22 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
return PropertyUtils::is_property_value_different(current_value, revert_value);
}
void EditorProperty::update_reload_status() {
void EditorProperty::update_revert_and_pin_status() {
if (property == StringName()) {
return; //no property, so nothing to do
}
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property);
bool new_pinned = false;
if (can_pin) {
Node *node = Object::cast_to<Node>(object);
CRASH_COND(!node);
new_pinned = node->is_property_pinned(property);
}
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property) && !is_read_only();
if (new_can_revert != can_revert) {
if (new_can_revert != can_revert || new_pinned != pinned) {
can_revert = new_can_revert;
pinned = new_pinned;
update();
}
}
@ -627,7 +648,7 @@ void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
emit_signal(SNAME("property_checked"), property, checked);
}
} else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
_ensure_popup();
_update_popup();
menu->set_position(get_screen_position() + get_local_mouse_position());
menu->set_size(Vector2(1, 1));
menu->popup();
@ -750,6 +771,56 @@ float EditorProperty::get_name_split_ratio() const {
void EditorProperty::set_object_and_property(Object *p_object, const StringName &p_property) {
object = p_object;
property = p_property;
_update_pin_flags();
}
static bool _is_value_potential_override(Node *p_node, const String &p_property) {
// Consider a value is potentially overriding another if either of the following is true:
// a) The node is foreign (inheriting or an instance), so the original value may come from another scene.
// b) The node belongs to the scene, but the original value comes from somewhere but the builtin class (i.e., a script).
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
Vector<SceneState::PackState> states_stack = PropertyUtils::get_node_states_stack(p_node, edited_scene);
if (states_stack.size()) {
return true;
} else {
bool is_class_default = false;
PropertyUtils::get_property_default_value(p_node, p_property, &states_stack, false, nullptr, &is_class_default);
return !is_class_default;
}
}
void EditorProperty::_update_pin_flags() {
can_pin = false;
pin_hidden = true;
if (read_only) {
return;
}
if (Node *node = Object::cast_to<Node>(object)) {
// Avoid errors down the road by ignoring nodes which are not part of a scene
if (!node->get_owner()) {
bool is_scene_root = false;
for (int i = 0; i < EditorNode::get_singleton()->get_editor_data().get_edited_scene_count(); ++i) {
if (EditorNode::get_singleton()->get_editor_data().get_edited_scene_root(i) == node) {
is_scene_root = true;
break;
}
}
if (!is_scene_root) {
return;
}
}
if (!_is_value_potential_override(node, property)) {
return;
}
pin_hidden = false;
{
Set<StringName> storable_properties;
node->get_storable_properties(storable_properties);
if (storable_properties.has(node->get_property_store_alias(property))) {
can_pin = true;
}
}
}
}
Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
@ -791,6 +862,10 @@ void EditorProperty::menu_option(int p_option) {
case MENU_COPY_PROPERTY_PATH: {
DisplayServer::get_singleton()->clipboard_set(property);
} break;
case MENU_PIN_VALUE: {
emit_signal(SNAME("property_pinned"), property, !pinned);
update();
} break;
}
}
@ -839,12 +914,14 @@ void EditorProperty::_bind_methods() {
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property")));
ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING_NAME, "property")));
ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::STRING, "bool")));
ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "checked")));
ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::BOOL, "pinned")));
ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
GDVIRTUAL_BIND(_update_property)
ClassDB::bind_method(D_METHOD("_update_revert_and_pin_status"), &EditorProperty::update_revert_and_pin_status);
}
EditorProperty::EditorProperty() {
@ -863,6 +940,9 @@ EditorProperty::EditorProperty() {
revert_hover = false;
check_hover = false;
can_revert = false;
can_pin = false;
pin_hidden = false;
pinned = false;
use_folding = false;
property_usage = 0;
selected = false;
@ -874,17 +954,29 @@ EditorProperty::EditorProperty() {
set_process_unhandled_key_input(true);
}
void EditorProperty::_ensure_popup() {
void EditorProperty::_update_popup() {
if (menu) {
return;
menu->clear();
} else {
menu = memnew(PopupMenu);
add_child(menu);
menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
}
menu = memnew(PopupMenu);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property"), MENU_COPY_PROPERTY);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/paste_property"), MENU_PASTE_PROPERTY);
menu->add_shortcut(ED_GET_SHORTCUT("property_editor/copy_property_path"), MENU_COPY_PROPERTY_PATH);
menu->connect("id_pressed", callable_mp(this, &EditorProperty::menu_option));
menu->set_item_disabled(MENU_PASTE_PROPERTY, is_read_only());
add_child(menu);
if (!pin_hidden) {
menu->add_separator();
if (can_pin) {
menu->add_check_item(TTR("Pin value"), MENU_PIN_VALUE);
menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), pinned);
menu->set_item_tooltip(menu->get_item_index(MENU_PIN_VALUE), TTR("Pinning a value forces it to be saved even if it's equal to the default."));
} else {
menu->add_check_item(vformat(TTR("Pin value [Disabled because '%s' is editor-only]"), property), MENU_PIN_VALUE);
menu->set_item_disabled(menu->get_item_index(MENU_PIN_VALUE), true);
}
}
}
////////////////////////////////////////////////
@ -2132,6 +2224,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
@ -2160,7 +2253,8 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->set_read_only(read_only);
ep->update_property();
ep->update_reload_status();
ep->_update_pin_flags();
ep->update_revert_and_pin_status();
ep->set_deletable(deletable_properties);
ep->update_cache();
}
@ -2713,6 +2807,7 @@ void EditorInspector::update_tree() {
ep->connect("property_deleted", callable_mp(this, &EditorInspector::_property_deleted), varray(), CONNECT_DEFERRED);
ep->connect("property_keyed_with_value", callable_mp(this, &EditorInspector::_property_keyed_with_value));
ep->connect("property_checked", callable_mp(this, &EditorInspector::_property_checked));
ep->connect("property_pinned", callable_mp(this, &EditorInspector::_property_pinned));
ep->connect("selected", callable_mp(this, &EditorInspector::_property_selected));
ep->connect("multiple_properties_changed", callable_mp(this, &EditorInspector::_multiple_properties_changed));
ep->connect("resource_selected", callable_mp(this, &EditorInspector::_resource_selected), varray(), CONNECT_DEFERRED);
@ -2723,7 +2818,8 @@ void EditorInspector::update_tree() {
ep->set_tooltip(property_prefix + p.name);
}
ep->update_property();
ep->update_reload_status();
ep->_update_pin_flags();
ep->update_revert_and_pin_status();
ep->update_cache();
if (current_selected && ep->property == current_selected) {
@ -2753,7 +2849,7 @@ void EditorInspector::update_property(const String &p_prop) {
for (EditorProperty *E : editor_property_map[p_prop]) {
E->update_property();
E->update_reload_status();
E->update_revert_and_pin_status();
E->update_cache();
}
}
@ -3032,7 +3128,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
if (editor_property_map.has(p_name)) {
for (EditorProperty *E : editor_property_map[p_name]) {
E->update_reload_status();
E->update_revert_and_pin_status();
}
}
}
@ -3131,7 +3227,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
if (editor_property_map.has(p_path)) {
for (EditorProperty *E : editor_property_map[p_path]) {
E->update_property();
E->update_reload_status();
E->update_revert_and_pin_status();
E->update_cache();
}
}
@ -3141,6 +3237,35 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
}
}
void EditorInspector::_property_pinned(const String &p_path, bool p_pinned) {
if (!object) {
return;
}
Node *node = Object::cast_to<Node>(object);
ERR_FAIL_COND(!node);
if (undo_redo) {
undo_redo->create_action(vformat(p_pinned ? TTR("Pinned %s") : TTR("Unpinned %s"), p_path));
undo_redo->add_do_method(node, "_set_property_pinned", p_path, p_pinned);
undo_redo->add_undo_method(node, "_set_property_pinned", p_path, !p_pinned);
if (editor_property_map.has(p_path)) {
for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
undo_redo->add_do_method(E->get(), "_update_revert_and_pin_status");
undo_redo->add_undo_method(E->get(), "_update_revert_and_pin_status");
}
}
undo_redo->commit_action();
} else {
node->set_property_pinned(p_path, p_pinned);
if (editor_property_map.has(p_path)) {
for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
E->get()->update_revert_and_pin_status();
}
}
}
}
void EditorInspector::_property_selected(const String &p_path, int p_focusable) {
property_selected = p_path;
property_focusable = p_focusable;
@ -3211,7 +3336,7 @@ void EditorInspector::_notification(int p_what) {
for (EditorProperty *E : F.value) {
if (!E->is_cache_valid()) {
E->update_property();
E->update_reload_status();
E->update_revert_and_pin_status();
E->update_cache();
}
}
@ -3233,7 +3358,7 @@ void EditorInspector::_notification(int p_what) {
if (editor_property_map.has(prop)) {
for (EditorProperty *E : editor_property_map[prop]) {
E->update_property();
E->update_reload_status();
E->update_revert_and_pin_status();
E->update_cache();
}
}

View File

@ -59,6 +59,7 @@ public:
MENU_COPY_PROPERTY,
MENU_PASTE_PROPERTY,
MENU_COPY_PROPERTY_PATH,
MENU_PIN_VALUE,
};
private:
@ -90,11 +91,14 @@ private:
bool delete_hover = false;
bool can_revert;
bool can_pin;
bool pin_hidden;
bool pinned;
bool use_folding;
bool draw_top_bg;
void _ensure_popup();
void _update_popup();
void _focusable_focused(int p_index);
bool selectable;
@ -113,6 +117,8 @@ private:
Map<StringName, Variant> cache;
GDVIRTUAL0(_update_property)
void _update_pin_flags();
protected:
void _notification(int p_what);
static void _bind_methods();
@ -137,7 +143,7 @@ public:
StringName get_edited_property();
virtual void update_property();
void update_reload_status();
void update_revert_and_pin_status();
virtual bool use_keying_next() const;
@ -458,8 +464,8 @@ class EditorInspector : public ScrollContainer {
void _property_keyed(const String &p_path, bool p_advance);
void _property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
void _property_deleted(const String &p_path);
void _property_checked(const String &p_path, bool p_checked);
void _property_pinned(const String &p_path, bool p_pinned);
void _resource_selected(const String &p_path, RES p_resource);
void _property_selected(const String &p_path, int p_focusable);

View File

@ -3623,7 +3623,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
sdata->set_path(lpath, true); // take over path
}
Node *new_scene = sdata->instantiate(PackedScene::GEN_EDIT_STATE_MAIN);
Node *new_scene = sdata->instantiate(p_set_inherited ? PackedScene::GEN_EDIT_STATE_MAIN_INHERITED : PackedScene::GEN_EDIT_STATE_MAIN);
if (!new_scene) {
sdata.unref();

View File

@ -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");
{

View File

@ -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 */

View File

@ -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() {

View File

@ -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);