Fix Inspector may scrolls away when editing a property that adds or removes sub properties

This commit is contained in:
Marius Hanl 2024-09-04 00:26:09 +02:00
parent 042b264c55
commit 27b7b433e0
5 changed files with 23 additions and 16 deletions

View File

@ -28,6 +28,7 @@
</method> </method>
</methods> </methods>
<members> <members>
<member name="follow_focus" type="bool" setter="set_follow_focus" getter="is_following_focus" overrides="ScrollContainer" default="true" />
<member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" overrides="ScrollContainer" enum="ScrollContainer.ScrollMode" default="0" /> <member name="horizontal_scroll_mode" type="int" setter="set_horizontal_scroll_mode" getter="get_horizontal_scroll_mode" overrides="ScrollContainer" enum="ScrollContainer.ScrollMode" default="0" />
</members> </members>
<signals> <signals>

View File

@ -2766,8 +2766,9 @@ void EditorInspector::update_tree() {
// TODO: Can be useful to store more context for the focusable, such as the caret position in LineEdit. // TODO: Can be useful to store more context for the focusable, such as the caret position in LineEdit.
StringName current_selected = property_selected; StringName current_selected = property_selected;
int current_focusable = -1; int current_focusable = -1;
// Temporarily disable focus following to avoid jumping while the inspector is updating.
set_follow_focus(false); // Temporarily disable focus following on the root inspector to avoid jumping while the inspector is updating.
get_root_inspector()->set_follow_focus(false);
if (property_focusable != -1) { if (property_focusable != -1) {
// Check that focusable is actually focusable. // Check that focusable is actually focusable.
@ -2795,6 +2796,7 @@ void EditorInspector::update_tree() {
_clear(!object); _clear(!object);
if (!object) { if (!object) {
get_root_inspector()->set_follow_focus(true);
return; return;
} }
@ -3532,7 +3534,8 @@ void EditorInspector::update_tree() {
// Updating inspector might invalidate some editing owners. // Updating inspector might invalidate some editing owners.
EditorNode::get_singleton()->hide_unused_editors(); EditorNode::get_singleton()->hide_unused_editors();
} }
set_follow_focus(true);
get_root_inspector()->set_follow_focus(true);
} }
void EditorInspector::update_property(const String &p_prop) { void EditorInspector::update_property(const String &p_prop) {
@ -3777,11 +3780,10 @@ void EditorInspector::set_use_wide_editors(bool p_enable) {
wide_editors = p_enable; wide_editors = p_enable;
} }
void EditorInspector::set_sub_inspector(bool p_enable) { void EditorInspector::set_root_inspector(EditorInspector *p_root_inspector) {
sub_inspector = p_enable; root_inspector = p_root_inspector;
if (!is_inside_tree()) { // Only the root inspector should follow focus.
return; set_follow_focus(false);
}
} }
void EditorInspector::set_use_deletable_properties(bool p_enabled) { void EditorInspector::set_use_deletable_properties(bool p_enabled) {
@ -4099,13 +4101,13 @@ void EditorInspector::_notification(int p_what) {
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed)); EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed));
set_process(is_visible_in_tree()); set_process(is_visible_in_tree());
add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
if (!sub_inspector) { if (!is_sub_inspector()) {
get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed)); get_tree()->connect("node_removed", callable_mp(this, &EditorInspector::_node_removed));
} }
} break; } break;
case NOTIFICATION_PREDELETE: { case NOTIFICATION_PREDELETE: {
if (!sub_inspector && is_inside_tree()) { if (!is_sub_inspector() && is_inside_tree()) {
get_tree()->disconnect("node_removed", callable_mp(this, &EditorInspector::_node_removed)); get_tree()->disconnect("node_removed", callable_mp(this, &EditorInspector::_node_removed));
} }
edit(nullptr); edit(nullptr);
@ -4164,7 +4166,7 @@ void EditorInspector::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
bool needs_update = false; bool needs_update = false;
if (EditorThemeManager::is_generated_theme_outdated() && !sub_inspector) { if (!is_sub_inspector() && EditorThemeManager::is_generated_theme_outdated()) {
add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree")));
} }

View File

@ -486,6 +486,7 @@ class EditorInspector : public ScrollContainer {
static Ref<EditorInspectorPlugin> inspector_plugins[MAX_PLUGINS]; static Ref<EditorInspectorPlugin> inspector_plugins[MAX_PLUGINS];
static int inspector_plugin_count; static int inspector_plugin_count;
EditorInspector *root_inspector = nullptr;
VBoxContainer *main_vbox = nullptr; VBoxContainer *main_vbox = nullptr;
// Map used to cache the instantiated editors. // Map used to cache the instantiated editors.
@ -514,7 +515,6 @@ class EditorInspector : public ScrollContainer {
bool update_all_pending = false; bool update_all_pending = false;
bool read_only = false; bool read_only = false;
bool keying = false; bool keying = false;
bool sub_inspector = false;
bool wide_editors = false; bool wide_editors = false;
bool deletable_properties = false; bool deletable_properties = false;
@ -645,8 +645,9 @@ public:
String get_object_class() const; String get_object_class() const;
void set_use_wide_editors(bool p_enable); void set_use_wide_editors(bool p_enable);
void set_sub_inspector(bool p_enable); void set_root_inspector(EditorInspector *p_root_inspector);
bool is_sub_inspector() const { return sub_inspector; } EditorInspector *get_root_inspector() { return is_sub_inspector() ? root_inspector : this; }
bool is_sub_inspector() const { return root_inspector != nullptr; }
void set_use_deletable_properties(bool p_enabled); void set_use_deletable_properties(bool p_enabled);

View File

@ -3238,7 +3238,10 @@ void EditorPropertyResource::update_property() {
sub_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); sub_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED);
sub_inspector->set_use_doc_hints(true); sub_inspector->set_use_doc_hints(true);
sub_inspector->set_sub_inspector(true); EditorInspector *parent_inspector = get_parent_inspector();
ERR_FAIL_NULL(parent_inspector);
sub_inspector->set_root_inspector(parent_inspector->get_root_inspector());
sub_inspector->set_property_name_style(InspectorDock::get_singleton()->get_property_name_style()); sub_inspector->set_property_name_style(InspectorDock::get_singleton()->get_property_name_style());
sub_inspector->connect("property_keyed", callable_mp(this, &EditorPropertyResource::_sub_inspector_property_keyed)); sub_inspector->connect("property_keyed", callable_mp(this, &EditorPropertyResource::_sub_inspector_property_keyed));

View File

@ -799,7 +799,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
inspector->set_use_folding(!bool(EDITOR_GET("interface/inspector/disable_folding"))); inspector->set_use_folding(!bool(EDITOR_GET("interface/inspector/disable_folding")));
inspector->register_text_enter(search); inspector->register_text_enter(search);
inspector->set_use_filter(true); // TODO: check me inspector->set_use_filter(true);
inspector->connect("resource_selected", callable_mp(this, &InspectorDock::_resource_selected)); inspector->connect("resource_selected", callable_mp(this, &InspectorDock::_resource_selected));