19106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn/* 29106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Copyright (C) 2014 The Android Open Source Project 39106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * 49106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 59106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * in compliance with the License. You may obtain a copy of the License at 69106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * 79106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * http://www.apache.org/licenses/LICENSE-2.0 89106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * 99106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Unless required by applicable law or agreed to in writing, software distributed under the License 109106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 119106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * or implied. See the License for the specific language governing permissions and limitations under 129106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * the License. 139106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 149106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 159106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbournpackage android.support.v17.leanback.widget; 169106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 17a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbournimport static android.support.v17.leanback.widget.BaseGridView.WINDOW_ALIGN_LOW_EDGE; 18a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbournimport static android.support.v17.leanback.widget.BaseGridView.WINDOW_ALIGN_HIGH_EDGE; 19a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbournimport static android.support.v17.leanback.widget.BaseGridView.WINDOW_ALIGN_BOTH_EDGE; 20a8a3b898da49324e83ea32c3f08776a481312166Tim Kilbournimport static android.support.v17.leanback.widget.BaseGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED; 219106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 229106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbournimport static android.support.v7.widget.RecyclerView.HORIZONTAL; 239106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 248e3566285de4ac771d6188f62fe947e23d371a3dKris Giesingimport android.view.View; 258e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing 269106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn/** 279106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Maintains Window Alignment information of two axis. 289106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 299106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbournclass WindowAlignment { 309106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 319106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** 329106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Maintains alignment information in one direction. 339106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 349106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn public static class Axis { 359106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** 369106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * mScrollCenter is used to calculate dynamic transformation based on how far a view 379106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * is from the mScrollCenter. For example, the views with center close to mScrollCenter 389106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * will be scaled up. 399106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 409106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private float mScrollCenter; 419106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** 429106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Right or bottom edge of last child. 439106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 449106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mMaxEdge; 459106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** 469106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn * Left or top edge of first child, typically should be zero. 479106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn */ 489106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mMinEdge; 4979b86b227e6794937ec311522b50e727f8eec263Dake Gu /** 5079b86b227e6794937ec311522b50e727f8eec263Dake Gu * Max Scroll value 5179b86b227e6794937ec311522b50e727f8eec263Dake Gu */ 5279b86b227e6794937ec311522b50e727f8eec263Dake Gu private int mMaxScroll; 5379b86b227e6794937ec311522b50e727f8eec263Dake Gu /** 5479b86b227e6794937ec311522b50e727f8eec263Dake Gu * Min Scroll value 5579b86b227e6794937ec311522b50e727f8eec263Dake Gu */ 5679b86b227e6794937ec311522b50e727f8eec263Dake Gu private int mMinScroll; 579106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 589106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mWindowAlignment = WINDOW_ALIGN_BOTH_EDGE; 599106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 609106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mWindowAlignmentOffset = 0; 619106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 629106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private float mWindowAlignmentOffsetPercent = 50f; 639106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 649106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mSize; 659106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 669106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mPaddingLow; 679106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 689106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mPaddingHigh; 699106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 70e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing private boolean mReversedFlow; 71e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing 729106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private String mName; // for debugging 739106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 749106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn public Axis(String name) { 759106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn reset(); 769106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mName = name; 779106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 789106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 799106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getWindowAlignment() { 809106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mWindowAlignment; 819106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 829106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 839106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setWindowAlignment(int windowAlignment) { 849106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mWindowAlignment = windowAlignment; 859106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 869106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 879106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getWindowAlignmentOffset() { 889106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mWindowAlignmentOffset; 899106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 909106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 919106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setWindowAlignmentOffset(int offset) { 929106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mWindowAlignmentOffset = offset; 939106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 949106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 959106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setWindowAlignmentOffsetPercent(float percent) { 969106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if ((percent < 0 || percent > 100) 979106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn && percent != WINDOW_ALIGN_OFFSET_PERCENT_DISABLED) { 989106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn throw new IllegalArgumentException(); 999106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1009106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mWindowAlignmentOffsetPercent = percent; 1019106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1029106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1039106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public float getWindowAlignmentOffsetPercent() { 1049106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mWindowAlignmentOffsetPercent; 1059106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1069106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1079106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getScrollCenter() { 1089106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return (int) mScrollCenter; 1099106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1109106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1119106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** set minEdge, Integer.MIN_VALUE means unknown*/ 1129106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setMinEdge(int minEdge) { 1139106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMinEdge = minEdge; 1149106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1159106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1166ef7396cd226efcce83389c5107166c121e25785Dake Gu final public int getMinEdge() { 1176ef7396cd226efcce83389c5107166c121e25785Dake Gu return mMinEdge; 1186ef7396cd226efcce83389c5107166c121e25785Dake Gu } 1196ef7396cd226efcce83389c5107166c121e25785Dake Gu 12079b86b227e6794937ec311522b50e727f8eec263Dake Gu /** set minScroll, Integer.MIN_VALUE means unknown*/ 12179b86b227e6794937ec311522b50e727f8eec263Dake Gu final public void setMinScroll(int minScroll) { 12279b86b227e6794937ec311522b50e727f8eec263Dake Gu mMinScroll = minScroll; 12379b86b227e6794937ec311522b50e727f8eec263Dake Gu } 12479b86b227e6794937ec311522b50e727f8eec263Dake Gu 12579b86b227e6794937ec311522b50e727f8eec263Dake Gu final public int getMinScroll() { 12679b86b227e6794937ec311522b50e727f8eec263Dake Gu return mMinScroll; 12779b86b227e6794937ec311522b50e727f8eec263Dake Gu } 12879b86b227e6794937ec311522b50e727f8eec263Dake Gu 12979b86b227e6794937ec311522b50e727f8eec263Dake Gu final public void invalidateScrollMin() { 1309106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMinEdge = Integer.MIN_VALUE; 13179b86b227e6794937ec311522b50e727f8eec263Dake Gu mMinScroll = Integer.MIN_VALUE; 1329106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1339106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1349106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn /** update max edge, Integer.MAX_VALUE means unknown*/ 1359106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setMaxEdge(int maxEdge) { 1369106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMaxEdge = maxEdge; 1379106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1389106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1396ef7396cd226efcce83389c5107166c121e25785Dake Gu final public int getMaxEdge() { 1406ef7396cd226efcce83389c5107166c121e25785Dake Gu return mMaxEdge; 1416ef7396cd226efcce83389c5107166c121e25785Dake Gu } 1426ef7396cd226efcce83389c5107166c121e25785Dake Gu 14379b86b227e6794937ec311522b50e727f8eec263Dake Gu /** update max scroll, Integer.MAX_VALUE means unknown*/ 14479b86b227e6794937ec311522b50e727f8eec263Dake Gu final public void setMaxScroll(int maxScroll) { 14579b86b227e6794937ec311522b50e727f8eec263Dake Gu mMaxScroll = maxScroll; 14679b86b227e6794937ec311522b50e727f8eec263Dake Gu } 14779b86b227e6794937ec311522b50e727f8eec263Dake Gu 14879b86b227e6794937ec311522b50e727f8eec263Dake Gu final public int getMaxScroll() { 14979b86b227e6794937ec311522b50e727f8eec263Dake Gu return mMaxScroll; 15079b86b227e6794937ec311522b50e727f8eec263Dake Gu } 15179b86b227e6794937ec311522b50e727f8eec263Dake Gu 15279b86b227e6794937ec311522b50e727f8eec263Dake Gu final public void invalidateScrollMax() { 1539106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMaxEdge = Integer.MAX_VALUE; 15479b86b227e6794937ec311522b50e727f8eec263Dake Gu mMaxScroll = Integer.MAX_VALUE; 1559106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1569106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1579106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public float updateScrollCenter(float scrollTarget) { 1589106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mScrollCenter = scrollTarget; 1599106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return scrollTarget; 1609106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1619106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1629106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private void reset() { 1639106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mScrollCenter = Integer.MIN_VALUE; 1649106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMinEdge = Integer.MIN_VALUE; 1659106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMaxEdge = Integer.MAX_VALUE; 1669106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1679106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1689106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public boolean isMinUnknown() { 1699106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mMinEdge == Integer.MIN_VALUE; 1709106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1719106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1729106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public boolean isMaxUnknown() { 1739106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mMaxEdge == Integer.MAX_VALUE; 1749106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1759106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1769106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setSize(int size) { 1779106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mSize = size; 1789106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1799106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1809106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getSize() { 1819106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mSize; 1829106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1839106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1849106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setPadding(int paddingLow, int paddingHigh) { 1859106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mPaddingLow = paddingLow; 1869106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mPaddingHigh = paddingHigh; 1879106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1889106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1899106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getPaddingLow() { 1909106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mPaddingLow; 1919106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1929106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1939106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getPaddingHigh() { 1949106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mPaddingHigh; 1959106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 1969106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 1979106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getClientSize() { 1989106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mSize - mPaddingLow - mPaddingHigh; 1999106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2009106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2017db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu final public int getSystemScrollPos(boolean isAtMin, boolean isAtMax) { 2027db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu return getSystemScrollPos((int) mScrollCenter, isAtMin, isAtMax); 2039106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2049106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2057db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu final public int getSystemScrollPos(int scrollCenter, boolean isAtMin, boolean isAtMax) { 2069106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn int middlePosition; 207e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if (!mReversedFlow) { 208e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if (mWindowAlignmentOffset >= 0) { 209e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition = mWindowAlignmentOffset - mPaddingLow; 210e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } else { 211e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition = mSize + mWindowAlignmentOffset - mPaddingLow; 212e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 213e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if (mWindowAlignmentOffsetPercent != WINDOW_ALIGN_OFFSET_PERCENT_DISABLED) { 214e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition += (int) (mSize * mWindowAlignmentOffsetPercent / 100); 215e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 2169106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } else { 217e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if (mWindowAlignmentOffset >= 0) { 218e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition = mSize - mWindowAlignmentOffset - mPaddingLow; 219e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } else { 220e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition = - mWindowAlignmentOffset - mPaddingLow; 221e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 222e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if (mWindowAlignmentOffsetPercent != WINDOW_ALIGN_OFFSET_PERCENT_DISABLED) { 223e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing middlePosition -= (int) (mSize * mWindowAlignmentOffsetPercent / 100); 224e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 2259106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2269106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn int clientSize = getClientSize(); 2279106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn int afterMiddlePosition = clientSize - middlePosition; 2289106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn boolean isMinUnknown = isMinUnknown(); 2299106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn boolean isMaxUnknown = isMaxUnknown(); 2309106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if (!isMinUnknown && !isMaxUnknown && 2319106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn (mWindowAlignment & WINDOW_ALIGN_BOTH_EDGE) == WINDOW_ALIGN_BOTH_EDGE) { 2329106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if (mMaxEdge - mMinEdge <= clientSize) { 2339106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn // total children size is less than view port and we want to align 2348e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing // both edge: align first child to start edge of view port 235e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing return mReversedFlow ? mMaxEdge - mPaddingLow - clientSize 236e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing : mMinEdge - mPaddingLow; 2379106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2389106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2399106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if (!isMinUnknown) { 240e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if ((!mReversedFlow ? (mWindowAlignment & WINDOW_ALIGN_LOW_EDGE) != 0 241e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing : (mWindowAlignment & WINDOW_ALIGN_HIGH_EDGE) != 0) 242e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing && (isAtMin || scrollCenter - mMinEdge <= middlePosition)) { 2438e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing // scroll center is within half of view port size: align the start edge 2448e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing // of first child to the start edge of view port 2457db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu return mMinEdge - mPaddingLow; 2469106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2479106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2489106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if (!isMaxUnknown) { 249e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing if ((!mReversedFlow ? (mWindowAlignment & WINDOW_ALIGN_HIGH_EDGE) != 0 250e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing : (mWindowAlignment & WINDOW_ALIGN_LOW_EDGE) != 0) 251e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing && (isAtMax || mMaxEdge - scrollCenter <= afterMiddlePosition)) { 2528e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing // scroll center is very close to the end edge of view port : align the 2538e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing // end edge of last children (plus expanded size) to view port's end 2547db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu return mMaxEdge - mPaddingLow - clientSize; 2559106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2569106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2579106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn // else put scroll center in middle of view port 2587db64bb839e5589b38322f9f7456cb928ffc2c1cDake Gu return scrollCenter - middlePosition - mPaddingLow; 2599106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2609106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 261e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing final public void setReversedFlow(boolean reversedFlow) { 262e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing mReversedFlow = reversedFlow; 263e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing } 264e0e66a21916f94ebbced0d1ffe3dc652c9c7a15eKris Giesing 2659106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn @Override 2669106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn public String toString() { 2679106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return "center: " + mScrollCenter + " min:" + mMinEdge + 2689106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn " max:" + mMaxEdge; 2699106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2709106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2719106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2729106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2739106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private int mOrientation = HORIZONTAL; 2749106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2759106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public Axis vertical = new Axis("vertical"); 2769106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2779106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public Axis horizontal = new Axis("horizontal"); 2789106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2799106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private Axis mMainAxis = horizontal; 2809106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2819106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn private Axis mSecondAxis = vertical; 2829106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2839106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public Axis mainAxis() { 2849106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mMainAxis; 2859106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2869106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2879106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public Axis secondAxis() { 2889106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mSecondAxis; 2899106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 2909106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 2919106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void setOrientation(int orientation) { 2929106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mOrientation = orientation; 2939106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn if (mOrientation == HORIZONTAL) { 2949106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMainAxis = horizontal; 2959106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mSecondAxis = vertical; 2969106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } else { 2979106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mMainAxis = vertical; 2989106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mSecondAxis = horizontal; 2999106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 3009106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 3019106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 3029106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public int getOrientation() { 3039106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return mOrientation; 3049106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 3059106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 3069106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn final public void reset() { 3079106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn mainAxis().reset(); 3089106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 3099106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 3109106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn @Override 3119106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn public String toString() { 3129106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn return new StringBuffer().append("horizontal=") 3139106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn .append(horizontal.toString()) 3148e3566285de4ac771d6188f62fe947e23d371a3dKris Giesing .append("; vertical=") 3159106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn .append(vertical.toString()) 3169106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn .toString(); 3179106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn } 3189106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn 3199106804a84e5e8733e0b9313f749fa1f726e5d11Tim Kilbourn} 320