14e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung/* 24e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * Copyright (C) 2011 The Android Open Source Project 34e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * 44e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 54e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * you may not use this file except in compliance with the License. 64e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * You may obtain a copy of the License at 74e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * 84e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 94e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * 104e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * Unless required by applicable law or agreed to in writing, software 114e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 124e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * See the License for the specific language governing permissions and 144e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * limitations under the License. 154e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung */ 164e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 174e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chungpackage com.android.launcher2; 184e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 194e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chungimport android.content.Context; 204e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chungimport android.view.MotionEvent; 214e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chungimport android.view.View; 224e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chungimport android.widget.FrameLayout; 23fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chungimport android.widget.GridLayout; 244e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 254e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung/** 264e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung * The grid based layout used strictly for the widget/wallpaper tab of the AppsCustomize pane 274e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung */ 28fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chungpublic class PagedViewGridLayout extends GridLayout implements Page { 294e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung static final String TAG = "PagedViewGridLayout"; 304e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 314e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung private int mCellCountX; 324e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung private int mCellCountY; 33038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka private Runnable mOnLayoutListener; 344e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 354e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public PagedViewGridLayout(Context context, int cellCountX, int cellCountY) { 364e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung super(context, null, 0); 374e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung mCellCountX = cellCountX; 384e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung mCellCountY = cellCountY; 394e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 404e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 414e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung int getCellCountX() { 424e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung return mCellCountX; 434e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 4422f823d340710bcde587b18a1542570cbe0360f5Adam Cohen 454e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung int getCellCountY() { 464e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung return mCellCountY; 474e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 484e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 49c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung /** 50c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung * Clears all the key listeners for the individual widgets. 51c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung */ 52c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung public void resetChildrenOnKeyListeners() { 53c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung int childCount = getChildCount(); 54c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung for (int j = 0; j < childCount; ++j) { 55c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung getChildAt(j).setOnKeyListener(null); 56c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 57c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung } 58c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung 594e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 604e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung // PagedView currently has issues with different-sized pages since it calculates the 614e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung // offset of each page to scroll to before it updates the actual size of each page 624e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung // (which can change depending on the content if the contents aren't a fixed size). 634e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung // We work around this by having a minimum size on each widget page). 64fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung int widthSpecSize = Math.min(getSuggestedMinimumWidth(), 654e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung MeasureSpec.getSize(widthMeasureSpec)); 66fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung int widthSpecMode = MeasureSpec.EXACTLY; 674e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung super.onMeasure(MeasureSpec.makeMeasureSpec(widthSpecSize, widthSpecMode), 684e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung heightMeasureSpec); 694e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 704e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 71e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka @Override 72e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka protected void onDetachedFromWindow() { 73e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka super.onDetachedFromWindow(); 74e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka mOnLayoutListener = null; 75e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka } 76e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka 77038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka public void setOnLayoutListener(Runnable r) { 78038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka mOnLayoutListener = r; 79038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 80038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka 81038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 82038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka super.onLayout(changed, left, top, right, bottom); 83038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka if (mOnLayoutListener != null) { 84038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka mOnLayoutListener.run(); 85038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 86038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka } 87038f9d8bfb53288e7cf5812f62ec3d5b25fec965Michael Jurka 884e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 894e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public boolean onTouchEvent(MotionEvent event) { 90f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung boolean result = super.onTouchEvent(event); 91f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int count = getPageChildCount(); 92f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (count > 0) { 93f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung // We only intercept the touch if we are tapping in empty space after the final row 94f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung View child = getChildOnPageAt(count - 1); 95f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung int bottom = child.getBottom(); 96f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung result = result || (event.getY() < bottom); 97f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 98f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return result; 994e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1004e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1014e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 1024e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public void removeAllViewsOnPage() { 1034e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung removeAllViews(); 1042a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka mOnLayoutListener = null; 10547639b9c1db9a5d0d89ce6b4b36d6b3c0d489602Michael Jurka setLayerType(LAYER_TYPE_NONE, null); 1064e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1074e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1084e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 1094e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public void removeViewOnPageAt(int index) { 1104e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung removeViewAt(index); 1114e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1124e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1134e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 1144e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public int getPageChildCount() { 1154e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung return getChildCount(); 1164e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1174e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1184e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 1194e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public View getChildOnPageAt(int i) { 1204e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung return getChildAt(i); 1214e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1224e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1234e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung @Override 1244e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public int indexOfChildOnPage(View v) { 1254e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung return indexOfChild(v); 1264e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1274e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung 1284e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public static class LayoutParams extends FrameLayout.LayoutParams { 1294e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung public LayoutParams(int width, int height) { 1304e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung super(width, height); 1314e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1324e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung } 1334e6a976c2d85f7261ae4318a9ccffd2440f73124Winson Chung} 134