OLD | NEW |
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 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windowsx.h> | 8 #include <windowsx.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <iterator> | 12 #include <iterator> |
13 #include <string> | 13 #include <string> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/compiler_specific.h" | 17 #include "base/compiler_specific.h" |
18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
21 #include "chrome/browser/defaults.h" | 21 #include "chrome/browser/defaults.h" |
22 #include "chrome/browser/ui/host_desktop.h" | 22 #include "chrome/browser/ui/host_desktop.h" |
23 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 23 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
24 #include "chrome/browser/ui/view_ids.h" | 24 #include "chrome/browser/ui/view_ids.h" |
| 25 #include "chrome/browser/ui/views/layout_constants.h" |
25 #include "chrome/browser/ui/views/tabs/stacked_tab_strip_layout.h" | 26 #include "chrome/browser/ui/views/tabs/stacked_tab_strip_layout.h" |
26 #include "chrome/browser/ui/views/tabs/tab.h" | 27 #include "chrome/browser/ui/views/tabs/tab.h" |
27 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" | 28 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" |
28 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" | 29 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" |
29 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" | 30 #include "chrome/browser/ui/views/tabs/tab_strip_observer.h" |
30 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" | 31 #include "chrome/browser/ui/views/touch_uma/touch_uma.h" |
31 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
32 #include "chrome/grit/generated_resources.h" | 33 #include "chrome/grit/generated_resources.h" |
33 #include "content/public/browser/user_metrics.h" | 34 #include "content/public/browser/user_metrics.h" |
34 #include "grit/theme_resources.h" | 35 #include "grit/theme_resources.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 107 |
107 // See UpdateLayoutTypeFromMouseEvent() for a description of these. | 108 // See UpdateLayoutTypeFromMouseEvent() for a description of these. |
108 #if !defined(USE_ASH) | 109 #if !defined(USE_ASH) |
109 const int kMouseMoveTimeMS = 200; | 110 const int kMouseMoveTimeMS = 200; |
110 const int kMouseMoveCountBeforeConsiderReal = 3; | 111 const int kMouseMoveCountBeforeConsiderReal = 3; |
111 #endif | 112 #endif |
112 | 113 |
113 // Amount of time we delay before resizing after a close from a touch. | 114 // Amount of time we delay before resizing after a close from a touch. |
114 const int kTouchResizeLayoutTimeMS = 2000; | 115 const int kTouchResizeLayoutTimeMS = 2000; |
115 | 116 |
116 // Amount of overlap between two adjacent tabs. | |
117 #if defined(OS_MACOSX) | |
118 const int kTabOverlap = 19; | |
119 #else | |
120 const int kTabOverlap = 26; | |
121 #endif | |
122 | |
123 // Amount to adjust the clip by when the tab is stacked before the active index. | 117 // Amount to adjust the clip by when the tab is stacked before the active index. |
124 const int kStackedTabLeftClip = 20; | 118 const int kStackedTabLeftClip = 20; |
125 | 119 |
126 // Amount to adjust the clip by when the tab is stacked after the active index. | 120 // Amount to adjust the clip by when the tab is stacked after the active index. |
127 const int kStackedTabRightClip = 20; | 121 const int kStackedTabRightClip = 20; |
128 | 122 |
129 base::string16 GetClipboardText() { | 123 base::string16 GetClipboardText() { |
130 if (!ui::Clipboard::IsSupportedClipboardType(ui::CLIPBOARD_TYPE_SELECTION)) | 124 if (!ui::Clipboard::IsSupportedClipboardType(ui::CLIPBOARD_TYPE_SELECTION)) |
131 return base::string16(); | 125 return base::string16(); |
132 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); | 126 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 | 797 |
804 int model_count = GetModelCount(); | 798 int model_count = GetModelCount(); |
805 if (model_count > 1 && model_index != model_count - 1) { | 799 if (model_count > 1 && model_index != model_count - 1) { |
806 // The user is about to close a tab other than the last tab. Set | 800 // The user is about to close a tab other than the last tab. Set |
807 // available_width_for_tabs_ so that if we do a layout we don't position a | 801 // available_width_for_tabs_ so that if we do a layout we don't position a |
808 // tab past the end of the second to last tab. We do this so that as the | 802 // tab past the end of the second to last tab. We do this so that as the |
809 // user closes tabs with the mouse a tab continues to fall under the mouse. | 803 // user closes tabs with the mouse a tab continues to fall under the mouse. |
810 Tab* last_tab = tab_at(model_count - 1); | 804 Tab* last_tab = tab_at(model_count - 1); |
811 Tab* tab_being_removed = tab_at(model_index); | 805 Tab* tab_being_removed = tab_at(model_index); |
812 available_width_for_tabs_ = last_tab->x() + last_tab->width() - | 806 available_width_for_tabs_ = last_tab->x() + last_tab->width() - |
813 tab_being_removed->width() + GetTabOverlap(); | 807 tab_being_removed->width() + GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
814 if (model_index == 0 && tab_being_removed->data().pinned && | 808 if (model_index == 0 && tab_being_removed->data().pinned && |
815 !tab_at(1)->data().pinned) { | 809 !tab_at(1)->data().pinned) { |
816 available_width_for_tabs_ -= kPinnedToNonPinnedGap; | 810 available_width_for_tabs_ -= kPinnedToNonPinnedGap; |
817 } | 811 } |
818 } | 812 } |
819 | 813 |
820 in_tab_close_ = true; | 814 in_tab_close_ = true; |
821 resize_layout_timer_.Stop(); | 815 resize_layout_timer_.Stop(); |
822 if (source == CLOSE_TAB_FROM_TOUCH) { | 816 if (source == CLOSE_TAB_FROM_TOUCH) { |
823 StartResizeLayoutTabsFromTouchTimer(); | 817 StartResizeLayoutTabsFromTouchTimer(); |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 tab_at(index)->height()); | 1201 tab_at(index)->height()); |
1208 } else if (index > active_index && index > 0) { | 1202 } else if (index > active_index && index > 0) { |
1209 const gfx::Rect& tab_bounds(tab_at(index)->bounds()); | 1203 const gfx::Rect& tab_bounds(tab_at(index)->bounds()); |
1210 const gfx::Rect& previous_tab_bounds(tab_at(index - 1)->bounds()); | 1204 const gfx::Rect& previous_tab_bounds(tab_at(index - 1)->bounds()); |
1211 if (tab_bounds.x() == previous_tab_bounds.x()) | 1205 if (tab_bounds.x() == previous_tab_bounds.x()) |
1212 return false; | 1206 return false; |
1213 | 1207 |
1214 if (tab_bounds.x() < previous_tab_bounds.x()) | 1208 if (tab_bounds.x() < previous_tab_bounds.x()) |
1215 return true; // Can happen during dragging. | 1209 return true; // Can happen during dragging. |
1216 | 1210 |
1217 if (previous_tab_bounds.right() - GetTabOverlap() != tab_bounds.x()) { | 1211 if (previous_tab_bounds.right() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP) != |
| 1212 tab_bounds.x()) { |
1218 int x = previous_tab_bounds.right() - tab_bounds.x() - | 1213 int x = previous_tab_bounds.right() - tab_bounds.x() - |
1219 kStackedTabRightClip; | 1214 kStackedTabRightClip; |
1220 clip->SetRect(x, 0, tab_bounds.width() - x, tab_bounds.height()); | 1215 clip->SetRect(x, 0, tab_bounds.width() - x, tab_bounds.height()); |
1221 } | 1216 } |
1222 } | 1217 } |
1223 return true; | 1218 return true; |
1224 } | 1219 } |
1225 | 1220 |
1226 bool TabStrip::IsImmersiveStyle() const { | 1221 bool TabStrip::IsImmersiveStyle() const { |
1227 return immersive_style_; | 1222 return immersive_style_; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 SkPaint paint; | 1318 SkPaint paint; |
1324 // If there are multiple tabs selected, fade non-selected tabs more to make | 1319 // If there are multiple tabs selected, fade non-selected tabs more to make |
1325 // the selected tabs more noticable. | 1320 // the selected tabs more noticable. |
1326 uint8_t alpha = selected_tab_count > 1 | 1321 uint8_t alpha = selected_tab_count > 1 |
1327 ? kGlassFrameInactiveTabAlphaMultiSelection | 1322 ? kGlassFrameInactiveTabAlphaMultiSelection |
1328 : kGlassFrameInactiveTabAlpha; | 1323 : kGlassFrameInactiveTabAlpha; |
1329 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255)); | 1324 paint.setColor(SkColorSetARGB(alpha, 255, 255, 255)); |
1330 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); | 1325 paint.setXfermodeMode(SkXfermode::kDstIn_Mode); |
1331 paint.setStyle(SkPaint::kFill_Style); | 1326 paint.setStyle(SkPaint::kFill_Style); |
1332 | 1327 |
1333 // The tab graphics include some shadows at the top, so the actual | 1328 gfx::Rect bounds(GetLocalBounds()); |
1334 // tabstrip top is 4 px. above the apparent top of the tab, to provide room | 1329 // The tab graphics include some shadows at the top, plus a 1 pixel top |
1335 // to draw these. Exclude this region when trying to make tabs transparent | 1330 // stroke. Exclude this region when trying to make tabs transparent as it's |
1336 // as it's transparent enough already, and drawing in this region can | 1331 // transparent enough already, and drawing in this region can overlap the |
1337 // overlap the avatar button, leading to visual artifacts. | 1332 // avatar button, leading to visual artifacts. Also exclude the toolbar |
1338 const int kTopOffset = 4; | 1333 // overlap region at the bottom. |
1339 // The tabstrip area overlaps the toolbar area by 2 px. | 1334 bounds.Inset(0, GetLayoutConstant(TABSTRIP_TOP_SHADOW_HEIGHT) + 1, 0, |
1340 recorder.canvas()->DrawRect( | 1335 GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP)); |
1341 gfx::Rect(0, kTopOffset, width(), height() - kTopOffset - 2), paint); | 1336 recorder.canvas()->DrawRect(bounds, paint); |
1342 } | 1337 } |
1343 | 1338 |
1344 // Now selected but not active. We don't want these dimmed if using native | 1339 // Now selected but not active. We don't want these dimmed if using native |
1345 // frame, so they're painted after initial pass. | 1340 // frame, so they're painted after initial pass. |
1346 for (size_t i = 0; i < selected_tabs.size(); ++i) | 1341 for (size_t i = 0; i < selected_tabs.size(); ++i) |
1347 selected_tabs[i]->Paint(context); | 1342 selected_tabs[i]->Paint(context); |
1348 | 1343 |
1349 // Next comes the active tab. | 1344 // Next comes the active tab. |
1350 if (active_tab && !is_dragging) | 1345 if (active_tab && !is_dragging) |
1351 active_tab->Paint(context); | 1346 active_tab->Paint(context); |
(...skipping 28 matching lines...) Expand all Loading... |
1380 // Otherwise the minimum width is based on the actual number of tabs. | 1375 // Otherwise the minimum width is based on the actual number of tabs. |
1381 const int pinned_tab_count = GetPinnedTabCount(); | 1376 const int pinned_tab_count = GetPinnedTabCount(); |
1382 needed_tab_width = pinned_tab_count * Tab::GetPinnedWidth(); | 1377 needed_tab_width = pinned_tab_count * Tab::GetPinnedWidth(); |
1383 const int remaining_tab_count = tab_count() - pinned_tab_count; | 1378 const int remaining_tab_count = tab_count() - pinned_tab_count; |
1384 const int min_selected_width = Tab::GetMinimumSelectedSize().width(); | 1379 const int min_selected_width = Tab::GetMinimumSelectedSize().width(); |
1385 const int min_unselected_width = Tab::GetMinimumUnselectedSize().width(); | 1380 const int min_unselected_width = Tab::GetMinimumUnselectedSize().width(); |
1386 if (remaining_tab_count > 0) { | 1381 if (remaining_tab_count > 0) { |
1387 needed_tab_width += kPinnedToNonPinnedGap + min_selected_width + | 1382 needed_tab_width += kPinnedToNonPinnedGap + min_selected_width + |
1388 ((remaining_tab_count - 1) * min_unselected_width); | 1383 ((remaining_tab_count - 1) * min_unselected_width); |
1389 } | 1384 } |
1390 const int tab_overlap = GetTabOverlap(); | 1385 const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
1391 if (tab_count() > 1) | 1386 if (tab_count() > 1) |
1392 needed_tab_width -= (tab_count() - 1) * tab_overlap; | 1387 needed_tab_width -= (tab_count() - 1) * tab_overlap; |
1393 | 1388 |
1394 // Don't let the tabstrip shrink smaller than is necessary to show one tab, | 1389 // Don't let the tabstrip shrink smaller than is necessary to show one tab, |
1395 // and don't force it to be larger than is necessary to show 20 tabs. | 1390 // and don't force it to be larger than is necessary to show 20 tabs. |
1396 const int largest_min_tab_width = | 1391 const int largest_min_tab_width = |
1397 min_selected_width + 19 * (min_unselected_width - tab_overlap); | 1392 min_selected_width + 19 * (min_unselected_width - tab_overlap); |
1398 needed_tab_width = std::min( | 1393 needed_tab_width = std::min( |
1399 std::max(needed_tab_width, min_selected_width), largest_min_tab_width); | 1394 std::max(needed_tab_width, min_selected_width), largest_min_tab_width); |
1400 } | 1395 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 available_width_for_tabs_ = -1; | 1543 available_width_for_tabs_ = -1; |
1549 | 1544 |
1550 GenerateIdealBounds(); | 1545 GenerateIdealBounds(); |
1551 | 1546 |
1552 Tab* tab = tab_at(model_index); | 1547 Tab* tab = tab_at(model_index); |
1553 if (model_index == 0) { | 1548 if (model_index == 0) { |
1554 tab->SetBounds(0, ideal_bounds(model_index).y(), 0, | 1549 tab->SetBounds(0, ideal_bounds(model_index).y(), 0, |
1555 ideal_bounds(model_index).height()); | 1550 ideal_bounds(model_index).height()); |
1556 } else { | 1551 } else { |
1557 Tab* last_tab = tab_at(model_index - 1); | 1552 Tab* last_tab = tab_at(model_index - 1); |
1558 tab->SetBounds(last_tab->bounds().right() - GetTabOverlap(), | 1553 tab->SetBounds( |
1559 ideal_bounds(model_index).y(), 0, | 1554 last_tab->bounds().right() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP), |
1560 ideal_bounds(model_index).height()); | 1555 ideal_bounds(model_index).y(), 0, ideal_bounds(model_index).height()); |
1561 } | 1556 } |
1562 | 1557 |
1563 AnimateToIdealBounds(); | 1558 AnimateToIdealBounds(); |
1564 } | 1559 } |
1565 | 1560 |
1566 void TabStrip::StartMoveTabAnimation() { | 1561 void TabStrip::StartMoveTabAnimation() { |
1567 PrepareForAnimation(); | 1562 PrepareForAnimation(); |
1568 GenerateIdealBounds(); | 1563 GenerateIdealBounds(); |
1569 AnimateToIdealBounds(); | 1564 AnimateToIdealBounds(); |
1570 } | 1565 } |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1799 void TabStrip::CalculateBoundsForDraggedTabs(const Tabs& tabs, | 1794 void TabStrip::CalculateBoundsForDraggedTabs(const Tabs& tabs, |
1800 std::vector<gfx::Rect>* bounds) { | 1795 std::vector<gfx::Rect>* bounds) { |
1801 int x = 0; | 1796 int x = 0; |
1802 for (size_t i = 0; i < tabs.size(); ++i) { | 1797 for (size_t i = 0; i < tabs.size(); ++i) { |
1803 Tab* tab = tabs[i]; | 1798 Tab* tab = tabs[i]; |
1804 if (i > 0 && tab->data().pinned != tabs[i - 1]->data().pinned) | 1799 if (i > 0 && tab->data().pinned != tabs[i - 1]->data().pinned) |
1805 x += kPinnedToNonPinnedGap; | 1800 x += kPinnedToNonPinnedGap; |
1806 gfx::Rect new_bounds = tab->bounds(); | 1801 gfx::Rect new_bounds = tab->bounds(); |
1807 new_bounds.set_origin(gfx::Point(x, 0)); | 1802 new_bounds.set_origin(gfx::Point(x, 0)); |
1808 bounds->push_back(new_bounds); | 1803 bounds->push_back(new_bounds); |
1809 x += tab->width() - GetTabOverlap(); | 1804 x += tab->width() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
1810 } | 1805 } |
1811 } | 1806 } |
1812 | 1807 |
1813 int TabStrip::GetSizeNeededForTabs(const Tabs& tabs) { | 1808 int TabStrip::GetSizeNeededForTabs(const Tabs& tabs) { |
1814 int width = 0; | 1809 int width = 0; |
1815 for (size_t i = 0; i < tabs.size(); ++i) { | 1810 for (size_t i = 0; i < tabs.size(); ++i) { |
1816 Tab* tab = tabs[i]; | 1811 Tab* tab = tabs[i]; |
1817 width += tab->width(); | 1812 width += tab->width(); |
1818 if (i > 0 && tab->data().pinned != tabs[i - 1]->data().pinned) | 1813 if (i > 0 && tab->data().pinned != tabs[i - 1]->data().pinned) |
1819 width += kPinnedToNonPinnedGap; | 1814 width += kPinnedToNonPinnedGap; |
1820 } | 1815 } |
1821 if (tabs.size() > 0) | 1816 if (!tabs.empty()) |
1822 width -= GetTabOverlap() * static_cast<int>(tabs.size() - 1); | 1817 width -= GetLayoutConstant(TABSTRIP_TAB_OVERLAP) * (tabs.size() - 1); |
1823 return width; | 1818 return width; |
1824 } | 1819 } |
1825 | 1820 |
1826 int TabStrip::GetTabOverlap() const { | |
1827 return kTabOverlap; | |
1828 } | |
1829 | |
1830 int TabStrip::GetPinnedTabCount() const { | 1821 int TabStrip::GetPinnedTabCount() const { |
1831 int pinned_count = 0; | 1822 int pinned_count = 0; |
1832 while (pinned_count < tab_count() && tab_at(pinned_count)->data().pinned) | 1823 while (pinned_count < tab_count() && tab_at(pinned_count)->data().pinned) |
1833 pinned_count++; | 1824 pinned_count++; |
1834 return pinned_count; | 1825 return pinned_count; |
1835 } | 1826 } |
1836 | 1827 |
1837 const Tab* TabStrip::GetLastVisibleTab() const { | 1828 const Tab* TabStrip::GetLastVisibleTab() const { |
1838 for (int i = tab_count() - 1; i >= 0; --i) { | 1829 for (int i = tab_count() - 1; i >= 0; --i) { |
1839 const Tab* tab = tab_at(i); | 1830 const Tab* tab = tab_at(i); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 *selected_width = min_selected_width; | 2097 *selected_width = min_selected_width; |
2107 | 2098 |
2108 if (tab_count == 0) { | 2099 if (tab_count == 0) { |
2109 // Return immediately to avoid divide-by-zero below. | 2100 // Return immediately to avoid divide-by-zero below. |
2110 return; | 2101 return; |
2111 } | 2102 } |
2112 | 2103 |
2113 // Determine how much space we can actually allocate to tabs. | 2104 // Determine how much space we can actually allocate to tabs. |
2114 int available_width = (available_width_for_tabs_ < 0) ? | 2105 int available_width = (available_width_for_tabs_ < 0) ? |
2115 tab_area_width() : available_width_for_tabs_; | 2106 tab_area_width() : available_width_for_tabs_; |
2116 const int tab_overlap = GetTabOverlap(); | 2107 const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2117 if (pinned_tab_count > 0) { | 2108 if (pinned_tab_count > 0) { |
2118 available_width -= | 2109 available_width -= |
2119 pinned_tab_count * (Tab::GetPinnedWidth() - tab_overlap); | 2110 pinned_tab_count * (Tab::GetPinnedWidth() - tab_overlap); |
2120 tab_count -= pinned_tab_count; | 2111 tab_count -= pinned_tab_count; |
2121 if (tab_count == 0) { | 2112 if (tab_count == 0) { |
2122 *selected_width = *unselected_width = Tab::GetStandardSize().width(); | 2113 *selected_width = *unselected_width = Tab::GetStandardSize().width(); |
2123 return; | 2114 return; |
2124 } | 2115 } |
2125 // Account for gap between the last pinned tab and first non-pinned tab. | 2116 // Account for gap between the last pinned tab and first non-pinned tab. |
2126 available_width -= kPinnedToNonPinnedGap; | 2117 available_width -= kPinnedToNonPinnedGap; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2219 | 2210 |
2220 void TabStrip::RemoveMessageLoopObserver() { | 2211 void TabStrip::RemoveMessageLoopObserver() { |
2221 mouse_watcher_.reset(NULL); | 2212 mouse_watcher_.reset(NULL); |
2222 } | 2213 } |
2223 | 2214 |
2224 gfx::Rect TabStrip::GetDropBounds(int drop_index, | 2215 gfx::Rect TabStrip::GetDropBounds(int drop_index, |
2225 bool drop_before, | 2216 bool drop_before, |
2226 bool* is_beneath) { | 2217 bool* is_beneath) { |
2227 DCHECK_NE(drop_index, -1); | 2218 DCHECK_NE(drop_index, -1); |
2228 int center_x; | 2219 int center_x; |
2229 const int tab_overlap = GetTabOverlap(); | 2220 const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2230 if (drop_index < tab_count()) { | 2221 if (drop_index < tab_count()) { |
2231 Tab* tab = tab_at(drop_index); | 2222 Tab* tab = tab_at(drop_index); |
2232 center_x = tab->x() + ((drop_before ? tab_overlap : tab->width()) / 2); | 2223 center_x = tab->x() + ((drop_before ? tab_overlap : tab->width()) / 2); |
2233 } else { | 2224 } else { |
2234 Tab* last_tab = tab_at(drop_index - 1); | 2225 Tab* last_tab = tab_at(drop_index - 1); |
2235 center_x = last_tab->x() + last_tab->width() - (tab_overlap / 2); | 2226 center_x = last_tab->x() + last_tab->width() - (tab_overlap / 2); |
2236 } | 2227 } |
2237 | 2228 |
2238 // Mirror the center point if necessary. | 2229 // Mirror the center point if necessary. |
2239 center_x = GetMirroredXInView(center_x); | 2230 center_x = GetMirroredXInView(center_x); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2385 } | 2376 } |
2386 | 2377 |
2387 GetDesiredTabWidths(tab_count(), GetPinnedTabCount(), | 2378 GetDesiredTabWidths(tab_count(), GetPinnedTabCount(), |
2388 ¤t_unselected_width_, ¤t_selected_width_); | 2379 ¤t_unselected_width_, ¤t_selected_width_); |
2389 | 2380 |
2390 // NOTE: This currently assumes a tab's height doesn't differ based on | 2381 // NOTE: This currently assumes a tab's height doesn't differ based on |
2391 // selected state or the number of tabs in the strip! | 2382 // selected state or the number of tabs in the strip! |
2392 int tab_height = Tab::GetStandardSize().height(); | 2383 int tab_height = Tab::GetStandardSize().height(); |
2393 int first_non_pinned_index = 0; | 2384 int first_non_pinned_index = 0; |
2394 double tab_x = GenerateIdealBoundsForPinnedTabs(&first_non_pinned_index); | 2385 double tab_x = GenerateIdealBoundsForPinnedTabs(&first_non_pinned_index); |
2395 const int tab_overlap = GetTabOverlap(); | 2386 const int tab_overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2396 for (int i = first_non_pinned_index; i < tab_count(); ++i) { | 2387 for (int i = first_non_pinned_index; i < tab_count(); ++i) { |
2397 Tab* tab = tab_at(i); | 2388 Tab* tab = tab_at(i); |
2398 DCHECK(!tab->data().pinned); | 2389 DCHECK(!tab->data().pinned); |
2399 double tab_width = | 2390 double tab_width = |
2400 tab->IsActive() ? current_selected_width_ : current_unselected_width_; | 2391 tab->IsActive() ? current_selected_width_ : current_unselected_width_; |
2401 double end_of_tab = tab_x + tab_width; | 2392 double end_of_tab = tab_x + tab_width; |
2402 int rounded_tab_x = Round(tab_x); | 2393 int rounded_tab_x = Round(tab_x); |
2403 tabs_.set_ideal_bounds( | 2394 tabs_.set_ideal_bounds( |
2404 i, | 2395 i, |
2405 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, | 2396 gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, |
(...skipping 17 matching lines...) Expand all Loading... |
2423 } | 2414 } |
2424 | 2415 |
2425 int TabStrip::GenerateIdealBoundsForPinnedTabs(int* first_non_pinned_index) { | 2416 int TabStrip::GenerateIdealBoundsForPinnedTabs(int* first_non_pinned_index) { |
2426 int next_x = 0; | 2417 int next_x = 0; |
2427 int pinned_width = Tab::GetPinnedWidth(); | 2418 int pinned_width = Tab::GetPinnedWidth(); |
2428 int tab_height = Tab::GetStandardSize().height(); | 2419 int tab_height = Tab::GetStandardSize().height(); |
2429 int index = 0; | 2420 int index = 0; |
2430 for (; index < tab_count() && tab_at(index)->data().pinned; ++index) { | 2421 for (; index < tab_count() && tab_at(index)->data().pinned; ++index) { |
2431 tabs_.set_ideal_bounds(index, | 2422 tabs_.set_ideal_bounds(index, |
2432 gfx::Rect(next_x, 0, pinned_width, tab_height)); | 2423 gfx::Rect(next_x, 0, pinned_width, tab_height)); |
2433 next_x += pinned_width - GetTabOverlap(); | 2424 next_x += pinned_width - GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2434 } | 2425 } |
2435 if (index > 0 && index < tab_count()) | 2426 if (index > 0 && index < tab_count()) |
2436 next_x += kPinnedToNonPinnedGap; | 2427 next_x += kPinnedToNonPinnedGap; |
2437 if (first_non_pinned_index) | 2428 if (first_non_pinned_index) |
2438 *first_non_pinned_index = index; | 2429 *first_non_pinned_index = index; |
2439 return next_x; | 2430 return next_x; |
2440 } | 2431 } |
2441 | 2432 |
2442 void TabStrip::StartResizeLayoutAnimation() { | 2433 void TabStrip::StartResizeLayoutAnimation() { |
2443 PrepareForAnimation(); | 2434 PrepareForAnimation(); |
2444 GenerateIdealBounds(); | 2435 GenerateIdealBounds(); |
2445 AnimateToIdealBounds(); | 2436 AnimateToIdealBounds(); |
2446 } | 2437 } |
2447 | 2438 |
2448 void TabStrip::StartPinnedTabAnimation() { | 2439 void TabStrip::StartPinnedTabAnimation() { |
2449 in_tab_close_ = false; | 2440 in_tab_close_ = false; |
2450 available_width_for_tabs_ = -1; | 2441 available_width_for_tabs_ = -1; |
2451 | 2442 |
2452 PrepareForAnimation(); | 2443 PrepareForAnimation(); |
2453 | 2444 |
2454 GenerateIdealBounds(); | 2445 GenerateIdealBounds(); |
2455 AnimateToIdealBounds(); | 2446 AnimateToIdealBounds(); |
2456 } | 2447 } |
2457 | 2448 |
2458 void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) { | 2449 void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) { |
2459 // The user initiated the close. We want to persist the bounds of all the | 2450 // The user initiated the close. We want to persist the bounds of all the |
2460 // existing tabs, so we manually shift ideal_bounds then animate. | 2451 // existing tabs, so we manually shift ideal_bounds then animate. |
2461 Tab* tab_closing = tab_at(model_index); | 2452 Tab* tab_closing = tab_at(model_index); |
2462 int delta = tab_closing->width() - GetTabOverlap(); | 2453 int delta = tab_closing->width() - GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2463 // If the tab being closed is a pinned tab next to a non-pinned tab, be sure | 2454 // If the tab being closed is a pinned tab next to a non-pinned tab, be sure |
2464 // to add the extra padding. | 2455 // to add the extra padding. |
2465 DCHECK_LT(model_index, tab_count() - 1); | 2456 DCHECK_LT(model_index, tab_count() - 1); |
2466 if (tab_closing->data().pinned && !tab_at(model_index + 1)->data().pinned) | 2457 if (tab_closing->data().pinned && !tab_at(model_index + 1)->data().pinned) |
2467 delta += kPinnedToNonPinnedGap; | 2458 delta += kPinnedToNonPinnedGap; |
2468 | 2459 |
2469 for (int i = model_index + 1; i < tab_count(); ++i) { | 2460 for (int i = model_index + 1; i < tab_count(); ++i) { |
2470 gfx::Rect bounds = ideal_bounds(i); | 2461 gfx::Rect bounds = ideal_bounds(i); |
2471 bounds.set_x(bounds.x() - delta); | 2462 bounds.set_x(bounds.x() - delta); |
2472 tabs_.set_ideal_bounds(i, bounds); | 2463 tabs_.set_ideal_bounds(i, bounds); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 const gfx::Point& point_in_tabstrip_coords) { | 2496 const gfx::Point& point_in_tabstrip_coords) { |
2506 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); | 2497 gfx::Point point_in_tab_coords(point_in_tabstrip_coords); |
2507 View::ConvertPointToTarget(this, tab, &point_in_tab_coords); | 2498 View::ConvertPointToTarget(this, tab, &point_in_tab_coords); |
2508 return tab->HitTestPoint(point_in_tab_coords); | 2499 return tab->HitTestPoint(point_in_tab_coords); |
2509 } | 2500 } |
2510 | 2501 |
2511 int TabStrip::GetStartXForNormalTabs() const { | 2502 int TabStrip::GetStartXForNormalTabs() const { |
2512 int pinned_tab_count = GetPinnedTabCount(); | 2503 int pinned_tab_count = GetPinnedTabCount(); |
2513 if (pinned_tab_count == 0) | 2504 if (pinned_tab_count == 0) |
2514 return 0; | 2505 return 0; |
2515 return pinned_tab_count * (Tab::GetPinnedWidth() - GetTabOverlap()) + | 2506 const int overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
| 2507 return pinned_tab_count * (Tab::GetPinnedWidth() - overlap) + |
2516 kPinnedToNonPinnedGap; | 2508 kPinnedToNonPinnedGap; |
2517 } | 2509 } |
2518 | 2510 |
2519 Tab* TabStrip::FindTabForEvent(const gfx::Point& point) { | 2511 Tab* TabStrip::FindTabForEvent(const gfx::Point& point) { |
2520 if (touch_layout_) { | 2512 if (touch_layout_) { |
2521 int active_tab_index = touch_layout_->active_index(); | 2513 int active_tab_index = touch_layout_->active_index(); |
2522 if (active_tab_index != -1) { | 2514 if (active_tab_index != -1) { |
2523 Tab* tab = FindTabForEventFrom(point, active_tab_index, -1); | 2515 Tab* tab = FindTabForEventFrom(point, active_tab_index, -1); |
2524 if (!tab) | 2516 if (!tab) |
2525 tab = FindTabForEventFrom(point, active_tab_index + 1, 1); | 2517 tab = FindTabForEventFrom(point, active_tab_index + 1, 1); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2576 bool needs_touch = NeedsTouchLayout(); | 2568 bool needs_touch = NeedsTouchLayout(); |
2577 bool using_touch = touch_layout_ != NULL; | 2569 bool using_touch = touch_layout_ != NULL; |
2578 if (needs_touch == using_touch) | 2570 if (needs_touch == using_touch) |
2579 return; | 2571 return; |
2580 | 2572 |
2581 if (needs_touch) { | 2573 if (needs_touch) { |
2582 gfx::Size tab_size(Tab::GetMinimumSelectedSize()); | 2574 gfx::Size tab_size(Tab::GetMinimumSelectedSize()); |
2583 tab_size.set_width(Tab::GetTouchWidth()); | 2575 tab_size.set_width(Tab::GetTouchWidth()); |
2584 touch_layout_.reset(new StackedTabStripLayout( | 2576 touch_layout_.reset(new StackedTabStripLayout( |
2585 tab_size, | 2577 tab_size, |
2586 GetTabOverlap(), | 2578 GetLayoutConstant(TABSTRIP_TAB_OVERLAP), |
2587 kStackedPadding, | 2579 kStackedPadding, |
2588 kMaxStackedCount, | 2580 kMaxStackedCount, |
2589 &tabs_)); | 2581 &tabs_)); |
2590 touch_layout_->SetWidth(tab_area_width()); | 2582 touch_layout_->SetWidth(tab_area_width()); |
2591 // This has to be after SetWidth() as SetWidth() is going to reset the | 2583 // This has to be after SetWidth() as SetWidth() is going to reset the |
2592 // bounds of the pinned tabs (since StackedTabStripLayout doesn't yet know | 2584 // bounds of the pinned tabs (since StackedTabStripLayout doesn't yet know |
2593 // how many pinned tabs there are). | 2585 // how many pinned tabs there are). |
2594 GenerateIdealBoundsForPinnedTabs(NULL); | 2586 GenerateIdealBoundsForPinnedTabs(NULL); |
2595 touch_layout_->SetXAndPinnedCount(GetStartXForNormalTabs(), | 2587 touch_layout_->SetXAndPinnedCount(GetStartXForNormalTabs(), |
2596 GetPinnedTabCount()); | 2588 GetPinnedTabCount()); |
(...skipping 10 matching lines...) Expand all Loading... |
2607 } | 2599 } |
2608 | 2600 |
2609 bool TabStrip::NeedsTouchLayout() const { | 2601 bool TabStrip::NeedsTouchLayout() const { |
2610 if (!stacked_layout_) | 2602 if (!stacked_layout_) |
2611 return false; | 2603 return false; |
2612 | 2604 |
2613 int pinned_tab_count = GetPinnedTabCount(); | 2605 int pinned_tab_count = GetPinnedTabCount(); |
2614 int normal_count = tab_count() - pinned_tab_count; | 2606 int normal_count = tab_count() - pinned_tab_count; |
2615 if (normal_count <= 1 || normal_count == pinned_tab_count) | 2607 if (normal_count <= 1 || normal_count == pinned_tab_count) |
2616 return false; | 2608 return false; |
2617 int x = GetStartXForNormalTabs(); | 2609 const int overlap = GetLayoutConstant(TABSTRIP_TAB_OVERLAP); |
2618 int available_width = tab_area_width() - x; | 2610 return (Tab::GetTouchWidth() * normal_count - overlap * (normal_count - 1)) > |
2619 return (Tab::GetTouchWidth() * normal_count - | 2611 tab_area_width() - GetStartXForNormalTabs(); |
2620 GetTabOverlap() * (normal_count - 1)) > available_width; | |
2621 } | 2612 } |
2622 | 2613 |
2623 void TabStrip::SetResetToShrinkOnExit(bool value) { | 2614 void TabStrip::SetResetToShrinkOnExit(bool value) { |
2624 if (!adjust_layout_) | 2615 if (!adjust_layout_) |
2625 return; | 2616 return; |
2626 | 2617 |
2627 if (value && !stacked_layout_) | 2618 if (value && !stacked_layout_) |
2628 value = false; // We're already using shrink (not stacked) layout. | 2619 value = false; // We're already using shrink (not stacked) layout. |
2629 | 2620 |
2630 if (value == reset_to_shrink_on_exit_) | 2621 if (value == reset_to_shrink_on_exit_) |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2779 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); | 2770 ConvertPointToViewAndGetEventHandler(this, newtab_button_, point); |
2780 if (view) | 2771 if (view) |
2781 return view; | 2772 return view; |
2782 } | 2773 } |
2783 Tab* tab = FindTabForEvent(point); | 2774 Tab* tab = FindTabForEvent(point); |
2784 if (tab) | 2775 if (tab) |
2785 return ConvertPointToViewAndGetEventHandler(this, tab, point); | 2776 return ConvertPointToViewAndGetEventHandler(this, tab, point); |
2786 } | 2777 } |
2787 return this; | 2778 return this; |
2788 } | 2779 } |
OLD | NEW |