tab_strip.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_ 6#define CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_ 7 8#include <vector> 9 10#include "base/compiler_specific.h" 11#include "base/memory/ref_counted.h" 12#include "base/timer/timer.h" 13#include "chrome/browser/ui/views/tabs/tab.h" 14#include "chrome/browser/ui/views/tabs/tab_controller.h" 15#include "ui/gfx/animation/animation_container.h" 16#include "ui/gfx/point.h" 17#include "ui/gfx/rect.h" 18#include "ui/views/animation/bounds_animator.h" 19#include "ui/views/controls/button/image_button.h" 20#include "ui/views/mouse_watcher.h" 21#include "ui/views/view.h" 22#include "ui/views/view_model.h" 23 24class NewTabButton; 25class StackedTabStripLayout; 26class Tab; 27class TabDragController; 28class TabStripController; 29class TabStripObserver; 30 31namespace ui { 32class ListSelectionModel; 33} 34 35namespace views { 36class ImageView; 37} 38 39/////////////////////////////////////////////////////////////////////////////// 40// 41// TabStrip 42// 43// A View that represents the TabStripModel. The TabStrip has the 44// following responsibilities: 45// - It implements the TabStripModelObserver interface, and acts as a 46// container for Tabs, and is also responsible for creating them. 47// - It takes part in Tab Drag & Drop with Tab, TabDragHelper and 48// DraggedTab, focusing on tasks that require reshuffling other tabs 49// in response to dragged tabs. 50// 51/////////////////////////////////////////////////////////////////////////////// 52class TabStrip : public views::View, 53 public views::ButtonListener, 54 public views::MouseWatcherListener, 55 public TabController { 56 public: 57 static const char kViewClassName[]; 58 59 explicit TabStrip(TabStripController* controller); 60 virtual ~TabStrip(); 61 62 // Add and remove observers to changes within this TabStrip. 63 void AddObserver(TabStripObserver* observer); 64 void RemoveObserver(TabStripObserver* observer); 65 66 // If |adjust_layout| is true the stacked layout changes based on whether the 67 // user uses a mouse or a touch device with the tabstrip. 68 void set_adjust_layout(bool adjust_layout) { adjust_layout_ = adjust_layout; } 69 70 // |stacked_layout_| defines what should happen when the tabs won't fit at 71 // their ideal size. When |stacked_layout_| is true the tabs are always sized 72 // to their ideal size and stacked on top of each other so that only a certain 73 // set of tabs are visible. This is used when the user uses a touch device. 74 // When |stacked_layout_| is false the tabs shrink to accommodate the 75 // available space. This is the default. 76 bool stacked_layout() const { return stacked_layout_; } 77 78 // Sets |stacked_layout_| and animates if necessary. 79 void SetStackedLayout(bool stacked_layout); 80 81 // Returns the bounds of the new tab button. 82 gfx::Rect GetNewTabButtonBounds(); 83 84 // Returns true if the new tab button should be sized to the top of the tab 85 // strip. 86 bool SizeTabButtonToTopOfTabStrip(); 87 88 // Starts highlighting the tab at the specified index. 89 void StartHighlight(int model_index); 90 91 // Stops all tab higlighting. 92 void StopAllHighlighting(); 93 94 // Adds a tab at the specified index. 95 void AddTabAt(int model_index, const TabRendererData& data, bool is_active); 96 97 // Moves a tab. 98 void MoveTab(int from_model_index, 99 int to_model_index, 100 const TabRendererData& data); 101 102 // Removes a tab at the specified index. 103 void RemoveTabAt(int model_index); 104 105 // Sets the tab data at the specified model index. 106 void SetTabData(int model_index, const TabRendererData& data); 107 108 // Invoked from the controller when the close initiates from the TabController 109 // (the user clicked the tab close button or middle clicked the tab). This is 110 // invoked from Close. Because of unload handlers Close is not always 111 // immediately followed by RemoveTabAt. 112 void PrepareForCloseAt(int model_index, CloseTabSource source); 113 114 // Invoked when the selection changes from |old_selection| to 115 // |new_selection|. 116 void SetSelection(const ui::ListSelectionModel& old_selection, 117 const ui::ListSelectionModel& new_selection); 118 119 // Invoked when the title of a tab changes and the tab isn't loading. 120 void TabTitleChangedNotLoading(int model_index); 121 122 // Retrieves the ideal bounds for the Tab at the specified index. 123 const gfx::Rect& ideal_bounds(int tab_data_index) { 124 return tabs_.ideal_bounds(tab_data_index); 125 } 126 127 // Returns the Tab at |index|. 128 Tab* tab_at(int index) const; 129 130 // Returns the index of the specified tab in the model coordinate system, or 131 // -1 if tab is closing or not valid. 132 int GetModelIndexOfTab(const Tab* tab) const; 133 134 // Gets the number of Tabs in the tab strip. 135 int tab_count() const { return tabs_.view_size(); } 136 137 // Cover method for TabStripController::GetCount. 138 int GetModelCount() const; 139 140 // Cover method for TabStripController::IsValidIndex. 141 bool IsValidModelIndex(int model_index) const; 142 143 TabStripController* controller() const { return controller_.get(); } 144 145 // Returns true if a drag session is currently active. 146 bool IsDragSessionActive() const; 147 148 // Returns true if a tab is being dragged into this tab strip. 149 bool IsActiveDropTarget() const; 150 151 // Returns true if the tab strip is editable. Returns false if the tab strip 152 // is being dragged or animated to prevent extensions from messing things up 153 // while that's happening. 154 bool IsTabStripEditable() const; 155 156 // Returns false when there is a drag operation in progress so that the frame 157 // doesn't close. 158 bool IsTabStripCloseable() const; 159 160 // Updates the loading animations displayed by tabs in the tabstrip to the 161 // next frame. 162 void UpdateLoadingAnimations(); 163 164 // Returns true if the specified point (in TabStrip coordinates) is in the 165 // window caption area of the browser window. 166 bool IsPositionInWindowCaption(const gfx::Point& point); 167 168 // Returns true if the specified rect (in TabStrip coordinates) intersects 169 // the window caption area of the browser window. 170 bool IsRectInWindowCaption(const gfx::Rect& rect); 171 172 // Set the background offset used by inactive tabs to match the frame image. 173 void SetBackgroundOffset(const gfx::Point& offset); 174 175 // Returns the new tab button. This is never NULL. 176 views::View* newtab_button(); 177 178 // Sets a painting style with miniature "tab indicator" rectangles at the top. 179 void SetImmersiveStyle(bool enable); 180 181 // Returns true if Tabs in this TabStrip are currently changing size or 182 // position. 183 bool IsAnimating() const; 184 185 // Stops any ongoing animations. If |layout| is true and an animation is 186 // ongoing this does a layout. 187 void StopAnimating(bool layout); 188 189 // Called to indicate whether the given URL is a supported file. 190 void FileSupported(const GURL& url, bool supported); 191 192 // TabController overrides: 193 virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE; 194 virtual bool SupportsMultipleSelection() OVERRIDE; 195 virtual void SelectTab(Tab* tab) OVERRIDE; 196 virtual void ExtendSelectionTo(Tab* tab) OVERRIDE; 197 virtual void ToggleSelected(Tab* tab) OVERRIDE; 198 virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE; 199 virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE; 200 virtual void ShowContextMenuForTab(Tab* tab, 201 const gfx::Point& p, 202 ui::MenuSourceType source_type) OVERRIDE; 203 virtual bool IsActiveTab(const Tab* tab) const OVERRIDE; 204 virtual bool IsTabSelected(const Tab* tab) const OVERRIDE; 205 virtual bool IsTabPinned(const Tab* tab) const OVERRIDE; 206 virtual void MaybeStartDrag( 207 Tab* tab, 208 const ui::LocatedEvent& event, 209 const ui::ListSelectionModel& original_selection) OVERRIDE; 210 virtual void ContinueDrag(views::View* view, 211 const ui::LocatedEvent& event) OVERRIDE; 212 virtual bool EndDrag(EndDragReason reason) OVERRIDE; 213 virtual Tab* GetTabAt(Tab* tab, 214 const gfx::Point& tab_in_tab_coordinates) OVERRIDE; 215 virtual void OnMouseEventInTab(views::View* source, 216 const ui::MouseEvent& event) OVERRIDE; 217 virtual bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) OVERRIDE; 218 virtual bool IsImmersiveStyle() const OVERRIDE; 219 220 // MouseWatcherListener overrides: 221 virtual void MouseMovedOutOfHost() OVERRIDE; 222 223 // views::View overrides: 224 virtual void Layout() OVERRIDE; 225 virtual void PaintChildren(gfx::Canvas* canvas, 226 const views::CullSet& cull_set) OVERRIDE; 227 virtual const char* GetClassName() const OVERRIDE; 228 virtual gfx::Size GetPreferredSize() const OVERRIDE; 229 // NOTE: the drag and drop methods are invoked from FrameView. This is done 230 // to allow for a drop region that extends outside the bounds of the TabStrip. 231 virtual void OnDragEntered(const ui::DropTargetEvent& event) OVERRIDE; 232 virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE; 233 virtual void OnDragExited() OVERRIDE; 234 virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE; 235 virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE; 236 virtual views::View* GetEventHandlerForRect(const gfx::Rect& rect) OVERRIDE; 237 virtual views::View* GetTooltipHandlerForPoint( 238 const gfx::Point& point) OVERRIDE; 239 240 // Returns preferred height in immersive style. 241 static int GetImmersiveHeight(); 242 243 protected: 244 // Horizontal gap between mini and non-mini-tabs. 245 static const int kMiniToNonMiniGap; 246 247 void set_ideal_bounds(int index, const gfx::Rect& bounds) { 248 tabs_.set_ideal_bounds(index, bounds); 249 } 250 251 // Returns the number of mini-tabs. 252 int GetMiniTabCount() const; 253 254 // views::ButtonListener implementation: 255 virtual void ButtonPressed(views::Button* sender, 256 const ui::Event& event) OVERRIDE; 257 258 // View overrides. 259 virtual const views::View* GetViewByID(int id) const OVERRIDE; 260 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE; 261 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE; 262 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE; 263 virtual void OnMouseCaptureLost() OVERRIDE; 264 virtual void OnMouseMoved(const ui::MouseEvent& event) OVERRIDE; 265 virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; 266 267 // ui::EventHandler overrides. 268 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; 269 270 private: 271 typedef std::map<int, std::vector<Tab*> > TabsClosingMap; 272 273 class RemoveTabDelegate; 274 275 friend class TabDragController; 276 friend class TabDragControllerTest; 277 FRIEND_TEST_ALL_PREFIXES(TabDragControllerTest, GestureEndShouldEndDragTest); 278 friend class TabStripTest; 279 FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabHitTestMaskWhenStacked); 280 FRIEND_TEST_ALL_PREFIXES(TabStripTest, ClippedTabCloseButton); 281 282 // Used during a drop session of a url. Tracks the position of the drop as 283 // well as a window used to highlight where the drop occurs. 284 struct DropInfo { 285 DropInfo(int drop_index, 286 bool drop_before, 287 bool point_down, 288 views::Widget* context); 289 ~DropInfo(); 290 291 // Index of the tab to drop on. If drop_before is true, the drop should 292 // occur between the tab at drop_index - 1 and drop_index. 293 // WARNING: if drop_before is true it is possible this will == tab_count, 294 // which indicates the drop should create a new tab at the end of the tabs. 295 int drop_index; 296 bool drop_before; 297 298 // Direction the arrow should point in. If true, the arrow is displayed 299 // above the tab and points down. If false, the arrow is displayed beneath 300 // the tab and points up. 301 bool point_down; 302 303 // Renders the drop indicator. 304 views::Widget* arrow_window; 305 views::ImageView* arrow_view; 306 307 // The URL for the drop event. 308 GURL url; 309 310 // Whether the MIME type of the file pointed to by |url| is supported. 311 bool file_supported; 312 313 private: 314 DISALLOW_COPY_AND_ASSIGN(DropInfo); 315 }; 316 317 void Init(); 318 319 // Creates and returns a new tab. The caller owners the returned tab. 320 Tab* CreateTab(); 321 322 // Invoked from |AddTabAt| after the newly created tab has been inserted. 323 void StartInsertTabAnimation(int model_index); 324 325 // Invoked from |MoveTab| after |tab_data_| has been updated to animate the 326 // move. 327 void StartMoveTabAnimation(); 328 329 // Starts the remove tab animation. 330 void StartRemoveTabAnimation(int model_index); 331 332 // Schedules the animations and bounds changes necessary for a remove tab 333 // animation. 334 void ScheduleRemoveTabAnimation(Tab* tab); 335 336 // Animates all the views to their ideal bounds. 337 // NOTE: this does *not* invoke GenerateIdealBounds, it uses the bounds 338 // currently set in ideal_bounds. 339 void AnimateToIdealBounds(); 340 341 // Returns whether the highlight button should be highlighted after a remove. 342 bool ShouldHighlightCloseButtonAfterRemove(); 343 344 // Invoked from Layout if the size changes or layout is really needed. 345 void DoLayout(); 346 347 // Drags the active tab by |delta|. |initial_positions| is the x-coordinates 348 // of the tabs when the drag started. 349 void DragActiveTab(const std::vector<int>& initial_positions, int delta); 350 351 // Sets the ideal bounds x-coordinates to |positions|. 352 void SetIdealBoundsFromPositions(const std::vector<int>& positions); 353 354 // Stacks the dragged tabs. This is used if the drag operation is 355 // MOVE_VISIBILE_TABS and the tabs don't fill the tabstrip. When this happens 356 // the active tab follows the mouse and the other tabs stack around it. 357 void StackDraggedTabs(int delta); 358 359 // Returns true if dragging has resulted in temporarily stacking the tabs. 360 bool IsStackingDraggedTabs() const; 361 362 // Invoked during drag to layout the tabs being dragged in |tabs| at 363 // |location|. If |initial_drag| is true, this is the initial layout after the 364 // user moved the mouse far enough to trigger a drag. 365 void LayoutDraggedTabsAt(const std::vector<Tab*>& tabs, 366 Tab* active_tab, 367 const gfx::Point& location, 368 bool initial_drag); 369 370 // Calculates the bounds needed for each of the tabs, placing the result in 371 // |bounds|. 372 void CalculateBoundsForDraggedTabs(const std::vector<Tab*>& tabs, 373 std::vector<gfx::Rect>* bounds); 374 375 // Returns the size needed for the specified tabs. This is invoked during drag 376 // and drop to calculate offsets and positioning. 377 int GetSizeNeededForTabs(const std::vector<Tab*>& tabs); 378 379 // Adds the tab at |index| to |tabs_closing_map_| and removes the tab from 380 // |tabs_|. 381 void RemoveTabFromViewModel(int index); 382 383 // Cleans up the Tab from the TabStrip. This is called from the tab animation 384 // code and is not a general-purpose method. 385 void RemoveAndDeleteTab(Tab* tab); 386 387 // Adjusts the indices of all tabs in |tabs_closing_map_| whose index is 388 // >= |index| to have a new index of |index + delta|. 389 void UpdateTabsClosingMap(int index, int delta); 390 391 // Used by TabDragController when the user starts or stops dragging tabs. 392 void StartedDraggingTabs(const std::vector<Tab*>& tabs); 393 394 // Invoked when TabDragController detaches a set of tabs. 395 void DraggedTabsDetached(); 396 397 // Used by TabDragController when the user stops dragging tabs. |move_only| is 398 // true if the move behavior is TabDragController::MOVE_VISIBILE_TABS. 399 // |completed| is true if the drag operation completed successfully, false if 400 // it was reverted. 401 void StoppedDraggingTabs(const std::vector<Tab*>& tabs, 402 const std::vector<int>& initial_positions, 403 bool move_only, 404 bool completed); 405 406 // Invoked from StoppedDraggingTabs to cleanup |tab|. If |tab| is known 407 // |is_first_tab| is set to true. 408 void StoppedDraggingTab(Tab* tab, bool* is_first_tab); 409 410 // Takes ownership of |controller|. 411 void OwnDragController(TabDragController* controller); 412 413 // Destroys the current TabDragController. This cancel the existing drag 414 // operation. 415 void DestroyDragController(); 416 417 // Releases ownership of the current TabDragController. 418 TabDragController* ReleaseDragController(); 419 420 // Paints all the tabs in |tabs_closing_map_[index]|. 421 void PaintClosingTabs(gfx::Canvas* canvas, 422 int index, 423 const views::CullSet& cull_set); 424 425 // Invoked when a mouse event occurs over |source|. Potentially switches the 426 // |stacked_layout_|. 427 void UpdateStackedLayoutFromMouseEvent(views::View* source, 428 const ui::MouseEvent& event); 429 430 // -- Tab Resize Layout ----------------------------------------------------- 431 432 // Returns the exact (unrounded) current width of each tab. 433 void GetCurrentTabWidths(double* unselected_width, 434 double* selected_width) const; 435 436 // Returns the exact (unrounded) desired width of each tab, based on the 437 // desired strip width and number of tabs. If 438 // |width_of_tabs_for_mouse_close_| is nonnegative we use that value in 439 // calculating the desired strip width; otherwise we use the current width. 440 // |mini_tab_count| gives the number of mini-tabs and |tab_count| the number 441 // of mini and non-mini-tabs. 442 void GetDesiredTabWidths(int tab_count, 443 int mini_tab_count, 444 double* unselected_width, 445 double* selected_width) const; 446 447 // Perform an animated resize-relayout of the TabStrip immediately. 448 void ResizeLayoutTabs(); 449 450 // Invokes ResizeLayoutTabs() as long as we're not in a drag session. If we 451 // are in a drag session this restarts the timer. 452 void ResizeLayoutTabsFromTouch(); 453 454 // Restarts |resize_layout_timer_|. 455 void StartResizeLayoutTabsFromTouchTimer(); 456 457 // Sets the bounds of the tabs to |tab_bounds|. 458 void SetTabBoundsForDrag(const std::vector<gfx::Rect>& tab_bounds); 459 460 // Ensure that the message loop observer used for event spying is added and 461 // removed appropriately so we can tell when to resize layout the tab strip. 462 void AddMessageLoopObserver(); 463 void RemoveMessageLoopObserver(); 464 465 // -- Link Drag & Drop ------------------------------------------------------ 466 467 // Returns the bounds to render the drop at, in screen coordinates. Sets 468 // |is_beneath| to indicate whether the arrow is beneath the tab, or above 469 // it. 470 gfx::Rect GetDropBounds(int drop_index, bool drop_before, bool* is_beneath); 471 472 // Updates the location of the drop based on the event. 473 void UpdateDropIndex(const ui::DropTargetEvent& event); 474 475 // Sets the location of the drop, repainting as necessary. 476 void SetDropIndex(int tab_data_index, bool drop_before); 477 478 // Returns the drop effect for dropping a URL on the tab strip. This does 479 // not query the data in anyway, it only looks at the source operations. 480 int GetDropEffect(const ui::DropTargetEvent& event); 481 482 // Returns the image to use for indicating a drop on a tab. If is_down is 483 // true, this returns an arrow pointing down. 484 static gfx::ImageSkia* GetDropArrowImage(bool is_down); 485 486 // -- Animations ------------------------------------------------------------ 487 488 // Invoked prior to starting a new animation. 489 void PrepareForAnimation(); 490 491 // Generates the ideal bounds for each of the tabs as well as the new tab 492 // button. 493 void GenerateIdealBounds(); 494 495 // Generates the ideal bounds for the mini tabs. Returns the index to position 496 // the first non-mini tab and sets |first_non_mini_index| to the index of the 497 // first non-mini tab. 498 int GenerateIdealBoundsForMiniTabs(int* first_non_mini_index); 499 500 // Returns the width needed for the new tab button (and padding). 501 static int new_tab_button_width(); 502 503 // Returns the vertical offset of the tab strip button. This offset applies 504 // only to restored windows. 505 static int button_v_offset(); 506 507 // Returns the width of the area that contains tabs. This does not include 508 // the width of the new tab button. 509 int tab_area_width() const; 510 511 // Starts various types of TabStrip animations. 512 void StartResizeLayoutAnimation(); 513 void StartMiniTabAnimation(); 514 void StartMouseInitiatedRemoveTabAnimation(int model_index); 515 516 // Returns true if the specified point in TabStrip coords is within the 517 // hit-test region of the specified Tab. 518 bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords); 519 520 // -- Touch Layout ---------------------------------------------------------- 521 522 // Returns the position normal tabs start at. 523 int GetStartXForNormalTabs() const; 524 525 // Returns the tab to use for event handling. This uses FindTabForEventFrom() 526 // to do the actual searching. 527 Tab* FindTabForEvent(const gfx::Point& point); 528 529 // Returns the tab to use for event handling starting at index |start| and 530 // iterating by |delta|. 531 Tab* FindTabForEventFrom(const gfx::Point& point, int start, int delta); 532 533 // For a given point, finds a tab that is hit by the point. If the point hits 534 // an area on which two tabs are overlapping, the tab is selected as follows: 535 // - If one of the tabs is active, select it. 536 // - Select the left one. 537 // If no tabs are hit, returns NULL. 538 views::View* FindTabHitByPoint(const gfx::Point& point); 539 540 // Returns the x-coordinates of the tabs. 541 std::vector<int> GetTabXCoordinates(); 542 543 // Creates/Destroys |touch_layout_| as necessary. 544 void SwapLayoutIfNecessary(); 545 546 // Returns true if |touch_layout_| is needed. 547 bool NeedsTouchLayout() const; 548 549 // Sets the value of |reset_to_shrink_on_exit_|. If true |mouse_watcher_| is 550 // used to track when the mouse truly exits the tabstrip and the stacked 551 // layout is reset. 552 void SetResetToShrinkOnExit(bool value); 553 554 // -- Member Variables ------------------------------------------------------ 555 556 // There is a one-to-one mapping between each of the tabs in the 557 // TabStripController (TabStripModel) and |tabs_|. Because we animate tab 558 // removal there exists a period of time where a tab is displayed but not in 559 // the model. When this occurs the tab is removed from |tabs_| and placed in 560 // |tabs_closing_map_|. When the animation completes the tab is removed from 561 // |tabs_closing_map_|. The painting code ensures both sets of tabs are 562 // painted, and the event handling code ensures only tabs in |tabs_| are used. 563 views::ViewModel tabs_; 564 TabsClosingMap tabs_closing_map_; 565 566 scoped_ptr<TabStripController> controller_; 567 568 // The "New Tab" button. 569 NewTabButton* newtab_button_; 570 571 // Ideal bounds of the new tab button. 572 gfx::Rect newtab_button_bounds_; 573 574 // The current widths of various types of tabs. We save these so that, as 575 // users close tabs while we're holding them at the same size, we can lay out 576 // tabs exactly and eliminate the "pixel jitter" we'd get from just leaving 577 // them all at their existing, rounded widths. 578 double current_unselected_width_; 579 double current_selected_width_; 580 581 // If this value is nonnegative, it is used in GetDesiredTabWidths() to 582 // calculate how much space in the tab strip to use for tabs. Most of the 583 // time this will be -1, but while we're handling closing a tab via the mouse, 584 // we'll set this to the edge of the last tab before closing, so that if we 585 // are closing the last tab and need to resize immediately, we'll resize only 586 // back to this width, thus once again placing the last tab under the mouse 587 // cursor. 588 int available_width_for_tabs_; 589 590 // True if PrepareForCloseAt has been invoked. When true remove animations 591 // preserve current tab bounds. 592 bool in_tab_close_; 593 594 // Valid for the lifetime of a drag over us. 595 scoped_ptr<DropInfo> drop_info_; 596 597 // To ensure all tabs pulse at the same time they share the same animation 598 // container. This is that animation container. 599 scoped_refptr<gfx::AnimationContainer> animation_container_; 600 601 // MouseWatcher is used for two things: 602 // . When a tab is closed to reset the layout. 603 // . When a mouse is used and the layout dynamically adjusts and is currently 604 // stacked (|stacked_layout_| is true). 605 scoped_ptr<views::MouseWatcher> mouse_watcher_; 606 607 // The controller for a drag initiated from a Tab. Valid for the lifetime of 608 // the drag session. 609 scoped_ptr<TabDragController> drag_controller_; 610 611 views::BoundsAnimator bounds_animator_; 612 613 // Size we last layed out at. 614 gfx::Size last_layout_size_; 615 616 // See description above stacked_layout(). 617 bool stacked_layout_; 618 619 // Should the layout dynamically adjust? 620 bool adjust_layout_; 621 622 // Only used while in touch mode. 623 scoped_ptr<StackedTabStripLayout> touch_layout_; 624 625 // If true the |stacked_layout_| is set to false when the mouse exits the 626 // tabstrip (as determined using MouseWatcher). 627 bool reset_to_shrink_on_exit_; 628 629 // Location of the mouse at the time of the last move. 630 gfx::Point last_mouse_move_location_; 631 632 // Time of the last mouse move event. 633 base::TimeTicks last_mouse_move_time_; 634 635 // Number of mouse moves. 636 int mouse_move_count_; 637 638 // Timer used when a tab is closed and we need to relayout. Only used when a 639 // tab close comes from a touch device. 640 base::OneShotTimer<TabStrip> resize_layout_timer_; 641 642 // True if tabs are painted as rectangular light-bars. 643 bool immersive_style_; 644 645 // Our observers. 646 typedef ObserverList<TabStripObserver> TabStripObservers; 647 TabStripObservers observers_; 648 649 DISALLOW_COPY_AND_ASSIGN(TabStrip); 650}; 651 652#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_ 653