summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-10 03:36:56 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-10 03:36:56 +0000
commit1d8e0549671de50700c47fbb9418b59569f61966 (patch)
tree7df6a2c85ea77638174b67f972592e091a507de8 /chrome/browser/views/tabs
parent3e4f1bc651d4a2027a19c572b352f7ba4e2c3c92 (diff)
downloadchromium_src-1d8e0549671de50700c47fbb9418b59569f61966.zip
chromium_src-1d8e0549671de50700c47fbb9418b59569f61966.tar.gz
chromium_src-1d8e0549671de50700c47fbb9418b59569f61966.tar.bz2
1. Correct shapes for side tabs.
2. Adjust transparency of background tabs a little. 3. Implement loading animation for side tabs. 4. Deeper shadow for side tabstrip between browser view and side tabstrip. http://crbug.com/34509 TEST=none Review URL: http://codereview.chromium.org/610002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/tabs')
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.cc11
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.h5
-rw-r--r--chrome/browser/views/tabs/side_tab.cc113
-rw-r--r--chrome/browser/views/tabs/side_tab.h18
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.cc8
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.h18
-rw-r--r--chrome/browser/views/tabs/side_tab_strip_model.h41
7 files changed, 188 insertions, 26 deletions
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc
index ddc147c..343ee09 100644
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/views/tabs/browser_tab_strip_controller.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/views/tabs/browser_tab_strip_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/tabs/side_tab_strip.h"
////////////////////////////////////////////////////////////////////////////////
// BrowserTabStripController, public:
@@ -34,6 +35,16 @@ bool BrowserTabStripController::IsSelected(int index) const {
return model_->selected_index() == index;
}
+SideTabStripModel::NetworkState
+ BrowserTabStripController::GetNetworkState(int index) const {
+ TabContents* contents = model_->GetTabContentsAt(index);
+ if (!contents || !contents->is_loading())
+ return NetworkState_None;
+ if (contents->waiting_for_response())
+ return NetworkState_Waiting;
+ return NetworkState_Loading;
+}
+
void BrowserTabStripController::SelectTab(int index) {
model_->SelectTabContentsAt(index, true);
}
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.h b/chrome/browser/views/tabs/browser_tab_strip_controller.h
index d2d6a90..e127659 100644
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.h
+++ b/chrome/browser/views/tabs/browser_tab_strip_controller.h
@@ -6,7 +6,9 @@
#define CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_
#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/views/tabs/side_tab_strip.h"
+#include "chrome/browser/views/tabs/side_tab_strip_model.h"
+
+class SideTabStrip;
// An implementation of SideTabStripModel that sources data from
// the TabContentses in a TabStripModel.
@@ -20,6 +22,7 @@ class BrowserTabStripController : public SideTabStripModel,
virtual SkBitmap GetIcon(int index) const;
virtual string16 GetTitle(int index) const;
virtual bool IsSelected(int index) const;
+ virtual NetworkState GetNetworkState(int index) const;
virtual void SelectTab(int index);
virtual void CloseTab(int index);
diff --git a/chrome/browser/views/tabs/side_tab.cc b/chrome/browser/views/tabs/side_tab.cc
index 8907a2e..ec7dbcd 100644
--- a/chrome/browser/views/tabs/side_tab.cc
+++ b/chrome/browser/views/tabs/side_tab.cc
@@ -5,10 +5,12 @@
#include "chrome/browser/views/tabs/side_tab.h"
#include "app/gfx/canvas.h"
+#include "app/gfx/path.h"
#include "app/gfx/skia_util.h"
#include "app/resource_bundle.h"
#include "app/theme_provider.h"
#include "base/string_util.h"
+#include "grit/app_resources.h"
#include "grit/theme_resources.h"
#include "views/controls/button/image_button.h"
@@ -19,8 +21,15 @@ const int kIconTitleSpacing = 4;
const int kTitleCloseSpacing = 4;
const SkScalar kRoundRectRadius = 5;
const SkColor kTabBackgroundColor = SK_ColorWHITE;
-const SkAlpha kBackgroundTabAlpha = 200;
+const SkAlpha kBackgroundTabAlpha = 170;
static const int kHoverDurationMs = 900;
+
+static SkBitmap* waiting_animation_frames = NULL;
+static SkBitmap* loading_animation_frames = NULL;
+static SkBitmap* crashed_fav_icon = NULL;
+static int loading_animation_frame_count = 0;
+static int waiting_animation_frame_count = 0;
+static int waiting_to_loading_frame_count_ratio = 0;
};
// static
@@ -34,7 +43,9 @@ SkBitmap* SideTab::close_button_p_ = NULL;
SideTab::SideTab(SideTabModel* model)
: model_(model),
- close_button_(NULL) {
+ close_button_(NULL),
+ current_state_(SideTabStripModel::NetworkState_None),
+ loading_animation_frame_(0) {
InitClass();
views::ImageButton* close_button = new views::ImageButton(this);
@@ -51,6 +62,31 @@ SideTab::SideTab(SideTabModel* model)
SideTab::~SideTab() {
}
+void SideTab::SetNetworkState(SideTabStripModel::NetworkState state) {
+ if (current_state_ != state) {
+ // The waiting animation is the reverse of the loading animation, but at a
+ // different rate - the following reverses and scales the animation_frame_
+ // so that the frame is at an equivalent position when going from one
+ // animation to the other.
+ if (current_state_ == SideTabStripModel::NetworkState_Waiting &&
+ current_state_ == SideTabStripModel::NetworkState_Loading) {
+ loading_animation_frame_ = loading_animation_frame_count -
+ (loading_animation_frame_ / waiting_to_loading_frame_count_ratio);
+ }
+ current_state_ = state;
+ }
+
+ if (current_state_ != SideTabStripModel::NetworkState_None) {
+ loading_animation_frame_ = ++loading_animation_frame_ %
+ ((current_state_ == SideTabStripModel::NetworkState_Waiting) ?
+ waiting_animation_frame_count :
+ loading_animation_frame_count);
+ } else {
+ loading_animation_frame_ = 0;
+ }
+ SchedulePaint();
+}
+
////////////////////////////////////////////////////////////////////////////////
// SideTab, AnimationDelegate implementation:
@@ -98,13 +134,11 @@ void SideTab::Paint(gfx::Canvas* canvas) {
SkPaint paint;
paint.setColor(kTabBackgroundColor);
paint.setAntiAlias(true);
- SkRect background_rect = gfx::RectToSkRect(GetLocalBounds(false));
- canvas->drawRoundRect(background_rect, kRoundRectRadius, kRoundRectRadius,
- paint);
+ gfx::Path tab_shape;
+ FillTabShapePath(&tab_shape);
+ canvas->drawPath(tab_shape, paint);
- canvas->DrawBitmapInt(model_->GetIcon(this), 0, 0, kIconSize, kIconSize,
- icon_bounds_.x(), icon_bounds_.y(),
- icon_bounds_.width(), icon_bounds_.height(), false);
+ PaintIcon(canvas);
canvas->DrawStringInt(UTF16ToWideHack(model_->GetTitle(this)), *font_,
SK_ColorBLACK, title_bounds_.x(), title_bounds_.y(),
title_bounds_.width(), title_bounds_.height());
@@ -122,8 +156,7 @@ void SideTab::Paint(gfx::Canvas* canvas) {
paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
paint.setStyle(SkPaint::kFill_Style);
paint.setAntiAlias(true);
- canvas->drawRoundRect(background_rect, kRoundRectRadius, kRoundRectRadius,
- paint);
+ canvas->FillRectInt(0, 0, width(), height(), paint);
}
}
@@ -150,6 +183,47 @@ bool SideTab::OnMousePressed(const views::MouseEvent& event) {
////////////////////////////////////////////////////////////////////////////////
// SideTab, private:
+#define CUBIC_ARC_FACTOR ((SK_ScalarSqrt2 - SK_Scalar1) * 4 / 3)
+
+void SideTab::FillTabShapePath(gfx::Path* path) {
+ SkScalar s = SkScalarMul(kRoundRectRadius, CUBIC_ARC_FACTOR);
+ path->moveTo(SkIntToScalar(kRoundRectRadius), 0);
+ path->cubicTo(SkIntToScalar(kRoundRectRadius) - s, 0, 0,
+ SkIntToScalar(kRoundRectRadius) - s, 0,
+ SkIntToScalar(kRoundRectRadius));
+ path->lineTo(0, SkIntToScalar(height() - kRoundRectRadius));
+ path->cubicTo(0, SkIntToScalar(height() - kRoundRectRadius) + s,
+ SkIntToScalar(kRoundRectRadius) - s, SkIntToScalar(height()),
+ SkIntToScalar(kRoundRectRadius),
+ SkIntToScalar(height()));
+ path->lineTo(SkIntToScalar(width()), SkIntToScalar(height()));
+ path->lineTo(SkIntToScalar(width()), 0);
+ path->lineTo(SkIntToScalar(kRoundRectRadius), 0);
+ path->close();
+}
+
+void SideTab::PaintIcon(gfx::Canvas* canvas) {
+ if (current_state_ == SideTabStripModel::NetworkState_None) {
+ canvas->DrawBitmapInt(model_->GetIcon(this), 0, 0, kIconSize, kIconSize,
+ icon_bounds_.x(), icon_bounds_.y(),
+ icon_bounds_.width(), icon_bounds_.height(), false);
+ } else {
+ PaintLoadingAnimation(canvas);
+ }
+}
+
+void SideTab::PaintLoadingAnimation(gfx::Canvas* canvas) {
+ SkBitmap* frames =
+ (current_state_ == SideTabStripModel::NetworkState_Waiting) ?
+ waiting_animation_frames : loading_animation_frames;
+ int image_size = frames->height();
+ int image_offset = loading_animation_frame_ * image_size;
+ int dst_y = (height() - image_size) / 2;
+ canvas->DrawBitmapInt(*frames, image_offset, 0, image_size,
+ image_size, icon_bounds_.x(), dst_y, image_size,
+ image_size, false);
+}
+
// static
void SideTab::InitClass() {
static bool initialized = false;
@@ -161,6 +235,25 @@ void SideTab::InitClass() {
close_button_h_ = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
close_button_p_ = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
+ // The loading animation image is a strip of states. Each state must be
+ // square, so the height must divide the width evenly.
+ loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
+ DCHECK(loading_animation_frames);
+ DCHECK(loading_animation_frames->width() %
+ loading_animation_frames->height() == 0);
+ loading_animation_frame_count =
+ loading_animation_frames->width() / loading_animation_frames->height();
+
+ waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
+ DCHECK(waiting_animation_frames);
+ DCHECK(waiting_animation_frames->width() %
+ waiting_animation_frames->height() == 0);
+ waiting_animation_frame_count =
+ waiting_animation_frames->width() / waiting_animation_frames->height();
+
+ waiting_to_loading_frame_count_ratio =
+ waiting_animation_frame_count / loading_animation_frame_count;
+
initialized = true;
}
}
diff --git a/chrome/browser/views/tabs/side_tab.h b/chrome/browser/views/tabs/side_tab.h
index 787cd33..72fc8b0 100644
--- a/chrome/browser/views/tabs/side_tab.h
+++ b/chrome/browser/views/tabs/side_tab.h
@@ -7,6 +7,7 @@
#include "app/gfx/font.h"
#include "app/slide_animation.h"
+#include "chrome/browser/views/tabs/side_tab_strip_model.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "views/controls/button/button.h"
#include "views/view.h"
@@ -34,6 +35,11 @@ class SideTab : public views::View,
explicit SideTab(SideTabModel* model);
virtual ~SideTab();
+ // Sets the current network state of the tab. The tab renders different
+ // animations in place of the icon when different types of network activity
+ // are occurring.
+ void SetNetworkState(SideTabStripModel::NetworkState state);
+
// AnimationDelegate implementation:
virtual void AnimationProgressed(const Animation* animation);
virtual void AnimationCanceled(const Animation* animation);
@@ -51,6 +57,12 @@ class SideTab : public views::View,
virtual bool OnMousePressed(const views::MouseEvent& event);
private:
+ void FillTabShapePath(gfx::Path* path);
+
+ // Paint various components of the tab.
+ void PaintIcon(gfx::Canvas* canvas);
+ void PaintLoadingAnimation(gfx::Canvas* canvas);
+
// Loads class-specific resources.
static void InitClass();
@@ -70,6 +82,12 @@ class SideTab : public views::View,
static SkBitmap* close_button_h_;
static SkBitmap* close_button_p_;
+ // The current network state for this tab.
+ SideTabStripModel::NetworkState current_state_;
+
+ // The current index into the Animation image strip.
+ int loading_animation_frame_;
+
DISALLOW_COPY_AND_ASSIGN(SideTab);
};
diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc
index 74df961..6896d42 100644
--- a/chrome/browser/views/tabs/side_tab_strip.cc
+++ b/chrome/browser/views/tabs/side_tab_strip.cc
@@ -14,7 +14,7 @@
namespace {
const int kVerticalTabSpacing = 2;
-const int kTabStripWidth = 127;
+const int kTabStripWidth = 140;
const int kTabStripInset = 3;
}
@@ -111,6 +111,9 @@ bool SideTabStrip::IsDragSessionActive() const {
}
void SideTabStrip::UpdateLoadingAnimations() {
+ int count = GetChildViewCount();
+ for (int i = 0; i < count; ++i)
+ GetSideTabAt(i)->SetNetworkState(model_->GetNetworkState(i));
}
bool SideTabStrip::IsAnimating() const {
@@ -147,3 +150,6 @@ int SideTabStrip::GetIndexOfSideTab(SideTab* tab) const {
return GetChildIndex(tab);
}
+SideTab* SideTabStrip::GetSideTabAt(int index) const {
+ return static_cast<SideTab*>(GetChildViewAt(index));
+}
diff --git a/chrome/browser/views/tabs/side_tab_strip.h b/chrome/browser/views/tabs/side_tab_strip.h
index 61a0bc4..71b704a 100644
--- a/chrome/browser/views/tabs/side_tab_strip.h
+++ b/chrome/browser/views/tabs/side_tab_strip.h
@@ -10,20 +10,7 @@
#include "chrome/browser/views/tabs/side_tab.h"
class Profile;
-
-class SideTabStripModel {
- public:
- // Returns metadata about the tab at the specified index.
- virtual SkBitmap GetIcon(int index) const = 0;
- virtual string16 GetTitle(int index) const = 0;
- virtual bool IsSelected(int index) const = 0;
-
- // Select the tab at the specified index in the model.
- virtual void SelectTab(int index) = 0;
-
- // Closes the tab at the specified index in the model.
- virtual void CloseTab(int index) = 0;
-};
+class SideTabStripModel;
class SideTabStrip : public BaseTabStrip,
public SideTabModel {
@@ -81,6 +68,9 @@ class SideTabStrip : public BaseTabStrip,
// Returns the model index of the specified |tab|.
int GetIndexOfSideTab(SideTab* tab) const;
+ // Returns the SideTab at the specified |index|.
+ SideTab* GetSideTabAt(int index) const;
+
scoped_ptr<SideTabStripModel> model_;
DISALLOW_COPY_AND_ASSIGN(SideTabStrip);
diff --git a/chrome/browser/views/tabs/side_tab_strip_model.h b/chrome/browser/views/tabs/side_tab_strip_model.h
new file mode 100644
index 0000000..a456c36
--- /dev/null
+++ b/chrome/browser/views/tabs/side_tab_strip_model.h
@@ -0,0 +1,41 @@
+// 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.
+
+#ifndef CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_MODEL_H_
+#define CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_MODEL_H_
+
+#include "base/string16.h"
+
+class SkBitmap;
+
+// A model interface implemented by an object that can provide information
+// about SideTabs in a SideTabStrip.
+class SideTabStripModel {
+ public:
+ // Returns metadata about the tab at the specified index.
+ virtual SkBitmap GetIcon(int index) const = 0;
+ virtual string16 GetTitle(int index) const = 0;
+ virtual bool IsSelected(int index) const = 0;
+
+ // Different types of network activity for a tab. The NetworkState of a tab
+ // may be used to alter the UI (e.g. show different kinds of loading
+ // animations).
+ enum NetworkState {
+ NetworkState_None, // no network activity.
+ NetworkState_Waiting, // waiting for a connection.
+ NetworkState_Loading // connected, transferring data.
+ };
+
+ // Returns the NetworkState of the tab at the specified index.
+ virtual NetworkState GetNetworkState(int index) const = 0;
+
+ // Select the tab at the specified index in the model.
+ virtual void SelectTab(int index) = 0;
+
+ // Closes the tab at the specified index in the model.
+ virtual void CloseTab(int index) = 0;
+};
+
+#endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_MODEL_H_
+