OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/gtk/tabs/tab_strip_gtk.h" | 5 #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 const int kAnimateToBoundsDurationMs = 150; | 48 const int kAnimateToBoundsDurationMs = 150; |
49 const int kMiniTabAnimationDurationMs = 150; | 49 const int kMiniTabAnimationDurationMs = 150; |
50 | 50 |
51 const int kNewTabButtonHOffset = -5; | 51 const int kNewTabButtonHOffset = -5; |
52 const int kNewTabButtonVOffset = 5; | 52 const int kNewTabButtonVOffset = 5; |
53 | 53 |
54 // The delay between when the mouse leaves the tabstrip and the resize animation | 54 // The delay between when the mouse leaves the tabstrip and the resize animation |
55 // is started. | 55 // is started. |
56 const int kResizeTabsTimeMs = 300; | 56 const int kResizeTabsTimeMs = 300; |
57 | 57 |
| 58 // A very short time just to make sure we don't clump up our Layout() calls |
| 59 // during slow window resizes. |
| 60 const int kLayoutAfterSizeAllocateMs = 10; |
| 61 |
58 // The range outside of the tabstrip where the pointer must enter/leave to | 62 // The range outside of the tabstrip where the pointer must enter/leave to |
59 // start/stop the resize animation. | 63 // start/stop the resize animation. |
60 const int kTabStripAnimationVSlop = 40; | 64 const int kTabStripAnimationVSlop = 40; |
61 | 65 |
62 const int kHorizontalMoveThreshold = 16; // pixels | 66 const int kHorizontalMoveThreshold = 16; // pixels |
63 | 67 |
64 // The horizontal offset from one tab to the next, which results in overlapping | 68 // The horizontal offset from one tab to the next, which results in overlapping |
65 // tabs. | 69 // tabs. |
66 const int kTabHOffset = -16; | 70 const int kTabHOffset = -16; |
67 | 71 |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 TabStripGtk::TabStripGtk(TabStripModel* model, BrowserWindowGtk* window) | 703 TabStripGtk::TabStripGtk(TabStripModel* model, BrowserWindowGtk* window) |
700 : current_unselected_width_(TabGtk::GetStandardSize().width()), | 704 : current_unselected_width_(TabGtk::GetStandardSize().width()), |
701 current_selected_width_(TabGtk::GetStandardSize().width()), | 705 current_selected_width_(TabGtk::GetStandardSize().width()), |
702 available_width_for_tabs_(-1), | 706 available_width_for_tabs_(-1), |
703 needs_resize_layout_(false), | 707 needs_resize_layout_(false), |
704 tab_vertical_offset_(0), | 708 tab_vertical_offset_(0), |
705 model_(model), | 709 model_(model), |
706 window_(window), | 710 window_(window), |
707 theme_service_(GtkThemeService::GetFrom(model->profile())), | 711 theme_service_(GtkThemeService::GetFrom(model->profile())), |
708 weak_factory_(this), | 712 weak_factory_(this), |
| 713 layout_factory_(this), |
709 added_as_message_loop_observer_(false), | 714 added_as_message_loop_observer_(false), |
710 hover_tab_selector_(model) { | 715 hover_tab_selector_(model) { |
711 } | 716 } |
712 | 717 |
713 TabStripGtk::~TabStripGtk() { | 718 TabStripGtk::~TabStripGtk() { |
714 model_->RemoveObserver(this); | 719 model_->RemoveObserver(this); |
715 tabstrip_.Destroy(); | 720 tabstrip_.Destroy(); |
716 | 721 |
717 // Free any remaining tabs. This is needed to free the very last tab, | 722 // Free any remaining tabs. This is needed to free the very last tab, |
718 // because it is not animated on close. This also happens when all of the | 723 // because it is not animated on close. This also happens when all of the |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 } | 1554 } |
1550 return kTabHOffset; | 1555 return kTabHOffset; |
1551 } | 1556 } |
1552 | 1557 |
1553 int TabStripGtk::tab_start_x() const { | 1558 int TabStripGtk::tab_start_x() const { |
1554 return 0; | 1559 return 0; |
1555 } | 1560 } |
1556 | 1561 |
1557 bool TabStripGtk::ResizeLayoutTabs() { | 1562 bool TabStripGtk::ResizeLayoutTabs() { |
1558 weak_factory_.InvalidateWeakPtrs(); | 1563 weak_factory_.InvalidateWeakPtrs(); |
| 1564 layout_factory_.InvalidateWeakPtrs(); |
1559 | 1565 |
1560 // It is critically important that this is unhooked here, otherwise we will | 1566 // It is critically important that this is unhooked here, otherwise we will |
1561 // keep spying on messages forever. | 1567 // keep spying on messages forever. |
1562 RemoveMessageLoopObserver(); | 1568 RemoveMessageLoopObserver(); |
1563 | 1569 |
1564 available_width_for_tabs_ = -1; | 1570 available_width_for_tabs_ = -1; |
1565 int mini_tab_count = GetMiniTabCount(); | 1571 int mini_tab_count = GetMiniTabCount(); |
1566 if (mini_tab_count == GetTabCount()) { | 1572 if (mini_tab_count == GetTabCount()) { |
1567 // Only mini tabs, we know the tab widths won't have changed (all mini-tabs | 1573 // Only mini tabs, we know the tab widths won't have changed (all mini-tabs |
1568 // have the same width), so there is nothing to do. | 1574 // have the same width), so there is nothing to do. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 TabGtk* tab = GetTabAt(i); | 1622 TabGtk* tab = GetTabAt(i); |
1617 if (tab->IsActive()) | 1623 if (tab->IsActive()) |
1618 active_tab = tab; | 1624 active_tab = tab; |
1619 else | 1625 else |
1620 tab->Raise(); | 1626 tab->Raise(); |
1621 } | 1627 } |
1622 if (active_tab) | 1628 if (active_tab) |
1623 active_tab->Raise(); | 1629 active_tab->Raise(); |
1624 } | 1630 } |
1625 | 1631 |
1626 | |
1627 void TabStripGtk::AddMessageLoopObserver() { | 1632 void TabStripGtk::AddMessageLoopObserver() { |
1628 if (!added_as_message_loop_observer_) { | 1633 if (!added_as_message_loop_observer_) { |
1629 MessageLoopForUI::current()->AddObserver(this); | 1634 MessageLoopForUI::current()->AddObserver(this); |
1630 added_as_message_loop_observer_ = true; | 1635 added_as_message_loop_observer_ = true; |
1631 } | 1636 } |
1632 } | 1637 } |
1633 | 1638 |
1634 void TabStripGtk::RemoveMessageLoopObserver() { | 1639 void TabStripGtk::RemoveMessageLoopObserver() { |
1635 if (added_as_message_loop_observer_) { | 1640 if (added_as_message_loop_observer_) { |
1636 MessageLoopForUI::current()->RemoveObserver(this); | 1641 MessageLoopForUI::current()->RemoveObserver(this); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 return; | 2079 return; |
2075 | 2080 |
2076 SetBounds(bounds); | 2081 SetBounds(bounds); |
2077 | 2082 |
2078 // No tabs, nothing to layout. This happens when a browser window is created | 2083 // No tabs, nothing to layout. This happens when a browser window is created |
2079 // and shown before tabs are added (as in a popup window). | 2084 // and shown before tabs are added (as in a popup window). |
2080 if (GetTabCount() == 0) | 2085 if (GetTabCount() == 0) |
2081 return; | 2086 return; |
2082 | 2087 |
2083 // When there is only one tab, Layout() so we don't animate it. With more | 2088 // When there is only one tab, Layout() so we don't animate it. With more |
2084 // tabs, do ResizeLayoutTabs(). In RTL(), we will also need to manually | 2089 // tabs, we should always attempt a resize unless we already have one coming |
2085 // Layout() when ResizeLayoutTabs() is a no-op. | 2090 // up in our message loop. |
2086 if ((GetTabCount() == 1) || (!ResizeLayoutTabs() && base::i18n::IsRTL())) | 2091 if (GetTabCount() == 1) { |
2087 Layout(); | 2092 Layout(); |
| 2093 } else if (!layout_factory_.HasWeakPtrs()) { |
| 2094 MessageLoop::current()->PostDelayedTask( |
| 2095 FROM_HERE, |
| 2096 base::Bind(&TabStripGtk::Layout, layout_factory_.GetWeakPtr()), |
| 2097 kLayoutAfterSizeAllocateMs); |
| 2098 } |
2088 } | 2099 } |
2089 | 2100 |
2090 gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context, | 2101 gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context, |
2091 gint x, gint y, guint time) { | 2102 gint x, gint y, guint time) { |
2092 UpdateDropIndex(context, x, y); | 2103 UpdateDropIndex(context, x, y); |
2093 return TRUE; | 2104 return TRUE; |
2094 } | 2105 } |
2095 | 2106 |
2096 gboolean TabStripGtk::OnDragDrop(GtkWidget* widget, GdkDragContext* context, | 2107 gboolean TabStripGtk::OnDragDrop(GtkWidget* widget, GdkDragContext* context, |
2097 gint x, gint y, guint time) { | 2108 gint x, gint y, guint time) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2218 } | 2229 } |
2219 | 2230 |
2220 void TabStripGtk::SetNewTabButtonBackground() { | 2231 void TabStripGtk::SetNewTabButtonBackground() { |
2221 SkColor color = theme_service_->GetColor( | 2232 SkColor color = theme_service_->GetColor( |
2222 ThemeService::COLOR_BUTTON_BACKGROUND); | 2233 ThemeService::COLOR_BUTTON_BACKGROUND); |
2223 SkBitmap* background = theme_service_->GetBitmapNamed( | 2234 SkBitmap* background = theme_service_->GetBitmapNamed( |
2224 IDR_THEME_WINDOW_CONTROL_BACKGROUND); | 2235 IDR_THEME_WINDOW_CONTROL_BACKGROUND); |
2225 SkBitmap* mask = theme_service_->GetBitmapNamed(IDR_NEWTAB_BUTTON_MASK); | 2236 SkBitmap* mask = theme_service_->GetBitmapNamed(IDR_NEWTAB_BUTTON_MASK); |
2226 newtab_button_->SetBackground(color, background, mask); | 2237 newtab_button_->SetBackground(color, background, mask); |
2227 } | 2238 } |
OLD | NEW |