summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tabs')
-rw-r--r--chrome/browser/views/tabs/base_tab.cc480
-rw-r--r--chrome/browser/views/tabs/base_tab.h197
-rw-r--r--chrome/browser/views/tabs/base_tab_strip.cc473
-rw-r--r--chrome/browser/views/tabs/base_tab_strip.h259
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.cc428
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.h112
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.cc1341
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.h332
-rw-r--r--chrome/browser/views/tabs/dragged_tab_view.cc222
-rw-r--r--chrome/browser/views/tabs/dragged_tab_view.h96
-rw-r--r--chrome/browser/views/tabs/native_view_photobooth.h39
-rw-r--r--chrome/browser/views/tabs/native_view_photobooth_gtk.cc34
-rw-r--r--chrome/browser/views/tabs/native_view_photobooth_gtk.h25
-rw-r--r--chrome/browser/views/tabs/native_view_photobooth_win.cc165
-rw-r--r--chrome/browser/views/tabs/native_view_photobooth_win.h53
-rw-r--r--chrome/browser/views/tabs/side_tab.cc114
-rw-r--r--chrome/browser/views/tabs/side_tab.h37
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.cc260
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.h60
-rw-r--r--chrome/browser/views/tabs/tab.cc610
-rw-r--r--chrome/browser/views/tabs/tab.h134
-rw-r--r--chrome/browser/views/tabs/tab_controller.h52
-rw-r--r--chrome/browser/views/tabs/tab_dragging_test.cc515
-rw-r--r--chrome/browser/views/tabs/tab_renderer_data.h39
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc982
-rw-r--r--chrome/browser/views/tabs/tab_strip.h280
-rw-r--r--chrome/browser/views/tabs/tab_strip_controller.h66
27 files changed, 47 insertions, 7358 deletions
diff --git a/chrome/browser/views/tabs/base_tab.cc b/chrome/browser/views/tabs/base_tab.cc
deleted file mode 100644
index fa752b3..0000000
--- a/chrome/browser/views/tabs/base_tab.cc
+++ /dev/null
@@ -1,480 +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.h"
-
-#include <limits>
-
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "app/slide_animation.h"
-#include "app/theme_provider.h"
-#include "app/throb_animation.h"
-#include "base/command_line.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/tabs/tab_controller.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/common/chrome_switches.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/favicon_size.h"
-#include "gfx/font.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "views/controls/button/image_button.h"
-
-#ifdef WIN32
-#include "app/win_util.h"
-#endif
-
-// How long the pulse throb takes.
-static const int kPulseDurationMs = 200;
-
-// How long the hover state takes.
-static const int kHoverDurationMs = 90;
-
-namespace {
-
-////////////////////////////////////////////////////////////////////////////////
-// TabCloseButton
-//
-// This is a Button subclass that causes middle clicks to be forwarded to the
-// parent View by explicitly not handling them in OnMousePressed.
-class TabCloseButton : public views::ImageButton {
- public:
- explicit TabCloseButton(views::ButtonListener* listener)
- : views::ImageButton(listener) {
- }
- virtual ~TabCloseButton() {}
-
- virtual bool OnMousePressed(const views::MouseEvent& event) {
- bool handled = ImageButton::OnMousePressed(event);
- // Explicitly mark midle-mouse clicks as non-handled to ensure the tab
- // sees them.
- return event.IsOnlyMiddleMouseButton() ? false : handled;
- }
-
- // We need to let the parent know about mouse state so that it
- // can highlight itself appropriately. Note that Exit events
- // fire before Enter events, so this works.
- virtual void OnMouseEntered(const views::MouseEvent& event) {
- CustomButton::OnMouseEntered(event);
- GetParent()->OnMouseEntered(event);
- }
-
- virtual void OnMouseExited(const views::MouseEvent& event) {
- CustomButton::OnMouseExited(event);
- GetParent()->OnMouseExited(event);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
-};
-
-} // namespace
-
-// static
-gfx::Font* BaseTab::font_ = NULL;
-// static
-int BaseTab::font_height_ = 0;
-
-////////////////////////////////////////////////////////////////////////////////
-// FaviconCrashAnimation
-//
-// A custom animation subclass to manage the favicon crash animation.
-class BaseTab::FavIconCrashAnimation : public LinearAnimation,
- public AnimationDelegate {
- public:
- explicit FavIconCrashAnimation(BaseTab* target)
- : ALLOW_THIS_IN_INITIALIZER_LIST(LinearAnimation(1000, 25, this)),
- target_(target) {
- }
- virtual ~FavIconCrashAnimation() {}
-
- // Animation overrides:
- virtual void AnimateToState(double state) {
- const double kHidingOffset = 27;
-
- if (state < .5) {
- target_->SetFavIconHidingOffset(
- static_cast<int>(floor(kHidingOffset * 2.0 * state)));
- } else {
- target_->DisplayCrashedFavIcon();
- target_->SetFavIconHidingOffset(
- static_cast<int>(
- floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset))));
- }
- }
-
- // AnimationDelegate overrides:
- virtual void AnimationCanceled(const Animation* animation) {
- target_->SetFavIconHidingOffset(0);
- }
-
- private:
- BaseTab* target_;
-
- DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation);
-};
-
-BaseTab::BaseTab(TabController* controller)
- : controller_(controller),
- closing_(false),
- dragging_(false),
- loading_animation_frame_(0),
- throbber_disabled_(false),
- theme_provider_(NULL),
- fav_icon_hiding_offset_(0),
- should_display_crashed_favicon_(false) {
- BaseTab::InitResources();
-
- SetID(VIEW_ID_TAB);
-
- // Add the Close Button.
- close_button_ = new TabCloseButton(this);
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- close_button_->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_TAB_CLOSE));
- close_button_->SetImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_TAB_CLOSE_H));
- close_button_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_TAB_CLOSE_P));
- close_button_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB));
- close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
- // Disable animation so that the red danger sign shows up immediately
- // to help avoid mis-clicks.
- close_button_->SetAnimationDuration(0);
- AddChildView(close_button_);
-
- SetContextMenuController(this);
-}
-
-BaseTab::~BaseTab() {
-}
-
-void BaseTab::SetData(const TabRendererData& data) {
- TabRendererData old(data_);
- data_ = data;
-
- if (data_.crashed) {
- if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation())
- StartCrashAnimation();
- } else {
- if (IsPerformingCrashAnimation())
- StopCrashAnimation();
- ResetCrashedFavIcon();
- }
-
- // Sets the accessible name for the tab.
- SetAccessibleName(UTF16ToWide(data_.title));
-
- DataChanged(old);
-
- Layout();
-}
-
-void BaseTab::UpdateLoadingAnimation(TabRendererData::NetworkState state) {
- // If this is an extension app and a command line flag is set,
- // then disable the throbber.
- throbber_disabled_ = data().app &&
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kAppsNoThrob);
-
- if (throbber_disabled_)
- return;
-
- if (state == data_.network_state &&
- state == TabRendererData::NETWORK_STATE_NONE) {
- // If the network state is none and hasn't changed, do nothing. Otherwise we
- // need to advance the animation frame.
- return;
- }
-
- TabRendererData::NetworkState old_state = data_.network_state;
- data_.network_state = state;
- AdvanceLoadingAnimation(old_state, state);
-}
-
-void BaseTab::StartPulse() {
- if (!pulse_animation_.get()) {
- pulse_animation_.reset(new ThrobAnimation(this));
- pulse_animation_->SetSlideDuration(kPulseDurationMs);
- if (animation_container_.get())
- pulse_animation_->SetContainer(animation_container_.get());
- }
- pulse_animation_->Reset();
- pulse_animation_->StartThrobbing(std::numeric_limits<int>::max());
-}
-
-void BaseTab::StopPulse() {
- if (!pulse_animation_.get())
- return;
-
- pulse_animation_->Stop(); // Do stop so we get notified.
- pulse_animation_.reset(NULL);
-}
-
-bool BaseTab::IsSelected() const {
- return controller() ? controller()->IsTabSelected(this) : true;
-}
-
-bool BaseTab::IsCloseable() const {
- return controller() ? controller()->IsTabCloseable(this) : true;
-}
-
-void BaseTab::OnMouseEntered(const views::MouseEvent& e) {
- if (!hover_animation_.get()) {
- hover_animation_.reset(new SlideAnimation(this));
- hover_animation_->SetContainer(animation_container_.get());
- hover_animation_->SetSlideDuration(kHoverDurationMs);
- }
- hover_animation_->SetTweenType(Tween::EASE_OUT);
- hover_animation_->Show();
-}
-
-void BaseTab::OnMouseExited(const views::MouseEvent& e) {
- hover_animation_->SetTweenType(Tween::EASE_IN);
- hover_animation_->Hide();
-}
-
-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
- // it was in the background.
- bool just_selected = !IsSelected();
- if (just_selected)
- controller()->SelectTab(this);
- controller()->MaybeStartDrag(this, event);
- }
- return true;
-}
-
-bool BaseTab::OnMouseDragged(const views::MouseEvent& 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
- // so, bail immediately, since our members are already dead and we shouldn't
- // do anything else except drop the tab where it is.
- if (controller()->EndDrag(canceled))
- return;
-
- // Close tab on middle click, but only if the button is released over the tab
- // (normal windows behavior is to discard presses of a UI element where the
- // releases happen off the element).
- if (event.IsMiddleMouseButton()) {
- if (HitTest(event.location())) {
- controller()->CloseTab(this);
- } else if (closing_) {
- // We're animating closed and a middle mouse button was pushed on us but
- // we don't contain the mouse anymore. We assume the user is clicking
- // quicker than the animation and we should close the tab that falls under
- // the mouse.
- BaseTab* closest_tab = controller()->GetTabAt(this, event.location());
- if (closest_tab)
- controller()->CloseTab(closest_tab);
- }
- }
-}
-
-bool BaseTab::GetTooltipText(const gfx::Point& p, std::wstring* tooltip) {
- if (data_.title.empty())
- return false;
-
- std::wstring title = UTF16ToWide(data_.title);
- // Only show the tooltip if the title is truncated.
- if (font_->GetStringWidth(title) > title_bounds().width()) {
- *tooltip = title;
- return true;
- }
- return false;
-}
-
-AccessibilityTypes::Role BaseTab::GetAccessibleRole() {
- return AccessibilityTypes::ROLE_PAGETAB;
-}
-
-ThemeProvider* BaseTab::GetThemeProvider() {
- ThemeProvider* tp = View::GetThemeProvider();
- return tp ? tp : theme_provider_;
-}
-
-void BaseTab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
- TabRendererData::NetworkState state) {
- static bool initialized = false;
- static int loading_animation_frame_count = 0;
- static int waiting_animation_frame_count = 0;
- static int waiting_to_loading_frame_count_ratio = 0;
- if (!initialized) {
- initialized = true;
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- SkBitmap loading_animation(*rb.GetBitmapNamed(IDR_THROBBER));
- loading_animation_frame_count =
- loading_animation.width() / loading_animation.height();
- SkBitmap waiting_animation(*rb.GetBitmapNamed(IDR_THROBBER_WAITING));
- waiting_animation_frame_count =
- waiting_animation.width() / waiting_animation.height();
- waiting_to_loading_frame_count_ratio =
- waiting_animation_frame_count / loading_animation_frame_count;
- }
-
- // 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 (state != old_state) {
- loading_animation_frame_ = loading_animation_frame_count -
- (loading_animation_frame_ / waiting_to_loading_frame_count_ratio);
- }
-
- if (state != TabRendererData::NETWORK_STATE_NONE) {
- loading_animation_frame_ = (loading_animation_frame_ + 1) %
- ((state == TabRendererData::NETWORK_STATE_WAITING) ?
- waiting_animation_frame_count : loading_animation_frame_count);
- } else {
- loading_animation_frame_ = 0;
- }
- SchedulePaint();
-}
-
-void BaseTab::PaintIcon(gfx::Canvas* canvas, int x, int y) {
- if (base::i18n::IsRTL()) {
- x = width() - x -
- (data().favicon.isNull() ? kFavIconSize : data().favicon.width());
- }
-
- int favicon_x = x;
- if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize)
- favicon_x += (data().favicon.width() - kFavIconSize) / 2;
-
- if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
- ThemeProvider* tp = GetThemeProvider();
- SkBitmap frames(*tp->GetBitmapNamed(
- (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ?
- IDR_THROBBER_WAITING : IDR_THROBBER));
- 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, favicon_x, dst_y, image_size, image_size,
- false);
- } else {
- canvas->Save();
- canvas->ClipRectInt(0, 0, width(), height());
- if (should_display_crashed_favicon_) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- SkBitmap crashed_fav_icon(*rb.GetBitmapNamed(IDR_SAD_FAVICON));
- canvas->DrawBitmapInt(crashed_fav_icon, 0, 0, crashed_fav_icon.width(),
- crashed_fav_icon.height(), favicon_x,
- (height() - crashed_fav_icon.height()) / 2 + fav_icon_hiding_offset_,
- kFavIconSize, kFavIconSize, true);
- } else {
- if (!data().favicon.isNull()) {
- // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
- // to using that class to render the favicon).
- int size = data().favicon.width();
- canvas->DrawBitmapInt(data().favicon, 0, 0,
- data().favicon.width(),
- data().favicon.height(),
- x, y + fav_icon_hiding_offset_, size, size,
- true);
- }
- }
- canvas->Restore();
- }
-}
-
-void BaseTab::PaintTitle(gfx::Canvas* canvas, SkColor title_color) {
- // Paint the Title.
- string16 title = data().title;
- if (title.empty()) {
- title = data().loading ?
- l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE) :
- TabContents::GetDefaultTitle();
- } else {
- Browser::FormatTitleForDisplay(&title);
- }
-
- canvas->DrawStringInt(UTF16ToWideHack(title), *font_, title_color,
- title_bounds().x(), title_bounds().y(),
- title_bounds().width(), title_bounds().height());
-}
-
-void BaseTab::AnimationProgressed(const Animation* animation) {
- SchedulePaint();
-}
-
-void BaseTab::AnimationCanceled(const Animation* animation) {
- SchedulePaint();
-}
-
-void BaseTab::AnimationEnded(const Animation* animation) {
- SchedulePaint();
-}
-
-void BaseTab::ButtonPressed(views::Button* sender, const views::Event& event) {
- DCHECK(sender == close_button_);
- controller()->CloseTab(this);
-}
-
-void BaseTab::ShowContextMenu(views::View* source,
- const gfx::Point& p,
- bool is_mouse_gesture) {
- if (controller())
- controller()->ShowContextMenu(this, p);
-}
-
-void BaseTab::SetFavIconHidingOffset(int offset) {
- fav_icon_hiding_offset_ = offset;
- SchedulePaint();
-}
-
-void BaseTab::DisplayCrashedFavIcon() {
- should_display_crashed_favicon_ = true;
-}
-
-void BaseTab::ResetCrashedFavIcon() {
- should_display_crashed_favicon_ = false;
-}
-
-void BaseTab::StartCrashAnimation() {
- if (!crash_animation_.get())
- crash_animation_.reset(new FavIconCrashAnimation(this));
- crash_animation_->Stop();
- crash_animation_->Start();
-}
-
-void BaseTab::StopCrashAnimation() {
- if (!crash_animation_.get())
- return;
- crash_animation_->Stop();
-}
-
-bool BaseTab::IsPerformingCrashAnimation() const {
- return crash_animation_.get() && crash_animation_->is_animating();
-}
-
-// static
-void BaseTab::InitResources() {
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- font_ = new gfx::Font(
- ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
- font_height_ = font_->GetHeight();
- }
-}
diff --git a/chrome/browser/views/tabs/base_tab.h b/chrome/browser/views/tabs/base_tab.h
index 9d6567b..e826fbf 100644
--- a/chrome/browser/views/tabs/base_tab.h
+++ b/chrome/browser/views/tabs/base_tab.h
@@ -6,199 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_BASE_TAB_H_
#pragma once
-#include "app/animation.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "chrome/browser/views/tabs/tab_renderer_data.h"
-#include "views/controls/button/button.h"
-#include "views/view.h"
-
-class AnimationContainer;
-class BaseTab;
-class SlideAnimation;
-class TabController;
-class ThrobAnimation;
-
-namespace gfx {
-class Font;
-} // namespace gfx
-
-namespace views {
-class ImageButton;
-} // namespace views
-
-// Base class for tab renderers.
-class BaseTab : public AnimationDelegate,
- public views::ButtonListener,
- public views::ContextMenuController,
- public views::View {
- public:
- explicit BaseTab(TabController* controller);
- virtual ~BaseTab();
-
- // Sets the data this tabs displays. Invokes DataChanged for subclasses to
- // update themselves appropriately.
- void SetData(const TabRendererData& data);
- const TabRendererData& data() const { return data_; }
-
- // Sets the network state. If the network state changes NetworkStateChanged is
- // invoked.
- virtual void UpdateLoadingAnimation(TabRendererData::NetworkState state);
-
- // Starts/Stops a pulse animation.
- void StartPulse();
- void StopPulse();
-
- // Used to set/check whether this Tab is being animated closed.
- void set_closing(bool closing) { closing_ = closing; }
- bool closing() const { return closing_; }
-
- // See description above field.
- void set_dragging(bool dragging) { dragging_ = dragging; }
- bool dragging() const { return dragging_; }
-
- // Sets the container all animations run from.
- void set_animation_container(AnimationContainer* container) {
- animation_container_ = container;
- }
- AnimationContainer* animation_container() const {
- return animation_container_.get();
- }
-
- // Set the theme provider - because we get detached, we are frequently
- // outside of a hierarchy with a theme provider at the top. This should be
- // called whenever we're detached or attached to a hierarchy.
- void set_theme_provider(ThemeProvider* provider) {
- theme_provider_ = provider;
- }
-
- // Returns true if the tab is selected.
- virtual bool IsSelected() const;
-
- // Returns true if the tab is closeable.
- bool IsCloseable() const;
-
- // views::View overrides:
- virtual void OnMouseEntered(const views::MouseEvent& event);
- virtual void OnMouseExited(const views::MouseEvent& event);
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual bool OnMouseDragged(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event,
- bool canceled);
- virtual bool GetTooltipText(const gfx::Point& p, std::wstring* tooltip);
- virtual AccessibilityTypes::Role GetAccessibleRole();
- virtual ThemeProvider* GetThemeProvider();
-
- protected:
- // Invoked from SetData after |data_| has been updated to the new data.
- virtual void DataChanged(const TabRendererData& old) {}
-
- // Invoked if data_.network_state changes, or the network_state is not none.
- virtual void AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
- TabRendererData::NetworkState state);
-
- TabController* controller() const { return controller_; }
-
- // Returns the pulse animation. The pulse animation is non-null if StartPulse
- // has been invoked.
- ThrobAnimation* pulse_animation() const { return pulse_animation_.get(); }
-
- // Returns the hover animation. This may return null.
- const SlideAnimation* hover_animation() const {
- return hover_animation_.get();
- }
-
- views::ImageButton* close_button() const { return close_button_; }
-
- // Paints the icon at the specified coordinates, mirrored for RTL if needed.
- void PaintIcon(gfx::Canvas* canvas, int x, int y);
- void PaintTitle(gfx::Canvas* canvas, SkColor title_color);
-
- // Overridden from AnimationDelegate:
- virtual void AnimationProgressed(const Animation* animation);
- virtual void AnimationCanceled(const Animation* animation);
- virtual void AnimationEnded(const Animation* animation);
-
- // views::ButtonListener overrides:
- virtual void ButtonPressed(views::Button* sender,
- const views::Event& event);
-
- // views::ContextMenuController overrides:
- virtual void ShowContextMenu(views::View* source,
- const gfx::Point& p,
- bool is_mouse_gesture);
-
- // Returns the bounds of the title.
- virtual const gfx::Rect& title_bounds() const = 0;
-
- static gfx::Font* font() { return font_; }
- static int font_height() { return font_height_; }
-
- private:
- // The animation object used to swap the favicon with the sad tab icon.
- class FavIconCrashAnimation;
-
- // Set the temporary offset for the favicon. This is used during the crash
- // animation.
- void SetFavIconHidingOffset(int offset);
-
- void DisplayCrashedFavIcon();
- void ResetCrashedFavIcon();
-
- // Starts/Stops the crash animation.
- void StartCrashAnimation();
- void StopCrashAnimation();
-
- // Return true if the crash animation is currently running.
- bool IsPerformingCrashAnimation() const;
-
- static void InitResources();
-
- // The controller.
- // WARNING: this is null during detached tab dragging.
- TabController* controller_;
-
- TabRendererData data_;
-
- // True if the tab is being animated closed.
- bool closing_;
-
- // True if the tab is being dragged.
- bool dragging_;
-
- // Pulse animation.
- scoped_ptr<ThrobAnimation> pulse_animation_;
-
- // Hover animation.
- scoped_ptr<SlideAnimation> hover_animation_;
-
- // Crash animation.
- scoped_ptr<FavIconCrashAnimation> crash_animation_;
-
- scoped_refptr<AnimationContainer> animation_container_;
-
- views::ImageButton* close_button_;
-
- // The current index of the loading animation.
- int loading_animation_frame_;
-
- // Whether to disable throbber animations. Only true if this is an app tab
- // renderer and a command line flag has been passed in to disable the
- // animations.
- bool throbber_disabled_;
-
- ThemeProvider* theme_provider_;
-
- // The offset used to animate the favicon location. This is used when the tab
- // crashes.
- int fav_icon_hiding_offset_;
-
- bool should_display_crashed_favicon_;
-
- static gfx::Font* font_;
- static int font_height_;
-
- DISALLOW_COPY_AND_ASSIGN(BaseTab);
-};
+#include "chrome/browser/ui/views/tabs/base_tab.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_BASE_TAB_H_
+
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();
-}
diff --git a/chrome/browser/views/tabs/base_tab_strip.h b/chrome/browser/views/tabs/base_tab_strip.h
index e3f5231..603dcf9 100644
--- a/chrome/browser/views/tabs/base_tab_strip.h
+++ b/chrome/browser/views/tabs/base_tab_strip.h
@@ -6,261 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_
#pragma once
-#include <vector>
-
-#include "base/scoped_ptr.h"
-#include "chrome/browser/views/tabs/base_tab.h"
-#include "chrome/browser/views/tabs/tab_controller.h"
-#include "views/animation/bounds_animator.h"
-#include "views/view.h"
-
-class BaseTab;
-class DraggedTabController;
-class TabStrip;
-class TabStripController;
-class ThemeProvider;
-
-// Base class for the view tab strip implementations.
-class BaseTabStrip : public views::View,
- public TabController {
- public:
- enum Type {
- HORIZONTAL_TAB_STRIP,
- VERTICAL_TAB_STRIP
- };
-
- BaseTabStrip(TabStripController* controller, Type type);
- virtual ~BaseTabStrip();
-
- Type type() const { return type_; }
-
- // Returns the preferred height of this TabStrip. This is based on the
- // typical height of its constituent tabs.
- virtual int GetPreferredHeight() = 0;
-
- // Set the background offset used by inactive tabs to match the frame image.
- virtual void SetBackgroundOffset(const gfx::Point& offset) = 0;
-
- // Returns true if the specified point(TabStrip coordinates) is
- // in the window caption area of the browser window.
- virtual bool IsPositionInWindowCaption(const gfx::Point& point) = 0;
-
- // Sets the bounds of the tab at the specified |tab_index|. |tab_bounds| are
- // in TabStrip coordinates.
- virtual void SetDraggedTabBounds(int tab_index,
- const gfx::Rect& tab_bounds) = 0;
-
- // Updates the loading animations displayed by tabs in the tabstrip to the
- // next frame.
- void UpdateLoadingAnimations();
-
- // Returns true if Tabs in this TabStrip are currently changing size or
- // position.
- virtual bool IsAnimating() const;
-
- // Returns this object as a TabStrip if it is one.
- virtual TabStrip* AsTabStrip() = 0;
-
- // Starts highlighting the tab at the specified index.
- virtual void StartHighlight(int model_index) = 0;
-
- // Stops all tab higlighting.
- virtual void StopAllHighlighting() = 0;
-
- // Returns the selected tab.
- virtual BaseTab* GetSelectedBaseTab() const;
-
- // Retrieves the ideal bounds for the Tab at the specified index.
- const gfx::Rect& ideal_bounds(int tab_data_index) {
- return tab_data_[tab_data_index].ideal_bounds;
- }
-
- // Creates and returns a tab that can be used for dragging. Ownership passes
- // to the caller.
- virtual BaseTab* CreateTabForDragging() = 0;
-
- // Adds a tab at the specified index.
- void AddTabAt(int model_index,
- bool foreground,
- const TabRendererData& data);
-
- // Invoked from the controller when the close initiates from the TabController
- // (the user clicked the tab close button or middle clicked the tab). This is
- // invoked from Close. Because of unload handlers Close is not always
- // immediately followed by RemoveTabAt.
- virtual void PrepareForCloseAt(int model_index) {}
-
- // Removes a tab at the specified index.
- virtual void RemoveTabAt(int model_index) = 0;
-
- // Selects a tab at the specified index. |old_model_index| is the selected
- // index prior to the selection change.
- virtual void SelectTabAt(int old_model_index, int new_model_index) = 0;
-
- // Moves a tab.
- virtual void MoveTab(int from_model_index, int to_model_index);
-
- // Invoked when the title of a tab changes and the tab isn't loading.
- 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);
-
- // Returns the tab at the specified model index.
- virtual BaseTab* GetBaseTabAtModelIndex(int model_index) const;
-
- // Returns the tab at the specified tab index.
- BaseTab* base_tab_at_tab_index(int tab_index) const {
- return tab_data_[tab_index].tab;
- }
-
- // Returns the index of the specified tab in the model coordiate system, or
- // -1 if tab is closing or not valid.
- virtual int GetModelIndexOfBaseTab(const BaseTab* tab) const;
-
- // Gets the number of Tabs in the tab strip.
- // WARNING: this is the number of tabs displayed by the tabstrip, which if
- // an animation is ongoing is not necessarily the same as the number of tabs
- // in the model.
- int tab_count() const { return static_cast<int>(tab_data_.size()); }
-
- // Cover method for TabStripController::GetCount.
- int GetModelCount() const;
-
- // Cover method for TabStripController::IsValidIndex.
- bool IsValidModelIndex(int model_index) const;
-
- // Returns the index into |tab_data_| corresponding to the index from the
- // TabStripModel, or |tab_data_.size()| if there is no tab representing
- // |model_index|.
- int ModelIndexToTabIndex(int model_index) const;
-
- TabStripController* controller() const { return controller_.get(); }
-
- // Returns true if a drag session is currently active.
- bool IsDragSessionActive() const;
-
- // TabController overrides:
- virtual void SelectTab(BaseTab* tab);
- virtual void CloseTab(BaseTab* tab);
- virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p);
- virtual bool IsTabSelected(const BaseTab* tab) const;
- virtual bool IsTabPinned(const BaseTab* tab) const;
- virtual bool IsTabCloseable(const BaseTab* tab) const;
- virtual void MaybeStartDrag(BaseTab* tab,
- const views::MouseEvent& event);
- virtual void ContinueDrag(const views::MouseEvent& event);
- virtual bool EndDrag(bool canceled);
- virtual BaseTab* GetTabAt(BaseTab* tab,
- const gfx::Point& tab_in_tab_coordinates);
-
- // View overrides:
- virtual void Layout();
-
- protected:
- // The Tabs we contain, and their last generated "good" bounds.
- struct TabData {
- BaseTab* tab;
- gfx::Rect ideal_bounds;
- };
-
- // View overrides.
- virtual bool OnMouseDragged(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event,
- bool canceled);
-
- // Creates and returns a new tab. The caller owners the returned tab.
- virtual BaseTab* CreateTab() = 0;
-
- // Invoked from |AddTabAt| after the newly created tab has been inserted.
- // Subclasses should either start an animation, or layout.
- virtual void StartInsertTabAnimation(int model_index, bool foreground) = 0;
-
- // Invoked from |MoveTab| after |tab_data_| has been updated to animate the
- // move.
- virtual void StartMoveTabAnimation() = 0;
-
- // 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; }
-
- // Animates all the views to their ideal bounds.
- // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds
- // currently set in ideal_bounds.
- virtual void AnimateToIdealBounds() = 0;
-
- // Cleans up the Tab from the TabStrip. This is called from the tab animation
- // code and is not a general-purpose method.
- void RemoveAndDeleteTab(BaseTab* tab);
-
- // Resets the bounds of all non-closing tabs.
- virtual void GenerateIdealBounds() = 0;
-
- void set_ideal_bounds(int index, const gfx::Rect& bounds) {
- tab_data_[index].ideal_bounds = bounds;
- }
-
- // Returns the index into |tab_data_| corresponding to the specified tab, or
- // -1 if the tab isn't in |tab_data_|.
- int TabIndexOfTab(BaseTab* tab) const;
-
- // Stops any ongoing animations. If |layout| is true and an animation is
- // ongoing this does a layout.
- virtual void StopAnimating(bool layout) = 0;
-
- // Destroys the active drag controller.
- void DestroyDragController();
-
- // Used by DraggedTabController when the user starts or stops dragging a tab.
- void StartedDraggingTab(BaseTab* tab);
- void StoppedDraggingTab(BaseTab* tab);
-
- // See description above field for details.
- bool attaching_dragged_tab() const { return attaching_dragged_tab_; }
-
- views::BoundsAnimator& bounds_animator() { return bounds_animator_; }
-
- // Invoked prior to starting a new animation.
- virtual void PrepareForAnimation();
-
- // Creates an AnimationDelegate that resets state after a remove animation
- // completes. The caller owns the returned object.
- AnimationDelegate* CreateRemoveTabDelegate(BaseTab* tab);
-
- // Invoked from Layout if the size changes or layout is really needed.
- virtual void DoLayout();
-
- private:
- class RemoveTabDelegate;
-
- friend class DraggedTabController;
-
- // See description above field for details.
- void set_attaching_dragged_tab(bool value) { attaching_dragged_tab_ = value; }
-
- scoped_ptr<TabStripController> controller_;
-
- const Type type_;
-
- std::vector<TabData> tab_data_;
-
- // The controller for a drag initiated from a Tab. Valid for the lifetime of
- // the drag session.
- scoped_ptr<DraggedTabController> drag_controller_;
-
- // If true, the insert is a result of a drag attaching the tab back to the
- // model.
- bool attaching_dragged_tab_;
-
- views::BoundsAnimator bounds_animator_;
-
- // Size we last layed out at.
- gfx::Size last_layout_size_;
-};
+#include "chrome/browser/ui/views/tabs/base_tab_strip.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_
+
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc
deleted file mode 100644
index 78b1aa1..0000000
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc
+++ /dev/null
@@ -1,428 +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/browser_tab_strip_controller.h"
-
-#include "base/auto_reset.h"
-#include "base/command_line.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_menu_model.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/views/tabs/base_tab_strip.h"
-#include "chrome/browser/views/tabs/tab_renderer_data.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/url_constants.h"
-#include "views/controls/menu/menu_2.h"
-#include "views/widget/widget.h"
-
-static TabRendererData::NetworkState TabContentsNetworkState(
- TabContents* contents) {
- if (!contents || !contents->is_loading())
- return TabRendererData::NETWORK_STATE_NONE;
- if (contents->waiting_for_response())
- return TabRendererData::NETWORK_STATE_WAITING;
- return TabRendererData::NETWORK_STATE_LOADING;
-}
-
-class BrowserTabStripController::TabContextMenuContents
- : public menus::SimpleMenuModel::Delegate {
- public:
- TabContextMenuContents(BaseTab* tab,
- BrowserTabStripController* controller)
- : ALLOW_THIS_IN_INITIALIZER_LIST(
- model_(this, controller->IsTabPinned(tab))),
- tab_(tab),
- controller_(controller),
- last_command_(TabStripModel::CommandFirst) {
- Build();
- }
- virtual ~TabContextMenuContents() {
- menu_->CancelMenu();
- if (controller_)
- controller_->tabstrip_->StopAllHighlighting();
- }
-
- void Cancel() {
- controller_ = NULL;
- }
-
- void RunMenuAt(const gfx::Point& point) {
- BrowserTabStripController* controller = controller_;
- menu_->RunMenuAt(point, views::Menu2::ALIGN_TOPLEFT);
- // We could be gone now. Assume |this| is junk!
- if (controller)
- controller->tabstrip_->StopAllHighlighting();
- }
-
- // Overridden from menus::SimpleMenuModel::Delegate:
- virtual bool IsCommandIdChecked(int command_id) const {
- return controller_->IsCommandCheckedForTab(
- static_cast<TabStripModel::ContextMenuCommand>(command_id),
- tab_);
- }
- virtual bool IsCommandIdEnabled(int command_id) const {
- return controller_->IsCommandEnabledForTab(
- static_cast<TabStripModel::ContextMenuCommand>(command_id),
- tab_);
- }
- virtual bool GetAcceleratorForCommandId(
- int command_id,
- menus::Accelerator* accelerator) {
- return controller_->tabstrip_->GetWidget()->GetAccelerator(command_id,
- accelerator);
- }
- virtual void CommandIdHighlighted(int command_id) {
- controller_->StopHighlightTabsForCommand(last_command_, tab_);
- last_command_ = static_cast<TabStripModel::ContextMenuCommand>(command_id);
- controller_->StartHighlightTabsForCommand(last_command_, tab_);
- }
- virtual void ExecuteCommand(int command_id) {
- controller_->ExecuteCommandForTab(
- static_cast<TabStripModel::ContextMenuCommand>(command_id),
- tab_);
- }
-
- private:
- void Build() {
- menu_.reset(new views::Menu2(&model_));
- }
-
- TabMenuModel model_;
- scoped_ptr<views::Menu2> menu_;
-
- // The tab we're showing a menu for.
- BaseTab* tab_;
-
- // A pointer back to our hosting controller, for command state information.
- BrowserTabStripController* controller_;
-
- // The last command that was selected, so that we can start/stop highlighting
- // appropriately as the user moves through the menu.
- TabStripModel::ContextMenuCommand last_command_;
-
- DISALLOW_COPY_AND_ASSIGN(TabContextMenuContents);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// BrowserTabStripController, public:
-
-BrowserTabStripController::BrowserTabStripController(Browser* browser,
- TabStripModel* model)
- : model_(model),
- tabstrip_(NULL),
- browser_(browser) {
- model_->AddObserver(this);
-
- notification_registrar_.Add(this,
- NotificationType::TAB_CLOSEABLE_STATE_CHANGED,
- NotificationService::AllSources());
-}
-
-BrowserTabStripController::~BrowserTabStripController() {
- // When we get here the TabStrip is being deleted. We need to explicitly
- // cancel the menu, otherwise it may try to invoke something on the tabstrip
- // from it's destructor.
- if (context_menu_contents_.get())
- context_menu_contents_->Cancel();
-
- model_->RemoveObserver(this);
-}
-
-void BrowserTabStripController::InitFromModel(BaseTabStrip* tabstrip) {
- tabstrip_ = tabstrip;
- // Walk the model, calling our insertion observer method for each item within
- // it.
- for (int i = 0; i < model_->count(); ++i) {
- TabInsertedAt(model_->GetTabContentsAt(i), i,
- i == model_->selected_index());
- }
-}
-
-bool BrowserTabStripController::IsCommandEnabledForTab(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) const {
- int model_index = tabstrip_->GetModelIndexOfBaseTab(tab);
- return model_->ContainsIndex(model_index) ?
- model_->IsContextMenuCommandEnabled(model_index, command_id) : false;
-}
-
-bool BrowserTabStripController::IsCommandCheckedForTab(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) const {
- int model_index = tabstrip_->GetModelIndexOfBaseTab(tab);
- return model_->ContainsIndex(model_index) ?
- model_->IsContextMenuCommandChecked(model_index, command_id) : false;
-}
-
-void BrowserTabStripController::ExecuteCommandForTab(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) {
- int model_index = tabstrip_->GetModelIndexOfBaseTab(tab);
- if (model_->ContainsIndex(model_index))
- model_->ExecuteContextMenuCommand(model_index, command_id);
-}
-
-bool BrowserTabStripController::IsTabPinned(BaseTab* tab) {
- return IsTabPinned(tabstrip_->GetModelIndexOfBaseTab(tab));
-}
-
-int BrowserTabStripController::GetCount() const {
- return model_->count();
-}
-
-bool BrowserTabStripController::IsValidIndex(int index) const {
- return model_->ContainsIndex(index);
-}
-
-int BrowserTabStripController::GetSelectedIndex() const {
- return model_->selected_index();
-}
-
-bool BrowserTabStripController::IsTabSelected(int model_index) const {
- return model_->selected_index() == model_index;
-}
-
-bool BrowserTabStripController::IsTabPinned(int model_index) const {
- return model_->ContainsIndex(model_index) && model_->IsTabPinned(model_index);
-}
-
-bool BrowserTabStripController::IsTabCloseable(int model_index) const {
- return !model_->ContainsIndex(model_index) ||
- model_->delegate()->CanCloseTab();
-}
-
-bool BrowserTabStripController::IsNewTabPage(int model_index) const {
- return model_->ContainsIndex(model_index) &&
- model_->GetTabContentsAt(model_index)->GetURL() ==
- GURL(chrome::kChromeUINewTabURL);
-}
-
-void BrowserTabStripController::SelectTab(int model_index) {
- model_->SelectTabContentsAt(model_index, true);
-}
-
-void BrowserTabStripController::CloseTab(int model_index) {
- tabstrip_->PrepareForCloseAt(model_index);
- model_->CloseTabContentsAt(model_index,
- TabStripModel::CLOSE_USER_GESTURE |
- TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
-}
-
-void BrowserTabStripController::ShowContextMenu(BaseTab* tab,
- const gfx::Point& p) {
- context_menu_contents_.reset(new TabContextMenuContents(tab, this));
- context_menu_contents_->RunMenuAt(p);
-}
-
-void BrowserTabStripController::UpdateLoadingAnimations() {
- // Don't use the model count here as it's possible for this to be invoked
- // before we've applied an update from the model (Browser::TabInsertedAt may
- // be processed before us and invokes this).
- for (int tab_index = 0, tab_count = tabstrip_->tab_count();
- tab_index < tab_count; ++tab_index) {
- BaseTab* tab = tabstrip_->base_tab_at_tab_index(tab_index);
- int model_index = tabstrip_->GetModelIndexOfBaseTab(tab);
- if (model_->ContainsIndex(model_index)) {
- TabContents* contents = model_->GetTabContentsAt(model_index);
- tab->UpdateLoadingAnimation(TabContentsNetworkState(contents));
- }
- }
-}
-
-int BrowserTabStripController::HasAvailableDragActions() const {
- return model_->delegate()->GetDragActions();
-}
-
-void BrowserTabStripController::PerformDrop(bool drop_before,
- int index,
- const GURL& url) {
- if (drop_before) {
- UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs"),
- model_->profile());
-
- // Insert a new tab.
- TabContents* contents = model_->delegate()->CreateTabContentsForURL(
- url, GURL(), model_->profile(), PageTransition::TYPED, false, NULL);
- model_->AddTabContents(contents, index, PageTransition::GENERATED,
- TabStripModel::ADD_SELECTED);
- } else {
- UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLOnTab"),
- model_->profile());
-
- model_->GetTabContentsAt(index)->controller().LoadURL(
- url, GURL(), PageTransition::GENERATED);
- model_->SelectTabContentsAt(index, true);
- }
-}
-
-bool BrowserTabStripController::IsCompatibleWith(BaseTabStrip* other) const {
- Profile* other_profile =
- static_cast<BrowserTabStripController*>(other->controller())->profile();
- return other_profile == profile();
-}
-
-void BrowserTabStripController::CreateNewTab() {
- UserMetrics::RecordAction(UserMetricsAction("NewTab_Button"),
- model_->profile());
-
- model_->delegate()->AddBlankTab(true);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BrowserTabStripController, TabStripModelObserver implementation:
-
-void BrowserTabStripController::TabInsertedAt(TabContents* contents,
- int model_index,
- bool foreground) {
- DCHECK(contents);
- DCHECK(model_index == TabStripModel::kNoTab ||
- model_->ContainsIndex(model_index));
- // This tab may be attached to another browser window, we should notify
- // renderer.
- contents->render_view_host()->UpdateBrowserWindowId(
- contents->controller().window_id().id());
-
- TabRendererData data;
- SetTabRendererDataFromModel(contents, model_index, &data);
- tabstrip_->AddTabAt(model_index, foreground, data);
-}
-
-void BrowserTabStripController::TabDetachedAt(TabContents* contents,
- int model_index) {
- tabstrip_->RemoveTabAt(model_index);
-}
-
-void BrowserTabStripController::TabSelectedAt(TabContents* old_contents,
- TabContents* contents,
- int model_index,
- bool user_gesture) {
- tabstrip_->SelectTabAt(model_->GetIndexOfTabContents(old_contents),
- model_index);
-}
-
-void BrowserTabStripController::TabMoved(TabContents* contents,
- int from_model_index,
- int to_model_index) {
- // Update the data first as the pinned state may have changed.
- TabRendererData data;
- SetTabRendererDataFromModel(contents, to_model_index, &data);
- tabstrip_->SetTabData(from_model_index, data);
-
- tabstrip_->MoveTab(from_model_index, to_model_index);
-}
-
-void BrowserTabStripController::TabChangedAt(TabContents* contents,
- int model_index,
- TabChangeType change_type) {
- if (change_type == TITLE_NOT_LOADING) {
- tabstrip_->TabTitleChangedNotLoading(model_index);
- // We'll receive another notification of the change asynchronously.
- return;
- }
-
- SetTabDataAt(contents, model_index);
-}
-
-void BrowserTabStripController::TabReplacedAt(TabContents* old_contents,
- TabContents* new_contents,
- int model_index) {
- SetTabDataAt(new_contents, model_index);
-}
-
-void BrowserTabStripController::TabPinnedStateChanged(TabContents* contents,
- int model_index) {
- // Currently none of the renderers render pinned state differently.
-}
-
-void BrowserTabStripController::TabMiniStateChanged(
- TabContents* contents,
- int model_index) {
- SetTabDataAt(contents, model_index);
-}
-
-void BrowserTabStripController::TabBlockedStateChanged(TabContents* contents,
- int model_index) {
- SetTabDataAt(contents, model_index);
-}
-
-void BrowserTabStripController::SetTabDataAt(TabContents* contents,
- int model_index) {
- TabRendererData data;
- SetTabRendererDataFromModel(contents, model_index, &data);
- tabstrip_->SetTabData(model_index, data);
-}
-
-void BrowserTabStripController::SetTabRendererDataFromModel(
- TabContents* contents,
- int model_index,
- TabRendererData* data) {
- SkBitmap* app_icon = NULL;
-
- // Extension App icons are slightly larger than favicons, so only allow
- // them if permitted by the model.
- if (model_->delegate()->LargeIconsPermitted())
- app_icon = contents->GetExtensionAppIcon();
-
- if (app_icon)
- data->favicon = *app_icon;
- else
- data->favicon = contents->GetFavIcon();
- data->network_state = TabContentsNetworkState(contents);
- data->title = contents->GetTitle();
- data->loading = contents->is_loading();
- data->crashed = contents->is_crashed();
- data->off_the_record = contents->profile()->IsOffTheRecord();
- data->show_icon = contents->ShouldDisplayFavIcon();
- data->mini = model_->IsMiniTab(model_index);
- data->blocked = model_->IsTabBlocked(model_index);
- data->app = contents->is_app();
-}
-
-void BrowserTabStripController::StartHighlightTabsForCommand(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) {
- if (command_id == TabStripModel::CommandCloseOtherTabs ||
- command_id == TabStripModel::CommandCloseTabsToRight) {
- int model_index = tabstrip_->GetModelIndexOfBaseTab(tab);
- if (IsValidIndex(model_index)) {
- std::vector<int> indices =
- model_->GetIndicesClosedByCommand(model_index, command_id);
- for (std::vector<int>::const_iterator i = indices.begin();
- i != indices.end(); ++i) {
- tabstrip_->StartHighlight(*i);
- }
- }
- }
-}
-
-void BrowserTabStripController::StopHighlightTabsForCommand(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) {
- if (command_id == TabStripModel::CommandCloseTabsToRight ||
- command_id == TabStripModel::CommandCloseOtherTabs) {
- // Just tell all Tabs to stop pulsing - it's safe.
- tabstrip_->StopAllHighlighting();
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// BrowserTabStripController, NotificationObserver implementation:
-
-void BrowserTabStripController::Observe(NotificationType type,
- const NotificationSource& source, const NotificationDetails& details) {
- DCHECK(type.value == NotificationType::TAB_CLOSEABLE_STATE_CHANGED);
- // Note that this notification may be fired during a model mutation and
- // possibly before the tabstrip has processed the change.
- // Here, we just re-layout each existing tab to reflect the change in its
- // closeable state, and then schedule paint for entire tabstrip.
- for (int i = 0; i < tabstrip_->tab_count(); ++i) {
- tabstrip_->base_tab_at_tab_index(i)->Layout();
- }
- tabstrip_->SchedulePaint();
-}
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.h b/chrome/browser/views/tabs/browser_tab_strip_controller.h
index bbf1121..6606f28 100644
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.h
+++ b/chrome/browser/views/tabs/browser_tab_strip_controller.h
@@ -6,116 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_
#pragma once
-#include "base/scoped_ptr.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/views/tabs/tab_strip_controller.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-
-class BaseTab;
-class BaseTabStrip;
-class Browser;
-
-struct TabRendererData;
-
-// An implementation of TabStripController that sources data from the
-// TabContentses in a TabStripModel.
-class BrowserTabStripController : public TabStripController,
- public TabStripModelObserver,
- public NotificationObserver {
- public:
- BrowserTabStripController(Browser* browser, TabStripModel* model);
- virtual ~BrowserTabStripController();
-
- void InitFromModel(BaseTabStrip* tabstrip);
-
- TabStripModel* model() const { return model_; }
-
- bool IsCommandEnabledForTab(TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) const;
- bool IsCommandCheckedForTab(TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab) const;
- void ExecuteCommandForTab(TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab);
- bool IsTabPinned(BaseTab* tab);
-
- // TabStripController implementation:
- virtual int GetCount() const;
- virtual bool IsValidIndex(int model_index) const;
- virtual int GetSelectedIndex() const;
- virtual bool IsTabSelected(int model_index) const;
- virtual bool IsTabPinned(int model_index) const;
- virtual bool IsTabCloseable(int model_index) const;
- virtual bool IsNewTabPage(int model_index) const;
- virtual void SelectTab(int model_index);
- virtual void CloseTab(int model_index);
- virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p);
- virtual void UpdateLoadingAnimations();
- virtual int HasAvailableDragActions() const;
- virtual void PerformDrop(bool drop_before, int index, const GURL& url);
- virtual bool IsCompatibleWith(BaseTabStrip* other) const;
- virtual void CreateNewTab();
-
- // TabStripModelObserver implementation:
- virtual void TabInsertedAt(TabContents* contents,
- int model_index,
- bool foreground);
- virtual void TabDetachedAt(TabContents* contents, int model_index);
- virtual void TabSelectedAt(TabContents* old_contents,
- TabContents* contents,
- int model_index,
- bool user_gesture);
- virtual void TabMoved(TabContents* contents,
- int from_model_index,
- int to_model_index);
- virtual void TabChangedAt(TabContents* contents,
- int model_index,
- TabChangeType change_type);
- virtual void TabReplacedAt(TabContents* old_contents,
- TabContents* new_contents,
- int model_index);
- virtual void TabPinnedStateChanged(TabContents* contents, int model_index);
- virtual void TabMiniStateChanged(TabContents* contents, int model_index);
- virtual void TabBlockedStateChanged(TabContents* contents, int model_index);
-
- // NotificationObserver implementation:
- virtual void Observe(NotificationType type, const NotificationSource& source,
- const NotificationDetails& details);
-
- private:
- class TabContextMenuContents;
-
- // Invokes tabstrip_->SetTabData.
- void SetTabDataAt(TabContents* contents, int model_index);
-
- // Sets the TabRendererData from the TabStripModel.
- void SetTabRendererDataFromModel(TabContents* contents,
- int model_index,
- TabRendererData* data);
-
- void StartHighlightTabsForCommand(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab);
- void StopHighlightTabsForCommand(
- TabStripModel::ContextMenuCommand command_id,
- BaseTab* tab);
-
- Profile* profile() const { return model_->profile(); }
-
- TabStripModel* model_;
-
- BaseTabStrip* tabstrip_;
-
- // Non-owning pointer to the browser which is using this controller.
- Browser* browser_;
-
- // If non-NULL it means we're showing a menu for the tab.
- scoped_ptr<TabContextMenuContents> context_menu_contents_;
-
- NotificationRegistrar notification_registrar_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserTabStripController);
-};
+#include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_
diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc
deleted file mode 100644
index 3798180..0000000
--- a/chrome/browser/views/tabs/dragged_tab_controller.cc
+++ /dev/null
@@ -1,1341 +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/dragged_tab_controller.h"
-
-#include <math.h>
-#include <set>
-
-#include "app/animation.h"
-#include "app/slide_animation.h"
-#include "app/resource_bundle.h"
-#include "base/callback.h"
-#include "base/i18n/rtl.h"
-#include "chrome/browser/browser_window.h"
-#include "chrome/browser/extensions/extension_function_dispatcher.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/metrics/user_metrics.h"
-#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/tabs/base_tab.h"
-#include "chrome/browser/views/tabs/base_tab_strip.h"
-#include "chrome/browser/views/tabs/browser_tab_strip_controller.h"
-#include "chrome/browser/views/tabs/dragged_tab_view.h"
-#include "chrome/browser/views/tabs/native_view_photobooth.h"
-#include "chrome/browser/views/tabs/side_tab.h"
-#include "chrome/browser/views/tabs/side_tab_strip.h"
-#include "chrome/browser/views/tabs/tab.h"
-#include "chrome/browser/views/tabs/tab_strip.h"
-#include "chrome/common/notification_service.h"
-#include "gfx/canvas_skia.h"
-#include "grit/theme_resources.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "views/event.h"
-#include "views/widget/root_view.h"
-#include "views/widget/widget.h"
-#include "views/window/window.h"
-
-#if defined(OS_WIN)
-#include "views/widget/widget_win.h"
-#endif
-
-#if defined(OS_LINUX)
-#include <gdk/gdk.h>
-#include <gdk/gdkkeysyms.h>
-#endif
-
-static const int kHorizontalMoveThreshold = 16; // Pixels.
-
-// Distance in pixels the user must move the mouse before we consider moving
-// an attached vertical tab.
-static const int kVerticalMoveThreshold = 8;
-
-// If non-null there is a drag underway.
-static DraggedTabController* instance_;
-
-namespace {
-
-// Delay, in ms, during dragging before we bring a window to front.
-const int kBringToFrontDelay = 750;
-
-// Radius of the rect drawn by DockView.
-const int kRoundedRectRadius = 4;
-
-// Spacing between tab icons when DockView is showing a docking location that
-// contains more than one tab.
-const int kTabSpacing = 4;
-
-// DockView is the view responsible for giving a visual indicator of where a
-// dock is going to occur.
-
-class DockView : public views::View {
- public:
- explicit DockView(DockInfo::Type type) : type_(type) {}
-
- virtual gfx::Size GetPreferredSize() {
- return gfx::Size(DockInfo::popup_width(), DockInfo::popup_height());
- }
-
- virtual void PaintBackground(gfx::Canvas* canvas) {
- SkRect outer_rect = { SkIntToScalar(0), SkIntToScalar(0),
- SkIntToScalar(width()),
- SkIntToScalar(height()) };
-
- // Fill the background rect.
- SkPaint paint;
- paint.setColor(SkColorSetRGB(108, 108, 108));
- paint.setStyle(SkPaint::kFill_Style);
- canvas->AsCanvasSkia()->drawRoundRect(
- outer_rect, SkIntToScalar(kRoundedRectRadius),
- SkIntToScalar(kRoundedRectRadius), paint);
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-
- SkBitmap* high_icon = rb.GetBitmapNamed(IDR_DOCK_HIGH);
- SkBitmap* wide_icon = rb.GetBitmapNamed(IDR_DOCK_WIDE);
-
- canvas->Save();
- bool rtl_ui = base::i18n::IsRTL();
- if (rtl_ui) {
- // Flip canvas to draw the mirrored tab images for RTL UI.
- canvas->TranslateInt(width(), 0);
- canvas->ScaleInt(-1, 1);
- }
- int x_of_active_tab = width() / 2 + kTabSpacing / 2;
- int x_of_inactive_tab = width() / 2 - high_icon->width() - kTabSpacing / 2;
- switch (type_) {
- case DockInfo::LEFT_OF_WINDOW:
- case DockInfo::LEFT_HALF:
- if (!rtl_ui)
- std::swap(x_of_active_tab, x_of_inactive_tab);
- canvas->DrawBitmapInt(*high_icon, x_of_active_tab,
- (height() - high_icon->height()) / 2);
- if (type_ == DockInfo::LEFT_OF_WINDOW) {
- DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab,
- (height() - high_icon->height()) / 2);
- }
- break;
-
-
- case DockInfo::RIGHT_OF_WINDOW:
- case DockInfo::RIGHT_HALF:
- if (rtl_ui)
- std::swap(x_of_active_tab, x_of_inactive_tab);
- canvas->DrawBitmapInt(*high_icon, x_of_active_tab,
- (height() - high_icon->height()) / 2);
- if (type_ == DockInfo::RIGHT_OF_WINDOW) {
- DrawBitmapWithAlpha(canvas, *high_icon, x_of_inactive_tab,
- (height() - high_icon->height()) / 2);
- }
- break;
-
- case DockInfo::TOP_OF_WINDOW:
- canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2,
- height() / 2 - high_icon->height());
- break;
-
- case DockInfo::MAXIMIZE: {
- SkBitmap* max_icon = rb.GetBitmapNamed(IDR_DOCK_MAX);
- canvas->DrawBitmapInt(*max_icon, (width() - max_icon->width()) / 2,
- (height() - max_icon->height()) / 2);
- break;
- }
-
- case DockInfo::BOTTOM_HALF:
- case DockInfo::BOTTOM_OF_WINDOW:
- canvas->DrawBitmapInt(*wide_icon, (width() - wide_icon->width()) / 2,
- height() / 2 + kTabSpacing / 2);
- if (type_ == DockInfo::BOTTOM_OF_WINDOW) {
- DrawBitmapWithAlpha(canvas, *wide_icon,
- (width() - wide_icon->width()) / 2,
- height() / 2 - kTabSpacing / 2 - wide_icon->height());
- }
- break;
-
- default:
- NOTREACHED();
- break;
- }
- canvas->Restore();
- }
-
- private:
- void DrawBitmapWithAlpha(gfx::Canvas* canvas, const SkBitmap& image,
- int x, int y) {
- SkPaint paint;
- paint.setAlpha(128);
- canvas->DrawBitmapInt(image, x, y, paint);
- }
-
- DockInfo::Type type_;
-
- DISALLOW_COPY_AND_ASSIGN(DockView);
-};
-
-gfx::Point ConvertScreenPointToTabStripPoint(BaseTabStrip* tabstrip,
- const gfx::Point& screen_point) {
- gfx::Point tabstrip_topleft;
- views::View::ConvertPointToScreen(tabstrip, &tabstrip_topleft);
- return gfx::Point(screen_point.x() - tabstrip_topleft.x(),
- screen_point.y() - tabstrip_topleft.y());
-}
-
-// Returns the the x-coordinate of |point| if the type of tabstrip is horizontal
-// otherwise returns the y-coordinate.
-int MajorAxisValue(const gfx::Point& point, BaseTabStrip* tabstrip) {
- return (tabstrip->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) ?
- point.x() : point.y();
-}
-
-} // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// DockDisplayer
-
-// DockDisplayer is responsible for giving the user a visual indication of a
-// possible dock position (as represented by DockInfo). DockDisplayer shows
-// a window with a DockView in it. Two animations are used that correspond to
-// the state of DockInfo::in_enable_area.
-class DraggedTabController::DockDisplayer : public AnimationDelegate {
- public:
- DockDisplayer(DraggedTabController* controller,
- const DockInfo& info)
- : controller_(controller),
- popup_(NULL),
- popup_view_(NULL),
- ALLOW_THIS_IN_INITIALIZER_LIST(animation_(this)),
- hidden_(false),
- in_enable_area_(info.in_enable_area()) {
-#if defined(OS_WIN)
- views::WidgetWin* popup = new views::WidgetWin;
- popup_ = popup;
- popup->set_window_style(WS_POPUP);
- popup->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW |
- WS_EX_TOPMOST);
- popup->SetOpacity(0x00);
- popup->Init(NULL, info.GetPopupRect());
- popup->SetContentsView(new DockView(info.type()));
- if (info.in_enable_area())
- animation_.Reset(1);
- else
- animation_.Show();
- popup->SetWindowPos(HWND_TOP, 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOMOVE | SWP_SHOWWINDOW);
-#else
- NOTIMPLEMENTED();
-#endif
- popup_view_ = popup_->GetNativeView();
- }
-
- ~DockDisplayer() {
- if (controller_)
- controller_->DockDisplayerDestroyed(this);
- }
-
- // Updates the state based on |in_enable_area|.
- void UpdateInEnabledArea(bool in_enable_area) {
- if (in_enable_area != in_enable_area_) {
- in_enable_area_ = in_enable_area;
- UpdateLayeredAlpha();
- }
- }
-
- // Resets the reference to the hosting DraggedTabController. This is invoked
- // when the DraggedTabController is destoryed.
- void clear_controller() { controller_ = NULL; }
-
- // NativeView of the window we create.
- gfx::NativeView popup_view() { return popup_view_; }
-
- // Starts the hide animation. When the window is closed the
- // DraggedTabController is notified by way of the DockDisplayerDestroyed
- // method
- void Hide() {
- if (hidden_)
- return;
-
- if (!popup_) {
- delete this;
- return;
- }
- hidden_ = true;
- animation_.Hide();
- }
-
- virtual void AnimationProgressed(const Animation* animation) {
- UpdateLayeredAlpha();
- }
-
- virtual void AnimationEnded(const Animation* animation) {
- if (!hidden_)
- return;
-#if defined(OS_WIN)
- static_cast<views::WidgetWin*>(popup_)->Close();
-#else
- NOTIMPLEMENTED();
-#endif
- delete this;
- }
-
- virtual void UpdateLayeredAlpha() {
-#if defined(OS_WIN)
- double scale = in_enable_area_ ? 1 : .5;
- static_cast<views::WidgetWin*>(popup_)->SetOpacity(
- static_cast<BYTE>(animation_.GetCurrentValue() * scale * 255.0));
- popup_->GetRootView()->SchedulePaint();
-#else
- NOTIMPLEMENTED();
-#endif
- }
-
- private:
- // DraggedTabController that created us.
- DraggedTabController* controller_;
-
- // Window we're showing.
- views::Widget* popup_;
-
- // NativeView of |popup_|. We cache this to avoid the possibility of
- // invoking a method on popup_ after we close it.
- gfx::NativeView popup_view_;
-
- // Animation for when first made visible.
- SlideAnimation animation_;
-
- // Have we been hidden?
- bool hidden_;
-
- // Value of DockInfo::in_enable_area.
- bool in_enable_area_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, public:
-
-DraggedTabController::DraggedTabController(BaseTab* source_tab,
- BaseTabStrip* source_tabstrip)
- : dragged_contents_(NULL),
- original_delegate_(NULL),
- source_tabstrip_(source_tabstrip),
- source_model_index_(source_tabstrip->GetModelIndexOfBaseTab(source_tab)),
- attached_tabstrip_(NULL),
- attached_tab_(NULL),
- offset_to_width_ratio_(0),
- old_focused_view_(NULL),
- last_move_screen_loc_(0),
- mini_(source_tab->data().mini),
- pinned_(source_tabstrip->IsTabPinned(source_tab)),
- started_drag_(false),
- active_(true) {
- instance_ = this;
- SetDraggedContents(
- GetModel(source_tabstrip_)->GetTabContentsAt(source_model_index_));
- // Listen for Esc key presses.
- MessageLoopForUI::current()->AddObserver(this);
-}
-
-DraggedTabController::~DraggedTabController() {
- if (instance_ == this)
- instance_ = NULL;
-
- MessageLoopForUI::current()->RemoveObserver(this);
- // Need to delete the view here manually _before_ we reset the dragged
- // contents to NULL, otherwise if the view is animating to its destination
- // bounds, it won't be able to clean up properly since its cleanup routine
- // uses GetIndexForDraggedContents, which will be invalid.
- view_.reset(NULL);
- SetDraggedContents(NULL); // This removes our observer.
-}
-
-// static
-bool DraggedTabController::IsAttachedTo(BaseTabStrip* tab_strip) {
- return instance_ && instance_->active_ &&
- instance_->attached_tabstrip_ == tab_strip;
-}
-
-void DraggedTabController::CaptureDragInfo(views::View* tab,
- const gfx::Point& mouse_offset) {
- if (tab->width() > 0) {
- offset_to_width_ratio_ = static_cast<float>(mouse_offset.x()) /
- static_cast<float>(tab->width());
- }
- start_screen_point_ = GetCursorScreenPoint();
- mouse_offset_ = mouse_offset;
- InitWindowCreatePoint();
-}
-
-void DraggedTabController::Drag() {
- bring_to_front_timer_.Stop();
-
- // Before we get to dragging anywhere, ensure that we consider ourselves
- // attached to the source tabstrip.
- if (!started_drag_ && CanStartDrag()) {
- started_drag_ = true;
- SaveFocus();
- Attach(source_tabstrip_, gfx::Point());
- }
-
- if (started_drag_)
- ContinueDragging();
-}
-
-void DraggedTabController::EndDrag(bool canceled) {
- EndDragImpl(canceled ? CANCELED : NORMAL);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, PageNavigator implementation:
-
-void DraggedTabController::OpenURLFromTab(TabContents* source,
- const GURL& url,
- const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition) {
- if (original_delegate_) {
- if (disposition == CURRENT_TAB)
- disposition = NEW_WINDOW;
-
- original_delegate_->OpenURLFromTab(source, url, referrer,
- disposition, transition);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, TabContentsDelegate implementation:
-
-void DraggedTabController::NavigationStateChanged(const TabContents* source,
- unsigned changed_flags) {
- if (view_.get())
- view_->Update();
-}
-
-void DraggedTabController::AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture) {
- DCHECK(disposition != CURRENT_TAB);
-
- // Theoretically could be called while dragging if the page tries to
- // spawn a window. Route this message back to the browser in most cases.
- if (original_delegate_) {
- original_delegate_->AddNewContents(source, new_contents, disposition,
- initial_pos, user_gesture);
- }
-}
-
-void DraggedTabController::ActivateContents(TabContents* contents) {
- // Ignored.
-}
-
-void DraggedTabController::DeactivateContents(TabContents* contents) {
- // Ignored.
-}
-
-void DraggedTabController::LoadingStateChanged(TabContents* source) {
- // It would be nice to respond to this message by changing the
- // screen shot in the dragged tab.
- if (view_.get())
- view_->Update();
-}
-
-void DraggedTabController::CloseContents(TabContents* source) {
- // Theoretically could be called by a window. Should be ignored
- // because window.close() is ignored (usually, even though this
- // method gets called.)
-}
-
-void DraggedTabController::MoveContents(TabContents* source,
- const gfx::Rect& pos) {
- // Theoretically could be called by a web page trying to move its
- // own window. Should be ignored since we're moving the window...
-}
-
-void DraggedTabController::ToolbarSizeChanged(TabContents* source,
- bool finished) {
- // Dragged tabs don't care about this.
-}
-
-void DraggedTabController::URLStarredChanged(TabContents* source,
- bool starred) {
- // Ignored.
-}
-
-void DraggedTabController::UpdateTargetURL(TabContents* source,
- const GURL& url) {
- // Ignored.
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, NotificationObserver implementation:
-
-void DraggedTabController::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
- DCHECK(Source<TabContents>(source).ptr() == dragged_contents_);
- EndDragImpl(TAB_DESTROYED);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, MessageLoop::Observer implementation:
-
-#if defined(OS_WIN)
-void DraggedTabController::WillProcessMessage(const MSG& msg) {
-}
-
-void DraggedTabController::DidProcessMessage(const MSG& msg) {
- // If the user presses ESC during a drag, we need to abort and revert things
- // to the way they were. This is the most reliable way to do this since no
- // single view or window reliably receives events throughout all the various
- // kinds of tab dragging.
- if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)
- EndDrag(true);
-}
-#else
-void DraggedTabController::WillProcessEvent(GdkEvent* event) {
-}
-
-void DraggedTabController::DidProcessEvent(GdkEvent* event) {
- if (event->type == GDK_KEY_PRESS &&
- reinterpret_cast<GdkEventKey*>(event)->keyval == GDK_Escape) {
- EndDrag(true);
- }
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabController, private:
-
-void DraggedTabController::InitWindowCreatePoint() {
- // window_create_point_ is only used in CompleteDrag() (through
- // GetWindowCreatePoint() to get the start point of the docked window) when
- // the attached_tabstrip_ is NULL and all the window's related bound
- // information are obtained from source_tabstrip_. So, we need to get the
- // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise,
- // the window_create_point_ is not in the correct coordinate system. Please
- // refer to http://crbug.com/6223 comment #15 for detailed information.
- views::View* first_tab = source_tabstrip_->base_tab_at_tab_index(0);
- views::View::ConvertPointToWidget(first_tab, &first_source_tab_point_);
- UpdateWindowCreatePoint();
-}
-
-void DraggedTabController::UpdateWindowCreatePoint() {
- // See comments in InitWindowCreatePoint for details on this.
- window_create_point_ = first_source_tab_point_;
- window_create_point_.Offset(mouse_offset_.x(), mouse_offset_.y());
-}
-
-gfx::Point DraggedTabController::GetWindowCreatePoint() const {
- gfx::Point cursor_point = GetCursorScreenPoint();
- if (dock_info_.type() != DockInfo::NONE) {
- // If we're going to dock, we need to return the exact coordinate,
- // otherwise we may attempt to maximize on the wrong monitor.
- return cursor_point;
- }
- return gfx::Point(cursor_point.x() - window_create_point_.x(),
- cursor_point.y() - window_create_point_.y());
-}
-
-void DraggedTabController::UpdateDockInfo(const gfx::Point& screen_point) {
- // Update the DockInfo for the current mouse coordinates.
- DockInfo dock_info = GetDockInfoAtPoint(screen_point);
- if (source_tabstrip_->type() == BaseTabStrip::VERTICAL_TAB_STRIP &&
- ((dock_info.type() == DockInfo::LEFT_OF_WINDOW &&
- !base::i18n::IsRTL()) ||
- (dock_info.type() == DockInfo::RIGHT_OF_WINDOW &&
- base::i18n::IsRTL()))) {
- // For side tabs it's way to easy to trigger to docking along the left/right
- // edge, so we disable it.
- dock_info = DockInfo();
- }
- if (!dock_info.equals(dock_info_)) {
- // DockInfo for current position differs.
- if (dock_info_.type() != DockInfo::NONE &&
- !dock_controllers_.empty()) {
- // Hide old visual indicator.
- dock_controllers_.back()->Hide();
- }
- dock_info_ = dock_info;
- if (dock_info_.type() != DockInfo::NONE) {
- // Show new docking position.
- DockDisplayer* controller = new DockDisplayer(this, dock_info_);
- if (controller->popup_view()) {
- dock_controllers_.push_back(controller);
- dock_windows_.insert(controller->popup_view());
- } else {
- delete controller;
- }
- }
- } else if (dock_info_.type() != DockInfo::NONE &&
- !dock_controllers_.empty()) {
- // Current dock position is the same as last, update the controller's
- // in_enable_area state as it may have changed.
- dock_controllers_.back()->UpdateInEnabledArea(dock_info_.in_enable_area());
- }
-}
-
-void DraggedTabController::SetDraggedContents(TabContents* new_contents) {
- if (dragged_contents_) {
- registrar_.Remove(this,
- NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(dragged_contents_));
- if (original_delegate_)
- dragged_contents_->set_delegate(original_delegate_);
- }
- original_delegate_ = NULL;
- dragged_contents_ = new_contents;
- if (dragged_contents_) {
- registrar_.Add(this,
- NotificationType::TAB_CONTENTS_DESTROYED,
- Source<TabContents>(dragged_contents_));
-
- // We need to be the delegate so we receive messages about stuff,
- // otherwise our dragged_contents() may be replaced and subsequently
- // collected/destroyed while the drag is in process, leading to
- // nasty crashes.
- original_delegate_ = dragged_contents_->delegate();
- dragged_contents_->set_delegate(this);
- }
-}
-
-void DraggedTabController::SaveFocus() {
- if (!old_focused_view_) {
- old_focused_view_ = source_tabstrip_->GetRootView()->GetFocusedView();
- source_tabstrip_->GetRootView()->FocusView(source_tabstrip_);
- }
-}
-
-void DraggedTabController::RestoreFocus() {
- if (old_focused_view_ && attached_tabstrip_ == source_tabstrip_)
- old_focused_view_->GetRootView()->FocusView(old_focused_view_);
- old_focused_view_ = NULL;
-}
-
-bool DraggedTabController::CanStartDrag() const {
- // Determine if the mouse has moved beyond a minimum elasticity distance in
- // any direction from the starting point.
- static const int kMinimumDragDistance = 10;
- gfx::Point screen_point = GetCursorScreenPoint();
- int x_offset = abs(screen_point.x() - start_screen_point_.x());
- int y_offset = abs(screen_point.y() - start_screen_point_.y());
- return sqrt(pow(static_cast<float>(x_offset), 2) +
- pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance;
-}
-
-void DraggedTabController::ContinueDragging() {
- // Note that the coordinates given to us by |drag_event| are basically
- // useless, since they're in source_tab_ coordinates. On the surface, you'd
- // think we could just convert them to screen coordinates, however in the
- // situation where we're dragging the last tab in a window when multiple
- // windows are open, the coordinates of |source_tab_| are way off in
- // hyperspace since the window was moved there instead of being closed so
- // that we'd keep receiving events. And our ConvertPointToScreen methods
- // aren't really multi-screen aware. So really it's just safer to get the
- // actual position of the mouse cursor directly from Windows here, which is
- // guaranteed to be correct regardless of monitor config.
- gfx::Point screen_point = GetCursorScreenPoint();
-
-#if defined(OS_CHROMEOS)
- // We don't allow detaching in chrome os.
- BaseTabStrip* target_tabstrip = source_tabstrip_;
-#else
- // Determine whether or not we have dragged over a compatible TabStrip in
- // another browser window. If we have, we should attach to it and start
- // dragging within it.
- BaseTabStrip* target_tabstrip = GetTabStripForPoint(screen_point);
-#endif
- if (target_tabstrip != attached_tabstrip_) {
- // Make sure we're fully detached from whatever TabStrip we're attached to
- // (if any).
- if (attached_tabstrip_)
- Detach();
- if (target_tabstrip)
- Attach(target_tabstrip, screen_point);
- }
- if (!target_tabstrip) {
- bring_to_front_timer_.Start(
- base::TimeDelta::FromMilliseconds(kBringToFrontDelay), this,
- &DraggedTabController::BringWindowUnderMouseToFront);
- }
-
- UpdateDockInfo(screen_point);
-
- if (attached_tabstrip_)
- MoveAttachedTab(screen_point);
- else
- MoveDetachedTab(screen_point);
-}
-
-void DraggedTabController::MoveAttachedTab(const gfx::Point& screen_point) {
- DCHECK(attached_tabstrip_);
- DCHECK(!view_.get());
-
- gfx::Point dragged_view_point = GetAttachedTabDragPoint(screen_point);
- TabStripModel* attached_model = GetModel(attached_tabstrip_);
- int from_index = attached_model->GetIndexOfTabContents(dragged_contents_);
-
- int threshold = kVerticalMoveThreshold;
- if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- TabStrip* tab_strip = static_cast<TabStrip*>(attached_tabstrip_);
-
- // Determine the horizontal move threshold. This is dependent on the width
- // of tabs. The smaller the tabs compared to the standard size, the smaller
- // the threshold.
- double unselected, selected;
- tab_strip->GetCurrentTabWidths(&unselected, &selected);
- double ratio = unselected / Tab::GetStandardSize().width();
- threshold = static_cast<int>(ratio * kHorizontalMoveThreshold);
- }
-
- // Update the model, moving the TabContents from one index to another. Do this
- // only if we have moved a minimum distance since the last reorder (to prevent
- // jitter).
- if (abs(MajorAxisValue(screen_point, attached_tabstrip_) -
- last_move_screen_loc_) > threshold) {
- gfx::Point dragged_view_screen_point(dragged_view_point);
- views::View::ConvertPointToScreen(attached_tabstrip_,
- &dragged_view_screen_point);
- gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_screen_point);
- int to_index = GetInsertionIndexForDraggedBounds(bounds, true);
- to_index = NormalizeIndexToAttachedTabStrip(to_index);
- if (from_index != to_index) {
- last_move_screen_loc_ = MajorAxisValue(screen_point, attached_tabstrip_);
- attached_model->MoveTabContentsAt(from_index, to_index, true);
- }
- }
-
- attached_tab_->SchedulePaint();
- attached_tab_->SetX(dragged_view_point.x());
- attached_tab_->SetX(
- attached_tabstrip_->MirroredLeftPointForRect(attached_tab_->bounds()));
- attached_tab_->SetY(dragged_view_point.y());
- attached_tab_->SchedulePaint();
-}
-
-void DraggedTabController::MoveDetachedTab(const gfx::Point& screen_point) {
- DCHECK(!attached_tabstrip_);
- DCHECK(view_.get());
-
- int x = screen_point.x() - mouse_offset_.x();
- int y = screen_point.y() - mouse_offset_.y();
-
- // Move the View. There are no changes to the model if we're detached.
- view_->MoveTo(gfx::Point(x, y));
-}
-
-DockInfo DraggedTabController::GetDockInfoAtPoint(
- const gfx::Point& screen_point) {
- if (attached_tabstrip_) {
- // If the mouse is over a tab strip, don't offer a dock position.
- return DockInfo();
- }
-
- if (dock_info_.IsValidForPoint(screen_point)) {
- // It's possible any given screen coordinate has multiple docking
- // positions. Check the current info first to avoid having the docking
- // position bounce around.
- return dock_info_;
- }
-
- gfx::NativeView dragged_hwnd = view_->GetWidget()->GetNativeView();
- dock_windows_.insert(dragged_hwnd);
- DockInfo info = DockInfo::GetDockInfoAtPoint(screen_point, dock_windows_);
- dock_windows_.erase(dragged_hwnd);
- return info;
-}
-
-BaseTabStrip* DraggedTabController::GetTabStripForPoint(
- const gfx::Point& screen_point) {
- gfx::NativeView dragged_view = NULL;
- if (view_.get()) {
- dragged_view = view_->GetWidget()->GetNativeView();
- dock_windows_.insert(dragged_view);
- }
- gfx::NativeWindow local_window =
- DockInfo::GetLocalProcessWindowAtPoint(screen_point, dock_windows_);
- if (dragged_view)
- dock_windows_.erase(dragged_view);
- if (!local_window)
- return NULL;
- BrowserView* browser =
- BrowserView::GetBrowserViewForNativeWindow(local_window);
- // We don't allow drops on windows that don't have tabstrips.
- if (!browser ||
- !browser->browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP))
- return NULL;
-
- BaseTabStrip* other_tabstrip = browser->tabstrip();
- if (!other_tabstrip->controller()->IsCompatibleWith(source_tabstrip_))
- return NULL;
- return GetTabStripIfItContains(other_tabstrip, screen_point);
-}
-
-BaseTabStrip* DraggedTabController::GetTabStripIfItContains(
- BaseTabStrip* tabstrip, const gfx::Point& screen_point) const {
- static const int kVerticalDetachMagnetism = 15;
- static const int kHorizontalDetachMagnetism = 15;
- // Make sure the specified screen point is actually within the bounds of the
- // specified tabstrip...
- gfx::Rect tabstrip_bounds = GetViewScreenBounds(tabstrip);
- if (tabstrip->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- if (screen_point.x() < tabstrip_bounds.right() &&
- screen_point.x() >= tabstrip_bounds.x()) {
- // TODO(beng): make this be relative to the start position of the mouse
- // for the source TabStrip.
- int upper_threshold = tabstrip_bounds.bottom() + kVerticalDetachMagnetism;
- int lower_threshold = tabstrip_bounds.y() - kVerticalDetachMagnetism;
- if (screen_point.y() >= lower_threshold &&
- screen_point.y() <= upper_threshold) {
- return tabstrip;
- }
- }
- } else {
- if (screen_point.y() < tabstrip_bounds.bottom() &&
- screen_point.y() >= tabstrip_bounds.y()) {
- int upper_threshold = tabstrip_bounds.right() +
- kHorizontalDetachMagnetism;
- int lower_threshold = tabstrip_bounds.x() - kHorizontalDetachMagnetism;
- if (screen_point.x() >= lower_threshold &&
- screen_point.x() <= upper_threshold) {
- return tabstrip;
- }
- }
- }
- return NULL;
-}
-
-void DraggedTabController::Attach(BaseTabStrip* attached_tabstrip,
- const gfx::Point& screen_point) {
- DCHECK(!attached_tabstrip_); // We should already have detached by the time
- // we get here.
- DCHECK(!attached_tab_); // Similarly there should be no attached tab.
-
- attached_tabstrip_ = attached_tabstrip;
-
- // We don't need the photo-booth while we're attached.
- photobooth_.reset(NULL);
-
- // And we don't need the dragged view.
- view_.reset();
-
- BaseTab* tab = GetTabMatchingDraggedContents(attached_tabstrip_);
-
- if (!tab) {
- // There is no Tab in |attached_tabstrip| that corresponds to the dragged
- // TabContents. We must now create one.
-
- // Remove ourselves as the delegate now that the dragged TabContents is
- // being inserted back into a Browser.
- dragged_contents_->set_delegate(NULL);
- original_delegate_ = NULL;
-
- // Return the TabContents' to normalcy.
- dragged_contents_->set_capturing_contents(false);
-
- // Inserting counts as a move. We don't want the tabs to jitter when the
- // user moves the tab immediately after attaching it.
- last_move_screen_loc_ = MajorAxisValue(screen_point, attached_tabstrip);
-
- // Figure out where to insert the tab based on the bounds of the dragged
- // representation and the ideal bounds of the other Tabs already in the
- // strip. ("ideal bounds" are stable even if the Tabs' actual bounds are
- // changing due to animation).
- gfx::Rect bounds = GetDraggedViewTabStripBounds(screen_point);
- int index = GetInsertionIndexForDraggedBounds(bounds, false);
- attached_tabstrip_->set_attaching_dragged_tab(true);
- GetModel(attached_tabstrip_)->InsertTabContentsAt(
- index, dragged_contents_,
- TabStripModel::ADD_SELECTED |
- (pinned_ ? TabStripModel::ADD_PINNED : 0));
- attached_tabstrip_->set_attaching_dragged_tab(false);
-
- tab = GetTabMatchingDraggedContents(attached_tabstrip_);
- }
- DCHECK(tab); // We should now have a tab.
- attached_tab_ = tab;
- attached_tabstrip_->StartedDraggingTab(tab);
-
- if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- // The size of the dragged tab may have changed. Adjust the x offset so that
- // ratio of mouse_offset_ to original width is maintained.
- mouse_offset_.set_x(static_cast<int>(offset_to_width_ratio_ *
- static_cast<int>(tab->width())));
- }
-
- // Move the corresponding window to the front.
- attached_tabstrip_->GetWindow()->Activate();
-}
-
-void DraggedTabController::Detach() {
- // Prevent the TabContents' HWND from being hidden by any of the model
- // operations performed during the drag.
- dragged_contents_->set_capturing_contents(true);
-
- // Update the Model.
- TabRendererData tab_data = attached_tab_->data();
- TabStripModel* attached_model = GetModel(attached_tabstrip_);
- int index = attached_model->GetIndexOfTabContents(dragged_contents_);
- DCHECK(index != -1);
- // Hide the tab so that the user doesn't see it animate closed.
- attached_tab_->SetVisible(false);
- int attached_tab_width = attached_tab_->width();
- attached_model->DetachTabContentsAt(index);
- // Detaching may end up deleting the tab, drop references to it.
- attached_tab_ = NULL;
-
- // If we've removed the last Tab from the TabStrip, hide the frame now.
- if (attached_model->empty())
- HideFrame();
-
- // Set up the photo booth to start capturing the contents of the dragged
- // TabContents.
- if (!photobooth_.get()) {
- photobooth_.reset(
- NativeViewPhotobooth::Create(dragged_contents_->GetNativeView()));
- }
-
- // Create the dragged view.
- EnsureDraggedView(tab_data);
- view_->SetTabWidthAndUpdate(attached_tab_width, photobooth_.get());
-
- // Detaching resets the delegate, but we still want to be the delegate.
- dragged_contents_->set_delegate(this);
-
- attached_tabstrip_ = NULL;
-}
-
-int DraggedTabController::GetInsertionIndexForDraggedBounds(
- const gfx::Rect& dragged_bounds,
- bool is_tab_attached) const {
- int right_tab_x = 0;
- int bottom_tab_y = 0;
-
- // If the UI layout of the tab strip is right-to-left, we need to mirror the
- // bounds of the dragged tab before performing the drag/drop related
- // calculations. We mirror the dragged bounds because we determine the
- // position of each tab on the tab strip by calling GetBounds() (without the
- // mirroring transformation flag) which effectively means that even though
- // the tabs are rendered from right to left, the code performs the
- // calculation as if the tabs are laid out from left to right. Mirroring the
- // dragged bounds adjusts the coordinates of the tab we are dragging so that
- // it uses the same orientation used by the tabs on the tab strip.
- gfx::Rect adjusted_bounds(dragged_bounds);
- adjusted_bounds.set_x(
- attached_tabstrip_->MirroredLeftPointForRect(adjusted_bounds));
-
- int index = -1;
- for (int i = 0; i < attached_tabstrip_->tab_count(); ++i) {
- const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i);
- if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- gfx::Rect left_half = ideal_bounds;
- left_half.set_width(left_half.width() / 2);
- gfx::Rect right_half = ideal_bounds;
- right_half.set_width(ideal_bounds.width() - left_half.width());
- right_half.set_x(left_half.right());
- right_tab_x = right_half.right();
- if (adjusted_bounds.x() >= right_half.x() &&
- adjusted_bounds.x() < right_half.right()) {
- index = i + 1;
- break;
- } else if (adjusted_bounds.x() >= left_half.x() &&
- adjusted_bounds.x() < left_half.right()) {
- index = i;
- break;
- }
- } else {
- // Vertical tab strip.
- int max_y = ideal_bounds.bottom();
- int mid_y = ideal_bounds.y() + ideal_bounds.height() / 2;
- bottom_tab_y = max_y;
- if (adjusted_bounds.y() < mid_y) {
- index = i;
- break;
- } else if (adjusted_bounds.y() >= mid_y && adjusted_bounds.y() < max_y) {
- index = i + 1;
- break;
- }
- }
- }
- if (index == -1) {
- if ((attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP &&
- adjusted_bounds.right() > right_tab_x) ||
- (attached_tabstrip_->type() == BaseTabStrip::VERTICAL_TAB_STRIP &&
- adjusted_bounds.y() >= bottom_tab_y)) {
- index = GetModel(attached_tabstrip_)->count();
- } else {
- index = 0;
- }
- }
-
- index = GetModel(attached_tabstrip_)->ConstrainInsertionIndex(index, mini_);
- if (is_tab_attached && mini_ &&
- index == GetModel(attached_tabstrip_)->IndexOfFirstNonMiniTab()) {
- index--;
- }
- return index;
-}
-
-gfx::Rect DraggedTabController::GetDraggedViewTabStripBounds(
- const gfx::Point& screen_point) {
- gfx::Point client_point =
- ConvertScreenPointToTabStripPoint(attached_tabstrip_, screen_point);
- // attached_tab_ is NULL when inserting into a new tabstrip.
- if (attached_tab_) {
- return gfx::Rect(client_point.x(), client_point.y(),
- attached_tab_->width(), attached_tab_->height());
- }
-
- if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- double sel_width, unselected_width;
- static_cast<TabStrip*>(attached_tabstrip_)->GetCurrentTabWidths(
- &sel_width, &unselected_width);
- return gfx::Rect(client_point.x(), client_point.y(),
- static_cast<int>(sel_width),
- Tab::GetStandardSize().height());
- }
-
- return gfx::Rect(client_point.x(), client_point.y(),
- attached_tabstrip_->width(),
- SideTab::GetPreferredHeight());
-}
-
-gfx::Point DraggedTabController::GetAttachedTabDragPoint(
- const gfx::Point& screen_point) {
- DCHECK(attached_tabstrip_); // The tab must be attached.
-
- int x = screen_point.x() - mouse_offset_.x();
- int y = screen_point.y() - mouse_offset_.y();
-
- gfx::Point tab_loc(x, y);
- views::View::ConvertPointToView(NULL, attached_tabstrip_, &tab_loc);
-
- x = tab_loc.x();
- y = tab_loc.y();
-
- const gfx::Size& tab_size = attached_tab_->bounds().size();
-
- if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) {
- int max_x = attached_tabstrip_->bounds().right() - tab_size.width();
- x = std::min(std::max(x, 0), max_x);
- y = 0;
- } else {
- x = SideTabStrip::kTabStripInset;
- int max_y = attached_tabstrip_->bounds().bottom() - tab_size.height();
- y = std::min(std::max(y, SideTabStrip::kTabStripInset), max_y);
- }
- return gfx::Point(x, y);
-}
-
-BaseTab* DraggedTabController::GetTabMatchingDraggedContents(
- BaseTabStrip* tabstrip) const {
- int model_index =
- GetModel(tabstrip)->GetIndexOfTabContents(dragged_contents_);
- return model_index == TabStripModel::kNoTab ?
- NULL : tabstrip->GetBaseTabAtModelIndex(model_index);
-}
-
-void DraggedTabController::EndDragImpl(EndDragType type) {
- // WARNING: this may be invoked multiple times. In particular, if deletion
- // occurs after a delay (as it does when the tab is released in the original
- // tab strip) and the navigation controller/tab contents is deleted before
- // the animation finishes, this is invoked twice. The second time through
- // type == TAB_DESTROYED.
-
- active_ = false;
-
- bring_to_front_timer_.Stop();
-
- // Hide the current dock controllers.
- for (size_t i = 0; i < dock_controllers_.size(); ++i) {
- // Be sure and clear the controller first, that way if Hide ends up
- // deleting the controller it won't call us back.
- dock_controllers_[i]->clear_controller();
- dock_controllers_[i]->Hide();
- }
- dock_controllers_.clear();
- dock_windows_.clear();
-
- if (type != TAB_DESTROYED) {
- // We only finish up the drag if we were actually dragging. If start_drag_
- // is false, the user just clicked and released and didn't move the mouse
- // enough to trigger a drag.
- if (started_drag_) {
- RestoreFocus();
- if (type == CANCELED)
- RevertDrag();
- else
- CompleteDrag();
- }
- if (dragged_contents_ && dragged_contents_->delegate() == this)
- dragged_contents_->set_delegate(original_delegate_);
- } else {
- // If we get here it means the NavigationController is going down. Don't
- // attempt to do any cleanup other than resetting the delegate (if we're
- // still the delegate).
- if (dragged_contents_ && dragged_contents_->delegate() == this)
- dragged_contents_->set_delegate(NULL);
- dragged_contents_ = NULL;
- }
-
- // The delegate of the dragged contents should have been reset. Unset the
- // original delegate so that we don't attempt to reset the delegate when
- // deleted.
- DCHECK(!dragged_contents_ || dragged_contents_->delegate() != this);
- original_delegate_ = NULL;
-
- source_tabstrip_->DestroyDragController();
-}
-
-void DraggedTabController::RevertDrag() {
- DCHECK(started_drag_);
-
- // We save this here because code below will modify |attached_tabstrip_|.
- bool restore_frame = attached_tabstrip_ != source_tabstrip_;
- if (attached_tabstrip_) {
- int index = GetModel(attached_tabstrip_)->GetIndexOfTabContents(
- dragged_contents_);
- if (attached_tabstrip_ != source_tabstrip_) {
- // The Tab was inserted into another TabStrip. We need to put it back
- // into the original one.
- GetModel(attached_tabstrip_)->DetachTabContentsAt(index);
- // TODO(beng): (Cleanup) seems like we should use Attach() for this
- // somehow.
- attached_tabstrip_ = source_tabstrip_;
- GetModel(source_tabstrip_)->InsertTabContentsAt(
- source_model_index_, dragged_contents_,
- TabStripModel::ADD_SELECTED |
- (pinned_ ? TabStripModel::ADD_PINNED : 0));
- } else {
- // The Tab was moved within the TabStrip where the drag was initiated.
- // Move it back to the starting location.
- GetModel(source_tabstrip_)->MoveTabContentsAt(index, source_model_index_,
- true);
- source_tabstrip_->StoppedDraggingTab(attached_tab_);
- }
- } else {
- // TODO(beng): (Cleanup) seems like we should use Attach() for this
- // somehow.
- attached_tabstrip_ = source_tabstrip_;
- // The Tab was detached from the TabStrip where the drag began, and has not
- // been attached to any other TabStrip. We need to put it back into the
- // source TabStrip.
- GetModel(source_tabstrip_)->InsertTabContentsAt(
- source_model_index_, dragged_contents_,
- TabStripModel::ADD_SELECTED |
- (pinned_ ? TabStripModel::ADD_PINNED : 0));
- }
-
- // If we're not attached to any TabStrip, or attached to some other TabStrip,
- // we need to restore the bounds of the original TabStrip's frame, in case
- // it has been hidden.
- if (restore_frame) {
- if (!restore_bounds_.IsEmpty()) {
-#if defined(OS_WIN)
- HWND frame_hwnd = source_tabstrip_->GetWidget()->GetNativeView();
- MoveWindow(frame_hwnd, restore_bounds_.x(), restore_bounds_.y(),
- restore_bounds_.width(), restore_bounds_.height(), TRUE);
-#else
- NOTIMPLEMENTED();
-#endif
- }
- }
-}
-
-void DraggedTabController::CompleteDrag() {
- DCHECK(started_drag_);
-
- if (attached_tabstrip_) {
- attached_tabstrip_->StoppedDraggingTab(attached_tab_);
- } else {
- if (dock_info_.type() != DockInfo::NONE) {
- Profile* profile = GetModel(source_tabstrip_)->profile();
- switch (dock_info_.type()) {
- case DockInfo::LEFT_OF_WINDOW:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Left"),
- profile);
- break;
-
- case DockInfo::RIGHT_OF_WINDOW:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Right"),
- profile);
- break;
-
- case DockInfo::BOTTOM_OF_WINDOW:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Bottom"),
- profile);
- break;
-
- case DockInfo::TOP_OF_WINDOW:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Top"),
- profile);
- break;
-
- case DockInfo::MAXIMIZE:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_Maximize"),
- profile);
- break;
-
- case DockInfo::LEFT_HALF:
- UserMetrics::RecordAction(UserMetricsAction("DockingWindow_LeftHalf"),
- profile);
- break;
-
- case DockInfo::RIGHT_HALF:
- UserMetrics::RecordAction(
- UserMetricsAction("DockingWindow_RightHalf"),
- profile);
- break;
-
- case DockInfo::BOTTOM_HALF:
- UserMetrics::RecordAction(
- UserMetricsAction("DockingWindow_BottomHalf"),
- profile);
- break;
-
- default:
- NOTREACHED();
- break;
- }
- }
- // Compel the model to construct a new window for the detached TabContents.
- views::Window* window = source_tabstrip_->GetWindow();
- gfx::Rect window_bounds(window->GetNormalBounds());
- window_bounds.set_origin(GetWindowCreatePoint());
- // When modifying the following if statement, please make sure not to
- // introduce issue listed in http://crbug.com/6223 comment #11.
- bool rtl_ui = base::i18n::IsRTL();
- bool has_dock_position = (dock_info_.type() != DockInfo::NONE);
- if (rtl_ui && has_dock_position) {
- // Mirror X axis so the docked tab is aligned using the mouse click as
- // the top-right corner.
- window_bounds.set_x(window_bounds.x() - window_bounds.width());
- }
- Browser* new_browser =
- GetModel(source_tabstrip_)->delegate()->CreateNewStripWithContents(
- dragged_contents_, window_bounds, dock_info_, window->IsMaximized());
- TabStripModel* new_model = new_browser->tabstrip_model();
- new_model->SetTabPinned(new_model->GetIndexOfTabContents(dragged_contents_),
- pinned_);
- new_browser->window()->Show();
- }
-
- CleanUpHiddenFrame();
-}
-
-void DraggedTabController::EnsureDraggedView(const TabRendererData& data) {
- if (!view_.get()) {
- gfx::Rect tab_bounds;
- dragged_contents_->GetContainerBounds(&tab_bounds);
- BaseTab* renderer = source_tabstrip_->CreateTabForDragging();
- renderer->SetData(data);
- // DraggedTabView takes ownership of renderer.
- view_.reset(new DraggedTabView(renderer, mouse_offset_,
- tab_bounds.size(),
- Tab::GetMinimumSelectedSize()));
- }
-}
-
-gfx::Point DraggedTabController::GetCursorScreenPoint() const {
-#if defined(OS_WIN)
- DWORD pos = GetMessagePos();
- return gfx::Point(pos);
-#else
- gint x, y;
- gdk_display_get_pointer(gdk_display_get_default(), NULL, &x, &y, NULL);
- return gfx::Point(x, y);
-#endif
-}
-
-gfx::Rect DraggedTabController::GetViewScreenBounds(views::View* view) const {
- gfx::Point view_topleft;
- views::View::ConvertPointToScreen(view, &view_topleft);
- gfx::Rect view_screen_bounds = view->GetLocalBounds(true);
- view_screen_bounds.Offset(view_topleft.x(), view_topleft.y());
- return view_screen_bounds;
-}
-
-int DraggedTabController::NormalizeIndexToAttachedTabStrip(int index) const {
- DCHECK(attached_tabstrip_) << "Can only be called when attached!";
- TabStripModel* attached_model = GetModel(attached_tabstrip_);
- if (index >= attached_model->count())
- return attached_model->count() - 1;
- if (index == TabStripModel::kNoTab)
- return 0;
- return index;
-}
-
-void DraggedTabController::HideFrame() {
-#if defined(OS_WIN)
- // We don't actually hide the window, rather we just move it way off-screen.
- // If we actually hide it, we stop receiving drag events.
- HWND frame_hwnd = source_tabstrip_->GetWidget()->GetNativeView();
- RECT wr;
- GetWindowRect(frame_hwnd, &wr);
- MoveWindow(frame_hwnd, 0xFFFF, 0xFFFF, wr.right - wr.left,
- wr.bottom - wr.top, TRUE);
-
- // We also save the bounds of the window prior to it being moved, so that if
- // the drag session is aborted we can restore them.
- restore_bounds_ = gfx::Rect(wr);
-#else
- NOTIMPLEMENTED();
-#endif
-}
-
-void DraggedTabController::CleanUpHiddenFrame() {
- // If the model we started dragging from is now empty, we must ask the
- // delegate to close the frame.
- if (GetModel(source_tabstrip_)->empty())
- GetModel(source_tabstrip_)->delegate()->CloseFrameAfterDragSession();
-}
-
-void DraggedTabController::DockDisplayerDestroyed(
- DockDisplayer* controller) {
- DockWindows::iterator dock_i =
- dock_windows_.find(controller->popup_view());
- if (dock_i != dock_windows_.end())
- dock_windows_.erase(dock_i);
- else
- NOTREACHED();
-
- std::vector<DockDisplayer*>::iterator i =
- std::find(dock_controllers_.begin(), dock_controllers_.end(),
- controller);
- if (i != dock_controllers_.end())
- dock_controllers_.erase(i);
- else
- NOTREACHED();
-}
-
-void DraggedTabController::BringWindowUnderMouseToFront() {
- // If we're going to dock to another window, bring it to the front.
- gfx::NativeWindow window = dock_info_.window();
- if (!window) {
- gfx::NativeView dragged_view = view_->GetWidget()->GetNativeView();
- dock_windows_.insert(dragged_view);
- window = DockInfo::GetLocalProcessWindowAtPoint(GetCursorScreenPoint(),
- dock_windows_);
- dock_windows_.erase(dragged_view);
- }
- if (window) {
-#if defined(OS_WIN)
- // Move the window to the front.
- SetWindowPos(window, HWND_TOP, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-
- // The previous call made the window appear on top of the dragged window,
- // move the dragged window to the front.
- SetWindowPos(view_->GetWidget()->GetNativeView(), HWND_TOP, 0, 0, 0, 0,
- SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
-#else
- NOTIMPLEMENTED();
-#endif
- }
-}
-
-TabStripModel* DraggedTabController::GetModel(BaseTabStrip* tabstrip) const {
- return static_cast<BrowserTabStripController*>(tabstrip->controller())->
- model();
-}
diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h
index 5c9c619..e445018 100644
--- a/chrome/browser/views/tabs/dragged_tab_controller.h
+++ b/chrome/browser/views/tabs/dragged_tab_controller.h
@@ -6,334 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
#pragma once
-#include "base/message_loop.h"
-#include "base/scoped_ptr.h"
-#include "base/timer.h"
-#include "chrome/browser/dock_info.h"
-#include "chrome/browser/tab_contents/tab_contents_delegate.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-#include "gfx/rect.h"
-
-namespace views {
-class View;
-}
-class BaseTab;
-class BaseTabStrip;
-class DraggedTabView;
-class NativeViewPhotobooth;
-class TabStripModel;
-
-struct TabRendererData;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// DraggedTabController
-//
-// An object that handles a drag session for an individual Tab within a
-// TabStrip. This object is created whenever the mouse is pressed down on a
-// Tab and destroyed when the mouse is released or the drag operation is
-// aborted. The Tab that the user dragged (the "source tab") owns this object
-// and must be the only one to destroy it (via |DestroyDragController|).
-//
-///////////////////////////////////////////////////////////////////////////////
-class DraggedTabController : public TabContentsDelegate,
- public NotificationObserver,
- public MessageLoopForUI::Observer {
- public:
- DraggedTabController(BaseTab* source_tab,
- BaseTabStrip* source_tabstrip);
- virtual ~DraggedTabController();
-
- // Returns true if there is a drag underway and the drag is attached to
- // |tab_strip|.
- // NOTE: this returns false if the dragged tab controller is in the process
- // of finishing the drag.
- static bool IsAttachedTo(BaseTabStrip* tab_strip);
-
- // Capture information needed to be used during a drag session for this
- // controller's associated source tab and BaseTabStrip. |mouse_offset| is the
- // distance of the mouse pointer from the tab's origin.
- void CaptureDragInfo(views::View* tab, const gfx::Point& mouse_offset);
-
- // Responds to drag events subsequent to StartDrag. If the mouse moves a
- // sufficient distance before the mouse is released, a drag session is
- // initiated.
- void Drag();
-
- // Complete the current drag session. If the drag session was canceled
- // because the user pressed Escape or something interrupted it, |canceled|
- // is true so the helper can revert the state to the world before the drag
- // begun.
- void EndDrag(bool canceled);
-
- TabContents* dragged_contents() { return dragged_contents_; }
-
- // Returns true if a drag started.
- bool started_drag() const { return started_drag_; }
-
- private:
- class DockDisplayer;
- friend class DockDisplayer;
-
- typedef std::set<gfx::NativeView> DockWindows;
-
- // Enumeration of the ways a drag session can end.
- enum EndDragType {
- // Drag session exited normally: the user released the mouse.
- NORMAL,
-
- // The drag session was canceled (alt-tab during drag, escape ...)
- CANCELED,
-
- // The tab (NavigationController) was destroyed during the drag.
- TAB_DESTROYED
- };
-
- // Overridden from TabContentsDelegate:
- virtual void OpenURLFromTab(TabContents* source,
- const GURL& url,
- const GURL& referrer,
- WindowOpenDisposition disposition,
- PageTransition::Type transition);
- virtual void NavigationStateChanged(const TabContents* source,
- unsigned changed_flags);
- virtual void AddNewContents(TabContents* source,
- TabContents* new_contents,
- WindowOpenDisposition disposition,
- const gfx::Rect& initial_pos,
- bool user_gesture);
- virtual void ActivateContents(TabContents* contents);
- virtual void DeactivateContents(TabContents* contents);
- virtual void LoadingStateChanged(TabContents* source);
- virtual void CloseContents(TabContents* source);
- virtual void MoveContents(TabContents* source, const gfx::Rect& pos);
- virtual void ToolbarSizeChanged(TabContents* source, bool is_animating);
- virtual void URLStarredChanged(TabContents* source, bool starred);
- virtual void UpdateTargetURL(TabContents* source, const GURL& url);
-
- // Overridden from NotificationObserver:
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- // Overridden from MessageLoop::Observer:
-#if defined(OS_WIN)
- virtual void WillProcessMessage(const MSG& msg);
- virtual void DidProcessMessage(const MSG& msg);
-#else
- virtual void WillProcessEvent(GdkEvent* event);
- virtual void DidProcessEvent(GdkEvent* event);
-#endif
-
- // Initialize the offset used to calculate the position to create windows
- // in |GetWindowCreatePoint|. This should only be invoked from
- // |CaptureDragInfo|.
- void InitWindowCreatePoint();
-
- // Updates the window create point from |mouse_offset_|.
- void UpdateWindowCreatePoint();
-
- // Returns the point where a detached window should be created given the
- // current mouse position.
- gfx::Point GetWindowCreatePoint() const;
-
- void UpdateDockInfo(const gfx::Point& screen_point);
-
- // Sets the TabContents being dragged with the specified |new_contents|.
- void SetDraggedContents(TabContents* new_contents);
-
- // Saves focus in the window that the drag initiated from. Focus will be
- // restored appropriately if the drag ends within this same window.
- void SaveFocus();
-
- // Restore focus to the View that had focus before the drag was started, if
- // the drag ends within the same Window as it began.
- void RestoreFocus();
-
- // Tests whether the position of the mouse is past a minimum elasticity
- // threshold required to start a drag.
- bool CanStartDrag() const;
-
- // Move the DraggedTabView according to the current mouse screen position,
- // potentially updating the source and other TabStrips.
- void ContinueDragging();
-
- // Handles dragging a tab while the tab is attached.
- void MoveAttachedTab(const gfx::Point& screen_point);
-
- // Handles dragging while the tab is detached.
- void MoveDetachedTab(const gfx::Point& screen_point);
-
- // Returns the compatible TabStrip that is under the specified point (screen
- // coordinates), or NULL if there is none.
- BaseTabStrip* GetTabStripForPoint(const gfx::Point& screen_point);
-
- DockInfo GetDockInfoAtPoint(const gfx::Point& screen_point);
-
- // Returns the specified |tabstrip| if it contains the specified point
- // (screen coordinates), NULL if it does not.
- BaseTabStrip* GetTabStripIfItContains(BaseTabStrip* tabstrip,
- const gfx::Point& screen_point) const;
-
- // Attach the dragged Tab to the specified TabStrip.
- void Attach(BaseTabStrip* attached_tabstrip, const gfx::Point& screen_point);
-
- // Detach the dragged Tab from the current TabStrip.
- void Detach();
-
- // Returns the index where the dragged TabContents should be inserted into
- // the attached TabStripModel given the DraggedTabView's bounds
- // |dragged_bounds| in coordinates relative to the attached TabStrip.
- // |is_tab_attached| is true if the tab has already been added.
- int GetInsertionIndexForDraggedBounds(const gfx::Rect& dragged_bounds,
- bool is_tab_attached) const;
-
- // Retrieve the bounds of the DraggedTabView, relative to the attached
- // TabStrip, given location of the dragged tab in screen coordinates.
- gfx::Rect GetDraggedViewTabStripBounds(const gfx::Point& screen_point);
-
- // Get the position of the dragged tab view relative to the attached tab
- // strip.
- gfx::Point GetAttachedTabDragPoint(const gfx::Point& screen_point);
-
- // Finds the Tab within the specified TabStrip that corresponds to the
- // dragged TabContents.
- BaseTab* GetTabMatchingDraggedContents(BaseTabStrip* tabstrip) const;
-
- // Does the work for EndDrag. If we actually started a drag and |how_end| is
- // not TAB_DESTROYED then one of EndDrag or RevertDrag is invoked.
- void EndDragImpl(EndDragType how_end);
-
- // Reverts a cancelled drag operation.
- void RevertDrag();
-
- // Finishes a succesful drag operation.
- void CompleteDrag();
-
- // Create the DraggedTabView, if it does not yet exist.
- void EnsureDraggedView(const TabRendererData& data);
-
- // Utility for getting the mouse position in screen coordinates.
- gfx::Point GetCursorScreenPoint() const;
-
- // Returns the bounds (in screen coordinates) of the specified View.
- gfx::Rect GetViewScreenBounds(views::View* tabstrip) const;
-
- // Utility to convert the specified TabStripModel index to something valid
- // for the attached TabStrip.
- int NormalizeIndexToAttachedTabStrip(int index) const;
-
- // Hides the frame for the window that contains the TabStrip the current
- // drag session was initiated from.
- void HideFrame();
-
- // Closes a hidden frame at the end of a drag session.
- void CleanUpHiddenFrame();
-
- void DockDisplayerDestroyed(DockDisplayer* controller);
-
- void BringWindowUnderMouseToFront();
-
- // Returns the TabStripModel for the specified tabstrip.
- TabStripModel* GetModel(BaseTabStrip* tabstrip) const;
-
- // Handles registering for notifications.
- NotificationRegistrar registrar_;
-
- // The TabContents being dragged.
- TabContents* dragged_contents_;
-
- // The original TabContentsDelegate of |dragged_contents_|, before it was
- // detached from the browser window. We store this so that we can forward
- // certain delegate notifications back to it if we can't handle them locally.
- TabContentsDelegate* original_delegate_;
-
- // The TabStrip |source_tab_| originated from.
- BaseTabStrip* source_tabstrip_;
-
- // This is the index of the |source_tab_| in |source_tabstrip_| when the drag
- // began. This is used to restore the previous state if the drag is aborted.
- int source_model_index_;
-
- // The TabStrip the dragged Tab is currently attached to, or NULL if the
- // dragged Tab is detached.
- BaseTabStrip* attached_tabstrip_;
-
- // If attached this is the tab we're dragging.
- BaseTab* attached_tab_;
-
- // The visual representation of the dragged Tab.
- scoped_ptr<DraggedTabView> view_;
-
- // The photo-booth the TabContents sits in when the Tab is detached, to
- // obtain screen shots.
- scoped_ptr<NativeViewPhotobooth> photobooth_;
-
- // The position of the mouse (in screen coordinates) at the start of the drag
- // operation. This is used to calculate minimum elasticity before a
- // DraggedTabView is constructed.
- gfx::Point start_screen_point_;
-
- // This is the offset of the mouse from the top left of the Tab where
- // dragging begun. This is used to ensure that the dragged view is always
- // positioned at the correct location during the drag, and to ensure that the
- // detached window is created at the right location.
- gfx::Point mouse_offset_;
-
- // Ratio of the x-coordinate of the mouse offset to the width of the tab.
- float offset_to_width_ratio_;
-
- // A hint to use when positioning new windows created by detaching Tabs. This
- // is the distance of the mouse from the top left of the dragged tab as if it
- // were the distance of the mouse from the top left of the first tab in the
- // attached TabStrip from the top left of the window.
- gfx::Point window_create_point_;
-
- // Location of the first tab in the source tabstrip in screen coordinates.
- // This is used to calculate window_create_point_.
- gfx::Point first_source_tab_point_;
-
- // The bounds of the browser window before the last Tab was detached. When
- // the last Tab is detached, rather than destroying the frame (which would
- // abort the drag session), the frame is moved off-screen. If the drag is
- // aborted (e.g. by the user pressing Esc, or capture being lost), the Tab is
- // attached to the hidden frame and the frame moved back to these bounds.
- gfx::Rect restore_bounds_;
-
- // The last view that had focus in the window containing |source_tab_|. This
- // is saved so that focus can be restored properly when a drag begins and
- // ends within this same window.
- views::View* old_focused_view_;
-
- // The position along the major axis of the mouse cursor in screen coordinates
- // at the time of the last re-order event.
- int last_move_screen_loc_;
-
- DockInfo dock_info_;
-
- DockWindows dock_windows_;
-
- std::vector<DockDisplayer*> dock_controllers_;
-
- // Is the tab mini?
- const bool mini_;
-
- // Is the tab pinned?
- const bool pinned_;
-
- // Timer used to bring the window under the cursor to front. If the user
- // stops moving the mouse for a brief time over a browser window, it is
- // brought to front.
- base::OneShotTimer<DraggedTabController> bring_to_front_timer_;
-
- // Did the mouse move enough that we started a drag?
- bool started_drag_;
-
- // Is the drag active?
- bool active_;
-
- DISALLOW_COPY_AND_ASSIGN(DraggedTabController);
-};
+#include "chrome/browser/ui/views/tabs/dragged_tab_controller.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_CONTROLLER_H_
+
diff --git a/chrome/browser/views/tabs/dragged_tab_view.cc b/chrome/browser/views/tabs/dragged_tab_view.cc
deleted file mode 100644
index 8f77a87..0000000
--- a/chrome/browser/views/tabs/dragged_tab_view.cc
+++ /dev/null
@@ -1,222 +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/dragged_tab_view.h"
-
-#include "chrome/browser/views/tabs/native_view_photobooth.h"
-#include "gfx/canvas_skia.h"
-#include "third_party/skia/include/core/SkShader.h"
-#include "views/widget/widget.h"
-
-#if defined(OS_WIN)
-#include "views/widget/widget_win.h"
-#elif defined(OS_LINUX)
-#include "views/widget/widget_gtk.h"
-#endif
-
-static const int kTransparentAlpha = 200;
-static const int kOpaqueAlpha = 255;
-static const int kDragFrameBorderSize = 2;
-static const int kTwiceDragFrameBorderSize = 2 * kDragFrameBorderSize;
-static const float kScalingFactor = 0.5;
-static const SkColor kDraggedTabBorderColor = SkColorSetRGB(103, 129, 162);
-
-////////////////////////////////////////////////////////////////////////////////
-// DraggedTabView, public:
-
-DraggedTabView::DraggedTabView(views::View* renderer,
- const gfx::Point& mouse_tab_offset,
- const gfx::Size& contents_size,
- const gfx::Size& min_size)
- : renderer_(renderer),
- show_contents_on_drag_(true),
- mouse_tab_offset_(mouse_tab_offset),
- tab_size_(min_size),
- photobooth_(NULL),
- contents_size_(contents_size) {
- set_parent_owned(false);
-
-#if defined(OS_WIN)
- container_.reset(new views::WidgetWin);
- container_->set_delete_on_destroy(false);
- container_->set_window_style(WS_POPUP);
- container_->set_window_ex_style(
- WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW);
- container_->set_can_update_layered_window(false);
- container_->Init(NULL, gfx::Rect(0, 0, 0, 0));
- container_->SetContentsView(this);
-
- BOOL drag;
- if ((::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &drag, 0) != 0) &&
- (drag == FALSE)) {
- show_contents_on_drag_ = false;
- }
-#else
- container_.reset(new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP));
- container_->MakeTransparent();
- container_->set_delete_on_destroy(false);
- container_->Init(NULL, gfx::Rect(0, 0, 0, 0));
- container_->SetContentsView(this);
-#endif
-}
-
-DraggedTabView::~DraggedTabView() {
- GetParent()->RemoveChildView(this);
- container_->CloseNow();
-}
-
-void DraggedTabView::MoveTo(const gfx::Point& screen_point) {
- int x;
- if (base::i18n::IsRTL()) {
- // On RTL locales, a dragged tab (when it is not attached to a tab strip)
- // is rendered using a right-to-left orientation so we should calculate the
- // window position differently.
- gfx::Size ps = GetPreferredSize();
- x = screen_point.x() - ScaleValue(ps.width()) + mouse_tab_offset_.x() +
- ScaleValue(
- renderer_->MirroredXCoordinateInsideView(mouse_tab_offset_.x()));
- } else {
- x = screen_point.x() + mouse_tab_offset_.x() -
- ScaleValue(mouse_tab_offset_.x());
- }
- int y = screen_point.y() + mouse_tab_offset_.y() -
- ScaleValue(mouse_tab_offset_.y());
-
-#if defined(OS_WIN)
- int show_flags = container_->IsVisible() ? SWP_NOZORDER : SWP_SHOWWINDOW;
-
- container_->SetWindowPos(HWND_TOP, x, y, 0, 0,
- SWP_NOSIZE | SWP_NOACTIVATE | show_flags);
-#else
- gfx::Rect bounds;
- container_->GetBounds(&bounds, true);
- container_->SetBounds(gfx::Rect(x, y, bounds.width(), bounds.height()));
- if (!container_->IsVisible())
- container_->Show();
-#endif
-}
-
-void DraggedTabView::SetTabWidthAndUpdate(int width,
- NativeViewPhotobooth* photobooth) {
- tab_size_.set_width(width);
- photobooth_ = photobooth;
-#if defined(OS_WIN)
- container_->SetOpacity(kTransparentAlpha);
-#endif
- ResizeContainer();
- Update();
-}
-
-void DraggedTabView::Update() {
-#if defined(OS_WIN)
- container_->set_can_update_layered_window(true);
- SchedulePaint();
- container_->PaintNow(gfx::Rect());
- container_->set_can_update_layered_window(false);
-#else
- SchedulePaint();
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// DraggedTabView, views::View overrides:
-
-void DraggedTabView::Paint(gfx::Canvas* canvas) {
- if (show_contents_on_drag_)
- PaintDetachedView(canvas);
- else
- PaintFocusRect(canvas);
-}
-
-void DraggedTabView::Layout() {
- int left = 0;
- if (base::i18n::IsRTL())
- left = GetPreferredSize().width() - tab_size_.width();
- // The renderer_'s width should be tab_size_.width() in both LTR and RTL
- // locales. Wrong width will cause the wrong positioning of the tab view in
- // dragging. Please refer to http://crbug.com/6223 for details.
- renderer_->SetBounds(left, 0, tab_size_.width(), tab_size_.height());
-}
-
-gfx::Size DraggedTabView::GetPreferredSize() {
- int width = std::max(tab_size_.width(), contents_size_.width()) +
- kTwiceDragFrameBorderSize;
- int height = tab_size_.height() + kDragFrameBorderSize +
- contents_size_.height();
- return gfx::Size(width, height);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DraggedTabView, private:
-
-void DraggedTabView::PaintDetachedView(gfx::Canvas* canvas) {
- gfx::Size ps = GetPreferredSize();
- gfx::CanvasSkia scale_canvas(ps.width(), ps.height(), false);
- SkBitmap& bitmap_device = const_cast<SkBitmap&>(
- scale_canvas.getTopPlatformDevice().accessBitmap(true));
- bitmap_device.eraseARGB(0, 0, 0, 0);
-
- scale_canvas.FillRectInt(kDraggedTabBorderColor, 0,
- tab_size_.height() - kDragFrameBorderSize,
- ps.width(), ps.height() - tab_size_.height());
- int image_x = kDragFrameBorderSize;
- int image_y = tab_size_.height();
- int image_w = ps.width() - kTwiceDragFrameBorderSize;
- int image_h = contents_size_.height();
- scale_canvas.FillRectInt(SK_ColorBLACK, image_x, image_y, image_w, image_h);
- photobooth_->PaintScreenshotIntoCanvas(
- &scale_canvas,
- gfx::Rect(image_x, image_y, image_w, image_h));
- renderer_->ProcessPaint(&scale_canvas);
-
- SkIRect subset;
- subset.set(0, 0, ps.width(), ps.height());
- SkBitmap mipmap = scale_canvas.ExtractBitmap();
- mipmap.buildMipMap(true);
-
- SkShader* bitmap_shader =
- SkShader::CreateBitmapShader(mipmap, SkShader::kClamp_TileMode,
- SkShader::kClamp_TileMode);
-
- SkMatrix shader_scale;
- shader_scale.setScale(kScalingFactor, kScalingFactor);
- bitmap_shader->setLocalMatrix(shader_scale);
-
- SkPaint paint;
- paint.setShader(bitmap_shader);
- paint.setAntiAlias(true);
- bitmap_shader->unref();
-
- SkRect rc;
- rc.fLeft = 0;
- rc.fTop = 0;
- rc.fRight = SkIntToScalar(ps.width());
- rc.fBottom = SkIntToScalar(ps.height());
- canvas->AsCanvasSkia()->drawRect(rc, paint);
-}
-
-void DraggedTabView::PaintFocusRect(gfx::Canvas* canvas) {
- gfx::Size ps = GetPreferredSize();
- canvas->DrawFocusRect(0, 0,
- static_cast<int>(ps.width() * kScalingFactor),
- static_cast<int>(ps.height() * kScalingFactor));
-}
-
-void DraggedTabView::ResizeContainer() {
- gfx::Size ps = GetPreferredSize();
- int w = ScaleValue(ps.width());
- int h = ScaleValue(ps.height());
-#if defined(OS_WIN)
- SetWindowPos(container_->GetNativeView(), HWND_TOPMOST, 0, 0, w, h,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
-#else
- gfx::Rect bounds;
- container_->GetBounds(&bounds, true);
- container_->SetBounds(gfx::Rect(bounds.x(), bounds.y(), w, h));
-#endif
-}
-
-int DraggedTabView::ScaleValue(int value) {
- return static_cast<int>(value * kScalingFactor);
-}
diff --git a/chrome/browser/views/tabs/dragged_tab_view.h b/chrome/browser/views/tabs/dragged_tab_view.h
index 0432d46..2848baf 100644
--- a/chrome/browser/views/tabs/dragged_tab_view.h
+++ b/chrome/browser/views/tabs/dragged_tab_view.h
@@ -6,98 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_VIEW_H_
#pragma once
-#include "build/build_config.h"
-#include "gfx/point.h"
-#include "gfx/size.h"
-#include "views/view.h"
-
-namespace views {
-#if defined(OS_WIN)
-class WidgetWin;
-#elif defined(OS_LINUX)
-class WidgetGtk;
-#endif
-}
-namespace gfx {
-class Point;
-}
-class NativeViewPhotobooth;
-class Tab;
-class TabRenderer;
-
-class DraggedTabView : public views::View {
- public:
- // Creates a new DraggedTabView using |renderer| as the View. DraggedTabView
- // takes ownership of |renderer|.
- DraggedTabView(views::View* renderer,
- const gfx::Point& mouse_tab_offset,
- const gfx::Size& contents_size,
- const gfx::Size& min_size);
- virtual ~DraggedTabView();
-
- // Moves the DraggedTabView to the appropriate location given the mouse
- // pointer at |screen_point|.
- void MoveTo(const gfx::Point& screen_point);
-
- // Sets the offset of the mouse from the upper left corner of the tab.
- void set_mouse_tab_offset(const gfx::Point& offset) {
- mouse_tab_offset_ = offset;
- }
-
- // Sets the width of the dragged tab and updates the dragged image.
- void SetTabWidthAndUpdate(int width, NativeViewPhotobooth* photobooth);
-
- // Notifies the DraggedTabView that it should update itself.
- void Update();
-
- private:
- // Overridden from views::View:
- virtual void Paint(gfx::Canvas* canvas);
- virtual void Layout();
- virtual gfx::Size GetPreferredSize();
-
- // Paint the view, when it's not attached to any TabStrip.
- void PaintDetachedView(gfx::Canvas* canvas);
-
- // Paint the view, when "Show window contents while dragging" is disabled.
- void PaintFocusRect(gfx::Canvas* canvas);
-
- // Resizes the container to fit the content for the current attachment mode.
- void ResizeContainer();
-
- // Utility for scaling a size by the current scaling factor.
- int ScaleValue(int value);
-
- // The window that contains the DraggedTabView.
-#if defined(OS_WIN)
- scoped_ptr<views::WidgetWin> container_;
-#elif defined(OS_LINUX)
- scoped_ptr<views::WidgetGtk> container_;
-#endif
-
- // The renderer that paints the Tab shape.
- scoped_ptr<views::View> renderer_;
-
- // True if "Show window contents while dragging" is enabled.
- bool show_contents_on_drag_;
-
- // The unscaled offset of the mouse from the top left of the dragged Tab.
- // This is used to maintain an appropriate offset for the mouse pointer when
- // dragging scaled and unscaled representations, and also to calculate the
- // position of detached windows.
- gfx::Point mouse_tab_offset_;
-
- // The size of the tab renderer.
- gfx::Size tab_size_;
-
- // A handle to the DIB containing the current screenshot of the TabContents
- // we are dragging.
- NativeViewPhotobooth* photobooth_;
-
- // Size of the TabContents being dragged.
- gfx::Size contents_size_;
-
- DISALLOW_COPY_AND_ASSIGN(DraggedTabView);
-};
+#include "chrome/browser/ui/views/tabs/dragged_tab_view.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_DRAGGED_TAB_VIEW_H_
+
diff --git a/chrome/browser/views/tabs/native_view_photobooth.h b/chrome/browser/views/tabs/native_view_photobooth.h
index 0eba321..1a954e5 100644
--- a/chrome/browser/views/tabs/native_view_photobooth.h
+++ b/chrome/browser/views/tabs/native_view_photobooth.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,39 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_H_
#pragma once
-#include "gfx/native_widget_types.h"
-
-namespace gfx {
-class Canvas;
-class Rect;
-}
-///////////////////////////////////////////////////////////////////////////////
-// NativeViewPhotobooth
-//
-// An object that a NativeView "steps into" to have its picture taken. This is
-// used to generate a full size screen shot of the contents of a NativeView
-// including any child windows.
-//
-// Implementation note: This causes the NativeView to be re-parented to a
-// mostly off-screen layered window.
-//
-class NativeViewPhotobooth {
- public:
- // Creates the photo booth. Constructs a nearly off-screen window, parents
- // the view, then shows it. The caller is responsible for destroying this
- // photo-booth, since the photo-booth will detach it before it is destroyed.
- static NativeViewPhotobooth* Create(gfx::NativeView initial_view);
-
- // Destroys the photo booth window.
- virtual ~NativeViewPhotobooth() {}
-
- // Replaces the view in the photo booth with the specified one.
- virtual void Replace(gfx::NativeView new_view) = 0;
-
- // Paints the current display image of the window into |canvas|, clipped to
- // |target_bounds|.
- virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas,
- const gfx::Rect& target_bounds) = 0;
-};
+#include "chrome/browser/ui/views/tabs/native_view_photobooth.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_H_
+
diff --git a/chrome/browser/views/tabs/native_view_photobooth_gtk.cc b/chrome/browser/views/tabs/native_view_photobooth_gtk.cc
deleted file mode 100644
index a307112..0000000
--- a/chrome/browser/views/tabs/native_view_photobooth_gtk.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2009 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/native_view_photobooth_gtk.h"
-
-#include "base/logging.h"
-#include "gfx/canvas.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// NativeViewPhotoboothGtk, public:
-
-// static
-NativeViewPhotobooth* NativeViewPhotobooth::Create(
- gfx::NativeView initial_view) {
- return new NativeViewPhotoboothGtk(initial_view);
-}
-
-NativeViewPhotoboothGtk::NativeViewPhotoboothGtk(
- gfx::NativeView initial_view) {
-}
-
-NativeViewPhotoboothGtk::~NativeViewPhotoboothGtk() {
-}
-
-void NativeViewPhotoboothGtk::Replace(gfx::NativeView new_view) {
- NOTIMPLEMENTED();
-}
-
-void NativeViewPhotoboothGtk::PaintScreenshotIntoCanvas(
- gfx::Canvas* canvas,
- const gfx::Rect& target_bounds) {
- NOTIMPLEMENTED();
-}
diff --git a/chrome/browser/views/tabs/native_view_photobooth_gtk.h b/chrome/browser/views/tabs/native_view_photobooth_gtk.h
index 8bc74063..22c3901 100644
--- a/chrome/browser/views/tabs/native_view_photobooth_gtk.h
+++ b/chrome/browser/views/tabs/native_view_photobooth_gtk.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,25 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_GTK_H_
#pragma once
-#include "chrome/browser/views/tabs/native_view_photobooth.h"
-
-class NativeViewPhotoboothGtk : public NativeViewPhotobooth {
- public:
- explicit NativeViewPhotoboothGtk(gfx::NativeView new_view);
-
- // Destroys the photo booth window.
- virtual ~NativeViewPhotoboothGtk();
-
- // Replaces the view in the photo booth with the specified one.
- virtual void Replace(gfx::NativeView new_view);
-
- // Paints the current display image of the window into |canvas|, clipped to
- // |target_bounds|.
- virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas,
- const gfx::Rect& target_bounds);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NativeViewPhotoboothGtk);
-};
+#include "chrome/browser/ui/views/tabs/native_view_photobooth_gtk.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_GTK_H_
+
diff --git a/chrome/browser/views/tabs/native_view_photobooth_win.cc b/chrome/browser/views/tabs/native_view_photobooth_win.cc
deleted file mode 100644
index d749ea0..0000000
--- a/chrome/browser/views/tabs/native_view_photobooth_win.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2006-2008 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/native_view_photobooth_win.h"
-
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/point.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "views/widget/widget_win.h"
-
-namespace {
-
-static BOOL CALLBACK MonitorEnumProc(HMONITOR monitor, HDC monitor_dc,
- RECT* monitor_rect, LPARAM data) {
- gfx::Point* point = reinterpret_cast<gfx::Point*>(data);
- if (monitor_rect->right > point->x() && monitor_rect->bottom > point->y()) {
- point->set_x(monitor_rect->right);
- point->set_y(monitor_rect->bottom);
- }
- return TRUE;
-}
-
-gfx::Point GetCaptureWindowPosition() {
- // Since the capture window must be visible to be painted, it must be opened
- // off screen to avoid flashing. But if it is opened completely off-screen
- // (e.g. at 0xFFFFx0xFFFF) then on Windows Vista it will not paint even if it
- // _is_ visible. So we need to find the right/bottommost monitor, and
- // position it so that 1x1 pixel is on-screen on that monitor which is enough
- // to convince Vista to paint it. Don't ask why this is so - this appears to
- // be a regression over XP.
- gfx::Point point(0, 0);
- EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc,
- reinterpret_cast<LPARAM>(&point));
- return gfx::Point(point.x() - 1, point.y() - 1);
-}
-
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// NativeViewPhotoboothWin, public:
-
-// static
-NativeViewPhotobooth* NativeViewPhotobooth::Create(
- gfx::NativeView initial_view) {
- return new NativeViewPhotoboothWin(initial_view);
-}
-
-NativeViewPhotoboothWin::NativeViewPhotoboothWin(HWND initial_hwnd)
- : capture_window_(NULL),
- current_hwnd_(initial_hwnd) {
- DCHECK(IsWindow(current_hwnd_));
- CreateCaptureWindow(initial_hwnd);
-}
-
-NativeViewPhotoboothWin::~NativeViewPhotoboothWin() {
- // Detach the attached HWND. The creator of the photo-booth is responsible
- // for destroying it.
- Replace(NULL);
- capture_window_->Close();
-}
-
-void NativeViewPhotoboothWin::Replace(HWND new_hwnd) {
- if (IsWindow(current_hwnd_) &&
- GetParent(current_hwnd_) == capture_window_->GetNativeView()) {
- // We need to hide the window too, so it doesn't show up in the TaskBar or
- // be parented to the desktop.
- ShowWindow(current_hwnd_, SW_HIDE);
- SetParent(current_hwnd_, NULL);
- }
- current_hwnd_ = new_hwnd;
-
- if (IsWindow(new_hwnd)) {
- // Insert the TabContents into the capture window.
- SetParent(current_hwnd_, capture_window_->GetNativeView());
-
- // Show the window (it may not be visible). This is the only safe way of
- // doing this. ShowWindow does not work.
- SetWindowPos(current_hwnd_, NULL, 0, 0, 0, 0,
- SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOCOPYBITS |
- SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOZORDER |
- SWP_SHOWWINDOW | SWP_NOSIZE);
- }
-}
-
-void NativeViewPhotoboothWin::PaintScreenshotIntoCanvas(
- gfx::Canvas* canvas,
- const gfx::Rect& target_bounds) {
- // Our contained window may have been re-parented. Make sure it belongs to
- // us until someone calls Replace(NULL).
- if (IsWindow(current_hwnd_) &&
- GetParent(current_hwnd_) != capture_window_->GetNativeView()) {
- Replace(current_hwnd_);
- }
-
- // We compel the contained HWND to paint now, synchronously. We do this to
- // populate the device context with valid and current data.
- RedrawWindow(current_hwnd_, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
-
- // Transfer the contents of the layered capture window to the screen-shot
- // canvas' DIB.
- HDC target_dc = canvas->BeginPlatformPaint();
- HDC source_dc = GetDC(current_hwnd_);
- RECT window_rect = {0};
- GetWindowRect(current_hwnd_, &window_rect);
- BitBlt(target_dc, target_bounds.x(), target_bounds.y(),
- target_bounds.width(), target_bounds.height(), source_dc, 0, 0,
- SRCCOPY);
- // Windows screws up the alpha channel on all text it draws, and so we need
- // to call makeOpaque _after_ the blit to correct for this.
- canvas->AsCanvasSkia()->getTopPlatformDevice().makeOpaque(
- target_bounds.x(), target_bounds.y(), target_bounds.width(),
- target_bounds.height());
- ReleaseDC(current_hwnd_, source_dc);
- canvas->EndPlatformPaint();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// NativeViewPhotoboothWin, private:
-
-void NativeViewPhotoboothWin::CreateCaptureWindow(HWND initial_hwnd) {
- // Snapshotting a HWND is tricky - if the HWND is clipped (e.g. positioned
- // partially off-screen) then just blitting from the HWND' DC to the capture
- // bitmap would be incorrect, since the capture bitmap would show only the
- // visible area of the HWND.
- //
- // The approach turns out to be to create a second layered window in
- // hyperspace the to act as a "photo booth." The window is created with the
- // size of the unclipped HWND, and we attach the HWND as a child, refresh the
- // HWND' by calling |Paint| on it, and then blitting from the HWND's DC to
- // the capture bitmap. This results in the entire unclipped HWND display
- // bitmap being captured.
- //
- // The capture window must be layered so that Windows generates a backing
- // store for it, so that blitting from a child window's DC produces data. If
- // the window is not layered, because it is off-screen Windows does not
- // retain its contents and blitting results in blank data. The capture window
- // is a "basic" (1 level of alpha) layered window because that is the mode
- // that supports having child windows (variable alpha layered windows do not
- // support child HWNDs).
- //
- // This function sets up the off-screen capture window, and attaches the
- // associated HWND to it. Note that the details are important here, see below
- // for further comments.
- //
- CRect contents_rect;
- GetClientRect(initial_hwnd, &contents_rect);
- gfx::Point window_position = GetCaptureWindowPosition();
- gfx::Rect capture_bounds(window_position.x(), window_position.y(),
- contents_rect.Width(), contents_rect.Height());
- capture_window_ = new views::WidgetWin;
- capture_window_->set_window_style(WS_POPUP);
- // WS_EX_TOOLWINDOW ensures the capture window doesn't produce a Taskbar
- // button.
- capture_window_->set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW);
- capture_window_->Init(NULL, capture_bounds);
- // If the capture window isn't visible, blitting from the TabContents'
- // HWND's DC to the capture bitmap produces blankness.
- capture_window_->Show();
- SetLayeredWindowAttributes(
- capture_window_->GetNativeView(), RGB(0xFF, 0xFF, 0xFF), 0xFF, LWA_ALPHA);
-
- Replace(initial_hwnd);
-}
diff --git a/chrome/browser/views/tabs/native_view_photobooth_win.h b/chrome/browser/views/tabs/native_view_photobooth_win.h
index 4ed4016..2cd2a4b 100644
--- a/chrome/browser/views/tabs/native_view_photobooth_win.h
+++ b/chrome/browser/views/tabs/native_view_photobooth_win.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -6,53 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_WIN_H_
#pragma once
-#include "chrome/browser/views/tabs/native_view_photobooth.h"
-
-namespace views {
-class WidgetWin;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// HWNDPhotobooth
-//
-// An object that a HWND "steps into" to have its picture taken. This is used
-// to generate a full size screen shot of the contents of a HWND including
-// any child windows.
-//
-// Implementation note: This causes the HWND to be re-parented to a mostly
-// off-screen layered window.
-//
-class NativeViewPhotoboothWin : public NativeViewPhotobooth {
- public:
- // Creates the photo booth. Constructs a nearly off-screen window, parents
- // the HWND, then shows it. The caller is responsible for destroying this
- // window, since the photo-booth will detach it before it is destroyed.
- // |canvas| is a canvas to paint the contents into, and dest_bounds is the
- // target area in |canvas| to which painted contents will be clipped.
- explicit NativeViewPhotoboothWin(gfx::NativeView initial_view);
-
- // Destroys the photo booth window.
- virtual ~NativeViewPhotoboothWin();
-
- // Replaces the view in the photo booth with the specified one.
- virtual void Replace(gfx::NativeView new_view);
-
- // Paints the current display image of the window into |canvas|, clipped to
- // |target_bounds|.
- virtual void PaintScreenshotIntoCanvas(gfx::Canvas* canvas,
- const gfx::Rect& target_bounds);
-
- private:
- // Creates a mostly off-screen window to contain the HWND to be captured.
- void CreateCaptureWindow(HWND initial_hwnd);
-
- // The nearly off-screen photo-booth layered window used to hold the HWND.
- views::WidgetWin* capture_window_;
-
- // The current HWND being captured.
- HWND current_hwnd_;
-
- DISALLOW_COPY_AND_ASSIGN(NativeViewPhotoboothWin);
-};
+#include "chrome/browser/ui/views/tabs/native_view_photobooth_win.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_NATIVE_VIEW_PHOTOBOOTH_WIN_H_
+
diff --git a/chrome/browser/views/tabs/side_tab.cc b/chrome/browser/views/tabs/side_tab.cc
deleted file mode 100644
index b42bca0..0000000
--- a/chrome/browser/views/tabs/side_tab.cc
+++ /dev/null
@@ -1,114 +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/side_tab.h"
-
-#include "app/resource_bundle.h"
-#include "base/utf_string_conversions.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/favicon_size.h"
-#include "gfx/path.h"
-#include "gfx/skia_util.h"
-#include "grit/app_resources.h"
-#include "grit/theme_resources.h"
-#include "views/controls/button/image_button.h"
-
-namespace {
-const int kVerticalTabHeight = 27;
-const int kTitleCloseSpacing = 4;
-const SkScalar kRoundRectRadius = 4;
-const SkColor kTabBackgroundColor = SK_ColorWHITE;
-const SkColor kTextColor = SK_ColorBLACK;
-
-// Padding between the edge and the icon.
-const int kIconLeftPadding = 5;
-
-// Location the title starts at.
-const int kTitleX = kIconLeftPadding + kFavIconSize + 5;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// SideTab, public:
-
-SideTab::SideTab(TabController* controller)
- : BaseTab(controller) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- close_button()->SetBackground(kTextColor,
- rb.GetBitmapNamed(IDR_TAB_CLOSE),
- rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK));
-}
-
-SideTab::~SideTab() {
-}
-
-// static
-int SideTab::GetPreferredHeight() {
- return 27;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// SideTab, views::View overrides:
-
-void SideTab::Layout() {
- if (ShouldShowIcon()) {
- int icon_x = kIconLeftPadding;
- int icon_y = (height() - kFavIconSize) / 2;
- int icon_size =
- !data().favicon.empty() ? data().favicon.width() : kFavIconSize;
- if (icon_size != kFavIconSize) {
- icon_x -= (icon_size - kFavIconSize) / 2;
- icon_y -= (icon_size - kFavIconSize) / 2;
- }
- icon_bounds_.SetRect(icon_x, icon_y, icon_size, icon_size);
- } else {
- icon_bounds_ = gfx::Rect();
- }
-
- gfx::Size ps = close_button()->GetPreferredSize();
- int close_y = (height() - ps.height()) / 2;
- close_button()->SetBounds(
- std::max(0, width() - ps.width() -
- (GetPreferredHeight() - ps.height()) / 2),
- close_y,
- ps.width(),
- ps.height());
-
- int title_y = (height() - font_height()) / 2;
- title_bounds_.SetRect(
- kTitleX,
- title_y,
- std::max(0, close_button()->x() - kTitleCloseSpacing - kTitleX),
- font_height());
-}
-
-void SideTab::Paint(gfx::Canvas* canvas) {
- if (ShouldPaintHighlight()) {
- SkPaint paint;
- paint.setColor(kTabBackgroundColor);
- paint.setAntiAlias(true);
- SkRect border_rect = { SkIntToScalar(0), SkIntToScalar(0),
- SkIntToScalar(width()), SkIntToScalar(height()) };
- canvas->AsCanvasSkia()->drawRoundRect(border_rect,
- SkIntToScalar(kRoundRectRadius),
- SkIntToScalar(kRoundRectRadius),
- paint);
- }
-
- if (ShouldShowIcon())
- PaintIcon(canvas, icon_bounds_.x(), icon_bounds_.y());
-
- PaintTitle(canvas, kTextColor);
-}
-
-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 6cff764..5d27ce3 100644
--- a/chrome/browser/views/tabs/side_tab.h
+++ b/chrome/browser/views/tabs/side_tab.h
@@ -6,39 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_H_
#pragma once
-#include "chrome/browser/views/tabs/base_tab.h"
-#include "gfx/font.h"
-
-class SideTab;
-class TabStripController;
-
-class SideTab : public BaseTab {
- public:
- explicit SideTab(TabController* controller);
- virtual ~SideTab();
-
- // Returns the preferred height of side tabs.
- static int GetPreferredHeight();
-
- // views::View Overrides:
- virtual void Layout();
- virtual void Paint(gfx::Canvas* canvas);
- virtual gfx::Size GetPreferredSize();
-
- 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;
-
- gfx::Rect icon_bounds_;
- gfx::Rect title_bounds_;
-
- DISALLOW_COPY_AND_ASSIGN(SideTab);
-};
+#include "chrome/browser/ui/views/tabs/side_tab.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_H_
+
diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc
deleted file mode 100644
index 84e8082..0000000
--- a/chrome/browser/views/tabs/side_tab_strip.cc
+++ /dev/null
@@ -1,260 +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/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;
-
-////////////////////////////////////////////////////////////////////////////////
-// SideTabStrip, public:
-
-SideTabStrip::SideTabStrip(TabStripController* controller)
- : 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() {
- DestroyDragController();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// SideTabStrip, BaseTabStrip implementation:
-
-int SideTabStrip::GetPreferredHeight() {
- return 0;
-}
-
-void SideTabStrip::SetBackgroundOffset(const gfx::Point& offset) {
-}
-
-bool SideTabStrip::IsPositionInWindowCaption(const gfx::Point& point) {
- return GetViewForPoint(point) == this;
-}
-
-void SideTabStrip::SetDraggedTabBounds(int tab_index,
- const gfx::Rect& tab_bounds) {
-}
-
-TabStrip* SideTabStrip::AsTabStrip() {
- return NULL;
-}
-
-void SideTabStrip::StartHighlight(int model_index) {
-}
-
-void SideTabStrip::StopAllHighlighting() {
-}
-
-BaseTab* SideTabStrip::CreateTabForDragging() {
- SideTab* tab = new SideTab(NULL);
- // Make sure the dragged tab shares our theme provider. We need to explicitly
- // do this as during dragging there isn't a theme provider.
- tab->set_theme_provider(GetThemeProvider());
- return tab;
-}
-
-void SideTabStrip::RemoveTabAt(int model_index) {
- StartRemoveTabAnimation(model_index);
-}
-
-void SideTabStrip::SelectTabAt(int old_model_index, int new_model_index) {
- GetBaseTabAtModelIndex(new_model_index)->SchedulePaint();
-}
-
-void SideTabStrip::TabTitleChangedNotLoading(int model_index) {
-}
-
-gfx::Size SideTabStrip::GetPreferredSize() {
- return gfx::Size(kTabStripWidth, 0);
-}
-
-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())
- dragging_tab = tab;
- else
- tab->ProcessPaint(canvas);
- }
-
- if (dragging_tab)
- dragging_tab->ProcessPaint(canvas);
-}
-
-BaseTab* SideTabStrip::CreateTab() {
- return new SideTab(this);
-}
-
-void SideTabStrip::GenerateIdealBounds() {
- gfx::Rect layout_rect = GetLocalBounds(false);
- 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) {
- PrepareForAnimation();
-
- GenerateIdealBounds();
-
- int tab_data_index = ModelIndexToTabIndex(model_index);
- BaseTab* tab = base_tab_at_tab_index(tab_data_index);
- if (model_index == 0) {
- tab->SetBounds(ideal_bounds(tab_data_index).x(), 0,
- ideal_bounds(tab_data_index).width(), 0);
- } else {
- BaseTab* last_tab = base_tab_at_tab_index(tab_data_index - 1);
- tab->SetBounds(last_tab->x(), last_tab->bounds().bottom(),
- ideal_bounds(tab_data_index).width(), 0);
- }
-
- AnimateToIdealBounds();
-}
-
-void SideTabStrip::StartMoveTabAnimation() {
- PrepareForAnimation();
-
- GenerateIdealBounds();
- AnimateToIdealBounds();
-}
-
-void SideTabStrip::StopAnimating(bool layout) {
- if (!IsAnimating())
- return;
-
- bounds_animator().Cancel();
-
- if (layout)
- DoLayout();
-}
-
-void SideTabStrip::AnimateToIdealBounds() {
- for (int i = 0; i < tab_count(); ++i) {
- BaseTab* tab = base_tab_at_tab_index(i);
- 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::DoLayout() {
- BaseTabStrip::DoLayout();
-
- 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 c847077..cbecf20 100644
--- a/chrome/browser/views/tabs/side_tab_strip.h
+++ b/chrome/browser/views/tabs/side_tab_strip.h
@@ -6,62 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_H_
#pragma once
-#include "chrome/browser/views/tabs/base_tab_strip.h"
-
-struct TabRendererData;
-
-class SideTabStrip : public BaseTabStrip {
- public:
- // The tabs are inset by this much along all axis.
- static const int kTabStripInset;
-
- explicit SideTabStrip(TabStripController* controller);
- virtual ~SideTabStrip();
-
- // BaseTabStrip implementation:
- virtual int GetPreferredHeight();
- virtual void SetBackgroundOffset(const gfx::Point& offset);
- virtual bool IsPositionInWindowCaption(const gfx::Point& point);
- virtual void SetDraggedTabBounds(int tab_index,
- const gfx::Rect& tab_bounds);
- virtual TabStrip* AsTabStrip();
-
- virtual void StartHighlight(int model_index);
- virtual void StopAllHighlighting();
- virtual BaseTab* CreateTabForDragging();
- virtual void RemoveTabAt(int model_index);
- virtual void SelectTabAt(int old_model_index, int new_model_index);
- virtual void TabTitleChangedNotLoading(int model_index);
-
- // views::View overrides:
- virtual gfx::Size GetPreferredSize();
- virtual void PaintChildren(gfx::Canvas* canvas);
-
- protected:
- // BaseTabStrip overrides:
- virtual BaseTab* CreateTab();
- virtual void GenerateIdealBounds();
- virtual void StartInsertTabAnimation(int model_index, bool foreground);
- virtual void StartMoveTabAnimation();
- virtual void StopAnimating(bool layout);
- virtual void AnimateToIdealBounds();
- virtual void DoLayout();
-
- 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);
-};
+#include "chrome/browser/ui/views/tabs/side_tab_strip.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_H_
+
diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc
deleted file mode 100644
index dda22fb..0000000
--- a/chrome/browser/views/tabs/tab.cc
+++ /dev/null
@@ -1,610 +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/tab.h"
-
-#include <limits>
-
-#include "app/multi_animation.h"
-#include "app/resource_bundle.h"
-#include "app/slide_animation.h"
-#include "app/throb_animation.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/defaults.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/favicon_size.h"
-#include "gfx/font.h"
-#include "gfx/path.h"
-#include "gfx/skbitmap_operations.h"
-#include "grit/app_resources.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
-#include "views/controls/button/image_button.h"
-#include "views/widget/tooltip_manager.h"
-#include "views/widget/widget.h"
-#include "views/window/non_client_view.h"
-#include "views/window/window.h"
-
-static const int kLeftPadding = 16;
-static const int kTopPadding = 6;
-static const int kRightPadding = 15;
-static const int kBottomPadding = 5;
-static const int kDropShadowHeight = 2;
-static const int kToolbarOverlap = 1;
-static const int kFavIconTitleSpacing = 4;
-static const int kTitleCloseButtonSpacing = 5;
-static const int kStandardTitleWidth = 175;
-static const int kCloseButtonVertFuzz = 0;
-static const int kCloseButtonHorzFuzz = 5;
-
-// Vertical adjustment to the favicon when the tab has a large icon.
-static const int kAppTapFaviconVerticalAdjustment = 2;
-
-// When a non-mini-tab becomes a mini-tab the width of the tab animates. If
-// the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab
-// is rendered as a normal tab. This is done to avoid having the title
-// immediately disappear when transitioning a tab from normal to mini-tab.
-static const int kMiniTabRendererAsNormalTabWidth =
- browser_defaults::kMiniTabWidth + 30;
-
-// How opaque to make the hover state (out of 1).
-static const double kHoverOpacity = 0.33;
-
-Tab::TabImage Tab::tab_alpha = {0};
-Tab::TabImage Tab::tab_active = {0};
-Tab::TabImage Tab::tab_inactive = {0};
-
-// Durations for the various parts of the mini tab title animation.
-static const int kMiniTitleChangeAnimationDuration1MS = 1600;
-static const int kMiniTitleChangeAnimationStart1MS = 0;
-static const int kMiniTitleChangeAnimationEnd1MS = 1900;
-static const int kMiniTitleChangeAnimationDuration2MS = 0;
-static const int kMiniTitleChangeAnimationDuration3MS = 550;
-static const int kMiniTitleChangeAnimationStart3MS = 150;
-static const int kMiniTitleChangeAnimationEnd3MS = 800;
-
-// Offset from the right edge for the start of the mini title change animation.
-static const int kMiniTitleChangeInitialXOffset = 6;
-
-// Radius of the radial gradient used for mini title change animation.
-static const int kMiniTitleChangeGradientRadius = 20;
-
-// Colors of the gradient used during the mini title change animation.
-static const SkColor kMiniTitleChangeGradientColor1 = SK_ColorWHITE;
-static const SkColor kMiniTitleChangeGradientColor2 =
- SkColorSetARGB(0, 255, 255, 255);
-
-// Hit mask constants.
-static const SkScalar kTabCapWidth = 15;
-static const SkScalar kTabTopCurveWidth = 4;
-static const SkScalar kTabBottomCurveWidth = 3;
-
-namespace {
-
-void InitTabResources() {
- static bool initialized = false;
- if (initialized)
- return;
-
- initialized = true;
- Tab::LoadTabImages();
-}
-
-} // namespace
-
-// static
-const char Tab::kViewClassName[] = "browser/tabs/Tab";
-
-////////////////////////////////////////////////////////////////////////////////
-// Tab, public:
-
-Tab::Tab(TabController* controller)
- : BaseTab(controller),
- showing_icon_(false),
- showing_close_button_(false),
- close_button_color_(NULL) {
- InitTabResources();
-}
-
-Tab::~Tab() {
-}
-
-void Tab::StartMiniTabTitleAnimation() {
- if (!mini_title_animation_.get()) {
- MultiAnimation::Parts parts;
- parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration1MS,
- Tween::EASE_OUT));
- parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration2MS,
- Tween::ZERO));
- parts.push_back(MultiAnimation::Part(kMiniTitleChangeAnimationDuration3MS,
- Tween::EASE_IN));
- parts[0].start_time_ms = kMiniTitleChangeAnimationStart1MS;
- parts[0].end_time_ms = kMiniTitleChangeAnimationEnd1MS;
- parts[2].start_time_ms = kMiniTitleChangeAnimationStart3MS;
- parts[2].end_time_ms = kMiniTitleChangeAnimationEnd3MS;
- mini_title_animation_.reset(new MultiAnimation(parts));
- mini_title_animation_->SetContainer(animation_container());
- mini_title_animation_->set_delegate(this);
- }
- mini_title_animation_->Start();
-}
-
-void Tab::StopMiniTabTitleAnimation() {
- if (mini_title_animation_.get())
- mini_title_animation_->Stop();
-}
-
-void Tab::PaintIcon(gfx::Canvas* canvas) {
- BaseTab::PaintIcon(canvas, favicon_bounds_.x(), favicon_bounds_.y());
-}
-
-// static
-gfx::Size Tab::GetMinimumUnselectedSize() {
- InitTabResources();
-
- gfx::Size minimum_size;
- minimum_size.set_width(kLeftPadding + kRightPadding);
- // Since we use bitmap images, the real minimum height of the image is
- // defined most accurately by the height of the end cap images.
- minimum_size.set_height(tab_active.image_l->height());
- return minimum_size;
-}
-
-// static
-gfx::Size Tab::GetMinimumSelectedSize() {
- gfx::Size minimum_size = GetMinimumUnselectedSize();
- minimum_size.set_width(kLeftPadding + kFavIconSize + kRightPadding);
- return minimum_size;
-}
-
-// static
-gfx::Size Tab::GetStandardSize() {
- gfx::Size standard_size = GetMinimumUnselectedSize();
- standard_size.set_width(
- standard_size.width() + kFavIconTitleSpacing + kStandardTitleWidth);
- return standard_size;
-}
-
-// static
-int Tab::GetMiniWidth() {
- return browser_defaults::kMiniTabWidth;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tab, protected:
-
-void Tab::DataChanged(const TabRendererData& old) {
- if (data().blocked == old.blocked)
- return;
-
- if (data().blocked)
- StartPulse();
- else
- StopPulse();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tab, views::View overrides:
-
-void Tab::Paint(gfx::Canvas* canvas) {
- // Don't paint if we're narrower than we can render correctly. (This should
- // only happen during animations).
- if (width() < GetMinimumUnselectedSize().width() && !data().mini)
- return;
-
- // See if the model changes whether the icons should be painted.
- const bool show_icon = ShouldShowIcon();
- const bool show_close_button = ShouldShowCloseBox();
- if (show_icon != showing_icon_ || show_close_button != showing_close_button_)
- Layout();
-
- PaintTabBackground(canvas);
-
- SkColor title_color = GetThemeProvider()->
- GetColor(IsSelected() ?
- BrowserThemeProvider::COLOR_TAB_TEXT :
- BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT);
-
- if (!data().mini || width() > kMiniTabRendererAsNormalTabWidth)
- PaintTitle(canvas, title_color);
-
- if (show_icon)
- PaintIcon(canvas);
-
- // If the close button color has changed, generate a new one.
- if (!close_button_color_ || title_color != close_button_color_) {
- close_button_color_ = title_color;
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- close_button()->SetBackground(close_button_color_,
- rb.GetBitmapNamed(IDR_TAB_CLOSE),
- rb.GetBitmapNamed(IDR_TAB_CLOSE_MASK));
- }
-}
-
-void Tab::Layout() {
- gfx::Rect lb = GetLocalBounds(false);
- if (lb.IsEmpty())
- return;
- lb.Inset(kLeftPadding, kTopPadding, kRightPadding, kBottomPadding);
-
- // The height of the content of the Tab is the largest of the favicon,
- // the title text and the close button graphic.
- int content_height = std::max(kFavIconSize, font_height());
- gfx::Size close_button_size(close_button()->GetPreferredSize());
- content_height = std::max(content_height, close_button_size.height());
-
- // Size the Favicon.
- showing_icon_ = ShouldShowIcon();
- if (showing_icon_) {
- // Use the size of the favicon as apps use a bigger favicon size.
- int favicon_size =
- !data().favicon.empty() ? data().favicon.width() : kFavIconSize;
- int favicon_top = kTopPadding + content_height / 2 - favicon_size / 2;
- int favicon_left = lb.x();
- if (favicon_size != kFavIconSize) {
- favicon_left -= (favicon_size - kFavIconSize) / 2;
- favicon_top -= kAppTapFaviconVerticalAdjustment;
- }
- favicon_bounds_.SetRect(favicon_left, favicon_top,
- favicon_size, favicon_size);
- if (data().mini && width() < kMiniTabRendererAsNormalTabWidth) {
- // Adjust the location of the favicon when transitioning from a normal
- // tab to a mini-tab.
- int mini_delta = kMiniTabRendererAsNormalTabWidth - GetMiniWidth();
- int ideal_delta = width() - GetMiniWidth();
- if (ideal_delta < mini_delta) {
- int ideal_x = (GetMiniWidth() - favicon_size) / 2;
- int x = favicon_bounds_.x() + static_cast<int>(
- (1 - static_cast<float>(ideal_delta) /
- static_cast<float>(mini_delta)) *
- (ideal_x - favicon_bounds_.x()));
- favicon_bounds_.set_x(x);
- }
- }
- } else {
- favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0);
- }
-
- // Size the Close button.
- showing_close_button_ = ShouldShowCloseBox();
- if (showing_close_button_) {
- int close_button_top = kTopPadding + kCloseButtonVertFuzz +
- (content_height - close_button_size.height()) / 2;
- // If the ratio of the close button size to tab width exceeds the maximum.
- close_button()->SetBounds(lb.width() + kCloseButtonHorzFuzz,
- close_button_top, close_button_size.width(),
- close_button_size.height());
- close_button()->SetVisible(true);
- } else {
- close_button()->SetBounds(0, 0, 0, 0);
- close_button()->SetVisible(false);
- }
-
- int title_left = favicon_bounds_.right() + kFavIconTitleSpacing;
- int title_top = kTopPadding + (content_height - font_height()) / 2;
- // Size the Title text to fill the remaining space.
- if (!data().mini || width() >= kMiniTabRendererAsNormalTabWidth) {
- // If the user has big fonts, the title will appear rendered too far down
- // on the y-axis if we use the regular top padding, so we need to adjust it
- // so that the text appears centered.
- gfx::Size minimum_size = GetMinimumUnselectedSize();
- int text_height = title_top + font_height() + kBottomPadding;
- if (text_height > minimum_size.height())
- title_top -= (text_height - minimum_size.height()) / 2;
-
- int title_width;
- if (close_button()->IsVisible()) {
- title_width = std::max(close_button()->x() -
- kTitleCloseButtonSpacing - title_left, 0);
- } else {
- title_width = std::max(lb.width() - title_left, 0);
- }
- title_bounds_.SetRect(title_left, title_top, title_width, font_height());
- } else {
- title_bounds_.SetRect(title_left, title_top, 0, 0);
- }
-
- // Certain UI elements within the Tab (the favicon, etc.) are not represented
- // as child Views (which is the preferred method). Instead, these UI elements
- // are drawn directly on the canvas from within Tab::Paint(). The Tab's child
- // Views (for example, the Tab's close button which is a views::Button
- // instance) are automatically mirrored by the mirroring infrastructure in
- // views. The elements Tab draws directly on the canvas need to be manually
- // mirrored if the View's layout is right-to-left.
- title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_));
-}
-
-void Tab::OnThemeChanged() {
- Tab::LoadTabImages();
-}
-
-bool Tab::HasHitTestMask() const {
- return true;
-}
-
-void Tab::GetHitTestMask(gfx::Path* path) const {
- DCHECK(path);
-
- SkScalar h = SkIntToScalar(height());
- SkScalar w = SkIntToScalar(width());
-
- path->moveTo(0, h);
-
- // Left end cap.
- path->lineTo(kTabBottomCurveWidth, h - kTabBottomCurveWidth);
- path->lineTo(kTabCapWidth - kTabTopCurveWidth, kTabTopCurveWidth);
- path->lineTo(kTabCapWidth, 0);
-
- // Connect to the right cap.
- path->lineTo(w - kTabCapWidth, 0);
-
- // Right end cap.
- path->lineTo(w - kTabCapWidth + kTabTopCurveWidth, kTabTopCurveWidth);
- path->lineTo(w - kTabBottomCurveWidth, h - kTabBottomCurveWidth);
- path->lineTo(w, h);
-
- // Close out the path.
- path->lineTo(0, h);
- path->close();
-}
-
-bool Tab::GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin) {
- origin->set_x(title_bounds().x() + 10);
- origin->set_y(-views::TooltipManager::GetTooltipHeight() - 4);
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tab, private
-
-void Tab::PaintTabBackground(gfx::Canvas* canvas) {
- if (IsSelected()) {
- PaintActiveTabBackground(canvas);
- } else {
- if (mini_title_animation_.get() && mini_title_animation_->is_animating())
- PaintInactiveTabBackgroundWithTitleChange(canvas);
- else
- PaintInactiveTabBackground(canvas);
-
- double throb_value = GetThrobValue();
- if (throb_value > 0) {
- canvas->SaveLayerAlpha(static_cast<int>(throb_value * 0xff),
- gfx::Rect(width(), height()));
- canvas->AsCanvasSkia()->drawARGB(0, 255, 255, 255,
- SkXfermode::kClear_Mode);
- PaintActiveTabBackground(canvas);
- canvas->Restore();
- }
- }
-}
-
-void Tab::PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas) {
- // Render the inactive tab background. We'll use this for clipping.
- gfx::CanvasSkia background_canvas(width(), height(), false);
- PaintInactiveTabBackground(&background_canvas);
-
- SkBitmap background_image = background_canvas.ExtractBitmap();
-
- // Draw a radial gradient to hover_canvas.
- gfx::CanvasSkia hover_canvas(width(), height(), false);
- int radius = kMiniTitleChangeGradientRadius;
- int x0 = width() + radius - kMiniTitleChangeInitialXOffset;
- int x1 = radius;
- int x2 = -radius;
- int x;
- if (mini_title_animation_->current_part_index() == 0) {
- x = mini_title_animation_->CurrentValueBetween(x0, x1);
- } else if (mini_title_animation_->current_part_index() == 1) {
- x = x1;
- } else {
- x = mini_title_animation_->CurrentValueBetween(x1, x2);
- }
- SkPaint paint;
- SkPoint loc = { SkIntToScalar(x), SkIntToScalar(0) };
- SkColor colors[2];
- colors[0] = kMiniTitleChangeGradientColor1;
- colors[1] = kMiniTitleChangeGradientColor2;
- SkShader* shader = SkGradientShader::CreateRadial(
- loc,
- SkIntToScalar(radius),
- colors,
- NULL,
- 2,
- SkShader::kClamp_TileMode);
- paint.setShader(shader);
- shader->unref();
- hover_canvas.DrawRectInt(x - radius, -radius, radius * 2, radius * 2, paint);
-
- // Draw the radial gradient clipped to the background into hover_image.
- SkBitmap hover_image = SkBitmapOperations::CreateMaskedBitmap(
- hover_canvas.ExtractBitmap(), background_image);
-
- // Draw the tab background to the canvas.
- canvas->DrawBitmapInt(background_image, 0, 0);
-
- // And then the gradient on top of that.
- if (mini_title_animation_->current_part_index() == 2) {
- canvas->SaveLayerAlpha(mini_title_animation_->CurrentValueBetween(255, 0));
- canvas->DrawBitmapInt(hover_image, 0, 0);
- canvas->Restore();
- } else {
- canvas->DrawBitmapInt(hover_image, 0, 0);
- }
-}
-
-void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas) {
- bool is_otr = data().off_the_record;
-
- // The tab image needs to be lined up with the background image
- // so that it feels partially transparent. These offsets represent the tab
- // position within the frame background image.
- int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) +
- background_offset_.x();
-
- int tab_id;
- if (GetWidget() &&
- GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) {
- tab_id = IDR_THEME_TAB_BACKGROUND_V;
- } else {
- tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO :
- IDR_THEME_TAB_BACKGROUND;
- }
-
- SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id);
-
- TabImage* tab_image = &tab_active;
- TabImage* tab_inactive_image = &tab_inactive;
- TabImage* alpha = &tab_alpha;
-
- // If the theme is providing a custom background image, then its top edge
- // should be at the top of the tab. Otherwise, we assume that the background
- // image is a composited foreground + frame image.
- int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ?
- 0 : background_offset_.y();
-
- // Draw left edge. Don't draw over the toolbar, as we're not the foreground
- // tab.
- SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap(
- *tab_bg, offset, bg_offset_y, tab_image->l_width, height());
- SkBitmap theme_l =
- SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l);
- canvas->DrawBitmapInt(theme_l,
- 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
- 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
- false);
-
- // Draw right edge. Again, don't draw over the toolbar.
- SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
- offset + width() - tab_image->r_width, bg_offset_y,
- tab_image->r_width, height());
- SkBitmap theme_r =
- SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r);
- canvas->DrawBitmapInt(theme_r,
- 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap,
- width() - theme_r.width(), 0, theme_r.width(),
- theme_r.height() - kToolbarOverlap, false);
-
- // Draw center. Instead of masking out the top portion we simply skip over
- // it by incrementing by kDropShadowHeight, since it's a simple rectangle.
- // And again, don't draw over the toolbar.
- canvas->TileImageInt(*tab_bg,
- offset + tab_image->l_width,
- bg_offset_y + kDropShadowHeight + tab_image->y_offset,
- tab_image->l_width,
- kDropShadowHeight + tab_image->y_offset,
- width() - tab_image->l_width - tab_image->r_width,
- height() - kDropShadowHeight - kToolbarOverlap - tab_image->y_offset);
-
- // Now draw the highlights/shadows around the tab edge.
- canvas->DrawBitmapInt(*tab_inactive_image->image_l, 0, 0);
- canvas->TileImageInt(*tab_inactive_image->image_c,
- tab_inactive_image->l_width, 0,
- width() - tab_inactive_image->l_width -
- tab_inactive_image->r_width,
- height());
- canvas->DrawBitmapInt(*tab_inactive_image->image_r,
- width() - tab_inactive_image->r_width, 0);
-}
-
-void Tab::PaintActiveTabBackground(gfx::Canvas* canvas) {
- int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) +
- background_offset_.x();
- ThemeProvider* tp = GetThemeProvider();
- if (!tp)
- NOTREACHED() << "Unable to get theme provider";
-
- SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR);
-
- TabImage* tab_image = &tab_active;
- TabImage* alpha = &tab_alpha;
-
- // Draw left edge.
- SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap(
- *tab_bg, offset, 0, tab_image->l_width, height());
- SkBitmap theme_l =
- SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l);
- canvas->DrawBitmapInt(theme_l, 0, 0);
-
- // Draw right edge.
- SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
- offset + width() - tab_image->r_width, 0, tab_image->r_width, height());
- SkBitmap theme_r =
- SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r);
- canvas->DrawBitmapInt(theme_r, width() - tab_image->r_width, 0);
-
- // Draw center. Instead of masking out the top portion we simply skip over it
- // by incrementing by kDropShadowHeight, since it's a simple rectangle.
- canvas->TileImageInt(*tab_bg,
- offset + tab_image->l_width,
- kDropShadowHeight + tab_image->y_offset,
- tab_image->l_width,
- kDropShadowHeight + tab_image->y_offset,
- width() - tab_image->l_width - tab_image->r_width,
- height() - kDropShadowHeight - tab_image->y_offset);
-
- // Now draw the highlights/shadows around the tab edge.
- canvas->DrawBitmapInt(*tab_image->image_l, 0, 0);
- canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0,
- width() - tab_image->l_width - tab_image->r_width, height());
- canvas->DrawBitmapInt(*tab_image->image_r, width() - tab_image->r_width, 0);
-}
-
-int Tab::IconCapacity() const {
- if (height() < GetMinimumUnselectedSize().height())
- return 0;
- return (width() - kLeftPadding - kRightPadding) / kFavIconSize;
-}
-
-bool Tab::ShouldShowIcon() const {
- if (data().mini && height() >= GetMinimumUnselectedSize().height())
- return true;
- if (!data().show_icon) {
- return false;
- } else if (IsSelected()) {
- // The selected tab clips favicon before close button.
- return IconCapacity() >= 2;
- }
- // Non-selected tabs clip close button before favicon.
- return IconCapacity() >= 1;
-}
-
-bool Tab::ShouldShowCloseBox() const {
- // The selected tab never clips close button.
- return !data().mini && IsCloseable() &&
- (IsSelected() || IconCapacity() >= 3);
-}
-
-double Tab::GetThrobValue() {
- if (pulse_animation() && pulse_animation()->is_animating())
- return pulse_animation()->GetCurrentValue() * kHoverOpacity;
-
- return hover_animation() ?
- kHoverOpacity * hover_animation()->GetCurrentValue() : 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Tab, private:
-
-// static
-void Tab::LoadTabImages() {
- // We're not letting people override tab images just yet.
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
-
- tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT);
- tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT);
-
- tab_active.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT);
- tab_active.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER);
- tab_active.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT);
- tab_active.l_width = tab_active.image_l->width();
- tab_active.r_width = tab_active.image_r->width();
-
- tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
- tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
- tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
- tab_inactive.l_width = tab_inactive.image_l->width();
- tab_inactive.r_width = tab_inactive.image_r->width();
-}
diff --git a/chrome/browser/views/tabs/tab.h b/chrome/browser/views/tabs/tab.h
index e99a8fd..11076c1 100644
--- a/chrome/browser/views/tabs/tab.h
+++ b/chrome/browser/views/tabs/tab.h
@@ -6,136 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_TAB_H_
#pragma once
-#include <string>
-
-#include "base/scoped_ptr.h"
-#include "chrome/browser/views/tabs/base_tab.h"
-#include "gfx/point.h"
-
-class MultiAnimation;
-class SlideAnimation;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// TabRenderer
-//
-// A View that renders a Tab, either in a TabStrip or in a DraggedTabView.
-//
-///////////////////////////////////////////////////////////////////////////////
-class Tab : public BaseTab {
- public:
- // The menu button's class name.
- static const char kViewClassName[];
-
- explicit Tab(TabController* controller);
- virtual ~Tab();
-
- // Start/stop the mini-tab title animation.
- void StartMiniTabTitleAnimation();
- void StopMiniTabTitleAnimation();
-
- // Set the background offset used to match the image in the inactive tab
- // to the frame image.
- void SetBackgroundOffset(const gfx::Point& offset) {
- background_offset_ = offset;
- }
-
- // Paints the icon. Most of the time you'll want to invoke Paint directly, but
- // in certain situations this invoked outside of Paint.
- void PaintIcon(gfx::Canvas* canvas);
-
- // Returns the minimum possible size of a single unselected Tab.
- static gfx::Size GetMinimumUnselectedSize();
- // Returns the minimum possible size of a selected Tab. Selected tabs must
- // always show a close button and have a larger minimum size than unselected
- // tabs.
- static gfx::Size GetMinimumSelectedSize();
- // Returns the preferred size of a single Tab, assuming space is
- // available.
- static gfx::Size GetStandardSize();
-
- // Returns the width for mini-tabs. Mini-tabs always have this width.
- static int GetMiniWidth();
-
- // Loads the images to be used for the tab background.
- static void LoadTabImages();
-
- protected:
- virtual const gfx::Rect& title_bounds() const { return title_bounds_; }
-
- // BaseTab overrides:
- virtual void DataChanged(const TabRendererData& old);
-
- private:
- // Overridden from views::View:
- virtual void Paint(gfx::Canvas* canvas);
- virtual void Layout();
- virtual void OnThemeChanged();
- virtual std::string GetClassName() const { return kViewClassName; }
- virtual bool HasHitTestMask() const;
- virtual void GetHitTestMask(gfx::Path* path) const;
- virtual bool GetTooltipTextOrigin(const gfx::Point& p, gfx::Point* origin);
-
- // Paint various portions of the Tab
- void PaintTabBackground(gfx::Canvas* canvas);
- void PaintInactiveTabBackgroundWithTitleChange(gfx::Canvas* canvas);
- void PaintInactiveTabBackground(gfx::Canvas* canvas);
- void PaintActiveTabBackground(gfx::Canvas* canvas);
-
- // Returns the number of favicon-size elements that can fit in the tab's
- // current size.
- int IconCapacity() const;
-
- // Returns whether the Tab should display a favicon.
- bool ShouldShowIcon() const;
-
- // Returns whether the Tab should display a close button.
- bool ShouldShowCloseBox() const;
-
- // Gets the throb value for the tab. When a tab is not selected the
- // active background is drawn at |GetThrobValue()|%. This is used for hover,
- // mini tab title change and pulsing.
- double GetThrobValue();
-
- // The bounds of various sections of the display.
- gfx::Rect favicon_bounds_;
- gfx::Rect title_bounds_;
-
- // The offset used to paint the inactive background image.
- gfx::Point background_offset_;
-
- // Hover animation.
- scoped_ptr<SlideAnimation> hover_animation_;
-
- // Animation used when the title of an inactive mini tab changes.
- scoped_ptr<MultiAnimation> mini_title_animation_;
-
- struct TabImage {
- SkBitmap* image_l;
- SkBitmap* image_c;
- SkBitmap* image_r;
- int l_width;
- int r_width;
- int y_offset;
- };
- static TabImage tab_active;
- static TabImage tab_inactive;
- static TabImage tab_alpha;
-
- // Whether we're showing the icon. It is cached so that we can detect when it
- // changes and layout appropriately.
- bool showing_icon_;
-
- // Whether we are showing the close button. It is cached so that we can
- // detect when it changes and layout appropriately.
- bool showing_close_button_;
-
- // The current color of the close button.
- SkColor close_button_color_;
-
- static bool initialized_;
-
- DISALLOW_COPY_AND_ASSIGN(Tab);
-};
+#include "chrome/browser/ui/views/tabs/tab.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_TAB_H_
+
diff --git a/chrome/browser/views/tabs/tab_controller.h b/chrome/browser/views/tabs/tab_controller.h
index abaaf0f..5205f5e 100644
--- a/chrome/browser/views/tabs/tab_controller.h
+++ b/chrome/browser/views/tabs/tab_controller.h
@@ -6,54 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_TAB_CONTROLLER_H_
#pragma once
-class BaseTab;
-
-namespace gfx {
-class Point;
-}
-namespace views {
-class MouseEvent;
-}
-
-// Controller for tabs.
-class TabController {
- public:
- // Selects the tab.
- virtual void SelectTab(BaseTab* tab) = 0;
-
- // Closes the tab.
- virtual void CloseTab(BaseTab* tab) = 0;
-
- // Shows a context menu for the tab at the specified point in screen coords.
- virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p) = 0;
-
- // Returns true if the specified Tab is selected.
- virtual bool IsTabSelected(const BaseTab* tab) const = 0;
-
- // Returns true if the specified Tab is pinned.
- virtual bool IsTabPinned(const BaseTab* tab) const = 0;
-
- // Returns true if the specified Tab is closeable.
- virtual bool IsTabCloseable(const BaseTab* tab) const = 0;
-
- // Potentially starts a drag for the specified Tab.
- virtual void MaybeStartDrag(BaseTab* tab, const views::MouseEvent& event) = 0;
-
- // Continues dragging a Tab.
- virtual void ContinueDrag(const views::MouseEvent& event) = 0;
-
- // Ends dragging a Tab. |canceled| is true if the drag was aborted in a way
- // other than the user releasing the mouse. Returns whether the tab has been
- // destroyed.
- virtual bool EndDrag(bool canceled) = 0;
-
- // Returns the tab that contains the specified coordinates, in terms of |tab|,
- // or NULL if there is no tab that contains the specified point.
- virtual BaseTab* GetTabAt(BaseTab* tab,
- const gfx::Point& tab_in_tab_coordinates) = 0;
-
- protected:
- virtual ~TabController() {}
-};
+#include "chrome/browser/ui/views/tabs/tab_controller.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_TAB_CONTROLLER_H_
+
diff --git a/chrome/browser/views/tabs/tab_dragging_test.cc b/chrome/browser/views/tabs/tab_dragging_test.cc
deleted file mode 100644
index 2cb0171..0000000
--- a/chrome/browser/views/tabs/tab_dragging_test.cc
+++ /dev/null
@@ -1,515 +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 "base/command_line.h"
-#include "base/file_util.h"
-#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "chrome/test/automation/tab_proxy.h"
-#include "chrome/test/automation/browser_proxy.h"
-#include "chrome/test/automation/window_proxy.h"
-#include "chrome/test/ui/ui_test.h"
-#include "gfx/rect.h"
-#include "googleurl/src/gurl.h"
-#include "net/base/net_util.h"
-#include "views/event.h"
-
-#if defined(OS_LINUX)
-// This test doesn't make sense on chromeos as chromeos doesn't allow dragging
-// tabs out.
-#define MAYBE_Tab2OutOfTabStrip DISABLED_Tab2OutOfTabStrip
-#else
-// Flaky, http://crbug.com/62311.
-#define MAYBE_Tab2OutOfTabStrip FLAKY_Tab2OutOfTabStrip
-#endif
-
-#if defined(OS_LINUX)
-// Disabled on Toolkit views bot. See http://crbug.com/42614
-#define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape
-#elif defined(OS_WIN)
-// Disabled on Windows. See http://crbug.com/57687
-#define MAYBE_Tab1Tab3Escape DISABLED_Tab1Tab3Escape
-#else
-#define MAYBE_Tab1Tab3Escape Tab1Tab3Escape
-#endif
-
-// These tests fail on Linux because we haven't implemented all of tab dragging
-// (it's not needed on chromeos). See http://crbug.com/10941
-#if defined(OS_LINUX)
-#define MAYBE_Tab1Tab2 DISABLED_Tab1Tab2
-#define MAYBE_Tab1Tab3 DISABLED_Tab1Tab3
-#else
-// Flaky, http://crbug.com/62311.
-#define MAYBE_Tab1Tab2 FLAKY_Tab1Tab2
-#define MAYBE_Tab1Tab3 FLAKY_Tab1Tab3
-#endif
-
-class TabDraggingTest : public UITest {
- protected:
- TabDraggingTest() {
- show_window_ = true;
- }
-};
-
-// Automated UI test to open three tabs in a new window, and drag Tab_1 into
-// the position of Tab_2.
-TEST_F(TabDraggingTest, MAYBE_Tab1Tab2) {
- scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
- ASSERT_TRUE(browser.get());
- scoped_refptr<WindowProxy> window(browser->GetWindow());
- ASSERT_TRUE(window.get());
-
- // Get initial tab count.
- int initial_tab_count = 0;
- ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
- ASSERT_TRUE(1 == initial_tab_count);
-
- // Get Tab_1 which comes with the browser window.
- scoped_refptr<TabProxy> tab1(browser->GetTab(0));
- ASSERT_TRUE(tab1.get());
- GURL tab1_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
-
- // Add Tab_2.
- GURL tab2_url("about:");
- ASSERT_TRUE(browser->AppendTab(tab2_url));
- scoped_refptr<TabProxy> tab2(browser->GetTab(1));
- ASSERT_TRUE(tab2.get());
-
- // Add Tab_3.
- GURL tab3_url("about:plugins");
- ASSERT_TRUE(browser->AppendTab(tab3_url));
- scoped_refptr<TabProxy> tab3(browser->GetTab(2));
- ASSERT_TRUE(tab3.get());
-
- // Make sure 3 tabs are open.
- ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
-
- // Get bounds for the tabs.
- gfx::Rect bounds1;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
- EXPECT_LT(0, bounds1.x());
- EXPECT_LT(0, bounds1.width());
- EXPECT_LT(0, bounds1.height());
-
- gfx::Rect bounds2;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
- EXPECT_LT(0, bounds2.width());
- EXPECT_LT(0, bounds2.height());
- EXPECT_LT(bounds1.x(), bounds2.x());
- EXPECT_EQ(bounds2.y(), bounds1.y());
-
- gfx::Rect bounds3;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
- EXPECT_LT(0, bounds3.width());
- EXPECT_LT(0, bounds3.height());
- EXPECT_LT(bounds2.x(), bounds3.x());
- EXPECT_EQ(bounds3.y(), bounds2.y());
-
- // Get url Bar bounds.
- gfx::Rect urlbar_bounds;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
- false));
- EXPECT_LT(0, urlbar_bounds.x());
- EXPECT_LT(0, urlbar_bounds.y());
- EXPECT_LT(0, urlbar_bounds.width());
- EXPECT_LT(0, urlbar_bounds.height());
-
- /*
- TEST: Move Tab_1 to the position of Tab_2
- ____________ ____________ ____________
- / \ / \ / \
- | Tab_1 | Tab_2 | Tab_3 |
- ---- ---- ---- ---- ---- ---- ---- ---- ----
- x---- ---->
- ____________
- / X \
- | Tab_1 |
- ---- ---- ----
- */
-
- gfx::Point start(bounds1.x() + bounds1.width() / 2,
- bounds1.y() + bounds1.height() / 2);
- gfx::Point end(start.x() + 2 * bounds1.width() / 3, start.y());
- ASSERT_TRUE(browser->SimulateDrag(start, end,
- views::Event::EF_LEFT_BUTTON_DOWN,
- false));
-
- // Now check for expected results.
- tab1 = browser->GetTab(0);
- ASSERT_TRUE(tab1.get());
- GURL tab1_new_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
-
- tab2 = browser->GetTab(1);
- ASSERT_TRUE(tab2.get());
- GURL tab2_new_url;
- ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
-
- EXPECT_EQ(tab1_url.spec(), tab2_new_url.spec());
- EXPECT_EQ(tab2_url.spec(), tab1_new_url.spec());
-}
-
-// Drag Tab_1 into the position of Tab_3.
-TEST_F(TabDraggingTest, MAYBE_Tab1Tab3) {
- scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
- ASSERT_TRUE(browser.get());
- scoped_refptr<WindowProxy> window(browser->GetWindow());
- ASSERT_TRUE(window.get());
-
- // Get initial tab count.
- int initial_tab_count = 0;
- ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
- ASSERT_TRUE(1 == initial_tab_count);
-
- // Get Tab_1 which comes with the browser window.
- scoped_refptr<TabProxy> tab1(browser->GetTab(0));
- ASSERT_TRUE(tab1.get());
- GURL tab1_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
-
- // Add Tab_2.
- GURL tab2_url("about:");
- ASSERT_TRUE(browser->AppendTab(tab2_url));
- scoped_refptr<TabProxy> tab2(browser->GetTab(1));
- ASSERT_TRUE(tab2.get());
-
- // Add Tab_3.
- GURL tab3_url("about:plugins");
- ASSERT_TRUE(browser->AppendTab(tab3_url));
- scoped_refptr<TabProxy> tab3(browser->GetTab(2));
- ASSERT_TRUE(tab3.get());
-
- // Make sure 3 tabs are open.
- ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
-
- // Get bounds for the tabs.
- gfx::Rect bounds1;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
- EXPECT_LT(0, bounds1.x());
- EXPECT_LT(0, bounds1.width());
- EXPECT_LT(0, bounds1.height());
-
- gfx::Rect bounds2;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
- EXPECT_LT(0, bounds2.width());
- EXPECT_LT(0, bounds2.height());
- EXPECT_LT(bounds1.x(), bounds2.x());
- EXPECT_EQ(bounds2.y(), bounds1.y());
-
- gfx::Rect bounds3;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
- EXPECT_LT(0, bounds3.width());
- EXPECT_LT(0, bounds3.height());
- EXPECT_LT(bounds2.x(), bounds3.x());
- EXPECT_EQ(bounds3.y(), bounds2.y());
-
- // Get url Bar bounds.
- gfx::Rect urlbar_bounds;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
- false));
- EXPECT_LT(0, urlbar_bounds.x());
- EXPECT_LT(0, urlbar_bounds.y());
- EXPECT_LT(0, urlbar_bounds.width());
- EXPECT_LT(0, urlbar_bounds.height());
-
- /*
- TEST: Move Tab_1 to the middle position of Tab_3
- ____________ ____________ ____________
- / \ / \ / \
- | Tab_1 | Tab_2 | Tab_3 |
- ---- ---- ---- ---- ---- ---- ---- ---- ----
- x---- ---- ---- ---- ---- ---->
- ____________
- / X \
- | Tab_1 |
- ---- ---- ----
- */
-
- gfx::Point start(bounds1.x() + bounds1.width() / 2,
- bounds1.y() + bounds1.height() / 2);
- gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() +
- bounds3.width() / 2,
- start.y());
- ASSERT_TRUE(browser->SimulateDrag(start, end,
- views::Event::EF_LEFT_BUTTON_DOWN,
- false));
-
- // Now check for expected results.
- tab1 = browser->GetTab(0);
- ASSERT_TRUE(tab1.get());
- GURL tab1_new_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
-
- tab2 = browser->GetTab(1);
- ASSERT_TRUE(tab2.get());
- GURL tab2_new_url;
- ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
-
- tab3 = browser->GetTab(2);
- ASSERT_TRUE(tab3.get());
- GURL tab3_new_url;
- ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url));
-
- EXPECT_EQ(tab1_new_url.spec(), tab2_url.spec());
- EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec());
- EXPECT_EQ(tab3_new_url.spec(), tab1_url.spec());
-}
-
-// Drag Tab_1 into the position of Tab_3, and press ESCAPE before releasing the
-// left mouse button.
-TEST_F(TabDraggingTest, MAYBE_Tab1Tab3Escape) {
- scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
- ASSERT_TRUE(browser.get());
- scoped_refptr<WindowProxy> window(browser->GetWindow());
- ASSERT_TRUE(window.get());
-
- // Get initial tab count.
- int initial_tab_count = 0;
- ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
- ASSERT_TRUE(1 == initial_tab_count);
-
- // Get Tab_1 which comes with the browser window.
- scoped_refptr<TabProxy> tab1(browser->GetTab(0));
- ASSERT_TRUE(tab1.get());
- GURL tab1_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
-
- // Add Tab_2.
- GURL tab2_url("about:blank");
- ASSERT_TRUE(browser->AppendTab(tab2_url));
- scoped_refptr<TabProxy> tab2(browser->GetTab(1));
- ASSERT_TRUE(tab2.get());
-
- // Add Tab_3.
- GURL tab3_url("about:plugins");
- ASSERT_TRUE(browser->AppendTab(tab3_url));
- scoped_refptr<TabProxy> tab3(browser->GetTab(2));
- ASSERT_TRUE(tab3.get());
-
- // Make sure 3 tabs are open.
- ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
-
- // Get bounds for the tabs.
- gfx::Rect bounds1;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
- EXPECT_LT(0, bounds1.x());
- EXPECT_LT(0, bounds1.width());
- EXPECT_LT(0, bounds1.height());
-
- gfx::Rect bounds2;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
- EXPECT_LT(0, bounds2.width());
- EXPECT_LT(0, bounds2.height());
- EXPECT_LT(bounds1.x(), bounds2.x());
- EXPECT_EQ(bounds2.y(), bounds1.y());
-
- gfx::Rect bounds3;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
- EXPECT_LT(0, bounds3.width());
- EXPECT_LT(0, bounds3.height());
- EXPECT_LT(bounds2.x(), bounds3.x());
- EXPECT_EQ(bounds3.y(), bounds2.y());
-
- // Get url Bar bounds.
- gfx::Rect urlbar_bounds;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
- false));
- EXPECT_LT(0, urlbar_bounds.x());
- EXPECT_LT(0, urlbar_bounds.y());
- EXPECT_LT(0, urlbar_bounds.width());
- EXPECT_LT(0, urlbar_bounds.height());
-
- /*
- TEST: Move Tab_1 to the middle position of Tab_3
- ____________ ____________ ____________
- / \ / \ / \
- | Tab_1 | Tab_2 | Tab_3 |
- ---- ---- ---- ---- ---- ---- ---- ---- ----
- x---- ---- ---- ---- ---- ----> + ESCAPE
- ____________
- / X \
- | Tab_1 |
- ---- ---- ----
- */
-
- gfx::Point start(bounds1.x() + bounds1.width() / 2,
- bounds1.y() + bounds1.height() / 2);
- gfx::Point end(start.x() + bounds1.width() / 2 + bounds2.width() +
- bounds3.width() / 2,
- start.y());
-
- // Simulate drag with 'true' as the last parameter. This will interrupt
- // in-flight with Escape.
- ASSERT_TRUE(browser->SimulateDrag(start, end,
- views::Event::EF_LEFT_BUTTON_DOWN,
- true));
-
- // Now check for expected results.
- tab1 = browser->GetTab(0);
- ASSERT_TRUE(tab1.get());
- GURL tab1_new_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
-
- tab2 = browser->GetTab(1);
- ASSERT_TRUE(tab2.get());
- GURL tab2_new_url;
- ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
-
- tab3 = browser->GetTab(2);
- ASSERT_TRUE(tab3.get());
- GURL tab3_new_url;
- ASSERT_TRUE(tab3->GetCurrentURL(&tab3_new_url));
-
- // The tabs should be in their original positions.
- EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec());
- EXPECT_EQ(tab2_new_url.spec(), tab2_url.spec());
- EXPECT_EQ(tab3_new_url.spec(), tab3_url.spec());
-}
-
-// Drag Tab_2 out of the Tab strip. A new window should open with this tab.
-TEST_F(TabDraggingTest, MAYBE_Tab2OutOfTabStrip) {
- scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
- ASSERT_TRUE(browser.get());
- scoped_refptr<WindowProxy> window(browser->GetWindow());
- ASSERT_TRUE(window.get());
-
- // Get initial tab count.
- int initial_tab_count = 0;
- ASSERT_TRUE(browser->GetTabCount(&initial_tab_count));
- ASSERT_TRUE(1 == initial_tab_count);
-
- // Get Tab_1 which comes with the browser window.
- scoped_refptr<TabProxy> tab1(browser->GetTab(0));
- ASSERT_TRUE(tab1.get());
- GURL tab1_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_url));
-
- // Add Tab_2.
- GURL tab2_url("about:version");
- ASSERT_TRUE(browser->AppendTab(tab2_url));
- scoped_refptr<TabProxy> tab2(browser->GetTab(1));
- ASSERT_TRUE(tab2.get());
-
- // Add Tab_3.
- GURL tab3_url("about:plugins");
- ASSERT_TRUE(browser->AppendTab(tab3_url));
- scoped_refptr<TabProxy> tab3(browser->GetTab(2));
- ASSERT_TRUE(tab3.get());
-
- // Make sure 3 tabs are opened.
- ASSERT_TRUE(browser->WaitForTabCountToBecome(initial_tab_count + 2));
-
- // Make sure all the tab URL specs are different.
- ASSERT_TRUE(tab1_url != tab2_url);
- ASSERT_TRUE(tab1_url != tab3_url);
- ASSERT_TRUE(tab2_url != tab3_url);
-
- // Get bounds for the tabs.
- gfx::Rect bounds1;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_0, &bounds1, false));
- EXPECT_LT(0, bounds1.x());
- EXPECT_LT(0, bounds1.width());
- EXPECT_LT(0, bounds1.height());
-
- gfx::Rect bounds2;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_1, &bounds2, false));
- EXPECT_LT(0, bounds2.width());
- EXPECT_LT(0, bounds2.height());
- EXPECT_LT(bounds1.x(), bounds2.x());
- EXPECT_EQ(bounds2.y(), bounds1.y());
-
- gfx::Rect bounds3;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_TAB_2, &bounds3, false));
- EXPECT_LT(0, bounds3.width());
- EXPECT_LT(0, bounds3.height());
- EXPECT_LT(bounds2.x(), bounds3.x());
- EXPECT_EQ(bounds3.y(), bounds2.y());
-
- // Get url Bar bounds.
- gfx::Rect urlbar_bounds;
- ASSERT_TRUE(window->GetViewBounds(VIEW_ID_LOCATION_BAR, &urlbar_bounds,
- false));
- EXPECT_LT(0, urlbar_bounds.x());
- EXPECT_LT(0, urlbar_bounds.y());
- EXPECT_LT(0, urlbar_bounds.width());
- EXPECT_LT(0, urlbar_bounds.height());
-
- /*
- TEST: Move Tab_2 down, out of the tab strip.
- This should result in the following:
- 1- Tab_3 shift left in place of Tab_2 in Window 1
- 2- Tab_1 to remain in its place
- 3- Tab_2 openes in a new window
-
- ____________ ____________ ____________
- / \ / \ / \
- | Tab_1 | Tab_2 | Tab_3 |
- ---- ---- ---- ---- ---- ---- ---- ---- ----
- x
- |
- | (Drag this below, out of tab strip)
- V
- ____________
- / X \
- | Tab_2 | (New Window)
- ---- ---- ---- ---- ---- ---- ----
- */
-
- gfx::Point start(bounds2.x() + bounds2.width() / 2,
- bounds2.y() + bounds2.height() / 2);
- gfx::Point end(start.x(),
- start.y() + 3 * urlbar_bounds.height());
-
- // Simulate tab drag.
- ASSERT_TRUE(browser->SimulateDrag(start, end,
- views::Event::EF_LEFT_BUTTON_DOWN,
- false));
-
- // Now, first make sure that the old window has only two tabs remaining.
- int new_tab_count = 0;
- ASSERT_TRUE(browser->GetTabCount(&new_tab_count));
- ASSERT_EQ(2, new_tab_count);
-
- // Get the two tabs - they are called Tab_1 and Tab_2 in the old window.
- tab1 = browser->GetTab(0);
- ASSERT_TRUE(tab1.get());
- GURL tab1_new_url;
- ASSERT_TRUE(tab1->GetCurrentURL(&tab1_new_url));
-
- tab2 = browser->GetTab(1);
- ASSERT_TRUE(tab2.get());
- GURL tab2_new_url;
- ASSERT_TRUE(tab2->GetCurrentURL(&tab2_new_url));
-
- // Now check for proper shifting of tabs; i.e., Tab_3 in window 1 should
- // shift left to the position of Tab_2; Tab_1 should stay where it was.
- EXPECT_EQ(tab1_new_url.spec(), tab1_url.spec());
- EXPECT_EQ(tab2_new_url.spec(), tab3_url.spec());
-
- // Now check to make sure a new window has opened.
- scoped_refptr<BrowserProxy> browser2(automation()->GetBrowserWindow(1));
- ASSERT_TRUE(browser2.get());
- scoped_refptr<WindowProxy> window2(browser2->GetWindow());
- ASSERT_TRUE(window2.get());
-
- // Make sure that the new window has only one tab.
- int tab_count_window_2 = 0;
- ASSERT_TRUE(browser2->GetTabCount(&tab_count_window_2));
- ASSERT_EQ(1, tab_count_window_2);
-
- // Get Tab_1_2 which should be Tab_1 in Window 2.
- scoped_refptr<TabProxy> tab1_2(browser2->GetTab(0));
- ASSERT_TRUE(tab1_2.get());
- GURL tab1_2_url;
- ASSERT_TRUE(tab1_2->GetCurrentURL(&tab1_2_url));
-
- // Tab_1_2 of Window 2 should essentially be Tab_2 of Window 1.
- EXPECT_EQ(tab1_2_url.spec(), tab2_url.spec());
- EXPECT_NE(tab1_2_url.spec(), tab1_url.spec());
- EXPECT_NE(tab1_2_url.spec(), tab3_url.spec());
-}
diff --git a/chrome/browser/views/tabs/tab_renderer_data.h b/chrome/browser/views/tabs/tab_renderer_data.h
index 31e84ed..dca47c9 100644
--- a/chrome/browser/views/tabs/tab_renderer_data.h
+++ b/chrome/browser/views/tabs/tab_renderer_data.h
@@ -6,41 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_TAB_RENDERER_DATA_H_
#pragma once
-#include "base/string16.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-// Wraps the state needed by the renderers.
-struct TabRendererData {
- // 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 {
- NETWORK_STATE_NONE, // no network activity.
- NETWORK_STATE_WAITING, // waiting for a connection.
- NETWORK_STATE_LOADING, // connected, transferring data.
- };
-
- TabRendererData()
- : network_state(NETWORK_STATE_NONE),
- loading(false),
- crashed(false),
- off_the_record(false),
- show_icon(true),
- mini(false),
- blocked(false),
- app(false) {
- }
-
- SkBitmap favicon;
- NetworkState network_state;
- string16 title;
- bool loading;
- bool crashed;
- bool off_the_record;
- bool show_icon;
- bool mini;
- bool blocked;
- bool app;
-};
+#include "chrome/browser/ui/views/tabs/tab_renderer_data.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_TAB_RENDERER_DATA_H_
+
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
deleted file mode 100644
index 9b25dfa..0000000
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ /dev/null
@@ -1,982 +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/tab_strip.h"
-
-#include "app/animation_container.h"
-#include "app/drag_drop_types.h"
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "base/compiler_specific.h"
-#include "base/stl_util-inl.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/defaults.h"
-#include "chrome/browser/themes/browser_theme_provider.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/browser/views/tabs/tab.h"
-#include "chrome/browser/views/tabs/tab_strip_controller.h"
-#include "chrome/common/pref_names.h"
-#include "gfx/canvas_skia.h"
-#include "gfx/path.h"
-#include "gfx/size.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.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"
-
-#if defined(OS_WIN)
-#include "app/win_util.h"
-#include "views/widget/widget_win.h"
-#elif defined(OS_LINUX)
-#include "views/widget/widget_gtk.h"
-#endif
-
-#undef min
-#undef max
-
-#if defined(COMPILER_GCC)
-// Squash false positive signed overflow warning in GenerateStartAndEndWidths
-// when doing 'start_tab_count < end_tab_count'.
-#pragma GCC diagnostic ignored "-Wstrict-overflow"
-#endif
-
-using views::DropTargetEvent;
-
-static const int kNewTabButtonHOffset = -5;
-static const int kNewTabButtonVOffset = 5;
-static const int kSuspendAnimationsTimeMs = 200;
-static const int kTabHOffset = -16;
-static const int kTabStripAnimationVSlop = 40;
-
-// Size of the drop indicator.
-static int drop_indicator_width;
-static int drop_indicator_height;
-
-static inline int Round(double x) {
- // Why oh why is this not in a standard header?
- return static_cast<int>(floor(x + 0.5));
-}
-
-namespace {
-
-///////////////////////////////////////////////////////////////////////////////
-// NewTabButton
-//
-// A subclass of button that hit-tests to the shape of the new tab button.
-
-class NewTabButton : public views::ImageButton {
- public:
- explicit NewTabButton(views::ButtonListener* listener)
- : views::ImageButton(listener) {
- }
- virtual ~NewTabButton() {}
-
- protected:
- // Overridden from views::View:
- virtual bool HasHitTestMask() const {
- // When the button is sized to the top of the tab strip we want the user to
- // be able to click on complete bounds, and so don't return a custom hit
- // mask.
- return !browser_defaults::kSizeTabButtonToTopOfTabStrip;
- }
- virtual void GetHitTestMask(gfx::Path* path) const {
- DCHECK(path);
-
- SkScalar w = SkIntToScalar(width());
-
- // These values are defined by the shape of the new tab bitmap. Should that
- // bitmap ever change, these values will need to be updated. They're so
- // custom it's not really worth defining constants for.
- path->moveTo(0, 1);
- path->lineTo(w - 7, 1);
- path->lineTo(w - 4, 4);
- path->lineTo(w, 16);
- path->lineTo(w - 1, 17);
- path->lineTo(7, 17);
- path->lineTo(4, 13);
- path->lineTo(0, 1);
- path->close();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(NewTabButton);
-};
-
-} // namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// TabStrip, public:
-
-// static
-const int TabStrip::mini_to_non_mini_gap_ = 3;
-
-TabStrip::TabStrip(TabStripController* controller)
- : BaseTabStrip(controller, BaseTabStrip::HORIZONTAL_TAB_STRIP),
- current_unselected_width_(Tab::GetStandardSize().width()),
- current_selected_width_(Tab::GetStandardSize().width()),
- available_width_for_tabs_(-1),
- in_tab_close_(false),
- animation_container_(new AnimationContainer()) {
- Init();
-}
-
-TabStrip::~TabStrip() {
- // The animations may reference the tabs. Shut down the animation before we
- // delete the tabs.
- StopAnimating(false);
-
- DestroyDragController();
-
- // Make sure we unhook ourselves as a message loop observer so that we don't
- // crash in the case where the user closes the window after closing a tab
- // but before moving the mouse.
- RemoveMessageLoopObserver();
-
- // 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);
-}
-
-void TabStrip::InitTabStripButtons() {
- newtab_button_ = new NewTabButton(this);
- if (browser_defaults::kSizeTabButtonToTopOfTabStrip) {
- newtab_button_->SetImageAlignment(views::ImageButton::ALIGN_LEFT,
- views::ImageButton::ALIGN_BOTTOM);
- }
- LoadNewTabButtonImage();
- newtab_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_NEWTAB));
- AddChildView(newtab_button_);
-}
-
-gfx::Rect TabStrip::GetNewTabButtonBounds() {
- return newtab_button_->bounds();
-}
-
-void TabStrip::MouseMovedOutOfView() {
- ResizeLayoutTabs();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabStrip, BaseTabStrip implementation:
-
-int TabStrip::GetPreferredHeight() {
- return GetPreferredSize().height();
-}
-
-void TabStrip::SetBackgroundOffset(const gfx::Point& offset) {
- for (int i = 0; i < tab_count(); ++i)
- GetTabAtTabDataIndex(i)->SetBackgroundOffset(offset);
-}
-
-bool TabStrip::IsPositionInWindowCaption(const gfx::Point& point) {
- views::View* v = GetViewForPoint(point);
-
- // If there is no control at this location, claim the hit was in the title
- // bar to get a move action.
- if (v == this)
- return true;
-
- // Check to see if the point is within the non-button parts of the new tab
- // button. The button has a non-rectangular shape, so if it's not in the
- // visual portions of the button we treat it as a click to the caption.
- gfx::Point point_in_newtab_coords(point);
- View::ConvertPointToView(this, newtab_button_, &point_in_newtab_coords);
- if (newtab_button_->bounds().Contains(point) &&
- !newtab_button_->HitTest(point_in_newtab_coords)) {
- return true;
- }
-
- // All other regions, including the new Tab button, should be considered part
- // of the containing Window's client area so that regular events can be
- // processed for them.
- return false;
-}
-
-void TabStrip::SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) {
-}
-
-TabStrip* TabStrip::AsTabStrip() {
- return this;
-}
-
-void TabStrip::PrepareForCloseAt(int model_index) {
- if (!in_tab_close_ && IsAnimating()) {
- // Cancel any current animations. We do this as remove uses the current
- // ideal bounds and we need to know ideal bounds is in a good state.
- StopAnimating(true);
- }
-
- int model_count = GetModelCount();
- if (model_index + 1 != model_count && model_count > 1) {
- // The user is about to close a tab other than the last tab. Set
- // available_width_for_tabs_ so that if we do a layout we don't position a
- // tab past the end of the second to last tab. We do this so that as the
- // user closes tabs with the mouse a tab continues to fall under the mouse.
- available_width_for_tabs_ = GetAvailableWidthForTabs(
- GetTabAtModelIndex(model_count - 2));
- }
-
- in_tab_close_ = true;
- AddMessageLoopObserver();
-}
-
-void TabStrip::RemoveTabAt(int model_index) {
- if (in_tab_close_ && model_index != GetModelCount())
- StartMouseInitiatedRemoveTabAnimation(model_index);
- else
- StartRemoveTabAnimation(model_index);
-}
-
-void TabStrip::SelectTabAt(int old_model_index, int new_model_index) {
- // We have "tiny tabs" if the tabs are so tiny that the unselected ones are
- // a different size to the selected ones.
- bool tiny_tabs = current_unselected_width_ != current_selected_width_;
- if (!IsAnimating() && (!in_tab_close_ || tiny_tabs)) {
- DoLayout();
- } else {
- SchedulePaint();
- }
-
- if (old_model_index >= 0) {
- GetTabAtTabDataIndex(ModelIndexToTabIndex(old_model_index))->
- StopMiniTabTitleAnimation();
- }
-}
-
-void TabStrip::TabTitleChangedNotLoading(int model_index) {
- Tab* tab = GetTabAtModelIndex(model_index);
- if (tab->data().mini && !tab->IsSelected())
- tab->StartMiniTabTitleAnimation();
-}
-
-void TabStrip::StartHighlight(int model_index) {
- GetTabAtModelIndex(model_index)->StartPulse();
-}
-
-void TabStrip::StopAllHighlighting() {
- for (int i = 0; i < tab_count(); ++i)
- GetTabAtTabDataIndex(i)->StopPulse();
-}
-
-BaseTab* TabStrip::CreateTabForDragging() {
- Tab* tab = new Tab(NULL);
- // Make sure the dragged tab shares our theme provider. We need to explicitly
- // do this as during dragging there isn't a theme provider.
- tab->set_theme_provider(GetThemeProvider());
- return tab;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TabStrip, views::View overrides:
-
-void TabStrip::PaintChildren(gfx::Canvas* canvas) {
- // Tabs are painted in reverse order, so they stack to the left.
- Tab* selected_tab = NULL;
- Tab* dragging_tab = NULL;
-
- for (int i = tab_count() - 1; i >= 0; --i) {
- Tab* tab = GetTabAtTabDataIndex(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 Tab is being
- // removed after its TabContents has been destroyed.
- if (tab->dragging()) {
- dragging_tab = tab;
- } else if (!tab->IsSelected()) {
- tab->ProcessPaint(canvas);
- } else {
- selected_tab = tab;
- }
- }
-
- if (GetWindow()->GetNonClientView()->UseNativeFrame()) {
- // Make sure unselected tabs are somewhat transparent.
- SkPaint paint;
- paint.setColor(SkColorSetARGB(200, 255, 255, 255));
- paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
- paint.setStyle(SkPaint::kFill_Style);
- canvas->DrawRectInt(0, 0, width(),
- height() - 2, // Visible region that overlaps the toolbar.
- paint);
- }
-
- // Paint the selected tab last, so it overlaps all the others.
- if (selected_tab)
- selected_tab->ProcessPaint(canvas);
-
- // Paint the New Tab button.
- newtab_button_->ProcessPaint(canvas);
-
- // And the dragged tab.
- if (dragging_tab)
- dragging_tab->ProcessPaint(canvas);
-}
-
-// Overridden to support automation. See automation_proxy_uitest.cc.
-views::View* TabStrip::GetViewByID(int view_id) const {
- if (tab_count() > 0) {
- if (view_id == VIEW_ID_TAB_LAST) {
- return GetTabAtTabDataIndex(tab_count() - 1);
- } else 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 GetTabAtTabDataIndex(index);
- } else {
- return NULL;
- }
- }
- }
-
- return View::GetViewByID(view_id);
-}
-
-gfx::Size TabStrip::GetPreferredSize() {
- return gfx::Size(0, Tab::GetMinimumUnselectedSize().height());
-}
-
-void TabStrip::OnDragEntered(const DropTargetEvent& event) {
- // Force animations to stop, otherwise it makes the index calculation tricky.
- StopAnimating(true);
-
- UpdateDropIndex(event);
-}
-
-int TabStrip::OnDragUpdated(const DropTargetEvent& event) {
- UpdateDropIndex(event);
- return GetDropEffect(event);
-}
-
-void TabStrip::OnDragExited() {
- SetDropIndex(-1, false);
-}
-
-int TabStrip::OnPerformDrop(const DropTargetEvent& event) {
- if (!drop_info_.get())
- return DragDropTypes::DRAG_NONE;
-
- const int drop_index = drop_info_->drop_index;
- const bool drop_before = drop_info_->drop_before;
-
- // Hide the drop indicator.
- SetDropIndex(-1, false);
-
- GURL url;
- std::wstring title;
- if (!event.GetData().GetURLAndTitle(&url, &title) || !url.is_valid())
- return DragDropTypes::DRAG_NONE;
-
- controller()->PerformDrop(drop_before, drop_index, url);
-
- return GetDropEffect(event);
-}
-
-AccessibilityTypes::Role TabStrip::GetAccessibleRole() {
- return AccessibilityTypes::ROLE_PAGETABLIST;
-}
-
-views::View* TabStrip::GetViewForPoint(const gfx::Point& point) {
- // Return any view that isn't a Tab or this TabStrip immediately. We don't
- // want to interfere.
- views::View* v = View::GetViewForPoint(point);
- if (v && v != this && v->GetClassName() != Tab::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 Tab, so we look ahead for it as we walk.
- for (int i = 0; i < tab_count(); ++i) {
- Tab* next_tab = i < (tab_count() - 1) ? GetTabAtTabDataIndex(i + 1) : NULL;
- if (next_tab && next_tab->IsSelected() && IsPointInTab(next_tab, point))
- return next_tab;
- Tab* tab = GetTabAtTabDataIndex(i);
- if (IsPointInTab(tab, point))
- return tab;
- }
-
- // No need to do any floating view stuff, we don't use them in the TabStrip.
- return this;
-}
-
-void TabStrip::OnThemeChanged() {
- LoadNewTabButtonImage();
-}
-
-BaseTab* TabStrip::CreateTab() {
- Tab* tab = new Tab(this);
- tab->set_animation_container(animation_container_.get());
- return tab;
-}
-
-void TabStrip::StartInsertTabAnimation(int model_index, bool foreground) {
- PrepareForAnimation();
-
- // The TabStrip can now use its entire width to lay out Tabs.
- in_tab_close_ = false;
- available_width_for_tabs_ = -1;
-
- GenerateIdealBounds();
-
- int tab_data_index = ModelIndexToTabIndex(model_index);
- BaseTab* tab = base_tab_at_tab_index(tab_data_index);
- if (model_index == 0) {
- tab->SetBounds(0, ideal_bounds(tab_data_index).y(), 0,
- ideal_bounds(tab_data_index).height());
- } else {
- BaseTab* last_tab = base_tab_at_tab_index(tab_data_index - 1);
- tab->SetBounds(last_tab->bounds().right() + kTabHOffset,
- ideal_bounds(tab_data_index).y(), 0,
- ideal_bounds(tab_data_index).height());
- }
-
- AnimateToIdealBounds();
-}
-
-void TabStrip::StartMoveTabAnimation() {
- PrepareForAnimation();
-
- GenerateIdealBounds();
- AnimateToIdealBounds();
-}
-
-void TabStrip::AnimateToIdealBounds() {
- for (int i = 0; i < tab_count(); ++i) {
- Tab* tab = GetTabAtTabDataIndex(i);
- if (!tab->closing() && !tab->dragging())
- bounds_animator().AnimateViewTo(tab, ideal_bounds(i));
- }
-
- bounds_animator().AnimateViewTo(newtab_button_, newtab_button_bounds_);
-}
-
-bool TabStrip::ShouldHighlightCloseButtonAfterRemove() {
- return in_tab_close_;
-}
-
-void TabStrip::DoLayout() {
- BaseTabStrip::DoLayout();
-
- newtab_button_->SetBounds(newtab_button_bounds_);
-}
-
-void TabStrip::ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child) {
- if (is_add && child == this)
- InitTabStripButtons();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TabStrip, Tab::Delegate implementation:
-
-bool TabStrip::IsTabSelected(const BaseTab* btr) const {
- const Tab* tab = static_cast<const Tab*>(btr);
- return !tab->closing() && BaseTabStrip::IsTabSelected(btr);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TabStrip, views::BaseButton::ButtonListener implementation:
-
-void TabStrip::ButtonPressed(views::Button* sender, const views::Event& event) {
- if (sender == newtab_button_)
- controller()->CreateNewTab();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TabStrip, private:
-
-void TabStrip::Init() {
- SetID(VIEW_ID_TAB_STRIP);
- newtab_button_bounds_.SetRect(0, 0, kNewTabButtonWidth, kNewTabButtonHeight);
- if (browser_defaults::kSizeTabButtonToTopOfTabStrip) {
- newtab_button_bounds_.set_height(
- kNewTabButtonHeight + kNewTabButtonVOffset);
- }
- if (drop_indicator_width == 0) {
- // Direction doesn't matter, both images are the same size.
- SkBitmap* drop_image = GetDropArrowImage(true);
- drop_indicator_width = drop_image->width();
- drop_indicator_height = drop_image->height();
- }
-}
-
-void TabStrip::LoadNewTabButtonImage() {
- ThemeProvider* tp = GetThemeProvider();
-
- // If we don't have a theme provider yet, it means we do not have a
- // root view, and are therefore in a test.
- bool in_test = false;
- if (tp == NULL) {
- tp = new views::DefaultThemeProvider();
- in_test = true;
- }
-
- SkBitmap* bitmap = tp->GetBitmapNamed(IDR_NEWTAB_BUTTON);
- SkColor color = tp->GetColor(BrowserThemeProvider::COLOR_BUTTON_BACKGROUND);
- SkBitmap* background = tp->GetBitmapNamed(
- IDR_THEME_WINDOW_CONTROL_BACKGROUND);
-
- newtab_button_->SetImage(views::CustomButton::BS_NORMAL, bitmap);
- newtab_button_->SetImage(views::CustomButton::BS_PUSHED,
- tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_P));
- newtab_button_->SetImage(views::CustomButton::BS_HOT,
- tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_H));
- newtab_button_->SetBackground(color, background,
- tp->GetBitmapNamed(IDR_NEWTAB_BUTTON_MASK));
- if (in_test)
- delete tp;
-}
-
-Tab* TabStrip::GetTabAtTabDataIndex(int tab_data_index) const {
- return static_cast<Tab*>(base_tab_at_tab_index(tab_data_index));
-}
-
-Tab* TabStrip::GetTabAtModelIndex(int model_index) const {
- return GetTabAtTabDataIndex(ModelIndexToTabIndex(model_index));
-}
-
-void TabStrip::GetCurrentTabWidths(double* unselected_width,
- double* selected_width) const {
- *unselected_width = current_unselected_width_;
- *selected_width = current_selected_width_;
-}
-
-void TabStrip::GetDesiredTabWidths(int tab_count,
- int mini_tab_count,
- double* unselected_width,
- double* selected_width) const {
- DCHECK(tab_count >= 0 && mini_tab_count >= 0 && mini_tab_count <= tab_count);
- const double min_unselected_width = Tab::GetMinimumUnselectedSize().width();
- const double min_selected_width = Tab::GetMinimumSelectedSize().width();
-
- *unselected_width = min_unselected_width;
- *selected_width = min_selected_width;
-
- if (tab_count == 0) {
- // Return immediately to avoid divide-by-zero below.
- return;
- }
-
- // Determine how much space we can actually allocate to tabs.
- int available_width;
- if (available_width_for_tabs_ < 0) {
- available_width = width();
- available_width -= (kNewTabButtonHOffset + newtab_button_bounds_.width());
- } else {
- // Interesting corner case: if |available_width_for_tabs_| > the result
- // of the calculation in the conditional arm above, the strip is in
- // overflow. We can either use the specified width or the true available
- // width here; the first preserves the consistent "leave the last tab under
- // the user's mouse so they can close many tabs" behavior at the cost of
- // prolonging the glitchy appearance of the overflow state, while the second
- // gets us out of overflow as soon as possible but forces the user to move
- // their mouse for a few tabs' worth of closing. We choose visual
- // imperfection over behavioral imperfection and select the first option.
- available_width = available_width_for_tabs_;
- }
-
- if (mini_tab_count > 0) {
- available_width -= mini_tab_count * (Tab::GetMiniWidth() + kTabHOffset);
- tab_count -= mini_tab_count;
- if (tab_count == 0) {
- *selected_width = *unselected_width = Tab::GetStandardSize().width();
- return;
- }
- // Account for gap between the last mini-tab and first non-mini-tab.
- available_width -= mini_to_non_mini_gap_;
- }
-
- // Calculate the desired tab widths by dividing the available space into equal
- // portions. Don't let tabs get larger than the "standard width" or smaller
- // than the minimum width for each type, respectively.
- const int total_offset = kTabHOffset * (tab_count - 1);
- const double desired_tab_width = std::min((static_cast<double>(
- available_width - total_offset) / static_cast<double>(tab_count)),
- static_cast<double>(Tab::GetStandardSize().width()));
- *unselected_width = std::max(desired_tab_width, min_unselected_width);
- *selected_width = std::max(desired_tab_width, min_selected_width);
-
- // When there are multiple tabs, we'll have one selected and some unselected
- // tabs. If the desired width was between the minimum sizes of these types,
- // try to shrink the tabs with the smaller minimum. For example, if we have
- // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5. If
- // selected tabs have a minimum width of 4 and unselected tabs have a minimum
- // width of 1, the above code would set *unselected_width = 2.5,
- // *selected_width = 4, which results in a total width of 11.5. Instead, we
- // want to set *unselected_width = 2, *selected_width = 4, for a total width
- // of 10.
- if (tab_count > 1) {
- if ((min_unselected_width < min_selected_width) &&
- (desired_tab_width < min_selected_width)) {
- // Unselected width = (total width - selected width) / (num_tabs - 1)
- *unselected_width = std::max(static_cast<double>(
- available_width - total_offset - min_selected_width) /
- static_cast<double>(tab_count - 1), min_unselected_width);
- } else if ((min_unselected_width > min_selected_width) &&
- (desired_tab_width < min_unselected_width)) {
- // Selected width = (total width - (unselected width * (num_tabs - 1)))
- *selected_width = std::max(available_width - total_offset -
- (min_unselected_width * (tab_count - 1)), min_selected_width);
- }
- }
-}
-
-void TabStrip::ResizeLayoutTabs() {
- // We've been called back after the TabStrip has been emptied out (probably
- // just prior to the window being destroyed). We need to do nothing here or
- // else GetTabAt below will crash.
- if (tab_count() == 0)
- return;
-
- // It is critically important that this is unhooked here, otherwise we will
- // keep spying on messages forever.
- RemoveMessageLoopObserver();
-
- in_tab_close_ = false;
- available_width_for_tabs_ = -1;
- int mini_tab_count = GetMiniTabCount();
- if (mini_tab_count == tab_count()) {
- // Only mini-tabs, we know the tab widths won't have changed (all
- // mini-tabs have the same width), so there is nothing to do.
- return;
- }
- Tab* first_tab = GetTabAtTabDataIndex(mini_tab_count);
- double unselected, selected;
- GetDesiredTabWidths(tab_count(), mini_tab_count, &unselected, &selected);
- int w = Round(first_tab->IsSelected() ? selected : selected);
-
- // We only want to run the animation if we're not already at the desired
- // size.
- if (abs(first_tab->width() - w) > 1)
- StartResizeLayoutAnimation();
-}
-
-void TabStrip::AddMessageLoopObserver() {
- if (!mouse_watcher_.get()) {
- mouse_watcher_.reset(
- new views::MouseWatcher(this, this,
- gfx::Insets(0, 0, kTabStripAnimationVSlop, 0)));
- }
- mouse_watcher_->Start();
-}
-
-void TabStrip::RemoveMessageLoopObserver() {
- mouse_watcher_.reset(NULL);
-}
-
-gfx::Rect TabStrip::GetDropBounds(int drop_index,
- bool drop_before,
- bool* is_beneath) {
- DCHECK(drop_index != -1);
- int center_x;
- if (drop_index < tab_count()) {
- Tab* tab = GetTabAtTabDataIndex(drop_index);
- if (drop_before)
- center_x = tab->x() - (kTabHOffset / 2);
- else
- center_x = tab->x() + (tab->width() / 2);
- } else {
- Tab* last_tab = GetTabAtTabDataIndex(drop_index - 1);
- center_x = last_tab->x() + last_tab->width() + (kTabHOffset / 2);
- }
-
- // Mirror the center point if necessary.
- center_x = MirroredXCoordinateInsideView(center_x);
-
- // Determine the screen bounds.
- gfx::Point drop_loc(center_x - drop_indicator_width / 2,
- -drop_indicator_height);
- ConvertPointToScreen(this, &drop_loc);
- gfx::Rect drop_bounds(drop_loc.x(), drop_loc.y(), drop_indicator_width,
- drop_indicator_height);
-
- // If the rect doesn't fit on the monitor, push the arrow to the bottom.
-#if defined(OS_WIN)
- gfx::Rect monitor_bounds = win_util::GetMonitorBoundsForRect(drop_bounds);
- *is_beneath = (monitor_bounds.IsEmpty() ||
- !monitor_bounds.Contains(drop_bounds));
-#else
- *is_beneath = false;
- NOTIMPLEMENTED();
-#endif
- if (*is_beneath)
- drop_bounds.Offset(0, drop_bounds.height() + height());
-
- return drop_bounds;
-}
-
-void TabStrip::UpdateDropIndex(const DropTargetEvent& event) {
- // If the UI layout is right-to-left, we need to mirror the mouse
- // coordinates since we calculate the drop index based on the
- // original (and therefore non-mirrored) positions of the tabs.
- const int x = MirroredXCoordinateInsideView(event.x());
- // We don't allow replacing the urls of mini-tabs.
- for (int i = GetMiniTabCount(); i < tab_count(); ++i) {
- Tab* tab = GetTabAtTabDataIndex(i);
- const int tab_max_x = tab->x() + tab->width();
- const int hot_width = tab->width() / 3;
- if (x < tab_max_x) {
- if (x < tab->x() + hot_width)
- SetDropIndex(i, true);
- else if (x >= tab_max_x - hot_width)
- SetDropIndex(i + 1, true);
- else
- SetDropIndex(i, false);
- return;
- }
- }
-
- // The drop isn't over a tab, add it to the end.
- SetDropIndex(tab_count(), true);
-}
-
-void TabStrip::SetDropIndex(int tab_data_index, bool drop_before) {
- if (tab_data_index == -1) {
- if (drop_info_.get())
- drop_info_.reset(NULL);
- return;
- }
-
- if (drop_info_.get() && drop_info_->drop_index == tab_data_index &&
- drop_info_->drop_before == drop_before) {
- return;
- }
-
- bool is_beneath;
- gfx::Rect drop_bounds = GetDropBounds(tab_data_index, drop_before,
- &is_beneath);
-
- if (!drop_info_.get()) {
- drop_info_.reset(new DropInfo(tab_data_index, drop_before, !is_beneath));
- } else {
- drop_info_->drop_index = tab_data_index;
- drop_info_->drop_before = drop_before;
- if (is_beneath == drop_info_->point_down) {
- drop_info_->point_down = !is_beneath;
- drop_info_->arrow_view->SetImage(
- GetDropArrowImage(drop_info_->point_down));
- }
- }
-
- // Reposition the window. Need to show it too as the window is initially
- // hidden.
-
-#if defined(OS_WIN)
- drop_info_->arrow_window->SetWindowPos(
- HWND_TOPMOST, drop_bounds.x(), drop_bounds.y(), drop_bounds.width(),
- drop_bounds.height(), SWP_NOACTIVATE | SWP_SHOWWINDOW);
-#else
- drop_info_->arrow_window->SetBounds(drop_bounds);
- drop_info_->arrow_window->Show();
-#endif
-}
-
-int TabStrip::GetDropEffect(const views::DropTargetEvent& event) {
- const int source_ops = event.GetSourceOperations();
- if (source_ops & DragDropTypes::DRAG_COPY)
- return DragDropTypes::DRAG_COPY;
- if (source_ops & DragDropTypes::DRAG_LINK)
- return DragDropTypes::DRAG_LINK;
- return DragDropTypes::DRAG_MOVE;
-}
-
-// static
-SkBitmap* TabStrip::GetDropArrowImage(bool is_down) {
- return ResourceBundle::GetSharedInstance().GetBitmapNamed(
- is_down ? IDR_TAB_DROP_DOWN : IDR_TAB_DROP_UP);
-}
-
-// TabStrip::DropInfo ----------------------------------------------------------
-
-TabStrip::DropInfo::DropInfo(int drop_index, bool drop_before, bool point_down)
- : drop_index(drop_index),
- drop_before(drop_before),
- point_down(point_down) {
- arrow_view = new views::ImageView;
- arrow_view->SetImage(GetDropArrowImage(point_down));
-
-#if defined(OS_WIN)
- arrow_window = new views::WidgetWin;
- arrow_window->set_window_style(WS_POPUP);
- arrow_window->set_window_ex_style(WS_EX_TOPMOST | WS_EX_NOACTIVATE |
- WS_EX_LAYERED | WS_EX_TRANSPARENT);
-#else
- arrow_window = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP);
- arrow_window->MakeTransparent();
-#endif
- arrow_window->Init(
- NULL,
- gfx::Rect(0, 0, drop_indicator_width, drop_indicator_height));
- arrow_window->SetContentsView(arrow_view);
-}
-
-TabStrip::DropInfo::~DropInfo() {
- // Close eventually deletes the window, which deletes arrow_view too.
- arrow_window->Close();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// Called from:
-// - BasicLayout
-// - Tab insertion/removal
-// - Tab reorder
-void TabStrip::GenerateIdealBounds() {
- int non_closing_tab_count = 0;
- int mini_tab_count = 0;
- for (int i = 0; i < tab_count(); ++i) {
- BaseTab* tab = base_tab_at_tab_index(i);
- if (!tab->closing()) {
- ++non_closing_tab_count;
- if (tab->data().mini)
- mini_tab_count++;
- }
- }
-
- double unselected, selected;
- GetDesiredTabWidths(non_closing_tab_count, mini_tab_count, &unselected,
- &selected);
-
- current_unselected_width_ = unselected;
- current_selected_width_ = selected;
-
- // NOTE: This currently assumes a tab's height doesn't differ based on
- // selected state or the number of tabs in the strip!
- int tab_height = Tab::GetStandardSize().height();
- double tab_x = 0;
- bool last_was_mini = false;
- for (int i = 0; i < tab_count(); ++i) {
- Tab* tab = GetTabAtTabDataIndex(i);
- if (!tab->closing()) {
- double tab_width = unselected;
- if (tab->data().mini) {
- tab_width = Tab::GetMiniWidth();
- } else {
- if (last_was_mini) {
- // Give a bigger gap between mini and non-mini tabs.
- tab_x += mini_to_non_mini_gap_;
- }
- if (tab->IsSelected())
- tab_width = selected;
- }
- double end_of_tab = tab_x + tab_width;
- int rounded_tab_x = Round(tab_x);
- set_ideal_bounds(i,
- gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x,
- tab_height));
- tab_x = end_of_tab + kTabHOffset;
- last_was_mini = tab->data().mini;
- }
- }
-
- // Update bounds of new tab button.
- int new_tab_x;
- int new_tab_y = browser_defaults::kSizeTabButtonToTopOfTabStrip ?
- 0 : kNewTabButtonVOffset;
- if (abs(Round(unselected) - Tab::GetStandardSize().width()) > 1 &&
- !in_tab_close_) {
- // We're shrinking tabs, so we need to anchor the New Tab button to the
- // right edge of the TabStrip's bounds, rather than the right edge of the
- // right-most Tab, otherwise it'll bounce when animating.
- new_tab_x = width() - newtab_button_bounds_.width();
- } else {
- new_tab_x = Round(tab_x - kTabHOffset) + kNewTabButtonHOffset;
- }
- newtab_button_bounds_.set_origin(gfx::Point(new_tab_x, new_tab_y));
-}
-
-void TabStrip::StartResizeLayoutAnimation() {
- PrepareForAnimation();
- GenerateIdealBounds();
- AnimateToIdealBounds();
-}
-
-void TabStrip::StartMiniTabAnimation() {
- in_tab_close_ = false;
- available_width_for_tabs_ = -1;
-
- PrepareForAnimation();
-
- GenerateIdealBounds();
- AnimateToIdealBounds();
-}
-
-void TabStrip::StartMouseInitiatedRemoveTabAnimation(int model_index) {
- // The user initiated the close. We want to persist the bounds of all the
- // existing tabs, so we manually shift ideal_bounds then animate.
- int tab_data_index = ModelIndexToTabIndex(model_index);
- DCHECK(tab_data_index != tab_count());
- BaseTab* tab_closing = base_tab_at_tab_index(tab_data_index);
- int delta = tab_closing->width() + kTabHOffset;
- if (tab_closing->data().mini && model_index + 1 < GetModelCount() &&
- !GetBaseTabAtModelIndex(model_index + 1)->data().mini) {
- delta += mini_to_non_mini_gap_;
- }
-
- for (int i = tab_data_index + 1; i < tab_count(); ++i) {
- BaseTab* tab = base_tab_at_tab_index(i);
- if (!tab->closing()) {
- gfx::Rect bounds = ideal_bounds(i);
- bounds.set_x(bounds.x() - delta);
- set_ideal_bounds(i, bounds);
- }
- }
-
- newtab_button_bounds_.set_x(newtab_button_bounds_.x() - delta);
-
- PrepareForAnimation();
-
- // Mark the tab as closing.
- tab_closing->set_closing(true);
-
- AnimateToIdealBounds();
-
- gfx::Rect tab_bounds = tab_closing->bounds();
- if (type() == HORIZONTAL_TAB_STRIP)
- tab_bounds.set_width(0);
- else
- tab_bounds.set_height(0);
- bounds_animator().AnimateViewTo(tab_closing, tab_bounds);
-
- // Register delegate to do cleanup when done, BoundsAnimator takes
- // ownership of RemoveTabDelegate.
- bounds_animator().SetAnimationDelegate(tab_closing,
- CreateRemoveTabDelegate(tab_closing),
- true);
-}
-
-void TabStrip::StopAnimating(bool layout) {
- if (!IsAnimating())
- return;
-
- bounds_animator().Cancel();
-
- DCHECK(!IsAnimating());
-
- if (layout)
- DoLayout();
-}
-
-int TabStrip::GetMiniTabCount() const {
- int mini_count = 0;
- for (int i = 0; i < tab_count(); ++i) {
- if (base_tab_at_tab_index(i)->data().mini)
- mini_count++;
- else
- return mini_count;
- }
- return mini_count;
-}
-
-int TabStrip::GetAvailableWidthForTabs(Tab* last_tab) const {
- return last_tab->x() + last_tab->width();
-}
-
-bool TabStrip::IsPointInTab(Tab* tab,
- const gfx::Point& point_in_tabstrip_coords) {
- gfx::Point point_in_tab_coords(point_in_tabstrip_coords);
- View::ConvertPointToView(this, tab, &point_in_tab_coords);
- return tab->HitTest(point_in_tab_coords);
-}
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index f7ec80fd..4c24f8c 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -6,282 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_
#pragma once
-#include "app/animation_container.h"
-#include "base/ref_counted.h"
-#include "base/timer.h"
-#include "chrome/browser/views/tabs/base_tab_strip.h"
-#include "gfx/point.h"
-#include "gfx/rect.h"
-#include "views/controls/button/image_button.h"
-#include "views/mouse_watcher.h"
-
-class Tab;
-
-namespace views {
-class ImageView;
-#if defined(OS_LINUX)
-class WidgetGtk;
-#elif defined(OS_WIN)
-class WidgetWin;
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// TabStrip
-//
-// A View that represents the TabStripModel. The TabStrip has the
-// following responsibilities:
-// - It implements the TabStripModelObserver interface, and acts as a
-// container for Tabs, and is also responsible for creating them.
-// - It takes part in Tab Drag & Drop with Tab, TabDragHelper and
-// DraggedTab, focusing on tasks that require reshuffling other tabs
-// in response to dragged tabs.
-//
-///////////////////////////////////////////////////////////////////////////////
-class TabStrip : public BaseTabStrip,
- public views::ButtonListener,
- public views::MouseWatcherListener {
- public:
- explicit TabStrip(TabStripController* controller);
- virtual ~TabStrip();
-
- // Creates the new tab button.
- void InitTabStripButtons();
-
- // Returns the bounds of the new tab button.
- gfx::Rect GetNewTabButtonBounds();
-
- // MouseWatcherListener overrides:
- virtual void MouseMovedOutOfView();
-
- // BaseTabStrip implementation:
- virtual int GetPreferredHeight();
- virtual void SetBackgroundOffset(const gfx::Point& offset);
- virtual bool IsPositionInWindowCaption(const gfx::Point& point);
- virtual void SetDraggedTabBounds(int tab_index,
- const gfx::Rect& tab_bounds);
- virtual TabStrip* AsTabStrip();
- virtual void PrepareForCloseAt(int model_index);
- 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 StartHighlight(int model_index);
- virtual void StopAllHighlighting();
- virtual BaseTab* CreateTabForDragging();
-
- // views::View overrides:
- virtual void PaintChildren(gfx::Canvas* canvas);
- virtual views::View* GetViewByID(int id) const;
- virtual gfx::Size GetPreferredSize();
- // NOTE: the drag and drop methods are invoked from FrameView. This is done to
- // allow for a drop region that extends outside the bounds of the TabStrip.
- virtual void OnDragEntered(const views::DropTargetEvent& event);
- virtual int OnDragUpdated(const views::DropTargetEvent& event);
- virtual void OnDragExited();
- virtual int OnPerformDrop(const views::DropTargetEvent& event);
- virtual AccessibilityTypes::Role GetAccessibleRole();
- virtual views::View* GetViewForPoint(const gfx::Point& point);
- virtual void OnThemeChanged();
-
- protected:
- // BaseTabStrip overrides:
- virtual BaseTab* CreateTab();
- virtual void StartInsertTabAnimation(int model_index, bool foreground);
- virtual void StartMoveTabAnimation();
- virtual void AnimateToIdealBounds();
- virtual bool ShouldHighlightCloseButtonAfterRemove();
- virtual void DoLayout();
-
- // views::View implementation:
- virtual void ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child);
-
- // TabController overrides.
- virtual bool IsTabSelected(const BaseTab* btr) const;
-
- // views::ButtonListener implementation:
- virtual void ButtonPressed(views::Button* sender, const views::Event& event);
-
- // Horizontal gap between mini and non-mini-tabs.
- static const int mini_to_non_mini_gap_;
-
- private:
- friend class DraggedTabController;
-
- // Used during a drop session of a url. Tracks the position of the drop as
- // well as a window used to highlight where the drop occurs.
- struct DropInfo {
- DropInfo(int index, bool drop_before, bool paint_down);
- ~DropInfo();
-
- // Index of the tab to drop on. If drop_before is true, the drop should
- // occur between the tab at drop_index - 1 and drop_index.
- // WARNING: if drop_before is true it is possible this will == tab_count,
- // which indicates the drop should create a new tab at the end of the tabs.
- int drop_index;
- bool drop_before;
-
- // Direction the arrow should point in. If true, the arrow is displayed
- // above the tab and points down. If false, the arrow is displayed beneath
- // the tab and points up.
- bool point_down;
-
- // Renders the drop indicator.
- // TODO(beng): should be views::Widget.
-#if defined(OS_WIN)
- views::WidgetWin* arrow_window;
-#else
- views::WidgetGtk* arrow_window;
-#endif
- views::ImageView* arrow_view;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(DropInfo);
- };
-
- void Init();
-
- // Set the images for the new tab button.
- void LoadNewTabButtonImage();
-
- // Retrieves the Tab at the specified index. Remember, the specified index
- // is in terms of tab_data, *not* the model.
- Tab* GetTabAtTabDataIndex(int tab_data_index) const;
-
- // Returns the tab at the specified index. If a remove animation is on going
- // and the index is >= the index of the tab being removed, the index is
- // incremented. While a remove operation is on going the indices of the model
- // do not line up with the indices of the view. This method adjusts the index
- // accordingly.
- //
- // Use this instead of GetTabAtTabDataIndex if the index comes from the model.
- Tab* GetTabAtModelIndex(int model_index) const;
-
- // Returns the number of mini-tabs.
- int GetMiniTabCount() const;
-
- // -- Tab Resize Layout -----------------------------------------------------
-
- // Returns the exact (unrounded) current width of each tab.
- void GetCurrentTabWidths(double* unselected_width,
- double* selected_width) const;
-
- // Returns the exact (unrounded) desired width of each tab, based on the
- // desired strip width and number of tabs. If
- // |width_of_tabs_for_mouse_close_| is nonnegative we use that value in
- // calculating the desired strip width; otherwise we use the current width.
- // |mini_tab_count| gives the number of mini-tabs and |tab_count| the number
- // of mini and non-mini-tabs.
- void GetDesiredTabWidths(int tab_count,
- int mini_tab_count,
- double* unselected_width,
- double* selected_width) const;
-
- // Perform an animated resize-relayout of the TabStrip immediately.
- void ResizeLayoutTabs();
-
- // Ensure that the message loop observer used for event spying is added and
- // removed appropriately so we can tell when to resize layout the tab strip.
- void AddMessageLoopObserver();
- void RemoveMessageLoopObserver();
-
- // -- Link Drag & Drop ------------------------------------------------------
-
- // Returns the bounds to render the drop at, in screen coordinates. Sets
- // |is_beneath| to indicate whether the arrow is beneath the tab, or above
- // it.
- gfx::Rect GetDropBounds(int drop_index, bool drop_before, bool* is_beneath);
-
- // Updates the location of the drop based on the event.
- void UpdateDropIndex(const views::DropTargetEvent& event);
-
- // Sets the location of the drop, repainting as necessary.
- void SetDropIndex(int tab_data_index, bool drop_before);
-
- // Returns the drop effect for dropping a URL on the tab strip. This does
- // not query the data in anyway, it only looks at the source operations.
- int GetDropEffect(const views::DropTargetEvent& event);
-
- // Returns the image to use for indicating a drop on a tab. If is_down is
- // true, this returns an arrow pointing down.
- static SkBitmap* GetDropArrowImage(bool is_down);
-
- // -- Animations ------------------------------------------------------------
-
- // Generates the ideal bounds of the TabStrip when all Tabs have finished
- // animating to their desired position/bounds. This is used by the standard
- // Layout method and other callers like the DraggedTabController that need
- // stable representations of Tab positions.
- void GenerateIdealBounds();
-
- // Starts various types of TabStrip animations.
- void StartResizeLayoutAnimation();
- void StartMoveTabAnimation(int from_model_index,
- int to_model_index);
- void StartMiniTabAnimation();
- void StartMouseInitiatedRemoveTabAnimation(int model_index);
-
- // Stops any ongoing animations. If |layout| is true and an animation is
- // ongoing this does a layout.
- virtual void StopAnimating(bool layout);
-
- // Calculates the available width for tabs, assuming a Tab is to be closed.
- int GetAvailableWidthForTabs(Tab* last_tab) const;
-
- // Returns true if the specified point in TabStrip coords is within the
- // hit-test region of the specified Tab.
- bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords);
-
- // -- Member Variables ------------------------------------------------------
-
- // The "New Tab" button.
- views::ImageButton* newtab_button_;
-
- // Ideal bounds of the new tab button.
- gfx::Rect newtab_button_bounds_;
-
- // The current widths of various types of tabs. We save these so that, as
- // users close tabs while we're holding them at the same size, we can lay out
- // tabs exactly and eliminate the "pixel jitter" we'd get from just leaving
- // them all at their existing, rounded widths.
- double current_unselected_width_;
- double current_selected_width_;
-
- // If this value is nonnegative, it is used in GetDesiredTabWidths() to
- // calculate how much space in the tab strip to use for tabs. Most of the
- // time this will be -1, but while we're handling closing a tab via the mouse,
- // we'll set this to the edge of the last tab before closing, so that if we
- // are closing the last tab and need to resize immediately, we'll resize only
- // back to this width, thus once again placing the last tab under the mouse
- // cursor.
- int available_width_for_tabs_;
-
- // True if PrepareForCloseAt has been invoked. When true remove animations
- // preserve current tab bounds.
- bool in_tab_close_;
-
- // The size of the new tab button must be hardcoded because we need to be
- // able to lay it out before we are able to get its image from the
- // ThemeProvider. It also makes sense to do this, because the size of the
- // new tab button should not need to be calculated dynamically.
- static const int kNewTabButtonWidth = 28;
- static const int kNewTabButtonHeight = 18;
-
- // Valid for the lifetime of a drag over us.
- scoped_ptr<DropInfo> drop_info_;
-
- // To ensure all tabs pulse at the same time they share the same animation
- // container. This is that animation container.
- scoped_refptr<AnimationContainer> animation_container_;
-
- // Used for stage 1 of new tab animation.
- base::OneShotTimer<TabStrip> new_tab_timer_;
-
- scoped_ptr<views::MouseWatcher> mouse_watcher_;
-
- DISALLOW_COPY_AND_ASSIGN(TabStrip);
-};
+#include "chrome/browser/ui/views/tabs/tab_strip.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_
+
diff --git a/chrome/browser/views/tabs/tab_strip_controller.h b/chrome/browser/views/tabs/tab_strip_controller.h
index bd52452..b0c7be9 100644
--- a/chrome/browser/views/tabs/tab_strip_controller.h
+++ b/chrome/browser/views/tabs/tab_strip_controller.h
@@ -6,68 +6,8 @@
#define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_
#pragma once
-class BaseTab;
-class BaseTabStrip;
-class GURL;
-
-namespace gfx {
-class Point;
-}
-
-// Model/Controller for the TabStrip.
-// NOTE: All indices used by this class are in model coordinates.
-class TabStripController {
- public:
- virtual ~TabStripController() {}
-
- // Returns the number of tabs in the model.
- virtual int GetCount() const = 0;
-
- // Returns true if |index| is a valid model index.
- virtual bool IsValidIndex(int index) const = 0;
-
- // Returns the selected index, in terms of the model.
- virtual int GetSelectedIndex() const = 0;
-
- // Returns true if the selected index is selected.
- virtual bool IsTabSelected(int index) const = 0;
-
- // Returns true if the selected index is pinned.
- virtual bool IsTabPinned(int index) const = 0;
-
- // Returns true if the selected index is closeable.
- virtual bool IsTabCloseable(int index) const = 0;
-
- // Returns true if the selected index is the new tab page.
- virtual bool IsNewTabPage(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;
-
- // Shows a context menu for the tab at the specified point in screen coords.
- virtual void ShowContextMenu(BaseTab* tab, const gfx::Point& p) = 0;
-
- // Updates the loading animations of all the tabs.
- virtual void UpdateLoadingAnimations() = 0;
-
- // Returns true if the associated TabStrip's delegate supports tab moving or
- // detaching. Used by the Frame to determine if dragging on the Tab
- // itself should move the window in cases where there's only one
- // non drag-able Tab.
- virtual int HasAvailableDragActions() const = 0;
-
- // Performans a drop at the specified location.
- virtual void PerformDrop(bool drop_before, int index, const GURL& url) = 0;
-
- // Return true if this tab strip is compatible with the provided tab strip.
- // Compatible tab strips can transfer tabs during drag and drop.
- virtual bool IsCompatibleWith(BaseTabStrip* other) const = 0;
-
- // Creates the new tab.
- virtual void CreateNewTab() = 0;
-};
+#include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
+// TODO(beng): remove this file once all includes have been updated.
#endif // CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_
+