Merge branch 'master' into honeycomb-release

This commit is contained in:
The Android Automerger
2010-10-01 07:24:11 -07:00
30 changed files with 686 additions and 182 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ LOCAL_CERTIFICATE := shared
LOCAL_OVERRIDES_PACKAGES := Home
LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
include $(BUILD_PACKAGE)
Executable
+220
View File
@@ -0,0 +1,220 @@
#!/usr/bin/env python2.5
import cgi
import os
import shutil
import sys
import sqlite3
SCREENS = 5
COLUMNS = 4
ROWS = 4
CELL_SIZE = 110
DIR = "db_files"
AUTO_FILE = DIR + "/launcher.db"
INDEX_FILE = DIR + "/index.html"
def usage():
print "usage: print_db.py launcher.db -- prints a launcher.db"
print "usage: print_db.py -- adb pulls a launcher.db from a device"
print " and prints it"
print
print "The dump will be created in a directory called db_files in cwd."
print "This script will delete any db_files directory you have now"
def make_dir():
shutil.rmtree(DIR, True)
os.makedirs(DIR)
def pull_file(fn):
print "pull_file: " + fn
rv = os.system("adb pull"
+ " /data/data/com.android.launcher/databases/launcher.db"
+ " " + fn);
if rv != 0:
print "adb pull failed"
sys.exit(1)
def get_favorites(conn):
c = conn.cursor()
c.execute("SELECT * FROM favorites")
columns = [d[0] for d in c.description]
rows = []
for row in c:
rows.append(row)
return columns,rows
def print_intent(out, id, i, cell):
if cell:
out.write("""<span class="intent" title="%s">shortcut</span>""" % (
cgi.escape(cell, True)
))
def print_icon(out, id, i, cell):
if cell:
icon_fn = "icon_%d.png" % id
out.write("""<img src="%s">""" % ( icon_fn ))
f = file(DIR + "/" + icon_fn, "w")
f.write(cell)
f.close()
def print_cell(out, id, i, cell):
if not cell is None:
out.write(cgi.escape(str(cell)))
FUNCTIONS = {
"intent": print_intent,
"icon": print_icon
}
def process_file(fn):
print "process_file: " + fn
conn = sqlite3.connect(fn)
columns,rows = get_favorites(conn)
data = [dict(zip(columns,row)) for row in rows]
out = file(INDEX_FILE, "w")
out.write("""<html>
<head>
<style type="text/css">
.intent {
font-style: italic;
}
</style>
</head>
<body>
""")
# Data table
out.write("<b>Favorites table</b><br/>\n")
out.write("""<html>
<table border=1 cellspacing=0 cellpadding=4>
<tr>
""")
print_functions = []
for col in columns:
print_functions.append(FUNCTIONS.get(col, print_cell))
for i in range(0,len(columns)):
col = columns[i]
out.write(""" <th>%s</th>
""" % ( col ))
out.write("""
</tr>
""")
for row in rows:
out.write("""<tr>
""")
for i in range(0,len(row)):
cell = row[i]
# row[0] is always _id
out.write(""" <td>""")
print_functions[i](out, row[0], row, cell)
out.write("""</td>
""")
out.write("""</tr>
""")
out.write("""</table>
""")
# Pages
screens = []
for i in range(0,SCREENS):
screen = []
for j in range(0,ROWS):
m = []
for k in range(0,COLUMNS):
m.append(None)
screen.append(m)
screens.append(screen)
occupied = "occupied"
for row in data:
screen = screens[row["screen"]]
# desktop
if row["container"] != -100:
continue
cellX = row["cellX"]
cellY = row["cellY"]
spanX = row["spanX"]
spanY = row["spanY"]
for j in range(cellY, cellY+spanY):
for k in range(cellX, cellX+spanX):
screen[j][k] = occupied
screen[cellY][cellX] = row
i=0
for screen in screens:
out.write("<br/><b>Screen %d</b><br/>\n" % i)
out.write("<table class=layout border=1 cellspacing=0 cellpadding=4>\n")
for m in screen:
out.write(" <tr>\n")
for cell in m:
if cell is None:
out.write(" <td width=%d height=%d></td>\n" %
(CELL_SIZE, CELL_SIZE))
elif cell == occupied:
pass
else:
cellX = cell["cellX"]
cellY = cell["cellY"]
spanX = cell["spanX"]
spanY = cell["spanY"]
intent = cell["intent"]
if intent:
title = "title=\"%s\"" % cgi.escape(cell["intent"], True)
else:
title = ""
out.write((" <td colspan=%d rowspan=%d width=%d height=%d"
+ " bgcolor=#dddddd align=center valign=middle %s>") % (
spanX, spanY,
(CELL_SIZE*spanX), (CELL_SIZE*spanY),
title))
itemType = cell["itemType"]
if itemType == 0:
out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
out.write("<br/>\n")
out.write(cgi.escape(cell["title"]) + " <br/><i>(app)</i>")
elif itemType == 1:
out.write("""<img src="icon_%d.png">\n""" % ( cell["_id"] ))
out.write("<br/>\n")
out.write(cgi.escape(cell["title"]) + " <br/><i>(shortcut)</i>")
elif itemType == 2:
out.write("""<i>folder</i>""")
elif itemType == 3:
out.write("""<i>live folder</i>""")
elif itemType == 4:
out.write("<i>widget %d</i><br/>\n" % cell["appWidgetId"])
elif itemType == 1000:
out.write("""<i>clock</i>""")
elif itemType == 1001:
out.write("""<i>search</i>""")
elif itemType == 1002:
out.write("""<i>photo frame</i>""")
else:
out.write("<b>unknown type: %d</b>" % itemType)
out.write("</td>\n")
out.write("</tr>\n")
out.write("</table>\n")
i=i+1
out.write("""
</body>
</html>
""")
out.close()
def main(argv):
if len(argv) == 1:
make_dir()
pull_file(AUTO_FILE)
process_file(AUTO_FILE)
elif len(argv) == 2:
make_dir()
process_file(argv[1])
else:
usage()
if __name__=="__main__":
main(sys.argv)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

