diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 03:36:56 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 03:36:56 +0000 |
commit | 1d8e0549671de50700c47fbb9418b59569f61966 (patch) | |
tree | 7df6a2c85ea77638174b67f972592e091a507de8 /chrome/browser/views/tabs | |
parent | 3e4f1bc651d4a2027a19c572b352f7ba4e2c3c92 (diff) | |
download | chromium_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.cc | 11 | ||||
-rw-r--r-- | chrome/browser/views/tabs/browser_tab_strip_controller.h | 5 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab.cc | 113 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab.h | 18 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.cc | 8 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.h | 18 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip_model.h | 41 |
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_ + |