Browse Source

Replace `TabBar`'s `min_width` with `max_tab_width` and expose it

Michael Alexsander 3 years ago
parent
commit
182e038af5
5 changed files with 45 additions and 60 deletions
  1. 3 0
      doc/classes/TabBar.xml
  2. 2 10
      editor/editor_node.cpp
  3. 1 2
      editor/editor_settings.cpp
  4. 35 46
      scene/gui/tab_bar.cpp
  5. 4 2
      scene/gui/tab_bar.h

+ 3 - 0
doc/classes/TabBar.xml

@@ -211,6 +211,9 @@
 		<member name="drag_to_rearrange_enabled" type="bool" setter="set_drag_to_rearrange_enabled" getter="get_drag_to_rearrange_enabled" default="false">
 			If [code]true[/code], tabs can be rearranged with mouse drag.
 		</member>
+		<member name="max_tab_width" type="int" setter="set_max_tab_width" getter="get_max_tab_width" default="0">
+			Sets the maximum width which all tabs should be limited to. Unlimited if set to [code]0[/code].
+		</member>
 		<member name="scroll_to_selected" type="bool" setter="set_scroll_to_selected" getter="get_scroll_to_selected" default="true">
 			If [code]true[/code], the tab offset will be changed to keep the the currently selected tab visible.
 		</member>

+ 2 - 10
editor/editor_node.cpp

@@ -725,11 +725,7 @@ void EditorNode::_notification(int p_what) {
 				help_menu->add_theme_style_override("hover", gui_base->get_theme_stylebox(SNAME("MenuHover"), SNAME("EditorStyles")));
 			}
 
-			if (EDITOR_GET("interface/scene_tabs/resize_if_many_tabs")) {
-				scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE);
-			} else {
-				scene_tabs->set_min_width(0);
-			}
+			scene_tabs->set_max_tab_width(int(EDITOR_GET("interface/scene_tabs/maximum_width")) * EDSCALE);
 			_update_scene_tabs();
 
 			recent_scenes->reset_size();
@@ -807,10 +803,6 @@ void EditorNode::_notification(int p_what) {
 
 			_update_update_spinner();
 		} break;
-
-		case Control::NOTIFICATION_RESIZED: {
-			_update_scene_tabs();
-		} break;
 	}
 }
 
@@ -6255,7 +6247,7 @@ EditorNode::EditorNode() {
 	scene_tabs->add_tab("unsaved");
 	scene_tabs->set_tab_alignment(TabBar::ALIGNMENT_LEFT);
 	scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
-	scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE);
+	scene_tabs->set_max_tab_width(int(EDITOR_GET("interface/scene_tabs/maximum_width")) * EDSCALE);
 	scene_tabs->set_drag_to_rearrange_enabled(true);
 	scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed));
 	scene_tabs->connect("tab_button_pressed", callable_mp(this, &EditorNode::_scene_tab_script_edited));

+ 1 - 2
editor/editor_settings.cpp

@@ -461,8 +461,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 
 	// Scene tabs
 	_initial_set("interface/scene_tabs/show_thumbnail_on_hover", true);
-	_initial_set("interface/scene_tabs/resize_if_many_tabs", true);
-	EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "interface/scene_tabs/minimum_width", 50, "50,500,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
+	EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "interface/scene_tabs/maximum_width", 350, "0,9999,1", PROPERTY_USAGE_DEFAULT)
 	_initial_set("interface/scene_tabs/show_script_button", false);
 
 	/* Filesystem */

+ 35 - 46
scene/gui/tab_bar.cpp

@@ -827,78 +827,52 @@ void TabBar::_update_cache() {
 	int limit_minus_buttons = limit - incr->get_width() - decr->get_width();
 
 	int w = 0;
-	int mw = 0;
-	int size_fixed = 0;
-	int count_resize = 0;
+
+	max_drawn_tab = tabs.size() - 1;
 
 	for (int i = 0; i < tabs.size(); i++) {
-		tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x);
 		tabs.write[i].text_buf->set_width(-1);
-
-		tabs.write[i].ofs_cache = 0;
+		tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x);
 		tabs.write[i].size_cache = get_tab_width(i);
 