+7
View File
@@ -38,4 +38,11 @@
the drag view should be offset from the position of the original view. -->
<integer name="config_dragViewOffsetX">0</integer>
<integer name="config_dragViewOffsetY">12</integer>
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->
<integer name="config_dragOutlineFadeTime">900</integer>
<!-- The alpha value at which to show the most recent drop visualization outline. -->
<integer name="config_dragOutlineMaxAlpha">180</integer>
</resources>
+4
View File
@@ -37,4 +37,8 @@
<!-- delete_zone_size_full - button_bar_height_portrait -->
<dimen name="delete_zone_padding">14dip</dimen>
<!-- the area at the edge of the screen that makes the workspace go left
or right while you're dragging. -->
<dimen name="scroll_zone">20dp</dimen>
</resources>
+119 -42
View File
@@ -31,18 +31,19 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LayoutAnimationController;
import java.util.Arrays;
public class CellLayout extends ViewGroup {
public class CellLayout extends ViewGroup implements Dimmable {
static final String TAG = "CellLayout";
private int mCellWidth;
@@ -75,17 +76,27 @@ public class CellLayout extends ViewGroup {
private float mBackgroundAlpha;
private final Rect mBackgroundLayoutRect = new Rect();
private Drawable mBackground;
private Drawable mBackgroundHover;
// If we're actively dragging something over this screen and it's small,
// mHover is true
private Drawable mBackgroundMini;
private Drawable mBackgroundMiniHover;
// If we're actively dragging something over this screen and it's small, mHover is true
private boolean mHover = false;
private final RectF mDragRect = new RectF();
private final Point mDragCenter = new Point();
private Drawable mDragRectDrawable;
// These arrays are used to implement the drag visualization on x-large screens.
// They are used as circular arrays, indexed by mDragRectCurrent.
private Rect[] mDragRects = new Rect[8];
private int[] mDragRectAlphas = new int[mDragRects.length];
private InterruptibleInOutAnimator[] mDragRectAnims =
new InterruptibleInOutAnimator[mDragRects.length];
// Used as an index into the above 3 arrays; indicates which is the most current value.
private int mDragRectCurrent = 0;
private Drawable mCrosshairsDrawable = null;
private ValueAnimator mCrosshairsAnimator = null;
private float mCrosshairsVisibility = 0.0f;
@@ -137,13 +148,18 @@ public class CellLayout extends ViewGroup {
if (LauncherApplication.isScreenXLarge()) {
final Resources res = getResources();
mBackground = res.getDrawable(R.drawable.mini_home_screen_bg);
mBackgroundMini = res.getDrawable(R.drawable.mini_home_screen_bg);
mBackgroundMini.setFilterBitmap(true);
mBackground = res.getDrawable(R.drawable.home_screen_bg);
mBackground.setFilterBitmap(true);
mBackgroundHover = res.getDrawable(R.drawable.mini_home_screen_bg_hover);
mBackgroundHover.setFilterBitmap(true);
mBackgroundMiniHover = res.getDrawable(R.drawable.mini_home_screen_bg_hover);
mBackgroundMiniHover.setFilterBitmap(true);
// Initialize the data structures used for the drag visualization.
mDragRectDrawable = res.getDrawable(R.drawable.rounded_rect_green);
mCrosshairsDrawable = res.getDrawable(R.drawable.gardening_crosshairs);
Interpolator interp = new DecelerateInterpolator(2.5f); // Quint ease out
// Set up the animation for fading the crosshairs in and out
int animDuration = res.getInteger(R.integer.config_crosshairsFadeInTime);
@@ -154,6 +170,32 @@ public class CellLayout extends ViewGroup {
CellLayout.this.invalidate();
}
});
mCrosshairsAnimator.setInterpolator(interp);
for (int i = 0; i < mDragRects.length; i++) {
mDragRects[i] = new Rect();
}
// When dragging things around the home screens, we show a green outline of
// where the item will land. The outlines gradually fade out, leaving a trail
// behind the drag path.
// Set up all the animations that are used to implement this fading.
final int duration = res.getInteger(R.integer.config_dragOutlineFadeTime);
final int fromAlphaValue = 0;
final int toAlphaValue = res.getInteger(R.integer.config_dragOutlineMaxAlpha);
for (int i = 0; i < mDragRectAnims.length; i++) {
final InterruptibleInOutAnimator anim =
new InterruptibleInOutAnimator(duration, fromAlphaValue, toAlphaValue);
anim.setInterpolator(interp);
final int thisIndex = i;
anim.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
mDragRectAlphas[thisIndex] = (Integer) animation.getAnimatedValue();
CellLayout.this.invalidate(mDragRects[thisIndex]);
}
});
mDragRectAnims[i] = anim;
}
}
}
@@ -176,7 +218,14 @@ public class CellLayout extends ViewGroup {
@Override
public void dispatchDraw(Canvas canvas) {
if (mBackgroundAlpha > 0.0f) {
final Drawable bg = mHover ? mBackgroundHover : mBackground;
Drawable bg;
if (mHover && getScaleX() < 0.5f) {
bg = mBackgroundMiniHover;
} else if (getScaleX() < 0.5f) {
bg = mBackgroundMini;
} else {
bg = mBackground;
}
bg.setAlpha((int) (mBackgroundAlpha * 255));
bg.draw(canvas);
}
@@ -189,16 +238,6 @@ public class CellLayout extends ViewGroup {
final int countX = mCountX;
final int countY = mCountY;
if (!mDragRect.isEmpty()) {
mDragRectDrawable.setBounds(
(int)mDragRect.left,
(int)mDragRect.top,
(int)mDragRect.right,
(int)mDragRect.bottom);
mDragRectDrawable.setAlpha((int) (mCrosshairsVisibility * 255));
mDragRectDrawable.draw(canvas);
}
final float MAX_ALPHA = 0.4f;
final int MAX_VISIBLE_DISTANCE = 600;
final float DISTANCE_MULTIPLIER = 0.002f;
@@ -225,9 +264,32 @@ public class CellLayout extends ViewGroup {
}
x += mCellWidth + mWidthGap;
}
for (int i = 0; i < mDragRects.length; i++) {
int alpha = mDragRectAlphas[i];
if (alpha > 0) {
mDragRectDrawable.setAlpha(alpha);
mDragRectDrawable.setBounds(mDragRects[i]);
mDragRectDrawable.draw(canvas);
}
}
}
}
public void setDimmableProgress(float progress) {
for (int i = 0; i < getChildCount(); i++) {
Dimmable d = (Dimmable) getChildAt(i);
d.setDimmableProgress(progress);
}
}
public float getDimmableProgress() {
if (getChildCount() > 0) {
return ((Dimmable) getChildAt(0)).getDimmableProgress();
}
return 0.0f;
}
@Override
public void cancelLongPress() {
super.cancelLongPress();
@@ -581,8 +643,11 @@ public class CellLayout extends ViewGroup {
if (mBackground != null) {
mBackground.setBounds(mBackgroundLayoutRect);
}
if (mBackgroundHover != null) {
mBackgroundHover.setBounds(mBackgroundLayoutRect);
if (mBackgroundMiniHover != null) {
mBackgroundMiniHover.setBounds(mBackgroundLayoutRect);
}
if (mBackgroundMini != null) {
mBackgroundMini.setBounds(mBackgroundLayoutRect);
}
}
@@ -723,13 +788,23 @@ public class CellLayout extends ViewGroup {
final int left = topLeft[0];
final int top = topLeft[1];
// Now find the bottom right
final int[] bottomRight = mTmpPoint;
cellToPoint(nearest[0] + spanX - 1, nearest[1] + spanY - 1, bottomRight);
bottomRight[0] += mCellWidth;
bottomRight[1] += mCellHeight;
mDragRect.set(left, top, bottomRight[0], bottomRight[1]);
invalidate();
final Rect dragRect = mDragRects[mDragRectCurrent];
if (dragRect.isEmpty() || left != dragRect.left || top != dragRect.top) {
// Now find the bottom right
final int[] bottomRight = mTmpPoint;
cellToPoint(nearest[0] + spanX - 1, nearest[1] + spanY - 1, bottomRight);
bottomRight[0] += mCellWidth;
bottomRight[1] += mCellHeight;
final int oldIndex = mDragRectCurrent;
mDragRectCurrent = (oldIndex + 1) % mDragRects.length;
mDragRects[mDragRectCurrent].set(left, top, bottomRight[0], bottomRight[1]);
mDragRectAnims[oldIndex].animateOut();
mDragRectAnims[mDragRectCurrent].animateIn();
}
}
}
@@ -766,9 +841,9 @@ public class CellLayout extends ViewGroup {
*/
int[] findNearestVacantArea(
int pixelX, int pixelY, int spanX, int spanY, View ignoreView, int[] result) {
if (ignoreView != null) {
markCellsAsUnoccupiedForView(ignoreView);
}
// mark space take by ignoreView as available (method checks if ignoreView is null)
markCellsAsUnoccupiedForView(ignoreView);
// Keep track of best-scoring drop area
final int[] bestXY = result != null ? result : new int[2];
double bestDistance = Double.MAX_VALUE;
@@ -802,9 +877,8 @@ public class CellLayout extends ViewGroup {
}
}
}
if (ignoreView != null) {
markCellsAsOccupiedForView(ignoreView);
}
// re-mark space taken by ignoreView as occupied
markCellsAsOccupiedForView(ignoreView);
// Return null if no suitable location found
if (bestDistance < Double.MAX_VALUE) {
@@ -872,9 +946,8 @@ public class CellLayout extends ViewGroup {
*/
boolean findCellForSpanThatIntersectsIgnoring(int[] cellXY, int spanX, int spanY,
int intersectX, int intersectY, View ignoreView) {
if (ignoreView != null) {
markCellsAsUnoccupiedForView(ignoreView);
}
// mark space take by ignoreView as available (method checks if ignoreView is null)
markCellsAsUnoccupiedForView(ignoreView);
boolean foundCell = false;
while (true) {
@@ -927,9 +1000,8 @@ public class CellLayout extends ViewGroup {
}
}
if (ignoreView != null) {
markCellsAsOccupiedForView(ignoreView);
}
// re-mark space taken by ignoreView as occupied
markCellsAsOccupiedForView(ignoreView);
return foundCell;
}
@@ -948,6 +1020,10 @@ public class CellLayout extends ViewGroup {
if (mCrosshairsAnimator != null) {
animateCrosshairsTo(0.0f);
}
mDragRectAnims[mDragRectCurrent].animateOut();
mDragRectCurrent = (mDragRectCurrent + 1) % mDragRects.length;
mDragRects[mDragRectCurrent].setEmpty();
}
/**
@@ -990,7 +1066,6 @@ public class CellLayout extends ViewGroup {
* or it may have begun on another layout.
*/
void onDragEnter(View dragView) {
mDragRect.setEmpty();
// Fade in the drag indicators
if (mCrosshairsAnimator != null) {
animateCrosshairsTo(1.0f);
@@ -1123,11 +1198,13 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
}
private void markCellsAsOccupiedForView(View view) {
if (view == null || view.getParent() != this) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true);
}
private void markCellsAsUnoccupiedForView(View view) {
if (view == null || view.getParent() != this) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false);
}
+6
View File
@@ -0,0 +1,6 @@
package com.android.launcher2;
public interface Dimmable {
public void setDimmableProgress(float progress);
public float getDimmableProgress();
}
@@ -21,52 +21,21 @@ import com.android.launcher.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.view.View;
public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView {
public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView implements Dimmable {
public DimmableAppWidgetHostView(Context context) {
super(context);
mPaint.setFilterBitmap(true);
}
private final Paint mPaint = new Paint();
private int mAlpha;
private int mDimmedAlpha;
private Bitmap mDimmedView;
private Canvas mDimmedViewCanvas;
private boolean isDimmedViewUpdatePass;
private static float cubic(float r) {
return (float) (Math.pow(r-1, 3) + 1);
}
/**
* Returns the interpolated holographic highlight alpha for the effect we want when scrolling
* pages.
*/
public static float highlightAlphaInterpolator(float r) {
final float pivot = 0.3f;
if (r < pivot) {
return Math.max(0.5f, 0.65f*cubic(r/pivot));
} else {
return Math.min(1.0f, 0.65f*cubic(1 - (r-pivot)/(1-pivot)));
}
}
/**
* Returns the interpolated view alpha for the effect we want when scrolling pages.
*/
public static float viewAlphaInterpolator(float r) {
final float pivot = 0.6f;
if (r < pivot) {
return r/pivot;
} else {
return 1.0f;
}
}
private float mDimmableProgress;
private void setChildAlpha(float alpha) {
if (getChildCount() > 0) {
@@ -83,20 +52,18 @@ public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView {
setChildAlpha(getAlpha());
}
@Override
//@Override
public boolean onSetAlpha(int alpha) {
super.onSetAlpha(alpha);
return true;
}
@Override
public void setAlpha(float alpha) {
final float viewAlpha = viewAlphaInterpolator(alpha);
final float dimmedAlpha = highlightAlphaInterpolator(alpha);
mAlpha = (int) (viewAlpha * 255);
mDimmedAlpha = (int) (dimmedAlpha * 255);
super.setAlpha(viewAlpha);
setChildAlpha(viewAlpha);
public void setDimmableProgress(float progress) {
mDimmableProgress = progress;
}
public float getDimmableProgress() {
return mDimmableProgress;
}
private void updateDimmedView() {
@@ -113,13 +80,14 @@ public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView {
int dimmedColor = getContext().getResources().getColor(R.color.dimmed_view_color);
mDimmedViewCanvas.drawColor(dimmedColor, PorterDuff.Mode.SRC_IN);
isDimmedViewUpdatePass = false;
invalidate();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mDimmedView == null && mDimmedAlpha > 0.0f) {
if (mDimmedView == null && mDimmableProgress > 0.0f) {
updateDimmedView();
}
}
@@ -134,9 +102,9 @@ public class DimmableAppWidgetHostView extends LauncherAppWidgetHostView {
canvas.restore();
setAlpha(alpha);
} else {
if (mDimmedView != null && mDimmedAlpha > 0) {
if (mDimmedView != null && mDimmableProgress > 0) {
// draw the dimmed version of this widget
mPaint.setAlpha(mDimmedAlpha);
mPaint.setAlpha((int) (mDimmableProgress * 255));
canvas.drawBitmap(mDimmedView, 0, 0, mPaint);
}
@@ -21,18 +21,17 @@ import com.android.launcher.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
public class DimmableBubbleTextView extends BubbleTextView {
public class DimmableBubbleTextView extends BubbleTextView implements Dimmable {
private Paint mDimmedPaint = new Paint();
private int mAlpha;
private int mDimmedAlpha;
private Bitmap mDimmedView;
private Canvas mDimmedViewCanvas;
private boolean isDimmedViewUpdatePass;
private float mDimmableProgress;
public DimmableBubbleTextView(Context context) {
super(context);
@@ -49,48 +48,12 @@ public class DimmableBubbleTextView extends BubbleTextView {
mDimmedPaint.setFilterBitmap(true);
}
private static float cubic(float r) {
return (float) (Math.pow(r-1, 3) + 1);
public void setDimmableProgress(float progress) {
mDimmableProgress = progress;
}
/**
* Returns the interpolated holographic highlight alpha for the effect we want when scrolling
* pages.
*/
public static float highlightAlphaInterpolator(float r) {
final float pivot = 0.3f;
if (r < pivot) {
return Math.max(0.5f, 0.65f*cubic(r/pivot));
} else {
return Math.min(1.0f, 0.65f*cubic(1 - (r-pivot)/(1-pivot)));
}
}
/**
* Returns the interpolated view alpha for the effect we want when scrolling pages.
*/
public static float viewAlphaInterpolator(float r) {
final float pivot = 0.6f;
if (r < pivot) {
return r/pivot;
} else {
return 1.0f;
}
}
@Override
public boolean onSetAlpha(int alpha) {
super.onSetAlpha(alpha);
return true;
}
@Override
public void setAlpha(float alpha) {
final float viewAlpha = viewAlphaInterpolator(alpha);
final float dimmedAlpha = highlightAlphaInterpolator(alpha);
mAlpha = (int) (viewAlpha * 255);
mDimmedAlpha = (int) (dimmedAlpha * 255);
super.setAlpha(viewAlpha);
public float getDimmableProgress() {
return mDimmableProgress;
}
@Override
@@ -124,13 +87,11 @@ public class DimmableBubbleTextView extends BubbleTextView {
super.setAlpha(alpha);
canvas.restore();
} else {
if (mAlpha > 0) {
super.onDraw(canvas);
}
super.onDraw(canvas);
}
if (mDimmedView != null && mDimmedAlpha > 0) {
mDimmedPaint.setAlpha(mDimmedAlpha);
if (mDimmedView != null && mDimmableProgress > 0) {
mDimmedPaint.setAlpha((int) (mDimmableProgress * 255));
canvas.drawBitmap(mDimmedView, mScrollX, mScrollY, mDimmedPaint);
}
}
+11 -4
View File
@@ -33,6 +33,8 @@ import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import com.android.launcher.R;
/**
* Class for initiating a drag within a view or across multiple views.
*/
@@ -47,7 +49,6 @@ public class DragController {
public static int DRAG_ACTION_COPY = 1;
private static final int SCROLL_DELAY = 600;
private static final int SCROLL_ZONE = 20;
private static final int VIBRATE_DURATION = 35;
private static final boolean PROFILE_DRAWING_DURING_DRAG = false;
@@ -87,6 +88,11 @@ public class DragController {
/** Y offset from the upper-left corner of the cell to where we touched. */
private float mTouchOffsetY;
/** the area at the edge of the screen that makes the workspace go left
* or right while you're dragging.
*/
private int mScrollZone;
/** Where the drag originated */
private DragSource mDragSource;
@@ -147,6 +153,7 @@ public class DragController {
public DragController(Context context) {
mContext = context;
mHandler = new Handler();
mScrollZone = context.getResources().getDimensionPixelSize(R.dimen.scroll_zone);
}
/**
@@ -475,13 +482,13 @@ public class DragController {
if (mDeleteRegion != null) {
inDeleteRegion = mDeleteRegion.contains(x, y);
}
if (!inDeleteRegion && x < SCROLL_ZONE) {
if (!inDeleteRegion && x < mScrollZone) {
if (mScrollState == SCROLL_OUTSIDE_ZONE) {
mScrollState = SCROLL_WAITING_IN_ZONE;
mScrollRunnable.setDirection(SCROLL_LEFT);
mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
}
} else if (!inDeleteRegion && x > mScrollView.getWidth() - SCROLL_ZONE) {
} else if (!inDeleteRegion && x > mScrollView.getWidth() - mScrollZone) {
if (mScrollState == SCROLL_OUTSIDE_ZONE) {
mScrollState = SCROLL_WAITING_IN_ZONE;
mScrollRunnable.setDirection(SCROLL_RIGHT);
@@ -514,7 +521,7 @@ public class DragController {
mMotionDownX = screenX;
mMotionDownY = screenY;
if ((screenX < SCROLL_ZONE) || (screenX > mScrollView.getWidth() - SCROLL_ZONE)) {
if ((screenX < mScrollZone) || (screenX > mScrollView.getWidth() - mScrollZone)) {
mScrollState = SCROLL_WAITING_IN_ZONE;
mHandler.postDelayed(mScrollRunnable, SCROLL_DELAY);
} else {
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher2;
import android.animation.ValueAnimator;
import android.util.Log;
/**
* A convenience class for two-way animations, e.g. a fadeIn/fadeOut animation.
* With a regular ValueAnimator, if you call reverse to show the 'out' animation, you'll get
* a frame-by-frame mirror of the 'in' animation -- i.e., the interpolated values will
* be exactly reversed. Using this class, both the 'in' and the 'out' animation use the
* interpolator in the same direction.
*/
public class InterruptibleInOutAnimator extends ValueAnimator {
private long mOriginalDuration;
private Object mOriginalFromValue;
private Object mOriginalToValue;
public InterruptibleInOutAnimator(long duration, Object fromValue, Object toValue) {
super(duration, fromValue, toValue);
mOriginalDuration = duration;
mOriginalFromValue = fromValue;
mOriginalToValue = toValue;
}
private void animate(Object fromValue, Object toValue) {
// This only makes sense when it's running in the opposite direction, or stopped.
setDuration(mOriginalDuration - getCurrentPlayTime());
final Object startValue = isRunning() ? getAnimatedValue() : fromValue;
cancel();
setValues(startValue, toValue);
start();
}
/**
* This is the equivalent of calling Animator.start(), except that it can be called when
* the animation is running in the opposite direction, in which case we reverse
* direction and animate for a correspondingly shorter duration.
*/
public void animateIn() {
animate(mOriginalFromValue, mOriginalToValue);
}
/**
* This is the roughly the equivalent of calling Animator.reverse(), except that it uses the
* same interpolation curve as animateIn(), rather than mirroring it. Also, like animateIn(),
* if the animation is currently running in the opposite direction, we reverse
* direction and animate for a correspondingly shorter duration.
*/
public void animateOut() {
animate(mOriginalToValue, mOriginalFromValue);
}
}
+7 -4
View File
@@ -300,8 +300,10 @@ public class LauncherModel extends BroadcastReceiver {
/**
* Creates a new unique child id, for a given cell span across all layouts.
*/
static int getCellLayoutChildId(int cellId, int screen, int localCellX, int localCellY, int spanX, int spanY) {
return ((cellId & 0xFF) << 16) | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
static int getCellLayoutChildId(
int cellId, int screen, int localCellX, int localCellY, int spanX, int spanY) {
return ((cellId & 0xFF) << 24)
| (screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
}
static int getCellCountX() {
@@ -412,8 +414,9 @@ public class LauncherModel extends BroadcastReceiver {
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_ADD, packages));
// When everything comes back, just reload everything. We might not
// have the right icons for apps on external storage.
startLoader(mApp, false);
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+19 -2
View File
@@ -73,11 +73,13 @@ public abstract class PagedView extends ViewGroup {
private float mDownMotionX;
private float mLastMotionX;
private float mLastMotionY;
private int mLastScreenCenter = -1;
protected final static int TOUCH_STATE_REST = 0;
protected final static int TOUCH_STATE_SCROLLING = 1;
protected final static int TOUCH_STATE_PREV_PAGE = 2;
protected final static int TOUCH_STATE_NEXT_PAGE = 3;
protected final static float ALPHA_QUANTIZE_LEVEL = 0.01f;
protected int mTouchState = TOUCH_STATE_REST;
@@ -367,7 +369,6 @@ public abstract class PagedView extends ViewGroup {
if (mDirtyPageAlpha || (mTouchState == TOUCH_STATE_SCROLLING) || !mScroller.isFinished()) {
int halfScreenSize = getMeasuredWidth() / 2;
int screenCenter = mScrollX + halfScreenSize;
final int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
View layout = (View) getChildAt(i);
@@ -391,6 +392,12 @@ public abstract class PagedView extends ViewGroup {
dimAlpha = Math.max(0.0f, Math.min(1.0f, (dimAlpha * dimAlpha)));
float alpha = 1.0f - dimAlpha;
if (alpha < ALPHA_QUANTIZE_LEVEL) {
alpha = 0.0f;
} else if (alpha > 1.0f - ALPHA_QUANTIZE_LEVEL) {
alpha = 1.0f;
}
if (Float.compare(alpha, layout.getAlpha()) != 0) {
layout.setAlpha(alpha);
}
@@ -400,9 +407,19 @@ public abstract class PagedView extends ViewGroup {
}
}
protected void screenScrolled(int screenCenter) {
}
@Override
protected void dispatchDraw(Canvas canvas) {
updateAdjacentPagesAlpha();
int halfScreenSize = getMeasuredWidth() / 2;
int screenCenter = mScrollX + halfScreenSize;
if (screenCenter != mLastScreenCenter) {
screenScrolled(screenCenter);
updateAdjacentPagesAlpha();
mLastScreenCenter = screenCenter;
}
// Find out which screens are visible; as an optimization we only call draw on them
// As an optimization, this code assumes that all pages have the same width as the 0th
+3 -3
View File
@@ -110,9 +110,9 @@ public class PagedViewIcon extends TextView implements Checkable {
mIconCacheKey = info;
mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
Drawable image = info.loadIcon(packageManager);
image.setBounds(0, 0, image.getIntrinsicWidth(), image.getIntrinsicHeight());
setCompoundDrawablesWithIntrinsicBounds(null, image, null, null);
Bitmap image = Utilities.createIconBitmap(info.loadIcon(packageManager), mContext);
setCompoundDrawablesWithIntrinsicBounds(null,
new FastBitmapDrawable(image), null, null);
setText(info.loadLabel(packageManager));
setTag(info);
}
+46 -12
View File
@@ -26,11 +26,15 @@ public abstract class SmoothPagedView extends PagedView {
private static final float SMOOTHING_SPEED = 0.75f;
private static final float SMOOTHING_CONSTANT = (float) (0.016 / Math.log(SMOOTHING_SPEED));
private float mBaseLineFlingVelocity;
private float mFlingVelocityInfluence;
private static final float BASELINE_FLING_VELOCITY = 2500.f;
private static final float FLING_VELOCITY_INFLUENCE = 0.4f;
static final int OVERSHOOT_MODE = 0;
static final int QUINTIC_MODE = 1;
private WorkspaceOvershootInterpolator mScrollInterpolator;
int mScrollMode;
private Interpolator mScrollInterpolator;
private static class WorkspaceOvershootInterpolator implements Interpolator {
private static final float DEFAULT_TENSION = 1.3f;
@@ -56,6 +60,16 @@ public abstract class SmoothPagedView extends PagedView {
}
}
private static class QuinticInterpolator implements Interpolator {
public QuinticInterpolator() {
}
public float getInterpolation(float t) {
t -= 1.0f;
return t*t*t*t*t + 1;
}
}
/**
* Used to inflate the Workspace from XML.
*
@@ -83,14 +97,27 @@ public abstract class SmoothPagedView extends PagedView {
mDeferScrollUpdate = true;
}
protected int getScrollMode() {
return OVERSHOOT_MODE;
}
/**
* Initializes various states for this workspace.
*/
@Override
protected void init() {
super.init();
mScrollInterpolator = new WorkspaceOvershootInterpolator();
// overwrite the previous mScroller
mScrollMode = getScrollMode();
if (mScrollMode == QUINTIC_MODE) {
mBaseLineFlingVelocity = 700.0f;
mFlingVelocityInfluence = 0.8f;
mScrollInterpolator = new QuinticInterpolator();
} else { // QUINTIC_MODE
mBaseLineFlingVelocity = 2500.0f;
mFlingVelocityInfluence = 0.4f;
mScrollInterpolator = new WorkspaceOvershootInterpolator();
}
mScroller = new Scroller(getContext(), mScrollInterpolator);
}
@@ -112,25 +139,32 @@ public abstract class SmoothPagedView extends PagedView {
final int screenDelta = Math.max(1, Math.abs(whichPage - mCurrentPage));
final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
final int delta = newX - mScrollX;
int duration = (screenDelta + 1) * 100;
int duration;
if (mScrollMode == OVERSHOOT_MODE) {
duration = (screenDelta + 1) * 100;
} else { // QUINTIC_MODE
duration = Math.round(Math.abs(delta) * 0.6f);
}
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
if (settle) {
mScrollInterpolator.setDistance(screenDelta);
} else {
mScrollInterpolator.disableSettle();
if (mScrollMode == OVERSHOOT_MODE) {
if (settle) {
((WorkspaceOvershootInterpolator) mScrollInterpolator).setDistance(screenDelta);
} else {
((WorkspaceOvershootInterpolator) mScrollInterpolator).disableSettle();
}
}
velocity = Math.abs(velocity);
if (velocity > 0) {
duration += (duration / (velocity / BASELINE_FLING_VELOCITY))
* FLING_VELOCITY_INFLUENCE;
duration += (duration / (velocity / mBaseLineFlingVelocity)) * mFlingVelocityInfluence;
} else {
duration += 100;
}
snapToPage(whichPage, delta, duration);
}
+152 -21
View File
@@ -33,7 +33,9 @@ import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -63,8 +65,8 @@ public class Workspace extends SmoothPagedView
// customization mode
private static final float SHRINK_FACTOR = 0.16f;
// The maximum Y rotation to apply to the mini home screens
private static final float MINI_PAGE_MAX_ROTATION = 25.0f;
// Y rotation to apply to the workspace screens
private static final float WORKSPACE_ROTATION = 12.5f;
// These are extra scale factors to apply to the mini home screens
// so as to achieve the desired transform
@@ -72,6 +74,18 @@ public class Workspace extends SmoothPagedView
private static final float EXTRA_SCALE_FACTOR_1 = 1.0f;
private static final float EXTRA_SCALE_FACTOR_2 = 1.08f;
private static final int BACKGROUND_FADE_OUT_DELAY = 300;
private static final int BACKGROUND_FADE_OUT_DURATION = 300;
private static final int BACKGROUND_FADE_IN_DURATION = 100;
static final int SCROLL_RIGHT = 0;
static final int SCROLL_LEFT = 1;
// These animators are used to fade the
private ObjectAnimator<Float> mBackgroundFadeIn;
private ObjectAnimator<Float> mBackgroundFadeOut;
private float mBackgroundAlpha = 0;
private enum ShrinkPosition { SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM };
private final WallpaperManager mWallpaperManager;
@@ -179,6 +193,15 @@ public class Workspace extends SmoothPagedView
mSnapVelocity = 600;
}
@Override
protected int getScrollMode() {
if (LauncherApplication.isScreenXLarge()) {
return SmoothPagedView.QUINTIC_MODE;
} else {
return SmoothPagedView.OVERSHOOT_MODE;
}
}
@Override
public void addView(View child, int index, LayoutParams params) {
if (!(child instanceof CellLayout)) {
@@ -322,7 +345,7 @@ public class Workspace extends SmoothPagedView
}
// Get the canonical child id to uniquely represent this view in this screen
int childId = LauncherModel.getCellLayoutChildId(child.getId(), screen, x, y, spanX, spanY);
int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY);
if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp)) {
// TODO: This branch occurs when the workspace is adding views
// outside of the defined grid
@@ -382,12 +405,14 @@ public class Workspace extends SmoothPagedView
enableChildrenCache(mCurrentPage - 1, mCurrentPage + 1);
}
}
showOutlines();
}
protected void pageEndMoving() {
if (!LauncherApplication.isScreenXLarge()) {
clearChildrenCache();
}
hideOutlines();
}
@Override
@@ -424,6 +449,99 @@ public class Workspace extends SmoothPagedView
}
}
private float getScaleXForRotation(float degrees) {
return (float) (1.0f / Math.cos(Math.PI * degrees / 180.0f));
}
public void showOutlines() {
if (mBackgroundFadeOut != null) mBackgroundFadeOut.cancel();
if (mBackgroundFadeIn != null) mBackgroundFadeIn.cancel();
mBackgroundFadeIn = new ObjectAnimator<Float>(BACKGROUND_FADE_IN_DURATION, this,
new PropertyValuesHolder<Float>("backgroundAlpha", 1.0f));
mBackgroundFadeIn.start();
}
public void hideOutlines() {
if (mBackgroundFadeIn != null) mBackgroundFadeIn.cancel();
if (mBackgroundFadeOut != null) mBackgroundFadeOut.cancel();
mBackgroundFadeOut = new ObjectAnimator<Float>(BACKGROUND_FADE_OUT_DURATION, this,
new PropertyValuesHolder<Float>("backgroundAlpha", 0.0f));
mBackgroundFadeOut.setStartDelay(BACKGROUND_FADE_OUT_DELAY);
mBackgroundFadeOut.start();
}
public void setBackgroundAlpha(float alpha) {
mBackgroundAlpha = alpha;
for (int i = 0; i < getChildCount(); i++) {
CellLayout cl = (CellLayout) getChildAt(i);
cl.setBackgroundAlpha(alpha);
}
}
public float getBackgroundAlpha() {
return mBackgroundAlpha;
}
@Override
protected void screenScrolled(int screenCenter) {
View cur = getChildAt(mCurrentPage);
View toRight = getChildAt(mCurrentPage + 1);
View toLeft = getChildAt(mCurrentPage - 1);
for (int i = 0; i < mCurrentPage - 1; i++) {
View v = getChildAt(i);
if (v != null) {
v.setRotationY(WORKSPACE_ROTATION);
v.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
}
}
for (int i = mCurrentPage + 1; i < getChildCount(); i++) {
View v = getChildAt(i);
if (v != null) {
v.setRotationY(-WORKSPACE_ROTATION);
v.setScaleX(getScaleXForRotation(-WORKSPACE_ROTATION));
}
}
int pageWidth = cur.getMeasuredWidth();
int delta = screenCenter - (mCurrentPage * pageWidth + pageWidth / 2 +
getRelativeChildOffset(0));
float scrollProgress = Math.abs(delta/(pageWidth*1.0f));
int scrollDirection = delta > 0 ? SCROLL_LEFT : SCROLL_RIGHT;
float rotation;
if (scrollDirection == SCROLL_RIGHT) {
rotation = -scrollProgress * WORKSPACE_ROTATION;
cur.setRotationY(rotation);
cur.setScaleX(getScaleXForRotation(rotation));
if (toLeft != null) {
rotation = WORKSPACE_ROTATION * (1 - scrollProgress);
toLeft.setRotationY(rotation);
toLeft.setScaleX(getScaleXForRotation(rotation));
}
if (toRight != null) {
toRight.setRotationY(-WORKSPACE_ROTATION);
toRight.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
}
} else {
rotation = scrollProgress * WORKSPACE_ROTATION;
cur.setRotationY(rotation);
cur.setScaleX(getScaleXForRotation(rotation));
if (toRight != null) {
rotation = -WORKSPACE_ROTATION * (1 - scrollProgress);
toRight.setRotationY(rotation);
toRight.setScaleX(getScaleXForRotation(rotation));
}
if (toLeft != null) {
toLeft.setRotationY(WORKSPACE_ROTATION);
toLeft.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
}
}
}
protected void onAttachedToWindow() {
super.onAttachedToWindow();
computeScroll();
@@ -624,7 +742,7 @@ public class Workspace extends SmoothPagedView
for (int i = 0; i < screenCount; i++) {
CellLayout cl = (CellLayout) getChildAt(i);
float rotation = (-i + 2) * MINI_PAGE_MAX_ROTATION / 2.0f;
float rotation = (-i + 2) * WORKSPACE_ROTATION;
float rotationScaleX = (float) (1.0f / Math.cos(Math.PI * rotation / 180.0f));
float rotationScaleY = getYScaleForScreen(i);
@@ -636,14 +754,16 @@ public class Workspace extends SmoothPagedView
new PropertyValuesHolder<Float>("scaleX", SHRINK_FACTOR * rotationScaleX),
new PropertyValuesHolder<Float>("scaleY", SHRINK_FACTOR * rotationScaleY),
new PropertyValuesHolder<Float>("backgroundAlpha", 1.0f),
new PropertyValuesHolder<Float>("dimmableProgress", 1.0f),
new PropertyValuesHolder<Float>("alpha", 0.0f),
new PropertyValuesHolder<Float>("rotationY", rotation)).start();
} else {
cl.setX((int)newX);
cl.setY((int)newY);
cl.setScaleX(SHRINK_FACTOR);
cl.setScaleY(SHRINK_FACTOR);
cl.setScaleX(SHRINK_FACTOR * rotationScaleX);
cl.setScaleY(SHRINK_FACTOR * rotationScaleY);
cl.setBackgroundAlpha(1.0f);
cl.setDimmableProgress(1.0f);
cl.setAlpha(0.0f);
cl.setRotationY(rotation);
}
@@ -696,6 +816,14 @@ public class Workspace extends SmoothPagedView
for (int i = 0; i < screenCount; i++) {
final CellLayout cl = (CellLayout)getChildAt(i);
float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
float rotation = 0.0f;
if (i < mCurrentPage) {
rotation = WORKSPACE_ROTATION;
} else if (i > mCurrentPage) {
rotation = -WORKSPACE_ROTATION;
}
if (animated) {
s.playTogether(
new ObjectAnimator<Float>(duration, cl, "translationX", 0.0f),
@@ -704,15 +832,17 @@ public class Workspace extends SmoothPagedView
new ObjectAnimator<Float>(duration, cl, "scaleY", 1.0f),
new ObjectAnimator<Float>(duration, cl, "backgroundAlpha", 0.0f),
new ObjectAnimator<Float>(duration, cl, "alpha", finalAlphaValue),
new ObjectAnimator<Float>(duration, cl, "rotationY", 0.0f));
new ObjectAnimator<Float>(duration, cl, "dimmableProgress", 0.0f),
new ObjectAnimator<Float>(duration, cl, "rotationY", rotation));
} else {
cl.setTranslationX(0.0f);
cl.setTranslationY(0.0f);
cl.setScaleX(1.0f);
cl.setScaleY(1.0f);
cl.setBackgroundAlpha(0.0f);
cl.setAlpha(1.0f);
cl.setRotationY(0.0f);
cl.setDimmableProgress(0.0f);
cl.setAlpha(finalAlphaValue);
cl.setRotationY(rotation);
}
}
s.addListener(mUnshrinkAnimationListener);
@@ -774,23 +904,25 @@ public class Workspace extends SmoothPagedView
} else {
cellLayout = getCurrentDropLayout();
}
if (source != this) {
onDropExternal(originX, originY, dragInfo, cellLayout);
} else {
// Move internally
if (mDragInfo != null) {
final View cell = mDragInfo.cell;
int index = mScroller.isFinished() ? mCurrentPage : mNextPage;
if (index != mDragInfo.screen) {
final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
originalCellLayout.removeView(cell);
addInScreen(cell, index, mDragInfo.cellX, mDragInfo.cellY,
mDragInfo.spanX, mDragInfo.spanY);
}
mTargetCell = findNearestVacantArea(originX, originY,
mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout,
mTargetCell);
int screen = indexOfChild(cellLayout);
if (screen != mDragInfo.screen) {
final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
originalCellLayout.removeView(cell);
addInScreen(cell, screen, mTargetCell[0], mTargetCell[1],
mDragInfo.spanX, mDragInfo.spanY);
}
cellLayout.onDropChild(cell);
// update the item's position after drop
@@ -799,9 +931,11 @@ public class Workspace extends SmoothPagedView
cellLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
lp.cellX = mTargetCell[0];
lp.cellY = mTargetCell[1];
cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen,
mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
LauncherModel.moveItemInDatabase(mLauncher, info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, index,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
lp.cellX, lp.cellY);
}
}
@@ -1152,15 +1286,12 @@ public class Workspace extends SmoothPagedView
private int[] findNearestVacantArea(int pixelX, int pixelY,
int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) {
final int[] cellXY = mTempCell;
int localPixelX = pixelX - (layout.getLeft() - mScrollX);
int localPixelY = pixelY - (layout.getTop() - mScrollY);
layout.estimateDropCell(localPixelX, localPixelY, spanX, spanY, cellXY);
layout.cellToPoint(cellXY[0], cellXY[1], mTempEstimate);
// Find the best target drop location
return layout.findNearestVacantArea(
mTempEstimate[0], mTempEstimate[1], spanX, spanY, ignoreView, recycle);
localPixelX, localPixelY, spanX, spanY, ignoreView, recycle);
}
/**