Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: ash/launcher/launcher_view.cc

Issue 10068027: ash: Fix launcher icon overlaps with status. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: use last_visible_index_ part from 9808026 and add tests Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "ash/launcher/launcher_button.h" 7 #include "ash/launcher/launcher_button.h"
8 #include "ash/launcher/launcher_delegate.h" 8 #include "ash/launcher/launcher_delegate.h"
9 #include "ash/launcher/launcher_model.h" 9 #include "ash/launcher/launcher_model.h"
10 #include "ash/launcher/tabbed_launcher_button.h" 10 #include "ash/launcher/tabbed_launcher_button.h"
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 case STATUS_RUNNING: 174 case STATUS_RUNNING:
175 button->ClearState(LauncherButton::STATE_ACTIVE); 175 button->ClearState(LauncherButton::STATE_ACTIVE);
176 button->AddState(LauncherButton::STATE_RUNNING); 176 button->AddState(LauncherButton::STATE_RUNNING);
177 break; 177 break;
178 case STATUS_ACTIVE: 178 case STATUS_ACTIVE:
179 button->AddState(LauncherButton::STATE_ACTIVE); 179 button->AddState(LauncherButton::STATE_ACTIVE);
180 button->ClearState(LauncherButton::STATE_RUNNING); 180 button->ClearState(LauncherButton::STATE_RUNNING);
181 break; 181 break;
182 } 182 }
183 } 183 }
184
185 // A class used by TestAPI to wait for animations.
186 class TestAPIAnimationObserver : public views::BoundsAnimatorObserver {
187 public:
188 TestAPIAnimationObserver() {}
189 virtual ~TestAPIAnimationObserver() {}
190
191 // views::BoundsAnimatorObserver overrides:
192 virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator) OVERRIDE {
193 MessageLoop::current()->Quit();
194 }
195
196 private:
197 DISALLOW_COPY_AND_ASSIGN(TestAPIAnimationObserver);
198 };
199
184 } // namespace 200 } // namespace
185 201
186 // AnimationDelegate used when inserting a new item. This steadily decreased the 202 // AnimationDelegate used when inserting a new item. This steadily decreased the
187 // opacity of the layer as the animation progress. 203 // opacity of the layer as the animation progress.
188 class LauncherView::FadeOutAnimationDelegate : 204 class LauncherView::FadeOutAnimationDelegate :
189 public views::BoundsAnimator::OwnedAnimationDelegate { 205 public views::BoundsAnimator::OwnedAnimationDelegate {
190 public: 206 public:
191 FadeOutAnimationDelegate(LauncherView* host, views::View* view) 207 FadeOutAnimationDelegate(LauncherView* host, views::View* view)
192 : launcher_view_(host), 208 : launcher_view_(host),
193 view_(view) {} 209 view_(view) {}
(...skipping 24 matching lines...) Expand all
218 public views::BoundsAnimator::OwnedAnimationDelegate { 234 public views::BoundsAnimator::OwnedAnimationDelegate {
219 public: 235 public:
220 StartFadeAnimationDelegate(LauncherView* host, 236 StartFadeAnimationDelegate(LauncherView* host,
221 views::View* view) 237 views::View* view)
222 : launcher_view_(host), 238 : launcher_view_(host),
223 view_(view) {} 239 view_(view) {}
224 virtual ~StartFadeAnimationDelegate() {} 240 virtual ~StartFadeAnimationDelegate() {}
225 241
226 // AnimationDelegate overrides: 242 // AnimationDelegate overrides:
227 virtual void AnimationEnded(const Animation* animation) OVERRIDE { 243 virtual void AnimationEnded(const Animation* animation) OVERRIDE {
228 view_->SetVisible(true);
229 launcher_view_->FadeIn(view_); 244 launcher_view_->FadeIn(view_);
230 } 245 }
231 virtual void AnimationCanceled(const Animation* animation) OVERRIDE { 246 virtual void AnimationCanceled(const Animation* animation) OVERRIDE {
232 view_->SetVisible(true); 247 view_->SetVisible(true);
233 } 248 }
234 249
235 private: 250 private:
236 LauncherView* launcher_view_; 251 LauncherView* launcher_view_;
237 views::View* view_; 252 views::View* view_;
238 253
239 DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); 254 DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate);
240 }; 255 };
241 256
242 int LauncherView::TestAPI::GetButtonCount() { 257 int LauncherView::TestAPI::GetButtonCount() {
243 return launcher_view_->view_model_->view_size(); 258 return launcher_view_->view_model_->view_size();
244 } 259 }
245 260
246 LauncherButton* LauncherView::TestAPI::GetButton(int index) { 261 LauncherButton* LauncherView::TestAPI::GetButton(int index) {
247 if (index == 0) 262 // App list button is not a LauncherButton.
263 if (index == GetButtonCount() - 1)
248 return NULL; 264 return NULL;
249 265
250 return static_cast<LauncherButton*>( 266 return static_cast<LauncherButton*>(
251 launcher_view_->view_model_->view_at(index)); 267 launcher_view_->view_model_->view_at(index));
252 } 268 }
253 269
270 int LauncherView::TestAPI::GetLastVisibleIndex() {
271 return launcher_view_->last_visible_index_;
272 }
273
274 bool LauncherView::TestAPI::IsOverflowButtonVisible() {
275 return launcher_view_->overflow_button_->visible();
276 }
277
278 void LauncherView::TestAPI::SetAnimationDuration(int duration_ms) {
279 launcher_view_->bounds_animator_->SetAnimationDuration(duration_ms);
280 }
281
282 void LauncherView::TestAPI::RunMessageLoopUntilAnimationsDone() {
283 if (!launcher_view_->bounds_animator_->IsAnimating())
284 return;
285
286 scoped_ptr<TestAPIAnimationObserver> observer(new TestAPIAnimationObserver());
287 launcher_view_->bounds_animator_->AddObserver(observer.get());
288
289 // This nest loop will quit when TestAPIAnimationObserver's
290 // OnBoundsAnimatorDone is called.
291 MessageLoop::current()->Run();
292
293 launcher_view_->bounds_animator_->RemoveObserver(observer.get());
294 }
295
254 LauncherView::LauncherView(LauncherModel* model, LauncherDelegate* delegate) 296 LauncherView::LauncherView(LauncherModel* model, LauncherDelegate* delegate)
255 : model_(model), 297 : model_(model),
256 delegate_(delegate), 298 delegate_(delegate),
257 view_model_(new views::ViewModel), 299 view_model_(new views::ViewModel),
300 last_visible_index_(-1),
258 overflow_button_(NULL), 301 overflow_button_(NULL),
259 dragging_(NULL), 302 dragging_(NULL),
260 drag_view_(NULL), 303 drag_view_(NULL),
261 drag_offset_(0), 304 drag_offset_(0),
262 start_drag_index_(-1), 305 start_drag_index_(-1),
263 context_menu_id_(0) { 306 context_menu_id_(0) {
264 DCHECK(model_); 307 DCHECK(model_);
265 bounds_animator_.reset(new views::BoundsAnimator(this)); 308 bounds_animator_.reset(new views::BoundsAnimator(this));
266 set_context_menu_controller(this); 309 set_context_menu_controller(this);
267 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); 310 focus_search_.reset(new LauncherFocusSearch(view_model_.get()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 } 382 }
340 383
341 View* LauncherView::GetFocusTraversableParentView() { 384 View* LauncherView::GetFocusTraversableParentView() {
342 return this; 385 return this;
343 } 386 }
344 387
345 void LauncherView::LayoutToIdealBounds() { 388 void LauncherView::LayoutToIdealBounds() {
346 IdealBounds ideal_bounds; 389 IdealBounds ideal_bounds;
347 CalculateIdealBounds(&ideal_bounds); 390 CalculateIdealBounds(&ideal_bounds);
348 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); 391 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_);
392 views::ViewModelUtils::SetViewVisibilityToIdealVisibility(*view_model_);
349 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); 393 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds);
350 } 394 }
351 395
352 void LauncherView::CalculateIdealBounds(IdealBounds* bounds) { 396 void LauncherView::CalculateIdealBounds(IdealBounds* bounds) {
353 int available_width = width(); 397 int available_width = width();
354 if (!available_width) 398 if (!available_width)
355 return; 399 return;
356 400
357 int x = kLeadingInset; 401 int x = kLeadingInset;
358 for (int i = 0; i < view_model_->view_size(); ++i) { 402 for (int i = 0; i < view_model_->view_size(); ++i) {
359 gfx::Size pref(kButtonWidth, kButtonHeight); 403 gfx::Size pref(kButtonWidth, kButtonHeight);
360 view_model_->set_ideal_bounds(i, gfx::Rect( 404 view_model_->set_ideal_bounds(i, gfx::Rect(
361 x, (kLauncherPreferredHeight - pref.height()) / 2, pref.width(), 405 x, (kLauncherPreferredHeight - pref.height()) / 2, pref.width(),
362 pref.height())); 406 pref.height()));
363 x += pref.width() + kButtonSpacing; 407 x += pref.width() + kButtonSpacing;
364 } 408 }
365 409
366 bounds->overflow_bounds.set_size(gfx::Size(kButtonWidth, kButtonHeight)); 410 bounds->overflow_bounds.set_size(gfx::Size(kButtonWidth, kButtonHeight));
367 int last_visible_index = DetermineLastVisibleIndex( 411 last_visible_index_ = DetermineLastVisibleIndex(
368 available_width - kLeadingInset - bounds->overflow_bounds.width() - 412 available_width - kLeadingInset - bounds->overflow_bounds.width() -
369 kButtonSpacing - kButtonWidth); 413 kButtonSpacing - kButtonWidth);
370 bool show_overflow =
371 (last_visible_index + 1 != view_model_->view_size());
372 int app_list_index = view_model_->view_size() - 1; 414 int app_list_index = view_model_->view_size() - 1;
373 if (overflow_button_->visible() != show_overflow) { 415 bool show_overflow = (last_visible_index_ + 1 < app_list_index);
374 // Only change visibility of the views if the visibility of the overflow 416
375 // button changes. Otherwise we'll effect the insertion animation, which 417 for (int i = 0; i < view_model_->view_size(); ++i) {
376 // changes the visibility. 418 view_model_->set_ideal_visibility(
377 for (int i = 0; i <= last_visible_index; ++i) 419 i,
378 view_model_->view_at(i)->SetVisible(true); 420 i == app_list_index || i <= last_visible_index_);
379 for (int i = last_visible_index + 1; i < view_model_->view_size(); ++i) {
380 if (i != app_list_index)
381 view_model_->view_at(i)->SetVisible(false);
382 }
383 } 421 }
422
384 overflow_button_->SetVisible(show_overflow); 423 overflow_button_->SetVisible(show_overflow);
385 if (show_overflow) { 424 if (show_overflow) {
386 DCHECK_NE(0, view_model_->view_size()); 425 DCHECK_NE(0, view_model_->view_size());
387 // We always want the app list visible. 426 // We always want the app list visible.
388 gfx::Rect app_list_bounds = view_model_->ideal_bounds(app_list_index); 427 gfx::Rect app_list_bounds = view_model_->ideal_bounds(app_list_index);
389 x = last_visible_index == -1 ? 428 x = last_visible_index_ == -1 ?
390 kLeadingInset : view_model_->ideal_bounds(last_visible_index).right(); 429 kLeadingInset : view_model_->ideal_bounds(last_visible_index_).right();
391 app_list_bounds.set_x(x); 430 app_list_bounds.set_x(x);
392 view_model_->set_ideal_bounds(app_list_index, app_list_bounds); 431 view_model_->set_ideal_bounds(app_list_index, app_list_bounds);
393 x = app_list_bounds.right() + kButtonSpacing; 432 x = app_list_bounds.right() + kButtonSpacing;
394 bounds->overflow_bounds.set_x(x); 433 bounds->overflow_bounds.set_x(x);
395 bounds->overflow_bounds.set_y( 434 bounds->overflow_bounds.set_y(
396 (kLauncherPreferredHeight - bounds->overflow_bounds.height()) / 2); 435 (kLauncherPreferredHeight - bounds->overflow_bounds.height()) / 2);
397 } 436 }
398 } 437 }
399 438
400 int LauncherView::DetermineLastVisibleIndex(int max_x) { 439 int LauncherView::DetermineLastVisibleIndex(int max_x) {
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 709
671 void LauncherView::LauncherItemAdded(int model_index) { 710 void LauncherView::LauncherItemAdded(int model_index) {
672 CancelDrag(NULL); 711 CancelDrag(NULL);
673 712
674 views::View* view = CreateViewForItem(model_->items()[model_index]); 713 views::View* view = CreateViewForItem(model_->items()[model_index]);
675 AddChildView(view); 714 AddChildView(view);
676 // Hide the view, it'll be made visible when the animation is done. 715 // Hide the view, it'll be made visible when the animation is done.
677 view->SetVisible(false); 716 view->SetVisible(false);
678 view_model_->Add(view, model_index); 717 view_model_->Add(view, model_index);
679 718
680 // Give the button it's ideal bounds. That way if we end up animating the 719 // Give the button its ideal bounds. That way if we end up animating the
681 // button before this animation completes it doesn't appear at some random 720 // button before this animation completes it doesn't appear at some random
682 // spot (because it was in the middle of animating from 0,0 0x0 to its 721 // spot (because it was in the middle of animating from 0,0 0x0 to its
683 // target). 722 // target).
684 IdealBounds ideal_bounds; 723 IdealBounds ideal_bounds;
685 CalculateIdealBounds(&ideal_bounds); 724 CalculateIdealBounds(&ideal_bounds);
686 view->SetBoundsRect(view_model_->ideal_bounds(model_index)); 725 view->SetBoundsRect(view_model_->ideal_bounds(model_index));
687 726
688 // The first animation moves all the views to their target position. |view| is 727 // The first animation moves all the views to their target position. |view|
689 // hidden, so it visually appears as though we are providing space for 728 // is hidden, so it visually appears as though we are providing space for
690 // it. When done we'll fade the view in. 729 // it. When done we'll fade the view in.
691 AnimateToIdealBounds(); 730 AnimateToIdealBounds();
692 if (!overflow_button_->visible()) { 731 if (model_index <= last_visible_index_) {
693 bounds_animator_->SetAnimationDelegate( 732 bounds_animator_->SetAnimationDelegate(
694 view, new StartFadeAnimationDelegate(this, view), true); 733 view, new StartFadeAnimationDelegate(this, view), true);
734
735 // Hides view that should become invisible immediately.
sky 2012/04/13 22:00:04 If possible, I would rather change the visibility
xiyuan 2012/04/13 22:49:53 This causes flashes. When CalculateIdealBounds set
xiyuan 2012/04/23 18:08:53 Done. Set opacity to 0 work as expected and thus r
736 for (int i = 0; i < view_model_->view_size(); ++i) {
737 if (!view_model_->ideal_visibility(i) &&
738 view_model_->view_at(i)->visible()) {
739 view_model_->view_at(i)->SetVisible(false);
740 }
741 }
695 } 742 }
696 } 743 }
697 744
698 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) { 745 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) {
699 #if !defined(OS_MACOSX) 746 #if !defined(OS_MACOSX)
700 if (id == context_menu_id_) 747 if (id == context_menu_id_)
701 launcher_menu_runner_.reset(); 748 launcher_menu_runner_.reset();
702 #endif 749 #endif
703 views::View* view = view_model_->view_at(model_index); 750 views::View* view = view_model_->view_at(model_index);
704 CancelDrag(view); 751 CancelDrag(view);
705 view_model_->Remove(model_index); 752 view_model_->Remove(model_index);
706 // The first animation fades out the view. When done we'll animate the rest of 753 // The first animation fades out the view. When done we'll animate the rest of
707 // the views to their target location. 754 // the views to their target location.
708 bounds_animator_->AnimateViewTo(view, view->bounds()); 755 bounds_animator_->AnimateViewTo(view, view->bounds());
709 bounds_animator_->SetAnimationDelegate( 756 bounds_animator_->SetAnimationDelegate(
710 view, new FadeOutAnimationDelegate(this, view), true); 757 view, new FadeOutAnimationDelegate(this, view), true);
758
759 IdealBounds ideal_bounds;
760 CalculateIdealBounds(&ideal_bounds);
761 if (model_index <= last_visible_index_) {
762 // Shows view that should become visible immediately.
763 for (int i = 0; i < view_model_->view_size(); ++i) {
764 if (view_model_->ideal_visibility(i) &&
765 !view_model_->view_at(i)->visible()) {
766 view_model_->view_at(i)->SetVisible(true);
767 }
768 }
769 }
711 } 770 }
712 771
713 void LauncherView::LauncherItemChanged(int model_index, 772 void LauncherView::LauncherItemChanged(int model_index,
714 const ash::LauncherItem& old_item) { 773 const ash::LauncherItem& old_item) {
715 const LauncherItem& item(model_->items()[model_index]); 774 const LauncherItem& item(model_->items()[model_index]);
716 if (old_item.type != item.type) { 775 if (old_item.type != item.type) {
717 // Type changed, swap the views. 776 // Type changed, swap the views.
718 scoped_ptr<views::View> old_view(view_model_->view_at(model_index)); 777 scoped_ptr<views::View> old_view(view_model_->view_at(model_index));
719 bounds_animator_->StopAnimatingView(old_view.get()); 778 bounds_animator_->StopAnimatingView(old_view.get());
720 CancelDrag(old_view.get()); 779 CancelDrag(old_view.get());
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 source->GetWidget(), NULL, gfx::Rect(point, gfx::Size()), 947 source->GetWidget(), NULL, gfx::Rect(point, gfx::Size()),
889 views::MenuItemView::TOPLEFT, 0) == views::MenuRunner::MENU_DELETED) 948 views::MenuItemView::TOPLEFT, 0) == views::MenuRunner::MENU_DELETED)
890 return; 949 return;
891 950
892 Shell::GetInstance()->UpdateShelfVisibility(); 951 Shell::GetInstance()->UpdateShelfVisibility();
893 #endif 952 #endif
894 } 953 }
895 954
896 } // namespace internal 955 } // namespace internal
897 } // namespace ash 956 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698