Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2016 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.widget;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.Canvas;
     21 import android.graphics.Paint;
     22 import android.graphics.Point;
     23 import android.graphics.Rect;
     24 import android.graphics.drawable.Drawable;
     25 import android.view.View;
     26 import android.widget.RemoteViews;
     27 
     28 import com.android.launcher3.DeviceProfile;
     29 import com.android.launcher3.DragSource;
     30 import com.android.launcher3.Launcher;
     31 import com.android.launcher3.LauncherAppState;
     32 import com.android.launcher3.PendingAddItemInfo;
     33 import com.android.launcher3.R;
     34 import com.android.launcher3.dragndrop.DragOptions;
     35 import com.android.launcher3.dragndrop.LivePreviewWidgetCell;
     36 import com.android.launcher3.graphics.DragPreviewProvider;
     37 import com.android.launcher3.graphics.LauncherIcons;
     38 
     39 /**
     40  * Extension of {@link DragPreviewProvider} with logic specific to pending widgets/shortcuts
     41  * dragged from the widget tray.
     42  */
     43 public class PendingItemDragHelper extends DragPreviewProvider {
     44 
     45     private static final float MAX_WIDGET_SCALE = 1.25f;
     46 
     47     private final PendingAddItemInfo mAddInfo;
     48     private int[] mEstimatedCellSize;
     49 
     50     private RemoteViews mPreview;
     51 
     52     public PendingItemDragHelper(View view) {
     53         super(view);
     54         mAddInfo = (PendingAddItemInfo) view.getTag();
     55     }
     56 
     57     public void setPreview(RemoteViews preview) {
     58         mPreview = preview;
     59     }
     60 
     61     /**
     62      * Starts the drag for the pending item associated with the view.
     63      *
     64      * @param previewBounds The bounds where the image was displayed,
     65      *                      {@link WidgetImageView#getBitmapBounds()}
     66      * @param previewBitmapWidth The actual width of the bitmap displayed in the view.
     67      * @param previewViewWidth The width of {@link WidgetImageView} displaying the preview
     68      * @param screenPos Position of {@link WidgetImageView} on the screen
     69      */
     70     public void startDrag(Rect previewBounds, int previewBitmapWidth, int previewViewWidth,
     71             Point screenPos, DragSource source, DragOptions options) {
     72         final Launcher launcher = Launcher.getLauncher(mView.getContext());
     73         LauncherAppState app = LauncherAppState.getInstance(launcher);
     74 
     75         Bitmap preview = null;
     76         final float scale;
     77         final Point dragOffset;
     78         final Rect dragRegion;
     79 
     80         mEstimatedCellSize = launcher.getWorkspace().estimateItemSize(mAddInfo);
     81 
     82         if (mAddInfo instanceof PendingAddWidgetInfo) {
     83             PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) mAddInfo;
     84 
     85             int maxWidth = Math.min((int) (previewBitmapWidth * MAX_WIDGET_SCALE), mEstimatedCellSize[0]);
     86 
     87             int[] previewSizeBeforeScale = new int[1];
     88 
     89             if (mPreview != null) {
     90                 preview = LivePreviewWidgetCell.generateFromRemoteViews(launcher, mPreview,
     91                         createWidgetInfo.info, maxWidth, previewSizeBeforeScale);
     92             }
     93             if (preview == null) {
     94                 preview = app.getWidgetCache().generateWidgetPreview(
     95                         launcher, createWidgetInfo.info, maxWidth, null, previewSizeBeforeScale);
     96             }
     97 
     98             if (previewSizeBeforeScale[0] < previewBitmapWidth) {
     99                 // The icon has extra padding around it.
    100                 int padding = (previewBitmapWidth - previewSizeBeforeScale[0]) / 2;
    101                 if (previewBitmapWidth > previewViewWidth) {
    102                     padding = padding * previewViewWidth / previewBitmapWidth;
    103                 }
    104 
    105                 previewBounds.left += padding;
    106                 previewBounds.right -= padding;
    107             }
    108             scale = previewBounds.width() / (float) preview.getWidth();
    109             launcher.getDragController().addDragListener(new WidgetHostViewLoader(launcher, mView));
    110 
    111             dragOffset = null;
    112             dragRegion = null;
    113         } else {
    114             PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
    115             Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
    116             LauncherIcons li = LauncherIcons.obtain(launcher);
    117             preview = li.createScaledBitmapWithoutShadow(icon, 0);
    118             li.recycle();
    119             scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getWidth();
    120 
    121             dragOffset = new Point(previewPadding / 2, previewPadding / 2);
    122 
    123             // Create a preview same as the workspace cell size and draw the icon at the
    124             // appropriate position.
    125             DeviceProfile dp = launcher.getDeviceProfile();
    126             int iconSize = dp.iconSizePx;
    127 
    128             int padding = launcher.getResources()
    129                     .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
    130             previewBounds.left += padding;
    131             previewBounds.top += padding;
    132 
    133             dragRegion = new Rect();
    134             dragRegion.left = (mEstimatedCellSize[0] - iconSize) / 2;
    135             dragRegion.right = dragRegion.left + iconSize;
    136             dragRegion.top = (mEstimatedCellSize[1]
    137                     - iconSize - dp.iconTextSizePx - dp.iconDrawablePaddingPx) / 2;
    138             dragRegion.bottom = dragRegion.top + iconSize;
    139         }
    140 
    141         // Since we are not going through the workspace for starting the drag, set drag related
    142         // information on the workspace before starting the drag.
    143         launcher.getWorkspace().prepareDragWithProvider(this);
    144 
    145         int dragLayerX = screenPos.x + previewBounds.left
    146                 + (int) ((scale * preview.getWidth() - preview.getWidth()) / 2);
    147         int dragLayerY = screenPos.y + previewBounds.top
    148                 + (int) ((scale * preview.getHeight() - preview.getHeight()) / 2);
    149 
    150         // Start the drag
    151         launcher.getDragController().startDrag(preview, dragLayerX, dragLayerY, source, mAddInfo,
    152                 dragOffset, dragRegion, scale, scale, options);
    153     }
    154 
    155     @Override
    156     protected Bitmap convertPreviewToAlphaBitmap(Bitmap preview) {
    157         if (mAddInfo instanceof PendingAddShortcutInfo || mEstimatedCellSize == null) {
    158             return super.convertPreviewToAlphaBitmap(preview);
    159         }
    160 
    161         int w = mEstimatedCellSize[0];
    162         int h = mEstimatedCellSize[1];
    163         final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
    164         Rect src = new Rect(0, 0, preview.getWidth(), preview.getHeight());
    165 
    166         float scaleFactor = Math.min((w - blurSizeOutline) / (float) preview.getWidth(),
    167                 (h - blurSizeOutline) / (float) preview.getHeight());
    168         int scaledWidth = (int) (scaleFactor * preview.getWidth());
    169         int scaledHeight = (int) (scaleFactor * preview.getHeight());
    170         Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
    171 
    172         // center the image
    173         dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
    174         new Canvas(b).drawBitmap(preview, src, dst, new Paint(Paint.FILTER_BITMAP_FLAG));
    175         return b;
    176     }
    177 }
    178