tab_strip.h revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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
25class NewTabButton;
26class StackedTabStripLayout;
27class Tab;
28class TabDragController;
29class TabStripController;
30class TabStripObserver;
31
32namespace ui {
33class ListSelectionModel;
34}
35
36namespace views {
37class 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///////////////////////////////////////////////////////////////////////////////
53class 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_
634