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 3 // found in the LICENSE file. 4 5 #ifndef UI_APP_LIST_PAGINATION_MODEL_H_ 6 #define UI_APP_LIST_PAGINATION_MODEL_H_ 7 8 #include "base/basictypes.h" 9 #include "base/compiler_specific.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/observer_list.h" 12 #include "base/time/time.h" 13 #include "ui/app_list/app_list_export.h" 14 #include "ui/gfx/animation/animation_delegate.h" 15 16 namespace gfx { 17 class SlideAnimation; 18 } 19 20 namespace app_list { 21 22 class PaginationModelObserver; 23 24 // A simple pagination model that consists of two numbers: the total pages and 25 // the currently selected page. The model is a single selection model that at 26 // the most one page can become selected at any time. 27 class APP_LIST_EXPORT PaginationModel : public gfx::AnimationDelegate { 28 public: 29 // Holds info for transition animation and touch scroll. 30 struct Transition { 31 Transition(int target_page, double progress) 32 : target_page(target_page), 33 progress(progress) { 34 } 35 36 bool Equals(const Transition& rhs) const { 37 return target_page == rhs.target_page && progress == rhs.progress; 38 } 39 40 // Target page for the transition or -1 if there is no target page. For 41 // page switcher, this is the target selected page. For touch scroll, 42 // this is usually the previous or next page (or -1 when there is no 43 // previous or next page). 44 int target_page; 45 46 // A [0, 1] progress indicates how much of the current page is being 47 // transitioned. 48 double progress; 49 }; 50 51 PaginationModel(); 52 virtual ~PaginationModel(); 53 54 void SetTotalPages(int total_pages); 55 56 // Selects a page. |animate| is true if the transition should be animated. 57 void SelectPage(int page, bool animate); 58 59 // Selects a page by relative |delta|. 60 void SelectPageRelative(int delta, bool animate); 61 62 void SetTransition(const Transition& transition); 63 void SetTransitionDurations(int duration_ms, int overscroll_duration_ms); 64 65 // Starts a scroll transition. If there is a running transition animation, 66 // cancels it but keeps the transition info. 67 void StartScroll(); 68 69 // Updates transition progress from |delta|. |delta| > 0 means transit to 70 // previous page (moving pages to the right). |delta| < 0 means transit 71 // to next page (moving pages to the left). 72 void UpdateScroll(double delta); 73 74 // Finishes the current scroll transition if |cancel| is false. Otherwise, 75 // reverses it. 76 void EndScroll(bool cancel); 77 78 // Returns true if current transition is being reverted. 79 bool IsRevertingCurrentTransition() const; 80 81 void AddObserver(PaginationModelObserver* observer); 82 void RemoveObserver(PaginationModelObserver* observer); 83 84 int total_pages() const { return total_pages_; } 85 int selected_page() const { return selected_page_; } 86 const Transition& transition() const { return transition_; } 87 88 bool is_valid_page(int page) const { 89 return page >= 0 && page < total_pages_; 90 } 91 92 bool has_transition() const { 93 return transition_.target_page != -1 || transition_.progress != 0; 94 } 95 96 private: 97 void NotifySelectedPageChanged(int old_selected, int new_selected); 98 void NotifyTransitionStarted(); 99 void NotifyTransitionChanged(); 100 101 void clear_transition() { 102 SetTransition(Transition(-1, 0)); 103 } 104 105 // Calculates a target page number by combining current page and |delta|. 106 // When there is no transition, current page is the currently selected page. 107 // If there is a transition, current page is the transition target page or the 108 // pending transition target page. When current page + |delta| goes beyond 109 // valid range and |selected_page_| is at the range ends, invalid page number 110 // -1 or |total_pages_| is returned to indicate the situation. 111 int CalculateTargetPage(int delta) const; 112 113 void StartTransitionAnimation(const Transition& transition); 114 void ResetTransitionAnimation(); 115 116 // gfx::AnimationDelegate overrides: 117 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; 118 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; 119 120 int total_pages_; 121 int selected_page_; 122 123 Transition transition_; 124 125 // Pending selected page when SelectedPage is called during a transition. If 126 // multiple SelectPage is called while a transition is in progress, only the 127 // last target page is remembered here. 128 int pending_selected_page_; 129 130 scoped_ptr<gfx::SlideAnimation> transition_animation_; 131 int transition_duration_ms_; // Transition duration in millisecond. 132 int overscroll_transition_duration_ms_; 133 134 int last_overscroll_target_page_; 135 base::TimeTicks last_overscroll_animation_start_time_; 136 137 ObserverList<PaginationModelObserver> observers_; 138 139 DISALLOW_COPY_AND_ASSIGN(PaginationModel); 140 }; 141 142 } // namespace app_list 143 144 #endif // UI_APP_LIST_PAGINATION_MODEL_H_ 145