Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / tabs / tab_strip.h
bloba8153daaa0fe2f2ff60cb88f28024ff9e83341ba
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.
5 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_
6 #define CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_
8 #include <vector>
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/geometry/point.h"
17 #include "ui/gfx/geometry/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"
25 class NewTabButton;
26 class StackedTabStripLayout;
27 class Tab;
28 class TabDragController;
29 class TabStripController;
30 class TabStripObserver;
32 namespace ui {
33 class ListSelectionModel;
36 namespace views {
37 class ImageView;
40 ///////////////////////////////////////////////////////////////////////////////
42 // TabStrip
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.
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[];
61 // Horizontal offset for the new tab button to bring it closer to the
62 // rightmost tab.
63 static const int kNewTabButtonHorizontalOffset;
65 // The vertical offset of the tab strip button. This offset applies only to
66 // restored windows.
67 static const int kNewTabButtonVerticalOffset;
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;
76 explicit TabStrip(TabStripController* controller);
77 ~TabStrip() override;
79 // Add and remove observers to changes within this TabStrip.
80 void AddObserver(TabStripObserver* observer);
81 void RemoveObserver(TabStripObserver* observer);
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; }
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_; }
95 // Sets |stacked_layout_| and animates if necessary.
96 void SetStackedLayout(bool stacked_layout);
98 // Returns the bounds of the new tab button.
99 gfx::Rect GetNewTabButtonBounds();
101 // Returns true if the new tab button should be sized to the top of the tab
102 // strip.
103 bool SizeTabButtonToTopOfTabStrip();
105 // Starts highlighting the tab at the specified index.
106 void StartHighlight(int model_index);
108 // Stops all tab higlighting.
109 void StopAllHighlighting();
111 // Adds a tab at the specified index.
112 void AddTabAt(int model_index, const TabRendererData& data, bool is_active);
114 // Moves a tab.
115 void MoveTab(int from_model_index,
116 int to_model_index,
117 const TabRendererData& data);
119 // Removes a tab at the specified index.
120 void RemoveTabAt(int model_index);
122 // Sets the tab data at the specified model index.
123 void SetTabData(int model_index, const TabRendererData& data);
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;
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);
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);
143 // Invoked when the title of a tab changes and the tab isn't loading.
144 void TabTitleChangedNotLoading(int model_index);
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);
151 // Returns the Tab at |index|.
152 Tab* tab_at(int index) const { return tabs_.view_at(index); }
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;
158 // Gets the number of Tabs in the tab strip.
159 int tab_count() const { return tabs_.view_size(); }
161 // Cover method for TabStripController::GetCount.
162 int GetModelCount() const;
164 // Cover method for TabStripController::IsValidIndex.
165 bool IsValidModelIndex(int model_index) const;
167 TabStripController* controller() const { return controller_.get(); }
169 // Returns true if a drag session is currently active.
170 bool IsDragSessionActive() const;
172 // Returns true if a tab is being dragged into this tab strip.
173 bool IsActiveDropTarget() const;
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;
180 // Returns false when there is a drag operation in progress so that the frame
181 // doesn't close.
182 bool IsTabStripCloseable() const;
184 // Updates the loading animations displayed by tabs in the tabstrip to the
185 // next frame.
186 void UpdateLoadingAnimations();
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);
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);
196 // Set the background offset used by inactive tabs to match the frame image.
197 void SetBackgroundOffset(const gfx::Point& offset);
199 // Sets a painting style with miniature "tab indicator" rectangles at the top.
200 void SetImmersiveStyle(bool enable);
202 // Returns true if Tabs in this TabStrip are currently changing size or
203 // position.
204 bool IsAnimating() const;
206 // Stops any ongoing animations. If |layout| is true and an animation is
207 // ongoing this does a layout.
208 void StopAnimating(bool layout);
210 // Called to indicate whether the given URL is a supported file.
211 void FileSupported(const GURL& url, bool supported);
213 // TabController overrides:
214 const ui::ListSelectionModel& GetSelectionModel() override;
215 bool SupportsMultipleSelection() override;
216 bool ShouldHideCloseButtonForInactiveTabs() override;
217 void SelectTab(Tab* tab) override;
218 void ExtendSelectionTo(Tab* tab) override;
219 void ToggleSelected(Tab* tab) override;
220 void AddSelectionFromAnchorTo(Tab* tab) override;
221 void CloseTab(Tab* tab, CloseTabSource source) override;
222 void ToggleTabAudioMute(Tab* tab) override;
223 void ShowContextMenuForTab(Tab* tab,
224 const gfx::Point& p,
225 ui::MenuSourceType source_type) override;
226 bool IsActiveTab(const Tab* tab) const override;
227 bool IsTabSelected(const Tab* tab) const override;
228 bool IsTabPinned(const Tab* tab) const override;
229 void MaybeStartDrag(
230 Tab* tab,
231 const ui::LocatedEvent& event,
232 const ui::ListSelectionModel& original_selection) override;
233 void ContinueDrag(views::View* view, const ui::LocatedEvent& event) override;
234 bool EndDrag(EndDragReason reason) override;
235 Tab* GetTabAt(Tab* tab, const gfx::Point& tab_in_tab_coordinates) override;
236 void OnMouseEventInTab(views::View* source,
237 const ui::MouseEvent& event) override;
238 bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) override;
239 bool IsImmersiveStyle() const override;
240 void UpdateTabAccessibilityState(const Tab* tab,
241 ui::AXViewState* state) override;
243 // MouseWatcherListener overrides:
244 void MouseMovedOutOfHost() override;
246 // views::View overrides:
247 void Layout() override;
248 void PaintChildren(const ui::PaintContext& context) 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;
260 // Returns preferred height in immersive style.
261 static int GetImmersiveHeight();
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;
269 class RemoveTabDelegate;
271 friend class TabDragController;
272 friend class TabDragControllerTest;
273 friend class TabStripTest;
274 FRIEND_TEST_ALL_PREFIXES(TabDragControllerTest, GestureEndShouldEndDragTest);
275 FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabHitTestMaskWhenStacked);
276 FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabCloseButtonVisibilityWhenStacked);
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();
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;
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;
299 // Renders the drop indicator.
300 views::Widget* arrow_window;
301 views::ImageView* arrow_view;
303 // The URL for the drop event.
304 GURL url;
306 // Whether the MIME type of the file pointed to by |url| is supported.
307 bool file_supported;
309 private:
310 DISALLOW_COPY_AND_ASSIGN(DropInfo);
313 // Horizontal gap between pinned and non-pinned tabs.
314 static const int kPinnedToNonPinnedGap;
316 void Init();
318 // Creates and returns a new tab. The caller owners the returned tab.
319 Tab* CreateTab();
321 // Invoked from |AddTabAt| after the newly created tab has been inserted.
322 void StartInsertTabAnimation(int model_index);
324 // Invoked from |MoveTab| after |tab_data_| has been updated to animate the
325 // move.
326 void StartMoveTabAnimation();
328 // Starts the remove tab animation.
329 void StartRemoveTabAnimation(int model_index);
331 // Schedules the animations and bounds changes necessary for a remove tab
332 // animation.
333 void ScheduleRemoveTabAnimation(Tab* tab);
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();
340 // Returns whether the highlight button should be highlighted after a remove.
341 bool ShouldHighlightCloseButtonAfterRemove();
343 // Invoked from Layout if the size changes or layout is really needed.
344 void DoLayout();
346 // Sets the visibility state of all tabs based on ShouldTabBeVisible().
347 void SetTabVisibility();
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);
353 // Sets the ideal bounds x-coordinates to |positions|.
354 void SetIdealBoundsFromPositions(const std::vector<int>& positions);
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);
361 // Returns true if dragging has resulted in temporarily stacking the tabs.
362 bool IsStackingDraggedTabs() const;
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);
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);
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);
381 // Returns the number of pinned tabs.
382 int GetPinnedTabCount() const;
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;
388 // Adds the tab at |index| to |tabs_closing_map_| and removes the tab from
389 // |tabs_|.
390 void RemoveTabFromViewModel(int index);
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);
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);
400 // Used by TabDragController when the user starts or stops dragging tabs.
401 void StartedDraggingTabs(const Tabs& tabs);
403 // Invoked when TabDragController detaches a set of tabs.
404 void DraggedTabsDetached();
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);
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);
419 // Takes ownership of |controller|.
420 void OwnDragController(TabDragController* controller);
422 // Destroys the current TabDragController. This cancel the existing drag
423 // operation.
424 void DestroyDragController();
426 // Releases ownership of the current TabDragController.
427 TabDragController* ReleaseDragController();
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);
433 // Paints all the tabs in |tabs_closing_map_[index]|.
434 void PaintClosingTabs(int index, const ui::PaintContext& context);
436 // Invoked when a mouse event occurs over |source|. Potentially switches the
437 // |stacked_layout_|.
438 void UpdateStackedLayoutFromMouseEvent(views::View* source,
439 const ui::MouseEvent& event);
441 // -- Tab Resize Layout -----------------------------------------------------
443 // Returns the exact (unrounded) current width of each tab.
444 void GetCurrentTabWidths(double* unselected_width,
445 double* selected_width) const;
447 // Returns the exact (unrounded) desired width of each tab, based on the
448 // desired strip width and number of tabs. If
449 // |width_of_tabs_for_mouse_close_| is nonnegative we use that value in
450 // calculating the desired strip width; otherwise we use the current width.
451 // |pinned_tab_count| gives the number of pinned tabs and |tab_count| the
452 // number of pinned and non-pinned tabs.
453 void GetDesiredTabWidths(int tab_count,
454 int pinned_tab_count,
455 double* unselected_width,
456 double* selected_width) const;
458 // Perform an animated resize-relayout of the TabStrip immediately.
459 void ResizeLayoutTabs();
461 // Invokes ResizeLayoutTabs() as long as we're not in a drag session. If we
462 // are in a drag session this restarts the timer.
463 void ResizeLayoutTabsFromTouch();
465 // Restarts |resize_layout_timer_|.
466 void StartResizeLayoutTabsFromTouchTimer();
468 // Sets the bounds of the tabs to |tab_bounds|.
469 void SetTabBoundsForDrag(const std::vector<gfx::Rect>& tab_bounds);
471 // Ensure that the message loop observer used for event spying is added and
472 // removed appropriately so we can tell when to resize layout the tab strip.
473 void AddMessageLoopObserver();
474 void RemoveMessageLoopObserver();
476 // -- Link Drag & Drop ------------------------------------------------------
478 // Returns the bounds to render the drop at, in screen coordinates. Sets
479 // |is_beneath| to indicate whether the arrow is beneath the tab, or above
480 // it.
481 gfx::Rect GetDropBounds(int drop_index, bool drop_before, bool* is_beneath);
483 // Updates the location of the drop based on the event.
484 void UpdateDropIndex(const ui::DropTargetEvent& event);
486 // Sets the location of the drop, repainting as necessary.
487 void SetDropIndex(int tab_data_index, bool drop_before);
489 // Returns the drop effect for dropping a URL on the tab strip. This does
490 // not query the data in anyway, it only looks at the source operations.
491 int GetDropEffect(const ui::DropTargetEvent& event);
493 // Returns the image to use for indicating a drop on a tab. If is_down is
494 // true, this returns an arrow pointing down.
495 static gfx::ImageSkia* GetDropArrowImage(bool is_down);
497 // -- Animations ------------------------------------------------------------
499 // Invoked prior to starting a new animation.
500 void PrepareForAnimation();
502 // Generates the ideal bounds for each of the tabs as well as the new tab
503 // button.
504 void GenerateIdealBounds();
506 // Generates the ideal bounds for the pinned tabs. Returns the index to
507 // position the first non-pinned tab and sets |first_non_pinned_index| to the
508 // index of the first non-pinned tab.
509 int GenerateIdealBoundsForPinnedTabs(int* first_non_pinned_index);
511 // Returns the width needed for the new tab button (and padding).
512 static int new_tab_button_width() {
513 return kNewTabButtonAssetWidth + kNewTabButtonHorizontalOffset;
516 // Returns the width of the area that contains tabs. This does not include
517 // the width of the new tab button.
518 int tab_area_width() const { return width() - new_tab_button_width(); }
520 // Starts various types of TabStrip animations.
521 void StartResizeLayoutAnimation();
522 void StartPinnedTabAnimation();
523 void StartMouseInitiatedRemoveTabAnimation(int model_index);
525 // Returns true if the specified point in TabStrip coords is within the
526 // hit-test region of the specified Tab.
527 bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords);
529 // -- Touch Layout ----------------------------------------------------------
531 // Returns the position normal tabs start at.
532 int GetStartXForNormalTabs() const;
534 // Returns the tab to use for event handling. This uses FindTabForEventFrom()
535 // to do the actual searching.
536 Tab* FindTabForEvent(const gfx::Point& point);
538 // Returns the tab to use for event handling starting at index |start| and
539 // iterating by |delta|.
540 Tab* FindTabForEventFrom(const gfx::Point& point, int start, int delta);
542 // For a given point, finds a tab that is hit by the point. If the point hits
543 // an area on which two tabs are overlapping, the tab is selected as follows:
544 // - If one of the tabs is active, select it.
545 // - Select the left one.
546 // If no tabs are hit, returns NULL.
547 views::View* FindTabHitByPoint(const gfx::Point& point);
549 // Returns the x-coordinates of the tabs.
550 std::vector<int> GetTabXCoordinates();
552 // Creates/Destroys |touch_layout_| as necessary.
553 void SwapLayoutIfNecessary();
555 // Returns true if |touch_layout_| is needed.
556 bool NeedsTouchLayout() const;
558 // Sets the value of |reset_to_shrink_on_exit_|. If true |mouse_watcher_| is
559 // used to track when the mouse truly exits the tabstrip and the stacked
560 // layout is reset.
561 void SetResetToShrinkOnExit(bool value);
563 // views::ButtonListener implementation:
564 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
566 // View overrides.
567 const views::View* GetViewByID(int id) const override;
568 bool OnMousePressed(const ui::MouseEvent& event) override;
569 bool OnMouseDragged(const ui::MouseEvent& event) override;
570 void OnMouseReleased(const ui::MouseEvent& event) override;
571 void OnMouseCaptureLost() override;
572 void OnMouseMoved(const ui::MouseEvent& event) override;
573 void OnMouseEntered(const ui::MouseEvent& event) override;
575 // ui::EventHandler overrides.
576 void OnGestureEvent(ui::GestureEvent* event) override;
578 // views::ViewTargeterDelegate:
579 views::View* TargetForRect(views::View* root, const gfx::Rect& rect) override;
581 // -- Member Variables ------------------------------------------------------
583 // There is a one-to-one mapping between each of the tabs in the
584 // TabStripController (TabStripModel) and |tabs_|. Because we animate tab
585 // removal there exists a period of time where a tab is displayed but not in
586 // the model. When this occurs the tab is removed from |tabs_| and placed in
587 // |tabs_closing_map_|. When the animation completes the tab is removed from
588 // |tabs_closing_map_|. The painting code ensures both sets of tabs are
589 // painted, and the event handling code ensures only tabs in |tabs_| are used.
590 views::ViewModelT<Tab> tabs_;
591 TabsClosingMap tabs_closing_map_;
593 scoped_ptr<TabStripController> controller_;
595 // The "New Tab" button.
596 NewTabButton* newtab_button_;
598 // Ideal bounds of the new tab button.
599 gfx::Rect newtab_button_bounds_;
601 // The current widths of various types of tabs. We save these so that, as
602 // users close tabs while we're holding them at the same size, we can lay out
603 // tabs exactly and eliminate the "pixel jitter" we'd get from just leaving
604 // them all at their existing, rounded widths.
605 double current_unselected_width_;
606 double current_selected_width_;
608 // If this value is nonnegative, it is used in GetDesiredTabWidths() to
609 // calculate how much space in the tab strip to use for tabs. Most of the
610 // time this will be -1, but while we're handling closing a tab via the mouse,
611 // we'll set this to the edge of the last tab before closing, so that if we
612 // are closing the last tab and need to resize immediately, we'll resize only
613 // back to this width, thus once again placing the last tab under the mouse
614 // cursor.
615 int available_width_for_tabs_;
617 // True if PrepareForCloseAt has been invoked. When true remove animations
618 // preserve current tab bounds.
619 bool in_tab_close_;
621 // Valid for the lifetime of a drag over us.
622 scoped_ptr<DropInfo> drop_info_;
624 // To ensure all tabs pulse at the same time they share the same animation
625 // container. This is that animation container.
626 scoped_refptr<gfx::AnimationContainer> animation_container_;
628 // MouseWatcher is used for two things:
629 // . When a tab is closed to reset the layout.
630 // . When a mouse is used and the layout dynamically adjusts and is currently
631 // stacked (|stacked_layout_| is true).
632 scoped_ptr<views::MouseWatcher> mouse_watcher_;
634 // The controller for a drag initiated from a Tab. Valid for the lifetime of
635 // the drag session.
636 scoped_ptr<TabDragController> drag_controller_;
638 views::BoundsAnimator bounds_animator_;
640 // Size we last layed out at.
641 gfx::Size last_layout_size_;
643 // See description above stacked_layout().
644 bool stacked_layout_;
646 // Should the layout dynamically adjust?
647 bool adjust_layout_;
649 // Only used while in touch mode.
650 scoped_ptr<StackedTabStripLayout> touch_layout_;
652 // If true the |stacked_layout_| is set to false when the mouse exits the
653 // tabstrip (as determined using MouseWatcher).
654 bool reset_to_shrink_on_exit_;
656 // Location of the mouse at the time of the last move.
657 gfx::Point last_mouse_move_location_;
659 // Time of the last mouse move event.
660 base::TimeTicks last_mouse_move_time_;
662 // Number of mouse moves.
663 int mouse_move_count_;
665 // Timer used when a tab is closed and we need to relayout. Only used when a
666 // tab close comes from a touch device.
667 base::OneShotTimer<TabStrip> resize_layout_timer_;
669 // True if tabs are painted as rectangular light-bars.
670 bool immersive_style_;
672 // Our observers.
673 typedef base::ObserverList<TabStripObserver> TabStripObservers;
674 TabStripObservers observers_;
676 DISALLOW_COPY_AND_ASSIGN(TabStrip);
679 #endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_H_