// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef UI_APP_LIST_PAGINATION_MODEL_H_ #define UI_APP_LIST_PAGINATION_MODEL_H_ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/time/time.h" #include "ui/app_list/app_list_export.h" #include "ui/gfx/animation/animation_delegate.h" namespace gfx { class SlideAnimation; } namespace app_list { class PaginationModelObserver; // A simple pagination model that consists of two numbers: the total pages and // the currently selected page. The model is a single selection model that at // the most one page can become selected at any time. class APP_LIST_EXPORT PaginationModel : public gfx::AnimationDelegate { public: // Holds info for transition animation and touch scroll. struct Transition { Transition(int target_page, double progress) : target_page(target_page), progress(progress) { } bool Equals(const Transition& rhs) const { return target_page == rhs.target_page && progress == rhs.progress; } // Target page for the transition or -1 if there is no target page. For // page switcher, this is the target selected page. For touch scroll, // this is usually the previous or next page (or -1 when there is no // previous or next page). int target_page; // A [0, 1] progress indicates how much of the current page is being // transitioned. double progress; }; PaginationModel(); ~PaginationModel() override; void SetTotalPages(int total_pages); // Selects a page. |animate| is true if the transition should be animated. void SelectPage(int page, bool animate); // Selects a page by relative |delta|. void SelectPageRelative(int delta, bool animate); // Immediately completes all queued animations, jumping directly to the final // target page. void FinishAnimation(); void SetTransition(const Transition& transition); void SetTransitionDurations(int duration_ms, int overscroll_duration_ms); // Starts a scroll transition. If there is a running transition animation, // cancels it but keeps the transition info. void StartScroll(); // Updates transition progress from |delta|. |delta| > 0 means transit to // previous page (moving pages to the right). |delta| < 0 means transit // to next page (moving pages to the left). void UpdateScroll(double delta); // Finishes the current scroll transition if |cancel| is false. Otherwise, // reverses it. void EndScroll(bool cancel); // Returns true if current transition is being reverted. bool IsRevertingCurrentTransition() const; void AddObserver(PaginationModelObserver* observer); void RemoveObserver(PaginationModelObserver* observer); int total_pages() const { return total_pages_; } int selected_page() const { return selected_page_; } const Transition& transition() const { return transition_; } bool is_valid_page(int page) const { return page >= 0 && page < total_pages_; } bool has_transition() const { return transition_.target_page != -1 || transition_.progress != 0; } // Gets the page that the animation will eventually land on. If there is no // active animation, just returns selected_page(). int SelectedTargetPage() const; private: void NotifySelectedPageChanged(int old_selected, int new_selected); void NotifyTransitionStarted(); void NotifyTransitionChanged(); void clear_transition() { SetTransition(Transition(-1, 0)); } // Calculates a target page number by combining current page and |delta|. // When there is no transition, current page is the currently selected page. // If there is a transition, current page is the transition target page or the // pending transition target page. When current page + |delta| goes beyond // valid range and |selected_page_| is at the range ends, invalid page number // -1 or |total_pages_| is returned to indicate the situation. int CalculateTargetPage(int delta) const; void StartTransitionAnimation(const Transition& transition); void ResetTransitionAnimation(); // gfx::AnimationDelegate overrides: void AnimationProgressed(const gfx::Animation* animation) override; void AnimationEnded(const gfx::Animation* animation) override; int total_pages_; int selected_page_; Transition transition_; // Pending selected page when SelectedPage is called during a transition. If // multiple SelectPage is called while a transition is in progress, only the // last target page is remembered here. int pending_selected_page_; scoped_ptr transition_animation_; int transition_duration_ms_; // Transition duration in millisecond. int overscroll_transition_duration_ms_; int last_overscroll_target_page_; base::TimeTicks last_overscroll_animation_start_time_; base::ObserverList observers_; DISALLOW_COPY_AND_ASSIGN(PaginationModel); }; } // namespace app_list #endif // UI_APP_LIST_PAGINATION_MODEL_H_