Skip to content

Commit

Permalink
Merge pull request #90839 from timothyqiu/tree-button
Browse files Browse the repository at this point in the history
Fix TreeItem button handling
  • Loading branch information
akien-mga committed Apr 22, 2024
2 parents ab57e8d + c78e9c3 commit 9498753
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 79 deletions.
181 changes: 102 additions & 79 deletions scene/gui/tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
#include "core/math/math_funcs.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
#include "scene/gui/box_container.h"
#include "scene/gui/text_edit.h"
#include "scene/main/window.h"
Expand Down Expand Up @@ -5267,6 +5265,86 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_
return nullptr;
}

// When on a button, r_index is valid.
// When on an item, both r_item and r_column are valid.
// Otherwise, all output arguments are invalid.
void Tree::_find_button_at_pos(const Point2 &p_pos, TreeItem *&r_item, int &r_column, int &r_index) const {
r_item = nullptr;
r_column = -1;
r_index = -1;

if (!root) {
return;
}

Point2 pos = p_pos - theme_cache.panel_style->get_offset();
pos.y -= _get_title_button_height();
if (pos.y < 0) {
return;
}

if (cache.rtl) {
pos.x = get_size().width - pos.x;
}
pos += theme_cache.offset; // Scrolling.

int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
if (!it) {
return;
}

r_item = it;
r_column = col;

const TreeItem::Cell &c = it->cells[col];
if (c.buttons.is_empty()) {
return;
}

int x_limit = get_size().width - theme_cache.panel_style->get_minimum_size().width + theme_cache.offset.x;
if (v_scroll->is_visible_in_tree()) {
x_limit -= v_scroll->get_minimum_size().width;
}

for (int i = 0; i < col; i++) {
const int col_w = get_column_width(i) + theme_cache.h_separation;
pos.x -= col_w;
x_limit -= col_w;
}

int x_check;
if (cache.rtl) {
x_check = get_column_width(col);
} else {
// Right edge of the buttons area, relative to the start of the column.
int buttons_area_min = 0;
if (col == 0) {
// Content of column 0 should take indentation into account.
for (TreeItem *current = it; current && (current != root || !hide_root); current = current->parent) {
buttons_area_min += theme_cache.item_margin;
}
}
for (int i = c.buttons.size() - 1; i >= 0; i--) {
Ref<Texture2D> b = c.buttons[i].texture;
buttons_area_min += b->get_size().width + theme_cache.button_pressed->get_minimum_size().width + theme_cache.button_margin;
}

x_check = MAX(buttons_area_min, MIN(get_column_width(col), x_limit));
}

for (int i = c.buttons.size() - 1; i >= 0; i--) {
Ref<Texture2D> b = c.buttons[i].texture;
Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size();
if (pos.x > x_check - size.width) {
x_limit -= theme_cache.item_margin;
r_index = i;
return;
}
x_check -= size.width + theme_cache.button_margin;
}
}

int Tree::get_column_at_position(const Point2 &p_pos) const {
if (root) {
Point2 pos = p_pos;
Expand Down Expand Up @@ -5358,92 +5436,37 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const {
}

int Tree::get_button_id_at_position(const Point2 &p_pos) const {
if (root) {
Point2 pos = p_pos;
pos -= theme_cache.panel_style->get_offset();
pos.y -= _get_title_button_height();
if (pos.y < 0) {
return -1;
}

if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
}
if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
}

int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
TreeItem *it;
int col, index;
_find_button_at_pos(p_pos, it, col, index);

if (it) {
const TreeItem::Cell &c = it->cells[col];
int col_width = get_column_width(col);

for (int i = 0; i < col; i++) {
pos.x -= get_column_width(i);
}

for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = c.buttons[j].texture;
Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size();
if (pos.x > col_width - size.width) {
return c.buttons[j].id;
}
col_width -= size.width;
}
}
if (index == -1) {
return -1;
}

return -1;
return it->cells[col].buttons[index].id;
}

String Tree::get_tooltip(const Point2 &p_pos) const {
if (root) {
Point2 pos = p_pos;
pos -= theme_cache.panel_style->get_offset();
pos.y -= _get_title_button_height();
if (pos.y < 0) {
return Control::get_tooltip(p_pos);
}

if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
}
if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
}
Point2 pos = p_pos - theme_cache.panel_style->get_offset();
pos.y -= _get_title_button_height();
if (pos.y < 0) {
return Control::get_tooltip(p_pos);
}

int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
TreeItem *it;
int col, index;
_find_button_at_pos(p_pos, it, col, index);

if (it) {
const TreeItem::Cell &c = it->cells[col];
int col_width = get_column_width(col);

for (int i = 0; i < col; i++) {
pos.x -= get_column_width(i);
}
if (index != -1) {
return it->cells[col].buttons[index].tooltip;
}

for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = c.buttons[j].texture;
Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size();
if (pos.x > col_width - size.width) {
String tooltip = c.buttons[j].tooltip;
if (!tooltip.is_empty()) {
return tooltip;
}
}
col_width -= size.width;
}
String ret;
if (it->get_tooltip_text(col) == "") {
ret = it->get_text(col);
} else {
ret = it->get_tooltip_text(col);
}
return ret;
if (it) {
const String item_tooltip = it->get_tooltip_text(col);
if (item_tooltip.is_empty()) {
return it->get_text(col);
}
return item_tooltip;
}

return Control::get_tooltip(p_pos);
Expand Down
2 changes: 2 additions & 0 deletions scene/gui/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ class Tree : public Control {

TreeItem *_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_column, int &h, int &section) const;

void _find_button_at_pos(const Point2 &p_pos, TreeItem *&r_item, int &r_column, int &r_index) const;

/* float drag_speed;
float drag_accum;
Expand Down

0 comments on commit 9498753

Please sign in to comment.