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