Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "ui/aura_shell/launcher/launcher_view.h" | 5 #include "ui/aura_shell/launcher/launcher_view.h" |
| 6 | 6 |
| 7 #include "base/utf_string_conversions.h" | 7 #include "base/utf_string_conversions.h" |
| 8 #include "grit/ui_resources.h" | 8 #include "grit/ui_resources.h" |
| 9 #include "ui/aura_shell/launcher/app_launcher_button.h" | 9 #include "ui/aura_shell/launcher/app_launcher_button.h" |
| 10 #include "ui/aura_shell/launcher/launcher_model.h" | 10 #include "ui/aura_shell/launcher/launcher_model.h" |
| 11 #include "ui/aura_shell/launcher/tabbed_launcher_button.h" | 11 #include "ui/aura_shell/launcher/tabbed_launcher_button.h" |
| 12 #include "ui/aura_shell/launcher/view_model.h" | 12 #include "ui/aura_shell/launcher/view_model.h" |
| 13 #include "ui/aura_shell/launcher/view_model_utils.h" | 13 #include "ui/aura_shell/launcher/view_model_utils.h" |
| 14 #include "ui/aura_shell/shell.h" | 14 #include "ui/aura_shell/shell.h" |
| 15 #include "ui/aura_shell/shell_delegate.h" | 15 #include "ui/aura_shell/shell_delegate.h" |
| 16 #include "ui/base/animation/animation.h" | |
| 16 #include "ui/base/resource/resource_bundle.h" | 17 #include "ui/base/resource/resource_bundle.h" |
| 18 #include "ui/gfx/compositor/layer.h" | |
| 17 #include "ui/gfx/image/image.h" | 19 #include "ui/gfx/image/image.h" |
| 18 #include "views/animation/bounds_animator.h" | 20 #include "views/animation/bounds_animator.h" |
| 19 #include "views/controls/button/image_button.h" | 21 #include "views/controls/button/image_button.h" |
| 20 #include "views/widget/widget.h" | 22 #include "views/widget/widget.h" |
| 21 | 23 |
| 24 using ui::Animation; | |
| 22 using views::View; | 25 using views::View; |
| 23 | 26 |
| 24 namespace aura_shell { | 27 namespace aura_shell { |
| 25 namespace internal { | 28 namespace internal { |
| 26 | 29 |
| 27 // Padding between each view. | 30 // Padding between each view. |
| 28 static const int kHorizontalPadding = 12; | 31 static const int kHorizontalPadding = 12; |
| 29 | 32 |
| 30 // Amount content is inset on the left edge. | 33 // Amount content is inset on the left edge. |
| 31 static const int kLeadingInset = 8; | 34 static const int kLeadingInset = 8; |
| 32 | 35 |
| 33 // Height of the LauncherView. Hard coded to avoid resizing as items are | 36 // Height of the LauncherView. Hard coded to avoid resizing as items are |
| 34 // added/removed. | 37 // added/removed. |
| 35 static const int kPreferredHeight = 48; | 38 static const int kPreferredHeight = 48; |
| 36 | 39 |
| 37 // Minimum distance before drag starts. | 40 // Minimum distance before drag starts. |
| 38 static const int kMinimumDragDistance = 8; | 41 static const int kMinimumDragDistance = 8; |
| 39 | 42 |
| 40 namespace { | 43 namespace { |
| 41 | 44 |
| 42 // AnimationDelegate that deletes a view when done. This is used when a launcher | 45 // AnimationDelegate that deletes a view when done. This is used when a launcher |
| 43 // item is removed, which triggers a remove animation. When the animation is | 46 // item is removed, which triggers a remove animation. When the animation is |
| 44 // done we delete the view. | 47 // done we delete the view. |
| 45 class DeleteViewAnimationDelegate : | 48 class DeleteViewAnimationDelegate : |
| 46 public views::BoundsAnimator::OwnedAnimationDelegate { | 49 public views::BoundsAnimator::OwnedAnimationDelegate { |
| 47 public: | 50 public: |
| 48 DeleteViewAnimationDelegate(views::View* view) : view_(view) {} | 51 explicit DeleteViewAnimationDelegate(views::View* view) : view_(view) {} |
| 49 virtual ~DeleteViewAnimationDelegate() {} | 52 virtual ~DeleteViewAnimationDelegate() {} |
| 50 | 53 |
| 51 private: | 54 private: |
| 52 scoped_ptr<views::View> view_; | 55 scoped_ptr<views::View> view_; |
| 53 | 56 |
| 54 DISALLOW_COPY_AND_ASSIGN(DeleteViewAnimationDelegate); | 57 DISALLOW_COPY_AND_ASSIGN(DeleteViewAnimationDelegate); |
| 55 }; | 58 }; |
| 56 | 59 |
| 60 // AnimationDelegate used when inserting a new item. This steadily increases the | |
| 61 // opacity of the layer as the animation progress. | |
| 62 class FadeInAnimationDelegate : | |
| 63 public views::BoundsAnimator::OwnedAnimationDelegate { | |
| 64 public: | |
| 65 explicit FadeInAnimationDelegate(views::View* view) : view_(view) {} | |
| 66 virtual ~FadeInAnimationDelegate() {} | |
| 67 | |
| 68 // AnimationDelegate overrides: | |
| 69 virtual void AnimationProgressed(const Animation* animation) OVERRIDE { | |
| 70 view_->layer()->SetOpacity(animation->GetCurrentValue()); | |
| 71 view_->layer()->ScheduleDraw(); | |
| 72 } | |
| 73 virtual void AnimationEnded(const Animation* animation) OVERRIDE { | |
| 74 view_->layer()->SetOpacity(1.0f); | |
| 75 view_->layer()->ScheduleDraw(); | |
| 76 } | |
| 77 virtual void AnimationCanceled(const Animation* animation) OVERRIDE { | |
| 78 view_->layer()->SetOpacity(1.0f); | |
| 79 view_->layer()->ScheduleDraw(); | |
|
Ben Goodger (Google)
2011/10/21 23:03:49
I think the default impl of this function calls An
| |
| 80 } | |
| 81 | |
| 82 private: | |
| 83 views::View* view_; | |
| 84 | |
| 85 DISALLOW_COPY_AND_ASSIGN(FadeInAnimationDelegate); | |
| 86 }; | |
| 87 | |
| 57 } // namespace | 88 } // namespace |
| 58 | 89 |
| 90 // AnimationDelegate used when inserting a new item. This steadily decreased the | |
| 91 // opacity of the layer as the animation progress. | |
| 92 class LauncherView::FadeOutAnimationDelegate : | |
| 93 public views::BoundsAnimator::OwnedAnimationDelegate { | |
| 94 public: | |
| 95 FadeOutAnimationDelegate(LauncherView* host, views::View* view) | |
| 96 : launcher_view_(host), | |
| 97 view_(view) {} | |
| 98 virtual ~FadeOutAnimationDelegate() {} | |
| 99 | |
| 100 // AnimationDelegate overrides: | |
| 101 virtual void AnimationProgressed(const Animation* animation) OVERRIDE { | |
| 102 view_->layer()->SetOpacity(1 - animation->GetCurrentValue()); | |
| 103 view_->layer()->ScheduleDraw(); | |
| 104 } | |
| 105 virtual void AnimationEnded(const Animation* animation) OVERRIDE { | |
| 106 launcher_view_->AnimateToIdealBounds(); | |
| 107 } | |
| 108 virtual void AnimationCanceled(const Animation* animation) OVERRIDE { | |
| 109 } | |
| 110 | |
| 111 private: | |
| 112 LauncherView* launcher_view_; | |
| 113 scoped_ptr<views::View> view_; | |
| 114 | |
| 115 DISALLOW_COPY_AND_ASSIGN(FadeOutAnimationDelegate); | |
| 116 }; | |
| 117 | |
| 118 // AnimationDelegate used to trigger fading an element in. When an item is | |
| 119 // inserted this delegate is attached to the animation that expands the size of | |
| 120 // the item. When done it kicks off another animation to fade the item in. | |
| 121 class LauncherView::StartFadeAnimationDelegate : | |
| 122 public views::BoundsAnimator::OwnedAnimationDelegate { | |
| 123 public: | |
| 124 StartFadeAnimationDelegate(LauncherView* host, | |
| 125 views::View* view) | |
| 126 : launcher_view_(host), | |
| 127 view_(view) {} | |
| 128 virtual ~StartFadeAnimationDelegate() {} | |
| 129 | |
| 130 // AnimationDelegate overrides: | |
| 131 virtual void AnimationEnded(const Animation* animation) OVERRIDE { | |
| 132 view_->SetVisible(true); | |
| 133 launcher_view_->FadeIn(view_); | |
| 134 } | |
| 135 virtual void AnimationCanceled(const Animation* animation) OVERRIDE { | |
| 136 view_->SetVisible(true); | |
| 137 } | |
| 138 | |
| 139 private: | |
| 140 LauncherView* launcher_view_; | |
| 141 views::View* view_; | |
| 142 | |
| 143 DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); | |
| 144 }; | |
| 145 | |
| 59 LauncherView::LauncherView(LauncherModel* model) | 146 LauncherView::LauncherView(LauncherModel* model) |
| 60 : model_(model), | 147 : model_(model), |
| 61 view_model_(new ViewModel), | 148 view_model_(new ViewModel), |
| 62 new_browser_button_(NULL), | 149 new_browser_button_(NULL), |
| 63 show_apps_button_(NULL), | 150 show_apps_button_(NULL), |
| 64 dragging_(NULL), | 151 dragging_(NULL), |
| 65 drag_view_(NULL), | 152 drag_view_(NULL), |
| 66 drag_offset_(0), | 153 drag_offset_(0), |
| 67 start_drag_index_(-1) { | 154 start_drag_index_(-1) { |
| 68 DCHECK(model_); | 155 DCHECK(model_); |
| 69 bounds_animator_.reset(new views::BoundsAnimator(this)); | 156 bounds_animator_.reset(new views::BoundsAnimator(this)); |
| 70 } | 157 } |
| 71 | 158 |
| 72 LauncherView::~LauncherView() { | 159 LauncherView::~LauncherView() { |
| 73 model_->RemoveObserver(this); | 160 model_->RemoveObserver(this); |
| 74 } | 161 } |
| 75 | 162 |
| 76 void LauncherView::Init() { | 163 void LauncherView::Init() { |
| 77 model_->AddObserver(this); | 164 model_->AddObserver(this); |
| 78 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 165 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 79 new_browser_button_ = new views::ImageButton(this); | 166 new_browser_button_ = new views::ImageButton(this); |
| 80 new_browser_button_->SetImage( | 167 new_browser_button_->SetImage( |
| 81 views::CustomButton::BS_NORMAL, | 168 views::CustomButton::BS_NORMAL, |
| 82 rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_CHROME).ToSkBitmap()); | 169 rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_CHROME).ToSkBitmap()); |
| 83 AddChildView(new_browser_button_); | 170 AddChildView(new_browser_button_); |
| 84 | 171 |
| 85 const LauncherItems& items(model_->items()); | 172 const LauncherItems& items(model_->items()); |
| 86 for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { | 173 for (LauncherItems::const_iterator i = items.begin(); i != items.end(); ++i) { |
| 87 views::View* child = CreateViewForItem(*i); | 174 views::View* child = CreateViewForItem(*i); |
| 175 child->SetPaintToLayer(true); | |
| 88 view_model_->Add(child, static_cast<int>(i - items.begin())); | 176 view_model_->Add(child, static_cast<int>(i - items.begin())); |
| 89 AddChildView(child); | 177 AddChildView(child); |
| 90 } | 178 } |
| 91 | 179 |
| 92 show_apps_button_ = new views::ImageButton(this); | 180 show_apps_button_ = new views::ImageButton(this); |
| 93 show_apps_button_->SetImage( | 181 show_apps_button_->SetImage( |
| 94 views::CustomButton::BS_NORMAL, | 182 views::CustomButton::BS_NORMAL, |
| 95 rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_APPLIST).ToSkBitmap()); | 183 rb.GetImageNamed(IDR_AURA_LAUNCHER_ICON_APPLIST).ToSkBitmap()); |
| 96 AddChildView(show_apps_button_); | 184 AddChildView(show_apps_button_); |
| 97 | 185 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 ideal_bounds.new_browser_bounds); | 226 ideal_bounds.new_browser_bounds); |
| 139 for (int i = 0; i < view_model_->view_size(); ++i) { | 227 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 140 bounds_animator_->AnimateViewTo(view_model_->view_at(i), | 228 bounds_animator_->AnimateViewTo(view_model_->view_at(i), |
| 141 view_model_->ideal_bounds(i)); | 229 view_model_->ideal_bounds(i)); |
| 142 } | 230 } |
| 143 bounds_animator_->AnimateViewTo(show_apps_button_, | 231 bounds_animator_->AnimateViewTo(show_apps_button_, |
| 144 ideal_bounds.show_apps_bounds); | 232 ideal_bounds.show_apps_bounds); |
| 145 } | 233 } |
| 146 | 234 |
| 147 views::View* LauncherView::CreateViewForItem(const LauncherItem& item) { | 235 views::View* LauncherView::CreateViewForItem(const LauncherItem& item) { |
| 236 views::View* view = NULL; | |
| 148 if (item.type == TYPE_TABBED) { | 237 if (item.type == TYPE_TABBED) { |
| 149 TabbedLauncherButton* button = new TabbedLauncherButton(this, this); | 238 TabbedLauncherButton* button = new TabbedLauncherButton(this, this); |
| 150 button->SetImages(item.tab_images); | 239 button->SetImages(item.tab_images); |
| 151 return button; | 240 view = button; |
| 241 } else { | |
| 242 DCHECK_EQ(TYPE_APP, item.type); | |
| 243 AppLauncherButton* button = new AppLauncherButton(this, this); | |
| 244 button->SetAppImage(item.app_image); | |
| 245 view = button; | |
| 152 } | 246 } |
| 153 AppLauncherButton* button = new AppLauncherButton(this, this); | 247 view->SetPaintToLayer(true); |
| 154 button->SetAppImage(item.app_image); | 248 return view; |
| 155 return button; | |
| 156 } | 249 } |
| 157 | 250 |
| 158 void LauncherView::Resize() { | 251 void LauncherView::FadeIn(views::View* view) { |
| 159 // TODO: we may want to force the width to a specific size. | 252 view->SetVisible(true); |
| 160 int y = GetWidget()->GetClientAreaScreenBounds().y(); | 253 view->layer()->SetOpacity(0); |
| 161 gfx::Size pref(GetPreferredSize()); | 254 AnimateToIdealBounds(); |
| 162 GetWidget()->SetBounds(gfx::Rect(0, y, pref.width(), pref.height())); | 255 bounds_animator_->SetAnimationDelegate( |
| 163 Layout(); | 256 view, new FadeInAnimationDelegate(view), true); |
| 164 } | 257 } |
| 165 | 258 |
| 166 void LauncherView::PrepareForDrag(const views::MouseEvent& event) { | 259 void LauncherView::PrepareForDrag(const views::MouseEvent& event) { |
| 167 DCHECK(drag_view_); | 260 DCHECK(drag_view_); |
| 168 dragging_ = true; | 261 dragging_ = true; |
| 169 start_drag_index_ = view_model_->GetIndexOfView(drag_view_); | 262 start_drag_index_ = view_model_->GetIndexOfView(drag_view_); |
| 170 // Move the view to the front so that it appears on top of other views. | 263 // Move the view to the front so that it appears on top of other views. |
| 171 ReorderChildView(drag_view_, -1); | 264 ReorderChildView(drag_view_, -1); |
| 172 bounds_animator_->StopAnimatingView(drag_view_); | 265 bounds_animator_->StopAnimatingView(drag_view_); |
| 173 } | 266 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 CalculateIdealBounds(&ideal_bounds); | 320 CalculateIdealBounds(&ideal_bounds); |
| 228 return gfx::Size(ideal_bounds.show_apps_bounds.right() + kLeadingInset, | 321 return gfx::Size(ideal_bounds.show_apps_bounds.right() + kLeadingInset, |
| 229 kPreferredHeight); | 322 kPreferredHeight); |
| 230 } | 323 } |
| 231 | 324 |
| 232 void LauncherView::LauncherItemAdded(int model_index) { | 325 void LauncherView::LauncherItemAdded(int model_index) { |
| 233 CancelDrag(NULL); | 326 CancelDrag(NULL); |
| 234 | 327 |
| 235 views::View* view = CreateViewForItem(model_->items()[model_index]); | 328 views::View* view = CreateViewForItem(model_->items()[model_index]); |
| 236 AddChildView(view); | 329 AddChildView(view); |
| 330 // Hide the view, it'll be made visible when the animation is done. | |
| 331 view->SetVisible(false); | |
| 237 view_model_->Add(view, model_index); | 332 view_model_->Add(view, model_index); |
| 238 | 333 |
| 239 // Update the bounds and reset the bounds of the newly created view to 0 width | 334 // The first animation moves all the views to their target position. |view| is |
| 240 // so that it appears to animate open. | 335 // hidden, so it visually appears as though we are providing space for |
| 241 IdealBounds ideal_bounds; | 336 // it. When done we'll fade the view in. |
| 242 CalculateIdealBounds(&ideal_bounds); | |
| 243 gfx::Rect bounds = view_model_->ideal_bounds(model_index); | |
| 244 bounds.set_width(0); | |
| 245 view->SetBoundsRect(bounds); | |
| 246 | |
| 247 // Resize and animate all the views. | |
| 248 Resize(); | |
| 249 AnimateToIdealBounds(); | 337 AnimateToIdealBounds(); |
| 338 bounds_animator_->SetAnimationDelegate( | |
| 339 view, new StartFadeAnimationDelegate(this, view), true); | |
| 250 } | 340 } |
| 251 | 341 |
| 252 void LauncherView::LauncherItemRemoved(int model_index) { | 342 void LauncherView::LauncherItemRemoved(int model_index) { |
| 253 views::View* view = view_model_->view_at(model_index); | 343 views::View* view = view_model_->view_at(model_index); |
| 254 CancelDrag(view); | 344 CancelDrag(view); |
| 255 view_model_->Remove(model_index); | 345 view_model_->Remove(model_index); |
| 256 Resize(); | 346 // The first animation fades out the view. When done we'll animate the rest of |
| 257 AnimateToIdealBounds(); | 347 // the views to their target location. |
| 258 gfx::Rect target_bounds = view->bounds(); | 348 bounds_animator_->AnimateViewTo(view, view->bounds()); |
| 259 target_bounds.set_width(0); | |
| 260 bounds_animator_->AnimateViewTo(view, target_bounds); | |
| 261 bounds_animator_->SetAnimationDelegate( | 349 bounds_animator_->SetAnimationDelegate( |
| 262 view, new DeleteViewAnimationDelegate(view), true); | 350 view, new FadeOutAnimationDelegate(this, view), true); |
| 263 } | 351 } |
| 264 | 352 |
| 265 void LauncherView::LauncherItemImagesChanged(int model_index) { | 353 void LauncherView::LauncherItemImagesChanged(int model_index) { |
| 266 const LauncherItem& item(model_->items()[model_index]); | 354 const LauncherItem& item(model_->items()[model_index]); |
| 267 views::View* view = view_model_->view_at(model_index); | 355 views::View* view = view_model_->view_at(model_index); |
| 268 if (item.type == TYPE_TABBED) { | 356 if (item.type == TYPE_TABBED) { |
| 269 TabbedLauncherButton* button = static_cast<TabbedLauncherButton*>(view); | 357 TabbedLauncherButton* button = static_cast<TabbedLauncherButton*>(view); |
| 270 gfx::Size pref = button->GetPreferredSize(); | 358 gfx::Size pref = button->GetPreferredSize(); |
| 271 button->SetImages(item.tab_images); | 359 button->SetImages(item.tab_images); |
| 272 if (pref != button->GetPreferredSize()) { | 360 if (pref != button->GetPreferredSize()) |
| 273 Resize(); | |
| 274 AnimateToIdealBounds(); | 361 AnimateToIdealBounds(); |
| 275 } else { | 362 else |
| 276 button->SchedulePaint(); | 363 button->SchedulePaint(); |
| 277 } | |
| 278 } else { | 364 } else { |
| 279 DCHECK_EQ(TYPE_APP, item.type); | 365 DCHECK_EQ(TYPE_APP, item.type); |
| 280 AppLauncherButton* button = static_cast<AppLauncherButton*>(view); | 366 AppLauncherButton* button = static_cast<AppLauncherButton*>(view); |
| 281 button->SetAppImage(item.app_image); | 367 button->SetAppImage(item.app_image); |
| 282 button->SchedulePaint(); | 368 button->SchedulePaint(); |
| 283 } | 369 } |
| 284 } | 370 } |
| 285 | 371 |
| 286 void LauncherView::LauncherItemMoved(int start_index, int target_index) { | 372 void LauncherView::LauncherItemMoved(int start_index, int target_index) { |
| 287 view_model_->Move(start_index, target_index); | 373 view_model_->Move(start_index, target_index); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 } else { | 415 } else { |
| 330 int view_index = view_model_->GetIndexOfView(sender); | 416 int view_index = view_model_->GetIndexOfView(sender); |
| 331 // May be -1 while in the process of animating closed. | 417 // May be -1 while in the process of animating closed. |
| 332 if (view_index != -1) | 418 if (view_index != -1) |
| 333 delegate->LauncherItemClicked(model_->items()[view_index]); | 419 delegate->LauncherItemClicked(model_->items()[view_index]); |
| 334 } | 420 } |
| 335 } | 421 } |
| 336 | 422 |
| 337 } // namespace internal | 423 } // namespace internal |
| 338 } // namespace aura_shell | 424 } // namespace aura_shell |
| OLD | NEW |