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 "ash/shelf/shelf_view.h" | 5 #include "ash/shelf/shelf_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ash/ash_constants.h" | 9 #include "ash/ash_constants.h" |
10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 closing_event_time_(base::TimeDelta()), | 382 closing_event_time_(base::TimeDelta()), |
383 got_deleted_(NULL), | 383 got_deleted_(NULL), |
384 drag_and_drop_item_pinned_(false), | 384 drag_and_drop_item_pinned_(false), |
385 drag_and_drop_shelf_id_(0), | 385 drag_and_drop_shelf_id_(0), |
386 dragged_off_shelf_(false), | 386 dragged_off_shelf_(false), |
387 snap_back_from_rip_off_view_(NULL), | 387 snap_back_from_rip_off_view_(NULL), |
388 item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), | 388 item_manager_(Shell::GetInstance()->shelf_item_delegate_manager()), |
389 layout_manager_(manager), | 389 layout_manager_(manager), |
390 overflow_mode_(false), | 390 overflow_mode_(false), |
391 main_shelf_(NULL), | 391 main_shelf_(NULL), |
392 dragged_off_from_overflow_to_shelf_(false) { | 392 dragged_off_from_overflow_to_shelf_(false), |
| 393 is_repost_event_(false), |
| 394 last_pressed_index_(-1) { |
393 DCHECK(model_); | 395 DCHECK(model_); |
394 bounds_animator_.reset(new views::BoundsAnimator(this)); | 396 bounds_animator_.reset(new views::BoundsAnimator(this)); |
395 bounds_animator_->AddObserver(this); | 397 bounds_animator_->AddObserver(this); |
396 set_context_menu_controller(this); | 398 set_context_menu_controller(this); |
397 focus_search_.reset(new ShelfFocusSearch(view_model_.get())); | 399 focus_search_.reset(new ShelfFocusSearch(view_model_.get())); |
398 tooltip_.reset(new ShelfTooltipManager(manager, this)); | 400 tooltip_.reset(new ShelfTooltipManager(manager, this)); |
399 } | 401 } |
400 | 402 |
401 ShelfView::~ShelfView() { | 403 ShelfView::~ShelfView() { |
402 bounds_animator_->RemoveObserver(this); | 404 bounds_animator_->RemoveObserver(this); |
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1564 | 1566 |
1565 int index = view_model_->GetIndexOfView(view); | 1567 int index = view_model_->GetIndexOfView(view); |
1566 if (index == -1) | 1568 if (index == -1) |
1567 return; | 1569 return; |
1568 | 1570 |
1569 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( | 1571 ShelfItemDelegate* item_delegate = item_manager_->GetShelfItemDelegate( |
1570 model_->items()[index].id); | 1572 model_->items()[index].id); |
1571 if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) | 1573 if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) |
1572 return; // View is being deleted or not draggable, ignore request. | 1574 return; // View is being deleted or not draggable, ignore request. |
1573 | 1575 |
| 1576 // Only when the repost event occurs on the same shelf item, we should ignore |
| 1577 // the call in ShelfView::ButtonPressed(...). |
| 1578 is_repost_event_ = IsRepostEvent(event) && (last_pressed_index_ == index); |
| 1579 |
1574 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); | 1580 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); |
1575 drag_view_ = static_cast<ShelfButton*>(view); | 1581 drag_view_ = static_cast<ShelfButton*>(view); |
1576 drag_origin_ = gfx::Point(event.x(), event.y()); | 1582 drag_origin_ = gfx::Point(event.x(), event.y()); |
1577 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", | 1583 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentUsage", |
1578 layout_manager_->SelectValueForShelfAlignment( | 1584 layout_manager_->SelectValueForShelfAlignment( |
1579 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, | 1585 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM, |
1580 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, | 1586 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT, |
1581 SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT, | 1587 SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT, |
1582 -1), | 1588 -1), |
1583 SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); | 1589 SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT); |
1584 } | 1590 } |
1585 | 1591 |
1586 void ShelfView::PointerDraggedOnButton(views::View* view, | 1592 void ShelfView::PointerDraggedOnButton(views::View* view, |
1587 Pointer pointer, | 1593 Pointer pointer, |
1588 const ui::LocatedEvent& event) { | 1594 const ui::LocatedEvent& event) { |
1589 // To prepare all drag types (moving an item in the shelf and dragging off), | 1595 // To prepare all drag types (moving an item in the shelf and dragging off), |
1590 // we should check the x-axis and y-axis offset. | 1596 // we should check the x-axis and y-axis offset. |
1591 if (!dragging() && drag_view_ && | 1597 if (!dragging() && drag_view_ && |
1592 ((std::abs(event.x() - drag_origin_.x()) >= kMinimumDragDistance) || | 1598 ((std::abs(event.x() - drag_origin_.x()) >= kMinimumDragDistance) || |
1593 (std::abs(event.y() - drag_origin_.y()) >= kMinimumDragDistance))) { | 1599 (std::abs(event.y() - drag_origin_.y()) >= kMinimumDragDistance))) { |
1594 PrepareForDrag(pointer, event); | 1600 PrepareForDrag(pointer, event); |
1595 } | 1601 } |
1596 if (drag_pointer_ == pointer) | 1602 if (drag_pointer_ == pointer) |
1597 ContinueDrag(event); | 1603 ContinueDrag(event); |
1598 } | 1604 } |
1599 | 1605 |
1600 void ShelfView::PointerReleasedOnButton(views::View* view, | 1606 void ShelfView::PointerReleasedOnButton(views::View* view, |
1601 Pointer pointer, | 1607 Pointer pointer, |
1602 bool canceled) { | 1608 bool canceled) { |
| 1609 // Reset |is_repost_event| to false. |
| 1610 is_repost_event_ = false; |
| 1611 |
1603 if (canceled) { | 1612 if (canceled) { |
1604 CancelDrag(-1); | 1613 CancelDrag(-1); |
1605 } else if (drag_pointer_ == pointer) { | 1614 } else if (drag_pointer_ == pointer) { |
1606 FinalizeRipOffDrag(false); | 1615 FinalizeRipOffDrag(false); |
1607 drag_pointer_ = NONE; | 1616 drag_pointer_ = NONE; |
1608 AnimateToIdealBounds(); | 1617 AnimateToIdealBounds(); |
1609 } | 1618 } |
1610 // If the drag pointer is NONE, no drag operation is going on and the | 1619 // If the drag pointer is NONE, no drag operation is going on and the |
1611 // drag_view can be released. | 1620 // drag_view can be released. |
1612 if (drag_pointer_ == NONE) | 1621 if (drag_pointer_ == NONE) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 if (sender == overflow_button_) { | 1665 if (sender == overflow_button_) { |
1657 ToggleOverflowBubble(); | 1666 ToggleOverflowBubble(); |
1658 return; | 1667 return; |
1659 } | 1668 } |
1660 | 1669 |
1661 int view_index = view_model_->GetIndexOfView(sender); | 1670 int view_index = view_model_->GetIndexOfView(sender); |
1662 // May be -1 while in the process of animating closed. | 1671 // May be -1 while in the process of animating closed. |
1663 if (view_index == -1) | 1672 if (view_index == -1) |
1664 return; | 1673 return; |
1665 | 1674 |
1666 // If the previous menu was closed by the same event as this one, we ignore | 1675 // If the menu was just closed by the same event as this one, we ignore |
1667 // the call. | 1676 // the call and don't open the menu again. See crbug.com/343005 for more |
1668 if (!IsUsableEvent(event)) | 1677 // detail. |
| 1678 if (is_repost_event_) |
1669 return; | 1679 return; |
1670 | 1680 |
| 1681 // Record the index for the last pressed shelf item. |
| 1682 last_pressed_index_ = view_index; |
| 1683 |
1671 // Don't activate the item twice on double-click. Otherwise the window starts | 1684 // Don't activate the item twice on double-click. Otherwise the window starts |
1672 // animating open due to the first click, then immediately minimizes due to | 1685 // animating open due to the first click, then immediately minimizes due to |
1673 // the second click. The user most likely intended to open or minimize the | 1686 // the second click. The user most likely intended to open or minimize the |
1674 // item once, not do both. | 1687 // item once, not do both. |
1675 if (event.flags() & ui::EF_IS_DOUBLE_CLICK) | 1688 if (event.flags() & ui::EF_IS_DOUBLE_CLICK) |
1676 return; | 1689 return; |
1677 | 1690 |
1678 { | 1691 { |
1679 ScopedTargetRootWindow scoped_target( | 1692 ScopedTargetRootWindow scoped_target( |
1680 sender->GetWidget()->GetNativeView()->GetRootWindow()); | 1693 sender->GetWidget()->GetNativeView()->GetRootWindow()); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 ShelfButton* button = static_cast<ShelfButton*>(view); | 1883 ShelfButton* button = static_cast<ShelfButton*>(view); |
1871 button->ClearState(ShelfButton::STATE_HIDDEN); | 1884 button->ClearState(ShelfButton::STATE_HIDDEN); |
1872 break; | 1885 break; |
1873 } | 1886 } |
1874 } | 1887 } |
1875 snap_back_from_rip_off_view_ = NULL; | 1888 snap_back_from_rip_off_view_ = NULL; |
1876 } | 1889 } |
1877 } | 1890 } |
1878 } | 1891 } |
1879 | 1892 |
1880 bool ShelfView::IsUsableEvent(const ui::Event& event) { | 1893 bool ShelfView::IsRepostEvent(const ui::Event& event) { |
1881 if (closing_event_time_ == base::TimeDelta()) | 1894 if (closing_event_time_ == base::TimeDelta()) |
1882 return true; | 1895 return false; |
1883 | 1896 |
1884 base::TimeDelta delta = | 1897 base::TimeDelta delta = |
1885 base::TimeDelta(event.time_stamp() - closing_event_time_); | 1898 base::TimeDelta(event.time_stamp() - closing_event_time_); |
1886 closing_event_time_ = base::TimeDelta(); | 1899 closing_event_time_ = base::TimeDelta(); |
1887 // TODO(skuhne): This time seems excessive, but it appears that the reposting | 1900 // If the current (press down) event is a repost event, the time stamp of |
1888 // takes that long. Need to come up with a better way of doing this. | 1901 // these two events should be the same. |
1889 return (delta.InMilliseconds() < 0 || delta.InMilliseconds() > 130); | 1902 return (delta.InMilliseconds() == 0); |
1890 } | 1903 } |
1891 | 1904 |
1892 const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { | 1905 const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { |
1893 int view_index = view_model_->GetIndexOfView(view); | 1906 int view_index = view_model_->GetIndexOfView(view); |
1894 if (view_index == -1) | 1907 if (view_index == -1) |
1895 return NULL; | 1908 return NULL; |
1896 return &(model_->items()[view_index]); | 1909 return &(model_->items()[view_index]); |
1897 } | 1910 } |
1898 | 1911 |
1899 bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { | 1912 bool ShelfView::ShouldShowTooltipForView(const views::View* view) const { |
(...skipping 25 matching lines...) Expand all Loading... |
1925 distance = bounds.x() - coordinate.x(); | 1938 distance = bounds.x() - coordinate.x(); |
1926 break; | 1939 break; |
1927 case SHELF_ALIGNMENT_TOP: | 1940 case SHELF_ALIGNMENT_TOP: |
1928 distance = coordinate.y() - bounds.bottom(); | 1941 distance = coordinate.y() - bounds.bottom(); |
1929 break; | 1942 break; |
1930 } | 1943 } |
1931 return distance > 0 ? distance : 0; | 1944 return distance > 0 ? distance : 0; |
1932 } | 1945 } |
1933 | 1946 |
1934 } // namespace ash | 1947 } // namespace ash |
OLD | NEW |