Ver código fonte

Lazy create menu and slider nodes in `Tree`

Haoyu Qiu 2 meses atrás
pai
commit
7aa9174bc4
2 arquivos alterados com 49 adições e 44 exclusões
  1. 45 44
      scene/gui/tree.cpp
  2. 4 0
      scene/gui/tree.h

+ 45 - 44
scene/gui/tree.cpp

@@ -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);
 

+ 4 - 0
scene/gui/tree.h

@@ -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);