Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Unified Diff: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm

Issue 8921035: Lay out tabs to have integer widths. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: moar comment Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index f39fffe9ece1525c06912e55f1dfdb738a2c9e9f..d9b9abf12f6209156f9dea7dcd8eeed1e5b2c84d 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -6,6 +6,7 @@
#import <QuartzCore/QuartzCore.h>
+#include <cmath>
#include <limits>
#include <string>
@@ -851,6 +852,7 @@ private:
// Initialize |nonMiniTabWidth| in case there aren't any non-mini-tabs; this
// value shouldn't actually be used.
CGFloat nonMiniTabWidth = kMaxTabWidth;
+ CGFloat nonMiniTabWidthFraction = 0;
const NSInteger numberOfOpenNonMiniTabs = [self numberOfOpenNonMiniTabs];
if (numberOfOpenNonMiniTabs) {
// Find the width of a non-mini-tab. This only applies to horizontal
@@ -862,6 +864,11 @@ private:
// Clamp the width between the max and min.
nonMiniTabWidth = MAX(MIN(nonMiniTabWidth, kMaxTabWidth), kMinTabWidth);
+
+ // Separate integral and fractional parts.
+ CGFloat integralPart = std::floor(nonMiniTabWidth);
+ nonMiniTabWidthFraction = nonMiniTabWidth - integralPart;
+ nonMiniTabWidth = integralPart;
}
BOOL visible = [[tabStripView_ window] isVisible];
@@ -870,6 +877,8 @@ private:
bool hasPlaceholderGap = false;
// Whether or not the last tab processed by the loop was a mini tab.
BOOL isLastTabMini = NO;
+ CGFloat tabWidthAccumulatedFraction = 0;
+ NSInteger laidOutNonMiniTabs = 0;
for (TabController* tab in tabArray_.get()) {
// Ignore a tab that is going through a close animation.
if ([closingControllers_ containsObject:tab])
@@ -920,8 +929,31 @@ private:
// Set the width. Selected tabs are slightly wider when things get really
// small and thus we enforce a different minimum width.
BOOL isMini = [tab mini];
- tabFrame.size.width = isMini ?
- ([tab app] ? kAppTabWidth : kMiniTabWidth) : nonMiniTabWidth;
+ if (isMini) {
+ tabFrame.size.width = [tab app] ? kAppTabWidth : kMiniTabWidth;
+ } else {
+ // Tabs have non-integer widths. Assign the integer part to the tab, and
+ // keep an accumulation of the fractional parts. When the fractional
+ // accumulation gets to be more than one pixel, assign that to the current
+ // tab being laid out. This is vaguely inspired by Bresenham's line
+ // algorithm.
+ tabFrame.size.width = nonMiniTabWidth;
+ tabWidthAccumulatedFraction += nonMiniTabWidthFraction;
+
+ if (tabWidthAccumulatedFraction >= 1.0) {
+ ++tabFrame.size.width;
+ --tabWidthAccumulatedFraction;
+ }
+
+ // In case of rounding error, give any left over pixels to the last tab.
+ if (laidOutNonMiniTabs == numberOfOpenNonMiniTabs - 1 &&
+ tabWidthAccumulatedFraction > 0.5) {
+ ++tabFrame.size.width;
+ }
+
+ ++laidOutNonMiniTabs;
+ }
+
if ([tab selected])
tabFrame.size.width = MAX(tabFrame.size.width, kMinSelectedTabWidth);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698