OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 5 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
6 | 6 |
7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
8 #include <windowsx.h> | 8 #include <windowsx.h> |
9 #endif | 9 #endif |
10 | 10 |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 | 504 |
505 TabStrip::TabStrip(TabStripController* controller) | 505 TabStrip::TabStrip(TabStripController* controller) |
506 : controller_(controller), | 506 : controller_(controller), |
507 newtab_button_(NULL), | 507 newtab_button_(NULL), |
508 current_unselected_width_(Tab::GetStandardSize().width()), | 508 current_unselected_width_(Tab::GetStandardSize().width()), |
509 current_selected_width_(Tab::GetStandardSize().width()), | 509 current_selected_width_(Tab::GetStandardSize().width()), |
510 available_width_for_tabs_(-1), | 510 available_width_for_tabs_(-1), |
511 in_tab_close_(false), | 511 in_tab_close_(false), |
512 animation_container_(new gfx::AnimationContainer()), | 512 animation_container_(new gfx::AnimationContainer()), |
513 bounds_animator_(this), | 513 bounds_animator_(this), |
514 layout_type_(TAB_STRIP_LAYOUT_SHRINK), | 514 stacked_layout_(false), |
515 adjust_layout_(false), | 515 adjust_layout_(false), |
516 reset_to_shrink_on_exit_(false), | 516 reset_to_shrink_on_exit_(false), |
517 mouse_move_count_(0), | 517 mouse_move_count_(0), |
518 immersive_style_(false) { | 518 immersive_style_(false) { |
519 Init(); | 519 Init(); |
520 } | 520 } |
521 | 521 |
522 TabStrip::~TabStrip() { | 522 TabStrip::~TabStrip() { |
523 FOR_EACH_OBSERVER(TabStripObserver, observers_, | 523 FOR_EACH_OBSERVER(TabStripObserver, observers_, |
524 TabStripDeleted(this)); | 524 TabStripDeleted(this)); |
(...skipping 15 matching lines...) Expand all Loading... |
540 } | 540 } |
541 | 541 |
542 void TabStrip::AddObserver(TabStripObserver* observer) { | 542 void TabStrip::AddObserver(TabStripObserver* observer) { |
543 observers_.AddObserver(observer); | 543 observers_.AddObserver(observer); |
544 } | 544 } |
545 | 545 |
546 void TabStrip::RemoveObserver(TabStripObserver* observer) { | 546 void TabStrip::RemoveObserver(TabStripObserver* observer) { |
547 observers_.RemoveObserver(observer); | 547 observers_.RemoveObserver(observer); |
548 } | 548 } |
549 | 549 |
550 void TabStrip::SetLayoutType(TabStripLayoutType layout_type, | 550 void TabStrip::SetStackedLayout(bool stacked_layout) { |
551 bool adjust_layout) { | 551 if (stacked_layout == stacked_layout_) |
552 adjust_layout_ = adjust_layout; | |
553 if (layout_type == layout_type_) | |
554 return; | 552 return; |
555 | 553 |
556 const int active_index = controller_->GetActiveIndex(); | 554 const int active_index = controller_->GetActiveIndex(); |
557 int active_center = 0; | 555 int active_center = 0; |
558 if (active_index != -1) { | 556 if (active_index != -1) { |
559 active_center = ideal_bounds(active_index).x() + | 557 active_center = ideal_bounds(active_index).x() + |
560 ideal_bounds(active_index).width() / 2; | 558 ideal_bounds(active_index).width() / 2; |
561 } | 559 } |
562 layout_type_ = layout_type; | 560 stacked_layout_ = stacked_layout; |
563 SetResetToShrinkOnExit(false); | 561 SetResetToShrinkOnExit(false); |
564 SwapLayoutIfNecessary(); | 562 SwapLayoutIfNecessary(); |
565 // When transitioning to stacked try to keep the active tab centered. | 563 // When transitioning to stacked try to keep the active tab centered. |
566 if (touch_layout_.get() && active_index != -1) { | 564 if (touch_layout_.get() && active_index != -1) { |
567 touch_layout_->SetActiveTabLocation( | 565 touch_layout_->SetActiveTabLocation( |
568 active_center - ideal_bounds(active_index).width() / 2); | 566 active_center - ideal_bounds(active_index).width() / 2); |
569 AnimateToIdealBounds(); | 567 AnimateToIdealBounds(); |
570 } | 568 } |
571 } | 569 } |
572 | 570 |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 } | 1110 } |
1113 | 1111 |
1114 bool TabStrip::IsImmersiveStyle() const { | 1112 bool TabStrip::IsImmersiveStyle() const { |
1115 return immersive_style_; | 1113 return immersive_style_; |
1116 } | 1114 } |
1117 | 1115 |
1118 void TabStrip::MouseMovedOutOfHost() { | 1116 void TabStrip::MouseMovedOutOfHost() { |
1119 ResizeLayoutTabs(); | 1117 ResizeLayoutTabs(); |
1120 if (reset_to_shrink_on_exit_) { | 1118 if (reset_to_shrink_on_exit_) { |
1121 reset_to_shrink_on_exit_ = false; | 1119 reset_to_shrink_on_exit_ = false; |
1122 SetLayoutType(TAB_STRIP_LAYOUT_SHRINK, true); | 1120 SetStackedLayout(false); |
1123 controller_->LayoutTypeMaybeChanged(); | 1121 controller_->LayoutTypeMaybeChanged(); |
1124 } | 1122 } |
1125 } | 1123 } |
1126 | 1124 |
1127 /////////////////////////////////////////////////////////////////////////////// | 1125 /////////////////////////////////////////////////////////////////////////////// |
1128 // TabStrip, views::View overrides: | 1126 // TabStrip, views::View overrides: |
1129 | 1127 |
1130 void TabStrip::Layout() { | 1128 void TabStrip::Layout() { |
1131 // Only do a layout if our size changed. | 1129 // Only do a layout if our size changed. |
1132 if (last_layout_size_ == size()) | 1130 if (last_layout_size_ == size()) |
(...skipping 10 matching lines...) Expand all Loading... |
1143 // |tabs_closing_map_|. | 1141 // |tabs_closing_map_|. |
1144 Tab* active_tab = NULL; | 1142 Tab* active_tab = NULL; |
1145 std::vector<Tab*> tabs_dragging; | 1143 std::vector<Tab*> tabs_dragging; |
1146 std::vector<Tab*> selected_tabs; | 1144 std::vector<Tab*> selected_tabs; |
1147 int selected_tab_count = 0; | 1145 int selected_tab_count = 0; |
1148 bool is_dragging = false; | 1146 bool is_dragging = false; |
1149 int active_tab_index = -1; | 1147 int active_tab_index = -1; |
1150 // Since |touch_layout_| is created based on number of tabs and width we use | 1148 // Since |touch_layout_| is created based on number of tabs and width we use |
1151 // the ideal state to determine if we should paint stacked. This minimizes | 1149 // the ideal state to determine if we should paint stacked. This minimizes |
1152 // painting changes as we switch between the two. | 1150 // painting changes as we switch between the two. |
1153 const bool stacking = (layout_type_ == TAB_STRIP_LAYOUT_STACKED) || | 1151 const bool stacking = stacked_layout_ || IsStackingDraggedTabs(); |
1154 IsStackingDraggedTabs(); | |
1155 | 1152 |
1156 const chrome::HostDesktopType host_desktop_type = | 1153 const chrome::HostDesktopType host_desktop_type = |
1157 chrome::GetHostDesktopTypeForNativeView(GetWidget()->GetNativeView()); | 1154 chrome::GetHostDesktopTypeForNativeView(GetWidget()->GetNativeView()); |
1158 const int inactive_tab_alpha = | 1155 const int inactive_tab_alpha = |
1159 host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH ? | 1156 host_desktop_type == chrome::HOST_DESKTOP_TYPE_ASH ? |
1160 kInactiveTabAndNewTabButtonAlphaAsh : | 1157 kInactiveTabAndNewTabButtonAlphaAsh : |
1161 kInactiveTabAndNewTabButtonAlpha; | 1158 kInactiveTabAndNewTabButtonAlpha; |
1162 | 1159 |
1163 if (inactive_tab_alpha < 255) | 1160 if (inactive_tab_alpha < 255) |
1164 canvas->SaveLayerAlpha(inactive_tab_alpha); | 1161 canvas->SaveLayerAlpha(inactive_tab_alpha); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1479 } | 1476 } |
1480 | 1477 |
1481 void TabStrip::OnGestureEvent(ui::GestureEvent* event) { | 1478 void TabStrip::OnGestureEvent(ui::GestureEvent* event) { |
1482 SetResetToShrinkOnExit(false); | 1479 SetResetToShrinkOnExit(false); |
1483 switch (event->type()) { | 1480 switch (event->type()) { |
1484 case ui::ET_GESTURE_SCROLL_END: | 1481 case ui::ET_GESTURE_SCROLL_END: |
1485 case ui::ET_SCROLL_FLING_START: | 1482 case ui::ET_SCROLL_FLING_START: |
1486 case ui::ET_GESTURE_END: | 1483 case ui::ET_GESTURE_END: |
1487 EndDrag(END_DRAG_COMPLETE); | 1484 EndDrag(END_DRAG_COMPLETE); |
1488 if (adjust_layout_) { | 1485 if (adjust_layout_) { |
1489 SetLayoutType(TAB_STRIP_LAYOUT_STACKED, true); | 1486 SetStackedLayout(true); |
1490 controller_->LayoutTypeMaybeChanged(); | 1487 controller_->LayoutTypeMaybeChanged(); |
1491 } | 1488 } |
1492 break; | 1489 break; |
1493 | 1490 |
1494 case ui::ET_GESTURE_LONG_PRESS: | 1491 case ui::ET_GESTURE_LONG_PRESS: |
1495 if (drag_controller_.get()) | 1492 if (drag_controller_.get()) |
1496 drag_controller_->SetMoveBehavior(TabDragController::REORDER); | 1493 drag_controller_->SetMoveBehavior(TabDragController::REORDER); |
1497 break; | 1494 break; |
1498 | 1495 |
1499 case ui::ET_GESTURE_LONG_TAP: { | 1496 case ui::ET_GESTURE_LONG_TAP: { |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1981 | 1978 |
1982 const std::vector<Tab*>& tabs = tabs_closing_map_[index]; | 1979 const std::vector<Tab*>& tabs = tabs_closing_map_[index]; |
1983 for (std::vector<Tab*>::const_reverse_iterator i(tabs.rbegin()); | 1980 for (std::vector<Tab*>::const_reverse_iterator i(tabs.rbegin()); |
1984 i != tabs.rend(); ++i) { | 1981 i != tabs.rend(); ++i) { |
1985 (*i)->Paint(canvas, cull_set); | 1982 (*i)->Paint(canvas, cull_set); |
1986 } | 1983 } |
1987 } | 1984 } |
1988 | 1985 |
1989 void TabStrip::UpdateLayoutTypeFromMouseEvent(views::View* source, | 1986 void TabStrip::UpdateLayoutTypeFromMouseEvent(views::View* source, |
1990 const ui::MouseEvent& event) { | 1987 const ui::MouseEvent& event) { |
1991 if (!GetAdjustLayout()) | 1988 if (!adjust_layout_) |
1992 return; | 1989 return; |
1993 | 1990 |
1994 // The following code attempts to switch to TAB_STRIP_LAYOUT_SHRINK when the | 1991 // The following code attempts to switch to shrink (not stacked) layout when |
1995 // mouse exits the tabstrip (or the mouse is pressed on a stacked tab) and | 1992 // the mouse exits the tabstrip (or the mouse is pressed on a stacked tab) and |
1996 // TAB_STRIP_LAYOUT_STACKED when a touch device is used. This is made | 1993 // to stacked layout when a touch device is used. This is made problematic by |
1997 // problematic by windows generating mouse move events that do not clearly | 1994 // windows generating mouse move events that do not clearly indicate the move |
1998 // indicate the move is the result of a touch device. This assumes a real | 1995 // is the result of a touch device. This assumes a real mouse is used if |
1999 // mouse is used if |kMouseMoveCountBeforeConsiderReal| mouse move events are | 1996 // |kMouseMoveCountBeforeConsiderReal| mouse move events are received within |
2000 // received within the time window |kMouseMoveTimeMS|. At the time we get a | 1997 // the time window |kMouseMoveTimeMS|. At the time we get a mouse press we |
2001 // mouse press we know whether its from a touch device or not, but we don't | 1998 // know whether its from a touch device or not, but we don't layout then else |
2002 // layout then else everything shifts. Instead we wait for the release. | 1999 // everything shifts. Instead we wait for the release. |
2003 // | 2000 // |
2004 // TODO(sky): revisit this when touch events are really plumbed through. | 2001 // TODO(sky): revisit this when touch events are really plumbed through. |
2005 | 2002 |
2006 switch (event.type()) { | 2003 switch (event.type()) { |
2007 case ui::ET_MOUSE_PRESSED: | 2004 case ui::ET_MOUSE_PRESSED: |
2008 mouse_move_count_ = 0; | 2005 mouse_move_count_ = 0; |
2009 last_mouse_move_time_ = base::TimeTicks(); | 2006 last_mouse_move_time_ = base::TimeTicks(); |
2010 SetResetToShrinkOnExit((event.flags() & ui::EF_FROM_TOUCH) == 0); | 2007 SetResetToShrinkOnExit((event.flags() & ui::EF_FROM_TOUCH) == 0); |
2011 if (reset_to_shrink_on_exit_ && touch_layout_.get()) { | 2008 if (reset_to_shrink_on_exit_ && touch_layout_.get()) { |
2012 gfx::Point tab_strip_point(event.location()); | 2009 gfx::Point tab_strip_point(event.location()); |
2013 views::View::ConvertPointToTarget(source, this, &tab_strip_point); | 2010 views::View::ConvertPointToTarget(source, this, &tab_strip_point); |
2014 Tab* tab = FindTabForEvent(tab_strip_point); | 2011 Tab* tab = FindTabForEvent(tab_strip_point); |
2015 if (tab && touch_layout_->IsStacked(GetModelIndexOfTab(tab))) { | 2012 if (tab && touch_layout_->IsStacked(GetModelIndexOfTab(tab))) { |
2016 SetLayoutType(TAB_STRIP_LAYOUT_SHRINK, true); | 2013 SetStackedLayout(false); |
2017 controller_->LayoutTypeMaybeChanged(); | 2014 controller_->LayoutTypeMaybeChanged(); |
2018 } | 2015 } |
2019 } | 2016 } |
2020 break; | 2017 break; |
2021 | 2018 |
2022 case ui::ET_MOUSE_MOVED: { | 2019 case ui::ET_MOUSE_MOVED: { |
2023 #if defined(USE_ASH) | 2020 #if defined(USE_ASH) |
2024 // Ash does not synthesize mouse events from touch events. | 2021 // Ash does not synthesize mouse events from touch events. |
2025 SetResetToShrinkOnExit(true); | 2022 SetResetToShrinkOnExit(true); |
2026 #else | 2023 #else |
(...skipping 19 matching lines...) Expand all Loading... |
2046 break; | 2043 break; |
2047 } | 2044 } |
2048 | 2045 |
2049 case ui::ET_MOUSE_RELEASED: { | 2046 case ui::ET_MOUSE_RELEASED: { |
2050 gfx::Point location(event.location()); | 2047 gfx::Point location(event.location()); |
2051 ConvertPointToTarget(source, this, &location); | 2048 ConvertPointToTarget(source, this, &location); |
2052 last_mouse_move_location_ = location; | 2049 last_mouse_move_location_ = location; |
2053 mouse_move_count_ = 0; | 2050 mouse_move_count_ = 0; |
2054 last_mouse_move_time_ = base::TimeTicks(); | 2051 last_mouse_move_time_ = base::TimeTicks(); |
2055 if ((event.flags() & ui::EF_FROM_TOUCH) == ui::EF_FROM_TOUCH) { | 2052 if ((event.flags() & ui::EF_FROM_TOUCH) == ui::EF_FROM_TOUCH) { |
2056 SetLayoutType(TAB_STRIP_LAYOUT_STACKED, true); | 2053 SetStackedLayout(true); |
2057 controller_->LayoutTypeMaybeChanged(); | 2054 controller_->LayoutTypeMaybeChanged(); |
2058 } | 2055 } |
2059 break; | 2056 break; |
2060 } | 2057 } |
2061 | 2058 |
2062 default: | 2059 default: |
2063 break; | 2060 break; |
2064 } | 2061 } |
2065 } | 2062 } |
2066 | 2063 |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2605 touch_layout_->SetActiveIndex(controller_->GetActiveIndex()); | 2602 touch_layout_->SetActiveIndex(controller_->GetActiveIndex()); |
2606 } else { | 2603 } else { |
2607 touch_layout_.reset(); | 2604 touch_layout_.reset(); |
2608 } | 2605 } |
2609 PrepareForAnimation(); | 2606 PrepareForAnimation(); |
2610 GenerateIdealBounds(); | 2607 GenerateIdealBounds(); |
2611 AnimateToIdealBounds(); | 2608 AnimateToIdealBounds(); |
2612 } | 2609 } |
2613 | 2610 |
2614 bool TabStrip::NeedsTouchLayout() const { | 2611 bool TabStrip::NeedsTouchLayout() const { |
2615 if (layout_type_ == TAB_STRIP_LAYOUT_SHRINK) | 2612 if (!stacked_layout_) |
2616 return false; | 2613 return false; |
2617 | 2614 |
2618 int mini_tab_count = GetMiniTabCount(); | 2615 int mini_tab_count = GetMiniTabCount(); |
2619 int normal_count = tab_count() - mini_tab_count; | 2616 int normal_count = tab_count() - mini_tab_count; |
2620 if (normal_count <= 1 || normal_count == mini_tab_count) | 2617 if (normal_count <= 1 || normal_count == mini_tab_count) |
2621 return false; | 2618 return false; |
2622 int x = GetStartXForNormalTabs(); | 2619 int x = GetStartXForNormalTabs(); |
2623 int available_width = width() - x - new_tab_button_width(); | 2620 int available_width = width() - x - new_tab_button_width(); |
2624 return (Tab::GetTouchWidth() * normal_count + | 2621 return (Tab::GetTouchWidth() * normal_count + |
2625 kTabHorizontalOffset * (normal_count - 1)) > available_width; | 2622 kTabHorizontalOffset * (normal_count - 1)) > available_width; |
2626 } | 2623 } |
2627 | 2624 |
2628 void TabStrip::SetResetToShrinkOnExit(bool value) { | 2625 void TabStrip::SetResetToShrinkOnExit(bool value) { |
2629 if (!GetAdjustLayout()) | 2626 if (!adjust_layout_) |
2630 return; | 2627 return; |
2631 | 2628 |
2632 if (value && layout_type_ == TAB_STRIP_LAYOUT_SHRINK) | 2629 if (value && !stacked_layout_) |
2633 value = false; // We're already at TAB_STRIP_LAYOUT_SHRINK. | 2630 value = false; // We're already using shrink (not stacked) layout. |
2634 | 2631 |
2635 if (value == reset_to_shrink_on_exit_) | 2632 if (value == reset_to_shrink_on_exit_) |
2636 return; | 2633 return; |
2637 | 2634 |
2638 reset_to_shrink_on_exit_ = value; | 2635 reset_to_shrink_on_exit_ = value; |
2639 // Add an observer so we know when the mouse moves out of the tabstrip. | 2636 // Add an observer so we know when the mouse moves out of the tabstrip. |
2640 if (reset_to_shrink_on_exit_) | 2637 if (reset_to_shrink_on_exit_) |
2641 AddMessageLoopObserver(); | 2638 AddMessageLoopObserver(); |
2642 else | 2639 else |
2643 RemoveMessageLoopObserver(); | 2640 RemoveMessageLoopObserver(); |
2644 } | 2641 } |
2645 | |
2646 bool TabStrip::GetAdjustLayout() const { | |
2647 if (!adjust_layout_) | |
2648 return false; | |
2649 return chrome::GetHostDesktopTypeForNativeView( | |
2650 GetWidget()->GetNativeView()) == chrome::HOST_DESKTOP_TYPE_ASH; | |
2651 } | |
OLD | NEW |