1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
// 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<gfx::SlideAnimation> 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_;
ObserverList<PaginationModelObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(PaginationModel);
};
} // namespace app_list
#endif // UI_APP_LIST_PAGINATION_MODEL_H_
|