Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.launcher3;
     18 
     19 import android.appwidget.AppWidgetProviderInfo;
     20 import android.content.Context;
     21 import android.content.pm.PackageManager;
     22 import android.content.pm.ResolveInfo;
     23 import android.content.res.Resources;
     24 import android.graphics.Rect;
     25 import android.util.AttributeSet;
     26 import android.util.TypedValue;
     27 import android.view.MotionEvent;
     28 import android.view.View;
     29 import android.widget.ImageView;
     30 import android.widget.LinearLayout;
     31 import android.widget.TextView;
     32 
     33 import com.android.launcher3.R;
     34 
     35 /**
     36  * The linear layout used strictly for the widget/wallpaper tab of the customization tray
     37  */
     38 public class PagedViewWidget extends LinearLayout {
     39     static final String TAG = "PagedViewWidgetLayout";
     40 
     41     private static boolean sDeletePreviewsWhenDetachedFromWindow = true;
     42     private static boolean sRecyclePreviewsWhenDetachedFromWindow = true;
     43 
     44     private String mDimensionsFormatString;
     45     CheckForShortPress mPendingCheckForShortPress = null;
     46     ShortPressListener mShortPressListener = null;
     47     boolean mShortPressTriggered = false;
     48     static PagedViewWidget sShortpressTarget = null;
     49     boolean mIsAppWidget;
     50     private final Rect mOriginalImagePadding = new Rect();
     51     private Object mInfo;
     52     private WidgetPreviewLoader mWidgetPreviewLoader;
     53 
     54     public PagedViewWidget(Context context) {
     55         this(context, null);
     56     }
     57 
     58     public PagedViewWidget(Context context, AttributeSet attrs) {
     59         this(context, attrs, 0);
     60     }
     61 
     62     public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) {
     63         super(context, attrs, defStyle);
     64 
     65         final Resources r = context.getResources();
     66         mDimensionsFormatString = r.getString(R.string.widget_dims_format);
     67 
     68         setWillNotDraw(false);
     69         setClipToPadding(false);
     70     }
     71 
     72     @Override
     73     protected void onFinishInflate() {
     74         super.onFinishInflate();
     75 
     76         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
     77         mOriginalImagePadding.left = image.getPaddingLeft();
     78         mOriginalImagePadding.top = image.getPaddingTop();
     79         mOriginalImagePadding.right = image.getPaddingRight();
     80         mOriginalImagePadding.bottom = image.getPaddingBottom();
     81 
     82         // Ensure we are using the right text size
     83         LauncherAppState app = LauncherAppState.getInstance();
     84         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
     85         TextView name = (TextView) findViewById(R.id.widget_name);
     86         if (name != null) {
     87             name.setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
     88         }
     89         TextView dims = (TextView) findViewById(R.id.widget_dims);
     90         if (dims != null) {
     91             dims.setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.iconTextSize);
     92         }
     93     }
     94 
     95     public static void setDeletePreviewsWhenDetachedFromWindow(boolean value) {
     96         sDeletePreviewsWhenDetachedFromWindow = value;
     97     }
     98 
     99     public static void setRecyclePreviewsWhenDetachedFromWindow(boolean value) {
    100         sRecyclePreviewsWhenDetachedFromWindow = value;
    101     }
    102 
    103     @Override
    104     protected void onDetachedFromWindow() {
    105         super.onDetachedFromWindow();
    106 
    107         if (sDeletePreviewsWhenDetachedFromWindow) {
    108             final ImageView image = (ImageView) findViewById(R.id.widget_preview);
    109             if (image != null) {
    110                 FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable();
    111                 if (sRecyclePreviewsWhenDetachedFromWindow &&
    112                         mInfo != null && preview != null && preview.getBitmap() != null) {
    113                     mWidgetPreviewLoader.recycleBitmap(mInfo, preview.getBitmap());
    114                 }
    115                 image.setImageDrawable(null);
    116             }
    117         }
    118     }
    119 
    120     public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info,
    121             int maxWidth, int[] cellSpan, WidgetPreviewLoader loader) {
    122         LauncherAppState app = LauncherAppState.getInstance();
    123         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
    124 
    125         mIsAppWidget = true;
    126         mInfo = info;
    127         final ImageView image = (ImageView) findViewById(R.id.widget_preview);
    128         if (maxWidth > -1) {
    129             image.setMaxWidth(maxWidth);
    130         }
    131         final TextView name = (TextView) findViewById(R.id.widget_name);
    132         name.setText(info.label);
    133         final TextView dims = (TextView) findViewById(R.id.widget_dims);
    134         if (dims != null) {
    135             int hSpan = Math.min(cellSpan[0], (int) grid.numColumns);
    136             int vSpan = Math.min(cellSpan[1], (int) grid.numRows);
    137             dims.setText(String.format(mDimensionsFormatString, hSpan, vSpan));
    138         }
    139         mWidgetPreviewLoader = loader;
    140     }
    141 
    142     public void applyFromResolveInfo(
    143             PackageManager pm, ResolveInfo info, WidgetPreviewLoader loader) {
    144         mIsAppWidget = false;
    145         mInfo = info;
    146         CharSequence label = info.loadLabel(pm);
    147         final TextView name = (TextView) findViewById(R.id.widget_name);
    148         name.setText(label);
    149         final TextView dims = (TextView) findViewById(R.id.widget_dims);
    150         if (dims != null) {
    151             dims.setText(String.format(mDimensionsFormatString, 1, 1));
    152         }
    153         mWidgetPreviewLoader = loader;
    154     }
    155 
    156     public int[] getPreviewSize() {
    157         final ImageView i = (ImageView) findViewById(R.id.widget_preview);
    158         int[] maxSize = new int[2];
    159         maxSize[0] = i.getWidth() - mOriginalImagePadding.left - mOriginalImagePadding.right;
    160         maxSize[1] = i.getHeight() - mOriginalImagePadding.top;
    161         return maxSize;
    162     }
    163 
    164     void applyPreview(FastBitmapDrawable preview, int index) {
    165         final PagedViewWidgetImageView image =
    166             (PagedViewWidgetImageView) findViewById(R.id.widget_preview);
    167         if (preview != null) {
    168             image.mAllowRequestLayout = false;
    169             image.setImageDrawable(preview);
    170             if (mIsAppWidget) {
    171                 // center horizontally
    172                 int[] imageSize = getPreviewSize();
    173                 int centerAmount = (imageSize[0] - preview.getIntrinsicWidth()) / 2;
    174                 image.setPadding(mOriginalImagePadding.left + centerAmount,
    175                         mOriginalImagePadding.top,
    176                         mOriginalImagePadding.right,
    177                         mOriginalImagePadding.bottom);
    178             }
    179             image.setAlpha(1f);
    180             image.mAllowRequestLayout = true;
    181         }
    182     }
    183 
    184     void setShortPressListener(ShortPressListener listener) {
    185         mShortPressListener = listener;
    186     }
    187 
    188     interface ShortPressListener {
    189         void onShortPress(View v);
    190         void cleanUpShortPress(View v);
    191     }
    192 
    193     class CheckForShortPress implements Runnable {
    194         public void run() {
    195             if (sShortpressTarget != null) return;
    196             if (mShortPressListener != null) {
    197                 mShortPressListener.onShortPress(PagedViewWidget.this);
    198                 sShortpressTarget = PagedViewWidget.this;
    199             }
    200             mShortPressTriggered = true;
    201         }
    202     }
    203 
    204     private void checkForShortPress() {
    205         if (sShortpressTarget != null) return;
    206         if (mPendingCheckForShortPress == null) {
    207             mPendingCheckForShortPress = new CheckForShortPress();
    208         }
    209         postDelayed(mPendingCheckForShortPress, 120);
    210     }
    211 
    212     /**
    213      * Remove the longpress detection timer.
    214      */
    215     private void removeShortPressCallback() {
    216         if (mPendingCheckForShortPress != null) {
    217           removeCallbacks(mPendingCheckForShortPress);
    218         }
    219     }
    220 
    221     private void cleanUpShortPress() {
    222         removeShortPressCallback();
    223         if (mShortPressTriggered) {
    224             if (mShortPressListener != null) {
    225                 mShortPressListener.cleanUpShortPress(PagedViewWidget.this);
    226             }
    227             mShortPressTriggered = false;
    228         }
    229     }
    230 
    231     static void resetShortPressTarget() {
    232         sShortpressTarget = null;
    233     }
    234 
    235     @Override
    236     public boolean onTouchEvent(MotionEvent event) {
    237         super.onTouchEvent(event);
    238 
    239         switch (event.getAction()) {
    240             case MotionEvent.ACTION_UP:
    241                 cleanUpShortPress();
    242                 break;
    243             case MotionEvent.ACTION_DOWN:
    244                 checkForShortPress();
    245                 break;
    246             case MotionEvent.ACTION_CANCEL:
    247                 cleanUpShortPress();
    248                 break;
    249             case MotionEvent.ACTION_MOVE:
    250                 break;
    251         }
    252 
    253         // We eat up the touch events here, since the PagedView (which uses the same swiping
    254         // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when
    255         // the user is scrolling between pages.  This means that if the pages themselves don't
    256         // handle touch events, it gets forwarded up to PagedView itself, and it's own
    257         // onTouchEvent() handling will prevent further intercept touch events from being called
    258         // (it's the same view in that case).  This is not ideal, but to prevent more changes,
    259         // we just always mark the touch event as handled.
    260         return true;
    261     }
    262 }
    263