| 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 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "ash/ash_constants.h" | 10 #include "ash/ash_constants.h" |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 } | 290 } |
| 291 tooltip_.Close(); | 291 tooltip_.Close(); |
| 292 if (overflow_bubble_) | 292 if (overflow_bubble_) |
| 293 overflow_bubble_->Hide(); | 293 overflow_bubble_->Hide(); |
| 294 // For crbug.com/587931, because AppListButton layout logic is in OnPaint. | 294 // For crbug.com/587931, because AppListButton layout logic is in OnPaint. |
| 295 AppListButton* app_list_button = GetAppListButton(); | 295 AppListButton* app_list_button = GetAppListButton(); |
| 296 if (app_list_button) | 296 if (app_list_button) |
| 297 app_list_button->SchedulePaint(); | 297 app_list_button->SchedulePaint(); |
| 298 } | 298 } |
| 299 | 299 |
| 300 gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(ShelfID id) { | 300 gfx::Rect ShelfView::GetIdealBoundsOfItemIcon(const ShelfID& id) { |
| 301 int index = model_->ItemIndexByID(id); | 301 int index = model_->ItemIndexByID(id); |
| 302 if (index < 0 || last_visible_index_ < 0) | 302 if (index < 0 || last_visible_index_ < 0) |
| 303 return gfx::Rect(); | 303 return gfx::Rect(); |
| 304 // Map all items from overflow area to the overflow button. Note that the | 304 // Map all items from overflow area to the overflow button. Note that the |
| 305 // section between last_index_hidden_ and model_->FirstPanelIndex() is the | 305 // section between last_index_hidden_ and model_->FirstPanelIndex() is the |
| 306 // list of invisible panel items. However, these items are currently nowhere | 306 // list of invisible panel items. However, these items are currently nowhere |
| 307 // represented and get dropped instead - see (crbug.com/378907). As such there | 307 // represented and get dropped instead - see (crbug.com/378907). As such there |
| 308 // is no way to address them or place them. We therefore move them over the | 308 // is no way to address them or place them. We therefore move them over the |
| 309 // overflow button. | 309 // overflow button. |
| 310 if (index > last_visible_index_ && index < model_->FirstPanelIndex()) | 310 if (index > last_visible_index_ && index < model_->FirstPanelIndex()) |
| 311 index = last_visible_index_ + 1; | 311 index = last_visible_index_ + 1; |
| 312 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); | 312 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); |
| 313 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); | 313 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); |
| 314 views::View* view = view_model_->view_at(index); | 314 views::View* view = view_model_->view_at(index); |
| 315 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); | 315 CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); |
| 316 ShelfButton* button = static_cast<ShelfButton*>(view); | 316 ShelfButton* button = static_cast<ShelfButton*>(view); |
| 317 gfx::Rect icon_bounds = button->GetIconBounds(); | 317 gfx::Rect icon_bounds = button->GetIconBounds(); |
| 318 return gfx::Rect(GetMirroredXWithWidthInView( | 318 return gfx::Rect(GetMirroredXWithWidthInView( |
| 319 ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()), | 319 ideal_bounds.x() + icon_bounds.x(), icon_bounds.width()), |
| 320 ideal_bounds.y() + icon_bounds.y(), icon_bounds.width(), | 320 ideal_bounds.y() + icon_bounds.y(), icon_bounds.width(), |
| 321 icon_bounds.height()); | 321 icon_bounds.height()); |
| 322 } | 322 } |
| 323 | 323 |
| 324 void ShelfView::UpdatePanelIconPosition(ShelfID id, | 324 void ShelfView::UpdatePanelIconPosition(const ShelfID& id, |
| 325 const gfx::Point& midpoint) { | 325 const gfx::Point& midpoint) { |
| 326 int current_index = model_->ItemIndexByID(id); | 326 int current_index = model_->ItemIndexByID(id); |
| 327 int first_panel_index = model_->FirstPanelIndex(); | 327 int first_panel_index = model_->FirstPanelIndex(); |
| 328 if (current_index < first_panel_index) | 328 if (current_index < first_panel_index) |
| 329 return; | 329 return; |
| 330 | 330 |
| 331 gfx::Point midpoint_in_view(GetMirroredXInView(midpoint.x()), midpoint.y()); | 331 gfx::Point midpoint_in_view(GetMirroredXInView(midpoint.x()), midpoint.y()); |
| 332 int target_index = current_index; | 332 int target_index = current_index; |
| 333 while ( | 333 while ( |
| 334 target_index > first_panel_index && | 334 target_index > first_panel_index && |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 522 |
| 523 void ShelfView::DestroyDragIconProxy() { | 523 void ShelfView::DestroyDragIconProxy() { |
| 524 drag_image_.reset(); | 524 drag_image_.reset(); |
| 525 drag_image_offset_ = gfx::Vector2d(0, 0); | 525 drag_image_offset_ = gfx::Vector2d(0, 0); |
| 526 } | 526 } |
| 527 | 527 |
| 528 bool ShelfView::StartDrag(const std::string& app_id, | 528 bool ShelfView::StartDrag(const std::string& app_id, |
| 529 const gfx::Point& location_in_screen_coordinates) { | 529 const gfx::Point& location_in_screen_coordinates) { |
| 530 // Bail if an operation is already going on - or the cursor is not inside. | 530 // Bail if an operation is already going on - or the cursor is not inside. |
| 531 // This could happen if mouse / touch operations overlap. | 531 // This could happen if mouse / touch operations overlap. |
| 532 if (drag_and_drop_shelf_id_ || | 532 if (!drag_and_drop_shelf_id_.IsNull() || |
| 533 !GetBoundsInScreen().Contains(location_in_screen_coordinates)) | 533 !GetBoundsInScreen().Contains(location_in_screen_coordinates)) |
| 534 return false; | 534 return false; |
| 535 | 535 |
| 536 // If the AppsGridView (which was dispatching this event) was opened by our | 536 // If the AppsGridView (which was dispatching this event) was opened by our |
| 537 // button, ShelfView dragging operations are locked and we have to unlock. | 537 // button, ShelfView dragging operations are locked and we have to unlock. |
| 538 CancelDrag(-1); | 538 CancelDrag(-1); |
| 539 drag_and_drop_item_pinned_ = false; | 539 drag_and_drop_item_pinned_ = false; |
| 540 drag_and_drop_app_id_ = app_id; | 540 drag_and_drop_app_id_ = app_id; |
| 541 drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_); | 541 drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_); |
| 542 // Check if the application is known and pinned - if not, we have to pin it so | 542 // Check if the application is known and pinned - if not, we have to pin it so |
| 543 // that we can re-arrange the shelf order accordingly. Note that items have | 543 // that we can re-arrange the shelf order accordingly. Note that items have |
| 544 // to be pinned to give them the same (order) possibilities as a shortcut. | 544 // to be pinned to give them the same (order) possibilities as a shortcut. |
| 545 // When an item is dragged from overflow to shelf, IsShowingOverflowBubble() | 545 // When an item is dragged from overflow to shelf, IsShowingOverflowBubble() |
| 546 // returns true. At this time, we don't need to pin the item. | 546 // returns true. At this time, we don't need to pin the item. |
| 547 if (!IsShowingOverflowBubble() && | 547 if (!IsShowingOverflowBubble() && |
| 548 (!drag_and_drop_shelf_id_ || !model_->IsAppPinned(app_id))) { | 548 (drag_and_drop_shelf_id_.IsNull() || !model_->IsAppPinned(app_id))) { |
| 549 model_->PinAppWithID(app_id); | 549 model_->PinAppWithID(app_id); |
| 550 drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_); | 550 drag_and_drop_shelf_id_ = model_->GetShelfIDForAppID(drag_and_drop_app_id_); |
| 551 if (!drag_and_drop_shelf_id_) | 551 if (drag_and_drop_shelf_id_.IsNull()) |
| 552 return false; | 552 return false; |
| 553 drag_and_drop_item_pinned_ = true; | 553 drag_and_drop_item_pinned_ = true; |
| 554 } | 554 } |
| 555 views::View* drag_and_drop_view = | 555 views::View* drag_and_drop_view = |
| 556 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); | 556 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); |
| 557 DCHECK(drag_and_drop_view); | 557 DCHECK(drag_and_drop_view); |
| 558 | 558 |
| 559 // Since there is already an icon presented by the caller, we hide this item | 559 // Since there is already an icon presented by the caller, we hide this item |
| 560 // for now. That has to be done by reducing the size since the visibility will | 560 // for now. That has to be done by reducing the size since the visibility will |
| 561 // change once a regrouping animation is performed. | 561 // change once a regrouping animation is performed. |
| 562 pre_drag_and_drop_size_ = drag_and_drop_view->size(); | 562 pre_drag_and_drop_size_ = drag_and_drop_view->size(); |
| 563 drag_and_drop_view->SetSize(gfx::Size()); | 563 drag_and_drop_view->SetSize(gfx::Size()); |
| 564 | 564 |
| 565 // First we have to center the mouse cursor over the item. | 565 // First we have to center the mouse cursor over the item. |
| 566 gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint(); | 566 gfx::Point pt = drag_and_drop_view->GetBoundsInScreen().CenterPoint(); |
| 567 views::View::ConvertPointFromScreen(drag_and_drop_view, &pt); | 567 views::View::ConvertPointFromScreen(drag_and_drop_view, &pt); |
| 568 gfx::Point point_in_root = | 568 gfx::Point point_in_root = |
| 569 wm::GetRootWindowAt(location_in_screen_coordinates) | 569 wm::GetRootWindowAt(location_in_screen_coordinates) |
| 570 ->ConvertPointFromScreen(location_in_screen_coordinates); | 570 ->ConvertPointFromScreen(location_in_screen_coordinates); |
| 571 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, pt, point_in_root, | 571 ui::MouseEvent event(ui::ET_MOUSE_PRESSED, pt, point_in_root, |
| 572 ui::EventTimeForNow(), 0, 0); | 572 ui::EventTimeForNow(), 0, 0); |
| 573 PointerPressedOnButton(drag_and_drop_view, DRAG_AND_DROP, event); | 573 PointerPressedOnButton(drag_and_drop_view, DRAG_AND_DROP, event); |
| 574 | 574 |
| 575 // Drag the item where it really belongs. | 575 // Drag the item where it really belongs. |
| 576 Drag(location_in_screen_coordinates); | 576 Drag(location_in_screen_coordinates); |
| 577 return true; | 577 return true; |
| 578 } | 578 } |
| 579 | 579 |
| 580 bool ShelfView::Drag(const gfx::Point& location_in_screen_coordinates) { | 580 bool ShelfView::Drag(const gfx::Point& location_in_screen_coordinates) { |
| 581 if (!drag_and_drop_shelf_id_ || | 581 if (drag_and_drop_shelf_id_.IsNull() || |
| 582 !GetBoundsInScreen().Contains(location_in_screen_coordinates)) | 582 !GetBoundsInScreen().Contains(location_in_screen_coordinates)) |
| 583 return false; | 583 return false; |
| 584 | 584 |
| 585 gfx::Point pt = location_in_screen_coordinates; | 585 gfx::Point pt = location_in_screen_coordinates; |
| 586 views::View* drag_and_drop_view = | 586 views::View* drag_and_drop_view = |
| 587 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); | 587 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); |
| 588 ConvertPointFromScreen(drag_and_drop_view, &pt); | 588 ConvertPointFromScreen(drag_and_drop_view, &pt); |
| 589 gfx::Point point_in_root = | 589 gfx::Point point_in_root = |
| 590 wm::GetRootWindowAt(location_in_screen_coordinates) | 590 wm::GetRootWindowAt(location_in_screen_coordinates) |
| 591 ->ConvertPointFromScreen(location_in_screen_coordinates); | 591 ->ConvertPointFromScreen(location_in_screen_coordinates); |
| 592 ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, point_in_root, | 592 ui::MouseEvent event(ui::ET_MOUSE_DRAGGED, pt, point_in_root, |
| 593 ui::EventTimeForNow(), 0, 0); | 593 ui::EventTimeForNow(), 0, 0); |
| 594 PointerDraggedOnButton(drag_and_drop_view, DRAG_AND_DROP, event); | 594 PointerDraggedOnButton(drag_and_drop_view, DRAG_AND_DROP, event); |
| 595 return true; | 595 return true; |
| 596 } | 596 } |
| 597 | 597 |
| 598 void ShelfView::EndDrag(bool cancel) { | 598 void ShelfView::EndDrag(bool cancel) { |
| 599 if (!drag_and_drop_shelf_id_) | 599 if (drag_and_drop_shelf_id_.IsNull()) |
| 600 return; | 600 return; |
| 601 | 601 |
| 602 views::View* drag_and_drop_view = | 602 views::View* drag_and_drop_view = |
| 603 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); | 603 view_model_->view_at(model_->ItemIndexByID(drag_and_drop_shelf_id_)); |
| 604 PointerReleasedOnButton(drag_and_drop_view, DRAG_AND_DROP, cancel); | 604 PointerReleasedOnButton(drag_and_drop_view, DRAG_AND_DROP, cancel); |
| 605 | 605 |
| 606 // Either destroy the temporarily created item - or - make the item visible. | 606 // Either destroy the temporarily created item - or - make the item visible. |
| 607 if (drag_and_drop_item_pinned_ && cancel) { | 607 if (drag_and_drop_item_pinned_ && cancel) { |
| 608 model_->UnpinAppWithID(drag_and_drop_app_id_); | 608 model_->UnpinAppWithID(drag_and_drop_app_id_); |
| 609 } else if (drag_and_drop_view) { | 609 } else if (drag_and_drop_view) { |
| 610 if (cancel) { | 610 if (cancel) { |
| 611 // When a hosted drag gets canceled, the item can remain in the same slot | 611 // When a hosted drag gets canceled, the item can remain in the same slot |
| 612 // and it might have moved within the bounds. In that case the item need | 612 // and it might have moved within the bounds. In that case the item need |
| 613 // to animate back to its correct location. | 613 // to animate back to its correct location. |
| 614 AnimateToIdealBounds(); | 614 AnimateToIdealBounds(); |
| 615 } else { | 615 } else { |
| 616 drag_and_drop_view->SetSize(pre_drag_and_drop_size_); | 616 drag_and_drop_view->SetSize(pre_drag_and_drop_size_); |
| 617 } | 617 } |
| 618 } | 618 } |
| 619 | 619 |
| 620 drag_and_drop_shelf_id_ = 0; | 620 drag_and_drop_shelf_id_ = ShelfID(); |
| 621 } | 621 } |
| 622 | 622 |
| 623 bool ShelfView::ShouldEventActivateButton(View* view, const ui::Event& event) { | 623 bool ShelfView::ShouldEventActivateButton(View* view, const ui::Event& event) { |
| 624 if (dragging()) | 624 if (dragging()) |
| 625 return false; | 625 return false; |
| 626 | 626 |
| 627 // Ignore if we are already in a pointer event sequence started with a repost | 627 // Ignore if we are already in a pointer event sequence started with a repost |
| 628 // event on the same shelf item. See crbug.com/343005 for more detail. | 628 // event on the same shelf item. See crbug.com/343005 for more detail. |
| 629 if (is_repost_event_on_same_item_) | 629 if (is_repost_event_on_same_item_) |
| 630 return false; | 630 return false; |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { | 962 void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { |
| 963 DCHECK(dragging()); | 963 DCHECK(dragging()); |
| 964 DCHECK(drag_view_); | 964 DCHECK(drag_view_); |
| 965 // Due to a syncing operation the application might have been removed. | 965 // Due to a syncing operation the application might have been removed. |
| 966 // Bail if it is gone. | 966 // Bail if it is gone. |
| 967 int current_index = view_model_->GetIndexOfView(drag_view_); | 967 int current_index = view_model_->GetIndexOfView(drag_view_); |
| 968 DCHECK_NE(-1, current_index); | 968 DCHECK_NE(-1, current_index); |
| 969 | 969 |
| 970 // If this is not a drag and drop host operation and not the app list item, | 970 // If this is not a drag and drop host operation and not the app list item, |
| 971 // check if the item got ripped off the shelf - if it did we are done. | 971 // check if the item got ripped off the shelf - if it did we are done. |
| 972 if (!drag_and_drop_shelf_id_ && | 972 if (drag_and_drop_shelf_id_.IsNull() && |
| 973 RemovableByRipOff(current_index) != NOT_REMOVABLE) { | 973 RemovableByRipOff(current_index) != NOT_REMOVABLE) { |
| 974 if (HandleRipOffDrag(event)) | 974 if (HandleRipOffDrag(event)) |
| 975 return; | 975 return; |
| 976 // The rip off handler could have changed the location of the item. | 976 // The rip off handler could have changed the location of the item. |
| 977 current_index = view_model_->GetIndexOfView(drag_view_); | 977 current_index = view_model_->GetIndexOfView(drag_view_); |
| 978 } | 978 } |
| 979 | 979 |
| 980 // TODO: I don't think this works correctly with RTL. | 980 // TODO: I don't think this works correctly with RTL. |
| 981 gfx::Point drag_point(event.location()); | 981 gfx::Point drag_point(event.location()); |
| 982 ConvertPointToTarget(drag_view_, this, &drag_point); | 982 ConvertPointToTarget(drag_view_, this, &drag_point); |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1606 if (!item) { | 1606 if (!item) { |
| 1607 ShellPort::Get()->ShowContextMenu(point, source_type); | 1607 ShellPort::Get()->ShowContextMenu(point, source_type); |
| 1608 return; | 1608 return; |
| 1609 } | 1609 } |
| 1610 | 1610 |
| 1611 std::unique_ptr<ui::MenuModel> context_menu_model( | 1611 std::unique_ptr<ui::MenuModel> context_menu_model( |
| 1612 Shell::Get()->shell_delegate()->CreateContextMenu(wm_shelf_, item)); | 1612 Shell::Get()->shell_delegate()->CreateContextMenu(wm_shelf_, item)); |
| 1613 if (!context_menu_model) | 1613 if (!context_menu_model) |
| 1614 return; | 1614 return; |
| 1615 | 1615 |
| 1616 context_menu_id_ = item ? item->id : 0; | 1616 context_menu_id_ = item ? item->id : ShelfID(); |
| 1617 ShowMenu(std::move(context_menu_model), source, point, true, source_type, | 1617 ShowMenu(std::move(context_menu_model), source, point, true, source_type, |
| 1618 nullptr); | 1618 nullptr); |
| 1619 } | 1619 } |
| 1620 | 1620 |
| 1621 void ShelfView::ShowMenu(std::unique_ptr<ui::MenuModel> menu_model, | 1621 void ShelfView::ShowMenu(std::unique_ptr<ui::MenuModel> menu_model, |
| 1622 views::View* source, | 1622 views::View* source, |
| 1623 const gfx::Point& click_point, | 1623 const gfx::Point& click_point, |
| 1624 bool context_menu, | 1624 bool context_menu, |
| 1625 ui::MenuSourceType source_type, | 1625 ui::MenuSourceType source_type, |
| 1626 views::InkDrop* ink_drop) { | 1626 views::InkDrop* ink_drop) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 break; | 1669 break; |
| 1670 } | 1670 } |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 // NOTE: if you convert to HAS_MNEMONICS be sure to update menu building code. | 1673 // NOTE: if you convert to HAS_MNEMONICS be sure to update menu building code. |
| 1674 launcher_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, anchor, | 1674 launcher_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, anchor, |
| 1675 menu_alignment, source_type); | 1675 menu_alignment, source_type); |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 void ShelfView::OnMenuClosed(views::InkDrop* ink_drop) { | 1678 void ShelfView::OnMenuClosed(views::InkDrop* ink_drop) { |
| 1679 context_menu_id_ = 0; | 1679 context_menu_id_ = ShelfID(); |
| 1680 | 1680 |
| 1681 // Hide the hide overflow bubble after showing a context menu for its items. | 1681 // Hide the hide overflow bubble after showing a context menu for its items. |
| 1682 if (owner_overflow_bubble_) | 1682 if (owner_overflow_bubble_) |
| 1683 owner_overflow_bubble_->Hide(); | 1683 owner_overflow_bubble_->Hide(); |
| 1684 | 1684 |
| 1685 closing_event_time_ = launcher_menu_runner_->closing_event_time(); | 1685 closing_event_time_ = launcher_menu_runner_->closing_event_time(); |
| 1686 | 1686 |
| 1687 if (ink_drop) | 1687 if (ink_drop) |
| 1688 ink_drop->AnimateToState(views::InkDropState::DEACTIVATED); | 1688 ink_drop->AnimateToState(views::InkDropState::DEACTIVATED); |
| 1689 | 1689 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 if (pointer == TOUCH && | 1761 if (pointer == TOUCH && |
| 1762 (base::TimeTicks::Now() - touch_press_time_) < | 1762 (base::TimeTicks::Now() - touch_press_time_) < |
| 1763 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { | 1763 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { |
| 1764 return false; | 1764 return false; |
| 1765 } | 1765 } |
| 1766 | 1766 |
| 1767 return true; | 1767 return true; |
| 1768 } | 1768 } |
| 1769 | 1769 |
| 1770 } // namespace ash | 1770 } // namespace ash |
| OLD | NEW |