summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Hinlopen <f.a.hinlopen@gmail.com>2020-07-05 20:06:51 +0200
committerStijn Hinlopen <f.a.hinlopen@gmail.com>2022-02-05 10:59:33 +0100
commit31824420e4cf3a30eb35334c43cb8393af585346 (patch)
treef348f13263224068db871e02e84cb2ce6040d47d
parentdf1724470d1cff4f67aeb4c0d039114373aeb001 (diff)
Center when scrolling to tree item.
-rw-r--r--doc/classes/Tree.xml1
-rw-r--r--editor/create_dialog.cpp6
-rw-r--r--editor/create_dialog.h2
-rw-r--r--scene/gui/tree.cpp28
-rw-r--r--scene/gui/tree.h2
5 files changed, 24 insertions, 15 deletions
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 766c740a2c..4b051c4938 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -240,6 +240,7 @@
<method name="scroll_to_item">
<return type="void" />
<argument index="0" name="item" type="TreeItem" />
+ <argument index="1" name="center_on_item" type="bool" default="false" />
<description>
Causes the [Tree] to jump to the specified [TreeItem].
</description>
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index e8fd97fa1a..0cf14ce1c7 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -446,14 +446,14 @@ void CreateDialog::_notification(int p_what) {
}
}
-void CreateDialog::select_type(const String &p_type) {
+void CreateDialog::select_type(const String &p_type, bool p_center_on_item) {
if (!search_options_types.has(p_type)) {
return;
}
TreeItem *to_select = search_options_types[p_type];
to_select->select(0);
- search_options->scroll_to_item(to_select);
+ search_options->scroll_to_item(to_select, p_center_on_item);
if (EditorHelp::get_doc_data()->class_list.has(p_type) && !DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description).is_empty()) {
// Display both class name and description, since the help bit may be displayed
@@ -520,7 +520,7 @@ Variant CreateDialog::instance_selected() {
void CreateDialog::_item_selected() {
String name = get_selected_type();
- select_type(name);
+ select_type(name, false);
}
void CreateDialog::_hide_requested() {
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f905160df3..a82c4db191 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -79,7 +79,7 @@ class CreateDialog : public ConfirmationDialog {
void _sbox_input(const Ref<InputEvent> &p_ie);
void _text_changed(const String &p_newtext);
- void select_type(const String &p_type);
+ void select_type(const String &p_type, bool p_center_on_item = true);
void _item_selected();
void _hide_requested();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 1b32884880..f499e6da46 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -4409,21 +4409,29 @@ Point2 Tree::get_scroll() const {
return ofs;
}
-void Tree::scroll_to_item(TreeItem *p_item) {
+void Tree::scroll_to_item(TreeItem *p_item, bool p_center_on_item) {
if (!is_visible_in_tree()) {
- // hack to work around crash in get_item_rect() if Tree is not in tree.
- return;
+ return; // Hack to work around crash in get_item_rect() if Tree is not in tree.
}
- // make sure the scrollbar min and max are up to date with latest changes.
update_scrollbars();
- const Rect2 r = get_item_rect(p_item);
+ const real_t tree_height = get_size().y;
+ const Rect2 item_rect = get_item_rect(p_item);
+ const real_t item_y = item_rect.position.y;
+ const real_t item_height = item_rect.size.y + cache.vseparation;
- if (r.position.y <= v_scroll->get_value()) {
- v_scroll->set_value(r.position.y);
- } else if (r.position.y + r.size.y + 2 * cache.vseparation > v_scroll->get_value() + get_size().y) {
- v_scroll->set_value(r.position.y + r.size.y + 2 * cache.vseparation - get_size().y);
+ if (p_center_on_item) {
+ v_scroll->set_value(item_y - (tree_height - item_height) / 2.0f);
+ } else {
+ if (item_y < v_scroll->get_value()) {
+ v_scroll->set_value(item_y);
+ } else {
+ const real_t new_position = item_y + item_height - tree_height;
+ if (new_position > v_scroll->get_value()) {
+ v_scroll->set_value(new_position);
+ }
+ }
}
}
@@ -4868,7 +4876,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
- ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::scroll_to_item);
+ ClassDB::bind_method(D_METHOD("scroll_to_item", "item", "center_on_item"), &Tree::scroll_to_item, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_h_scroll_enabled", "h_scroll"), &Tree::set_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &Tree::is_h_scroll_enabled);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index c24763a0e4..255a4f0576 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -682,7 +682,7 @@ public:
TreeItem *get_item_with_text(const String &p_find) const;
Point2 get_scroll() const;
- void scroll_to_item(TreeItem *p_item);
+ void scroll_to_item(TreeItem *p_item, bool p_center_on_item = false);
void set_h_scroll_enabled(bool p_enable);
bool is_h_scroll_enabled() const;
void set_v_scroll_enabled(bool p_enable);