summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/layout/user_folder_icon_normalized.xml6
-rw-r--r--res/values/dimens.xml4
-rw-r--r--src/com/android/launcher3/FastBitmapDrawable.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java2
-rw-r--r--src/com/android/launcher3/config/FeatureFlags.java3
-rw-r--r--src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java128
-rw-r--r--src/com/android/launcher3/folder/FolderIcon.java49
-rw-r--r--src/com/android/launcher3/folder/StackFolderIconLayoutRule.java21
8 files changed, 184 insertions, 31 deletions
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 75b5c4839..d445a7ae3 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.Folder xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.folder.Folder xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -34,7 +34,7 @@
android:layout_width="20dp"
android:layout_height="20dp" />
- <com.android.launcher3.FolderPagedView
+ <com.android.launcher3.folder.FolderPagedView
android:id="@+id/folder_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -82,4 +82,4 @@
</LinearLayout>
-</com.android.launcher3.Folder>
+</com.android.launcher3.folder.Folder>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 468beaa37..fee62dcb8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -138,8 +138,8 @@
<dimen name="quantum_panel_outer_padding">4dp</dimen>
<!-- Folders -->
- <!-- The amount that the preview contents are inset from the preview background -->
- <dimen name="folder_preview_padding">4dp</dimen>
+ <!-- The size of the padding on the preview background drawable -->
+ <dimen name="folder_preview_padding">6dp</dimen>
<!-- Sizes for managed profile badges -->
<dimen name="profile_badge_size">24dp</dimen>
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index d7f1d8677..38700805f 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -93,7 +93,7 @@ public class FastBitmapDrawable extends Drawable {
private static final ColorMatrix sTempBrightnessMatrix = new ColorMatrix();
private static final ColorMatrix sTempFilterMatrix = new ColorMatrix();
- private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
private final Bitmap mBitmap;
private State mState = State.NORMAL;
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 63c03e564..dcc4b2972 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -40,13 +40,13 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.ExtendedEditText;
+import com.android.launcher3.folder.Folder;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherTransitionable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
-import com.android.launcher3.folder.Folder;
import com.android.launcher3.util.ComponentKey;
import java.nio.charset.Charset;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index b0b602c8c..e8e15c207 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -31,7 +31,8 @@ public final class FeatureFlags {
public static boolean IS_RELEASE_BUILD = true;
// Custom flags go below this
- public static boolean LAUNCHER3_ICON_NORMALIZATION = false;
// As opposed to the new spring-loaded workspace.
public static boolean LAUNCHER3_LEGACY_WORKSPACE_DND = false;
+ public static boolean LAUNCHER3_ICON_NORMALIZATION = true;
+ public static boolean LAUNCHER3_CLIPPED_FOLDER_ICON = false;
}
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
new file mode 100644
index 000000000..44d7ac6e9
--- /dev/null
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -0,0 +1,128 @@
+package com.android.launcher3.folder;
+
+import android.graphics.Path;
+import android.graphics.Point;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.Utilities;
+
+public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
+
+ static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;
+ private static final int MIN_NUM_ITEMS_IN_PREVIEW = 2;
+
+ final float MIN_SCALE = 0.48f;
+ final float MAX_SCALE = 0.58f;
+ final float MAX_RADIUS_DILATION = 0.15f;
+
+ private float[] mTmpPoint = new float[2];
+
+ private float mAvailableSpace;
+ private float mRadius;
+ private float mIconSize;
+ private boolean mIsRtl;
+ private Path mClipPath = new Path();
+
+ @Override
+ public void init(int availableSpace, int intrinsicIconSize, boolean rtl) {
+ mAvailableSpace = availableSpace;
+ mRadius = 0.66f * availableSpace;
+ mIconSize = intrinsicIconSize;
+ mIsRtl = rtl;
+
+ // We make the clip radius just slightly smaller than the background drawable
+ // TODO(adamcohen): this is hacky, needs cleanup (likely through programmatic drawing).
+ int clipRadius = (int) mAvailableSpace / 2 - 1;
+
+ mClipPath.addCircle(mAvailableSpace / 2, mAvailableSpace / 2, clipRadius, Path.Direction.CW);
+ }
+
+ @Override
+ public FolderIcon.PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
+ int curNumItems, FolderIcon.PreviewItemDrawingParams params) {
+
+ getPosition(index, curNumItems, mTmpPoint);
+
+ float transX = mTmpPoint[0];
+ float transY = mTmpPoint[1];
+ float totalScale = scaleForNumItems(curNumItems);
+ float overlayAlpha = 0;
+
+ if (params == null) {
+ params = new FolderIcon.PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
+ } else {
+ params.transX = transX;
+ params.transY = transY;
+ params.scale = totalScale;
+ params.overlayAlpha = overlayAlpha;
+ }
+
+ return params;
+ }
+
+ private void getPosition(int index, int curNumItems, float[] result) {
+ // The case of two items is homomorphic to the case of one.
+ curNumItems = Math.max(curNumItems, 2);
+
+
+ // We model the preview as a circle of items starting in the appropriate piece of the
+ // upper left quadrant (to achieve horizontal and vertical symmetry).
+ double theta0 = mIsRtl ? 0 : Math.PI;
+
+ // In RTL we go counterclockwise
+ int direction = mIsRtl ? 1 : -1;
+
+ double thetaShift = 0;
+ if (curNumItems == 3) {
+ thetaShift = Math.PI / 6;
+ } else if (curNumItems == 4) {
+ thetaShift = Math.PI / 4;
+ }
+ theta0 += direction * thetaShift;
+
+ // We want the items to appear in reading order. For the case of 1, 2 and 3 items, this
+ // is natural for the circular model. With 4 items, however, we need to swap the 3rd and
+ // 4th indices to achieve reading order.
+ if (curNumItems == 4 && index == 3) {
+ index = 2;
+ } else if (curNumItems == 4 && index == 2) {
+ index = 3;
+ }
+
+ // We bump the radius up between 0 and MAX_RADIUS_DILATION % as the number of items increase
+ float radius = mRadius * (1 + MAX_RADIUS_DILATION * (curNumItems -
+ MIN_NUM_ITEMS_IN_PREVIEW) / (MAX_NUM_ITEMS_IN_PREVIEW - MIN_NUM_ITEMS_IN_PREVIEW));
+ double theta = theta0 + index * (2 * Math.PI / curNumItems) * direction;
+
+ float halfIconSize = (mIconSize * scaleForNumItems(curNumItems)) / 2;
+
+ // Map the location along the circle, and offset the coordinates to represent the center
+ // of the icon, and to be based from the top / left of the preview area. The y component
+ // is inverted to match the coordinate system.
+ result[0] = mAvailableSpace / 2 + (float) (radius * Math.cos(theta) / 2) - halfIconSize;
+ result[1] = mAvailableSpace / 2 + (float) (- radius * Math.sin(theta) / 2) - halfIconSize;
+
+ }
+
+ private float scaleForNumItems(int numItems) {
+ if (numItems <= 2) {
+ return MAX_SCALE;
+ } else if (numItems == 3) {
+ return (MAX_SCALE + MIN_SCALE) / 2;
+ } else {
+ return MIN_SCALE;
+ }
+ }
+
+ @Override
+ public int numItems() {
+ return MAX_NUM_ITEMS_IN_PREVIEW;
+ }
+
+ @Override
+ public Path getClipPath() {
+ return mClipPath;
+ }
+
+}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 8b95e76cf..5c084d949 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -65,6 +66,7 @@ import com.android.launcher3.SimpleOnStylusPressListener;
import com.android.launcher3.StylusEventHelper;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.util.Thunk;
@@ -81,8 +83,9 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private FolderInfo mInfo;
@Thunk static boolean sStaticValuesDirty = true;
- // TODO(adamcohen): remove this
- public static final int NUM_ITEMS_IN_PREVIEW = 3;
+ public static final int NUM_ITEMS_IN_PREVIEW = FeatureFlags.LAUNCHER3_CLIPPED_FOLDER_ICON ?
+ ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW :
+ StackFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
private CheckLongPressHelper mLongPressHelper;
private StylusEventHelper mStylusEventHelper;
@@ -152,7 +155,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private void init() {
mLongPressHelper = new CheckLongPressHelper(this);
mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
- mPreviewLayoutRule = new StackFolderIconLayoutRule();
+ mPreviewLayoutRule = FeatureFlags.LAUNCHER3_CLIPPED_FOLDER_ICON ?
+ new ClippedFolderIconLayoutRule() :
+ new StackFolderIconLayoutRule();
+
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
}
@@ -468,7 +474,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
int[] center = new int[2];
- float scale = getLocalCenterForIndex(index, center);
+ float scale = getLocalCenterForIndex(index, index + 1, center);
center[0] = (int) Math.round(scaleRelativeToDragLayer * center[0]);
center[1] = (int) Math.round(scaleRelativeToDragLayer * center[1]);
@@ -516,7 +522,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
mIntrinsicIconSize = drawableSize;
mTotalWidth = totalSize;
- final int previewSize = mPreviewBackground.getLayoutParams().height;
+ final int previewSize = FolderRingAnimator.sPreviewSize;
final int previewPadding = FolderRingAnimator.sPreviewPadding;
mAvailableSpaceInPreview = (previewSize - 2 * previewPadding);
@@ -524,8 +530,8 @@ public class FolderIcon extends FrameLayout implements FolderListener {
mPreviewOffsetX = (mTotalWidth - mAvailableSpaceInPreview) / 2;
mPreviewOffsetY = previewPadding + grid.folderBackgroundOffset + getPaddingTop();
- // Initialize the preview layout rule
- mPreviewLayoutRule.init(mAvailableSpaceInPreview, mIntrinsicIconSize);
+ mPreviewLayoutRule.init(mAvailableSpaceInPreview, mIntrinsicIconSize,
+ Utilities.isRtl(getResources()));
}
}
@@ -547,9 +553,9 @@ public class FolderIcon extends FrameLayout implements FolderListener {
Drawable drawable;
}
- private float getLocalCenterForIndex(int index, int[] center) {
+ private float getLocalCenterForIndex(int index, int curNumItems, int[] center) {
mParams = computePreviewItemDrawingParams(Math.min(mPreviewLayoutRule.numItems(), index),
- mParams);
+ curNumItems, mParams);
mParams.transX += mPreviewOffsetX;
mParams.transY += mPreviewOffsetY;
@@ -561,14 +567,14 @@ public class FolderIcon extends FrameLayout implements FolderListener {
return mParams.scale;
}
- private PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
+ private PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params) {
- return mPreviewLayoutRule.computePreviewItemDrawingParams(index, params);
+ return mPreviewLayoutRule.computePreviewItemDrawingParams(index, curNumItems, params);
}
private void drawPreviewItem(Canvas canvas, PreviewItemDrawingParams params) {
canvas.save();
- canvas.translate(params.transX + mPreviewOffsetX, params.transY + mPreviewOffsetY);
+ canvas.translate(params.transX, params.transY);
canvas.scale(params.scale, params.scale);
Drawable d = params.drawable;
@@ -612,13 +618,20 @@ public class FolderIcon extends FrameLayout implements FolderListener {
computePreviewDrawingParams(d);
}
+ canvas.save();
+ canvas.translate(mPreviewOffsetX, mPreviewOffsetY);
+ Path clipPath = mPreviewLayoutRule.getClipPath();
+ if (clipPath != null) {
+ canvas.clipPath(clipPath);
+ }
+
int nItemsInPreview = Math.min(items.size(), mPreviewLayoutRule.numItems());
if (!mAnimating) {
for (int i = nItemsInPreview - 1; i >= 0; i--) {
v = (TextView) items.get(i);
if (!mHiddenItems.contains(v.getTag())) {
d = getTopDrawable(v);
- mParams = computePreviewItemDrawingParams(i, mParams);
+ mParams = computePreviewItemDrawingParams(i, nItemsInPreview, mParams);
mParams.drawable = d;
drawPreviewItem(canvas, mParams);
}
@@ -626,6 +639,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
} else {
drawPreviewItem(canvas, mAnimParams);
}
+ canvas.restore();
}
private Drawable getTopDrawable(TextView v) {
@@ -635,7 +649,9 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private void animateFirstItem(final Drawable d, int duration, final boolean reverse,
final Runnable onCompleteRunnable) {
- final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null);
+
+ final PreviewItemDrawingParams finalParams =
+ computePreviewItemDrawingParams(0, reverse ? 1 : 2, null);
float iconSize = mLauncher.getDeviceProfile().iconSizePx;
final float scale0 = iconSize / d.getIntrinsicWidth() ;
@@ -749,11 +765,12 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
public interface PreviewLayoutRule {
- public PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
+ public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params);
- public void init(int availableSpace, int intrinsicIconSize);
+ public void init(int availableSpace, int intrinsicIconSize, boolean rtl);
public int numItems();
+ public Path getClipPath();
}
}
diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
index 1405b40c5..87f5f897b 100644
--- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
@@ -16,11 +16,13 @@
package com.android.launcher3.folder;
+import android.graphics.Path;
+
import com.android.launcher3.folder.FolderIcon.PreviewItemDrawingParams;
public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
- public static final int NUM_ITEMS_IN_PREVIEW = 3;
+ static final int MAX_NUM_ITEMS_IN_PREVIEW = 3;
// The degree to which the item in the back of the stack is scaled [0...1]
// (0 means it's not scaled at all, 1 means it's scaled to nothing)
@@ -29,13 +31,13 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
// The amount of vertical spread between items in the stack [0...1]
private static final float PERSPECTIVE_SHIFT_FACTOR = 0.18f;
- //private int mIntrinsicIconSize;
private float mBaselineIconScale;
private int mBaselineIconSize;
private int mAvailableSpaceInPreview;
private float mMaxPerspectiveShift;
- public void init(int availableSpace, int intrinsicIconSize) {
+ @Override
+ public void init(int availableSpace, int intrinsicIconSize, boolean rtl) {
mAvailableSpaceInPreview = availableSpace;
// cos(45) = 0.707 + ~= 0.1) = 0.8f
@@ -50,11 +52,11 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
}
@Override
- public PreviewItemDrawingParams computePreviewItemDrawingParams(int index,
+ public PreviewItemDrawingParams computePreviewItemDrawingParams(int index, int curNumItems,
PreviewItemDrawingParams params) {
- index = NUM_ITEMS_IN_PREVIEW - index - 1;
- float r = (index * 1.0f) / (NUM_ITEMS_IN_PREVIEW - 1);
+ index = MAX_NUM_ITEMS_IN_PREVIEW - index - 1;
+ float r = (index * 1.0f) / (MAX_NUM_ITEMS_IN_PREVIEW - 1);
float scale = (1 - PERSPECTIVE_SCALE_FACTOR * (1 - r));
float offset = (1 - r) * mMaxPerspectiveShift;
@@ -81,6 +83,11 @@ public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
@Override
public int numItems() {
- return NUM_ITEMS_IN_PREVIEW;
+ return MAX_NUM_ITEMS_IN_PREVIEW;
+ }
+
+ @Override
+ public Path getClipPath() {
+ return null;
}
}