1f923d595ace34894c49d1609d3c629336b175b89Dake Gu/*
2f923d595ace34894c49d1609d3c629336b175b89Dake Gu * Copyright (C) 2015 The Android Open Source Project
3f923d595ace34894c49d1609d3c629336b175b89Dake Gu *
4f923d595ace34894c49d1609d3c629336b175b89Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5f923d595ace34894c49d1609d3c629336b175b89Dake Gu * in compliance with the License. You may obtain a copy of the License at
6f923d595ace34894c49d1609d3c629336b175b89Dake Gu *
7f923d595ace34894c49d1609d3c629336b175b89Dake Gu * http://www.apache.org/licenses/LICENSE-2.0
8f923d595ace34894c49d1609d3c629336b175b89Dake Gu *
9f923d595ace34894c49d1609d3c629336b175b89Dake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License
10f923d595ace34894c49d1609d3c629336b175b89Dake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11f923d595ace34894c49d1609d3c629336b175b89Dake Gu * or implied. See the License for the specific language governing permissions and limitations under
12f923d595ace34894c49d1609d3c629336b175b89Dake Gu * the License.
13f923d595ace34894c49d1609d3c629336b175b89Dake Gu */
14f923d595ace34894c49d1609d3c629336b175b89Dake Gupackage android.support.v17.leanback.widget;
15f923d595ace34894c49d1609d3c629336b175b89Dake Gu
16f923d595ace34894c49d1609d3c629336b175b89Dake Guimport android.support.v4.util.CircularIntArray;
17f923d595ace34894c49d1609d3c629336b175b89Dake Gu
18f923d595ace34894c49d1609d3c629336b175b89Dake Guimport java.io.PrintWriter;
19f923d595ace34894c49d1609d3c629336b175b89Dake Gu
20f923d595ace34894c49d1609d3c629336b175b89Dake Gu/**
21f923d595ace34894c49d1609d3c629336b175b89Dake Gu * A Grid with restriction to single row.
22f923d595ace34894c49d1609d3c629336b175b89Dake Gu */
23f923d595ace34894c49d1609d3c629336b175b89Dake Guclass SingleRow extends Grid {
24f923d595ace34894c49d1609d3c629336b175b89Dake Gu
25f923d595ace34894c49d1609d3c629336b175b89Dake Gu    private final Location mTmpLocation = new Location(0);
26f923d595ace34894c49d1609d3c629336b175b89Dake Gu    private Object[] mTmpItem = new Object[1];
27f923d595ace34894c49d1609d3c629336b175b89Dake Gu
28f923d595ace34894c49d1609d3c629336b175b89Dake Gu    SingleRow() {
29f923d595ace34894c49d1609d3c629336b175b89Dake Gu        setNumRows(1);
30f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
31f923d595ace34894c49d1609d3c629336b175b89Dake Gu
32f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
33f923d595ace34894c49d1609d3c629336b175b89Dake Gu    public final Location getLocation(int index) {
34f923d595ace34894c49d1609d3c629336b175b89Dake Gu        // all items are on row 0, share the same Location object.
35f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return mTmpLocation;
36f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
37f923d595ace34894c49d1609d3c629336b175b89Dake Gu
38f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
39f923d595ace34894c49d1609d3c629336b175b89Dake Gu    public final void debugPrint(PrintWriter pw) {
40f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.print("SingleRow<");
41f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.print(mFirstVisibleIndex);
42f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.print(",");
43f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.print(mLastVisibleIndex);
44f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.print(">");
45f923d595ace34894c49d1609d3c629336b175b89Dake Gu        pw.println();
46f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
47f923d595ace34894c49d1609d3c629336b175b89Dake Gu
48f923d595ace34894c49d1609d3c629336b175b89Dake Gu    int getStartIndexForAppend() {
49f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (mLastVisibleIndex >= 0) {
50f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return mLastVisibleIndex + 1;
51f923d595ace34894c49d1609d3c629336b175b89Dake Gu        } else if (mStartIndex != START_DEFAULT) {
52f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return Math.min(mStartIndex, mProvider.getCount() - 1);
53f923d595ace34894c49d1609d3c629336b175b89Dake Gu        } else {
54f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return 0;
55f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
56f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
57f923d595ace34894c49d1609d3c629336b175b89Dake Gu
58f923d595ace34894c49d1609d3c629336b175b89Dake Gu    int getStartIndexForPrepend() {
59f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (mFirstVisibleIndex >= 0) {
60f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return mFirstVisibleIndex - 1;
61f923d595ace34894c49d1609d3c629336b175b89Dake Gu        } else if (mStartIndex != START_DEFAULT) {
62f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return Math.min(mStartIndex, mProvider.getCount() - 1);
63f923d595ace34894c49d1609d3c629336b175b89Dake Gu        } else {
64f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return mProvider.getCount() - 1;
65f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
66f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
67f923d595ace34894c49d1609d3c629336b175b89Dake Gu
68f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
69f923d595ace34894c49d1609d3c629336b175b89Dake Gu    protected final boolean prependVisibleItems(int toLimit, boolean oneColumnMode) {
70f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (mProvider.getCount() == 0) {
71f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return false;
72f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
73f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (!oneColumnMode && checkPrependOverLimit(toLimit)) {
74f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return false;
75f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
76f923d595ace34894c49d1609d3c629336b175b89Dake Gu        boolean filledOne = false;
77f923d595ace34894c49d1609d3c629336b175b89Dake Gu        for (int index = getStartIndexForPrepend(); index >= 0; index--) {
78f923d595ace34894c49d1609d3c629336b175b89Dake Gu            int size = mProvider.createItem(index, false, mTmpItem);
79f923d595ace34894c49d1609d3c629336b175b89Dake Gu            int edge;
80f923d595ace34894c49d1609d3c629336b175b89Dake Gu            if (mFirstVisibleIndex < 0 || mLastVisibleIndex < 0) {
81f923d595ace34894c49d1609d3c629336b175b89Dake Gu                edge = mReversedFlow ? Integer.MIN_VALUE : Integer.MAX_VALUE;
82f923d595ace34894c49d1609d3c629336b175b89Dake Gu                mLastVisibleIndex = mFirstVisibleIndex = index;
83f923d595ace34894c49d1609d3c629336b175b89Dake Gu            } else {
84f923d595ace34894c49d1609d3c629336b175b89Dake Gu                if (mReversedFlow) {
85f923d595ace34894c49d1609d3c629336b175b89Dake Gu                    edge = mProvider.getEdge(index + 1) + mMargin + size;
86f923d595ace34894c49d1609d3c629336b175b89Dake Gu                } else {
87f923d595ace34894c49d1609d3c629336b175b89Dake Gu                    edge = mProvider.getEdge(index + 1) - mMargin - size;
88f923d595ace34894c49d1609d3c629336b175b89Dake Gu                }
89f923d595ace34894c49d1609d3c629336b175b89Dake Gu                mFirstVisibleIndex = index;
90f923d595ace34894c49d1609d3c629336b175b89Dake Gu            }
91f923d595ace34894c49d1609d3c629336b175b89Dake Gu            mProvider.addItem(mTmpItem[0], index, size, 0, edge);
92f923d595ace34894c49d1609d3c629336b175b89Dake Gu            filledOne = true;
93f923d595ace34894c49d1609d3c629336b175b89Dake Gu            if (oneColumnMode || checkPrependOverLimit(toLimit)) {
94f923d595ace34894c49d1609d3c629336b175b89Dake Gu                break;
95f923d595ace34894c49d1609d3c629336b175b89Dake Gu            }
96f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
97f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return filledOne;
98f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
99f923d595ace34894c49d1609d3c629336b175b89Dake Gu
100f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
101f923d595ace34894c49d1609d3c629336b175b89Dake Gu    protected final boolean appendVisibleItems(int toLimit, boolean oneColumnMode) {
102f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (mProvider.getCount() == 0) {
103f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return false;
104f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
105f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (!oneColumnMode && checkAppendOverLimit(toLimit)) {
106f923d595ace34894c49d1609d3c629336b175b89Dake Gu            // not in one column mode, return immediately if over limit
107f923d595ace34894c49d1609d3c629336b175b89Dake Gu            return false;
108f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
109f923d595ace34894c49d1609d3c629336b175b89Dake Gu        boolean filledOne = false;
110f923d595ace34894c49d1609d3c629336b175b89Dake Gu        for (int index = getStartIndexForAppend(); index < mProvider.getCount(); index++) {
111f923d595ace34894c49d1609d3c629336b175b89Dake Gu            int size = mProvider.createItem(index, true, mTmpItem);
112f923d595ace34894c49d1609d3c629336b175b89Dake Gu            int edge;
113f923d595ace34894c49d1609d3c629336b175b89Dake Gu            if (mFirstVisibleIndex < 0 || mLastVisibleIndex< 0) {
114f923d595ace34894c49d1609d3c629336b175b89Dake Gu                edge = mReversedFlow ? Integer.MAX_VALUE : Integer.MIN_VALUE;
115f923d595ace34894c49d1609d3c629336b175b89Dake Gu                mLastVisibleIndex = mFirstVisibleIndex = index;
116f923d595ace34894c49d1609d3c629336b175b89Dake Gu            } else {
117f923d595ace34894c49d1609d3c629336b175b89Dake Gu                if (mReversedFlow) {
118f923d595ace34894c49d1609d3c629336b175b89Dake Gu                    edge = mProvider.getEdge(index - 1) - mProvider.getSize(index - 1) - mMargin;
119f923d595ace34894c49d1609d3c629336b175b89Dake Gu                } else {
120f923d595ace34894c49d1609d3c629336b175b89Dake Gu                    edge = mProvider.getEdge(index - 1) + mProvider.getSize(index - 1) + mMargin;
121f923d595ace34894c49d1609d3c629336b175b89Dake Gu                }
122f923d595ace34894c49d1609d3c629336b175b89Dake Gu                mLastVisibleIndex = index;
123f923d595ace34894c49d1609d3c629336b175b89Dake Gu            }
124f923d595ace34894c49d1609d3c629336b175b89Dake Gu            mProvider.addItem(mTmpItem[0], index, size, 0, edge);
125f923d595ace34894c49d1609d3c629336b175b89Dake Gu            filledOne = true;
126f923d595ace34894c49d1609d3c629336b175b89Dake Gu            if (oneColumnMode || checkAppendOverLimit(toLimit)) {
127f923d595ace34894c49d1609d3c629336b175b89Dake Gu                break;
128f923d595ace34894c49d1609d3c629336b175b89Dake Gu            }
129f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
130f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return filledOne;
131f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
132f923d595ace34894c49d1609d3c629336b175b89Dake Gu
133f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
134f923d595ace34894c49d1609d3c629336b175b89Dake Gu    public final CircularIntArray[] getItemPositionsInRows(int startPos, int endPos) {
135f923d595ace34894c49d1609d3c629336b175b89Dake Gu        // all items are on the same row:
136f923d595ace34894c49d1609d3c629336b175b89Dake Gu        mTmpItemPositionsInRows[0].clear();
137f923d595ace34894c49d1609d3c629336b175b89Dake Gu        mTmpItemPositionsInRows[0].addLast(startPos);
138f923d595ace34894c49d1609d3c629336b175b89Dake Gu        mTmpItemPositionsInRows[0].addLast(endPos);
139f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return mTmpItemPositionsInRows;
140f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
141f923d595ace34894c49d1609d3c629336b175b89Dake Gu
142f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
143f923d595ace34894c49d1609d3c629336b175b89Dake Gu    protected final int findRowMin(boolean findLarge, int indexLimit, int[] indices) {
144f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (indices != null) {
145f923d595ace34894c49d1609d3c629336b175b89Dake Gu            indices[0] = 0;
146f923d595ace34894c49d1609d3c629336b175b89Dake Gu            indices[1] = indexLimit;
147f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
148f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return mReversedFlow ? mProvider.getEdge(indexLimit) - mProvider.getSize(indexLimit)
149f923d595ace34894c49d1609d3c629336b175b89Dake Gu                : mProvider.getEdge(indexLimit);
150f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
151f923d595ace34894c49d1609d3c629336b175b89Dake Gu
152f923d595ace34894c49d1609d3c629336b175b89Dake Gu    @Override
153f923d595ace34894c49d1609d3c629336b175b89Dake Gu    protected final int findRowMax(boolean findLarge, int indexLimit, int[] indices) {
154f923d595ace34894c49d1609d3c629336b175b89Dake Gu        if (indices != null) {
155f923d595ace34894c49d1609d3c629336b175b89Dake Gu            indices[0] = 0;
156f923d595ace34894c49d1609d3c629336b175b89Dake Gu            indices[1] = indexLimit;
157f923d595ace34894c49d1609d3c629336b175b89Dake Gu        }
158f923d595ace34894c49d1609d3c629336b175b89Dake Gu        return mReversedFlow ? mProvider.getEdge(indexLimit)
159f923d595ace34894c49d1609d3c629336b175b89Dake Gu                : mProvider.getEdge(indexLimit) + mProvider.getSize(indexLimit);
160f923d595ace34894c49d1609d3c629336b175b89Dake Gu    }
161f923d595ace34894c49d1609d3c629336b175b89Dake Gu
162f923d595ace34894c49d1609d3c629336b175b89Dake Gu}
163