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/launcher/launcher_view.h" | 5 #include "ash/launcher/launcher_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/launcher/app_list_button.h" | 10 #include "ash/launcher/app_list_button.h" |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
269 }; | 269 }; |
270 | 270 |
271 LauncherView::LauncherView(LauncherModel* model, | 271 LauncherView::LauncherView(LauncherModel* model, |
272 LauncherDelegate* delegate, | 272 LauncherDelegate* delegate, |
273 ShelfLayoutManager* shelf_layout_manager) | 273 ShelfLayoutManager* shelf_layout_manager) |
274 : model_(model), | 274 : model_(model), |
275 delegate_(delegate), | 275 delegate_(delegate), |
276 view_model_(new views::ViewModel), | 276 view_model_(new views::ViewModel), |
277 first_visible_index_(0), | 277 first_visible_index_(0), |
278 last_visible_index_(-1), | 278 last_visible_index_(-1), |
279 end_align_index_(0), | |
279 overflow_button_(NULL), | 280 overflow_button_(NULL), |
280 drag_pointer_(NONE), | 281 drag_pointer_(NONE), |
281 drag_view_(NULL), | 282 drag_view_(NULL), |
282 drag_offset_(0), | 283 drag_offset_(0), |
283 start_drag_index_(-1), | 284 start_drag_index_(-1), |
284 context_menu_id_(0), | 285 context_menu_id_(0), |
285 alignment_(SHELF_ALIGNMENT_BOTTOM), | 286 alignment_(SHELF_ALIGNMENT_BOTTOM), |
286 leading_inset_(kDefaultLeadingInset) { | 287 leading_inset_(kDefaultLeadingInset) { |
287 DCHECK(model_); | 288 DCHECK(model_); |
288 bounds_animator_.reset(new views::BoundsAnimator(this)); | 289 bounds_animator_.reset(new views::BoundsAnimator(this)); |
289 bounds_animator_->AddObserver(this); | 290 bounds_animator_->AddObserver(this); |
290 set_context_menu_controller(this); | 291 set_context_menu_controller(this); |
291 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); | 292 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); |
292 tooltip_.reset(new LauncherTooltipManager( | 293 tooltip_.reset(new LauncherTooltipManager( |
293 alignment_, shelf_layout_manager, this)); | 294 alignment_, shelf_layout_manager, this)); |
294 } | 295 } |
295 | 296 |
296 LauncherView::~LauncherView() { | 297 LauncherView::~LauncherView() { |
297 bounds_animator_->RemoveObserver(this); | 298 bounds_animator_->RemoveObserver(this); |
298 model_->RemoveObserver(this); | 299 model_->RemoveObserver(this); |
299 } | 300 } |
300 | 301 |
301 void LauncherView::Init() { | 302 void LauncherView::Init() { |
302 model_->AddObserver(this); | 303 model_->AddObserver(this); |
303 | 304 |
305 end_align_index_ = model_->EndAlignedIndex(); | |
304 const LauncherItems& items(model_->items()); | 306 const LauncherItems& items(model_->items()); |
305 for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { | 307 for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { |
306 views::View* child = CreateViewForItem(*i); | 308 views::View* child = CreateViewForItem(*i); |
307 child->SetPaintToLayer(true); | 309 child->SetPaintToLayer(true); |
308 view_model_->Add(child, static_cast<int>(i - items.begin())); | 310 view_model_->Add(child, static_cast<int>(i - items.begin())); |
309 AddChildView(child); | 311 AddChildView(child); |
310 } | 312 } |
311 UpdateFirstButtonPadding(); | 313 UpdateFirstButtonPadding(); |
312 LauncherStatusChanged(); | 314 LauncherStatusChanged(); |
313 | |
314 overflow_button_ = new OverflowButton(this); | 315 overflow_button_ = new OverflowButton(this); |
315 overflow_button_->set_context_menu_controller(this); | 316 overflow_button_->set_context_menu_controller(this); |
316 ConfigureChildView(overflow_button_); | 317 ConfigureChildView(overflow_button_); |
317 AddChildView(overflow_button_); | 318 AddChildViewAt(overflow_button_, end_align_index_); |
sky
2012/11/28 05:13:25
Does the index really matter here?
flackr
2012/11/28 18:07:52
I guess it doesn't. Reverted.
| |
318 | 319 |
319 // We'll layout when our bounds change. | 320 // We'll layout when our bounds change. |
320 } | 321 } |
321 | 322 |
322 void LauncherView::SetAlignment(ShelfAlignment alignment) { | 323 void LauncherView::SetAlignment(ShelfAlignment alignment) { |
323 if (alignment_ == alignment) | 324 if (alignment_ == alignment) |
324 return; | 325 return; |
325 alignment_ = alignment; | 326 alignment_ = alignment; |
326 UpdateFirstButtonPadding(); | 327 UpdateFirstButtonPadding(); |
327 overflow_button_->SetShelfAlignment(alignment_); | 328 overflow_button_->SetShelfAlignment(alignment_); |
328 LayoutToIdealBounds(); | 329 LayoutToIdealBounds(); |
329 tooltip_->SetArrowLocation(alignment_); | 330 tooltip_->SetArrowLocation(alignment_); |
330 if (overflow_bubble_.get()) | 331 if (overflow_bubble_.get()) |
331 overflow_bubble_->Hide(); | 332 overflow_bubble_->Hide(); |
332 } | 333 } |
333 | 334 |
334 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) { | 335 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) { |
335 int index = model_->ItemIndexByID(id); | 336 int index = model_->ItemIndexByID(id); |
336 if (index == -1 || index > last_visible_index_) | 337 if (index == -1 || (index > last_visible_index_ && |
338 index < end_align_index_)) | |
337 return gfx::Rect(); | 339 return gfx::Rect(); |
338 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); | 340 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); |
339 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); | 341 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); |
340 LauncherButton* button = | 342 LauncherButton* button = |
341 static_cast<LauncherButton*>(view_model_->view_at(index)); | 343 static_cast<LauncherButton*>(view_model_->view_at(index)); |
342 gfx::Rect icon_bounds = button->GetIconBounds(); | 344 gfx::Rect icon_bounds = button->GetIconBounds(); |
343 return gfx::Rect(ideal_bounds.x() + icon_bounds.x(), | 345 return gfx::Rect(ideal_bounds.x() + icon_bounds.x(), |
344 ideal_bounds.y() + icon_bounds.y(), | 346 ideal_bounds.y() + icon_bounds.y(), |
345 icon_bounds.width(), icon_bounds.height()); | 347 icon_bounds.width(), icon_bounds.height()); |
346 } | 348 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 return; | 402 return; |
401 | 403 |
402 // Initial x,y values account both leading_inset in primary | 404 // Initial x,y values account both leading_inset in primary |
403 // coordinate and secondary coordinate based on the dynamic edge of the | 405 // coordinate and secondary coordinate based on the dynamic edge of the |
404 // launcher (eg top edge on bottom-aligned launcher). | 406 // launcher (eg top edge on bottom-aligned launcher). |
405 int x = alignment_based_value(leading_inset(), | 407 int x = alignment_based_value(leading_inset(), |
406 width() - kLauncherPreferredSize, | 408 width() - kLauncherPreferredSize, |
407 std::max(width() - kLauncherPreferredSize, | 409 std::max(width() - kLauncherPreferredSize, |
408 ShelfLayoutManager::kAutoHideSize + 1)); | 410 ShelfLayoutManager::kAutoHideSize + 1)); |
409 int y = primary_axis_coordinate(0, leading_inset()); | 411 int y = primary_axis_coordinate(0, leading_inset()); |
410 for (int i = 0; i < view_model_->view_size(); ++i) { | 412 int w = primary_axis_coordinate(kLauncherPreferredSize, width()); |
413 int h = primary_axis_coordinate(height(), kLauncherPreferredSize); | |
414 for (int i = 0; i < end_align_index_; ++i) { | |
411 if (i < first_visible_index_) { | 415 if (i < first_visible_index_) { |
412 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); | 416 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); |
413 continue; | 417 continue; |
414 } | 418 } |
415 | 419 |
416 int w = primary_axis_coordinate(kLauncherPreferredSize, width()); | |
417 int h = primary_axis_coordinate(height(), kLauncherPreferredSize); | |
418 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 420 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
419 x = primary_axis_coordinate(x + w + kButtonSpacing, x); | 421 x = primary_axis_coordinate(x + w + kButtonSpacing, x); |
420 y = primary_axis_coordinate(y, y + h + kButtonSpacing); | 422 y = primary_axis_coordinate(y, y + h + kButtonSpacing); |
421 } | 423 } |
422 | 424 |
423 int app_list_index = view_model_->view_size() - 1; | 425 // Right aligned icons |
sky
2012/11/28 05:13:25
How do you know all the panels icons fit?
I don't
flackr
2012/11/28 18:07:52
They may not all fit. There was an open question o
sky
2012/11/28 21:59:39
I'm fine with punting, just add a TODO.
flackr
2012/11/28 23:51:22
Done.
| |
426 int end_position = available_size - kButtonSpacing; | |
427 x = primary_axis_coordinate(end_position, leading_inset()); | |
428 y = primary_axis_coordinate(0, end_position); | |
429 for (int i = view_model_->view_size() - 1; i >= end_align_index_; --i) { | |
430 x = primary_axis_coordinate(x - w - kButtonSpacing, x); | |
431 y = primary_axis_coordinate(y, y - h - kButtonSpacing); | |
432 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | |
433 end_position = primary_axis_coordinate(x, y); | |
434 } | |
435 | |
436 int app_list_index = end_align_index_ - 1; | |
424 if (is_overflow_mode()) { | 437 if (is_overflow_mode()) { |
425 last_visible_index_ = app_list_index - 1; | 438 last_visible_index_ = app_list_index - 1; |
426 for (int i = 0; i < view_model_->view_size(); ++i) { | 439 for (int i = 0; i < view_model_->view_size(); ++i) { |
427 view_model_->view_at(i)->SetVisible( | 440 view_model_->view_at(i)->SetVisible( |
428 i >= first_visible_index_ && i <= last_visible_index_); | 441 i >= first_visible_index_ && i <= last_visible_index_); |
429 } | 442 } |
430 return; | 443 return; |
431 } | 444 } |
432 | 445 |
433 bounds->overflow_bounds.set_size(gfx::Size( | 446 bounds->overflow_bounds.set_size(gfx::Size( |
434 primary_axis_coordinate(kLauncherPreferredSize, width()), | 447 primary_axis_coordinate(kLauncherPreferredSize, width()), |
435 primary_axis_coordinate(height(), kLauncherPreferredSize))); | 448 primary_axis_coordinate(height(), kLauncherPreferredSize))); |
436 last_visible_index_ = DetermineLastVisibleIndex( | 449 last_visible_index_ = DetermineLastVisibleIndex( |
437 available_size - leading_inset() - kLauncherPreferredSize - | 450 end_position - leading_inset() - 2 * kLauncherPreferredSize); |
438 kButtonSpacing - kLauncherPreferredSize); | |
439 bool show_overflow = (last_visible_index_ + 1 < app_list_index); | 451 bool show_overflow = (last_visible_index_ + 1 < app_list_index); |
440 | 452 |
441 for (int i = 0; i < view_model_->view_size(); ++i) { | 453 for (int i = 0; i < view_model_->view_size(); ++i) { |
442 view_model_->view_at(i)->SetVisible( | 454 view_model_->view_at(i)->SetVisible( |
443 i == app_list_index || i <= last_visible_index_); | 455 i <= last_visible_index_ || i >= app_list_index); |
444 } | 456 } |
445 | 457 |
446 overflow_button_->SetVisible(show_overflow); | 458 overflow_button_->SetVisible(show_overflow); |
447 if (show_overflow) { | 459 if (show_overflow) { |
448 DCHECK_NE(0, view_model_->view_size()); | 460 DCHECK_NE(0, view_model_->view_size()); |
449 if (last_visible_index_ == -1) { | 461 if (last_visible_index_ == -1) { |
450 x = alignment_based_value(leading_inset(), | 462 x = alignment_based_value(leading_inset(), |
451 width() - kLauncherPreferredSize, | 463 width() - kLauncherPreferredSize, |
452 std::max(width() - kLauncherPreferredSize, | 464 std::max(width() - kLauncherPreferredSize, |
453 ShelfLayoutManager::kAutoHideSize + 1)); | 465 ShelfLayoutManager::kAutoHideSize + 1)); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
595 | 607 |
596 // If the item is no longer draggable, bail out. | 608 // If the item is no longer draggable, bail out. |
597 if (current_index == -1 || | 609 if (current_index == -1 || |
598 !delegate_->IsDraggable(model_->items()[current_index])) { | 610 !delegate_->IsDraggable(model_->items()[current_index])) { |
599 CancelDrag(-1); | 611 CancelDrag(-1); |
600 return; | 612 return; |
601 } | 613 } |
602 | 614 |
603 // Constrain the location to the range of valid indices for the type. | 615 // Constrain the location to the range of valid indices for the type. |
604 std::pair<int, int> indices(GetDragRange(current_index)); | 616 std::pair<int, int> indices(GetDragRange(current_index)); |
617 int first_drag_index = indices.first; | |
605 int last_drag_index = indices.second; | 618 int last_drag_index = indices.second; |
606 // If the last index isn't valid, we're overflowing. Constrain to the app list | 619 // If the last index isn't valid, we're overflowing. Constrain to the app list |
607 // (which is the last visible item). | 620 // (which is the last visible item). |
608 if (last_drag_index > last_visible_index_) | 621 if (first_drag_index < end_align_index_ && |
622 last_drag_index > last_visible_index_) | |
609 last_drag_index = last_visible_index_; | 623 last_drag_index = last_visible_index_; |
610 int x = 0, y = 0; | 624 int x = 0, y = 0; |
611 if (is_horizontal_alignment()) { | 625 if (is_horizontal_alignment()) { |
612 x = std::max(view_model_->ideal_bounds(indices.first).x(), | 626 x = std::max(view_model_->ideal_bounds(indices.first).x(), |
613 drag_point.x() - drag_offset_); | 627 drag_point.x() - drag_offset_); |
614 x = std::min(view_model_->ideal_bounds(last_drag_index).right() - | 628 x = std::min(view_model_->ideal_bounds(last_drag_index).right() - |
615 view_model_->ideal_bounds(current_index).width(), | 629 view_model_->ideal_bounds(current_index).width(), |
616 x); | 630 x); |
617 if (drag_view_->x() == x) | 631 if (drag_view_->x() == x) |
618 return; | 632 return; |
(...skipping 24 matching lines...) Expand all Loading... | |
643 // Change the model, the LauncherItemMoved() callback will handle the | 657 // Change the model, the LauncherItemMoved() callback will handle the |
644 // |view_model_| update. | 658 // |view_model_| update. |
645 model_->Move(current_index, target_index); | 659 model_->Move(current_index, target_index); |
646 bounds_animator_->StopAnimatingView(drag_view_); | 660 bounds_animator_->StopAnimatingView(drag_view_); |
647 } | 661 } |
648 | 662 |
649 bool LauncherView::SameDragType(LauncherItemType typea, | 663 bool LauncherView::SameDragType(LauncherItemType typea, |
650 LauncherItemType typeb) const { | 664 LauncherItemType typeb) const { |
651 switch (typea) { | 665 switch (typea) { |
652 case TYPE_TABBED: | 666 case TYPE_TABBED: |
653 case TYPE_APP_PANEL: | |
654 case TYPE_PLATFORM_APP: | 667 case TYPE_PLATFORM_APP: |
655 return (typeb == TYPE_TABBED || | 668 return (typeb == TYPE_TABBED || typeb == TYPE_PLATFORM_APP); |
656 typeb == TYPE_APP_PANEL || | |
657 typeb == TYPE_PLATFORM_APP); | |
658 case TYPE_APP_SHORTCUT: | 669 case TYPE_APP_SHORTCUT: |
659 case TYPE_APP_LIST: | 670 case TYPE_APP_LIST: |
671 case TYPE_APP_PANEL: | |
660 case TYPE_BROWSER_SHORTCUT: | 672 case TYPE_BROWSER_SHORTCUT: |
661 return typeb == typea; | 673 return typeb == typea; |
662 } | 674 } |
663 NOTREACHED(); | 675 NOTREACHED(); |
664 return false; | 676 return false; |
665 } | 677 } |
666 | 678 |
667 std::pair<int, int> LauncherView::GetDragRange(int index) { | 679 std::pair<int, int> LauncherView::GetDragRange(int index) { |
668 int min_index = -1; | 680 int min_index = -1; |
669 int max_index = -1; | 681 int max_index = -1; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
795 | 807 |
796 void LauncherView::LauncherItemAdded(int model_index) { | 808 void LauncherView::LauncherItemAdded(int model_index) { |
797 model_index = CancelDrag(model_index); | 809 model_index = CancelDrag(model_index); |
798 views::View* view = CreateViewForItem(model_->items()[model_index]); | 810 views::View* view = CreateViewForItem(model_->items()[model_index]); |
799 AddChildView(view); | 811 AddChildView(view); |
800 // Hide the view, it'll be made visible when the animation is done. Using | 812 // Hide the view, it'll be made visible when the animation is done. Using |
801 // opacity 0 here to avoid messing with CalculateIdealBounds which touches | 813 // opacity 0 here to avoid messing with CalculateIdealBounds which touches |
802 // the view's visibility. | 814 // the view's visibility. |
803 view->layer()->SetOpacity(0); | 815 view->layer()->SetOpacity(0); |
804 view_model_->Add(view, model_index); | 816 view_model_->Add(view, model_index); |
817 end_align_index_ = model_->EndAlignedIndex(); | |
805 | 818 |
806 // Give the button its ideal bounds. That way if we end up animating the | 819 // Give the button its ideal bounds. That way if we end up animating the |
807 // button before this animation completes it doesn't appear at some random | 820 // button before this animation completes it doesn't appear at some random |
808 // spot (because it was in the middle of animating from 0,0 0x0 to its | 821 // spot (because it was in the middle of animating from 0,0 0x0 to its |
809 // target). | 822 // target). |
810 IdealBounds ideal_bounds; | 823 IdealBounds ideal_bounds; |
811 CalculateIdealBounds(&ideal_bounds); | 824 CalculateIdealBounds(&ideal_bounds); |
812 view->SetBoundsRect(view_model_->ideal_bounds(model_index)); | 825 view->SetBoundsRect(view_model_->ideal_bounds(model_index)); |
813 | 826 |
814 // The first animation moves all the views to their target position. |view| | 827 // The first animation moves all the views to their target position. |view| |
815 // is hidden, so it visually appears as though we are providing space for | 828 // is hidden, so it visually appears as though we are providing space for |
816 // it. When done we'll fade the view in. | 829 // it. When done we'll fade the view in. |
817 AnimateToIdealBounds(); | 830 AnimateToIdealBounds(); |
818 if (model_index <= last_visible_index_) { | 831 if (model_index <= last_visible_index_ || model_index >= end_align_index_) { |
819 bounds_animator_->SetAnimationDelegate( | 832 bounds_animator_->SetAnimationDelegate( |
820 view, new StartFadeAnimationDelegate(this, view), true); | 833 view, new StartFadeAnimationDelegate(this, view), true); |
821 } else { | 834 } else { |
822 // Undo the hiding if animation does not run. | 835 // Undo the hiding if animation does not run. |
823 view->layer()->SetOpacity(1.0f); | 836 view->layer()->SetOpacity(1.0f); |
824 } | 837 } |
825 } | 838 } |
826 | 839 |
827 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) { | 840 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) { |
828 #if !defined(OS_MACOSX) | 841 #if !defined(OS_MACOSX) |
829 if (id == context_menu_id_) | 842 if (id == context_menu_id_) |
830 launcher_menu_runner_.reset(); | 843 launcher_menu_runner_.reset(); |
831 #endif | 844 #endif |
832 model_index = CancelDrag(model_index); | 845 model_index = CancelDrag(model_index); |
833 views::View* view = view_model_->view_at(model_index); | 846 views::View* view = view_model_->view_at(model_index); |
834 view_model_->Remove(model_index); | 847 view_model_->Remove(model_index); |
848 end_align_index_ = model_->EndAlignedIndex(); | |
835 // The first animation fades out the view. When done we'll animate the rest of | 849 // The first animation fades out the view. When done we'll animate the rest of |
836 // the views to their target location. | 850 // the views to their target location. |
837 bounds_animator_->AnimateViewTo(view, view->bounds()); | 851 bounds_animator_->AnimateViewTo(view, view->bounds()); |
838 bounds_animator_->SetAnimationDelegate( | 852 bounds_animator_->SetAnimationDelegate( |
839 view, new FadeOutAnimationDelegate(this, view), true); | 853 view, new FadeOutAnimationDelegate(this, view), true); |
840 } | 854 } |
841 | 855 |
842 void LauncherView::LauncherItemChanged(int model_index, | 856 void LauncherView::LauncherItemChanged(int model_index, |
843 const ash::LauncherItem& old_item) { | 857 const ash::LauncherItem& old_item) { |
844 const LauncherItem& item(model_->items()[model_index]); | 858 const LauncherItem& item(model_->items()[model_index]); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1087 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | 1101 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, |
1088 OnLauncherIconPositionsChanged()); | 1102 OnLauncherIconPositionsChanged()); |
1089 PreferredSizeChanged(); | 1103 PreferredSizeChanged(); |
1090 } | 1104 } |
1091 | 1105 |
1092 void LauncherView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { | 1106 void LauncherView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { |
1093 } | 1107 } |
1094 | 1108 |
1095 } // namespace internal | 1109 } // namespace internal |
1096 } // namespace ash | 1110 } // namespace ash |
OLD | NEW |