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