summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 20:16:53 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 20:16:53 +0000
commit464b0dd4cd94623495c88cd1d879e9c7be45be9f (patch)
treedcc1a55b55c493061a7845e261feda3bf8466d21
parent81bc31690d650df788b2a8779e6bd3c4bf248c7c (diff)
downloadchromium_src-464b0dd4cd94623495c88cd1d879e9c7be45be9f.zip
chromium_src-464b0dd4cd94623495c88cd1d879e9c7be45be9f.tar.gz
chromium_src-464b0dd4cd94623495c88cd1d879e9c7be45be9f.tar.bz2
Implements mini-tab support for linux.
BUG=36797 TEST=make sure pinned tabs work on linux. Review URL: http://codereview.chromium.org/669163 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40767 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/frame/normal_browser_frame_view.cc15
-rw-r--r--chrome/browser/defaults.cc9
-rw-r--r--chrome/browser/defaults.h2
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc217
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h48
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_gtk.cc27
-rw-r--r--chrome/browser/gtk/tabs/dragged_tab_gtk.h19
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.cc8
-rw-r--r--chrome/browser/gtk/tabs/tab_gtk.h7
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc105
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.h55
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc363
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h28
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc2
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc1
15 files changed, 472 insertions, 434 deletions
diff --git a/chrome/browser/chromeos/frame/normal_browser_frame_view.cc b/chrome/browser/chromeos/frame/normal_browser_frame_view.cc
index 0b49df2..fe766798 100644
--- a/chrome/browser/chromeos/frame/normal_browser_frame_view.cc
+++ b/chrome/browser/chromeos/frame/normal_browser_frame_view.cc
@@ -19,27 +19,18 @@
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/x11_util.h"
#include "grit/app_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/image_button.h"
#include "views/controls/image_view.h"
+#include "views/window/hit_test.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"
#include "views/window/window_resources.h"
-#if defined(OS_WIN)
-#include "app/win_util.h"
-#endif
-
-#if defined(OS_LINUX)
-#include "chrome/common/x11_util.h"
-#include "views/window/hit_test.h"
-#endif
-
-const int kCustomFrameBackgroundVerticalOffset = 15;
-
namespace {
// The frame border is usually 0 as chromeos has no border. The border
@@ -65,6 +56,8 @@ const int kIconLeftSpacing = 2;
// the top of the screen so the tabs appear flush against the screen edge.
const int kTabstripTopShadowThickness = 1;
+const int kCustomFrameBackgroundVerticalOffset = 15;
+
} // namespace
namespace chromeos {
diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc
index 89bd8a2..f924cc7 100644
--- a/chrome/browser/defaults.cc
+++ b/chrome/browser/defaults.cc
@@ -46,12 +46,6 @@ const bool kCanToggleSystemTitleBar = true;
#endif
-#if defined(TOOLKIT_VIEWS)
-const bool kEnablePinnedTabs = true;
-#else
-const bool kEnablePinnedTabs = false;
-#endif
-
#if !defined(OS_CHROMEOS)
const SessionStartupPref::Type kDefaultSessionStartupType =
@@ -76,8 +70,11 @@ const bool kShowOtherBrowsersInAboutMemory = true;
#if defined(OS_MACOSX)
const bool kBrowserAliveWithNoWindows = true;
+// When this gets enabled on Mac, remove this default.
+const bool kEnablePinnedTabs = false;
#else
const bool kBrowserAliveWithNoWindows = false;
+const bool kEnablePinnedTabs = true;
#endif
} // namespace browser_defaults
diff --git a/chrome/browser/defaults.h b/chrome/browser/defaults.h
index 3feb44c..ad6d634 100644
--- a/chrome/browser/defaults.h
+++ b/chrome/browser/defaults.h
@@ -65,8 +65,6 @@ extern const bool kSizeTabButtonToTopOfTabStrip;
extern const bool kBootstrapSyncAuthentication;
// Are pinned tabs enabled?
-// TODO: if you're the last to make this true on all platforms, remove the
-// field.
extern const bool kEnablePinnedTabs;
// Should other browsers be shown in about:memory page?
diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc
index 5e2c110..98b5ace 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc
+++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.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.
@@ -26,20 +26,9 @@ const int kBringToFrontDelay = 750;
// their indexes.
const int kHorizontalMoveThreshold = 16; // pixels
-// Threshold for pinned tabs.
-const int kHorizontalPinnedMoveThreshold = 4; // pixels
-
// How far a drag must pull a tab out of the tabstrip in order to detach it.
const int kVerticalDetachMagnetism = 15; // 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.
-const int kHorizontalPinTabOffset = 16;
-
-// 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.
-const int kPinTabDelay = 300;
-
} // namespace
DraggedTabControllerGtk::DraggedTabControllerGtk(TabGtk* source_tab,
@@ -52,7 +41,8 @@ DraggedTabControllerGtk::DraggedTabControllerGtk(TabGtk* source_tab,
attached_tabstrip_(source_tabstrip),
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_));
}
@@ -78,7 +68,6 @@ void DraggedTabControllerGtk::Drag() {
return;
bring_to_front_timer_.Stop();
- pin_timer_.Stop();
EnsureDraggedTab();
@@ -280,136 +269,33 @@ void DraggedTabControllerGtk::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_tab_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 (!dragged_tab_->is_pinned()) {
- double unselected, selected;
- attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected);
- double ratio = unselected / TabGtk::GetStandardSize().width();
- threshold = static_cast<int>(ratio * kHorizontalMoveThreshold);
- }
+ double unselected, selected;
+ attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected);
+ double ratio = unselected / TabGtk::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 = GetDraggedTabTabStripBounds(dragged_tab_point);
- int to_index = GetInsertionIndexForDraggedBounds(bounds);
+ int to_index = GetInsertionIndexForDraggedBounds(bounds, true);
to_index = NormalizeIndexToAttachedTabStrip(to_index);
- if (!dragged_tab_->is_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 dragged tab. There are no changes to the model if we're detached.
dragged_tab_->MoveTo(dragged_tab_point);
}
-void DraggedTabControllerGtk::MakeDraggedTabPinned() {
- MakeDraggedTabPinned(0);
-}
-
-void DraggedTabControllerGtk::MakeDraggedTabPinned(int tab_index) {
- DCHECK(dragged_tab_.get());
- DCHECK(!dragged_tab_->is_pinned());
-
- // Mark the tab as pinned and update the model.
- dragged_tab_->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(TabGtk::GetPinnedWidth() / 2 - 1);
- InitWindowCreatePoint();
- dragged_tab_->set_mouse_tab_offset(mouse_offset_);
-
- // Resize the dragged tab.
- dragged_tab_->Resize(TabGtk::GetPinnedWidth());
-}
-
-void DraggedTabControllerGtk::StartPinTimerIfNecessary(
- const gfx::Point& screen_point) {
- if (dragged_tab_->is_pinned())
- return;
-
- TabStripModel* attached_model = attached_tabstrip_->model();
- int pinned_count = attached_model->IndexOfFirstNonMiniTab();
- if (pinned_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,
- &DraggedTabControllerGtk::MakeDraggedTabPinned);
-}
-
-void DraggedTabControllerGtk::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 (!dragged_tab_->is_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 = GetDraggedTabPoint(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 =
- gtk_util::GetWidgetScreenBounds(attached_tabstrip_->tabstrip_.get());
- 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.
- dragged_tab_->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_);
-
- dragged_tab_->Resize(dragged_tab_->tab_width());
- }
-}
-
TabStripGtk* DraggedTabControllerGtk::GetTabStripForPoint(
const gfx::Point& screen_point) {
GtkWidget* dragged_window = dragged_tab_->widget();
@@ -470,36 +356,14 @@ void DraggedTabControllerGtk::Attach(TabStripGtk* 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 = 0, selected_width = 0;
- attached_tabstrip_->GetDesiredTabWidths(tab_count, pinned_tab_count,
+ attached_tabstrip_->GetDesiredTabWidths(tab_count, mini_tab_count,
&unselected_width, &selected_width);
- int dragged_tab_width = static_cast<int>(selected_width);
- dragged_tab_->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 = TabGtk::GetPinnedWidth();
- pinned = true;
- }
- }
- dragged_tab_->set_pinned(pinned);
+ int dragged_tab_width =
+ mini_ ? TabGtk::GetMiniWidth() : static_cast<int>(selected_width);
dragged_tab_->Attach(dragged_tab_width);
if (!tab) {
@@ -529,10 +393,9 @@ void DraggedTabControllerGtk::Attach(TabStripGtk* attached_tabstrip,
// strip. ("ideal bounds" are stable even if the tabs' actual bounds are
// changing due to animation).
gfx::Rect bounds = GetDraggedTabTabStripBounds(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_);
}
@@ -578,21 +441,6 @@ gfx::Point DraggedTabControllerGtk::ConvertScreenPointToTabStripPoint(
return gfx::Point(screen_point.x() - x, screen_point.y() - y);
}
-int DraggedTabControllerGtk::GetPinnedThreshold() {
- int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonMiniTab();
- if (pinned_count == 0)
- return 0;
- if (!dragged_tab_->is_pinned()) {
- gfx::Rect non_pinned_bounds =
- attached_tabstrip_->GetIdealBounds(pinned_count);
- return non_pinned_bounds.x() + TabGtk::GetPinnedWidth() / 2;
- }
- gfx::Rect last_pinned_bounds =
- attached_tabstrip_->GetIdealBounds(pinned_count - 1);
- return last_pinned_bounds.x() + TabStripGtk::pinned_to_non_pinned_gap_ +
- TabGtk::GetPinnedWidth() / 2;
-}
-
gfx::Rect DraggedTabControllerGtk::GetDraggedTabTabStripBounds(
const gfx::Point& screen_point) {
gfx::Point client_point =
@@ -603,13 +451,15 @@ gfx::Rect DraggedTabControllerGtk::GetDraggedTabTabStripBounds(
}
int DraggedTabControllerGtk::GetInsertionIndexForDraggedBounds(
- const gfx::Rect& dragged_bounds) const {
+ const gfx::Rect& dragged_bounds,
+ bool is_tab_attached) const {
int right_tab_x = 0;
// TODO(jhawkins): Handle RTL layout.
// Divides each tab into two halves to see if the dragged tab has crossed
// the halfway boundary necessary to move past the next tab.
+ int index = -1;
for (int i = 0; i < attached_tabstrip_->GetTabCount(); i++) {
gfx::Rect ideal_bounds = attached_tabstrip_->GetIdealBounds(i);
@@ -624,17 +474,29 @@ int DraggedTabControllerGtk::GetInsertionIndexForDraggedBounds(
if (dragged_bounds.x() >= right_half.x() &&
dragged_bounds.x() < right_half.right()) {
- return i + 1;
+ index = i + 1;
+ break;
} else if (dragged_bounds.x() >= left_half.x() &&
dragged_bounds.x() < left_half.right()) {
- return i;
+ index = i;
+ break;
}
}
- if (dragged_bounds.right() > right_tab_x)
- return attached_tabstrip_->model()->count();
+ if (index == -1) {
+ if (dragged_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 TabStripModel::kNoTab;
+ return index;
}
gfx::Point DraggedTabControllerGtk::GetDraggedTabPoint(
@@ -696,7 +558,6 @@ TabGtk* DraggedTabControllerGtk::GetTabMatchingDraggedContents(
}
bool DraggedTabControllerGtk::EndDragImpl(EndDragType type) {
- pin_timer_.Stop();
bring_to_front_timer_.Stop();
// WARNING: this may be invoked multiple times. In particular, if deletion
@@ -756,7 +617,7 @@ void DraggedTabControllerGtk::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.
@@ -771,9 +632,8 @@ void DraggedTabControllerGtk::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 tab strip, or attached to some other tab
// strip, we need to restore the bounds of the original tab strip's frame, in
@@ -802,6 +662,9 @@ bool DraggedTabControllerGtk::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();
}
@@ -815,7 +678,7 @@ void DraggedTabControllerGtk::EnsureDraggedTab() {
dragged_contents_->GetContainerBounds(&rect);
dragged_tab_.reset(new DraggedTabGtk(dragged_contents_, mouse_offset_,
- gfx::Size(rect.width(), rect.height())));
+ rect.size(), mini_));
}
}
diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
index ebdf799..46905df 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
+++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.h
@@ -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.
@@ -111,29 +111,6 @@ class DraggedTabControllerGtk : public NotificationObserver,
// 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.
TabStripGtk* GetTabStripForPoint(const gfx::Point& screen_point);
@@ -153,12 +130,6 @@ class DraggedTabControllerGtk : public NotificationObserver,
gfx::Point ConvertScreenPointToTabStripPoint(TabStripGtk* tabstrip,
const gfx::Point& screen_point);
- // 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();
-
// Retrieve the bounds of the DraggedTabGtk, relative to the attached
// TabStrip, given location of the dragged tab in screen coordinates.
gfx::Rect GetDraggedTabTabStripBounds(const gfx::Point& screen_point);
@@ -166,7 +137,9 @@ class DraggedTabControllerGtk : public NotificationObserver,
// 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;
// Get the position of the dragged tab relative to the attached tab strip.
gfx::Point GetDraggedTabPoint(const gfx::Point& screen_point);
@@ -278,20 +251,17 @@ class DraggedTabControllerGtk : public NotificationObserver,
typedef std::set<GtkWidget*> DockWindows;
DockWindows dock_windows_;
- // 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<DraggedTabControllerGtk> 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<DraggedTabControllerGtk> pin_timer_;
-
DISALLOW_COPY_AND_ASSIGN(DraggedTabControllerGtk);
};
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_gtk.cc
index 67b6cf5..bc2cd81 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.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.
@@ -46,16 +46,17 @@ const double kDraggedTabBorderColor[] = { 103.0 / 0xff,
DraggedTabGtk::DraggedTabGtk(TabContents* datasource,
const gfx::Point& mouse_tab_offset,
- const gfx::Size& contents_size)
+ const gfx::Size& contents_size,
+ bool mini)
: data_source_(datasource),
renderer_(new TabRendererGtk(datasource->profile()->GetThemeProvider())),
attached_(false),
mouse_tab_offset_(mouse_tab_offset),
attached_tab_size_(TabRendererGtk::GetMinimumSelectedSize()),
contents_size_(contents_size),
- close_animation_(this),
- tab_width_(0) {
- renderer_->UpdateData(datasource, false);
+ close_animation_(this) {
+ renderer_->UpdateData(datasource, false, false);
+ renderer_->set_mini(mini);
container_ = gtk_window_new(GTK_WINDOW_POPUP);
SetContainerColorMap();
@@ -99,23 +100,7 @@ void DraggedTabGtk::Resize(int width) {
ResizeContainer();
}
-void DraggedTabGtk::set_pinned(bool pinned) {
- renderer_->set_pinned(pinned);
-}
-
-bool DraggedTabGtk::is_pinned() const {
- return renderer_->is_pinned();
-}
-
void DraggedTabGtk::Detach() {
- // 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;
ResizeContainer();
diff --git a/chrome/browser/gtk/tabs/dragged_tab_gtk.h b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
index dd24c1b..ab40aca 100644
--- a/chrome/browser/gtk/tabs/dragged_tab_gtk.h
+++ b/chrome/browser/gtk/tabs/dragged_tab_gtk.h
@@ -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.
@@ -23,7 +23,8 @@ class DraggedTabGtk : public AnimationDelegate {
public:
DraggedTabGtk(TabContents* datasource,
const gfx::Point& mouse_tab_offset,
- const gfx::Size& contents_size);
+ const gfx::Size& contents_size,
+ bool mini);
virtual ~DraggedTabGtk();
// Moves the dragged tab to the appropriate location given the mouse
@@ -35,23 +36,12 @@ class DraggedTabGtk : public AnimationDelegate {
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 dragged tab 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 is_pinned() const;
-
// Notifies the dragged tab that it has been detached from a tabstrip.
void Detach();
@@ -149,9 +139,6 @@ class DraggedTabGtk : public AnimationDelegate {
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(DraggedTabGtk);
};
diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc
index 46fecc2..d7ab875 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_gtk.cc
@@ -58,7 +58,7 @@ class TabGtk::ContextMenuController : public menus::SimpleMenuModel::Delegate {
virtual bool IsCommandIdChecked(int command_id) const {
if (!tab_ || command_id != TabStripModel::CommandTogglePinned)
return false;
- return tab_->is_pinned();
+ return tab_->delegate()->IsTabPinned(tab_);
}
virtual bool IsCommandIdEnabled(int command_id) const {
return tab_ && tab_->delegate()->IsCommandEnabledForTab(
@@ -328,8 +328,10 @@ void TabGtk::CloseButtonClicked() {
delegate_->CloseTab(this);
}
-void TabGtk::UpdateData(TabContents* contents, bool loading_only) {
- TabRendererGtk::UpdateData(contents, loading_only);
+void TabGtk::UpdateData(TabContents* contents,
+ bool phantom,
+ bool loading_only) {
+ TabRendererGtk::UpdateData(contents, phantom, loading_only);
// Cache the title width so we don't recalculate it every time the tab is
// resized.
title_width_ = GetTitleWidth(title_font(), GetTitle());
diff --git a/chrome/browser/gtk/tabs/tab_gtk.h b/chrome/browser/gtk/tabs/tab_gtk.h
index a82742f..a2614e1 100644
--- a/chrome/browser/gtk/tabs/tab_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_gtk.h
@@ -28,6 +28,9 @@ class TabGtk : public TabRendererGtk,
// Returns true if the specified Tab is selected.
virtual bool IsTabSelected(const TabGtk* tab) const = 0;
+ // Returns true if the specified Tab is pinned.
+ virtual bool IsTabPinned(const TabGtk* tab) const = 0;
+
// Returns true if the specified Tab is detached.
virtual bool IsTabDetached(const TabGtk* tab) const = 0;
@@ -95,7 +98,9 @@ class TabGtk : public TabRendererGtk,
virtual bool IsVisible() const;
virtual void SetVisible(bool visible) const;
virtual void CloseButtonClicked();
- virtual void UpdateData(TabContents* contents, bool loading_only);
+ virtual void UpdateData(TabContents* contents,
+ bool phantom,
+ bool loading_only);
virtual void SetBounds(const gfx::Rect& bounds);
private:
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index b8f8e54..a288022 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -39,11 +39,11 @@ const int kStandardTitleWidth = 175;
const int kDropShadowOffset = 2;
const int kInactiveTabBackgroundOffsetY = 15;
-// 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.
-const int kPinnedTabRendererAsTabWidth =
+// 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.
+const int kMiniTabRendererAsNormalTabWidth =
browser_defaults::kMiniTabWidth + 30;
// The tab images are designed to overlap the toolbar by 1 pixel. For now we
@@ -57,11 +57,11 @@ const int kHoverDurationMs = 90;
// How opaque to make the hover state (out of 1).
const double kHoverOpacity = 0.33;
-// 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;
const SkScalar kTabCapWidth = 15;
const SkScalar kTabTopCurveWidth = 4;
@@ -249,10 +249,6 @@ TabRendererGtk::TabRendererGtk(ThemeProvider* theme_provider)
close_button_color_(NULL) {
InitResources();
- data_.pinned = false;
- data_.blocked = false;
- data_.animating_pinned_change = false;
-
tab_.Own(gtk_fixed_new());
gtk_widget_set_app_paintable(tab_.get(), TRUE);
g_signal_connect(tab_.get(), "expose-event",
@@ -277,7 +273,9 @@ TabRendererGtk::~TabRendererGtk() {
}
}
-void TabRendererGtk::UpdateData(TabContents* contents, bool loading_only) {
+void TabRendererGtk::UpdateData(TabContents* contents,
+ bool phantom,
+ bool loading_only) {
DCHECK(contents);
theme_provider_ = GtkThemeProvider::GetFrom(contents->profile());
@@ -287,6 +285,7 @@ void TabRendererGtk::UpdateData(TabContents* contents, bool loading_only) {
data_.off_the_record = contents->profile()->IsOffTheRecord();
data_.crashed = contents->is_crashed();
data_.favicon = contents->GetFavIcon();
+ data_.phantom = phantom;
// This is kind of a hacky way to determine whether our icon is the default
// favicon. But the plumbing that would be necessary to do it right would
// be a good bit of work and would sully code for other platforms which
@@ -319,14 +318,6 @@ void TabRendererGtk::UpdateFromModel() {
}
}
-void TabRendererGtk::set_pinned(bool pinned) {
- data_.pinned = pinned;
-}
-
-bool TabRendererGtk::is_pinned() const {
- return data_.pinned;
-}
-
void TabRendererGtk::SetBlocked(bool blocked) {
if (data_.blocked == blocked)
return;
@@ -338,10 +329,6 @@ bool TabRendererGtk::is_blocked() const {
return data_.blocked;
}
-void TabRendererGtk::set_animating_pinned_change(bool value) {
- data_.animating_pinned_change = value;
-}
-
bool TabRendererGtk::IsSelected() const {
return true;
}
@@ -353,7 +340,7 @@ bool TabRendererGtk::IsVisible() const {
void TabRendererGtk::SetVisible(bool visible) const {
if (visible) {
gtk_widget_show(tab_.get());
- if (data_.pinned)
+ if (data_.mini)
gtk_widget_show(close_button_->widget());
} else {
gtk_widget_hide_all(tab_.get());
@@ -449,7 +436,7 @@ gfx::Size TabRendererGtk::GetStandardSize() {
}
// static
-int TabRendererGtk::GetPinnedWidth() {
+int TabRendererGtk::GetMiniWidth() {
return browser_defaults::kMiniTabWidth;
}
@@ -508,26 +495,26 @@ gfx::Rect TabRendererGtk::GetRequisition() const {
requisition_.width(), requisition_.height());
}
-void TabRendererGtk::StartPinnedTabTitleAnimation() {
- if (!pinned_title_animation_.get()) {
- pinned_title_animation_.reset(new ThrobAnimation(this));
- pinned_title_animation_->SetThrobDuration(kPinnedDuration);
+void TabRendererGtk::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 TabRendererGtk::StopPinnedTabTitleAnimation() {
- if (pinned_title_animation_.get())
- pinned_title_animation_->Stop();
+void TabRendererGtk::StopMiniTabTitleAnimation() {
+ if (mini_title_animation_.get())
+ mini_title_animation_->Stop();
}
void TabRendererGtk::SetBounds(const gfx::Rect& bounds) {
@@ -607,7 +594,7 @@ void TabRendererGtk::ResetCrashedFavIcon() {
void TabRendererGtk::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() && !is_pinned())
+ if (width() < GetMinimumUnselectedSize().width() && !mini())
return;
// See if the model changes whether the icons should be painted.
@@ -617,8 +604,14 @@ void TabRendererGtk::Paint(gfx::Canvas* canvas) {
show_close_button != showing_close_button_)
Layout();
- PaintTabBackground(canvas);
- if (!is_pinned() || width() > kPinnedTabRendererAsTabWidth)
+ if (!phantom()) {
+ // TODO: this isn't quite right. To match the Windows side we need to render
+ // phantom tabs to a separate layer than alpha composite that. This will do
+ // for now though.
+ PaintTabBackground(canvas);
+ }
+
+ if (!mini() || width() > kMiniTabRendererAsNormalTabWidth)
PaintTitle(canvas);
if (show_icon)
@@ -660,15 +653,15 @@ void TabRendererGtk::Layout() {
int favicon_top = kTopPadding + (content_height - kFavIconSize) / 2;
favicon_bounds_.SetRect(local_bounds.x(), favicon_top,
kFavIconSize, kFavIconSize);
- if ((is_pinned() || data_.animating_pinned_change) &&
- bounds_.width() < kPinnedTabRendererAsTabWidth) {
- int pin_delta = kPinnedTabRendererAsTabWidth - GetPinnedWidth();
- int ideal_delta = bounds_.width() - GetPinnedWidth();
- if (ideal_delta < pin_delta) {
- int ideal_x = (GetPinnedWidth() - kFavIconSize) / 2;
+ if ((mini() || data_.animating_mini_change) &&
+ bounds_.width() < kMiniTabRendererAsNormalTabWidth) {
+ int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
+ int ideal_delta = bounds_.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);
}
@@ -703,7 +696,7 @@ void TabRendererGtk::Layout() {
close_button_bounds_.SetRect(0, 0, 0, 0);
}
- if (!is_pinned() || width() >= kPinnedTabRendererAsTabWidth) {
+ if (!mini() || width() >= kMiniTabRendererAsNormalTabWidth) {
// Size the Title text to fill the remaining space.
int title_left = favicon_bounds_.right() + kFavIconTitleSpacing;
int title_top = kTopPadding;
@@ -954,7 +947,7 @@ int TabRendererGtk::IconCapacity() const {
}
bool TabRendererGtk::ShouldShowIcon() const {
- if (is_pinned() && height() >= GetMinimumUnselectedSize().height()) {
+ if (mini() && height() >= GetMinimumUnselectedSize().height()) {
return true;
} else if (!data_.show_icon) {
return false;
@@ -968,7 +961,7 @@ bool TabRendererGtk::ShouldShowIcon() const {
bool TabRendererGtk::ShouldShowCloseBox() const {
// The selected tab never clips close button.
- return !is_pinned() && (IsSelected() || IconCapacity() >= 3);
+ return !mini() && (IsSelected() || IconCapacity() >= 3);
}
CustomDrawButton* TabRendererGtk::MakeCloseButton() {
@@ -990,8 +983,10 @@ CustomDrawButton* TabRendererGtk::MakeCloseButton() {
}
double TabRendererGtk::GetThrobValue() {
- 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/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
index 227322b..c62a87c 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
@@ -102,18 +102,26 @@ class TabRendererGtk : public AnimationDelegate,
// TabContents. If only the loading state was updated, the loading_only flag
// should be specified. If other things change, set this flag to false to
// update everything.
- virtual void UpdateData(TabContents* contents, bool loading_only);
+ virtual 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 pinned);
bool is_blocked() const;
- // Sets the pinned state of the tab.
- void set_pinned(bool pinned);
- bool is_pinned() const;
+ // Sets the mini-state of the tab.
+ void set_mini(bool mini) { data_.mini = mini; }
+ bool mini() const { return data_.mini; }
- // Are we in the process of animating a pinned state change on this tab?
- void set_animating_pinned_change(bool value);
+ // 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 mini tab state change on this tab?
+ void set_animating_mini_change(bool value) {
+ data_.animating_mini_change = value;
+ }
// Updates the display to reflect the contents of this TabRenderer's model.
void UpdateFromModel();
@@ -170,8 +178,8 @@ class TabRendererGtk : public AnimationDelegate,
// 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();
@@ -200,9 +208,9 @@ class TabRendererGtk : public AnimationDelegate,
GtkWidget* widget() const { return tab_.get(); }
- // Start/stop the pinned tab title animation.
- void StartPinnedTabTitleAnimation();
- void StopPinnedTabTitleAnimation();
+ // Start/stop the mini-tab title animation.
+ void StartMiniTabTitleAnimation();
+ void StopMiniTabTitleAnimation();
void set_vertical_offset(int offset) { background_offset_y_ = offset; }
@@ -239,6 +247,18 @@ class TabRendererGtk : public AnimationDelegate,
// model, which is tricky since instances of this object can outlive the
// corresponding objects in the underlying model.
struct TabData {
+ TabData()
+ : is_default_favicon(false),
+ loading(false),
+ crashed(false),
+ off_the_record(false),
+ show_icon(true),
+ mini(false),
+ blocked(false),
+ animating_mini_change(false),
+ phantom(false) {
+ }
+
SkBitmap favicon;
bool is_default_favicon;
string16 title;
@@ -246,9 +266,10 @@ class TabRendererGtk : public AnimationDelegate,
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;
};
// TODO(jhawkins): Move into TabResources class.
@@ -325,7 +346,7 @@ class TabRendererGtk : public AnimationDelegate,
// 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
- // and pinned tab title change effects.
+ // and mini-tab title change effects.
double GetThrobValue();
// Handles the clicked signal for the close button.
@@ -398,8 +419,8 @@ class TabRendererGtk : public AnimationDelegate,
// Hover animation.
scoped_ptr<SlideAnimation> hover_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_;
// Contains the loading animation state.
LoadingAnimation loading_animation_;
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index b038fc8..ec8c893 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -16,6 +16,7 @@
#include "base/string_util.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/browser_theme_provider.h"
+#include "chrome/browser/gtk/browser_window_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
@@ -33,6 +34,7 @@ const int kDefaultAnimationDurationMs = 100;
const int kResizeLayoutAnimationDurationMs = 166;
const int kReorderAnimationDurationMs = 166;
const int kAnimateToBoundsDurationMs = 150;
+const int kMiniTabAnimationDurationMs = 150;
const int kNewTabButtonHOffset = -5;
const int kNewTabButtonVOffset = 5;
@@ -108,6 +110,8 @@ class TabStripGtk::TabAnimation : public AnimationDelegate {
REMOVE,
MOVE,
RESIZE,
+ MINI,
+ MINI_MOVE
};
TabAnimation(TabStripGtk* tabstrip, Type type)
@@ -148,8 +152,8 @@ class TabStripGtk::TabAnimation : public AnimationDelegate {
int index) {
TabGtk* tab = tabstrip->GetTabAt(index);
double tab_width;
- if (tab->is_pinned()) {
- tab_width = TabGtk::GetPinnedWidth();
+ if (tab->mini()) {
+ tab_width = TabGtk::GetMiniWidth();
} else {
double unselected, selected;
tabstrip->GetCurrentTabWidths(&unselected, &selected);
@@ -201,9 +205,9 @@ class TabStripGtk::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 =
@@ -217,7 +221,7 @@ class TabStripGtk::TabAnimation : public AnimationDelegate {
}
tabstrip_->GenerateIdealBounds();
- tabstrip_->GetDesiredTabWidths(end_tab_count, end_pinned_count,
+ tabstrip_->GetDesiredTabWidths(end_tab_count, end_mini_count,
&end_unselected_width_,
&end_selected_width_);
}
@@ -251,12 +255,12 @@ class InsertTabAnimation : public TabStripGtk::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() {}
@@ -266,9 +270,9 @@ class InsertTabAnimation : public TabStripGtk::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 = TabGtk::GetMinimumSelectedSize().width();
- target_width = TabGtk::GetPinnedWidth();
+ target_width = TabGtk::GetMiniWidth();
} else {
target_width =
is_selected ? end_unselected_width_ : end_selected_width_;
@@ -284,8 +288,8 @@ class InsertTabAnimation : public TabStripGtk::TabAnimation {
return start_width;
}
- if (tabstrip_->GetTabAt(index)->is_pinned())
- return TabGtk::GetPinnedWidth();
+ if (tabstrip_->GetTabAt(index)->mini())
+ return TabGtk::GetMiniWidth();
if (tabstrip_->GetTabAt(index)->IsSelected()) {
double delta = end_selected_width_ - start_selected_width_;
@@ -311,20 +315,23 @@ class RemoveTabAnimation : public TabStripGtk::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)));
}
virtual ~RemoveTabAnimation() {}
@@ -340,8 +347,8 @@ class RemoveTabAnimation : public TabStripGtk::TabAnimation {
if (index == index_) {
// The tab(s) being removed are gradually shrunken depending on the state
// of the animation.
- if (tab->is_pinned()) {
- return animation_.CurrentValueBetween(TabGtk::GetPinnedWidth(),
+ if (tab->mini()) {
+ return animation_.CurrentValueBetween(TabGtk::GetMiniWidth(),
-kTabHOffset);
}
@@ -355,8 +362,8 @@ class RemoveTabAnimation : public TabStripGtk::TabAnimation {
return animation_.CurrentValueBetween(start_width, target_width);
}
- if (tab->is_pinned())
- return TabGtk::GetPinnedWidth();
+ if (tab->mini())
+ return TabGtk::GetMiniWidth();
if (tabstrip_->available_width_for_tabs_ != -1 &&
index_ != tabstrip_->GetTabCount() - 1) {
@@ -448,9 +455,9 @@ class ResizeLayoutAnimation : public TabStripGtk::TabAnimation {
explicit ResizeLayoutAnimation(TabStripGtk* 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() {}
@@ -470,8 +477,8 @@ class ResizeLayoutAnimation : public TabStripGtk::TabAnimation {
virtual double GetWidthForTab(int index) const {
TabGtk* tab = tabstrip_->GetTabAt(index);
- if (tab->is_pinned())
- return TabGtk::GetPinnedWidth();
+ if (tab->mini())
+ return TabGtk::GetMiniWidth();
if (tab->IsSelected()) {
return animation_.CurrentValueBetween(start_selected_width_,
@@ -490,7 +497,7 @@ class ResizeLayoutAnimation : public TabStripGtk::TabAnimation {
void InitStartState() {
for (int i = 0; i < tabstrip_->GetTabCount(); ++i) {
TabGtk* current_tab = tabstrip_->GetTabAt(i);
- if (!current_tab->is_pinned()) {
+ if (!current_tab->mini()) {
if (current_tab->IsSelected()) {
start_selected_width_ = current_tab->width();
} else {
@@ -503,11 +510,177 @@ class ResizeLayoutAnimation : public TabStripGtk::TabAnimation {
DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation);
};
+// Handles a tabs mini-state changing while the tab does not change position
+// in the model.
+class MiniTabAnimation : public TabStripGtk::TabAnimation {
+ public:
+ explicit MiniTabAnimation(TabStripGtk* 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 TabStripGtk::TabAnimation:
+ virtual int GetDuration() const {
+ return kMiniTabAnimationDurationMs;
+ }
+
+ virtual double GetWidthForTab(int index) const {
+ TabGtk* tab = tabstrip_->GetTabAt(index);
+
+ if (index == index_) {
+ if (tab->mini()) {
+ return animation_.CurrentValueBetween(
+ start_selected_width_,
+ static_cast<double>(TabGtk::GetMiniWidth()));
+ } else {
+ return animation_.CurrentValueBetween(
+ static_cast<double>(TabGtk::GetMiniWidth()),
+ end_selected_width_);
+ }
+ } else if (tab->mini()) {
+ return TabGtk::GetMiniWidth();
+ }
+
+ if (tab->IsSelected()) {
+ return animation_.CurrentValueBetween(start_selected_width_,
+ end_selected_width_);
+ }
+
+ return animation_.CurrentValueBetween(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 MiniMoveAnimation : public TabStripGtk::TabAnimation {
+ public:
+ explicit MiniMoveAnimation(TabStripGtk* 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 = animation_.CurrentValueBetween(start_bounds_.x(),
+ target_bounds_.x());
+ int width = animation_.CurrentValueBetween(start_bounds_.width(),
+ target_bounds_.width());
+ gfx::Rect tab_bounds(x, start_bounds_.y(), width,
+ start_bounds_.height());
+ tabstrip_->SetTabBounds(tab_, tab_bounds);
+ }
+
+ virtual void AnimationEnded(const Animation* animation) {
+ tabstrip_->needs_resize_layout_ = false;
+ TabStripGtk::TabAnimation::AnimationEnded(animation);
+ }
+
+ virtual double GetGapWidth(int index) {
+ if (to_index_ < from_index_) {
+ // The tab was made mini.
+ if (index == to_index_) {
+ double current_size =
+ animation_.CurrentValueBetween(0, target_bounds_.width());
+ if (current_size < -kTabHOffset)
+ return -(current_size + kTabHOffset);
+ } else if (index == from_index_ + 1) {
+ return animation_.CurrentValueBetween(start_bounds_.width(), 0);
+ }
+ } else {
+ // The tab was was made a normal tab.
+ if (index == from_index_) {
+ return animation_.CurrentValueBetween(
+ TabGtk::GetMiniWidth() + kTabHOffset, 0);
+ }
+ }
+ return 0;
+ }
+
+ protected:
+ // Overridden from TabStripGtk::TabAnimation:
+ virtual int GetDuration() const { return kReorderAnimationDurationMs; }
+
+ virtual double GetWidthForTab(int index) const {
+ TabGtk* tab = tabstrip_->GetTabAt(index);
+
+ if (index == to_index_)
+ return animation_.CurrentValueBetween(0, target_bounds_.width());
+
+ if (tab->mini())
+ return TabGtk::GetMiniWidth();
+
+ if (tab->IsSelected()) {
+ return animation_.CurrentValueBetween(start_selected_width_,
+ end_selected_width_);
+ }
+
+ return animation_.CurrentValueBetween(start_unselected_width_,
+ end_unselected_width_);
+ }
+
+ private:
+ // The tab being moved.
+ TabGtk* 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);
+};
+
////////////////////////////////////////////////////////////////////////////////
// TabStripGtk, public:
// static
-const int TabStripGtk::pinned_to_non_pinned_gap_ = 3;
+const int TabStripGtk::mini_to_non_mini_gap_ = 3;
TabStripGtk::TabStripGtk(TabStripModel* model, BrowserWindowGtk* window)
: current_unselected_width_(TabGtk::GetStandardSize().width()),
@@ -612,7 +785,7 @@ void TabStripGtk::Layout() {
for (int i = 0; i < tab_count; ++i) {
const gfx::Rect& bounds = tab_data_.at(i).ideal_bounds;
TabGtk* tab = GetTabAt(i);
- tab->set_animating_pinned_change(false);
+ tab->set_animating_mini_change(false);
tab->set_vertical_offset(tab_vertical_offset_);
SetTabBounds(tab, bounds);
tab_right = bounds.right();
@@ -788,9 +961,9 @@ void TabStripGtk::TabInsertedAt(TabContents* contents,
if (!contains_tab) {
TabData d = { tab, gfx::Rect() };
tab_data_.insert(tab_data_.begin() + index, d);
- tab->UpdateData(contents, false);
+ tab->UpdateData(contents, model_->IsPhantomTab(index), false);
}
- tab->set_pinned(model_->IsTabPinned(index));
+ tab->set_mini(model_->IsMiniTab(index));
tab->SetBlocked(model_->IsTabBlocked(index));
if (gtk_widget_get_parent(tab->widget()) != tabstrip_.get())
@@ -834,7 +1007,7 @@ void TabStripGtk::TabSelectedAt(TabContents* old_contents,
int old_index = model_->GetIndexOfTabContents(old_contents);
if (old_index >= 0) {
GetTabAt(old_index)->SchedulePaint();
- GetTabAt(old_index)->StopPinnedTabTitleAnimation();
+ GetTabAt(old_index)->StopMiniTabTitleAnimation();
}
}
@@ -845,9 +1018,11 @@ void TabStripGtk::TabMoved(TabContents* contents,
TabGtk* 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))
+ tab->set_phantom(!tab->phantom());
GenerateIdealBounds();
StartMoveTabAnimation(from_index, to_index);
}
@@ -858,17 +1033,32 @@ void TabStripGtk::TabChangedAt(TabContents* contents, int index,
// case we have an animation going.
TabGtk* tab = GetTabAtAdjustForAnimation(index);
if (change_type == TITLE_NOT_LOADING) {
- if (tab->is_pinned() && !tab->IsSelected())
- tab->StartPinnedTabTitleAnimation();
+ if (tab->mini() && !tab->IsSelected())
+ tab->StartMiniTabTitleAnimation();
// We'll receive another notification of the change asynchronously.
return;
}
- tab->UpdateData(contents, change_type == LOADING_ONLY);
+ tab->UpdateData(contents, model_->IsPhantomTab(index),
+ change_type == LOADING_ONLY);
tab->UpdateFromModel();
}
-void TabStripGtk::TabPinnedStateChanged(TabContents* contents, int index) {
- GetTabAt(index)->set_pinned(model_->IsTabPinned(index));
+void TabStripGtk::TabReplacedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index) {
+ TabChangedAt(new_contents, index, ALL);
+}
+
+void TabStripGtk::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 (window_ && window_->window() &&
+ GTK_WIDGET_VISIBLE(GTK_WIDGET(window_->window()))) {
+ StartMiniTabAnimation(index);
+ } else {
+ Layout();
+ }
}
void TabStripGtk::TabBlockedStateChanged(TabContents* contents, int index) {
@@ -897,6 +1087,13 @@ void TabStripGtk::GetCurrentTabWidths(double* unselected_width,
*selected_width = current_selected_width_;
}
+bool TabStripGtk::IsTabPinned(const TabGtk* tab) const {
+ if (tab->closing())
+ return false;
+
+ return model_->IsTabPinned(GetIndexOfTab(tab));
+}
+
void TabStripGtk::SelectTab(TabGtk* tab) {
int index = GetIndexOfTab(tab);
if (model_->ContainsIndex(index))
@@ -1030,15 +1227,15 @@ int TabStripGtk::GetTabCount() const {
return static_cast<int>(tab_data_.size());
}
-int TabStripGtk::GetPinnedTabCount() const {
- int pinned_count = 0;
+int TabStripGtk::GetMiniTabCount() const {
+ int mini_count = 0;
for (size_t i = 0; i < tab_data_.size(); ++i) {
- if (tab_data_[i].tab->is_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 TabStripGtk::GetAvailableWidthForTabs(TabGtk* last_tab) const {
@@ -1109,7 +1306,7 @@ void TabStripGtk::HandleGlobalMouseMoveEvent() {
void TabStripGtk::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;
@@ -1121,8 +1318,8 @@ void TabStripGtk::GenerateIdealBounds() {
for (int i = 0; i < tab_count; ++i) {
TabGtk* tab = GetTabAt(i);
double tab_width = unselected;
- if (tab->is_pinned())
- tab_width = TabGtk::GetPinnedWidth();
+ if (tab->mini())
+ tab_width = TabGtk::GetMiniWidth();
else if (tab->IsSelected())
tab_width = selected;
double end_of_tab = tab_x + tab_width;
@@ -1154,11 +1351,10 @@ void TabStripGtk::LayoutNewTabButton(double last_tab_right,
}
void TabStripGtk::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 =
TabGtk::GetMinimumUnselectedSize().width();
const double min_selected_width =
@@ -1191,16 +1387,15 @@ void TabStripGtk::GetDesiredTabWidths(int tab_count,
available_width = available_width_for_tabs_;
}
- if (pinned_tab_count > 0) {
- available_width -= pinned_tab_count * (TabGtk::GetPinnedWidth() +
- kTabHOffset);
- tab_count -= pinned_tab_count;
+ if (mini_tab_count > 0) {
+ available_width -= mini_tab_count * (TabGtk::GetMiniWidth() + kTabHOffset);
+ tab_count -= mini_tab_count;
if (tab_count == 0) {
*selected_width = *unselected_width = TabGtk::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 normal tab.
+ available_width -= mini_to_non_mini_gap_;
}
// Calculate the desired tab widths by dividing the available space into equal
@@ -1241,9 +1436,9 @@ void TabStripGtk::GetDesiredTabWidths(int tab_count,
}
int TabStripGtk::GetTabHOffset(int tab_index) {
- if (tab_index < GetTabCount() && GetTabAt(tab_index - 1)->is_pinned() &&
- !GetTabAt(tab_index)->is_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;
}
@@ -1260,15 +1455,15 @@ void TabStripGtk::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;
}
- TabGtk* first_tab = GetTabAt(pinned_tab_count);
+ TabGtk* 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 : unselected);
// We only want to run the animation if we're not already at the desired
@@ -1350,7 +1545,8 @@ void TabStripGtk::UpdateDropIndex(GdkDragContext* context, gint x, gint y) {
// coordinates since we calculate the drop index based on the
// original (and therefore non-mirrored) positions of the tabs.
x = gtk_util::MirroredXCoordinate(tabstrip_.get(), x);
- for (int i = 0; i < GetTabCount(); ++i) {
+ // We don't allow replacing the urls of mini-tabs.
+ for (int i = GetMiniTabCount(); i < GetTabCount(); ++i) {
TabGtk* tab = GetTabAt(i);
gfx::Rect bounds = tab->GetNonMirroredBounds(tabstrip_.get());
const int tab_max_x = bounds.x() + bounds.width();
@@ -1607,13 +1803,28 @@ void TabStripGtk::StartResizeLayoutAnimation() {
active_animation_->Start();
}
+void TabStripGtk::StartMiniTabAnimation(int index) {
+ StopAnimation();
+ active_animation_.reset(new MiniTabAnimation(this, index));
+ active_animation_->Start();
+}
+
+void TabStripGtk::StartMiniMoveTabAnimation(int from_index,
+ int to_index,
+ const gfx::Rect& start_bounds) {
+ StopAnimation();
+ active_animation_.reset(
+ new MiniMoveAnimation(this, from_index, to_index, start_bounds));
+ active_animation_->Start();
+}
+
void TabStripGtk::FinishAnimation(TabStripGtk::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();
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h
index 1c4a5b7..570d39f 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h
@@ -110,12 +110,16 @@ class TabStripGtk : public TabStripModelObserver,
int to_index);
virtual void TabChangedAt(TabContents* contents, int index,
TabChangeType change_type);
- virtual void TabPinnedStateChanged(TabContents* contents, int index);
+ virtual void TabReplacedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index);
+ virtual void TabMiniStateChanged(TabContents* contents, int index);
virtual void TabBlockedStateChanged(TabContents* contents,
int index);
// TabGtk::TabDelegate implementation:
virtual bool IsTabSelected(const TabGtk* tab) const;
+ virtual bool IsTabPinned(const TabGtk* tab) const;
virtual bool IsTabDetached(const TabGtk* tab) const;
virtual void SelectTab(TabGtk* tab);
virtual void CloseTab(TabGtk* tab);
@@ -143,15 +147,17 @@ class TabStripGtk : public TabStripModelObserver,
const NotificationSource& source,
const NotificationDetails& details);
- // Horizontal gap between pinned and non-pinned tabs.
- static const int pinned_to_non_pinned_gap_;
+ // Horizontal gap between mini-tabs and normal tabs.
+ static const int mini_to_non_mini_gap_;
private:
friend class BrowserWindowGtk;
friend class DraggedTabControllerGtk;
friend class InsertTabAnimation;
- friend class RemoveTabAnimation;
+ friend class MiniMoveAnimation;
+ friend class MiniTabAnimation;
friend class MoveTabAnimation;
+ friend class RemoveTabAnimation;
friend class ResizeLayoutAnimation;
friend class TabAnimation;
@@ -272,8 +278,8 @@ class TabStripGtk : public TabStripModelObserver,
// 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;
// Retrieves the Tab at the specified index. Take care in using this, you may
// need to use GetTabAtAdjustForAnimation.
@@ -296,10 +302,10 @@ class TabStripGtk : public TabStripModelObserver,
// 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;
@@ -383,6 +389,10 @@ class TabStripGtk : public TabStripModelObserver,
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);
void StartResizeLayoutAnimation();
// Notifies the TabStrip that the specified TabAnimation has completed.
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc
index c859c7f..a9dcaeb 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc
@@ -592,7 +592,7 @@ void OpaqueBrowserFrameView::PaintRestoredFrameBorder(gfx::Canvas* canvas) {
if (ShouldPaintAsActive()) {
theme_frame = rb.GetBitmapNamed(is_off_the_record ?
IDR_THEME_FRAME_INCOGNITO : IDR_FRAME);
- frame_color = is_off_the_record ?
+ frame_color = is_off_the_record ?
ResourceBundle::frame_color_incognito :
ResourceBundle::frame_color;
} else {
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index 7918408..1697d79 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -43,6 +43,7 @@ static const int kStandardTitleWidth = 175;
static const int kCloseButtonVertFuzz = 0;
static const int kCloseButtonHorzFuzz = 5;
static const int kSelectedTitleColor = SK_ColorBLACK;
+
// 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