summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs/base_tab_strip.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tabs/base_tab_strip.cc')
-rw-r--r--chrome/browser/views/tabs/base_tab_strip.cc473
1 files changed, 0 insertions, 473 deletions
diff --git a/chrome/browser/views/tabs/base_tab_strip.cc b/chrome/browser/views/tabs/base_tab_strip.cc
deleted file mode 100644
index 4f844ed..0000000
--- a/chrome/browser/views/tabs/base_tab_strip.cc
+++ /dev/null
@@ -1,473 +0,0 @@
-// 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/views/tabs/base_tab_strip.h"
-
-#include "base/logging.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/browser/views/tabs/dragged_tab_controller.h"
-#include "chrome/browser/views/tabs/tab_strip_controller.h"
-#include "views/widget/root_view.h"
-#include "views/window/window.h"
-
-#if defined(OS_WIN)
-#include "app/win_util.h"
-#include "views/widget/widget_win.h"
-#endif
-
-namespace {
-
-// Animation delegate used when a dragged tab is released. When done sets the
-// dragging state to false.
-class ResetDraggingStateDelegate
- : public views::BoundsAnimator::OwnedAnimationDelegate {
- public:
- explicit ResetDraggingStateDelegate(BaseTab* tab) : tab_(tab) {
- }
-
- virtual void AnimationEnded(const Animation* animation) {
- tab_->set_dragging(false);
- }
-
- virtual void AnimationCanceled(const Animation* animation) {
- tab_->set_dragging(false);
- }
-
- private:
- BaseTab* tab_;
-
- DISALLOW_COPY_AND_ASSIGN(ResetDraggingStateDelegate);
-};
-
-} // namespace
-
-// AnimationDelegate used when removing a tab. Does the necessary cleanup when
-// done.
-class BaseTabStrip::RemoveTabDelegate
- : public views::BoundsAnimator::OwnedAnimationDelegate {
- public:
- RemoveTabDelegate(BaseTabStrip* tab_strip, BaseTab* tab)
- : tabstrip_(tab_strip),
- tab_(tab) {
- }
-
- virtual void AnimationEnded(const Animation* animation) {
- CompleteRemove();
- }
-
- virtual void AnimationCanceled(const Animation* animation) {
- // We can be canceled for two interesting reasons:
- // . The tab we reference was dragged back into the tab strip. In this case
- // we don't want to remove the tab (closing is false).
- // . The drag was completed before the animation completed
- // (DestroyDraggedSourceTab). In this case we need to remove the tab
- // (closing is true).
- if (tab_->closing())
- CompleteRemove();
- }
-
- private:
- void CompleteRemove() {
- if (!tab_->closing()) {
- // The tab was added back yet we weren't canceled. This shouldn't happen.
- NOTREACHED();
- return;
- }
- tabstrip_->RemoveAndDeleteTab(tab_);
- HighlightCloseButton();
- }
-
- // When the animation completes, we send the Container a message to simulate
- // a mouse moved event at the current mouse position. This tickles the Tab
- // the mouse is currently over to show the "hot" state of the close button.
- void HighlightCloseButton() {
- if (tabstrip_->IsDragSessionActive() ||
- !tabstrip_->ShouldHighlightCloseButtonAfterRemove()) {
- // This function is not required (and indeed may crash!) for removes
- // spawned by non-mouse closes and drag-detaches.
- return;
- }
-
-#if defined(OS_WIN)
- views::Widget* widget = tabstrip_->GetWidget();
- // This can be null during shutdown. See http://crbug.com/42737.
- if (!widget)
- return;
- // Force the close button (that slides under the mouse) to highlight by
- // saying the mouse just moved, but sending the same coordinates.
- DWORD pos = GetMessagePos();
- POINT cursor_point = {GET_X_LPARAM(pos), GET_Y_LPARAM(pos)};
- MapWindowPoints(NULL, widget->GetNativeView(), &cursor_point, 1);
-
- static_cast<views::WidgetWin*>(widget)->ResetLastMouseMoveFlag();
- // Return to message loop - otherwise we may disrupt some operation that's
- // in progress.
- SendMessage(widget->GetNativeView(), WM_MOUSEMOVE, 0,
- MAKELPARAM(cursor_point.x, cursor_point.y));
-#else
- NOTIMPLEMENTED();
-#endif
- }
-
- BaseTabStrip* tabstrip_;
- BaseTab* tab_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoveTabDelegate);
-};
-
-BaseTabStrip::BaseTabStrip(TabStripController* controller, Type type)
- : controller_(controller),
- type_(type),
- attaching_dragged_tab_(false),
- ALLOW_THIS_IN_INITIALIZER_LIST(bounds_animator_(this)) {
-}
-
-BaseTabStrip::~BaseTabStrip() {
-}
-
-void BaseTabStrip::UpdateLoadingAnimations() {
- controller_->UpdateLoadingAnimations();
-}
-
-bool BaseTabStrip::IsAnimating() const {
- return bounds_animator_.IsAnimating();
-}
-
-BaseTab* BaseTabStrip::GetSelectedBaseTab() const {
- return GetBaseTabAtModelIndex(controller_->GetSelectedIndex());
-}
-
-void BaseTabStrip::AddTabAt(int model_index,
- bool foreground,
- const TabRendererData& data) {
- BaseTab* tab = CreateTab();
- tab->SetData(data);
-
- TabData d = { tab, gfx::Rect() };
- tab_data_.insert(tab_data_.begin() + ModelIndexToTabIndex(model_index), d);
-
- AddChildView(tab);
-
- // Don't animate the first tab, it looks weird, and don't animate anything
- // if the containing window isn't visible yet.
- if (tab_count() > 1 && GetWindow() && GetWindow()->IsVisible())
- StartInsertTabAnimation(model_index, foreground);
- else
- DoLayout();
-}
-
-void BaseTabStrip::MoveTab(int from_model_index, int to_model_index) {
- int from_tab_data_index = ModelIndexToTabIndex(from_model_index);
-
- BaseTab* tab = tab_data_[from_tab_data_index].tab;
- tab_data_.erase(tab_data_.begin() + from_tab_data_index);
-
- TabData data = {tab, gfx::Rect()};
-
- int to_tab_data_index = ModelIndexToTabIndex(to_model_index);
-
- tab_data_.insert(tab_data_.begin() + to_tab_data_index, data);
-
- 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
- DoLayout();
- }
-}
-
-BaseTab* BaseTabStrip::GetBaseTabAtModelIndex(int model_index) const {
- return base_tab_at_tab_index(ModelIndexToTabIndex(model_index));
-}
-
-int BaseTabStrip::GetModelIndexOfBaseTab(const BaseTab* tab) const {
- for (int i = 0, model_index = 0; i < tab_count(); ++i) {
- BaseTab* current_tab = base_tab_at_tab_index(i);
- if (!current_tab->closing()) {
- if (current_tab == tab)
- return model_index;
- model_index++;
- }
- }
- return -1;
-}
-
-int BaseTabStrip::GetModelCount() const {
- return controller_->GetCount();
-}
-
-bool BaseTabStrip::IsValidModelIndex(int model_index) const {
- return controller_->IsValidIndex(model_index);
-}
-
-int BaseTabStrip::ModelIndexToTabIndex(int model_index) const {
- int current_model_index = 0;
- for (int i = 0; i < tab_count(); ++i) {
- if (!base_tab_at_tab_index(i)->closing()) {
- if (current_model_index == model_index)
- return i;
- current_model_index++;
- }
- }
- return static_cast<int>(tab_data_.size());
-}
-
-bool BaseTabStrip::IsDragSessionActive() const {
- return drag_controller_.get() != NULL;
-}
-
-void BaseTabStrip::SelectTab(BaseTab* tab) {
- int model_index = GetModelIndexOfBaseTab(tab);
- if (IsValidModelIndex(model_index))
- controller_->SelectTab(model_index);
-}
-
-void BaseTabStrip::CloseTab(BaseTab* tab) {
- // Find the closest model index. We do this so that the user can rapdily close
- // tabs and have the close click close the next tab.
- int model_index = 0;
- for (int i = 0; i < tab_count(); ++i) {
- BaseTab* current_tab = base_tab_at_tab_index(i);
- if (current_tab == tab)
- break;
- if (!current_tab->closing())
- model_index++;
- }
-
- if (IsValidModelIndex(model_index))
- controller_->CloseTab(model_index);
-}
-
-void BaseTabStrip::ShowContextMenu(BaseTab* tab, const gfx::Point& p) {
- controller_->ShowContextMenu(tab, p);
-}
-
-bool BaseTabStrip::IsTabSelected(const BaseTab* tab) const {
- int model_index = GetModelIndexOfBaseTab(tab);
- return IsValidModelIndex(model_index) &&
- controller_->IsTabSelected(model_index);
-}
-
-bool BaseTabStrip::IsTabPinned(const BaseTab* tab) const {
- if (tab->closing())
- return false;
-
- int model_index = GetModelIndexOfBaseTab(tab);
- return IsValidModelIndex(model_index) &&
- controller_->IsTabPinned(model_index);
-}
-
-bool BaseTabStrip::IsTabCloseable(const BaseTab* tab) const {
- int model_index = GetModelIndexOfBaseTab(tab);
- return !IsValidModelIndex(model_index) ||
- controller_->IsTabCloseable(model_index);
-}
-
-void BaseTabStrip::MaybeStartDrag(BaseTab* tab,
- const views::MouseEvent& event) {
- // Don't accidentally start any drag operations during animations if the
- // mouse is down... during an animation tabs are being resized automatically,
- // so the View system can misinterpret this easily if the mouse is down that
- // the user is dragging.
- if (IsAnimating() || tab->closing() ||
- controller_->HasAvailableDragActions() == 0) {
- return;
- }
- int model_index = GetModelIndexOfBaseTab(tab);
- if (!IsValidModelIndex(model_index)) {
- CHECK(false);
- return;
- }
- drag_controller_.reset(new DraggedTabController(tab, this));
- drag_controller_->CaptureDragInfo(tab, event.location());
-}
-
-void BaseTabStrip::ContinueDrag(const views::MouseEvent& event) {
- // We can get called even if |MaybeStartDrag| wasn't called in the event of
- // a TabStrip animation when the mouse button is down. In this case we should
- // _not_ continue the drag because it can lead to weird bugs.
- if (drag_controller_.get()) {
- bool started_drag = drag_controller_->started_drag();
- drag_controller_->Drag();
- if (drag_controller_->started_drag() && !started_drag) {
- // The drag just started. Redirect mouse events to us to that the tab that
- // originated the drag can be safely deleted.
- GetRootView()->SetMouseHandler(this);
- }
- }
-}
-
-bool BaseTabStrip::EndDrag(bool canceled) {
- if (!drag_controller_.get())
- return false;
- bool started_drag = drag_controller_->started_drag();
- drag_controller_->EndDrag(canceled);
- return started_drag;
-}
-
-BaseTab* BaseTabStrip::GetTabAt(BaseTab* tab,
- const gfx::Point& tab_in_tab_coordinates) {
- gfx::Point local_point = tab_in_tab_coordinates;
- ConvertPointToView(tab, this, &local_point);
- views::View* view = GetViewForPoint(local_point);
- if (!view)
- return NULL; // No tab contains the point.
-
- // Walk up the view hierarchy until we find a tab, or the TabStrip.
- while (view && view != this && view->GetID() != VIEW_ID_TAB)
- view = view->GetParent();
-
- return view && view->GetID() == VIEW_ID_TAB ?
- static_cast<BaseTab*>(view) : NULL;
-}
-
-void BaseTabStrip::Layout() {
- // Only do a layout if our size changed.
- if (last_layout_size_ == size())
- return;
- DoLayout();
-}
-
-bool BaseTabStrip::OnMouseDragged(const views::MouseEvent& event) {
- if (drag_controller_.get())
- drag_controller_->Drag();
- return true;
-}
-
-void BaseTabStrip::OnMouseReleased(const views::MouseEvent& event,
- bool canceled) {
- EndDrag(canceled);
-}
-
-void BaseTabStrip::StartRemoveTabAnimation(int model_index) {
- PrepareForAnimation();
-
- // Mark the tab as closing.
- BaseTab* tab = GetBaseTabAtModelIndex(model_index);
- tab->set_closing(true);
-
- // Start an animation for the tabs.
- GenerateIdealBounds();
- AnimateToIdealBounds();
-
- // Animate the tab being closed to 0x0.
- gfx::Rect tab_bounds = tab->bounds();
- if (type() == HORIZONTAL_TAB_STRIP)
- tab_bounds.set_width(0);
- else
- tab_bounds.set_height(0);
- bounds_animator_.AnimateViewTo(tab, tab_bounds);
-
- // Register delegate to do cleanup when done, BoundsAnimator takes
- // ownership of RemoveTabDelegate.
- bounds_animator_.SetAnimationDelegate(tab, new RemoveTabDelegate(this, tab),
- true);
-}
-
-void BaseTabStrip::StartMiniTabAnimation() {
- PrepareForAnimation();
-
- GenerateIdealBounds();
- AnimateToIdealBounds();
-}
-
-void BaseTabStrip::RemoveAndDeleteTab(BaseTab* tab) {
- int tab_data_index = TabIndexOfTab(tab);
-
- DCHECK(tab_data_index != -1);
-
- // Remove the Tab from the TabStrip's list...
- tab_data_.erase(tab_data_.begin() + tab_data_index);
-
- delete tab;
-}
-
-int BaseTabStrip::TabIndexOfTab(BaseTab* tab) const {
- for (int i = 0; i < tab_count(); ++i) {
- if (base_tab_at_tab_index(i) == tab)
- return i;
- }
- return -1;
-}
-
-void BaseTabStrip::DestroyDragController() {
- if (IsDragSessionActive())
- drag_controller_.reset(NULL);
-}
-
-void BaseTabStrip::StartedDraggingTab(BaseTab* tab) {
- PrepareForAnimation();
-
- // Reset the dragging state of all other tabs. We do this as the painting code
- // only handles one tab being dragged at a time. If another tab is marked as
- // dragging, it should also be closing.
- for (int i = 0; i < tab_count(); ++i)
- base_tab_at_tab_index(i)->set_dragging(false);
-
- tab->set_dragging(true);
-
- // Stop any animations on the tab.
- bounds_animator_.StopAnimatingView(tab);
-
- // Move the tab to its ideal bounds.
- GenerateIdealBounds();
- int tab_data_index = TabIndexOfTab(tab);
- DCHECK(tab_data_index != -1);
- tab->SetBounds(ideal_bounds(tab_data_index));
- SchedulePaint();
-}
-
-void BaseTabStrip::StoppedDraggingTab(BaseTab* tab) {
- int tab_data_index = TabIndexOfTab(tab);
- if (tab_data_index == -1) {
- // The tab was removed before the drag completed. Don't do anything.
- return;
- }
-
- PrepareForAnimation();
-
- // Animate the view back to its correct position.
- GenerateIdealBounds();
- AnimateToIdealBounds();
- bounds_animator_.AnimateViewTo(tab, ideal_bounds(TabIndexOfTab(tab)));
-
- // Install a delegate to reset the dragging state when done. We have to leave
- // dragging true for the tab otherwise it'll draw beneath the new tab button.
- bounds_animator_.SetAnimationDelegate(tab,
- new ResetDraggingStateDelegate(tab),
- true);
-}
-
-void BaseTabStrip::PrepareForAnimation() {
- if (!IsDragSessionActive() && !DraggedTabController::IsAttachedTo(this)) {
- for (int i = 0; i < tab_count(); ++i)
- base_tab_at_tab_index(i)->set_dragging(false);
- }
-}
-
-AnimationDelegate* BaseTabStrip::CreateRemoveTabDelegate(BaseTab* tab) {
- return new RemoveTabDelegate(this, tab);
-}
-
-void BaseTabStrip::DoLayout() {
- last_layout_size_ = size();
-
- StopAnimating(false);
-
- GenerateIdealBounds();
-
- for (int i = 0; i < tab_count(); ++i)
- tab_data_[i].tab->SetBounds(tab_data_[i].ideal_bounds);
-
- SchedulePaint();
-}