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 |