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