Browse Source

Merge pull request #82384 from YeldhamDev/corner_cases_man_i_swear

Make hovered tabs be drawn with the unselected's width at minimum
Rémi Verschelde 2 years ago
parent
commit
048abcb2bb
4 changed files with 13 additions and 6 deletions
  1. 1 0
      doc/classes/TabBar.xml
  2. 1 0
      doc/classes/TabContainer.xml
  3. 10 5
      scene/gui/tab_bar.cpp
  4. 1 1
      scene/gui/tab_bar.h

+ 1 - 0
doc/classes/TabBar.xml

@@ -414,6 +414,7 @@
 		</theme_item>
 		<theme_item name="tab_hovered" data_type="style" type="StyleBox">
 			The style of the currently hovered tab. Does not apply to the selected tab.
+			[b]Note:[/b] This style will be drawn with the same width as [theme_item tab_unselected] at minimum.
 		</theme_item>
 		<theme_item name="tab_selected" data_type="style" type="StyleBox">
 			The style of the currently selected tab.

+ 1 - 0
doc/classes/TabContainer.xml

@@ -318,6 +318,7 @@
 		</theme_item>
 		<theme_item name="tab_hovered" data_type="style" type="StyleBox">
 			The style of the currently hovered tab.
+			[b]Note:[/b] This style will be drawn with the same width as [theme_item tab_unselected] at minimum.
 		</theme_item>
 		<theme_item name="tab_selected" data_type="style" type="StyleBox">
 			The style of the currently selected tab.

+ 10 - 5
scene/gui/tab_bar.cpp

@@ -948,7 +948,7 @@ void TabBar::_update_hover() {
 	}
 }
 
-void TabBar::_update_cache() {
+void TabBar::_update_cache(bool p_update_hover) {
 	if (tabs.is_empty()) {
 		buttons_visible = false;
 		return;
@@ -1011,7 +1011,9 @@ void TabBar::_update_cache() {
 	buttons_visible = offset > 0 || missing_right;
 
 	if (tab_alignment == ALIGNMENT_LEFT) {
-		_update_hover();
+		if (p_update_hover) {
+			_update_hover();
+		}
 		return;
 	}
 
@@ -1029,7 +1031,9 @@ void TabBar::_update_cache() {
 		}
 	}
 
-	_update_hover();
+	if (p_update_hover) {
+		_update_hover();
+	}
 }
 
 void TabBar::_on_mouse_exited() {
@@ -1039,7 +1043,7 @@ void TabBar::_on_mouse_exited() {
 	highlight_arrow = -1;
 	dragging_valid_tab = false;
 
-	_update_cache();
+	_update_cache(false);
 	queue_redraw();
 }
 
@@ -1373,7 +1377,8 @@ int TabBar::get_tab_width(int p_idx) const {
 		style = theme_cache.tab_disabled_style;
 	} else if (current == p_idx) {
 		style = theme_cache.tab_selected_style;
-	} else if (hover == p_idx) {
+		// Use the unselected style's width if the hovered one is shorter, to avoid an infinite loop when switching tabs with the mouse.
+	} else if (hover == p_idx && theme_cache.tab_hovered_style->get_minimum_size().width >= theme_cache.tab_unselected_style->get_minimum_size().width) {
 		style = theme_cache.tab_hovered_style;
 	} else {
 		style = theme_cache.tab_unselected_style;

+ 1 - 1
scene/gui/tab_bar.h

@@ -148,7 +148,7 @@ private:
 	void _ensure_no_over_offset();
 
 	void _update_hover();
-	void _update_cache();
+	void _update_cache(bool p_update_hover = true);
 
 	void _on_mouse_exited();