Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2011 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.animation.Animator;
     20 import android.animation.AnimatorListenerAdapter;
     21 import android.animation.ArgbEvaluator;
     22 import android.animation.ValueAnimator;
     23 import android.content.Context;
     24 import android.graphics.Color;
     25 import android.graphics.Rect;
     26 import android.graphics.drawable.ColorDrawable;
     27 import android.graphics.drawable.Drawable;
     28 import android.support.v4.graphics.ColorUtils;
     29 import android.util.AttributeSet;
     30 import android.view.LayoutInflater;
     31 import android.view.MotionEvent;
     32 import android.view.View;
     33 import android.view.ViewDebug;
     34 import android.widget.FrameLayout;
     35 import android.widget.TextView;
     36 
     37 import com.android.launcher3.config.FeatureFlags;
     38 import com.android.launcher3.dynamicui.ExtractedColors;
     39 import com.android.launcher3.logging.UserEventDispatcher;
     40 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
     41 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
     42 import com.android.launcher3.util.Themes;
     43 
     44 public class Hotseat extends FrameLayout
     45         implements UserEventDispatcher.LogContainerProvider {
     46 
     47     private CellLayout mContent;
     48 
     49     private Launcher mLauncher;
     50 
     51     @ViewDebug.ExportedProperty(category = "launcher")
     52     private final boolean mHasVerticalHotseat;
     53 
     54     @ViewDebug.ExportedProperty(category = "launcher")
     55     private int mBackgroundColor;
     56     @ViewDebug.ExportedProperty(category = "launcher")
     57     private ColorDrawable mBackground;
     58     private ValueAnimator mBackgroundColorAnimator;
     59 
     60     public Hotseat(Context context) {
     61         this(context, null);
     62     }
     63 
     64     public Hotseat(Context context, AttributeSet attrs) {
     65         this(context, attrs, 0);
     66     }
     67 
     68     public Hotseat(Context context, AttributeSet attrs, int defStyle) {
     69         super(context, attrs, defStyle);
     70         mLauncher = Launcher.getLauncher(context);
     71         mHasVerticalHotseat = mLauncher.getDeviceProfile().isVerticalBarLayout();
     72         mBackgroundColor = ColorUtils.setAlphaComponent(
     73                 Themes.getAttrColor(context, android.R.attr.colorPrimary), 0);
     74         mBackground = new ColorDrawable(mBackgroundColor);
     75         if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
     76             setBackground(mBackground);
     77         }
     78     }
     79 
     80     public CellLayout getLayout() {
     81         return mContent;
     82     }
     83 
     84     /**
     85      * Returns whether there are other icons than the all apps button in the hotseat.
     86      */
     87     public boolean hasIcons() {
     88         return mContent.getShortcutsAndWidgets().getChildCount() > 1;
     89     }
     90 
     91     /**
     92      * Registers the specified listener on the cell layout of the hotseat.
     93      */
     94     @Override
     95     public void setOnLongClickListener(OnLongClickListener l) {
     96         mContent.setOnLongClickListener(l);
     97     }
     98 
     99     /* Get the orientation invariant order of the item in the hotseat for persistence. */
    100     int getOrderInHotseat(int x, int y) {
    101         return mHasVerticalHotseat ? (mContent.getCountY() - y - 1) : x;
    102     }
    103 
    104     /* Get the orientation specific coordinates given an invariant order in the hotseat. */
    105     int getCellXFromOrder(int rank) {
    106         return mHasVerticalHotseat ? 0 : rank;
    107     }
    108 
    109     int getCellYFromOrder(int rank) {
    110         return mHasVerticalHotseat ? (mContent.getCountY() - (rank + 1)) : 0;
    111     }
    112 
    113     @Override
    114     protected void onFinishInflate() {
    115         super.onFinishInflate();
    116         DeviceProfile grid = mLauncher.getDeviceProfile();
    117         mContent = (CellLayout) findViewById(R.id.layout);
    118         if (grid.isVerticalBarLayout()) {
    119             mContent.setGridSize(1, grid.inv.numHotseatIcons);
    120         } else {
    121             mContent.setGridSize(grid.inv.numHotseatIcons, 1);
    122         }
    123 
    124         resetLayout();
    125     }
    126 
    127     void resetLayout() {
    128         mContent.removeAllViewsInLayout();
    129 
    130         if (!FeatureFlags.NO_ALL_APPS_ICON) {
    131             // Add the Apps button
    132             Context context = getContext();
    133             DeviceProfile grid = mLauncher.getDeviceProfile();
    134             int allAppsButtonRank = grid.inv.getAllAppsButtonRank();
    135 
    136             LayoutInflater inflater = LayoutInflater.from(context);
    137             TextView allAppsButton = (TextView)
    138                     inflater.inflate(R.layout.all_apps_button, mContent, false);
    139             Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
    140             d.setBounds(0, 0, grid.iconSizePx, grid.iconSizePx);
    141 
    142             int scaleDownPx = getResources().getDimensionPixelSize(R.dimen.all_apps_button_scale_down);
    143             Rect bounds = d.getBounds();
    144             d.setBounds(bounds.left, bounds.top + scaleDownPx / 2, bounds.right - scaleDownPx,
    145                     bounds.bottom - scaleDownPx / 2);
    146             allAppsButton.setCompoundDrawables(null, d, null, null);
    147 
    148             allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
    149             allAppsButton.setOnKeyListener(new HotseatIconKeyEventListener());
    150             if (mLauncher != null) {
    151                 mLauncher.setAllAppsButton(allAppsButton);
    152                 allAppsButton.setOnClickListener(mLauncher);
    153                 allAppsButton.setOnFocusChangeListener(mLauncher.mFocusHandler);
    154             }
    155 
    156             // Note: We do this to ensure that the hotseat is always laid out in the orientation of
    157             // the hotseat in order regardless of which orientation they were added
    158             int x = getCellXFromOrder(allAppsButtonRank);
    159             int y = getCellYFromOrder(allAppsButtonRank);
    160             CellLayout.LayoutParams lp = new CellLayout.LayoutParams(x, y, 1, 1);
    161             lp.canReorder = false;
    162             mContent.addViewToCellLayout(allAppsButton, -1, allAppsButton.getId(), lp, true);
    163         }
    164     }
    165 
    166     @Override
    167     public boolean onInterceptTouchEvent(MotionEvent ev) {
    168         // We don't want any clicks to go through to the hotseat unless the workspace is in
    169         // the normal state or an accessible drag is in progress.
    170         return !mLauncher.getWorkspace().workspaceIconsCanBeDragged() &&
    171                 !mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
    172     }
    173 
    174     @Override
    175     public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
    176         target.gridX = info.cellX;
    177         target.gridY = info.cellY;
    178         targetParent.containerType = ContainerType.HOTSEAT;
    179     }
    180 
    181     public void updateColor(ExtractedColors extractedColors, boolean animate) {
    182         if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
    183             // not hotseat visible
    184             return;
    185         }
    186         if (!mHasVerticalHotseat) {
    187             int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
    188             if (mBackgroundColorAnimator != null) {
    189                 mBackgroundColorAnimator.cancel();
    190             }
    191             if (!animate) {
    192                 setBackgroundColor(color);
    193             } else {
    194                 mBackgroundColorAnimator = ValueAnimator.ofInt(mBackgroundColor, color);
    195                 mBackgroundColorAnimator.setEvaluator(new ArgbEvaluator());
    196                 mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    197                     @Override
    198                     public void onAnimationUpdate(ValueAnimator animation) {
    199                         mBackground.setColor((Integer) animation.getAnimatedValue());
    200                     }
    201                 });
    202                 mBackgroundColorAnimator.addListener(new AnimatorListenerAdapter() {
    203                     @Override
    204                     public void onAnimationEnd(Animator animation) {
    205                         mBackgroundColorAnimator = null;
    206                     }
    207                 });
    208                 mBackgroundColorAnimator.start();
    209             }
    210             mBackgroundColor = color;
    211         }
    212     }
    213 
    214     public void setBackgroundTransparent(boolean enable) {
    215         if (enable) {
    216             mBackground.setAlpha(0);
    217         } else {
    218             mBackground.setAlpha(255);
    219         }
    220     }
    221 
    222     public int getBackgroundDrawableColor() {
    223         return mBackgroundColor;
    224     }
    225 }
    226