summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-09 18:40:51 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-09 18:40:51 +0000
commit95b9162bf10740841d7803bcb978b87f52bfea3e (patch)
tree6bc0573df989b59ccf6bbe35e46eec21142bd72c
parent3a249031886bcc8e85880b28839ce2420d0acfeb (diff)
downloadchromium_src-95b9162bf10740841d7803bcb978b87f52bfea3e.zip
chromium_src-95b9162bf10740841d7803bcb978b87f52bfea3e.tar.gz
chromium_src-95b9162bf10740841d7803bcb978b87f52bfea3e.tar.bz2
Add a resize layout animation to the Linux tabstrip.
Review URL: http://codereview.chromium.org/65014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13440 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc100
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h5
2 files changed, 98 insertions, 7 deletions
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 07a4a4a..5f41458 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -18,6 +18,7 @@
namespace {
const int kDefaultAnimationDurationMs = 100;
+const int kResizeLayoutAnimationDurationMs = 166;
const int kNewTabButtonHOffset = -5;
const int kNewTabButtonVOffset = 5;
@@ -175,10 +176,10 @@ class TabStripGtk::TabAnimation : public AnimationDelegate {
const Type type_;
- DISALLOW_EVIL_CONSTRUCTORS(TabAnimation);
+ DISALLOW_COPY_AND_ASSIGN(TabAnimation);
};
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// Handles insertion of a Tab at |index|.
class InsertTabAnimation : public TabStripGtk::TabAnimation {
@@ -221,10 +222,10 @@ class InsertTabAnimation : public TabStripGtk::TabAnimation {
private:
int index_;
- DISALLOW_EVIL_CONSTRUCTORS(InsertTabAnimation);
+ DISALLOW_COPY_AND_ASSIGN(InsertTabAnimation);
};
-///////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// Handles removal of a Tab from |index|
class RemoveTabAnimation : public TabStripGtk::TabAnimation {
@@ -236,7 +237,7 @@ class RemoveTabAnimation : public TabStripGtk::TabAnimation {
GenerateStartAndEndWidths(tab_count, tab_count - 1);
}
- virtual ~RemoveTabAnimation() { }
+ virtual ~RemoveTabAnimation() {}
// Returns the index of the tab being removed.
int index() const { return index_; }
@@ -307,7 +308,62 @@ class RemoveTabAnimation : public TabStripGtk::TabAnimation {
int index_;
- DISALLOW_EVIL_CONSTRUCTORS(RemoveTabAnimation);
+ DISALLOW_COPY_AND_ASSIGN(RemoveTabAnimation);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Handles the animated resize layout of the entire TabStrip from one width
+// to another.
+class ResizeLayoutAnimation : public TabStripGtk::TabAnimation {
+ public:
+ explicit ResizeLayoutAnimation(TabStripGtk* tabstrip)
+ : TabAnimation(tabstrip, RESIZE) {
+ int tab_count = tabstrip->GetTabCount();
+ GenerateStartAndEndWidths(tab_count, tab_count);
+ InitStartState();
+ }
+ virtual ~ResizeLayoutAnimation() {}
+
+ // Overridden from AnimationDelegate:
+ virtual void AnimationEnded(const Animation* animation) {
+ tabstrip_->resize_layout_scheduled_ = false;
+ TabStripGtk::TabAnimation::AnimationEnded(animation);
+ }
+
+ protected:
+ // Overridden from TabStripGtk::TabAnimation:
+ virtual int GetDuration() const {
+ return kResizeLayoutAnimationDurationMs;
+ }
+
+ virtual double GetWidthForTab(int index) const {
+ if (tabstrip_->GetTabAt(index)->IsSelected()) {
+ double delta = end_selected_width_ - start_selected_width_;
+ return start_selected_width_ + (delta * animation_.GetCurrentValue());
+ }
+
+ double delta = end_unselected_width_ - start_unselected_width_;
+ return start_unselected_width_ + (delta * animation_.GetCurrentValue());
+ }
+
+ private:
+ // We need to start from the current widths of the Tabs as they were last
+ // laid out, _not_ the last known good state, which is what'll be done if we
+ // don't measure the Tab sizes here and just go with the default TabAnimation
+ // behavior...
+ void InitStartState() {
+ for (int i = 0; i < tabstrip_->GetTabCount(); ++i) {
+ TabGtk* current_tab = tabstrip_->GetTabAt(i);
+ if (current_tab->IsSelected()) {
+ start_selected_width_ = current_tab->width();
+ } else {
+ start_unselected_width_ = current_tab->width();
+ }
+ }
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation);
};
////////////////////////////////////////////////////////////////////////////////
@@ -699,6 +755,19 @@ void TabStripGtk::GetDesiredTabWidths(int tab_count,
}
}
+void TabStripGtk::ResizeLayoutTabs() {
+ available_width_for_tabs_ = -1;
+ double unselected, selected;
+ GetDesiredTabWidths(GetTabCount(), &unselected, &selected);
+ TabGtk* first_tab = GetTabAt(0);
+ int w = Round(first_tab->IsSelected() ? selected : selected);
+
+ // We only want to run the animation if we're not already at the desired
+ // size.
+ if (abs(first_tab->width() - w) > 1)
+ StartResizeLayoutAnimation();
+}
+
// Called from:
// - animation tick
void TabStripGtk::AnimationLayout(double unselected_width) {
@@ -743,6 +812,13 @@ void TabStripGtk::StartRemoveTabAnimation(int index, TabContents* contents) {
active_animation_->Start();
}
+void TabStripGtk::StartResizeLayoutAnimation() {
+ if (active_animation_.get())
+ active_animation_->Stop();
+ active_animation_.reset(new ResizeLayoutAnimation(this));
+ active_animation_->Start();
+}
+
bool TabStripGtk::CanUpdateDisplay() {
// Don't bother laying out/painting when we're closing all tabs.
if (model_->closing_all()) {
@@ -798,7 +874,17 @@ gboolean TabStripGtk::OnConfigure(GtkWidget* widget, GdkEventConfigure* event,
TabStripGtk* tabstrip) {
gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
tabstrip->SetBounds(bounds);
- tabstrip->Layout();
+
+ // Do a regular layout on the first configure-event so we don't animate
+ // the first tab.
+ // TODO(jhawkins): Windows resizes the layout tabs continuously during
+ // a resize. I need to investigate which signal to watch in order to
+ // reproduce this behavior.
+ if (tabstrip->GetTabCount() == 1)
+ tabstrip->Layout();
+ else
+ tabstrip->ResizeLayoutTabs();
+
return TRUE;
}
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h
index 9504963..d80312c 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h
@@ -75,6 +75,7 @@ class TabStripGtk : public TabStripModelObserver,
private:
friend class InsertTabAnimation;
friend class RemoveTabAnimation;
+ friend class ResizeLayoutAnimation;
friend class TabAnimation;
struct TabData {
@@ -124,6 +125,9 @@ class TabStripGtk : public TabStripModelObserver,
double* unselected_width,
double* selected_width) const;
+ // Perform an animated resize-relayout of the TabStrip immediately.
+ void ResizeLayoutTabs();
+
// Calculates the available width for tabs, assuming a Tab is to be closed.
int GetAvailableWidthForTabs(TabGtk* last_tab) const;
@@ -150,6 +154,7 @@ class TabStripGtk : public TabStripModelObserver,
// Starts various types of TabStrip animations.
void StartInsertTabAnimation(int index);
void StartRemoveTabAnimation(int index, TabContents* contents);
+ void StartResizeLayoutAnimation();
// Returns true if detach or select changes in the model should be reflected
// in the TabStrip. This returns false if we're closing all tabs in the