[Scummvm-git-logs] scummvm master -> 7c259fe1295fda60f3d6b5f5c6e3efd67ca9b852

sev- sev at scummvm.org
Wed Mar 1 08:17:41 CET 2017


This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
af831f26b9 GUI: Clean up GlobalOptionsDialog reflow changing visible tabs
5510640dbc GUI: Give each tab in TabWidget its own width
c64d91833f GUI: Check rect validity for popup/radio drawing
7dd1a1e4f5 GUI: Increase tab title spacing
7c259fe129 Merge pull request #911 from wjp/tabs


Commit: af831f26b97590024218801528f50e008f3b2f72
    https://github.com/scummvm/scummvm/commit/af831f26b97590024218801528f50e008f3b2f72
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2017-02-28T15:55:51+01:00

Commit Message:
GUI: Clean up GlobalOptionsDialog reflow changing visible tabs

Changed paths:
    gui/options.cpp


diff --git a/gui/options.cpp b/gui/options.cpp
index f9c0541..d70c843 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -2002,14 +2002,8 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
 #ifdef USE_LIBCURL
 	case kPopUpItemSelectedCmd:
 	{
-		//update container's scrollbar and make sure tabs are not re-arranged
-		if (_tabWidget) {
-			int oldFirstVisible = _tabWidget->getFirstVisible();
-			reflowLayout();
-			_tabWidget->setFirstVisible(oldFirstVisible);
-		} else {
-			reflowLayout();
-		}
+		// update container's scrollbar
+		reflowLayout();
 		break;
 	}
 	case kConfigureStorageCmd:
