You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-11 13:10:58 +00:00
Add property value pinning
This commit is contained in:
@@ -102,7 +102,7 @@
|
|||||||
</signal>
|
</signal>
|
||||||
<signal name="property_checked">
|
<signal name="property_checked">
|
||||||
<argument index="0" name="property" type="String" />
|
<argument index="0" name="property" type="String" />
|
||||||
<argument index="1" name="bool" type="String" />
|
<argument index="1" name="checked" type="bool" />
|
||||||
<description>
|
<description>
|
||||||
Emitted when a property was checked. Used internally.
|
Emitted when a property was checked. Used internally.
|
||||||
</description>
|
</description>
|
||||||
@@ -120,6 +120,14 @@
|
|||||||
Emit it if you want to key a property with a single value.
|
Emit it if you want to key a property with a single value.
|
||||||
</description>
|
</description>
|
||||||
</signal>
|
</signal>
|
||||||
|
<signal name="property_pinned">
|
||||||
|
<argument index="0" name="property" type="String" />
|
||||||
|
<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">
|
<signal name="resource_selected">
|
||||||
<argument index="0" name="path" type="String" />
|
<argument index="0" name="path" type="String" />
|
||||||
<argument index="1" name="resource" type="Resource" />
|
<argument index="1" name="resource" type="Resource" />
|
||||||
|
|||||||
@@ -86,5 +86,9 @@
|
|||||||
If passed to [method instance], provides local scene resources to the local scene. Only the main scene should receive the main edit state.
|
If passed to [method instance], 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.
|
[b]Note:[/b] Only available in editor builds.
|
||||||
</constant>
|
</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>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|||||||
@@ -168,5 +168,9 @@
|
|||||||
If passed to [method PackedScene.instance], provides local scene resources to the local scene. Only the main scene should receive the main edit state.
|
If passed to [method PackedScene.instance], 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.
|
[b]Note:[/b] Only available in editor builds.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="GEN_EDIT_STATE_MAIN_INHERITED" value="3" enum="GenEditState">
|
||||||
|
If passed to [method PackedScene.instance], 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>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
|||||||
@@ -261,6 +261,14 @@ void EditorProperty::_notification(int p_what) {
|
|||||||
revert_rect = Rect2();
|
revert_rect = Rect2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pin_hidden && is_pinned) {
|
||||||
|
Ref<Texture> pinned_icon = get_icon("Pin", "EditorIcons");
|
||||||
|
int margin_w = get_constant("hseparator", "Tree") * 2;
|
||||||
|
text_limit -= margin_w + pinned_icon->get_width();
|
||||||
|
int text_w = MIN(font->get_string_size(label).x, text_limit);
|
||||||
|
draw_texture(pinned_icon, Vector2(ofs + text_w + margin_w, (size.height - pinned_icon->get_height()) / 2), color);
|
||||||
|
}
|
||||||
|
|
||||||
int v_ofs = (size.height - font->get_height()) / 2;
|
int v_ofs = (size.height - font->get_height()) / 2;
|
||||||
draw_string(font, Point2(ofs, v_ofs + font->get_ascent()), label, color, text_limit);
|
draw_string(font, Point2(ofs, v_ofs + font->get_ascent()), label, color, text_limit);
|
||||||
|
|
||||||
@@ -337,15 +345,22 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
|
|||||||
return PropertyUtils::is_property_value_different(current_value, revert_value);
|
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()) {
|
if (property == StringName()) {
|
||||||
return; //no property, so nothing to do
|
return; //no property, so nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool new_is_pinned = false;
|
||||||
|
if (can_pin) {
|
||||||
|
Node *node = Object::cast_to<Node>(object);
|
||||||
|
CRASH_COND(!node);
|
||||||
|
new_is_pinned = node->is_property_pinned(property);
|
||||||
|
}
|
||||||
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property);
|
bool new_can_revert = EditorPropertyRevert::can_property_revert(object, property);
|
||||||
|
|
||||||
if (new_can_revert != can_revert) {
|
if (new_can_revert != can_revert || new_is_pinned != is_pinned) {
|
||||||
can_revert = new_can_revert;
|
can_revert = new_can_revert;
|
||||||
|
is_pinned = new_is_pinned;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -516,6 +531,14 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
|
|||||||
update();
|
update();
|
||||||
emit_signal("property_checked", property, checked);
|
emit_signal("property_checked", property, checked);
|
||||||
}
|
}
|
||||||
|
} else if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
|
||||||
|
_update_popup();
|
||||||
|
if (menu->get_item_count()) {
|
||||||
|
menu->set_position(get_global_mouse_position());
|
||||||
|
menu->set_as_minsize();
|
||||||
|
menu->popup();
|
||||||
|
select();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,6 +598,56 @@ float EditorProperty::get_name_split_ratio() const {
|
|||||||
void EditorProperty::set_object_and_property(Object *p_object, const StringName &p_property) {
|
void EditorProperty::set_object_and_property(Object *p_object, const StringName &p_property) {
|
||||||
object = p_object;
|
object = p_object;
|
||||||
property = p_property;
|
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 {
|
Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
|
||||||
@@ -627,6 +700,7 @@ void EditorProperty::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object);
|
ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("_gui_input"), &EditorProperty::_gui_input);
|
ClassDB::bind_method(D_METHOD("_gui_input"), &EditorProperty::_gui_input);
|
||||||
|
ClassDB::bind_method(D_METHOD("_menu_option"), &EditorProperty::_menu_option);
|
||||||
ClassDB::bind_method(D_METHOD("_focusable_focused"), &EditorProperty::_focusable_focused);
|
ClassDB::bind_method(D_METHOD("_focusable_focused"), &EditorProperty::_focusable_focused);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_tooltip_text"), &EditorProperty::get_tooltip_text);
|
ClassDB::bind_method(D_METHOD("get_tooltip_text"), &EditorProperty::get_tooltip_text);
|
||||||
@@ -646,7 +720,8 @@ void EditorProperty::_bind_methods() {
|
|||||||
ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::POOL_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value")));
|
ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::POOL_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value")));
|
||||||
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property")));
|
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property")));
|
||||||
ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
|
ADD_SIGNAL(MethodInfo("property_keyed_with_value", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
|
||||||
ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::STRING, "bool")));
|
ADD_SIGNAL(MethodInfo("property_checked", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked")));
|
||||||
|
ADD_SIGNAL(MethodInfo("property_pinned", PropertyInfo(Variant::STRING, "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("resource_selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
|
||||||
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::INT, "id")));
|
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::INT, "id")));
|
||||||
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
|
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
|
||||||
@@ -654,6 +729,8 @@ void EditorProperty::_bind_methods() {
|
|||||||
MethodInfo vm;
|
MethodInfo vm;
|
||||||
vm.name = "update_property";
|
vm.name = "update_property";
|
||||||
BIND_VMETHOD(vm);
|
BIND_VMETHOD(vm);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_update_revert_and_pin_status"), &EditorProperty::update_revert_and_pin_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorProperty::EditorProperty() {
|
EditorProperty::EditorProperty() {
|
||||||
@@ -671,13 +748,47 @@ EditorProperty::EditorProperty() {
|
|||||||
revert_hover = false;
|
revert_hover = false;
|
||||||
check_hover = false;
|
check_hover = false;
|
||||||
can_revert = false;
|
can_revert = false;
|
||||||
|
can_pin = false;
|
||||||
|
pin_hidden = false;
|
||||||
|
is_pinned = false;
|
||||||
use_folding = false;
|
use_folding = false;
|
||||||
property_usage = 0;
|
property_usage = 0;
|
||||||
selected = false;
|
selected = false;
|
||||||
selected_focusable = -1;
|
selected_focusable = -1;
|
||||||
label_reference = nullptr;
|
label_reference = nullptr;
|
||||||
bottom_editor = nullptr;
|
bottom_editor = nullptr;
|
||||||
|
menu = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorProperty::_update_popup() {
|
||||||
|
if (menu) {
|
||||||
|
menu->clear();
|
||||||
|
} else {
|
||||||
|
menu = memnew(PopupMenu);
|
||||||
|
add_child(menu);
|
||||||
|
menu->connect("id_pressed", this, "_menu_option");
|
||||||
|
}
|
||||||
|
if (!pin_hidden) {
|
||||||
|
if (can_pin) {
|
||||||
|
menu->add_check_item(TTR("Pin value"), MENU_PIN_VALUE);
|
||||||
|
menu->set_item_checked(menu->get_item_index(MENU_PIN_VALUE), is_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorProperty::_menu_option(int p_option) {
|
||||||
|
switch (p_option) {
|
||||||
|
case MENU_PIN_VALUE: {
|
||||||
|
emit_signal("property_pinned", property, !is_pinned);
|
||||||
|
update();
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -1142,6 +1253,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
|
|||||||
ep->connect("property_keyed", this, "_property_keyed");
|
ep->connect("property_keyed", this, "_property_keyed");
|
||||||
ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
|
ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
|
||||||
ep->connect("property_checked", this, "_property_checked");
|
ep->connect("property_checked", this, "_property_checked");
|
||||||
|
ep->connect("property_pinned", this, "_property_pinned");
|
||||||
ep->connect("selected", this, "_property_selected");
|
ep->connect("selected", this, "_property_selected");
|
||||||
ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
|
ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
|
||||||
ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
|
ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
|
||||||
@@ -1170,7 +1282,8 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
|
|||||||
|
|
||||||
ep->set_read_only(read_only);
|
ep->set_read_only(read_only);
|
||||||
ep->update_property();
|
ep->update_property();
|
||||||
ep->update_reload_status();
|
ep->_update_pin_flags();
|
||||||
|
ep->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ped->added_editors.clear();
|
ped->added_editors.clear();
|
||||||
@@ -1566,6 +1679,7 @@ void EditorInspector::update_tree() {
|
|||||||
ep->connect("property_keyed", this, "_property_keyed");
|
ep->connect("property_keyed", this, "_property_keyed");
|
||||||
ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
|
ep->connect("property_keyed_with_value", this, "_property_keyed_with_value");
|
||||||
ep->connect("property_checked", this, "_property_checked");
|
ep->connect("property_checked", this, "_property_checked");
|
||||||
|
ep->connect("property_pinned", this, "_property_pinned");
|
||||||
ep->connect("selected", this, "_property_selected");
|
ep->connect("selected", this, "_property_selected");
|
||||||
ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
|
ep->connect("multiple_properties_changed", this, "_multiple_properties_changed");
|
||||||
ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
|
ep->connect("resource_selected", this, "_resource_selected", varray(), CONNECT_DEFERRED);
|
||||||
@@ -1576,7 +1690,8 @@ void EditorInspector::update_tree() {
|
|||||||
ep->set_tooltip(property_prefix + p.name);
|
ep->set_tooltip(property_prefix + p.name);
|
||||||
}
|
}
|
||||||
ep->update_property();
|
ep->update_property();
|
||||||
ep->update_reload_status();
|
ep->_update_pin_flags();
|
||||||
|
ep->update_revert_and_pin_status();
|
||||||
|
|
||||||
if (current_selected && ep->property == current_selected) {
|
if (current_selected && ep->property == current_selected) {
|
||||||
ep->select(current_focusable);
|
ep->select(current_focusable);
|
||||||
@@ -1605,7 +1720,7 @@ void EditorInspector::update_property(const String &p_prop) {
|
|||||||
|
|
||||||
for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) {
|
for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) {
|
||||||
E->get()->update_property();
|
E->get()->update_property();
|
||||||
E->get()->update_reload_status();
|
E->get()->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1844,7 +1959,7 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
|
|||||||
|
|
||||||
if (editor_property_map.has(p_name)) {
|
if (editor_property_map.has(p_name)) {
|
||||||
for (List<EditorProperty *>::Element *E = editor_property_map[p_name].front(); E; E = E->next()) {
|
for (List<EditorProperty *>::Element *E = editor_property_map[p_name].front(); E; E = E->next()) {
|
||||||
E->get()->update_reload_status();
|
E->get()->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1935,7 +2050,7 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
|
|||||||
if (editor_property_map.has(p_path)) {
|
if (editor_property_map.has(p_path)) {
|
||||||
for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
|
for (List<EditorProperty *>::Element *E = editor_property_map[p_path].front(); E; E = E->next()) {
|
||||||
E->get()->update_property();
|
E->get()->update_property();
|
||||||
E->get()->update_reload_status();
|
E->get()->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1944,6 +2059,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) {
|
void EditorInspector::_property_selected(const String &p_path, int p_focusable) {
|
||||||
property_selected = p_path;
|
property_selected = p_path;
|
||||||
property_focusable = p_focusable;
|
property_focusable = p_focusable;
|
||||||
@@ -2008,7 +2152,7 @@ void EditorInspector::_notification(int p_what) {
|
|||||||
for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) {
|
for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) {
|
||||||
for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) {
|
for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) {
|
||||||
E->get()->update_property();
|
E->get()->update_property();
|
||||||
E->get()->update_reload_status();
|
E->get()->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2027,7 +2171,7 @@ void EditorInspector::_notification(int p_what) {
|
|||||||
if (editor_property_map.has(prop)) {
|
if (editor_property_map.has(prop)) {
|
||||||
for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) {
|
for (List<EditorProperty *>::Element *E = editor_property_map[prop].front(); E; E = E->next()) {
|
||||||
E->get()->update_property();
|
E->get()->update_property();
|
||||||
E->get()->update_reload_status();
|
E->get()->update_revert_and_pin_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pending.erase(pending.front());
|
pending.erase(pending.front());
|
||||||
@@ -2090,6 +2234,7 @@ void EditorInspector::_bind_methods() {
|
|||||||
ClassDB::bind_method("_property_keyed", &EditorInspector::_property_keyed);
|
ClassDB::bind_method("_property_keyed", &EditorInspector::_property_keyed);
|
||||||
ClassDB::bind_method("_property_keyed_with_value", &EditorInspector::_property_keyed_with_value);
|
ClassDB::bind_method("_property_keyed_with_value", &EditorInspector::_property_keyed_with_value);
|
||||||
ClassDB::bind_method("_property_checked", &EditorInspector::_property_checked);
|
ClassDB::bind_method("_property_checked", &EditorInspector::_property_checked);
|
||||||
|
ClassDB::bind_method("_property_pinned", &EditorInspector::_property_pinned);
|
||||||
ClassDB::bind_method("_property_selected", &EditorInspector::_property_selected);
|
ClassDB::bind_method("_property_selected", &EditorInspector::_property_selected);
|
||||||
ClassDB::bind_method("_resource_selected", &EditorInspector::_resource_selected);
|
ClassDB::bind_method("_resource_selected", &EditorInspector::_resource_selected);
|
||||||
ClassDB::bind_method("_object_id_selected", &EditorInspector::_object_id_selected);
|
ClassDB::bind_method("_object_id_selected", &EditorInspector::_object_id_selected);
|
||||||
|
|||||||
@@ -50,6 +50,11 @@ public:
|
|||||||
class EditorProperty : public Container {
|
class EditorProperty : public Container {
|
||||||
GDCLASS(EditorProperty, Container);
|
GDCLASS(EditorProperty, Container);
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum MenuItems {
|
||||||
|
MENU_PIN_VALUE,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String label;
|
String label;
|
||||||
int text_size;
|
int text_size;
|
||||||
@@ -76,10 +81,15 @@ private:
|
|||||||
bool check_hover;
|
bool check_hover;
|
||||||
|
|
||||||
bool can_revert;
|
bool can_revert;
|
||||||
|
bool can_pin;
|
||||||
|
bool pin_hidden;
|
||||||
|
bool is_pinned;
|
||||||
|
|
||||||
bool use_folding;
|
bool use_folding;
|
||||||
bool draw_top_bg;
|
bool draw_top_bg;
|
||||||
|
|
||||||
|
void _update_popup();
|
||||||
|
void _menu_option(int p_option);
|
||||||
void _focusable_focused(int p_index);
|
void _focusable_focused(int p_index);
|
||||||
|
|
||||||
bool selectable;
|
bool selectable;
|
||||||
@@ -91,9 +101,12 @@ private:
|
|||||||
Vector<Control *> focusables;
|
Vector<Control *> focusables;
|
||||||
Control *label_reference;
|
Control *label_reference;
|
||||||
Control *bottom_editor;
|
Control *bottom_editor;
|
||||||
|
PopupMenu *menu;
|
||||||
|
|
||||||
mutable String tooltip_text;
|
mutable String tooltip_text;
|
||||||
|
|
||||||
|
void _update_pin_flags();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
@@ -115,7 +128,7 @@ public:
|
|||||||
StringName get_edited_property();
|
StringName get_edited_property();
|
||||||
|
|
||||||
virtual void update_property();
|
virtual void update_property();
|
||||||
void update_reload_status();
|
void update_revert_and_pin_status();
|
||||||
|
|
||||||
virtual bool use_keying_next() const;
|
virtual bool use_keying_next() const;
|
||||||
|
|
||||||
@@ -305,8 +318,8 @@ class EditorInspector : public ScrollContainer {
|
|||||||
void _multiple_properties_changed(Vector<String> p_paths, Array p_values);
|
void _multiple_properties_changed(Vector<String> p_paths, Array p_values);
|
||||||
void _property_keyed(const String &p_path, bool p_advance);
|
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_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance);
|
||||||
|
|
||||||
void _property_checked(const String &p_path, bool p_checked);
|
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 _resource_selected(const String &p_path, RES p_resource);
|
||||||
void _property_selected(const String &p_path, int p_focusable);
|
void _property_selected(const String &p_path, int p_focusable);
|
||||||
|
|||||||
@@ -3588,7 +3588,7 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
|
|||||||
sdata->set_path(lpath, true); //take over path
|
sdata->set_path(lpath, true); //take over path
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *new_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_MAIN);
|
Node *new_scene = sdata->instance(p_set_inherited ? PackedScene::GEN_EDIT_STATE_MAIN_INHERITED : PackedScene::GEN_EDIT_STATE_MAIN);
|
||||||
|
|
||||||
if (!new_scene) {
|
if (!new_scene) {
|
||||||
sdata.unref();
|
sdata.unref();
|
||||||
|
|||||||
@@ -439,6 +439,16 @@ void Node2D::_bind_methods() {
|
|||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "z_as_relative"), "set_z_as_relative", "is_z_relative");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
StringName Node2D::get_property_store_alias(const StringName &p_property) const {
|
||||||
|
if (p_property == "rotation_degrees") {
|
||||||
|
return "rotation";
|
||||||
|
} else {
|
||||||
|
return Node::get_property_store_alias(p_property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Node2D::Node2D() {
|
Node2D::Node2D() {
|
||||||
angle = 0;
|
angle = 0;
|
||||||
_scale = Vector2(1, 1);
|
_scale = Vector2(1, 1);
|
||||||
|
|||||||
@@ -116,6 +116,10 @@ public:
|
|||||||
|
|
||||||
Transform2D get_transform() const;
|
Transform2D get_transform() const;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
virtual StringName get_property_store_alias(const StringName &p_property) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
Node2D();
|
Node2D();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -306,6 +306,16 @@ void CanvasLayer::_bind_methods() {
|
|||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
StringName CanvasLayer::get_property_store_alias(const StringName &p_property) const {
|
||||||
|
if (p_property == "rotation_degrees") {
|
||||||
|
return "rotation";
|
||||||
|
} else {
|
||||||
|
return Node::get_property_store_alias(p_property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
CanvasLayer::CanvasLayer() {
|
CanvasLayer::CanvasLayer() {
|
||||||
vp = nullptr;
|
vp = nullptr;
|
||||||
scale = Vector2(1, 1);
|
scale = Vector2(1, 1);
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ public:
|
|||||||
|
|
||||||
RID get_canvas() const;
|
RID get_canvas() const;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
StringName get_property_store_alias(const StringName &p_property) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
CanvasLayer();
|
CanvasLayer();
|
||||||
~CanvasLayer();
|
~CanvasLayer();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1866,6 +1866,56 @@ Node *Node::get_deepest_editable_node(Node *p_start_node) const {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
void Node::set_property_pinned(const StringName &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.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() {
|
String Node::to_string() {
|
||||||
if (get_script_instance()) {
|
if (get_script_instance()) {
|
||||||
bool valid;
|
bool valid;
|
||||||
@@ -2811,6 +2861,10 @@ void Node::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
|
ClassDB::bind_method(D_METHOD("_get_import_path"), &Node::get_import_path);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
|
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "_import_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_import_path", "_get_import_path");
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned);
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
MethodInfo mi;
|
MethodInfo mi;
|
||||||
|
|
||||||
|
|||||||
@@ -314,6 +314,13 @@ public:
|
|||||||
bool is_editable_instance(const Node *p_node) const;
|
bool is_editable_instance(const Node *p_node) const;
|
||||||
Node *get_deepest_editable_node(Node *start_node) const;
|
Node *get_deepest_editable_node(Node *start_node) const;
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
void set_property_pinned(const StringName &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();
|
virtual String to_string();
|
||||||
|
|
||||||
/* NOTIFICATIONS */
|
/* NOTIFICATIONS */
|
||||||
|
|||||||
@@ -47,6 +47,30 @@ bool SceneState::can_instance() const {
|
|||||||
return nodes.size() > 0;
|
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.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.empty()) {
|
||||||
|
p_node->remove_meta("_edit_pinned_properties_");
|
||||||
|
}
|
||||||
|
return pinned;
|
||||||
|
}
|
||||||
|
|
||||||
Node *SceneState::instance(GenEditState p_edit_state) const {
|
Node *SceneState::instance(GenEditState p_edit_state) const {
|
||||||
// nodes where instancing failed (because something is missing)
|
// nodes where instancing failed (because something is missing)
|
||||||
List<Node *> stray_instances;
|
List<Node *> stray_instances;
|
||||||
@@ -227,7 +251,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
|
|||||||
} else {
|
} else {
|
||||||
Node *base = i == 0 ? node : ret_nodes[0];
|
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
|
//for the main scene, use the resource as is
|
||||||
res->configure_for_local_scene(base, resources_local_to_scene);
|
res->configure_for_local_scene(base, resources_local_to_scene);
|
||||||
resources_local_to_scene[res] = res;
|
resources_local_to_scene[res] = res;
|
||||||
@@ -291,6 +315,13 @@ Node *SceneState::instance(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;
|
ret_nodes[i] = node;
|
||||||
|
|
||||||
if (node && gen_node_path_cache && ret_nodes[0]) {
|
if (node && gen_node_path_cache && ret_nodes[0]) {
|
||||||
@@ -440,23 +471,39 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
|
|||||||
List<PropertyInfo> plist;
|
List<PropertyInfo> plist;
|
||||||
p_node->get_property_list(&plist);
|
p_node->get_property_list(&plist);
|
||||||
|
|
||||||
|
Array pinned_props = _sanitize_node_pinned_properties(p_node);
|
||||||
|
|
||||||
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
|
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
|
||||||
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
|
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variant forced_value;
|
||||||
|
|
||||||
// If instance or inheriting, not saving if property requested so, or it's meta
|
// If instance or inheriting, not saving if property requested so, or it's meta
|
||||||
if (states_stack.size() && ((E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE) || E->get().name == "__meta__")) {
|
if (states_stack.size()) {
|
||||||
|
if ((E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Meta is normally not saved in instances/inherited (see GH-12838), but we need to save the pinned list
|
||||||
|
if (E->get().name == "__meta__") {
|
||||||
|
if (pinned_props.size()) {
|
||||||
|
Dictionary meta_override;
|
||||||
|
meta_override["_edit_pinned_properties_"] = pinned_props;
|
||||||
|
forced_value = meta_override;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String name = E->get().name;
|
String name = E->get().name;
|
||||||
Variant value = p_node->get(name);
|
Variant value = forced_value.get_type() == Variant::NIL ? p_node->get(name) : forced_value;
|
||||||
|
|
||||||
|
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);
|
Variant default_value = PropertyUtils::get_property_default_value(p_node, name, &states_stack, true);
|
||||||
if (!PropertyUtils::is_property_value_different(value, default_value)) {
|
if (!PropertyUtils::is_property_value_different(value, default_value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NodeData::Property prop;
|
NodeData::Property prop;
|
||||||
prop.name = _nm_get_string(name, name_map);
|
prop.name = _nm_get_string(name, name_map);
|
||||||
@@ -1504,6 +1551,7 @@ void SceneState::_bind_methods() {
|
|||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
||||||
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN_INHERITED);
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneState::SceneState() {
|
SceneState::SceneState() {
|
||||||
@@ -1594,6 +1642,7 @@ void PackedScene::_bind_methods() {
|
|||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_DISABLED);
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_INSTANCE);
|
||||||
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN);
|
||||||
|
BIND_ENUM_CONSTANT(GEN_EDIT_STATE_MAIN_INHERITED);
|
||||||
}
|
}
|
||||||
|
|
||||||
PackedScene::PackedScene() {
|
PackedScene::PackedScene() {
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ public:
|
|||||||
GEN_EDIT_STATE_DISABLED,
|
GEN_EDIT_STATE_DISABLED,
|
||||||
GEN_EDIT_STATE_INSTANCE,
|
GEN_EDIT_STATE_INSTANCE,
|
||||||
GEN_EDIT_STATE_MAIN,
|
GEN_EDIT_STATE_MAIN,
|
||||||
|
GEN_EDIT_STATE_MAIN_INHERITED,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PackState {
|
struct PackState {
|
||||||
@@ -207,6 +208,7 @@ public:
|
|||||||
GEN_EDIT_STATE_DISABLED,
|
GEN_EDIT_STATE_DISABLED,
|
||||||
GEN_EDIT_STATE_INSTANCE,
|
GEN_EDIT_STATE_INSTANCE,
|
||||||
GEN_EDIT_STATE_MAIN,
|
GEN_EDIT_STATE_MAIN,
|
||||||
|
GEN_EDIT_STATE_MAIN_INHERITED,
|
||||||
};
|
};
|
||||||
|
|
||||||
Error pack(Node *p_scene);
|
Error pack(Node *p_scene);
|
||||||
|
|||||||
Reference in New Issue
Block a user