Merge pull request #106588 from timothyqiu/tree-new-bee

Lazy create menu and slider nodes in `Tree`
This commit is contained in:
Thaddeus Crews 2025-05-19 16:22:30 -05:00
commit be3ecaeb3c
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
2 changed files with 49 additions and 44 deletions

View file

@ -3197,12 +3197,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
} break;
case TreeItem::CELL_MODE_RANGE: {
if (!c.text.is_empty()) {
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
String s = c.text.get_slicec(',', i);
popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).is_empty() ? i : s.get_slicec(':', 1).to_int());
}
_update_popup_menu(c);
popup_menu->set_size(Size2(col_width, 0));
popup_menu->set_position(get_screen_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h) - theme_cache.offset);
popup_menu->popup();
@ -3332,7 +3327,7 @@ void Tree::_text_editor_popup_modal_close() {
return; // ESC pressed, app focus lost, or forced close from code.
}
if (value_editor->has_point(value_editor->get_local_mouse_position())) {
if (value_editor && value_editor->has_point(value_editor->get_local_mouse_position())) {
return;
}
@ -3449,6 +3444,37 @@ void Tree::value_editor_changed(double p_value) {
queue_redraw();
}
void Tree::_update_popup_menu(const TreeItem::Cell &p_cell) {
if (popup_menu == nullptr) {
popup_menu = memnew(PopupMenu);
popup_menu->hide();
add_child(popup_menu, false, INTERNAL_MODE_FRONT);
popup_menu->connect(SceneStringName(id_pressed), callable_mp(this, &Tree::popup_select));
}
popup_menu->clear();
for (int i = 0; i < p_cell.text.get_slice_count(","); i++) {
String s = p_cell.text.get_slicec(',', i);
popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).is_empty() ? i : s.get_slicec(':', 1).to_int());
}
}
void Tree::_update_value_editor(const TreeItem::Cell &p_cell) {
if (value_editor == nullptr) {
value_editor = memnew(HSlider);
value_editor->set_v_size_flags(SIZE_EXPAND_FILL);
value_editor->hide();
popup_editor_vb->add_child(value_editor);
value_editor->connect(SceneStringName(value_changed), callable_mp(this, &Tree::value_editor_changed));
}
updating_value_editor = true;
value_editor->set_min(p_cell.min);
value_editor->set_max(p_cell.max);
value_editor->set_step(p_cell.step);
value_editor->set_value(p_cell.val);
value_editor->set_exp_ratio(p_cell.expr);
updating_value_editor = false;
}
void Tree::popup_select(int p_option) {
if (!popup_edited_item) {
return;
@ -4308,12 +4334,7 @@ bool Tree::edit_selected(bool p_force_edit) {
return true;
} else if (c.mode == TreeItem::CELL_MODE_RANGE && !c.text.is_empty()) {
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
String s2 = c.text.get_slicec(',', i);
popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).is_empty() ? i : s2.get_slicec(':', 1).to_int());
}
_update_popup_menu(c);
popup_menu->set_size(Size2(rect.size.width, 0));
popup_menu->set_position(get_screen_position() + rect.position + Point2i(0, rect.size.height));
popup_menu->popup();
@ -4322,9 +4343,16 @@ bool Tree::edit_selected(bool p_force_edit) {
return true;
} else if ((c.mode == TreeItem::CELL_MODE_STRING && !c.edit_multiline) || c.mode == TreeItem::CELL_MODE_RANGE) {
Rect2 popup_rect;
int value_editor_height = 0;
if (c.mode == TreeItem::CELL_MODE_RANGE) {
_update_value_editor(c);
value_editor_height = value_editor->get_minimum_size().height;
value_editor->show();
} else if (value_editor) {
value_editor->hide();
}
int value_editor_height = c.mode == TreeItem::CELL_MODE_RANGE ? value_editor->get_minimum_size().height : 0;
Rect2 popup_rect;
// `floor()` centers vertically.
Vector2 ofs(0, Math::floor((MAX(line_editor->get_minimum_size().height, rect.size.height - value_editor_height) - rect.size.height) / 2));
@ -4334,8 +4362,7 @@ bool Tree::edit_selected(bool p_force_edit) {
icon_ofs = _get_cell_icon_size(c).x * popup_scale + theme_cache.h_separation;
}
popup_rect.size = rect.size;
popup_rect.size.x -= icon_ofs;
popup_rect.size = rect.size + Vector2(-icon_ofs, value_editor_height);
popup_rect.position = rect.position - ofs;
popup_rect.position.x += icon_ofs;
@ -4351,21 +4378,6 @@ bool Tree::edit_selected(bool p_force_edit) {
text_editor->hide();
if (c.mode == TreeItem::CELL_MODE_RANGE) {
popup_rect.size.y += value_editor_height;
value_editor->show();
updating_value_editor = true;
value_editor->set_min(c.min);
value_editor->set_max(c.max);
value_editor->set_step(c.step);
value_editor->set_value(c.val);
value_editor->set_exp_ratio(c.expr);
updating_value_editor = false;
} else {
value_editor->hide();
}
popup_editor->set_position(popup_rect.position);
popup_editor->set_size(popup_rect.size * popup_scale);
if (!popup_editor->is_embedded()) {
@ -6634,14 +6646,10 @@ Tree::Tree() {
set_focus_mode(FOCUS_ALL);
popup_menu = memnew(PopupMenu);
popup_menu->hide();
add_child(popup_menu, false, INTERNAL_MODE_FRONT);
popup_editor = memnew(Popup);
add_child(popup_editor, false, INTERNAL_MODE_FRONT);
VBoxContainer *popup_editor_vb = memnew(VBoxContainer);
popup_editor_vb = memnew(VBoxContainer);
popup_editor_vb->add_theme_constant_override("separation", 0);
popup_editor_vb->set_anchors_and_offsets_preset(PRESET_FULL_RECT);
popup_editor->add_child(popup_editor_vb);
@ -6656,11 +6664,6 @@ Tree::Tree() {
text_editor->hide();
popup_editor_vb->add_child(text_editor);
value_editor = memnew(HSlider);
value_editor->set_v_size_flags(SIZE_EXPAND_FILL);
value_editor->hide();
popup_editor_vb->add_child(value_editor);
h_scroll = memnew(HScrollBar);
v_scroll = memnew(VScrollBar);
@ -6676,8 +6679,6 @@ Tree::Tree() {
line_editor->connect(SceneStringName(text_submitted), callable_mp(this, &Tree::_line_editor_submit));
text_editor->connect(SceneStringName(gui_input), callable_mp(this, &Tree::_text_editor_gui_input));
popup_editor->connect("popup_hide", callable_mp(this, &Tree::_text_editor_popup_modal_close));
popup_menu->connect(SceneStringName(id_pressed), callable_mp(this, &Tree::popup_select));
value_editor->connect(SceneStringName(value_changed), callable_mp(this, &Tree::value_editor_changed));
set_notify_transform(true);

View file

@ -33,6 +33,7 @@
#include "scene/gui/control.h"
#include "scene/resources/text_paragraph.h"
class VBoxContainer;
class HScrollBar;
class HSlider;
class LineEdit;
@ -529,6 +530,7 @@ private:
bool popup_edit_committed = true;
RID accessibility_scroll_element;
VBoxContainer *popup_editor_vb = nullptr;
Popup *popup_editor = nullptr;
LineEdit *line_editor = nullptr;
TextEdit *text_editor = nullptr;
@ -559,6 +561,8 @@ private:
void _text_editor_popup_modal_close();
void _text_editor_gui_input(const Ref<InputEvent> &p_event);
void value_editor_changed(double p_value);
void _update_popup_menu(const TreeItem::Cell &p_cell);
void _update_value_editor(const TreeItem::Cell &p_cell);
void popup_select(int p_option);