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

Side by Side Diff: chrome/browser/ui/views/tabs/tab_strip.cc

Issue 10115029: Set toolbar padding to something appropriate for Metro icons. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Better positioning for new tab button. Simplify scale.h interface. Created 8 years, 8 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/tabs/tab_strip.h" 5 #include "chrome/browser/ui/views/tabs/tab_strip.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 14 matching lines...) Expand all
25 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" 25 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
26 #include "grit/generated_resources.h" 26 #include "grit/generated_resources.h"
27 #include "grit/theme_resources.h" 27 #include "grit/theme_resources.h"
28 #include "grit/theme_resources_standard.h" 28 #include "grit/theme_resources_standard.h"
29 #include "ui/base/accessibility/accessible_view_state.h" 29 #include "ui/base/accessibility/accessible_view_state.h"
30 #include "ui/base/animation/animation_container.h" 30 #include "ui/base/animation/animation_container.h"
31 #include "ui/base/animation/throb_animation.h" 31 #include "ui/base/animation/throb_animation.h"
32 #include "ui/base/dragdrop/drag_drop_types.h" 32 #include "ui/base/dragdrop/drag_drop_types.h"
33 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/resource/resource_bundle.h" 34 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/base/scale.h"
35 #include "ui/base/touch/touch_mode_support.h" 36 #include "ui/base/touch/touch_mode_support.h"
36 #include "ui/gfx/canvas.h" 37 #include "ui/gfx/canvas.h"
37 #include "ui/gfx/path.h" 38 #include "ui/gfx/path.h"
38 #include "ui/gfx/size.h" 39 #include "ui/gfx/size.h"
39 #include "ui/gfx/skbitmap_operations.h" 40 #include "ui/gfx/skbitmap_operations.h"
40 #include "ui/views/controls/image_view.h" 41 #include "ui/views/controls/image_view.h"
41 #include "ui/views/mouse_watcher_view_host.h" 42 #include "ui/views/mouse_watcher_view_host.h"
42 #include "ui/views/view_model_utils.h" 43 #include "ui/views/view_model_utils.h"
43 #include "ui/views/widget/default_theme_provider.h" 44 #include "ui/views/widget/default_theme_provider.h"
44 #include "ui/views/widget/root_view.h" 45 #include "ui/views/widget/root_view.h"
45 #include "ui/views/widget/widget.h" 46 #include "ui/views/widget/widget.h"
46 #include "ui/views/window/non_client_view.h" 47 #include "ui/views/window/non_client_view.h"
47 48
48 #if defined(OS_WIN) 49 #if defined(OS_WIN)
49 #include "ui/base/win/hwnd_util.h" 50 #include "ui/base/win/hwnd_util.h"
50 #include "ui/views/widget/monitor_win.h" 51 #include "ui/views/widget/monitor_win.h"
51 #endif 52 #endif
52 53
53 using views::DropTargetEvent; 54 using views::DropTargetEvent;
54 55
55 // Offset for the new tab button to bring it closer to the rightmost tab. 56 namespace {
56 #if defined(USE_ASH) 57
57 static const int kNewTabButtonHOffset = -11; 58 // Offsets for the new tab button to bring it closer to the rightmost tab.
58 static const int kNewTabButtonVOffset = 7; 59
59 #else 60 const int GetNewTabButtonHOffset() {
60 static const int kNewTabButtonHOffset = -5; 61 switch (ui::GetDisplayScale()) {
61 static const int kNewTabButtonVOffset = 5; 62 case ui::DS_ASH:
62 #endif 63 return -11;
64 case ui::DS_METRO_100:
65 case ui::DS_METRO_140:
66 case ui::DS_METRO_180:
67 // TODO(joi): Metro scales other than 100%.
68 return -6;
69 default:
70 return -5;
71 }
72 }
73
74 const int GetNewTabButtonVOffset() {
75 switch (ui::GetDisplayScale()) {
76 case ui::DS_ASH:
77 return 7;
78 case ui::DS_METRO_100:
79 case ui::DS_METRO_140:
80 case ui::DS_METRO_180:
81 // TODO(joi): Metro scales other than 100%.
82 return 10;
83 default:
84 return 5;
85 }
86 }
87
63 // Amount the left edge of a tab is offset from the rectangle of the tab's 88 // Amount the left edge of a tab is offset from the rectangle of the tab's
64 // favicon/title/close box. Related to the width of IDR_TAB_ACTIVE_LEFT. 89 // favicon/title/close box. Related to the width of IDR_TAB_ACTIVE_LEFT.
65 #if defined(USE_ASH) 90
66 static const int kTabHOffset = -27; 91 const int GetTabHOffset() {
67 #else 92 switch (ui::GetDisplayScale()) {
68 static const int kTabHOffset = -16; 93 case ui::DS_ASH:
69 #endif 94 return -27;
95 case ui::DS_METRO_100:
96 case ui::DS_METRO_140:
97 case ui::DS_METRO_180:
98 // TODO(joi): Metro scales other than 100%.
99 return -16;
100 default:
101 return -16;
102 }
103 }
104
70 static const int kTabStripAnimationVSlop = 40; 105 static const int kTabStripAnimationVSlop = 40;
71 // Inactive tabs in a native frame are slightly transparent. 106 // Inactive tabs in a native frame are slightly transparent.
72 static const int kNativeFrameInactiveTabAlpha = 200; 107 static const int kNativeFrameInactiveTabAlpha = 200;
73 // If there are multiple tabs selected then make non-selected inactive tabs 108 // If there are multiple tabs selected then make non-selected inactive tabs
74 // even more transparent. 109 // even more transparent.
75 static const int kNativeFrameInactiveTabAlphaMultiSelection = 150; 110 static const int kNativeFrameInactiveTabAlphaMultiSelection = 150;
76 111
77 // Inverse ratio of the width of a tab edge to the width of the tab. When 112 // Inverse ratio of the width of a tab edge to the width of the tab. When
78 // hovering over the left or right edge of a tab, the drop indicator will 113 // hovering over the left or right edge of a tab, the drop indicator will
79 // point between tabs. 114 // point between tabs.
80 static const int kTabEdgeRatioInverse = 4; 115 static const int kTabEdgeRatioInverse = 4;
81 116
82 // Size of the drop indicator. 117 // Size of the drop indicator.
83 static int drop_indicator_width; 118 static int drop_indicator_width;
84 static int drop_indicator_height; 119 static int drop_indicator_height;
85 120
86 static inline int Round(double x) { 121 static inline int Round(double x) {
87 // Why oh why is this not in a standard header? 122 // Why oh why is this not in a standard header?
88 return static_cast<int>(floor(x + 0.5)); 123 return static_cast<int>(floor(x + 0.5));
89 } 124 }
90 125
91 // Max width reserved for stacked tabs along a particular edge. 126 // Max width reserved for stacked tabs along a particular edge.
92 static const double kMaxEdgeStackWidth = 24; 127 static const double kMaxEdgeStackWidth = 24;
93 128
94 namespace {
95
96 // Animation delegate used when a dragged tab is released. When done sets the 129 // Animation delegate used when a dragged tab is released. When done sets the
97 // dragging state to false. 130 // dragging state to false.
98 class ResetDraggingStateDelegate 131 class ResetDraggingStateDelegate
99 : public views::BoundsAnimator::OwnedAnimationDelegate { 132 : public views::BoundsAnimator::OwnedAnimationDelegate {
100 public: 133 public:
101 explicit ResetDraggingStateDelegate(BaseTab* tab) : tab_(tab) { 134 explicit ResetDraggingStateDelegate(BaseTab* tab) : tab_(tab) {
102 } 135 }
103 136
104 virtual void AnimationEnded(const ui::Animation* animation) { 137 virtual void AnimationEnded(const ui::Animation* animation) {
105 tab_->set_dragging(false); 138 tab_->set_dragging(false);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 int height = mask->height(); 277 int height = mask->height();
245 int width = mask->width(); 278 int width = mask->width();
246 gfx::Canvas canvas(gfx::Size(width, height), false); 279 gfx::Canvas canvas(gfx::Size(width, height), false);
247 280
248 // For custom images the background starts at the top of the tab strip. 281 // For custom images the background starts at the top of the tab strip.
249 // Otherwise the background starts at the top of the frame. 282 // Otherwise the background starts at the top of the frame.
250 SkBitmap* background = GetThemeProvider()->GetBitmapNamed(background_id); 283 SkBitmap* background = GetThemeProvider()->GetBitmapNamed(background_id);
251 int offset_y = GetThemeProvider()->HasCustomImage(background_id) ? 284 int offset_y = GetThemeProvider()->HasCustomImage(background_id) ?
252 0 : background_offset_.y(); 285 0 : background_offset_.y();
253 canvas.TileImageInt(*background, GetMirroredX() + background_offset_.x(), 286 canvas.TileImageInt(*background, GetMirroredX() + background_offset_.x(),
254 kNewTabButtonVOffset + offset_y, 0, 0, width, height); 287 GetNewTabButtonVOffset() + offset_y, 0, 0, width, height);
255 288
256 if (alpha != 255) { 289 if (alpha != 255) {
257 SkPaint paint; 290 SkPaint paint;
258 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255)); 291 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255));
259 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); 292 paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
260 paint.setStyle(SkPaint::kFill_Style); 293 paint.setStyle(SkPaint::kFill_Style);
261 canvas.DrawRect(gfx::Rect(0, 0, width, height), paint); 294 canvas.DrawRect(gfx::Rect(0, 0, width, height), paint);
262 } 295 }
263 296
264 // White highlight on hover. 297 // White highlight on hover.
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 527
495 int model_count = GetModelCount(); 528 int model_count = GetModelCount();
496 if (model_index + 1 != model_count && model_count > 1) { 529 if (model_index + 1 != model_count && model_count > 1) {
497 // The user is about to close a tab other than the last tab. Set 530 // The user is about to close a tab other than the last tab. Set
498 // available_width_for_tabs_ so that if we do a layout we don't position a 531 // available_width_for_tabs_ so that if we do a layout we don't position a
499 // tab past the end of the second to last tab. We do this so that as the 532 // tab past the end of the second to last tab. We do this so that as the
500 // user closes tabs with the mouse a tab continues to fall under the mouse. 533 // user closes tabs with the mouse a tab continues to fall under the mouse.
501 Tab* last_tab = tab_at(model_count - 1); 534 Tab* last_tab = tab_at(model_count - 1);
502 Tab* tab_being_removed = tab_at(model_index); 535 Tab* tab_being_removed = tab_at(model_index);
503 available_width_for_tabs_ = last_tab->x() + last_tab->width() - 536 available_width_for_tabs_ = last_tab->x() + last_tab->width() -
504 tab_being_removed->width() - kTabHOffset; 537 tab_being_removed->width() - GetTabHOffset();
505 if (model_index == 0 && tab_being_removed->data().mini && 538 if (model_index == 0 && tab_being_removed->data().mini &&
506 !tab_at(1)->data().mini) { 539 !tab_at(1)->data().mini) {
507 available_width_for_tabs_ -= kMiniToNonMiniGap; 540 available_width_for_tabs_ -= kMiniToNonMiniGap;
508 } 541 }
509 } 542 }
510 543
511 in_tab_close_ = true; 544 in_tab_close_ = true;
512 AddMessageLoopObserver(); 545 AddMessageLoopObserver();
513 } 546 }
514 547
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 std::string TabStrip::GetClassName() const { 952 std::string TabStrip::GetClassName() const {
920 return kViewClassName; 953 return kViewClassName;
921 } 954 }
922 955
923 gfx::Size TabStrip::GetPreferredSize() { 956 gfx::Size TabStrip::GetPreferredSize() {
924 // Report the minimum width as the size required for a single selected tab 957 // Report the minimum width as the size required for a single selected tab
925 // plus the new tab button. Don't base it on the actual number of tabs because 958 // plus the new tab button. Don't base it on the actual number of tabs because
926 // it's undesirable to have the minimum window size change when a new tab is 959 // it's undesirable to have the minimum window size change when a new tab is
927 // opened. 960 // opened.
928 int needed_width = Tab::GetMinimumSelectedSize().width(); 961 int needed_width = Tab::GetMinimumSelectedSize().width();
929 needed_width += kNewTabButtonHOffset - kTabHOffset; 962 needed_width += GetNewTabButtonHOffset() - GetTabHOffset();
930 needed_width += newtab_button_bounds_.width(); 963 needed_width += newtab_button_bounds_.width();
931 return gfx::Size(needed_width, Tab::GetMinimumUnselectedSize().height()); 964 return gfx::Size(needed_width, Tab::GetMinimumUnselectedSize().height());
932 } 965 }
933 966
934 void TabStrip::OnDragEntered(const DropTargetEvent& event) { 967 void TabStrip::OnDragEntered(const DropTargetEvent& event) {
935 // Force animations to stop, otherwise it makes the index calculation tricky. 968 // Force animations to stop, otherwise it makes the index calculation tricky.
936 StopAnimating(true); 969 StopAnimating(true);
937 970
938 UpdateDropIndex(event); 971 UpdateDropIndex(event);
939 } 972 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 available_width_for_tabs_ = -1; 1129 available_width_for_tabs_ = -1;
1097 1130
1098 GenerateIdealBounds(); 1131 GenerateIdealBounds();
1099 1132
1100 BaseTab* tab = tab_at(model_index); 1133 BaseTab* tab = tab_at(model_index);
1101 if (model_index == 0) { 1134 if (model_index == 0) {
1102 tab->SetBounds(0, ideal_bounds(model_index).y(), 0, 1135 tab->SetBounds(0, ideal_bounds(model_index).y(), 0,
1103 ideal_bounds(model_index).height()); 1136 ideal_bounds(model_index).height());
1104 } else { 1137 } else {
1105 BaseTab* last_tab = tab_at(model_index - 1); 1138 BaseTab* last_tab = tab_at(model_index - 1);
1106 tab->SetBounds(last_tab->bounds().right() + kTabHOffset, 1139 tab->SetBounds(last_tab->bounds().right() + GetTabHOffset(),
1107 ideal_bounds(model_index).y(), 0, 1140 ideal_bounds(model_index).y(), 0,
1108 ideal_bounds(model_index).height()); 1141 ideal_bounds(model_index).height());
1109 } 1142 }
1110 1143
1111 AnimateToIdealBounds(); 1144 AnimateToIdealBounds();
1112 } 1145 }
1113 1146
1114 void TabStrip::StartMoveTabAnimation() { 1147 void TabStrip::StartMoveTabAnimation() {
1115 PrepareForAnimation(); 1148 PrepareForAnimation();
1116 GenerateIdealBounds(); 1149 GenerateIdealBounds();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 GenerateIdealBounds(); 1214 GenerateIdealBounds();
1182 1215
1183 views::ViewModelUtils::SetViewBoundsToIdealBounds(tabs_); 1216 views::ViewModelUtils::SetViewBoundsToIdealBounds(tabs_);
1184 1217
1185 SchedulePaint(); 1218 SchedulePaint();
1186 1219
1187 // It is possible we don't have a new tab button yet. 1220 // It is possible we don't have a new tab button yet.
1188 if (newtab_button_) { 1221 if (newtab_button_) {
1189 if (SizeTabButtonToTopOfTabStrip()) { 1222 if (SizeTabButtonToTopOfTabStrip()) {
1190 newtab_button_bounds_.set_height( 1223 newtab_button_bounds_.set_height(
1191 kNewTabButtonHeight + kNewTabButtonVOffset); 1224 kNewTabButtonHeight + GetNewTabButtonVOffset());
1192 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, 1225 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
1193 views::ImageButton::ALIGN_BOTTOM); 1226 views::ImageButton::ALIGN_BOTTOM);
1194 } else { 1227 } else {
1195 newtab_button_bounds_.set_height(kNewTabButtonHeight); 1228 newtab_button_bounds_.set_height(kNewTabButtonHeight);
1196 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT, 1229 newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
1197 views::ImageButton::ALIGN_TOP); 1230 views::ImageButton::ALIGN_TOP);
1198 } 1231 }
1199 newtab_button_->SetBoundsRect(newtab_button_bounds_); 1232 newtab_button_->SetBoundsRect(newtab_button_bounds_);
1200 } 1233 }
1201 } 1234 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 void TabStrip::CalculateBoundsForDraggedTabs(const std::vector<BaseTab*>& tabs, 1279 void TabStrip::CalculateBoundsForDraggedTabs(const std::vector<BaseTab*>& tabs,
1247 std::vector<gfx::Rect>* bounds) { 1280 std::vector<gfx::Rect>* bounds) {
1248 int x = 0; 1281 int x = 0;
1249 for (size_t i = 0; i < tabs.size(); ++i) { 1282 for (size_t i = 0; i < tabs.size(); ++i) {
1250 BaseTab* tab = tabs[i]; 1283 BaseTab* tab = tabs[i];
1251 if (i > 0 && tab->data().mini != tabs[i - 1]->data().mini) 1284 if (i > 0 && tab->data().mini != tabs[i - 1]->data().mini)
1252 x += kMiniToNonMiniGap; 1285 x += kMiniToNonMiniGap;
1253 gfx::Rect new_bounds = tab->bounds(); 1286 gfx::Rect new_bounds = tab->bounds();
1254 new_bounds.set_origin(gfx::Point(x, 0)); 1287 new_bounds.set_origin(gfx::Point(x, 0));
1255 bounds->push_back(new_bounds); 1288 bounds->push_back(new_bounds);
1256 x += tab->width() + kTabHOffset; 1289 x += tab->width() + GetTabHOffset();
1257 } 1290 }
1258 } 1291 }
1259 1292
1260 int TabStrip::GetSizeNeededForTabs(const std::vector<BaseTab*>& tabs) { 1293 int TabStrip::GetSizeNeededForTabs(const std::vector<BaseTab*>& tabs) {
1261 int width = 0; 1294 int width = 0;
1262 for (size_t i = 0; i < tabs.size(); ++i) { 1295 for (size_t i = 0; i < tabs.size(); ++i) {
1263 BaseTab* tab = tabs[i]; 1296 BaseTab* tab = tabs[i];
1264 width += tab->width(); 1297 width += tab->width();
1265 if (i > 0 && tab->data().mini != tabs[i - 1]->data().mini) 1298 if (i > 0 && tab->data().mini != tabs[i - 1]->data().mini)
1266 width += kMiniToNonMiniGap; 1299 width += kMiniToNonMiniGap;
1267 } 1300 }
1268 if (tabs.size() > 0) 1301 if (tabs.size() > 0)
1269 width += kTabHOffset * static_cast<int>(tabs.size() - 1); 1302 width += GetTabHOffset() * static_cast<int>(tabs.size() - 1);
1270 return width; 1303 return width;
1271 } 1304 }
1272 1305
1273 void TabStrip::RemoveTabFromViewModel(int index) { 1306 void TabStrip::RemoveTabFromViewModel(int index) {
1274 // We still need to paint the tab until we actually remove it. Put it 1307 // We still need to paint the tab until we actually remove it. Put it
1275 // in tabs_closing_map_ so we can find it. 1308 // in tabs_closing_map_ so we can find it.
1276 tabs_closing_map_[index].push_back(tab_at(index)); 1309 tabs_closing_map_[index].push_back(tab_at(index));
1277 UpdateTabsClosingMap(index + 1, -1); 1310 UpdateTabsClosingMap(index + 1, -1);
1278 tabs_.Remove(index); 1311 tabs_.Remove(index);
1279 } 1312 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1398 for (int i = index1; i < index2; ++i) { 1431 for (int i = index1; i < index2; ++i) {
1399 if (!tab_at(i)->closing()) 1432 if (!tab_at(i)->closing())
1400 count++; 1433 count++;
1401 } 1434 }
1402 return count; 1435 return count;
1403 } 1436 }
1404 1437
1405 void TabStrip::UpdateNumVisibleTabs(int non_closing_tab_count, 1438 void TabStrip::UpdateNumVisibleTabs(int non_closing_tab_count,
1406 int width, 1439 int width,
1407 double tab_size) { 1440 double tab_size) {
1408 num_visible_tabs_ = (width + kTabHOffset) / (tab_size + kTabHOffset); 1441 num_visible_tabs_ = (width + GetTabHOffset()) / (tab_size + GetTabHOffset());
1409 num_visible_tabs_ = std::max(1, num_visible_tabs_); 1442 num_visible_tabs_ = std::max(1, num_visible_tabs_);
1410 // Make sure the first_visible_tab_index_ is valid. 1443 // Make sure the first_visible_tab_index_ is valid.
1411 // TODO: this isn't quite right, it doesn't take into account closing tabs. 1444 // TODO: this isn't quite right, it doesn't take into account closing tabs.
1412 first_visible_tab_index_ = 1445 first_visible_tab_index_ =
1413 std::min(first_visible_tab_index_, non_closing_tab_count - 1446 std::min(first_visible_tab_index_, non_closing_tab_count -
1414 num_visible_tabs_); 1447 num_visible_tabs_);
1415 first_visible_tab_index_ = std::max(0, first_visible_tab_index_); 1448 first_visible_tab_index_ = std::max(0, first_visible_tab_index_);
1416 } 1449 }
1417 1450
1418 void TabStrip::EnsureModelIndexIsVisible(int model_index) { 1451 void TabStrip::EnsureModelIndexIsVisible(int model_index) {
(...skipping 27 matching lines...) Expand all
1446 1479
1447 if (tab_count == 0) { 1480 if (tab_count == 0) {
1448 // Return immediately to avoid divide-by-zero below. 1481 // Return immediately to avoid divide-by-zero below.
1449 return; 1482 return;
1450 } 1483 }
1451 1484
1452 // Determine how much space we can actually allocate to tabs. 1485 // Determine how much space we can actually allocate to tabs.
1453 int available_width; 1486 int available_width;
1454 if (available_width_for_tabs_ < 0) { 1487 if (available_width_for_tabs_ < 0) {
1455 available_width = width(); 1488 available_width = width();
1456 available_width -= (kNewTabButtonHOffset + newtab_button_bounds_.width()); 1489 available_width -=
1490 (GetNewTabButtonHOffset() + newtab_button_bounds_.width());
1457 } else { 1491 } else {
1458 // Interesting corner case: if |available_width_for_tabs_| > the result 1492 // Interesting corner case: if |available_width_for_tabs_| > the result
1459 // of the calculation in the conditional arm above, the strip is in 1493 // of the calculation in the conditional arm above, the strip is in
1460 // overflow. We can either use the specified width or the true available 1494 // overflow. We can either use the specified width or the true available
1461 // width here; the first preserves the consistent "leave the last tab under 1495 // width here; the first preserves the consistent "leave the last tab under
1462 // the user's mouse so they can close many tabs" behavior at the cost of 1496 // the user's mouse so they can close many tabs" behavior at the cost of
1463 // prolonging the glitchy appearance of the overflow state, while the second 1497 // prolonging the glitchy appearance of the overflow state, while the second
1464 // gets us out of overflow as soon as possible but forces the user to move 1498 // gets us out of overflow as soon as possible but forces the user to move
1465 // their mouse for a few tabs' worth of closing. We choose visual 1499 // their mouse for a few tabs' worth of closing. We choose visual
1466 // imperfection over behavioral imperfection and select the first option. 1500 // imperfection over behavioral imperfection and select the first option.
1467 available_width = available_width_for_tabs_; 1501 available_width = available_width_for_tabs_;
1468 } 1502 }
1469 1503
1470 if (mini_tab_count > 0) { 1504 if (mini_tab_count > 0) {
1471 available_width -= mini_tab_count * (Tab::GetMiniWidth() + kTabHOffset); 1505 available_width -= mini_tab_count * (Tab::GetMiniWidth() + GetTabHOffset());
1472 tab_count -= mini_tab_count; 1506 tab_count -= mini_tab_count;
1473 if (tab_count == 0) { 1507 if (tab_count == 0) {
1474 *selected_width = *unselected_width = Tab::GetStandardSize().width(); 1508 *selected_width = *unselected_width = Tab::GetStandardSize().width();
1475 return; 1509 return;
1476 } 1510 }
1477 // Account for gap between the last mini-tab and first non-mini-tab. 1511 // Account for gap between the last mini-tab and first non-mini-tab.
1478 available_width -= kMiniToNonMiniGap; 1512 available_width -= kMiniToNonMiniGap;
1479 } 1513 }
1480 1514
1481 // Calculate the desired tab widths by dividing the available space into equal 1515 // Calculate the desired tab widths by dividing the available space into equal
1482 // portions. Don't let tabs get larger than the "standard width" or smaller 1516 // portions. Don't let tabs get larger than the "standard width" or smaller
1483 // than the minimum width for each type, respectively. 1517 // than the minimum width for each type, respectively.
1484 const int total_offset = kTabHOffset * (tab_count - 1); 1518 const int total_offset = GetTabHOffset() * (tab_count - 1);
1485 const double desired_tab_width = std::min((static_cast<double>( 1519 const double desired_tab_width = std::min((static_cast<double>(
1486 available_width - total_offset) / static_cast<double>(tab_count)), 1520 available_width - total_offset) / static_cast<double>(tab_count)),
1487 static_cast<double>(Tab::GetStandardSize().width())); 1521 static_cast<double>(Tab::GetStandardSize().width()));
1488 *unselected_width = std::max(desired_tab_width, min_unselected_width); 1522 *unselected_width = std::max(desired_tab_width, min_unselected_width);
1489 *selected_width = std::max(desired_tab_width, min_selected_width); 1523 *selected_width = std::max(desired_tab_width, min_selected_width);
1490 1524
1491 // When there are multiple tabs, we'll have one selected and some unselected 1525 // When there are multiple tabs, we'll have one selected and some unselected
1492 // tabs. If the desired width was between the minimum sizes of these types, 1526 // tabs. If the desired width was between the minimum sizes of these types,
1493 // try to shrink the tabs with the smaller minimum. For example, if we have 1527 // try to shrink the tabs with the smaller minimum. For example, if we have
1494 // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5. If 1528 // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5. If
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 } 1601 }
1568 1602
1569 gfx::Rect TabStrip::GetDropBounds(int drop_index, 1603 gfx::Rect TabStrip::GetDropBounds(int drop_index,
1570 bool drop_before, 1604 bool drop_before,
1571 bool* is_beneath) { 1605 bool* is_beneath) {
1572 DCHECK_NE(drop_index, -1); 1606 DCHECK_NE(drop_index, -1);
1573 int center_x; 1607 int center_x;
1574 if (drop_index < tab_count()) { 1608 if (drop_index < tab_count()) {
1575 Tab* tab = tab_at(drop_index); 1609 Tab* tab = tab_at(drop_index);
1576 if (drop_before) 1610 if (drop_before)
1577 center_x = tab->x() - (kTabHOffset / 2); 1611 center_x = tab->x() - (GetTabHOffset() / 2);
1578 else 1612 else
1579 center_x = tab->x() + (tab->width() / 2); 1613 center_x = tab->x() + (tab->width() / 2);
1580 } else { 1614 } else {
1581 Tab* last_tab = tab_at(drop_index - 1); 1615 Tab* last_tab = tab_at(drop_index - 1);
1582 center_x = last_tab->x() + last_tab->width() + (kTabHOffset / 2); 1616 center_x = last_tab->x() + last_tab->width() + (GetTabHOffset() / 2);
1583 } 1617 }
1584 1618
1585 // Mirror the center point if necessary. 1619 // Mirror the center point if necessary.
1586 center_x = GetMirroredXInView(center_x); 1620 center_x = GetMirroredXInView(center_x);
1587 1621
1588 // Determine the screen bounds. 1622 // Determine the screen bounds.
1589 gfx::Point drop_loc(center_x - drop_indicator_width / 2, 1623 gfx::Point drop_loc(center_x - drop_indicator_width / 2,
1590 -drop_indicator_height); 1624 -drop_indicator_height);
1591 ConvertPointToScreen(this, &drop_loc); 1625 ConvertPointToScreen(this, &drop_loc);
1592 gfx::Rect drop_bounds(drop_loc.x(), drop_loc.y(), drop_indicator_width, 1626 gfx::Rect drop_bounds(drop_loc.x(), drop_loc.y(), drop_indicator_width,
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1758 tab_x += kMiniToNonMiniGap; 1792 tab_x += kMiniToNonMiniGap;
1759 } 1793 }
1760 if (tab->IsActive()) 1794 if (tab->IsActive())
1761 tab_width = selected; 1795 tab_width = selected;
1762 } 1796 }
1763 double end_of_tab = tab_x + tab_width; 1797 double end_of_tab = tab_x + tab_width;
1764 int rounded_tab_x = Round(tab_x); 1798 int rounded_tab_x = Round(tab_x);
1765 set_ideal_bounds(i, 1799 set_ideal_bounds(i,
1766 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, 1800 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x,
1767 tab_height)); 1801 tab_height));
1768 tab_x = end_of_tab + kTabHOffset; 1802 tab_x = end_of_tab + GetTabHOffset();
1769 last_was_mini = tab->data().mini; 1803 last_was_mini = tab->data().mini;
1770 } 1804 }
1771 } 1805 }
1772 1806
1773 // If we're in stacking mode, update the positions now that we have 1807 // If we're in stacking mode, update the positions now that we have
1774 // appropriate widths. 1808 // appropriate widths.
1775 if (stacking_ && tab_x - kTabHOffset > 1809 if (stacking_ && tab_x - GetTabHOffset() >
1776 width() - newtab_button_bounds_.width()) { 1810 width() - newtab_button_bounds_.width()) {
1777 tab_x = GenerateIdealBoundsWithStacking( 1811 tab_x = GenerateIdealBoundsWithStacking(
1778 mini_tab_count, non_closing_tab_count, tab_x, selected); 1812 mini_tab_count, non_closing_tab_count, tab_x, selected);
1779 } 1813 }
1780 1814
1781 // Update bounds of new tab button. 1815 // Update bounds of new tab button.
1782 int new_tab_x; 1816 int new_tab_x;
1783 int new_tab_y = SizeTabButtonToTopOfTabStrip() ? 0 : kNewTabButtonVOffset; 1817 int new_tab_y = SizeTabButtonToTopOfTabStrip() ? 0 : GetNewTabButtonVOffset();
1784 if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 && 1818 if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 &&
1785 !in_tab_close_) { 1819 !in_tab_close_) {
1786 // We're shrinking tabs, so we need to anchor the New Tab button to the 1820 // We're shrinking tabs, so we need to anchor the New Tab button to the
1787 // right edge of the TabStrip's bounds, rather than the right edge of the 1821 // right edge of the TabStrip's bounds, rather than the right edge of the
1788 // right-most Tab, otherwise it'll bounce when animating. 1822 // right-most Tab, otherwise it'll bounce when animating.
1789 new_tab_x = width() - newtab_button_bounds_.width(); 1823 new_tab_x = width() - newtab_button_bounds_.width();
1790 } else { 1824 } else {
1791 new_tab_x = Round(tab_x - kTabHOffset) + kNewTabButtonHOffset; 1825 new_tab_x = Round(tab_x - GetTabHOffset()) + GetNewTabButtonHOffset();
1792 } 1826 }
1793 newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y)); 1827 newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y));
1794 } 1828 }
1795 1829
1796 double TabStrip::GenerateIdealBoundsWithStacking(int mini_tab_count, 1830 double TabStrip::GenerateIdealBoundsWithStacking(int mini_tab_count,
1797 int non_closing_tab_count, 1831 int non_closing_tab_count,
1798 double new_tab_x, 1832 double new_tab_x,
1799 double selected_size) { 1833 double selected_size) {
1800 if (non_closing_tab_count == mini_tab_count) 1834 if (non_closing_tab_count == mini_tab_count)
1801 return new_tab_x; 1835 return new_tab_x;
1802 1836
1803 // Pinned tabs always have their desired size, and don't stack. We rely on 1837 // Pinned tabs always have their desired size, and don't stack. We rely on
1804 // GenerateIdealBounds to have positioned pinned tabs already, so don't move 1838 // GenerateIdealBounds to have positioned pinned tabs already, so don't move
1805 // them. 1839 // them.
1806 int tab_index = 0; 1840 int tab_index = 0;
1807 double next_x = 0; 1841 double next_x = 0;
1808 for (; tab_index < tab_count(); ++tab_index) { 1842 for (; tab_index < tab_count(); ++tab_index) {
1809 BaseTab* tab = tab_at(tab_index); 1843 BaseTab* tab = tab_at(tab_index);
1810 if (!tab->closing() && !tab->data().mini) { 1844 if (!tab->closing() && !tab->data().mini) {
1811 next_x = ideal_bounds(tab_index).x(); 1845 next_x = ideal_bounds(tab_index).x();
1812 break; 1846 break;
1813 } 1847 }
1814 } 1848 }
1815 if (tab_index == tab_count()) 1849 if (tab_index == tab_count())
1816 return new_tab_x; 1850 return new_tab_x;
1817 1851
1818 // Always reserve kMaxEdgeStackWidth on each side for stacking. We don't 1852 // Always reserve kMaxEdgeStackWidth on each side for stacking. We don't
1819 // later try to adjust as it can lead to tabs bouncing around. 1853 // later try to adjust as it can lead to tabs bouncing around.
1820 int available_width = width() - 1854 int available_width = width() -
1821 (kNewTabButtonHOffset + newtab_button_bounds_.width()) - next_x - 1855 (GetNewTabButtonHOffset() + newtab_button_bounds_.width()) - next_x -
1822 2 * kMaxEdgeStackWidth; 1856 2 * kMaxEdgeStackWidth;
1823 if (available_width <= 0) 1857 if (available_width <= 0)
1824 return new_tab_x; 1858 return new_tab_x;
1825 UpdateNumVisibleTabs(non_closing_tab_count, available_width, selected_size); 1859 UpdateNumVisibleTabs(non_closing_tab_count, available_width, selected_size);
1826 int stacked_leading_index = tab_index; 1860 int stacked_leading_index = tab_index;
1827 int stacked_trailing_index = first_visible_tab_index_; 1861 int stacked_trailing_index = first_visible_tab_index_;
1828 for (int visible_count = 0; 1862 for (int visible_count = 0;
1829 stacked_trailing_index < tab_count() && 1863 stacked_trailing_index < tab_count() &&
1830 visible_count < num_visible_tabs_; ++stacked_trailing_index) { 1864 visible_count < num_visible_tabs_; ++stacked_trailing_index) {
1831 if (!tab_at(stacked_trailing_index)->closing()) 1865 if (!tab_at(stacked_trailing_index)->closing())
(...skipping 18 matching lines...) Expand all
1850 } 1884 }
1851 } else { 1885 } else {
1852 tab_index = first_visible_tab_index_; 1886 tab_index = first_visible_tab_index_;
1853 } 1887 }
1854 1888
1855 if (stacked_leading_count > 0 && stacked_trailing_count == 0) { 1889 if (stacked_leading_count > 0 && stacked_trailing_count == 0) {
1856 // If there are no stacked tabs on the right and there is extra space, give 1890 // If there are no stacked tabs on the right and there is extra space, give
1857 // it to the last stacked tab on the left. 1891 // it to the last stacked tab on the left.
1858 next_x += available_width + kMaxEdgeStackWidth - 1892 next_x += available_width + kMaxEdgeStackWidth -
1859 (num_visible_tabs_ * selected_size + 1893 (num_visible_tabs_ * selected_size +
1860 std::max(num_visible_tabs_ - 1, 0) * kTabHOffset); 1894 std::max(num_visible_tabs_ - 1, 0) * GetTabHOffset());
1861 } 1895 }
1862 1896
1863 // Totally visible tabs. 1897 // Totally visible tabs.
1864 for (int visible_count = 0; 1898 for (int visible_count = 0;
1865 tab_index < tab_count() && visible_count < num_visible_tabs_; 1899 tab_index < tab_count() && visible_count < num_visible_tabs_;
1866 tab_index++) { 1900 tab_index++) {
1867 if (tab_at(tab_index)->closing()) 1901 if (tab_at(tab_index)->closing())
1868 continue; 1902 continue;
1869 gfx::Rect bounds = ideal_bounds(tab_index); 1903 gfx::Rect bounds = ideal_bounds(tab_index);
1870 bounds.set_x(next_x); 1904 bounds.set_x(next_x);
1871 next_x = bounds.right() + kTabHOffset; 1905 next_x = bounds.right() + GetTabHOffset();
1872 set_ideal_bounds(tab_index, bounds); 1906 set_ideal_bounds(tab_index, bounds);
1873 visible_count++; 1907 visible_count++;
1874 } 1908 }
1875 1909
1876 // Stacked tabs to the right. 1910 // Stacked tabs to the right.
1877 if (stacked_trailing_count == 0) 1911 if (stacked_trailing_count == 0)
1878 return next_x; 1912 return next_x;
1879 1913
1880 double stacked_offset = 1914 double stacked_offset =
1881 kMaxEdgeStackWidth / static_cast<double>(stacked_trailing_count); 1915 kMaxEdgeStackWidth / static_cast<double>(stacked_trailing_count);
1882 next_x = width() - (kNewTabButtonHOffset + newtab_button_bounds_.width()) - 1916 next_x = width() -
1917 (GetNewTabButtonHOffset() + newtab_button_bounds_.width()) -
1883 (stacked_trailing_count - 1) * stacked_offset - selected_size; 1918 (stacked_trailing_count - 1) * stacked_offset - selected_size;
1884 for (; tab_index < tab_count(); ++tab_index) { 1919 for (; tab_index < tab_count(); ++tab_index) {
1885 if (tab_at(tab_index)->closing()) 1920 if (tab_at(tab_index)->closing())
1886 continue; 1921 continue;
1887 gfx::Rect bounds = ideal_bounds(tab_index); 1922 gfx::Rect bounds = ideal_bounds(tab_index);
1888 bounds.set_x(next_x); 1923 bounds.set_x(next_x);
1889 set_ideal_bounds(tab_index, bounds); 1924 set_ideal_bounds(tab_index, bounds);
1890 next_x += stacked_offset; 1925 next_x += stacked_offset;
1891 } 1926 }
1892 1927
1893 return next_x + kTabHOffset; 1928 return next_x + GetTabHOffset();
1894 } 1929 }
1895 1930
1896 void TabStrip::StartResizeLayoutAnimation() { 1931 void TabStrip::StartResizeLayoutAnimation() {
1897 PrepareForAnimation(); 1932 PrepareForAnimation();
1898 GenerateIdealBounds(); 1933 GenerateIdealBounds();
1899 AnimateToIdealBounds(); 1934 AnimateToIdealBounds();
1900 } 1935 }
1901 1936
1902 void TabStrip::StartMiniTabAnimation() { 1937 void TabStrip::StartMiniTabAnimation() {
1903 in_tab_close_ = false; 1938 in_tab_close_ = false;
1904 available_width_for_tabs_ = -1; 1939 available_width_for_tabs_ = -1;
1905 1940
1906 PrepareForAnimation(); 1941 PrepareForAnimation();
1907 1942
1908 GenerateIdealBounds(); 1943 GenerateIdealBounds();
1909 AnimateToIdealBounds(); 1944 AnimateToIdealBounds();
1910 } 1945 }
1911 1946
1912 void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) { 1947 void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) {
1913 // The user initiated the close. We want to persist the bounds of all the 1948 // The user initiated the close. We want to persist the bounds of all the
1914 // existing tabs, so we manually shift ideal_bounds then animate. 1949 // existing tabs, so we manually shift ideal_bounds then animate.
1915 BaseTab* tab_closing = tab_at(model_index); 1950 BaseTab* tab_closing = tab_at(model_index);
1916 int delta = tab_closing->width() + kTabHOffset; 1951 int delta = tab_closing->width() + GetTabHOffset();
1917 // If the tab being closed is a mini-tab next to a non-mini-tab, be sure to 1952 // If the tab being closed is a mini-tab next to a non-mini-tab, be sure to
1918 // add the extra padding. 1953 // add the extra padding.
1919 DCHECK_NE(model_index + 1, tab_count()); 1954 DCHECK_NE(model_index + 1, tab_count());
1920 if (tab_closing->data().mini && model_index + 1 < tab_count() && 1955 if (tab_closing->data().mini && model_index + 1 < tab_count() &&
1921 !tab_at(model_index + 1)->data().mini) { 1956 !tab_at(model_index + 1)->data().mini) {
1922 delta += kMiniToNonMiniGap; 1957 delta += kMiniToNonMiniGap;
1923 } 1958 }
1924 1959
1925 for (int i = model_index + 1; i < tab_count(); ++i) { 1960 for (int i = model_index + 1; i < tab_count(); ++i) {
1926 gfx::Rect bounds = ideal_bounds(i); 1961 gfx::Rect bounds = ideal_bounds(i);
(...skipping 24 matching lines...) Expand all
1951 new RemoveTabDelegate(this, tab_closing), 1986 new RemoveTabDelegate(this, tab_closing),
1952 true); 1987 true);
1953 } 1988 }
1954 1989
1955 bool TabStrip::IsPointInTab(Tab* tab, 1990 bool TabStrip::IsPointInTab(Tab* tab,
1956 const gfx::Point& point_in_tabstrip_coords) { 1991 const gfx::Point& point_in_tabstrip_coords) {
1957 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); 1992 gfx::Point point_in_tab_coords(point_in_tabstrip_coords);
1958 View::ConvertPointToView(this, tab, &point_in_tab_coords); 1993 View::ConvertPointToView(this, tab, &point_in_tab_coords);
1959 return tab->HitTest(point_in_tab_coords); 1994 return tab->HitTest(point_in_tab_coords);
1960 } 1995 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698