diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-06 00:43:16 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-06 00:43:16 +0000 |
commit | df72ac7d639a53573b3696dc5174e37a5a32ce07 (patch) | |
tree | 24eb66d053f2893da731113a6edaf5ea8366c82a | |
parent | 0fe52a020563061cc9b354f5a3892080b8500d8f (diff) | |
download | chromium_src-df72ac7d639a53573b3696dc5174e37a5a32ce07.zip chromium_src-df72ac7d639a53573b3696dc5174e37a5a32ce07.tar.gz chromium_src-df72ac7d639a53573b3696dc5174e37a5a32ce07.tar.bz2 |
Makes mini-tabs work on the UI side (at least for views). I still have
a handful of things to resolve before I turn on pinning.
BUG=32845
TEST=none
Review URL: http://codereview.chromium.org/579011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38287 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.cc | 2 | ||||
-rw-r--r-- | chrome/browser/defaults.cc | 4 | ||||
-rw-r--r-- | chrome/browser/defaults.h | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_renderer_gtk.cc | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 13 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.cc | 30 | ||||
-rw-r--r-- | chrome/browser/tabs/tab_strip_model.h | 27 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_controller.cc | 234 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_controller.h | 46 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_view.cc | 23 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_view.h | 17 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab.h | 3 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_renderer.cc | 90 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_renderer.h | 44 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 338 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.h | 25 |
17 files changed, 473 insertions, 433 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 97eabe8..6884979 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1651,7 +1651,7 @@ TabContents* Browser::AddBlankTabAt(int index, bool foreground) { // TabContents, but we want to include the time it takes to create the // TabContents object too. base::TimeTicks new_tab_start_time = base::TimeTicks::Now(); - TabContents* tab_contents = AddTabWithURL(GURL(chrome::kChromeUINewTabURL), + TabContents* tab_contents = AddTabWithURL(GURL(chrome::kChromeUINewTabURL), GURL(), PageTransition::TYPED, foreground, index, false, NULL); tab_contents->set_new_tab_start_time(new_tab_start_time); return tab_contents; diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc index a901949..0f5e55f 100644 --- a/chrome/browser/defaults.cc +++ b/chrome/browser/defaults.cc @@ -14,7 +14,7 @@ const double kAutocompleteEditFontPixelSizeInPopup = kAutocompletePopupFontSize; const int kAutocompletePopupFontSize = 7; const SessionStartupPref::Type kDefaultSessionStartupType = SessionStartupPref::LAST; -const int kPinnedTabWidth = 64; +const int kMiniTabWidth = 64; const bool kCanToggleSystemTitleBar = false; const bool kRestorePopups = true; const bool kShowImportOnBookmarkBar = false; @@ -49,7 +49,7 @@ const bool kCanToggleSystemTitleBar = true; const SessionStartupPref::Type kDefaultSessionStartupType = SessionStartupPref::DEFAULT; -const int kPinnedTabWidth = 56; +const int kMiniTabWidth = 56; const bool kRestorePopups = false; const bool kShowImportOnBookmarkBar = true; const bool kDownloadPageHasShowInFolder = true; diff --git a/chrome/browser/defaults.h b/chrome/browser/defaults.h index 595bb70..f4ebe02a 100644 --- a/chrome/browser/defaults.h +++ b/chrome/browser/defaults.h @@ -31,8 +31,8 @@ extern const bool kCanToggleSystemTitleBar; // The default value for session startup. extern const SessionStartupPref::Type kDefaultSessionStartupType; -// Width of pinned tabs. -extern const int kPinnedTabWidth; +// Width of mini-tabs. +extern const int kMiniTabWidth; // Should session restore restore popup windows? extern const bool kRestorePopups; diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc index 0a992cc..b015468 100644 --- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc @@ -43,7 +43,7 @@ const int kInactiveTabBackgroundOffsetY = 20; // as a normal tab. This is done to avoid having the title immediately // disappear when transitioning a tab from normal to pinned. const int kPinnedTabRendererAsTabWidth = - browser_defaults::kPinnedTabWidth + 30; + browser_defaults::kMiniTabWidth + 30; // The tab images are designed to overlap the toolbar by 1 pixel. For now we // don't actually overlap the toolbar, so this is used to know how many pixels @@ -445,7 +445,7 @@ gfx::Size TabRendererGtk::GetStandardSize() { // static int TabRendererGtk::GetPinnedWidth() { - return browser_defaults::kPinnedTabWidth; + return browser_defaults::kMiniTabWidth; } // static diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 3f61ddb..ebc370b 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1230,10 +1230,14 @@ void TabContents::OnCloseStarted() { } TabContents* TabContents::CloneAndMakePhantom() { - DCHECK(app_extension_); // Should only be invoked on apps. - TabNavigation tab_nav; - tab_nav.set_url(app_extension_->app_launch_url()); + + NavigationEntry* entry = controller().GetActiveEntry(); + if (app_extension_) + tab_nav.set_url(app_extension_->app_launch_url()); + else if (entry) + tab_nav.SetFromNavigationEntry(*entry); + std::vector<TabNavigation> navigations; navigations.push_back(tab_nav); @@ -1242,6 +1246,9 @@ TabContents* TabContents::CloneAndMakePhantom() { new_contents->SetAppExtension(app_extension_); new_contents->controller().RestoreFromState(navigations, 0, false); + if (!app_extension_ && entry) + new_contents->controller().GetActiveEntry()->favicon() = entry->favicon(); + return new_contents; } diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 4730f76..167604f 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -108,12 +108,7 @@ void TabStripModel::InsertTabContentsAt(int index, bool foreground, bool inherit_group, bool pinned) { - // Make sure the index maintains that all app tab occurs before non-app tabs. - int first_non_mini_tab = IndexOfFirstNonMiniTab(); - if (contents->is_app() || pinned) - index = std::min(first_non_mini_tab, index); - else - index = std::max(first_non_mini_tab, index); + index = ConstrainInsertionIndex(index, contents->is_app() || pinned); // In tab dragging situations, if the last tab in the window was detached // then the user aborted the drag, we will have the |closing_all_| member @@ -169,11 +164,11 @@ TabContents* TabStripModel::DetachTabContentsAt(int index) { DCHECK(ContainsIndex(index)); TabContents* removed_contents = GetContentsAt(index); - next_selected_index_ = + int next_selected_index = order_controller_->DetermineNewSelectedIndex(index, true); - next_selected_index_ = IndexOfNextNonPhantomTab(next_selected_index_, -1); delete contents_data_.at(index); contents_data_.erase(contents_data_.begin() + index); + next_selected_index = IndexOfNextNonPhantomTab(next_selected_index, -1); if (!HasNonPhantomTabs()) closing_all_ = true; TabStripModelObservers::Iterator iter(observers_); @@ -184,15 +179,13 @@ TabContents* TabStripModel::DetachTabContentsAt(int index) { } if (HasNonPhantomTabs()) { if (index == selected_index_) { - ChangeSelectedContentsFrom(removed_contents, next_selected_index_, - false); + ChangeSelectedContentsFrom(removed_contents, next_selected_index, false); } else if (index < selected_index_) { // The selected tab didn't change, but its position shifted; update our // index to continue to point at it. --selected_index_; } } - next_selected_index_ = selected_index_; return removed_contents; } @@ -405,6 +398,10 @@ void TabStripModel::SetTabPinned(int index, bool pinned) { MoveTabContentsAtImpl(index, non_mini_tab_index - 1, false); return; // Don't send TabPinnedStateChanged notification. } + + FOR_EACH_OBSERVER(TabStripModelObserver, observers_, + TabMiniStateChanged(contents_data_[index]->contents, + index)); } // else: the tab was at the boundary and it's position doesn't need to @@ -444,6 +441,11 @@ int TabStripModel::IndexOfFirstNonMiniTab() const { return count(); } +int TabStripModel::ConstrainInsertionIndex(int index, bool mini_tab) { + return mini_tab ? std::min(std::max(0, index), IndexOfFirstNonMiniTab()) : + std::min(count(), std::max(index, IndexOfFirstNonMiniTab())); +} + void TabStripModel::AddTabContents(TabContents* contents, int index, bool force_index, @@ -547,8 +549,7 @@ bool TabStripModel::IsContextMenuCommandEnabled( switch (command_id) { case CommandNewTab: case CommandCloseTab: - // Phantom tabs can't be closed. - return !IsPhantomTab(context_index); + return true; case CommandReload: if (TabContents* contents = GetTabContentsAt(context_index)) { return contents->delegate()->CanReloadContents(contents); @@ -858,6 +859,9 @@ int TabStripModel::IndexOfNextNonPhantomTab(int index, bool TabStripModel::ShouldMakePhantomOnClose(int index) { if (IsTabPinned(index) && !IsPhantomTab(index) && !closing_all_ && profile()) { + if (!IsAppTab(index)) + return true; // Always make non-app tabs go phantom. + ExtensionsService* extension_service = profile()->GetExtensionsService(); if (!extension_service) return false; diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index 8c6f546..67a5243 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -105,8 +105,17 @@ class TabStripModelObserver { // Invoked when the mini state of a tab changes. This is not invoked if the // tab ends up moving as a result of the mini state changing. + // See note in TabMiniStateChanged as to how this relates to + // TabMiniStateChanged. virtual void TabPinnedStateChanged(TabContents* contents, int index) {} + // Invoked if the mini state of a tab changes. This is not invoked if the + // tab ends up moving as a result of the mini state changing. + // NOTE: this is sent when the pinned state of a non-app tab changes and is + // sent in addition to TabPinnedStateChanged. UI code typically need not care + // about TabPinnedStateChanged, but instead this. + virtual void TabMiniStateChanged(TabContents* contents, int index) {} + // Invoked when the blocked state of a tab changes. // NOTE: This is invoked when a tab becomes blocked/unblocked by a tab modal // window. @@ -294,9 +303,6 @@ class TabStripModel : public NotificationObserver { // Retrieve the index of the currently selected TabContents. int selected_index() const { return selected_index_; } - // See documentation for |next_selected_index_| below. - int next_selected_index() const { return next_selected_index_; } - // Returns true if the tabstrip is currently closing all open tabs (via a // call to CloseAllTabs). As tabs close, the selection in the tabstrip // changes which notifies observers, which can use this as an optimization to @@ -490,6 +496,13 @@ class TabStripModel : public NotificationObserver { // mini-tabs. int IndexOfFirstNonMiniTab() const; + // Returns a valid index for inserting a new tab into this model. |index| is + // the proposed index and |mini_tab| is true if inserting a tab will become + // mini (pinned or app). If |mini_tab| is true, the returned index is between + // 0 and IndexOfFirstNonMiniTab. If |mini_tab| is false, the returned index + // is between IndexOfFirstNonMiniTab and count(). + int ConstrainInsertionIndex(int index, bool mini_tab); + // Command level API ///////////////////////////////////////////////////////// // Adds a TabContents at the best position in the TabStripModel given the @@ -702,14 +715,6 @@ class TabStripModel : public NotificationObserver { // The index of the TabContents in |contents_| that is currently selected. int selected_index_; - // The index of the TabContnets in |contents_| that will be selected when the - // current composite operation completes. A Tab Detach is an example of a - // composite operation - it not only removes a tab from the strip, but also - // causes the selection to shift. Some code needs to know what the next - // selected index will be. In other cases, this value is equal to - // selected_index_. - int next_selected_index_; - // A profile associated with this TabStripModel, used when creating new Tabs. Profile* profile_; diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc index 96dcaae..576815f 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/views/tabs/dragged_tab_controller.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -12,6 +12,7 @@ #include "app/gfx/canvas.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" +#include "base/keyboard_codes.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -34,18 +35,12 @@ #include "views/widget/widget_win.h" #endif -static const int kHorizontalMoveThreshold = 16; // pixels - -// Threshold for pinned tabs. -static const int kHorizontalPinnedMoveThreshold = 4; // pixels - -// Amount, in pixels, from the edge of the tab strip that causes a non-pinned -// tab to be pinned. See description of pin_timer_ for details. -static const int kHorizontalPinTabOffset = 16; +#if defined(OS_LINUX) +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> +#endif -// Delay, in ms, between when the user drags a tab to the edge of the tab strip -// and when the tab becomes pinned. See description of pin_timer_ for details. -static const int kPinTabDelay = 300; +static const int kHorizontalMoveThreshold = 16; // pixels namespace { @@ -324,7 +319,8 @@ DraggedTabController::DraggedTabController(Tab* source_tab, old_focused_view_(NULL), in_destructor_(false), last_move_screen_x_(0), - was_pinned_(source_tabstrip->model()->IsTabPinned(source_model_index_)) { + mini_(source_tabstrip->model()->IsMiniTab(source_model_index_)), + pinned_(source_tabstrip->model()->IsTabPinned(source_model_index_)) { SetDraggedContents( source_tabstrip_->model()->GetTabContentsAt(source_model_index_)); // Listen for Esc key presses. @@ -351,7 +347,6 @@ void DraggedTabController::CaptureDragInfo(const gfx::Point& mouse_offset) { void DraggedTabController::Drag() { bring_to_front_timer_.Stop(); - pin_timer_.Stop(); // Before we get to dragging anywhere, ensure that we consider ourselves // attached to the source tabstrip. @@ -493,7 +488,10 @@ void DraggedTabController::WillProcessEvent(GdkEvent* event) { } void DraggedTabController::DidProcessEvent(GdkEvent* event) { - NOTIMPLEMENTED(); + if (event->type == GDK_KEY_PRESS && + reinterpret_cast<GdkEventKey*>(event)->keyval == GDK_Escape) { + EndDrag(true); + } } #endif @@ -623,7 +621,7 @@ void DraggedTabController::ContinueDragging() { gfx::Point screen_point = GetCursorScreenPoint(); // TODO(sky): make this define OS_CHROMEOS when we merge views and chromeos. -#if defined(OS_LINUX) +#if defined(OS_CHROMEOS) // We don't allow detaching in chrome os. TabStrip* target_tabstrip = source_tabstrip_; #else @@ -657,39 +655,27 @@ void DraggedTabController::MoveTab(const gfx::Point& screen_point) { if (attached_tabstrip_) { TabStripModel* attached_model = attached_tabstrip_->model(); int from_index = attached_model->GetIndexOfTabContents(dragged_contents_); - AdjustDragPointForPinnedTabs(screen_point, &from_index, - &dragged_view_point); // Determine the horizontal move threshold. This is dependent on the width // of tabs. The smaller the tabs compared to the standard size, the smaller // the threshold. - int threshold = kHorizontalPinnedMoveThreshold; - if (!view_->pinned()) { - double unselected, selected; - attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected); - double ratio = unselected / Tab::GetStandardSize().width(); - threshold = static_cast<int>(ratio * kHorizontalMoveThreshold); - } + double unselected, selected; + attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected); + double ratio = unselected / Tab::GetStandardSize().width(); + int threshold = static_cast<int>(ratio * kHorizontalMoveThreshold); // Update the model, moving the TabContents from one index to another. Do // this only if we have moved a minimum distance since the last reorder (to // prevent jitter). if (abs(screen_point.x() - last_move_screen_x_) > threshold) { gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_point); - int to_index = GetInsertionIndexForDraggedBounds(bounds); + int to_index = GetInsertionIndexForDraggedBounds(bounds, true); to_index = NormalizeIndexToAttachedTabStrip(to_index); - if (!view_->pinned()) { - // If the dragged tab isn't pinned, don't allow the drag to a pinned - // tab. - to_index = std::max(to_index, attached_model->IndexOfFirstNonMiniTab()); - } if (from_index != to_index) { last_move_screen_x_ = screen_point.x(); attached_model->MoveTabContentsAt(from_index, to_index, true); } } - - StartPinTimerIfNecessary(screen_point); } // Move the View. There are no changes to the model if we're detached. view_->MoveTo(dragged_view_point); @@ -716,97 +702,6 @@ DockInfo DraggedTabController::GetDockInfoAtPoint( return info; } -void DraggedTabController::MakeDraggedTabPinned() { - MakeDraggedTabPinned(0); -} - -void DraggedTabController::MakeDraggedTabPinned(int tab_index) { - DCHECK(view_.get()); - DCHECK(!view_->pinned()); - - // Mark the tab as pinned and update the model. - view_->set_pinned(true); - attached_tabstrip_->model()->SetTabPinned(tab_index, true); - - // Reset the hotspot (mouse_offset_) for the dragged tab. Otherwise the - // dragged tab may be nowhere near the mouse. - mouse_offset_.set_x(Tab::GetPinnedWidth() / 2 - 1); - UpdateWindowCreatePoint(); - view_->set_mouse_tab_offset(mouse_offset_); - - // Resize the dragged tab. - view_->Resize(Tab::GetPinnedWidth()); -} - -void DraggedTabController::StartPinTimerIfNecessary( - const gfx::Point& screen_point) { - if (view_->pinned()) - return; - - TabStripModel* attached_model = attached_tabstrip_->model(); - int app_count = attached_model->IndexOfFirstNonMiniTab(); - if (app_count > 0) - return; - - int index = attached_model->GetIndexOfTabContents(dragged_contents_); - if (index != 0) - return; - - gfx::Point local_point = - ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point); - if (local_point.x() > kHorizontalPinTabOffset) - return; - - pin_timer_.Start( - base::TimeDelta::FromMilliseconds(kPinTabDelay), this, - &DraggedTabController::MakeDraggedTabPinned); -} - -void DraggedTabController::AdjustDragPointForPinnedTabs( - const gfx::Point& screen_point, - int* from_index, - gfx::Point* dragged_tab_point) { - TabStripModel* attached_model = attached_tabstrip_->model(); - int pinned_count = attached_model->IndexOfFirstNonMiniTab(); - if (pinned_count == 0) - return; - - gfx::Point local_point = - ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point); - int pinned_threshold = GetPinnedThreshold(); - if (!view_->pinned()) { - gfx::Rect tab_bounds = attached_tabstrip_->GetIdealBounds(pinned_count); - if (local_point.x() <= pinned_threshold) { - // The mouse was moved below the threshold that triggers the tab to be - // pinned. - MakeDraggedTabPinned(*from_index); - - // The dragged tab point was calculated using the old mouse_offset, which - // we just reset. Recalculate it. - *dragged_tab_point = GetDraggedViewPoint(screen_point); - } else if (local_point.x() - mouse_offset_.x() < tab_bounds.x()) { - // The mouse has not moved below the threshold that triggers the tab to - // be pinned. Make sure the dragged tab does not go before the first - // non-pinned tab. - gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_); - dragged_tab_point->set_x(std::max(dragged_tab_point->x(), - tabstrip_bounds.x() + tab_bounds.x())); - } - } else if (local_point.x() > pinned_threshold) { - // The mouse has moved past the point that triggers the tab to be unpinned. - // Update the dragged tab and model accordingly. - view_->set_pinned(false); - attached_model->SetTabPinned(*from_index, false); - - // Changing the tabs pinned state may have forced it to move (as can happen - // if the user rapidly drags a pinned tab past other pinned tabs). Update - // the from_index. - *from_index = attached_model->GetIndexOfTabContents(dragged_contents_); - - view_->Resize(view_->tab_width()); - } -} - TabStrip* DraggedTabController::GetTabStripForPoint( const gfx::Point& screen_point) { gfx::NativeView dragged_view = view_->GetWidget()->GetNativeView(); @@ -867,37 +762,15 @@ void DraggedTabController::Attach(TabStrip* attached_tabstrip, // the dragged representation will be a different size to others in the // TabStrip. int tab_count = attached_tabstrip_->GetTabCount(); - int pinned_tab_count = attached_tabstrip_->GetPinnedTabCount(); + int mini_tab_count = attached_tabstrip_->GetMiniTabCount(); if (!tab) ++tab_count; double unselected_width, selected_width = 0; - attached_tabstrip_->GetDesiredTabWidths(tab_count, pinned_tab_count, + attached_tabstrip_->GetDesiredTabWidths(tab_count, mini_tab_count, &unselected_width, &selected_width); EnsureDraggedView(); - int dragged_tab_width = static_cast<int>(selected_width); - view_->set_tab_width(dragged_tab_width); - bool pinned = false; - if (pinned_tab_count > 0) { - int insert_index; - if (tab && tab->IsVisible()) { - // Initial call to Attach. Don't use the screen_point as it's 0,0. - insert_index = source_model_index_; - } else { - gfx::Point client_point = - ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point); - insert_index = GetInsertionIndexForDraggedBounds( - gfx::Rect(client_point, gfx::Size(1, 1))); - insert_index = std::max( - std::min(insert_index, attached_tabstrip_->model()->count()), 0); - } - if (insert_index < pinned_tab_count) { - // New tab is going to be pinned, use the pinned size for the dragged - // tab. - dragged_tab_width = Tab::GetPinnedWidth(); - pinned = true; - } - } - view_->set_pinned(pinned); + int dragged_tab_width = + mini_ ? Tab::GetMiniWidth() : static_cast<int>(selected_width); view_->Attach(dragged_tab_width); if (!tab) { @@ -927,10 +800,9 @@ void DraggedTabController::Attach(TabStrip* attached_tabstrip, // strip. ("ideal bounds" are stable even if the Tabs' actual bounds are // changing due to animation). gfx::Rect bounds = GetDraggedViewTabStripBounds(screen_point); - int index = GetInsertionIndexForDraggedBounds(bounds); - index = std::max(std::min(index, attached_tabstrip_->model()->count()), 0); + int index = GetInsertionIndexForDraggedBounds(bounds, false); attached_tabstrip_->model()->InsertTabContentsAt(index, dragged_contents_, - true, false); + true, false, pinned_); tab = GetTabMatchingDraggedContents(attached_tabstrip_); } @@ -980,23 +852,9 @@ void DraggedTabController::Detach() { attached_tabstrip_ = NULL; } -int DraggedTabController::GetPinnedThreshold() { - int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonMiniTab(); - if (pinned_count == 0) - return 0; - if (!view_->pinned()) { - gfx::Rect non_pinned_bounds = - attached_tabstrip_->GetIdealBounds(pinned_count); - return non_pinned_bounds.x() + Tab::GetPinnedWidth() / 2; - } - gfx::Rect last_pinned_bounds = - attached_tabstrip_->GetIdealBounds(pinned_count - 1); - return last_pinned_bounds.x() + TabStrip::pinned_to_non_pinned_gap_ + - Tab::GetPinnedWidth() / 2; -} - int DraggedTabController::GetInsertionIndexForDraggedBounds( - const gfx::Rect& dragged_bounds) const { + const gfx::Rect& dragged_bounds, + bool is_tab_attached) const { int right_tab_x = 0; // If the UI layout of the tab strip is right-to-left, we need to mirror the @@ -1012,6 +870,7 @@ int DraggedTabController::GetInsertionIndexForDraggedBounds( adjusted_bounds.set_x( attached_tabstrip_->MirroredLeftPointForRect(adjusted_bounds)); + int index = -1; for (int i = 0; i < attached_tabstrip_->GetTabCount(); ++i) { gfx::Rect ideal_bounds = attached_tabstrip_->GetIdealBounds(i); gfx::Rect left_half = ideal_bounds; @@ -1022,15 +881,27 @@ int DraggedTabController::GetInsertionIndexForDraggedBounds( right_tab_x = right_half.right(); if (adjusted_bounds.x() >= right_half.x() && adjusted_bounds.x() < right_half.right()) { - return i + 1; + index = i + 1; + break; } else if (adjusted_bounds.x() >= left_half.x() && adjusted_bounds.x() < left_half.right()) { - return i; + index = i; + break; } } - if (adjusted_bounds.right() > right_tab_x) - return attached_tabstrip_->model()->count(); - return TabStripModel::kNoTab; + if (index == -1) { + if (adjusted_bounds.right() > right_tab_x) + index = attached_tabstrip_->model()->count(); + else + index = 0; + } + + index = attached_tabstrip_->model()->ConstrainInsertionIndex(index, mini_); + if (is_tab_attached && mini_ && + index == attached_tabstrip_->model()->IndexOfFirstNonMiniTab()) { + index--; + } + return index; } gfx::Rect DraggedTabController::GetDraggedViewTabStripBounds( @@ -1050,6 +921,7 @@ gfx::Point DraggedTabController::GetDraggedViewPoint( // If we're not attached, we just use x and y from above. if (attached_tabstrip_) { gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_); + // Snap the dragged Tab to the TabStrip if we are attached, detaching // only when the mouse position (screen_point) exceeds the screen bounds // of the TabStrip. @@ -1075,8 +947,7 @@ gfx::Point DraggedTabController::GetDraggedViewPoint( (tabstrip_bounds.bottom() + vertical_drag_magnetism)) { y = max_y; } - // TODO(sky): make this define OS_CHROMEOS when we merge views and - // chromeos. + #if defined(OS_LINUX) // We currently don't allow detaching on chromeos. This restricts dragging // to the main window. @@ -1101,7 +972,6 @@ bool DraggedTabController::EndDragImpl(EndDragType type) { // the animation finishes, this is invoked twice. The second time through // type == TAB_DESTROYED. - pin_timer_.Stop(); bring_to_front_timer_.Stop(); // Hide the current dock controllers. @@ -1165,7 +1035,7 @@ void DraggedTabController::RevertDrag() { // somehow. attached_tabstrip_ = source_tabstrip_; source_tabstrip_->model()->InsertTabContentsAt(source_model_index_, - dragged_contents_, true, false); + dragged_contents_, true, false, pinned_); } else { // The Tab was moved within the TabStrip where the drag was initiated. // Move it back to the starting location. @@ -1180,9 +1050,8 @@ void DraggedTabController::RevertDrag() { // been attached to any other TabStrip. We need to put it back into the // source TabStrip. source_tabstrip_->model()->InsertTabContentsAt(source_model_index_, - dragged_contents_, true, false); + dragged_contents_, true, false, pinned_); } - source_tabstrip_->model()->SetTabPinned(source_model_index_, was_pinned_); // If we're not attached to any TabStrip, or attached to some other TabStrip, // we need to restore the bounds of the original TabStrip's frame, in case @@ -1276,6 +1145,9 @@ bool DraggedTabController::CompleteDrag() { Browser* new_browser = source_tabstrip_->model()->delegate()->CreateNewStripWithContents( dragged_contents_, window_bounds, dock_info_); + TabStripModel* new_model = new_browser->tabstrip_model(); + new_model->SetTabPinned(new_model->GetIndexOfTabContents(dragged_contents_), + pinned_); new_browser->window()->Show(); CleanUpHiddenFrame(); } @@ -1288,7 +1160,7 @@ void DraggedTabController::EnsureDraggedView() { gfx::Rect tab_bounds; dragged_contents_->GetContainerBounds(&tab_bounds); view_.reset(new DraggedTabView(dragged_contents_, mouse_offset_, - tab_bounds.size())); + tab_bounds.size(), mini_)); } } diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h index c609db6..5ebe6e3 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.h +++ b/chrome/browser/views/tabs/dragged_tab_controller.h @@ -158,29 +158,6 @@ class DraggedTabController : public TabContentsDelegate, // Handles moving the Tab within a TabStrip as well as updating the View. void MoveTab(const gfx::Point& screen_point); - // Cover for MakeDraggedTabPinned(0). This is invoked from the pin_timer_. - void MakeDraggedTabPinned(); - - // Changes the dragged tab from a normal tab to pinned, updating the - // necessary state. - void MakeDraggedTabPinned(int tab_index); - - // If |screen_point| is along the edge of the tab strip and there are no - // pinned tabs in the model, pin_timer_ is started. - void StartPinTimerIfNecessary(const gfx::Point& screen_point); - - // Invoked from |MoveTab| to adjust |dragged_tab_point|. |screen_point| is - // the location of the mouse and |from_index| the index the dragged tab is - // at. - // This updates the pinned state of the dragged tab and model based on the - // location of the mouse. If |screen_point| is before the pinned threshold - // the dragged tab (and model) are pinned. If |screen_point| is after the - // pinned threshold, the dragged tab is not allowed to go before the first - // non-pinned tab and the dragged tab (and model) are marked as non-pinned. - void AdjustDragPointForPinnedTabs(const gfx::Point& screen_point, - int* from_index, - gfx::Point* dragged_tab_point); - // Returns the compatible TabStrip that is under the specified point (screen // coordinates), or NULL if there is none. TabStrip* GetTabStripForPoint(const gfx::Point& screen_point); @@ -198,16 +175,12 @@ class DraggedTabController : public TabContentsDelegate, // Detach the dragged Tab from the current TabStrip. void Detach(); - // Returns the horizontal location (relative to the tabstrip) at which the - // dragged tab is pinned. That is, if the current x location is < then the - // return value of this the dragged tab and model should be made pinned, - // otherwise the dragged tab and model should not be pinned. - int GetPinnedThreshold(); - // Returns the index where the dragged TabContents should be inserted into // the attached TabStripModel given the DraggedTabView's bounds // |dragged_bounds| in coordinates relative to the attached TabStrip. - int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds) const; + // |is_tab_attached| is true if the tab has already been added. + int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds, + bool is_tab_attached) const; // Retrieve the bounds of the DraggedTabView, relative to the attached // TabStrip, given location of the dragged tab in screen coordinates. @@ -340,20 +313,17 @@ class DraggedTabController : public TabContentsDelegate, DockWindows dock_windows_; std::vector<DockDisplayer*> dock_controllers_; - // Was the tab originally pinned? Used if we end up reverting the drag. - const bool was_pinned_; + // Is the tab mini? + const bool mini_; + + // Is the tab pinned? + const bool pinned_; // Timer used to bring the window under the cursor to front. If the user // stops moving the mouse for a brief time over a browser window, it is // brought to front. base::OneShotTimer<DraggedTabController> bring_to_front_timer_; - // Timer used to pin the first tab. When the user drags a tab to the first - // tab in the tab strip this timer is started. If the user doesn't move the - // mouse, the tab is pinned. This timer invokes MakeDraggedTabPinned when it - // fires. - base::OneShotTimer<DraggedTabController> pin_timer_; - DISALLOW_COPY_AND_ASSIGN(DraggedTabController); }; diff --git a/chrome/browser/views/tabs/dragged_tab_view.cc b/chrome/browser/views/tabs/dragged_tab_view.cc index 5cd7531..2f95971c 100644 --- a/chrome/browser/views/tabs/dragged_tab_view.cc +++ b/chrome/browser/views/tabs/dragged_tab_view.cc @@ -30,7 +30,8 @@ static const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162); DraggedTabView::DraggedTabView(TabContents* datasource, const gfx::Point& mouse_tab_offset, - const gfx::Size& contents_size) + const gfx::Size& contents_size, + bool mini) : renderer_(new TabRenderer), attached_(false), show_contents_on_drag_(true), @@ -38,11 +39,11 @@ DraggedTabView::DraggedTabView(TabContents* datasource, attached_tab_size_(TabRenderer::GetMinimumSelectedSize()), photobooth_(NULL), contents_size_(contents_size), - close_animation_(this), - tab_width_(0) { + close_animation_(this) { set_parent_owned(false); renderer_->UpdateData(datasource, false, false); + renderer_->set_mini(mini); #if defined(OS_WIN) container_.reset(new views::WidgetWin); @@ -121,23 +122,7 @@ void DraggedTabView::Resize(int width) { Update(); } -void DraggedTabView::set_pinned(bool pinned) { - renderer_->set_pinned(pinned); -} - -bool DraggedTabView::pinned() const { - return renderer_->pinned(); -} - void DraggedTabView::Detach(NativeViewPhotobooth* photobooth) { - // Detached tabs are never pinned. - renderer_->set_pinned(false); - - if (attached_tab_size_.width() != tab_width_) { - // The attached tab size differs from current tab size. Resize accordingly. - Resize(tab_width_); - } - attached_ = false; photobooth_ = photobooth; #if defined(OS_WIN) diff --git a/chrome/browser/views/tabs/dragged_tab_view.h b/chrome/browser/views/tabs/dragged_tab_view.h index 1c212b6..c640df3 100644 --- a/chrome/browser/views/tabs/dragged_tab_view.h +++ b/chrome/browser/views/tabs/dragged_tab_view.h @@ -33,7 +33,8 @@ class DraggedTabView : public views::View, public: DraggedTabView(TabContents* datasource, const gfx::Point& mouse_tab_offset, - const gfx::Size& contents_size); + const gfx::Size& contents_size, + bool mini); virtual ~DraggedTabView(); // Moves the DraggedTabView to the appropriate location given the mouse @@ -45,23 +46,12 @@ class DraggedTabView : public views::View, mouse_tab_offset_ = offset; } - // Sets the non-pinned tab width. The actual width of the dragged tab is the - // value last past to Attach or Resize. |tab_width| is used when Detach is - // invoked (which triggers resizing to |tab_width|), or when dragging within - // a tab strip and the dragged tab changes state from pinned to non-pinned. - void set_tab_width(int tab_width) { tab_width_ = tab_width; } - int tab_width() const { return tab_width_; } - // Notifies the DraggedTabView that it has become attached to a TabStrip. void Attach(int selected_width); // Resizes the dragged tab to a width of |width|. void Resize(int width); - // Sets whether the tab is rendered pinned or not. - void set_pinned(bool pinned); - bool pinned() const; - // Notifies the DraggedTabView that it has been detached from a TabStrip. void Detach(NativeViewPhotobooth* photobooth); @@ -146,9 +136,6 @@ class DraggedTabView : public views::View, gfx::Rect animation_start_bounds_; gfx::Rect animation_end_bounds_; - // Non-pinned tab width. See description above setter for how this is used. - int tab_width_; - DISALLOW_COPY_AND_ASSIGN(DraggedTabView); }; diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc index efebda1..e65fb16 100644 --- a/chrome/browser/views/tabs/tab.cc +++ b/chrome/browser/views/tabs/tab.cc @@ -53,7 +53,7 @@ class Tab::TabContextMenuContents : public menus::SimpleMenuModel::Delegate { virtual bool IsCommandIdChecked(int command_id) const { if (!tab_ || command_id != TabStripModel::CommandTogglePinned) return false; - return tab_->pinned(); + return tab_->delegate()->IsTabPinned(tab_); } virtual bool IsCommandIdEnabled(int command_id) const { return tab_ && tab_->delegate()->IsCommandEnabledForTab( diff --git a/chrome/browser/views/tabs/tab.h b/chrome/browser/views/tabs/tab.h index 303a80a..a5638f7 100644 --- a/chrome/browser/views/tabs/tab.h +++ b/chrome/browser/views/tabs/tab.h @@ -33,6 +33,9 @@ class Tab : public TabRenderer, // Returns true if the specified Tab is selected. virtual bool IsTabSelected(const Tab* tab) const = 0; + // Returns true if the specified Tab is pinned. + virtual bool IsTabPinned(const Tab* tab) const = 0; + // Selects the specified Tab. virtual void SelectTab(Tab* tab) = 0; diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc index 34bee57..169f46d 100644 --- a/chrome/browser/views/tabs/tab_renderer.cc +++ b/chrome/browser/views/tabs/tab_renderer.cc @@ -43,12 +43,12 @@ static const int kStandardTitleWidth = 175; static const int kCloseButtonVertFuzz = 0; static const int kCloseButtonHorzFuzz = 5; static const int kSelectedTitleColor = SK_ColorBLACK; -// When a non-pinned tab is pinned the width of the tab animates. If the width -// of a pinned tab is >= kPinnedTabRendererAsTabWidth then the tab is rendered -// as a normal tab. This is done to avoid having the title immediately -// disappear when transitioning a tab from normal to pinned. -static const int kPinnedTabRendererAsTabWidth = - browser_defaults::kPinnedTabWidth + 30; +// When a non-mini-tab becomes a mini-tab the width of the tab animates. If +// the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab +// is rendered as a normal tab. This is done to avoid having the title +// immediately disappear when transitioning a tab from normal to mini-tab. +static const int kMiniTabRendererAsNormalTabWidth = + browser_defaults::kMiniTabWidth + 30; // How long the hover state takes. static const int kHoverDurationMs = 90; @@ -80,11 +80,11 @@ TabRenderer::TabImage TabRenderer::tab_alpha = {0}; TabRenderer::TabImage TabRenderer::tab_active = {0}; TabRenderer::TabImage TabRenderer::tab_inactive = {0}; -// Max opacity for the pinned tab title change animation. -const double kPinnedThrobOpacity = 0.75; +// Max opacity for the mini-tab title change animation. +const double kMiniTitleChangeThrobOpacity = 0.75; -// Duration for when the title of an inactive pinned tab changes. -const int kPinnedDuration = 1000; +// Duration for when the title of an inactive mini-tab changes. +const int kMiniTitleChangeThrobDuration = 1000; namespace { @@ -255,11 +255,6 @@ TabRenderer::TabRenderer() theme_provider_(NULL) { InitResources(); - data_.blocked = false; - data_.pinned = false; - data_.animating_pinned_change = false; - data_.phantom = false; - // Add the Close Button. close_button_ = new TabCloseButton(this); close_button_->SetImage(views::CustomButton::BS_NORMAL, close_button_n); @@ -330,8 +325,8 @@ void TabRenderer::UpdateFromModel() { } } -void TabRenderer::set_animating_pinned_change(bool value) { - data_.animating_pinned_change = value; +void TabRenderer::set_animating_mini_change(bool value) { + data_.animating_mini_change = value; } bool TabRenderer::IsSelected() const { @@ -374,26 +369,26 @@ void TabRenderer::StopPulse() { pulse_animation_->Stop(); } -void TabRenderer::StartPinnedTabTitleAnimation() { - if (!pinned_title_animation_.get()) { - pinned_title_animation_.reset(new ThrobAnimation(this)); - pinned_title_animation_->SetThrobDuration(kPinnedDuration); +void TabRenderer::StartMiniTabTitleAnimation() { + if (!mini_title_animation_.get()) { + mini_title_animation_.reset(new ThrobAnimation(this)); + mini_title_animation_->SetThrobDuration(kMiniTitleChangeThrobDuration); } - if (!pinned_title_animation_->IsAnimating()) { - pinned_title_animation_->StartThrobbing(2); - } else if (pinned_title_animation_->cycles_remaining() <= 2) { + if (!mini_title_animation_->IsAnimating()) { + mini_title_animation_->StartThrobbing(2); + } else if (mini_title_animation_->cycles_remaining() <= 2) { // The title changed while we're already animating. Add at most one more // cycle. This is done in an attempt to smooth out pages that continuously // change the title. - pinned_title_animation_->set_cycles_remaining( - pinned_title_animation_->cycles_remaining() + 2); + mini_title_animation_->set_cycles_remaining( + mini_title_animation_->cycles_remaining() + 2); } } -void TabRenderer::StopPinnedTabTitleAnimation() { - if (pinned_title_animation_.get()) - pinned_title_animation_->Stop(); +void TabRenderer::StopMiniTabTitleAnimation() { + if (mini_title_animation_.get()) + mini_title_animation_->Stop(); } // static @@ -424,8 +419,8 @@ gfx::Size TabRenderer::GetStandardSize() { } // static -int TabRenderer::GetPinnedWidth() { - return browser_defaults::kPinnedTabWidth; +int TabRenderer::GetMiniWidth() { + return browser_defaults::kMiniTabWidth; } //////////////////////////////////////////////////////////////////////////////// @@ -451,7 +446,7 @@ void TabRenderer::OnMouseExited(const views::MouseEvent& e) { void TabRenderer::Paint(gfx::Canvas* canvas) { // Don't paint if we're narrower than we can render correctly. (This should // only happen during animations). - if (width() < GetMinimumUnselectedSize().width() && !pinned()) + if (width() < GetMinimumUnselectedSize().width() && !mini()) return; // See if the model changes whether the icons should be painted. @@ -469,7 +464,7 @@ void TabRenderer::Paint(gfx::Canvas* canvas) { BrowserThemeProvider::COLOR_TAB_TEXT : BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT); - if (!pinned() || width() > kPinnedTabRendererAsTabWidth) + if (!mini() || width() > kMiniTabRendererAsNormalTabWidth) PaintTitle(title_color, canvas); if (show_icon) @@ -499,15 +494,17 @@ void TabRenderer::Layout() { if (showing_icon_) { int favicon_top = kTopPadding + (content_height - kFavIconSize) / 2; favicon_bounds_.SetRect(lb.x(), favicon_top, kFavIconSize, kFavIconSize); - if ((pinned() || data_.animating_pinned_change) && - width() < kPinnedTabRendererAsTabWidth) { - int pin_delta = kPinnedTabRendererAsTabWidth - GetPinnedWidth(); - int ideal_delta = width() - GetPinnedWidth(); - if (ideal_delta < pin_delta) { - int ideal_x = (GetPinnedWidth() - kFavIconSize) / 2; + if ((mini() || data_.animating_mini_change) && + width() < kMiniTabRendererAsNormalTabWidth) { + // Adjust the location of the favicon when transitioning from a normal + // tab to a mini-tab. + int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth(); + int ideal_delta = width() - GetMiniWidth(); + if (ideal_delta < mini_delta) { + int ideal_x = (GetMiniWidth() - kFavIconSize) / 2; int x = favicon_bounds_.x() + static_cast<int>( (1 - static_cast<float>(ideal_delta) / - static_cast<float>(pin_delta)) * + static_cast<float>(mini_delta)) * (ideal_x - favicon_bounds_.x())); favicon_bounds_.set_x(x); } @@ -535,7 +532,7 @@ void TabRenderer::Layout() { int title_left = favicon_bounds_.right() + kFavIconTitleSpacing; int title_top = kTopPadding + (content_height - title_font_height) / 2; // Size the Title text to fill the remaining space. - if (!pinned() || width() >= kPinnedTabRendererAsTabWidth) { + if (!mini() || width() >= kMiniTabRendererAsNormalTabWidth) { // If the user has big fonts, the title will appear rendered too far down // on the y-axis if we use the regular top padding, so we need to adjust it // so that the text appears centered. @@ -793,7 +790,7 @@ void TabRenderer::PaintLoadingAnimation(gfx::Canvas* canvas) { // loading animation also needs to be mirrored if the View's UI layout is // right-to-left. int dst_x; - if (pinned()) { + if (mini()) { dst_x = favicon_bounds_.x(); } else { if (UILayoutIsRightToLeft()) { @@ -814,7 +811,7 @@ int TabRenderer::IconCapacity() const { } bool TabRenderer::ShouldShowIcon() const { - if (pinned() && height() >= GetMinimumUnselectedSize().height()) + if (mini() && height() >= GetMinimumUnselectedSize().height()) return true; if (!data_.show_icon) { return false; @@ -828,15 +825,16 @@ bool TabRenderer::ShouldShowIcon() const { bool TabRenderer::ShouldShowCloseBox() const { // The selected tab never clips close button. - return !pinned() && (IsSelected() || IconCapacity() >= 3); + return !mini() && (IsSelected() || IconCapacity() >= 3); } double TabRenderer::GetThrobValue() { if (pulse_animation_->IsAnimating()) return pulse_animation_->GetCurrentValue() * kHoverOpacity; - if (pinned_title_animation_.get() && pinned_title_animation_->IsAnimating()) - return pinned_title_animation_->GetCurrentValue() * kPinnedThrobOpacity; + if (mini_title_animation_.get() && mini_title_animation_->IsAnimating()) + return mini_title_animation_->GetCurrentValue() * + kMiniTitleChangeThrobOpacity; return hover_animation_.get() ? kHoverOpacity * hover_animation_->GetCurrentValue() : 0; diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h index a5e1d99..ec3e319 100644 --- a/chrome/browser/views/tabs/tab_renderer.h +++ b/chrome/browser/views/tabs/tab_renderer.h @@ -47,20 +47,20 @@ class TabRenderer : public views::View, // See TabStripModel::TabChangedAt documentation for what loading_only means. void UpdateData(TabContents* contents, bool phantom, bool loading_only); - // Sets the pinned state of the tab. + // Sets the blocked state of the tab. void SetBlocked(bool blocked); bool blocked() const { return data_.blocked; } - // Sets the pinned state of the tab. - void set_pinned(bool pinned) { data_.pinned = pinned; } - bool pinned() const { return data_.pinned; } + // Sets the mini-state of the tab. + void set_mini(bool mini) { data_.mini = mini; } + bool mini() const { return data_.mini; } // Sets the phantom state of the tab. void set_phantom(bool phantom) { data_.phantom = phantom; } bool phantom() const { return data_.phantom; } - // Are we in the process of animating a pinned state change on this tab? - void set_animating_pinned_change(bool value); + // Are we in the process of animating a mini tab state change on this tab? + void set_animating_mini_change(bool value); // Updates the display to reflect the contents of this TabRenderer's model. void UpdateFromModel(); @@ -76,9 +76,9 @@ class TabRenderer : public views::View, void StartPulse(); void StopPulse(); - // Start/stop the pinned tab title animation. - void StartPinnedTabTitleAnimation(); - void StopPinnedTabTitleAnimation(); + // Start/stop the mini-tab title animation. + void StartMiniTabTitleAnimation(); + void StopMiniTabTitleAnimation(); // Set the background offset used to match the image in the inactive tab // to the frame image. @@ -103,8 +103,8 @@ class TabRenderer : public views::View, // available. static gfx::Size GetStandardSize(); - // Returns the width for pinned tabs. Pinned tabs always have this width. - static int GetPinnedWidth(); + // Returns the width for mini-tabs. Mini-tabs always have this width. + static int GetMiniWidth(); // Loads the images to be used for the tab background. static void LoadTabImages(); @@ -155,7 +155,6 @@ class TabRenderer : public views::View, void PaintInactiveTabBackground(gfx::Canvas* canvas); void PaintActiveTabBackground(gfx::Canvas* canvas); void PaintHoverTabBackground(gfx::Canvas* canvas, double opacity); - void PaintPinnedTabBackground(gfx::Canvas* canvas); void PaintLoadingAnimation(gfx::Canvas* canvas); // Returns the number of favicon-size elements that can fit in the tab's @@ -170,7 +169,7 @@ class TabRenderer : public views::View, // Gets the throb value for the tab. When a tab is not selected the // active background is drawn at |GetThrobValue()|%. This is used for hover, - // pinned tab title change and pulsing. + // mini tab title change and pulsing. double GetThrobValue(); // The bounds of various sections of the display. @@ -195,22 +194,33 @@ class TabRenderer : public views::View, // Pulse animation. scoped_ptr<ThrobAnimation> pulse_animation_; - // Animation used when the title of an inactive pinned tab changes. - scoped_ptr<ThrobAnimation> pinned_title_animation_; + // Animation used when the title of an inactive mini tab changes. + scoped_ptr<ThrobAnimation> mini_title_animation_; // Model data. We store this here so that we don't need to ask the underlying // model, which is tricky since instances of this object can outlive the // corresponding objects in the underlying model. struct TabData { + TabData() + : loading(false), + crashed(false), + off_the_record(false), + show_icon(true), + mini(false), + blocked(false), + animating_mini_change(false), + phantom(false) { + } + SkBitmap favicon; string16 title; bool loading; bool crashed; bool off_the_record; bool show_icon; - bool pinned; + bool mini; bool blocked; - bool animating_pinned_change; + bool animating_mini_change; bool phantom; }; TabData data_; diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index c3e79b8..6f6e0d0 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -52,6 +52,7 @@ using views::DropTargetEvent; static const int kDefaultAnimationDurationMs = 200; static const int kResizeLayoutAnimationDurationMs = 200; static const int kReorderAnimationDurationMs = 200; +static const int kMiniTabAnimationDurationMs = 200; static const int kNewTabButtonHOffset = -5; static const int kNewTabButtonVOffset = 5; @@ -128,6 +129,8 @@ class TabStrip::TabAnimation : public AnimationDelegate { REMOVE, MOVE, RESIZE, + MINI, + MINI_MOVE }; TabAnimation(TabStrip* tabstrip, Type type) @@ -168,8 +171,8 @@ class TabStrip::TabAnimation : public AnimationDelegate { int index) { Tab* tab = tabstrip->GetTabAt(index); double tab_width; - if (tab->pinned()) { - tab_width = Tab::GetPinnedWidth(); + if (tab->mini()) { + tab_width = Tab::GetMiniWidth(); } else { double unselected, selected; tabstrip->GetCurrentTabWidths(&unselected, &selected); @@ -219,9 +222,9 @@ class TabStrip::TabAnimation : public AnimationDelegate { // Figure out the desired start and end widths for the specified pre- and // post- animation tab counts. void GenerateStartAndEndWidths(int start_tab_count, int end_tab_count, - int start_pinned_count, - int end_pinned_count) { - tabstrip_->GetDesiredTabWidths(start_tab_count, start_pinned_count, + int start_mini_count, + int end_mini_count) { + tabstrip_->GetDesiredTabWidths(start_tab_count, start_mini_count, &start_unselected_width_, &start_selected_width_); double standard_tab_width = @@ -233,7 +236,7 @@ class TabStrip::TabAnimation : public AnimationDelegate { start_unselected_width_ -= minimum_tab_width / start_tab_count; } tabstrip_->GenerateIdealBounds(); - tabstrip_->GetDesiredTabWidths(end_tab_count, end_pinned_count, + tabstrip_->GetDesiredTabWidths(end_tab_count, end_mini_count, &end_unselected_width_, &end_selected_width_); } @@ -282,12 +285,12 @@ class TabStrip::InsertTabAnimation : public TabStrip::TabAnimation { : TabAnimation(tabstrip, INSERT), index_(index) { int tab_count = tabstrip->GetTabCount(); - int end_pinned_count = tabstrip->GetPinnedTabCount(); - int start_pinned_count = end_pinned_count; - if (index < end_pinned_count) - start_pinned_count--; - GenerateStartAndEndWidths(tab_count - 1, tab_count, start_pinned_count, - end_pinned_count); + int end_mini_count = tabstrip->GetMiniTabCount(); + int start_mini_count = end_mini_count; + if (index < end_mini_count) + start_mini_count--; + GenerateStartAndEndWidths(tab_count - 1, tab_count, start_mini_count, + end_mini_count); } virtual ~InsertTabAnimation() {} @@ -297,9 +300,9 @@ class TabStrip::InsertTabAnimation : public TabStrip::TabAnimation { if (index == index_) { bool is_selected = tabstrip_->model()->selected_index() == index; double start_width, target_width; - if (index < tabstrip_->GetPinnedTabCount()) { + if (index < tabstrip_->GetMiniTabCount()) { start_width = Tab::GetMinimumSelectedSize().width(); - target_width = Tab::GetPinnedWidth(); + target_width = Tab::GetMiniWidth(); } else { target_width = is_selected ? end_unselected_width_ : end_selected_width_; @@ -313,8 +316,8 @@ class TabStrip::InsertTabAnimation : public TabStrip::TabAnimation { return start_width; } - if (tabstrip_->GetTabAt(index)->pinned()) - return Tab::GetPinnedWidth(); + if (tabstrip_->GetTabAt(index)->mini()) + return Tab::GetMiniWidth(); if (tabstrip_->GetTabAt(index)->IsSelected()) { double delta = end_selected_width_ - start_selected_width_; @@ -340,20 +343,23 @@ class TabStrip::RemoveTabAnimation : public TabStrip::TabAnimation { : TabAnimation(tabstrip, REMOVE), index_(index) { int tab_count = tabstrip->GetTabCount(); - int start_pinned_count = tabstrip->GetPinnedTabCount(); - int end_pinned_count = start_pinned_count; - if (index < start_pinned_count) - end_pinned_count--; - GenerateStartAndEndWidths(tab_count, tab_count - 1, start_pinned_count, - end_pinned_count); - // If the last non-pinned tab is being removed we force a layout on + int start_mini_count = tabstrip->GetMiniTabCount(); + int end_mini_count = start_mini_count; + if (index < start_mini_count) + end_mini_count--; + GenerateStartAndEndWidths(tab_count, tab_count - 1, start_mini_count, + end_mini_count); + // If the last non-mini-tab is being removed we force a layout on // completion. This is necessary as the value returned by GetTabHOffset // changes once the tab is actually removed (which happens at the end of // the animation), and unless we layout GetTabHOffset won't be called after // the removal. - set_layout_on_completion(start_pinned_count > 0 && - start_pinned_count == end_pinned_count && - tab_count == start_pinned_count + 1); + // We do the same when the last mini-tab is being removed for the same + // reason. + set_layout_on_completion(start_mini_count > 0 && + (end_mini_count == 0 || + (start_mini_count == end_mini_count && + tab_count == start_mini_count + 1))); } // Returns the index of the tab being removed. @@ -370,8 +376,8 @@ class TabStrip::RemoveTabAnimation : public TabStrip::TabAnimation { // The tab(s) being removed are gradually shrunken depending on the state // of the animation. // Removed animated Tabs are never selected. - if (tab->pinned()) - return AnimationPosition(Tab::GetPinnedWidth(), -kTabHOffset); + if (tab->mini()) + return AnimationPosition(Tab::GetMiniWidth(), -kTabHOffset); double start_width = start_unselected_width_; // Make sure target_width is at least abs(kTabHOffset), otherwise if @@ -382,8 +388,8 @@ class TabStrip::RemoveTabAnimation : public TabStrip::TabAnimation { return AnimationPosition(start_width, target_width); } - if (tab->pinned()) - return Tab::GetPinnedWidth(); + if (tab->mini()) + return Tab::GetMiniWidth(); if (tabstrip_->available_width_for_tabs_ != -1 && index_ != tabstrip_->GetTabCount() - 1) { @@ -503,9 +509,9 @@ class TabStrip::ResizeLayoutAnimation : public TabStrip::TabAnimation { explicit ResizeLayoutAnimation(TabStrip* tabstrip) : TabAnimation(tabstrip, RESIZE) { int tab_count = tabstrip->GetTabCount(); - int pinned_tab_count = tabstrip->GetPinnedTabCount(); - GenerateStartAndEndWidths(tab_count, tab_count, pinned_tab_count, - pinned_tab_count); + int mini_tab_count = tabstrip->GetMiniTabCount(); + GenerateStartAndEndWidths(tab_count, tab_count, mini_tab_count, + mini_tab_count); InitStartState(); } virtual ~ResizeLayoutAnimation() { @@ -525,8 +531,8 @@ class TabStrip::ResizeLayoutAnimation : public TabStrip::TabAnimation { virtual double GetWidthForTab(int index) const { Tab* tab = tabstrip_->GetTabAt(index); - if (tab->pinned()) - return Tab::GetPinnedWidth(); + if (tab->mini()) + return Tab::GetMiniWidth(); if (tab->IsSelected()) return AnimationPosition(start_selected_width_, end_selected_width_); @@ -542,7 +548,7 @@ class TabStrip::ResizeLayoutAnimation : public TabStrip::TabAnimation { void InitStartState() { for (int i = 0; i < tabstrip_->GetTabCount(); ++i) { Tab* current_tab = tabstrip_->GetTabAt(i); - if (!current_tab->pinned()) { + if (!current_tab->mini()) { if (current_tab->IsSelected()) { start_selected_width_ = current_tab->width(); } else { @@ -555,11 +561,167 @@ class TabStrip::ResizeLayoutAnimation : public TabStrip::TabAnimation { DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation); }; +// Handles a tabs mini-state changing while the tab does not change position +// in the model. +class TabStrip::MiniTabAnimation : public TabStrip::TabAnimation { + public: + explicit MiniTabAnimation(TabStrip* tabstrip, int index) + : TabAnimation(tabstrip, MINI), + index_(index) { + int tab_count = tabstrip->GetTabCount(); + int start_mini_count = tabstrip->GetMiniTabCount(); + int end_mini_count = start_mini_count; + if (tabstrip->GetTabAt(index)->mini()) + start_mini_count--; + else + start_mini_count++; + tabstrip_->GetTabAt(index)->set_animating_mini_change(true); + GenerateStartAndEndWidths(tab_count, tab_count, start_mini_count, + end_mini_count); + } + + protected: + // Overridden from TabStrip::TabAnimation: + virtual int GetDuration() const { + return kMiniTabAnimationDurationMs; + } + + virtual double GetWidthForTab(int index) const { + Tab* tab = tabstrip_->GetTabAt(index); + + if (index == index_) { + if (tab->mini()) { + return AnimationPosition( + start_selected_width_, + static_cast<double>(Tab::GetMiniWidth())); + } else { + return AnimationPosition(static_cast<double>(Tab::GetMiniWidth()), + end_selected_width_); + } + } else if (tab->mini()) { + return Tab::GetMiniWidth(); + } + + if (tab->IsSelected()) + return AnimationPosition(start_selected_width_, end_selected_width_); + + return AnimationPosition(start_unselected_width_, end_unselected_width_); + } + + private: + // Index of the tab whose mini state changed. + int index_; + + DISALLOW_COPY_AND_ASSIGN(MiniTabAnimation); +}; + +//////////////////////////////////////////////////////////////////////////////// + +// Handles the animation when a tabs mini state changes and the tab moves as a +// result. +class TabStrip::MiniMoveAnimation : public TabStrip::TabAnimation { + public: + explicit MiniMoveAnimation(TabStrip* tabstrip, + int from_index, + int to_index, + const gfx::Rect& start_bounds) + : TabAnimation(tabstrip, MINI_MOVE), + tab_(tabstrip->GetTabAt(to_index)), + start_bounds_(start_bounds), + from_index_(from_index), + to_index_(to_index) { + int tab_count = tabstrip->GetTabCount(); + int start_mini_count = tabstrip->GetMiniTabCount(); + int end_mini_count = start_mini_count; + if (tabstrip->GetTabAt(to_index)->mini()) + start_mini_count--; + else + start_mini_count++; + GenerateStartAndEndWidths(tab_count, tab_count, start_mini_count, + end_mini_count); + target_bounds_ = tabstrip->GetIdealBounds(to_index); + tab_->set_animating_mini_change(true); + } + + // Overridden from AnimationDelegate: + virtual void AnimationProgressed(const Animation* animation) { + // Do the normal layout. + TabAnimation::AnimationProgressed(animation); + + // Then special case the position of the tab being moved. + int x = AnimationPosition(start_bounds_.x(), target_bounds_.x()); + int width = AnimationPosition(start_bounds_.width(), + target_bounds_.width()); + gfx::Rect tab_bounds(x, start_bounds_.y(), width, + start_bounds_.height()); + tab_->SetBounds(tab_bounds); + } + + virtual void AnimationEnded(const Animation* animation) { + tabstrip_->needs_resize_layout_ = false; + TabStrip::TabAnimation::AnimationEnded(animation); + } + + virtual double GetGapWidth(int index) { + if (to_index_ < from_index_) { + // The tab was mini. + if (index == to_index_) { + double current_size = AnimationPosition(0, target_bounds_.width()); + if (current_size < -kTabHOffset) + return -(current_size + kTabHOffset); + } else if (index == from_index_ + 1) { + return AnimationPosition(start_bounds_.width(), 0); + } + } else { + // The tab was made a normal tab. + if (index == from_index_) { + return AnimationPosition(Tab::GetMiniWidth() + kTabHOffset, 0); + } + } + return 0; + } + + protected: + // Overridden from TabStrip::TabAnimation: + virtual int GetDuration() const { return kReorderAnimationDurationMs; } + + virtual double GetWidthForTab(int index) const { + Tab* tab = tabstrip_->GetTabAt(index); + + if (index == to_index_) + return AnimationPosition(0, target_bounds_.width()); + + if (tab->mini()) + return Tab::GetMiniWidth(); + + if (tab->IsSelected()) + return AnimationPosition(start_selected_width_, end_selected_width_); + + return AnimationPosition(start_unselected_width_, end_unselected_width_); + } + + private: + // The tab being moved. + Tab* tab_; + + // Initial bounds of tab_. + gfx::Rect start_bounds_; + + // Target bounds. + gfx::Rect target_bounds_; + + // Start and end indices of the tab. + int from_index_; + int to_index_; + + DISALLOW_COPY_AND_ASSIGN(MiniMoveAnimation); +}; + /////////////////////////////////////////////////////////////////////////////// // TabStrip, public: // static -const int TabStrip::pinned_to_non_pinned_gap_ = 3; +const int TabStrip::mini_to_non_mini_gap_ = 3; TabStrip::TabStrip(TabStripModel* model) : model_(model), @@ -788,7 +950,7 @@ void TabStrip::Layout() { for (int i = 0; i < tab_count; ++i) { const gfx::Rect& bounds = tab_data_.at(i).ideal_bounds; Tab* tab = GetTabAt(i); - tab->set_animating_pinned_change(false); + tab->set_animating_mini_change(false); tab->SetBounds(bounds.x(), bounds.y(), bounds.width(), bounds.height()); tab_right = bounds.right(); tab_right += GetTabHOffset(i + 1); @@ -959,7 +1121,7 @@ void TabStrip::TabInsertedAt(TabContents* contents, tab_data_.insert(tab_data_.begin() + index, d); tab->UpdateData(contents, model_->IsPhantomTab(index), false); } - tab->set_pinned(model_->IsTabPinned(index)); + tab->set_mini(model_->IsMiniTab(index)); tab->SetBlocked(model_->IsTabBlocked(index)); // We only add the tab to the child list if it's not already - an invisible @@ -1001,7 +1163,7 @@ void TabStrip::TabSelectedAt(TabContents* old_contents, int old_index = model_->GetIndexOfTabContents(old_contents); if (old_index >= 0) - GetTabAt(old_index)->StopPinnedTabTitleAnimation(); + GetTabAt(old_index)->StopMiniTabTitleAnimation(); } void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index) { @@ -1009,7 +1171,7 @@ void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index) { Tab* tab = GetTabAt(from_index); tab_data_.erase(tab_data_.begin() + from_index); TabData data = {tab, gfx::Rect()}; - tab->set_pinned(model_->IsTabPinned(to_index)); + tab->set_mini(model_->IsMiniTab(to_index)); tab->SetBlocked(model_->IsTabBlocked(to_index)); tab_data_.insert(tab_data_.begin() + to_index, data); if (tab->phantom() != model_->IsPhantomTab(to_index)) @@ -1024,8 +1186,8 @@ void TabStrip::TabChangedAt(TabContents* contents, int index, // case we have an animation going. Tab* tab = GetTabAtAdjustForAnimation(index); if (change_type == TITLE_NOT_LOADING) { - if (tab->pinned() && !tab->IsSelected()) - tab->StartPinnedTabTitleAnimation(); + if (tab->mini() && !tab->IsSelected()) + tab->StartMiniTabTitleAnimation(); // We'll receive another notification of the change asynchronously. return; } @@ -1040,8 +1202,14 @@ void TabStrip::TabReplacedAt(TabContents* old_contents, TabChangedAt(new_contents, index, ALL); } -void TabStrip::TabPinnedStateChanged(TabContents* contents, int index) { - GetTabAt(index)->set_pinned(model_->IsTabPinned(index)); +void TabStrip::TabMiniStateChanged(TabContents* contents, int index) { + GetTabAt(index)->set_mini(model_->IsMiniTab(index)); + // Don't animate if the window isn't visible yet. The window won't be visible + // when dragging a mini-tab to a new window. + if (GetWindow() && GetWindow()->IsVisible()) + StartMiniTabAnimation(index); + else + Layout(); } void TabStrip::TabBlockedStateChanged(TabContents* contents, int index) { @@ -1058,6 +1226,13 @@ bool TabStrip::IsTabSelected(const Tab* tab) const { return GetIndexOfTab(tab) == model_->selected_index(); } +bool TabStrip::IsTabPinned(const Tab* tab) const { + if (tab->closing()) + return false; + + return model_->IsTabPinned(GetIndexOfTab(tab)); +} + void TabStrip::SelectTab(Tab* tab) { int index = GetIndexOfTab(tab); if (model_->ContainsIndex(index)) @@ -1313,11 +1488,10 @@ void TabStrip::GetCurrentTabWidths(double* unselected_width, } void TabStrip::GetDesiredTabWidths(int tab_count, - int pinned_tab_count, + int mini_tab_count, double* unselected_width, double* selected_width) const { - DCHECK(tab_count >= 0 && pinned_tab_count >= 0 && - pinned_tab_count <= tab_count); + DCHECK(tab_count >= 0 && mini_tab_count >= 0 && mini_tab_count <= tab_count); const double min_unselected_width = Tab::GetMinimumUnselectedSize().width(); const double min_selected_width = Tab::GetMinimumSelectedSize().width(); @@ -1347,16 +1521,15 @@ void TabStrip::GetDesiredTabWidths(int tab_count, available_width = available_width_for_tabs_; } - if (pinned_tab_count > 0) { - available_width -= pinned_tab_count * (Tab::GetPinnedWidth() + - kTabHOffset); - tab_count -= pinned_tab_count; + if (mini_tab_count > 0) { + available_width -= mini_tab_count * (Tab::GetMiniWidth() + kTabHOffset); + tab_count -= mini_tab_count; if (tab_count == 0) { *selected_width = *unselected_width = Tab::GetStandardSize().width(); return; } - // Account for gap between the last pinned tab and first non-pinned tab. - available_width -= pinned_to_non_pinned_gap_; + // Account for gap between the last mini-tab and first non-mini-tab. + available_width -= mini_to_non_mini_gap_; } // Calculate the desired tab widths by dividing the available space into equal @@ -1395,9 +1568,9 @@ void TabStrip::GetDesiredTabWidths(int tab_count, } int TabStrip::GetTabHOffset(int tab_index) { - if (tab_index < GetTabCount() && GetTabAt(tab_index - 1)->pinned() && - !GetTabAt(tab_index)->pinned()) { - return pinned_to_non_pinned_gap_ + kTabHOffset; + if (tab_index < GetTabCount() && GetTabAt(tab_index - 1)->mini() && + !GetTabAt(tab_index)->mini()) { + return mini_to_non_mini_gap_ + kTabHOffset; } return kTabHOffset; } @@ -1416,15 +1589,15 @@ void TabStrip::ResizeLayoutTabs() { RemoveMessageLoopObserver(); available_width_for_tabs_ = -1; - int pinned_tab_count = GetPinnedTabCount(); - if (pinned_tab_count == GetTabCount()) { - // Only pinned tabs, we know the tab widths won't have changed (all pinned - // tabs have the same width), so there is nothing to do. + int mini_tab_count = GetMiniTabCount(); + if (mini_tab_count == GetTabCount()) { + // Only mini-tabs, we know the tab widths won't have changed (all + // mini-tabs have the same width), so there is nothing to do. return; } - Tab* first_tab = GetTabAt(pinned_tab_count); + Tab* first_tab = GetTabAt(mini_tab_count); double unselected, selected; - GetDesiredTabWidths(GetTabCount(), pinned_tab_count, &unselected, &selected); + GetDesiredTabWidths(GetTabCount(), mini_tab_count, &unselected, &selected); int w = Round(first_tab->IsSelected() ? selected : selected); // We only want to run the animation if we're not already at the desired @@ -1476,7 +1649,7 @@ gfx::Rect TabStrip::GetDropBounds(int drop_index, int center_x; if (drop_index < GetTabCount()) { Tab* tab = GetTabAt(drop_index); - // TODO(sky): update these for pinned tabs. + // TODO(sky): update these for mini-tabs. if (drop_before) center_x = tab->x() - (kTabHOffset / 2); else @@ -1631,7 +1804,7 @@ TabStrip::DropInfo::~DropInfo() { void TabStrip::GenerateIdealBounds() { int tab_count = GetTabCount(); double unselected, selected; - GetDesiredTabWidths(tab_count, GetPinnedTabCount(), &unselected, &selected); + GetDesiredTabWidths(tab_count, GetMiniTabCount(), &unselected, &selected); current_unselected_width_ = unselected; current_selected_width_ = selected; @@ -1643,8 +1816,8 @@ void TabStrip::GenerateIdealBounds() { for (int i = 0; i < tab_count; ++i) { Tab* tab = GetTabAt(i); double tab_width = unselected; - if (tab->pinned()) - tab_width = Tab::GetPinnedWidth(); + if (tab->mini()) + tab_width = Tab::GetMiniWidth(); else if (tab->IsSelected()) tab_width = selected; double end_of_tab = tab_x + tab_width; @@ -1734,13 +1907,30 @@ void TabStrip::StartMoveTabAnimation(int from_index, int to_index) { active_animation_->Start(); } +void TabStrip::StartMiniTabAnimation(int index) { + if (active_animation_.get()) + active_animation_->Stop(); + active_animation_.reset(new MiniTabAnimation(this, index)); + active_animation_->Start(); +} + +void TabStrip::StartMiniMoveTabAnimation(int from_index, + int to_index, + const gfx::Rect& start_bounds) { + if (active_animation_.get()) + active_animation_->Stop(); + active_animation_.reset( + new MiniMoveAnimation(this, from_index, to_index, start_bounds)); + active_animation_->Start(); +} + void TabStrip::FinishAnimation(TabStrip::TabAnimation* animation, bool layout) { active_animation_.reset(NULL); // Reset the animation state of each tab. for (int i = 0, count = GetTabCount(); i < count; ++i) - GetTabAt(i)->set_animating_pinned_change(false); + GetTabAt(i)->set_animating_mini_change(false); if (layout) Layout(); @@ -1758,15 +1948,15 @@ int TabStrip::GetIndexOfTab(const Tab* tab) const { return -1; } -int TabStrip::GetPinnedTabCount() const { - int pinned_count = 0; +int TabStrip::GetMiniTabCount() const { + int mini_count = 0; for (size_t i = 0; i < tab_data_.size(); ++i) { - if (tab_data_[i].tab->pinned()) - pinned_count++; + if (tab_data_[i].tab->mini()) + mini_count++; else - return pinned_count; + return mini_count; } - return pinned_count; + return mini_count; } int TabStrip::GetAvailableWidthForTabs(Tab* last_tab) const { diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index c942ab7..8c5dbe5 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -126,11 +126,12 @@ class TabStrip : public BaseTabStrip, virtual void TabReplacedAt(TabContents* old_contents, TabContents* new_contents, int index); - virtual void TabPinnedStateChanged(TabContents* contents, int index); + virtual void TabMiniStateChanged(TabContents* contents, int index); virtual void TabBlockedStateChanged(TabContents* contents, int index); // Tab::Delegate implementation: virtual bool IsTabSelected(const Tab* tab) const; + virtual bool IsTabPinned(const Tab* tab) const; virtual void SelectTab(Tab* tab); virtual void CloseTab(Tab* tab); virtual bool IsCommandEnabledForTab( @@ -159,11 +160,13 @@ class TabStrip : public BaseTabStrip, virtual void DidProcessEvent(GdkEvent* event); #endif - // Horizontal gap between pinned and non-pinned tabs. - static const int pinned_to_non_pinned_gap_; + // Horizontal gap between mini and non-mini-tabs. + static const int mini_to_non_mini_gap_; private: class InsertTabAnimation; + class MiniMoveAnimation; + class MiniTabAnimation; class MoveTabAnimation; class RemoveTabAnimation; class ResizeLayoutAnimation; @@ -171,6 +174,8 @@ class TabStrip : public BaseTabStrip, friend class DraggedTabController; friend class InsertTabAnimation; + friend class MiniMoveAnimation; + friend class MiniTabAnimation; friend class MoveTabAnimation; friend class RemoveTabAnimation; friend class ResizeLayoutAnimation; @@ -198,8 +203,8 @@ class TabStrip : public BaseTabStrip, // Gets the number of Tabs in the collection. int GetTabCount() const; - // Returns the number of pinned tabs. - int GetPinnedTabCount() const; + // Returns the number of mini-tabs. + int GetMiniTabCount() const; // -- Tab Resize Layout ----------------------------------------------------- @@ -211,10 +216,10 @@ class TabStrip : public BaseTabStrip, // desired strip width and number of tabs. If // |width_of_tabs_for_mouse_close_| is nonnegative we use that value in // calculating the desired strip width; otherwise we use the current width. - // |pinned_tab_count| gives the number of pinned tabs, and |tab_count| the - // number of pinned and non-pinned tabs. + // |mini_tab_count| gives the number of mini-tabs, and |tab_count| the + // number of mini and non-mini-tabs. void GetDesiredTabWidths(int tab_count, - int pinned_tab_count, + int mini_tab_count, double* unselected_width, double* selected_width) const; @@ -275,6 +280,10 @@ class TabStrip : public BaseTabStrip, void StartInsertTabAnimation(int index); void StartRemoveTabAnimation(int index, TabContents* contents); void StartMoveTabAnimation(int from_index, int to_index); + void StartMiniTabAnimation(int index); + void StartMiniMoveTabAnimation(int from_index, + int to_index, + const gfx::Rect& start_bounds); // Notifies the TabStrip that the specified TabAnimation has completed. // Optionally a full Layout will be performed, specified by |layout|. |