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