| 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 |