| Index: chrome/browser/ui/views/sidebar/sidebar_tab_strip.cc
|
| ===================================================================
|
| --- chrome/browser/ui/views/sidebar/sidebar_tab_strip.cc (revision 0)
|
| +++ chrome/browser/ui/views/sidebar/sidebar_tab_strip.cc (revision 0)
|
| @@ -0,0 +1,223 @@
|
| +// 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.
|
| +
|
| +#include "chrome/browser/ui/views/sidebar/sidebar_tab_strip.h"
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/stl_util-inl.h"
|
| +#include "chrome/browser/defaults.h"
|
| +#include "chrome/browser/themes/browser_theme_provider.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/view_ids.h"
|
| +#include "chrome/browser/ui/views/sidebar/sidebar_tab.h"
|
| +#include "chrome/browser/ui/views/sidebar/sidebar_tab_strip_controller.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "gfx/canvas_skia.h"
|
| +#include "gfx/path.h"
|
| +#include "gfx/point.h"
|
| +#include "gfx/rect.h"
|
| +#include "gfx/size.h"
|
| +#include "grit/generated_resources.h"
|
| +#include "grit/theme_resources.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| +#include "views/controls/image_view.h"
|
| +#include "views/widget/default_theme_provider.h"
|
| +#include "views/window/non_client_view.h"
|
| +#include "views/window/window.h"
|
| +
|
| +#undef min
|
| +#undef max
|
| +
|
| +namespace {
|
| +const int kTabOffset = -1;
|
| +const int kFisrtTabInitalHeight = 6;
|
| +} // namespace
|
| +
|
| +// SidebarTabStrip, public:
|
| +
|
| +SidebarTabStrip::SidebarTabStrip(SidebarTabStripController* controller)
|
| + : SidebarBaseTabStrip(controller),
|
| + animation_container_(new ui::AnimationContainer()) {
|
| +}
|
| +
|
| +SidebarTabStrip::~SidebarTabStrip() {
|
| + // The animations may reference the tabs. Shut down the animation before we
|
| + // delete the tabs.
|
| + StopAnimating();
|
| +
|
| + // The children (tabs) may callback to us from their destructor. Delete them
|
| + // so that if they call back we aren't in a weird state.
|
| + RemoveAllChildViews(true);
|
| +}
|
| +
|
| +// SidebarTabStrip, views::View overrides:
|
| +
|
| +void SidebarTabStrip::Layout() {
|
| + UpdateViewBounds();
|
| +
|
| + SchedulePaint();
|
| +}
|
| +
|
| +views::View* SidebarTabStrip::GetViewForPoint(const gfx::Point& point) {
|
| + // Return any view that isn't a SidebarTab or this SidebarTabStrip
|
| + // immediately. We don't want to interfere.
|
| + views::View* v = View::GetViewForPoint(point);
|
| + if (v && v != this && v->GetClassName() != SidebarTab::kViewClassName)
|
| + return v;
|
| +
|
| + // The display order doesn't necessarily match the child list order, so we
|
| + // walk the display list hit-testing Tabs. Since the selected tab always
|
| + // renders on top of adjacent tabs, it needs to be hit-tested before any
|
| + // left-adjacent SidebarTab, so we look ahead for it as we walk.
|
| + for (int i = 0; i < tab_count(); ++i) {
|
| + SidebarBaseTab* next_tab =
|
| + i < (tab_count() - 1) ? base_tab_at_tab_index(i + 1) : NULL;
|
| + if (next_tab && next_tab->IsSelected() && IsPointInTab(next_tab, point))
|
| + return next_tab;
|
| + SidebarBaseTab* tab = base_tab_at_tab_index(i);
|
| + if (IsPointInTab(tab, point))
|
| + return tab;
|
| + }
|
| +
|
| + // No need to do any floating view stuff, we don't use them
|
| + // in the SidebarTabStrip.
|
| + return this;
|
| +}
|
| +
|
| +// Overridden to support automation. See automation_proxy_uitest.cc.
|
| +views::View* SidebarTabStrip::GetViewByID(int view_id) const {
|
| + if (tab_count() > 0) {
|
| + if (view_id == VIEW_ID_TAB_LAST)
|
| + return base_tab_at_tab_index(tab_count() - 1);
|
| + if ((view_id >= VIEW_ID_TAB_0) && (view_id < VIEW_ID_TAB_LAST)) {
|
| + int index = view_id - VIEW_ID_TAB_0;
|
| + if (index >= 0 && index < tab_count())
|
| + return base_tab_at_tab_index(index);
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| + return View::GetViewByID(view_id);
|
| +}
|
| +
|
| +AccessibilityTypes::Role SidebarTabStrip::GetAccessibleRole() {
|
| + return AccessibilityTypes::ROLE_PAGETABLIST;
|
| +}
|
| +
|
| +void SidebarTabStrip::PaintChildren(gfx::Canvas* canvas) {
|
| + // Painting closing tabs first, so they appear behind the regular ones.
|
| + for (int i = tab_count() - 1; i >= 0; --i) {
|
| + SidebarBaseTab* tab = base_tab_at_tab_index(i);
|
| + // We must ask the _Tab's_ model, not ourselves, because in some situations
|
| + // the model will be different to this object, e.g. when a SidebarTab
|
| + // is being removed after its TabContents has been destroyed.
|
| + if (tab->closing())
|
| + tab->ProcessPaint(canvas);
|
| + }
|
| +
|
| + // Tabs are painted in reverse order, so they stack to the bottom.
|
| + SidebarBaseTab* selected_tab = NULL;
|
| +
|
| + // Paint all non-closing tabs, except the selected one.
|
| + for (int i = tab_count() - 1; i >= 0; --i) {
|
| + SidebarBaseTab* tab = base_tab_at_tab_index(i);
|
| + if (!tab->closing()) {
|
| + if (!tab->IsSelected())
|
| + tab->ProcessPaint(canvas);
|
| + else
|
| + selected_tab = tab;
|
| + }
|
| + }
|
| +
|
| + // Paint the selected tab last, so it overlaps all the others.
|
| + if (selected_tab)
|
| + selected_tab->ProcessPaint(canvas);
|
| +}
|
| +
|
| +// SidebarBaseTabStrip overrides:
|
| +
|
| +SidebarBaseTab* SidebarTabStrip::CreateTab() {
|
| + SidebarTab* tab = new SidebarTab(this);
|
| + tab->set_animation_container(animation_container_.get());
|
| + return tab;
|
| +}
|
| +
|
| +void SidebarTabStrip::StartInsertTabAnimation(int model_index) {
|
| + // The only tab should not be animated, it looks wierd.
|
| + DCHECK_GT(tab_count(), 1);
|
| +
|
| + GenerateIdealBounds();
|
| +
|
| + // Override inserted tab bounds to achieve a desired animation effect.
|
| + int tab_data_index = ModelIndexToTabIndex(model_index);
|
| + SidebarBaseTab* tab = base_tab_at_tab_index(tab_data_index);
|
| + if (tab_data_index == 0) {
|
| + // First tab is animated from its own ideal bounds().y(), so in combination
|
| + // with tab strip position update it looks like this new tab grows and
|
| + // pushes all other tabs up.
|
| + tab->SetBounds(0, ideal_bounds(tab_data_index).y(),
|
| + ideal_bounds(tab_data_index).width(), kFisrtTabInitalHeight);
|
| + } else {
|
| + // Non-first tabs are animated from the previous tab position, so they
|
| + // slide up from underneath the previous tab and pushes the rest of the tabs
|
| + // up.
|
| + SidebarBaseTab* previous_tab = base_tab_at_tab_index(tab_data_index - 1);
|
| + tab->SetBoundsRect(previous_tab->bounds());
|
| + }
|
| +
|
| + AnimateToIdealBounds();
|
| +}
|
| +
|
| +void SidebarTabStrip::StartRemoveTabAnimation(int model_index) {
|
| + // Mark the tab as closing.
|
| + SidebarBaseTab* tab = GetBaseTabAtModelIndex(model_index);
|
| + tab->set_closing(true);
|
| +
|
| + // Start an animation for the tabs.
|
| + GenerateIdealBounds();
|
| + AnimateToIdealBounds();
|
| +}
|
| +
|
| +void SidebarTabStrip::GenerateIdealBounds() {
|
| + if (tab_count() == 0)
|
| + return;
|
| +
|
| + int non_closing_tab_count = 0;
|
| + for (int i = 0; i < tab_count(); ++i) {
|
| + if (!base_tab_at_tab_index(i)->closing())
|
| + ++non_closing_tab_count;
|
| + }
|
| +
|
| + int tab_width = SidebarTab::GetStandardSize().width();
|
| + int tab_height = SidebarTab::GetStandardSize().height();
|
| + int tab_y = non_closing_tab_count == 0 ? 0 :
|
| + (non_closing_tab_count - 1) * (tab_height + kTabOffset);
|
| +
|
| + bool first_non_closing_tab = true;
|
| + gfx::Rect current_tab_bounds(0, tab_y, tab_width, tab_height);
|
| +
|
| + for (int i = 0; i < tab_count(); ++i) {
|
| + if (!base_tab_at_tab_index(i)->closing()) {
|
| + if (!first_non_closing_tab) {
|
| + tab_y -= tab_height + kTabOffset;
|
| + current_tab_bounds.set_y(tab_y);
|
| + } else {
|
| + first_non_closing_tab = false;
|
| + }
|
| + }
|
| + set_ideal_bounds(i, current_tab_bounds);
|
| + }
|
| +}
|
| +
|
| +// SidebarTabStrip, private:
|
| +
|
| +bool SidebarTabStrip::IsPointInTab(
|
| + SidebarBaseTab* tab,
|
| + const gfx::Point& point_in_tab_strip_coords) {
|
| + gfx::Point point_in_tab_coords(point_in_tab_strip_coords);
|
| + View::ConvertPointToView(this, tab, &point_in_tab_coords);
|
| + return tab->HitTest(point_in_tab_coords);
|
| +}
|
| +
|
|
|
| Property changes on: chrome\browser\ui\views\sidebar\sidebar_tab_strip.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|