EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.content.browser]

COVERAGE SUMMARY FOR SOURCE FILE [SnapScrollController.java]

nameclass, %method, %block, %line, %
SnapScrollController.java100% (1/1)88%  (7/8)85%  (228/269)85%  (52.8/62)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SnapScrollController100% (1/1)88%  (7/8)85%  (228/269)85%  (52.8/62)
isSnapVertical (): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
calculateChannelDistance (Context): void 100% (1/1)71%  (45/63)65%  (7.8/12)
updateSnapScrollMode (float, float): void 100% (1/1)79%  (57/72)73%  (11/15)
SnapScrollController (Context, ZoomManager): void 100% (1/1)100% (27/27)100% (10/10)
isSnapHorizontal (): boolean 100% (1/1)100% (8/8)100% (1/1)
isSnappingScrolls (): boolean 100% (1/1)100% (7/7)100% (1/1)
resetSnapScrollMode (): void 100% (1/1)100% (4/4)100% (2/2)
setSnapScrollingMode (MotionEvent): void 100% (1/1)100% (80/80)100% (20/20)

1// Copyright (c) 2013 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 
5package org.chromium.content.browser;
6 
7import android.content.Context;
8import android.util.DisplayMetrics;
9import android.util.Log;
10import android.view.MotionEvent;
11 
12/**
13 * This objects controls the scroll snapping behavior based on scroll updates.
14 */
15class SnapScrollController {
16    private static final String TAG = "SnapScrollController";
17    private static final int SNAP_NONE = 0;
18    private static final int SNAP_HORIZ = 1;
19    private static final int SNAP_VERT = 2;
20    private static final int SNAP_BOUND = 16;
21 
22    private float mChannelDistance = 16f;
23    private int mSnapScrollMode = SNAP_NONE;
24    private int mFirstTouchX = -1;
25    private int mFirstTouchY = -1;
26    private float mDistanceX = 0;
27    private float mDistanceY = 0;
28    private ZoomManager mZoomManager;
29 
30    SnapScrollController(Context context, ZoomManager zoomManager) {
31        calculateChannelDistance(context);
32        mZoomManager = zoomManager;
33    }
34 
35    /**
36     * Updates the snap scroll mode based on the given X and Y distance to be moved on scroll.
37     * If the scroll update is above a threshold, the snapping behavior is reset.
38     * @param distanceX X distance for the current scroll update.
39     * @param distanceY Y distance for the current scroll update.
40     */
41    void updateSnapScrollMode(float distanceX, float distanceY) {
42        if (mSnapScrollMode == SNAP_HORIZ || mSnapScrollMode == SNAP_VERT) {
43            mDistanceX += Math.abs(distanceX);
44            mDistanceY += Math.abs(distanceY);
45            if (mSnapScrollMode == SNAP_HORIZ) {
46                if (mDistanceY > mChannelDistance) {
47                    mSnapScrollMode = SNAP_NONE;
48                } else if (mDistanceX > mChannelDistance) {
49                    mDistanceX = 0;
50                    mDistanceY = 0;
51                }
52            } else {
53                if (mDistanceX > mChannelDistance) {
54                    mSnapScrollMode = SNAP_NONE;
55                } else if (mDistanceY > mChannelDistance) {
56                    mDistanceX = 0;
57                    mDistanceY = 0;
58                }
59            }
60        }
61    }
62 
63    /**
64     * Sets the snap scroll mode based on the event type.
65     * @param event The received MotionEvent.
66     */
67    void setSnapScrollingMode(MotionEvent event) {
68        switch(event.getAction()) {
69            case MotionEvent.ACTION_DOWN:
70                mSnapScrollMode = SNAP_NONE;
71                mFirstTouchX = (int) event.getX();
72                mFirstTouchY = (int) event.getY();
73                break;
74             // Set scrolling mode to SNAP_X if scroll towards x-axis exceeds SNAP_BOUND
75             // and movement towards y-axis is trivial.
76             // Set scrolling mode to SNAP_Y if scroll towards y-axis exceeds SNAP_BOUND
77             // and movement towards x-axis is trivial.
78             // Scrolling mode will remain in SNAP_NONE for other conditions.
79            case MotionEvent.ACTION_MOVE:
80                if (!mZoomManager.isScaleGestureDetectionInProgress() &&
81                        mSnapScrollMode == SNAP_NONE) {
82                    int xDiff = (int) Math.abs(event.getX() - mFirstTouchX);
83                    int yDiff = (int) Math.abs(event.getY() - mFirstTouchY);
84                    if (xDiff > SNAP_BOUND && yDiff < SNAP_BOUND) {
85                        mSnapScrollMode = SNAP_HORIZ;
86                    } else if (xDiff < SNAP_BOUND && yDiff > SNAP_BOUND) {
87                        mSnapScrollMode = SNAP_VERT;
88                    }
89                }
90                break;
91            case MotionEvent.ACTION_UP:
92            case MotionEvent.ACTION_CANCEL:
93                mFirstTouchX = -1;
94                mFirstTouchY = -1;
95                mDistanceX = 0;
96                mDistanceY = 0;
97                break;
98            default:
99                Log.i(TAG, "setSnapScrollingMode case-default no-op");
100                break;
101        }
102    }
103 
104    private void calculateChannelDistance(Context context) {
105        // The channel distance is adjusted for density and screen size.
106        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
107        final double screenSize = Math.hypot((double) metrics.widthPixels / metrics.densityDpi,
108                (double) metrics.heightPixels / metrics.densityDpi);
109        if (screenSize < 3.0) {
110            mChannelDistance = 16f;
111        } else if (screenSize < 5.0) {
112            mChannelDistance = 22f;
113        } else if (screenSize < 7.0) {
114            mChannelDistance = 28f;
115        } else {
116            mChannelDistance = 34f;
117        }
118        mChannelDistance = mChannelDistance * metrics.density;
119        if (mChannelDistance < 16f) mChannelDistance = 16f;
120    }
121 
122    /**
123     * Resets the snap scroll mode to default.
124     */
125    void resetSnapScrollMode() {
126        mSnapScrollMode = SNAP_NONE;
127    }
128 
129    /**
130     * @return Whether current snap scroll mode is vertical.
131     */
132    boolean isSnapVertical() {
133        return mSnapScrollMode == SNAP_VERT;
134    }
135 
136    /**
137     * @return Whether current snap scroll mode is horizontal.
138     */
139    boolean isSnapHorizontal() {
140        return mSnapScrollMode == SNAP_HORIZ;
141    }
142 
143    /**
144     * @return Whether currently snapping scrolls.
145     */
146    boolean isSnappingScrolls() {
147        return mSnapScrollMode != SNAP_NONE;
148    }
149}

[all classes][org.chromium.content.browser]
EMMA 2.0.5312 (C) Vladimir Roubtsov