浏览代码

Merge pull request #39805 from RandomShaper/fix_gone_popup_crash

Handle gone TabContainer popup nicely
Rémi Verschelde 5 年之前
父节点
当前提交
057489b329
共有 2 个文件被更改,包括 21 次插入4 次删除
  1. 20 3
      scene/gui/tab_container.cpp
  2. 1 1
      scene/gui/tab_container.h

+ 20 - 3
scene/gui/tab_container.cpp

@@ -71,6 +71,8 @@ int TabContainer::_get_top_margin() const {
 void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
 	Ref<InputEventMouseButton> mb = p_event;
 
+	Popup *popup = get_popup();
+
 	if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
 		Point2 pos(mb->get_position().x, mb->get_position().y);
 		Size2 size = get_size();
@@ -82,6 +84,7 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
 
 		// Handle menu button.
 		Ref<Texture2D> menu = get_theme_icon("menu");
+
 		if (popup && pos.x > size.width - menu->get_width()) {
 			emit_signal("pre_popup_pressed");
 
@@ -223,6 +226,7 @@ void TabContainer::_notification(int p_what) {
 			int header_width = get_size().width - side_margin * 2;
 
 			// Find the width of the header area.
+			Popup *popup = get_popup();
 			if (popup) {
 				header_width -= menu->get_width();
 			}
@@ -284,6 +288,7 @@ void TabContainer::_notification(int p_what) {
 			int header_x = side_margin;
 			int header_width = size.width - side_margin * 2;
 			int header_height = _get_top_margin();
+			Popup *popup = get_popup();
 			if (popup) {
 				header_width -= menu->get_width();
 			}
@@ -749,6 +754,7 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const {
 	Size2 size = get_size();
 	int right_ofs = 0;
 
+	Popup *popup = get_popup();
 	if (popup) {
 		Ref<Texture2D> menu = get_theme_icon("menu");
 		right_ofs += menu->get_width();
@@ -948,12 +954,24 @@ Size2 TabContainer::get_minimum_size() const {
 
 void TabContainer::set_popup(Node *p_popup) {
 	ERR_FAIL_NULL(p_popup);
-	popup = Object::cast_to<Popup>(p_popup);
+	Popup *popup = Object::cast_to<Popup>(p_popup);
+	popup_obj_id = popup ? popup->get_instance_id() : ObjectID();
 	update();
 }
 
 Popup *TabContainer::get_popup() const {
-	return popup;
+	if (popup_obj_id.is_valid()) {
+		Popup *popup = Object::cast_to<Popup>(ObjectDB::get_instance(popup_obj_id));
+		if (popup) {
+			return popup;
+		} else {
+#ifdef DEBUG_ENABLED
+			ERR_PRINT("Popup assigned to TabContainer is gone!");
+#endif
+			popup_obj_id = ObjectID();
+		}
+	}
+	return nullptr;
 }
 
 void TabContainer::set_drag_to_rearrange_enabled(bool p_enabled) {
@@ -1037,7 +1055,6 @@ TabContainer::TabContainer() {
 	previous = 0;
 	align = ALIGN_CENTER;
 	tabs_visible = true;
-	popup = nullptr;
 	drag_to_rearrange_enabled = false;
 	tabs_rearrange_group = -1;
 	use_hidden_tabs_for_min_size = false;

+ 1 - 1
scene/gui/tab_container.h

@@ -57,7 +57,7 @@ private:
 	TabAlign align;
 	Control *_get_tab(int p_idx) const;
 	int _get_top_margin() const;
-	Popup *popup;
+	mutable ObjectID popup_obj_id;
 	bool drag_to_rearrange_enabled;
 	bool use_hidden_tabs_for_min_size;
 	int tabs_rearrange_group;