@@ -2125,6 +2119,7 @@ void GlobalOptionsDialog::handleTickle() {
 }
 
 void GlobalOptionsDialog::reflowLayout() {
+	int firstVisible = _tabWidget->getFirstVisible();
 	int activeTab = _tabWidget->getActiveTab();
 
 	if (_midiTabId != -1) {
@@ -2156,6 +2151,8 @@ void GlobalOptionsDialog::reflowLayout() {
 	}
 
 	_tabWidget->setActiveTab(activeTab);
+	_tabWidget->setFirstVisible(firstVisible);
+
 	OptionsDialog::reflowLayout();
 #ifdef USE_CLOUD
 	setupCloudTab();


Commit: 5510640dbcd1bda6ae41942ed56c9ac037fc5228
    https://github.com/scummvm/scummvm/commit/5510640dbcd1bda6ae41942ed56c9ac037fc5228
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2017-02-28T15:55:52+01:00

Commit Message:
GUI: Give each tab in TabWidget its own width

The width of each tab is now computed from its title, independently of
the other tabs. This increases the number of tabs that fit on the
screen.

This rewrite also fixes a bug where if the window size increased while
_firstVisibleTab > 0, some tabs would become inaccessible when the
scroll buttons were hidden.

The layout key Globals.TabWidget.Tab.Width is now treated as minimal
tab width. This is set so that the tabs fit reasonably well in lowres
layouts.

At the same time, this reduces the lowres scroll buttons heights to fit.

This patch makes the Nintento DS hacks in TabWidget obsolete.
(Hopefully! I'm not able to test.)

Changed paths:
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h
    gui/themes/scummclassic.zip
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern.zip
    gui/themes/scummmodern/scummmodern_layout.stx
    gui/themes/scummmodern/scummmodern_layout_lowres.stx
    gui/widgets/tab.cpp
    gui/widgets/tab.h


diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index d859a88..64b25d8 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1620,28 +1620,34 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co
 	}
 }
 
-void ThemeEngine::drawTabClip(const Common::Rect &r, const Common::Rect &clip, int tabHeight, int tabWidth, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) {
+void ThemeEngine::drawTabClip(const Common::Rect &r, const Common::Rect &clip, int tabHeight, const Common::Array<int> &tabWidths, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) {
 	if (!ready())
 		return;
 
+	assert(tabs.size() == tabWidths.size());
+
 	queueDDClip(kDDTabBackground, Common::Rect(r.left, r.top, r.right, r.top + tabHeight), clip);
 
-	for (int i = 0; i < (int)tabs.size(); ++i) {
-		if (i == active)
+	int width = 0;
+	int activePos = -1;
+	for (int i = 0; i < (int)tabs.size(); width += tabWidths[i++]) {
+		if (r.left + width > r.right || r.left + width + tabWidths[i] > r.right)
 			continue;
 
-		if (r.left + i * tabWidth > r.right || r.left + (i + 1) * tabWidth > r.right)
+		if (i == active) {
+			activePos = width;
 			continue;
+		}
 
-		Common::Rect tabRect(r.left + i * tabWidth, r.top, r.left + (i + 1) * tabWidth, r.top + tabHeight);
+
+		Common::Rect tabRect(r.left + width, r.top, r.left + width + tabWidths[i], r.top + tabHeight);
 		queueDDClip(kDDTabInactive, tabRect, clip);
 		queueDDTextClip(getTextData(kDDTabInactive), getTextColor(kDDTabInactive), tabRect, clip, tabs[i], false, false, _widgets[kDDTabInactive]->_textAlignH, _widgets[kDDTabInactive]->_textAlignV);
 	}
 
-	if (active >= 0 &&
-		(r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) {
-		Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight);
-		const uint16 tabLeft = active * tabWidth;
+	if (activePos >= 0) {
+		Common::Rect tabRect(r.left + activePos, r.top, r.left + activePos + tabWidths[active], r.top + tabHeight);
+		const uint16 tabLeft = activePos;
 		const uint16 tabRight = MAX(r.right - tabRect.right, 0);
 		queueDDClip(kDDTabActive, tabRect, clip, (tabLeft << 16) | (tabRight & 0xFFFF));
 		queueDDTextClip(getTextData(kDDTabActive), getTextColor(kDDTabActive), tabRect, clip, tabs[active], false, false, _widgets[kDDTabActive]->_textAlignH, _widgets[kDDTabActive]->_textAlignV);
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 8a6db17..9d8ed41 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -388,7 +388,7 @@ public:
 	void drawTab(const Common::Rect &r, int tabHeight, int tabWidth,
 	             const Common::Array<Common::String> &tabs, int active, uint16 hints,
 	             int titleVPad, WidgetStateInfo state = kStateEnabled);
-	void drawTabClip(const Common::Rect &r, const Common::Rect &clippingRect, int tabHeight, int tabWidth,
+	void drawTabClip(const Common::Rect &r, const Common::Rect &clippingRect, int tabHeight, const Common::Array<int> &tabWidths,
 				 const Common::Array<Common::String> &tabs, int active, uint16 hints,
 				 int titleVPad, WidgetStateInfo state = kStateEnabled);
 
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index e84768b..8024437 100644
Binary files a/gui/themes/scummclassic.zip and b/gui/themes/scummclassic.zip differ
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index 75ffee2..35f4a03 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -95,7 +95,7 @@
 				size = '15, 0'
 		/>
 		<widget name = 'TabWidget.Tab'
-				size = '75, 27'
+				size = '40, 27'
 				padding = '0, 0, 8, 0'
 		/>
 		<widget name = 'TabWidget.Body'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index e46db3e..1085c5f 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -93,14 +93,14 @@
 				size = '9, 0'
 		/>
 		<widget name = 'TabWidget.Tab'
-				size = '45, 16'
+				size = '40, 16'
 				padding = '0, 0, 2, 0'
 		/>
 		<widget name = 'TabWidget.Body'
 				padding = '0, 0, 0, 0'
 		/>
 		<widget name = 'TabWidget.NavButton'
-				size = '32, 18'
+				size = '32, 14'
 				padding = '0, 0, 1, 0'
 		/>
 		<widget name = 'EditRecordLabel'
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index ed1e3c0..73aee35 100644
Binary files a/gui/themes/scummmodern.zip and b/gui/themes/scummmodern.zip differ
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index 754bc25..9633cb4 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -98,7 +98,7 @@
 				size = '15, 0'
 		/>
 		<widget name = 'TabWidget.Tab'
-				size = '75, 27'
+				size = '40, 27'
 				padding = '0, 0, 8, 0'
 		/>
 
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index eadb305..be8ce0c 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -91,14 +91,14 @@
 				size = '9, 0'
 		/>
 		<widget name = 'TabWidget.Tab'
-				size = '45, 16'
+				size = '40, 16'
 				padding = '0, 0, 2, 0'
 		/>
 		<widget name = 'TabWidget.Body'
 				padding = '0, 0, 0, 0'
 		/>
 		<widget name = 'TabWidget.NavButton'
-				size = '32, 18'
+				size = '32, 14'
 				padding = '0, 0, 2, 0'
 		/>
 		<widget name = 'EditRecordLabel'
diff --git a/gui/widgets/tab.cpp b/gui/widgets/tab.cpp
index 8e8c6b4..c86c835 100644
--- a/gui/widgets/tab.cpp
+++ b/gui/widgets/tab.cpp
@@ -48,8 +48,10 @@ void TabWidget::init() {
 	_type = kTabWidget;
 	_activeTab = -1;
 	_firstVisibleTab = 0;
+	_lastVisibleTab = 0;
+	_navButtonsVisible = false;
 
-	_tabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width");
+	_minTabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width");
 	_tabHeight = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Height");
 	_titleVPad = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Padding.Top");
 
@@ -105,52 +107,16 @@ int TabWidget::addTab(const String &title) {
 	newTab.title = title;
 	newTab.firstWidget = 0;
 
+	// Determine the new tab width
+	int newWidth = g_gui.getStringWidth(title) + 2 * 3;
+	if (newWidth < _minTabWidth)
+		newWidth = _minTabWidth;
+	newTab._tabWidth = newWidth;
+
 	_tabs.push_back(newTab);
 
 	int numTabs = _tabs.size();
 
-	// HACK: Nintendo DS uses a custom config dialog. This dialog does not work with
-	// our default "Globals.TabWidget.Tab.Width" setting.
-	//
-	// TODO: Add proper handling in the theme layout for such cases.
-	//
-	// There are different solutions to this problem:
-	//  - offer a "Tab.Width" setting per tab widget and thus let the Ninteno DS
-	//    backend set a default value for its special dialog.
-	//
-	//  - change our themes to use auto width calculaction by default
-	//
-	//  - change "Globals.TabWidget.Tab.Width" to be the minimal tab width setting and
-	//    rename it accordingly.
-	//    Actually this solution is pretty similar to our HACK for the Nintendo DS
-	//    backend. This hack enables auto width calculation by default with the
-	//    "Globals.TabWidget.Tab.Width" value as minimal width for the tab buttons.
-	//
-	//  - we might also consider letting every tab button having its own width.
-	//
-	//  - other solutions you can think of, which are hopefully less evil ;-).
-	//
-	// Of course also the Ninteno DS' dialog should be in our layouting engine, instead
-	// of being hard coded like it is right now.
-	//
-	// There are checks for __DS__ all over this source file to take care of the
-	// aforemnetioned problem.
-#ifdef __DS__
-	if (true) {
-#else
-	if (g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width") == 0) {
-#endif
-		if (_tabWidth == 0)
-			_tabWidth = 40;
-		// Determine the new tab width
-		int newWidth = g_gui.getStringWidth(title) + 2 * 3;
-		if (_tabWidth < newWidth)
-			_tabWidth = newWidth;
-		int maxWidth = _w / numTabs;
-		if (_tabWidth > maxWidth)
-			_tabWidth = maxWidth;
-	}
-
 	// Activate the new tab
 	setActiveTab(numTabs - 1);
 
@@ -160,7 +126,7 @@ int TabWidget::addTab(const String &title) {
 void TabWidget::removeTab(int tabID) {
 	assert(0 <= tabID && tabID < (int)_tabs.size());
 
-	// Deactive the tab if it's currently the active one
+	// Deactivate the tab if it's currently the active one
 	if (tabID == _activeTab) {
 		_tabs[tabID].firstWidget = _firstWidget;
 		releaseFocus();
@@ -202,9 +168,9 @@ void TabWidget::setActiveTab(int tabID) {
 		
 		// Also ensure the tab is visible in the tab bar
 		if (_firstVisibleTab > tabID)
-			_firstVisibleTab = tabID;
-		else if (_firstVisibleTab + _w / _tabWidth <= tabID)
-			_firstVisibleTab = tabID - _w / _tabWidth + 1;
+			setFirstVisible(tabID, true);
+		while (_lastVisibleTab < tabID)
+			setFirstVisible(_firstVisibleTab + 1, false);
 
 		_boss->draw();
 	}
@@ -216,16 +182,14 @@ void TabWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 
 	switch (cmd) {
 	case kCmdLeft:
-		if (_firstVisibleTab) {
-			_firstVisibleTab--;
-			draw();
+		if (_firstVisibleTab > 0) {
+			setFirstVisible(_firstVisibleTab - 1);
 		}
 		break;
 
 	case kCmdRight:
-		if (_firstVisibleTab + _w / _tabWidth < (int)_tabs.size()) {
-			_firstVisibleTab++;
-			draw();
+		if (_lastVisibleTab + 1 < (int)_tabs.size()) {
+			setFirstVisible(_firstVisibleTab + 1, false);
 		}
 		break;
 	}
@@ -234,18 +198,20 @@ void TabWidget::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
 void TabWidget::handleMouseDown(int x, int y, int button, int clickCount) {
 	assert(y < _tabHeight);
 
+	if (x < 0)
+		return;
+
 	// Determine which tab was clicked
-	int tabID = -1;
-	if (x >= 0 && (x % _tabWidth) < _tabWidth) {
-		tabID = x / _tabWidth;
-		if (tabID >= (int)_tabs.size())
-			tabID = -1;
+	int tabID;
+	for (tabID = _firstVisibleTab; tabID <= _lastVisibleTab; ++tabID) {
+		x -= _tabs[tabID]._tabWidth;
+		if (x < 0)
+			break;
 	}
 
 	// If a tab was clicked, switch to that pane
-	if (tabID >= 0 && tabID + _firstVisibleTab < (int)_tabs.size()) {
-		setActiveTab(tabID + _firstVisibleTab);
-	}
+	if (tabID <= _lastVisibleTab)
+		setActiveTab(tabID);
 }
 
 bool TabWidget::handleKeyDown(Common::KeyState state) {
@@ -265,26 +231,20 @@ void TabWidget::adjustTabs(int value) {
 	else if (tabID < 0)
 		tabID = ((int)_tabs.size() - 1);
 
-	// Slides _firstVisibleTab forward to the correct tab
-	int maxTabsOnScreen = (_w / _tabWidth);
-	if (tabID >= maxTabsOnScreen && (_firstVisibleTab + maxTabsOnScreen) < (int)_tabs.size())
-		_firstVisibleTab++;
-
-	// Slides _firstVisibleTab backwards to the correct tab
-	while (tabID < _firstVisibleTab)
-		_firstVisibleTab--;
-
 	setActiveTab(tabID);
 }
 
-int TabWidget::getFirstVisible() {
+int TabWidget::getFirstVisible() const {
 	return _firstVisibleTab;
 }
 
-void TabWidget::setFirstVisible(int tabID) {
+void TabWidget::setFirstVisible(int tabID, bool adjustIfRoom) {
 	assert(0 <= tabID && tabID < (int)_tabs.size());
 	_firstVisibleTab = tabID;
-	_boss->draw();
+
+	computeLastVisibleTab(adjustIfRoom);
+
+	_boss->draw(); // TODO: Necessary?
 }
 
 void TabWidget::reflowLayout() {
@@ -293,9 +253,14 @@ void TabWidget::reflowLayout() {
 	// NOTE: if you change that, make sure to do the same
 	// changes in the ThemeLayoutTabWidget (gui/ThemeLayout.cpp)
 	_tabHeight = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Height");
-	_tabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width");
+	_minTabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width");
 	_titleVPad = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Padding.Top");
 
+	_butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.PaddingRight", 0);
+	_butTP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Top", 0);
+	_butW = g_gui.xmlEval()->getVar("GlobalsTabWidget.NavButton.Width", 10);
+	_butH = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Height", 10);
+
 	// If widgets were added or removed in the current tab, without tabs
 	// having been switched using setActiveTab() afterward, then the
 	// firstWidget in the _tabs list for the active tab may not be up to
@@ -311,28 +276,34 @@ void TabWidget::reflowLayout() {
 		}
 	}
 
-	if (_tabWidth == 0) {
-		_tabWidth = 40;
-#ifdef __DS__
-	}
-	if (true) {
-#endif
-		int maxWidth = _w / _tabs.size();
-
-		for (uint i = 0; i < _tabs.size(); ++i) {
-			// Determine the new tab width
-			int newWidth = g_gui.getStringWidth(_tabs[i].title) + 2 * 3;
-			if (_tabWidth < newWidth)
-				_tabWidth = newWidth;
-			if (_tabWidth > maxWidth)
-				_tabWidth = maxWidth;
-		}
+	for (uint i = 0; i < _tabs.size(); ++i) {
+		// Determine the new tab width
+		int newWidth = g_gui.getStringWidth(_tabs[i].title) + 2 * 3;
+		if (newWidth < _minTabWidth)
+			newWidth = _minTabWidth;
+		_tabs[i]._tabWidth = newWidth;
 	}
 
-	_butRP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.PaddingRight", 0);
-	_butTP = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Padding.Top", 0);
-	_butW = g_gui.xmlEval()->getVar("GlobalsTabWidget.NavButton.Width", 10);
-	_butH = g_gui.xmlEval()->getVar("Globals.TabWidget.NavButton.Height", 10);
+	// See how many tabs fit on screen.
+	// We do this in a loop, because it will change if we need to
+	// add left/right scroll buttons, if we scroll left to use free
+	// space on the right, or a combination of those.
+	_navButtonsVisible = _firstVisibleTab > 0;
+	do {
+		computeLastVisibleTab(true);
+
+		if (_firstVisibleTab > 0 || _lastVisibleTab + 1 < (int)_tabs.size()) {
+			if (!_navButtonsVisible)
+				_navButtonsVisible = true;
+			else
+				break;
+		} else {
+			if (_navButtonsVisible)
+				_navButtonsVisible = false;
+			else
+				break;
+		}
+	} while (true);
 
 	int x = _w - _butRP - _butW * 2 - 2;
 	int y = _butTP - _tabHeight;
@@ -342,18 +313,20 @@ void TabWidget::reflowLayout() {
 
 void TabWidget::drawWidget() {
 	Common::Array<Common::String> tabs;
-	for (int i = _firstVisibleTab; i < (int)_tabs.size(); ++i) {
+	Common::Array<int> widths;
+	for (int i = _firstVisibleTab; i <= _lastVisibleTab; ++i) {
 		tabs.push_back(_tabs[i].title);
+		widths.push_back(_tabs[i]._tabWidth);
 	}
 	g_gui.theme()->drawDialogBackgroundClip(Common::Rect(_x + _bodyLP, _y + _bodyTP, _x+_w-_bodyRP, _y+_h-_bodyBP+_tabHeight), getBossClipRect(), _bodyBackgroundType);
 
-	g_gui.theme()->drawTabClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _tabHeight, _tabWidth, tabs, _activeTab - _firstVisibleTab, 0, _titleVPad);
+	g_gui.theme()->drawTabClip(Common::Rect(_x, _y, _x+_w, _y+_h), getBossClipRect(), _tabHeight, widths, tabs, _activeTab - _firstVisibleTab, 0, _titleVPad);
 }
 
 void TabWidget::draw() {
 	Widget::draw();
 
-	if (_tabWidth * _tabs.size() > _w) {
+	if (_navButtonsVisible) {
 		_navLeft->draw();
 		_navRight->draw();
 	}
@@ -361,7 +334,7 @@ void TabWidget::draw() {
 
 Widget *TabWidget::findWidget(int x, int y) {
 	if (y < _tabHeight) {
-		if (_tabWidth * _tabs.size() > _w) {
+		if (_navButtonsVisible) {
 			if (y >= _butTP && y < _butTP + _butH) {
 				if (x >= _w - _butRP - _butW * 2 - 2 && x < _w - _butRP - _butW - 2)
 					return _navLeft;
@@ -378,4 +351,30 @@ Widget *TabWidget::findWidget(int x, int y) {
 	}
 }
 
+void TabWidget::computeLastVisibleTab(bool adjustFirstIfRoom) {
+	int availableWidth = _w;
+	if (_navButtonsVisible)
+		availableWidth -= 2 + _butW * 2;
+
+	_lastVisibleTab = _tabs.size() - 1;
+	for (int i = _firstVisibleTab; i < (int)_tabs.size(); ++i) {
+		if (_tabs[i]._tabWidth > availableWidth) {
+			if (i > _firstVisibleTab)
+				_lastVisibleTab = i - 1;
+			else
+				_lastVisibleTab = _firstVisibleTab; // Always show 1
+			break;
+		}
+		availableWidth -= _tabs[i]._tabWidth;
+	}
+
+	if (adjustFirstIfRoom) {
+		// If possible, scroll to fit if there's unused space to the right
+		while (_firstVisibleTab > 0 && _tabs[_firstVisibleTab-1]._tabWidth <= availableWidth) {
+			availableWidth -= _tabs[_firstVisibleTab-1]._tabWidth;
+			_firstVisibleTab--;
+		}
+	}
+}
+
 } // End of namespace GUI
diff --git a/gui/widgets/tab.h b/gui/widgets/tab.h
index 4516c3c..a1a5e06 100644
--- a/gui/widgets/tab.h
+++ b/gui/widgets/tab.h
@@ -39,15 +39,17 @@ class TabWidget : public Widget {
 	struct Tab {
 		String title;
 		Widget *firstWidget;
+		int _tabWidth;
 	};
 	typedef Common::Array<Tab> TabList;
 
 protected:
 	int _activeTab;
 	int _firstVisibleTab;
+	int _lastVisibleTab;
 	TabList _tabs;
-	int _tabWidth;
 	int _tabHeight;
+	int _minTabWidth;
 
 	int _bodyRP, _bodyTP, _bodyLP, _bodyBP;
 	ThemeEngine::DialogBackground _bodyBackgroundType;
@@ -57,6 +59,7 @@ protected:
 	int _butRP, _butTP, _butW, _butH;
 
 	ButtonWidget *_navLeft, *_navRight;
+	bool _navButtonsVisible;
 
 public:
 	TabWidget(GuiObject *boss, int x, int y, int w, int h);
@@ -101,8 +104,8 @@ public:
 	virtual void handleMouseDown(int x, int y, int button, int clickCount);
 	virtual bool handleKeyDown(Common::KeyState state);
 	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
-	virtual int getFirstVisible();
-	virtual void setFirstVisible(int tabID); 
+	virtual int getFirstVisible() const;
+	virtual void setFirstVisible(int tabID, bool adjustIfRoom = false);
 
 	virtual void reflowLayout();
 
@@ -111,14 +114,16 @@ public:
 protected:
 	// We overload getChildY to make sure child widgets are positioned correctly.
 	// Essentially this compensates for the space taken up by the tab title header.
-	virtual int16	getChildY() const;
-	virtual uint16	getHeight() const;
+	virtual int16 getChildY() const;
+	virtual uint16 getHeight() const;
 
 	virtual void drawWidget();
 
 	virtual Widget *findWidget(int x, int y);
 
 	virtual void adjustTabs(int value);
+
+	virtual void computeLastVisibleTab(bool adjustFirstIfRoom);
 };
 
 } // End of namespace GUI


Commit: c64d91833f0b35ad415ef4a722038ce729bac85b
    https://github.com/scummvm/scummvm/commit/c64d91833f0b35ad415ef4a722038ce729bac85b
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2017-02-28T15:55:52+01:00

Commit Message:
GUI: Check rect validity for popup/radio drawing

Changed paths:
    gui/ThemeEngine.cpp


diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 64b25d8..8e04b35 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -1308,7 +1308,7 @@ void ThemeEngine::drawRadiobuttonClip(const Common::Rect &r, const Common::Rect
 	queueDDClip(dd, r2, clippingRect);
 
 	r2.left = r2.right + checkBoxSize;
-	r2.right = r.right;
+	r2.right = MAX(r2.left, r.right);
 
 	queueDDTextClip(getTextData(dd), getTextColor(dd), r2, clippingRect, str, true, false, _widgets[kDDRadiobuttonDefault]->_textAlignH, _widgets[dd]->_textAlignV);
 }
@@ -1519,7 +1519,7 @@ void ThemeEngine::drawPopUpWidgetClip(const Common::Rect &r, const Common::Rect
 
 	queueDDClip(dd, r, clip);
 
-	if (!sel.empty()) {
+	if (!sel.empty() && r.width() >= 13 && r.height() >= 1) {
 		Common::Rect text(r.left + 3, r.top + 1, r.right - 10, r.bottom);
 		queueDDTextClip(getTextData(dd), getTextColor(dd), text, clip, sel, true, false, _widgets[dd]->_textAlignH, _widgets[dd]->_textAlignV, deltax);
 	}


Commit: 7dd1a1e4f52b962ebcfe78584acdb9242797028f
    https://github.com/scummvm/scummvm/commit/7dd1a1e4f52b962ebcfe78584acdb9242797028f
Author: Willem Jan Palenstijn (wjp at usecode.org)
Date: 2017-03-01T00:24:06+01:00

Commit Message:
GUI: Increase tab title spacing

Changed paths:
    gui/widgets/tab.cpp


diff --git a/gui/widgets/tab.cpp b/gui/widgets/tab.cpp
index c86c835..9bf9527 100644
--- a/gui/widgets/tab.cpp
+++ b/gui/widgets/tab.cpp
@@ -33,6 +33,8 @@ enum {
 	kCmdRight = 'RGHT'
 };
 
+static const int kTabTitleSpacing = 2 * 5;
+
 TabWidget::TabWidget(GuiObject *boss, int x, int y, int w, int h)
 	: Widget(boss, x, y, w, h), _bodyBackgroundType(GUI::ThemeEngine::kDialogBackgroundDefault) {
 	init();
@@ -108,7 +110,7 @@ int TabWidget::addTab(const String &title) {
 	newTab.firstWidget = 0;
 
 	// Determine the new tab width
-	int newWidth = g_gui.getStringWidth(title) + 2 * 3;
+	int newWidth = g_gui.getStringWidth(title) + kTabTitleSpacing;
 	if (newWidth < _minTabWidth)
 		newWidth = _minTabWidth;
 	newTab._tabWidth = newWidth;
@@ -278,7 +280,7 @@ void TabWidget::reflowLayout() {
 
 	for (uint i = 0; i < _tabs.size(); ++i) {
 		// Determine the new tab width
-		int newWidth = g_gui.getStringWidth(_tabs[i].title) + 2 * 3;
+		int newWidth = g_gui.getStringWidth(_tabs[i].title) + kTabTitleSpacing;
 		if (newWidth < _minTabWidth)
 			newWidth = _minTabWidth;
 		_tabs[i]._tabWidth = newWidth;


Commit: 7c259fe1295fda60f3d6b5f5c6e3efd67ca9b852
    https://github.com/scummvm/scummvm/commit/7c259fe1295fda60f3d6b5f5c6e3efd67ca9b852
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2017-03-01T08:17:34+01:00

Commit Message:
Merge pull request #911 from wjp/tabs

GUI: Improve tab widget

Changed paths:
    gui/ThemeEngine.cpp
    gui/ThemeEngine.h
    gui/options.cpp
    gui/themes/scummclassic.zip
    gui/themes/scummclassic/classic_layout.stx
    gui/themes/scummclassic/classic_layout_lowres.stx
    gui/themes/scummmodern.zip
    gui/themes/scummmodern/scummmodern_layout.stx
    gui/themes/scummmodern/scummmodern_layout_lowres.stx
    gui/widgets/tab.cpp
    gui/widgets/tab.h







More information about the Scummvm-git-logs mailing list