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