-		if (!tabs[i].hidden) {
-			mw += tabs[i].size_cache;
+		if (max_width > 0 && tabs[i].size_cache > max_width) {
+			int size_textless = tabs[i].size_cache - tabs[i].size_text;
+			int mw = MAX(size_textless, max_width);
 
-			if (tabs[i].size_cache <= min_width || i == current) {
-				size_fixed += tabs[i].size_cache;
-			} else {
-				count_resize++;
-			}
+			tabs.write[i].size_text = MAX(mw - size_textless, 1);
+			tabs.write[i].text_buf->set_width(tabs[i].size_text);
+			tabs.write[i].size_cache = size_textless + tabs[i].size_text;
 		}
-	}
-
-	int m_width = min_width;
-	if (count_resize > 0) {
-		m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width);
-	}
-
-	for (int i = offset; i < tabs.size(); i++) {
-		if (tabs[i].hidden) {
-			tabs.write[i].ofs_cache = w;
-			max_drawn_tab = i;
 
+		if (i < offset || i > max_drawn_tab) {
+			tabs.write[i].ofs_cache = 0;
 			continue;
 		}
 
-		int lsize = tabs[i].size_cache;
-		int slen = tabs[i].size_text;
+		tabs.write[i].ofs_cache = w;
 
-		// FIXME: This is completely broken.
-		if (min_width > 0 && (mw > limit || (offset > 0 && mw > limit_minus_buttons)) && i != current && lsize > m_width) {
-			slen = MAX(m_width - tabs[i].size_cache + tabs[i].size_text, 1);
-			lsize = m_width;
+		if (tabs[i].hidden) {
+			continue;
 		}
 
-		tabs.write[i].ofs_cache = w;
-		tabs.write[i].size_cache = lsize;
-		tabs.write[i].size_text = slen;
-		tabs.write[i].text_buf->set_width(slen);
-
-		w += lsize;
-		max_drawn_tab = i;
+		w += tabs[i].size_cache;
 
 		// Check if all tabs would fit inside the area.
 		if (clip_tabs && i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) {
 			tabs.write[i].ofs_cache = 0;
-			tabs.write[i].text_buf->set_width(-1);
 
 			w -= tabs[i].size_cache;
-			max_drawn_tab--;
+			max_drawn_tab = i - 1;
 
 			while (w > limit_minus_buttons && max_drawn_tab > offset) {
 				tabs.write[max_drawn_tab].ofs_cache = 0;
 
 				if (!tabs[max_drawn_tab].hidden) {
-					tabs.write[max_drawn_tab].text_buf->set_width(-1);
 					w -= tabs[max_drawn_tab].size_cache;
 				}
 
 				max_drawn_tab--;
 			}
-
-			break;
 		}
 	}
 
@@ -938,12 +912,11 @@ void TabBar::_on_mouse_exited() {
 void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
 	Tab t;
 	t.text = p_str;
-	t.xl_text = atr(p_str);
 	t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
-	t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
 	t.icon = p_icon;
 	tabs.push_back(t);
 
+	_shape(tabs.size() - 1);
 	_update_cache();
 	if (scroll_to_selected) {
 		ensure_tab_visible(current);
@@ -1379,8 +1352,21 @@ TabBar::CloseButtonDisplayPolicy TabBar::get_tab_close_display_policy() const {
 	return cb_displaypolicy;
 }
 
-void TabBar::set_min_width(int p_width) {
-	min_width = p_width;
+void TabBar::set_max_tab_width(int p_width) {
+	ERR_FAIL_COND(p_width < 0);
+	max_width = p_width;
+
+	_update_cache();
+	_ensure_no_over_offset();
+	if (scroll_to_selected) {
+		ensure_tab_visible(current);
+	}
+	update();
+	update_minimum_size();
+}
+
+int TabBar::get_max_tab_width() const {
+	return max_width;
 }
 
 void TabBar::set_scrolling_enabled(bool p_enabled) {
@@ -1515,6 +1501,8 @@ void TabBar::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &TabBar::move_tab);
 	ClassDB::bind_method(D_METHOD("set_tab_close_display_policy", "policy"), &TabBar::set_tab_close_display_policy);
 	ClassDB::bind_method(D_METHOD("get_tab_close_display_policy"), &TabBar::get_tab_close_display_policy);
+	ClassDB::bind_method(D_METHOD("set_max_tab_width", "width"), &TabBar::set_max_tab_width);
+	ClassDB::bind_method(D_METHOD("get_max_tab_width"), &TabBar::get_max_tab_width);
 	ClassDB::bind_method(D_METHOD("set_scrolling_enabled", "enabled"), &TabBar::set_scrolling_enabled);
 	ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &TabBar::get_scrolling_enabled);
 	ClassDB::bind_method(D_METHOD("set_drag_to_rearrange_enabled", "enabled"), &TabBar::set_drag_to_rearrange_enabled);
@@ -1539,6 +1527,7 @@ void TabBar::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "max_tab_width", PROPERTY_HINT_RANGE, "0,99999,1"), "set_max_tab_width", "get_max_tab_width");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tabs_rearrange_group"), "set_tabs_rearrange_group", "get_tabs_rearrange_group");

+ 4 - 2
scene/gui/tab_bar.h

@@ -98,7 +98,7 @@ private:
 	CloseButtonDisplayPolicy cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER;
 
 	int hover = -1; // Hovered tab.
-	int min_width = 0;
+	int max_width = 0;
 	bool scrolling_enabled = true;
 	bool drag_to_rearrange_enabled = false;
 	bool scroll_to_selected = true;
@@ -198,7 +198,9 @@ public:
 	bool get_select_with_rmb() const;
 
 	void ensure_tab_visible(int p_idx);
-	void set_min_width(int p_width);
+
+	void set_max_tab_width(int p_width);
+	int get_max_tab_width() const;
 
 	Rect2 get_tab_rect(int p_tab) const;
 	Size2 get_minimum_size() const override;