diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-27 14:54:15 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-27 14:54:15 +0000 |
commit | b68becccf8fd9deb39346f1d36413817ab924e78 (patch) | |
tree | 0fa25577bf4034d9e5e380fdfb9f0b7a9d82d564 /chrome/browser/views/tabs | |
parent | 539d8f80f984dfed455b40533df0ad5d15e2c2ba (diff) | |
download | chromium_src-b68becccf8fd9deb39346f1d36413817ab924e78.zip chromium_src-b68becccf8fd9deb39346f1d36413817ab924e78.tar.gz chromium_src-b68becccf8fd9deb39346f1d36413817ab924e78.tar.bz2 |
Adds the new tab button to side tabs.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/2224003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@48389 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/tabs')
-rw-r--r-- | chrome/browser/views/tabs/base_tab.cc | 12 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab.h | 2 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab_strip.cc | 21 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab_strip.h | 5 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab.h | 3 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.cc | 106 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.h | 15 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 14 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.h | 1 |
10 files changed, 157 insertions, 28 deletions
diff --git a/chrome/browser/views/tabs/base_tab.cc b/chrome/browser/views/tabs/base_tab.cc index 070e1ee..f128abc 100644 --- a/chrome/browser/views/tabs/base_tab.cc +++ b/chrome/browser/views/tabs/base_tab.cc @@ -248,6 +248,9 @@ void BaseTab::OnMouseExited(const views::MouseEvent& e) { } bool BaseTab::OnMousePressed(const views::MouseEvent& event) { + if (!controller()) + return false; + if (event.IsOnlyLeftMouseButton()) { // Store whether or not we were selected just now... we only want to be // able to drag foreground tabs, so we don't start dragging the tab if @@ -261,11 +264,15 @@ bool BaseTab::OnMousePressed(const views::MouseEvent& event) { } bool BaseTab::OnMouseDragged(const views::MouseEvent& event) { - controller()->ContinueDrag(event); + if (controller()) + controller()->ContinueDrag(event); return true; } void BaseTab::OnMouseReleased(const views::MouseEvent& event, bool canceled) { + if (!controller()) + return; + // Notify the drag helper that we're done with any potential drag operations. // Clean up the drag helper, which is re-created on the next mouse press. // In some cases, ending the drag will schedule the tab for destruction; if @@ -413,7 +420,8 @@ void BaseTab::ButtonPressed(views::Button* sender, const views::Event& event) { void BaseTab::ShowContextMenu(views::View* source, const gfx::Point& p, bool is_mouse_gesture) { - controller()->ShowContextMenu(this, p); + if (controller()) + controller()->ShowContextMenu(this, p); } void BaseTab::ThemeChanged() { diff --git a/chrome/browser/views/tabs/base_tab.h b/chrome/browser/views/tabs/base_tab.h index 678594d..e2ac34a 100644 --- a/chrome/browser/views/tabs/base_tab.h +++ b/chrome/browser/views/tabs/base_tab.h @@ -72,7 +72,7 @@ class BaseTab : public AnimationDelegate, } // Returns true if the tab is selected. - bool IsSelected() const; + virtual bool IsSelected() const; // views::View overrides: virtual void OnMouseEntered(const views::MouseEvent& event); diff --git a/chrome/browser/views/tabs/base_tab_strip.cc b/chrome/browser/views/tabs/base_tab_strip.cc index f978385..5008ddb 100644 --- a/chrome/browser/views/tabs/base_tab_strip.cc +++ b/chrome/browser/views/tabs/base_tab_strip.cc @@ -172,6 +172,20 @@ void BaseTabStrip::MoveTab(int from_model_index, int to_model_index) { StartMoveTabAnimation(); } +void BaseTabStrip::SetTabData(int model_index, const TabRendererData& data) { + BaseTab* tab = GetBaseTabAtModelIndex(model_index); + bool mini_state_changed = tab->data().mini != data.mini; + tab->SetData(data); + tab->SchedulePaint(); + + if (mini_state_changed) { + if (GetWindow() && GetWindow()->IsVisible()) + StartMiniTabAnimation(); + else + Layout(); + } +} + BaseTab* BaseTabStrip::GetBaseTabAtModelIndex(int model_index) const { return base_tab_at_tab_index(ModelIndexToTabIndex(model_index)); } @@ -342,6 +356,13 @@ void BaseTabStrip::StartRemoveTabAnimation(int model_index) { true); } +void BaseTabStrip::StartMiniTabAnimation() { + PrepareForAnimation(); + + GenerateIdealBounds(); + AnimateToIdealBounds(); +} + void BaseTabStrip::RemoveAndDeleteTab(BaseTab* tab) { int tab_data_index = TabIndexOfTab(tab); diff --git a/chrome/browser/views/tabs/base_tab_strip.h b/chrome/browser/views/tabs/base_tab_strip.h index ded0b07..244edb2 100644 --- a/chrome/browser/views/tabs/base_tab_strip.h +++ b/chrome/browser/views/tabs/base_tab_strip.h @@ -104,7 +104,7 @@ class BaseTabStrip : public views::View, virtual void TabTitleChangedNotLoading(int model_index) = 0; // Sets the tab data at the specified model index. - virtual void SetTabData(int model_index, const TabRendererData& data) = 0; + virtual void SetTabData(int model_index, const TabRendererData& data); // Returns the tab at the specified model index. virtual BaseTab* GetBaseTabAtModelIndex(int model_index) const; @@ -183,6 +183,9 @@ class BaseTabStrip : public views::View, // Starts the remove tab animation. virtual void StartRemoveTabAnimation(int model_index); + // Starts the mini-tab animation. + virtual void StartMiniTabAnimation(); + // Returns whether the highlight button should be highlighted after a remove. virtual bool ShouldHighlightCloseButtonAfterRemove() { return true; } diff --git a/chrome/browser/views/tabs/side_tab.cc b/chrome/browser/views/tabs/side_tab.cc index d456a5d..fab7bf2 100644 --- a/chrome/browser/views/tabs/side_tab.cc +++ b/chrome/browser/views/tabs/side_tab.cc @@ -80,7 +80,7 @@ void SideTab::Layout() { } void SideTab::Paint(gfx::Canvas* canvas) { - if (IsSelected() || !controller()) { + if (ShouldPaintHighlight()) { SkPaint paint; paint.setColor(kTabBackgroundColor); paint.setAntiAlias(true); @@ -100,6 +100,10 @@ gfx::Size SideTab::GetPreferredSize() { return gfx::Size(0, GetPreferredHeight()); } +bool SideTab::ShouldPaintHighlight() const { + return IsSelected() || !controller(); +} + bool SideTab::ShouldShowIcon() const { return data().mini || data().show_icon; } diff --git a/chrome/browser/views/tabs/side_tab.h b/chrome/browser/views/tabs/side_tab.h index d3b4236..9bc9631 100644 --- a/chrome/browser/views/tabs/side_tab.h +++ b/chrome/browser/views/tabs/side_tab.h @@ -28,6 +28,9 @@ class SideTab : public BaseTab { protected: virtual const gfx::Rect& title_bounds() const { return title_bounds_; } + // Returns true if the selected highlight should be rendered. + virtual bool ShouldPaintHighlight() const; + private: // Returns true if the icon should be shown. bool ShouldShowIcon() const; diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc index 586f9c4..4b97b08 100644 --- a/chrome/browser/views/tabs/side_tab_strip.cc +++ b/chrome/browser/views/tabs/side_tab_strip.cc @@ -4,16 +4,66 @@ #include "chrome/browser/views/tabs/side_tab_strip.h" +#include "app/l10n_util.h" +#include "app/resource_bundle.h" #include "chrome/browser/views/tabs/side_tab.h" +#include "chrome/browser/views/tabs/tab_strip_controller.h" #include "chrome/browser/view_ids.h" +#include "gfx/canvas.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "views/background.h" +#include "views/controls/button/image_button.h" namespace { const int kVerticalTabSpacing = 2; const int kTabStripWidth = 140; const SkColor kBackgroundColor = SkColorSetARGB(255, 209, 220, 248); +const SkColor kSeparatorColor = SkColorSetARGB(255, 151, 159, 179); + +// Height of the separator. +const int kSeparatorHeight = 1; + +// The new tab button is rendered using a SideTab. +class SideTabNewTabButton : public SideTab { + public: + explicit SideTabNewTabButton(TabStripController* controller); + + virtual bool ShouldPaintHighlight() const { return false; } + virtual bool IsSelected() const { return false; } + bool OnMousePressed(const views::MouseEvent& event); + void OnMouseReleased(const views::MouseEvent& event, bool canceled); + + private: + TabStripController* controller_; + + DISALLOW_COPY_AND_ASSIGN(SideTabNewTabButton); +}; + +SideTabNewTabButton::SideTabNewTabButton(TabStripController* controller) + : SideTab(NULL), + controller_(controller) { + // Never show a close button for the new tab button. + close_button()->SetVisible(false); + TabRendererData data; + data.favicon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_SIDETABS_NEW_TAB); + data.title = l10n_util::GetStringUTF16(IDS_NEW_TAB_TITLE); + SetData(data); } +bool SideTabNewTabButton::OnMousePressed(const views::MouseEvent& event) { + return true; +} + +void SideTabNewTabButton::OnMouseReleased(const views::MouseEvent& event, + bool canceled) { + if (!canceled && event.IsOnlyLeftMouseButton() && HitTest(event.location())) + controller_->CreateNewTab(); +} + +} // namespace + // static const int SideTabStrip::kTabStripInset = 3; @@ -21,9 +71,15 @@ const int SideTabStrip::kTabStripInset = 3; // SideTabStrip, public: SideTabStrip::SideTabStrip(TabStripController* controller) - : BaseTabStrip(controller, BaseTabStrip::VERTICAL_TAB_STRIP) { + : BaseTabStrip(controller, BaseTabStrip::VERTICAL_TAB_STRIP), + newtab_button_(new SideTabNewTabButton(controller)), + separator_(new views::View()) { SetID(VIEW_ID_TAB_STRIP); set_background(views::Background::CreateSolidBackground(kBackgroundColor)); + AddChildView(newtab_button_); + separator_->set_background( + views::Background::CreateSolidBackground(kSeparatorColor)); + AddChildView(separator_); } SideTabStrip::~SideTabStrip() { @@ -77,12 +133,6 @@ void SideTabStrip::SelectTabAt(int old_model_index, int new_model_index) { void SideTabStrip::TabTitleChangedNotLoading(int model_index) { } -void SideTabStrip::SetTabData(int model_index, const TabRendererData& data) { - BaseTab* tab = GetBaseTabAtModelIndex(model_index); - tab->SetData(data); - tab->SchedulePaint(); -} - gfx::Size SideTabStrip::GetPreferredSize() { return gfx::Size(kTabStripWidth, 0); } @@ -91,6 +141,11 @@ void SideTabStrip::PaintChildren(gfx::Canvas* canvas) { // Make sure the dragged tab appears on top of all others by paint it last. BaseTab* dragging_tab = NULL; + // Paint the new tab and separator first so that any tabs animating appear on + // top. + separator_->ProcessPaint(canvas); + newtab_button_->ProcessPaint(canvas); + for (int i = tab_count() - 1; i >= 0; --i) { BaseTab* tab = base_tab_at_tab_index(i); if (tab->dragging()) @@ -112,15 +167,40 @@ void SideTabStrip::GenerateIdealBounds() { layout_rect.Inset(kTabStripInset, kTabStripInset); int y = layout_rect.y(); + bool last_was_mini = true; + bool has_non_closing_tab = false; + separator_bounds_.SetRect(0, -kSeparatorHeight, width(), kSeparatorHeight); for (int i = 0; i < tab_count(); ++i) { BaseTab* tab = base_tab_at_tab_index(i); if (!tab->closing()) { + if (last_was_mini != tab->data().mini) { + if (has_non_closing_tab) { + separator_bounds_.SetRect(0, y, width(), kSeparatorHeight); + y += kSeparatorHeight + kVerticalTabSpacing; + } + newtab_button_bounds_.SetRect( + layout_rect.x(), y, layout_rect.width(), + newtab_button_->GetPreferredSize().height()); + y = newtab_button_bounds_.bottom() + kVerticalTabSpacing; + last_was_mini = tab->data().mini; + } gfx::Rect bounds = gfx::Rect(layout_rect.x(), y, layout_rect.width(), tab->GetPreferredSize().height()); set_ideal_bounds(i, bounds); y = bounds.bottom() + kVerticalTabSpacing; + has_non_closing_tab = true; } } + + if (last_was_mini) { + if (has_non_closing_tab) { + separator_bounds_.SetRect(0, y, width(), kSeparatorHeight); + y += kSeparatorHeight + kVerticalTabSpacing; + } + newtab_button_bounds_ = + gfx::Rect(layout_rect.x(), y, layout_rect.width(), + newtab_button_->GetPreferredSize().height()); + } } void SideTabStrip::StartInsertTabAnimation(int model_index, bool foreground) { @@ -165,4 +245,16 @@ void SideTabStrip::AnimateToIdealBounds() { if (!tab->closing() && !tab->dragging()) bounds_animator().AnimateViewTo(tab, ideal_bounds(i)); } + + bounds_animator().AnimateViewTo(newtab_button_, newtab_button_bounds_); + + bounds_animator().AnimateViewTo(separator_, separator_bounds_); +} + +void SideTabStrip::Layout() { + BaseTabStrip::Layout(); + + newtab_button_->SetBounds(newtab_button_bounds_); + + separator_->SetBounds(separator_bounds_); } diff --git a/chrome/browser/views/tabs/side_tab_strip.h b/chrome/browser/views/tabs/side_tab_strip.h index 7603b060..6e52e70 100644 --- a/chrome/browser/views/tabs/side_tab_strip.h +++ b/chrome/browser/views/tabs/side_tab_strip.h @@ -31,7 +31,6 @@ class SideTabStrip : public BaseTabStrip { virtual void RemoveTabAt(int model_index); virtual void SelectTabAt(int old_model_index, int new_model_index); virtual void TabTitleChangedNotLoading(int model_index); - virtual void SetTabData(int model_index, const TabRendererData& data); // views::View overrides: virtual gfx::Size GetPreferredSize(); @@ -45,8 +44,22 @@ class SideTabStrip : public BaseTabStrip { virtual void StartMoveTabAnimation(); virtual void StopAnimating(bool layout); virtual void AnimateToIdealBounds(); + virtual void Layout(); private: + // The "New Tab" button. + views::View* newtab_button_; + + // Ideal bounds of the new tab button. + gfx::Rect newtab_button_bounds_; + + // Separator between mini-tabs and the new tab button. The separator is + // positioned above the visible area if there are no mini-tabs. + views::View* separator_; + + // Bounds of the sepatator. + gfx::Rect separator_bounds_; + DISALLOW_COPY_AND_ASSIGN(SideTabStrip); }; diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 23d2389..857122a 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -303,20 +303,6 @@ void TabStrip::TabTitleChangedNotLoading(int model_index) { tab->StartMiniTabTitleAnimation(); } -void TabStrip::SetTabData(int model_index, const TabRendererData& data) { - Tab* tab = GetTabAtModelIndex(model_index); - bool mini_state_changed = tab->data().mini != data.mini; - tab->SetData(data); - tab->SchedulePaint(); - - if (mini_state_changed) { - if (GetWindow() && GetWindow()->IsVisible()) - StartMiniTabAnimation(); - else - Layout(); - } -} - void TabStrip::StartHighlight(int model_index) { GetTabAtModelIndex(model_index)->StartPulse(); } diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index f547ca3..d1e9b29 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -73,7 +73,6 @@ class TabStrip : public BaseTabStrip, virtual void RemoveTabAt(int model_index); virtual void SelectTabAt(int old_model_index, int new_model_index); virtual void TabTitleChangedNotLoading(int model_index); - virtual void SetTabData(int model_index, const TabRendererData& data); virtual void StartHighlight(int model_index); virtual void StopAllHighlighting(); virtual BaseTab* CreateTabForDragging(); |