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 |