Stripping LiveFolders from Launcher
Change-Id: Ic105fbeb1289e43469d5975b7d977b2fc7900c0b
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.launcher2.UserFolder
|
||||
<com.android.launcher2.Folder
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
|
||||
android:orientation="vertical">
|
||||
@@ -58,4 +58,4 @@
|
||||
android:numColumns="5" />
|
||||
</FrameLayout>
|
||||
|
||||
</com.android.launcher2.UserFolder>
|
||||
</com.android.launcher2.Folder>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<com.android.launcher2.UserFolder
|
||||
<com.android.launcher2.Folder
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
|
||||
android:orientation="vertical">
|
||||
@@ -57,4 +57,4 @@
|
||||
android:numColumns="4" />
|
||||
</FrameLayout>
|
||||
|
||||
</com.android.launcher2.UserFolder>
|
||||
</com.android.launcher2.Folder>
|
||||
|
||||
@@ -40,7 +40,6 @@ public class AddAdapter extends BaseAdapter {
|
||||
|
||||
public static final int ITEM_SHORTCUT = 0;
|
||||
public static final int ITEM_APPWIDGET = 1;
|
||||
public static final int ITEM_LIVE_FOLDER = 2;
|
||||
public static final int ITEM_WALLPAPER = 3;
|
||||
|
||||
/**
|
||||
@@ -76,9 +75,6 @@ public class AddAdapter extends BaseAdapter {
|
||||
mItems.add(new ListItem(res, R.string.group_widgets,
|
||||
R.drawable.ic_launcher_appwidget, ITEM_APPWIDGET));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_live_folders,
|
||||
R.drawable.ic_launcher_folder, ITEM_LIVE_FOLDER));
|
||||
|
||||
mItems.add(new ListItem(res, R.string.group_wallpapers,
|
||||
R.drawable.ic_launcher_wallpaper, ITEM_WALLPAPER));
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -31,7 +31,6 @@ import android.graphics.drawable.TransitionDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.TranslateAnimation;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
@@ -113,18 +112,18 @@ public class DeleteZone extends IconDropTarget {
|
||||
if (item instanceof LauncherAppWidgetInfo) {
|
||||
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
|
||||
}
|
||||
} else if (source instanceof UserFolder) {
|
||||
final UserFolder userFolder = (UserFolder) source;
|
||||
final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
|
||||
} else if (source instanceof Folder) {
|
||||
final Folder folder = (Folder) source;
|
||||
final FolderInfo folderInfo = (FolderInfo) folder.getInfo();
|
||||
// Item must be a ShortcutInfo otherwise it couldn't have been in the folder
|
||||
// in the first place.
|
||||
userFolderInfo.remove((ShortcutInfo)item);
|
||||
folderInfo.remove((ShortcutInfo)item);
|
||||
}
|
||||
|
||||
if (item instanceof UserFolderInfo) {
|
||||
final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
|
||||
LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
|
||||
mLauncher.removeFolder(userFolderInfo);
|
||||
if (item instanceof FolderInfo) {
|
||||
final FolderInfo folderInfo = (FolderInfo)item;
|
||||
LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
|
||||
mLauncher.removeFolder(folderInfo);
|
||||
} else if (item instanceof LauncherAppWidgetInfo) {
|
||||
final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
|
||||
final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
|
||||
|
||||
@@ -16,14 +16,25 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
|
||||
@@ -33,14 +44,14 @@ import com.android.launcher.R;
|
||||
* Represents a set of icons chosen by the user or generated by the system.
|
||||
*/
|
||||
public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
|
||||
OnItemClickListener, OnClickListener, View.OnLongClickListener {
|
||||
OnItemClickListener, OnClickListener, View.OnLongClickListener, DropTarget {
|
||||
|
||||
protected DragController mDragController;
|
||||
|
||||
|
||||
protected Launcher mLauncher;
|
||||
|
||||
protected Button mCloseButton;
|
||||
|
||||
|
||||
protected FolderInfo mInfo;
|
||||
|
||||
/**
|
||||
@@ -48,6 +59,19 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
*/
|
||||
protected ShortcutInfo mDragItem;
|
||||
|
||||
private static final String TAG = "Launcher.Folder";
|
||||
|
||||
static final int STATE_NONE = -1;
|
||||
static final int STATE_SMALL = 0;
|
||||
static final int STATE_ANIMATING = 1;
|
||||
static final int STATE_OPEN = 2;
|
||||
|
||||
private int mExpandDuration;
|
||||
protected CellLayout mContent;
|
||||
private final LayoutInflater mInflater;
|
||||
private final IconCache mIconCache;
|
||||
private int mState = STATE_NONE;
|
||||
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
@@ -57,6 +81,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
public Folder(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setAlwaysDrawnWithCacheEnabled(false);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache();
|
||||
mExpandDuration = getResources().getInteger(R.integer.config_folderAnimDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,6 +93,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
mCloseButton = (Button) findViewById(R.id.folder_close);
|
||||
mCloseButton.setOnClickListener(this);
|
||||
mCloseButton.setOnLongClickListener(this);
|
||||
mContent = (CellLayout) findViewById(R.id.folder_content);
|
||||
}
|
||||
|
||||
public void onItemClick(AdapterView parent, View v, int position, long id) {
|
||||
@@ -78,12 +106,38 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
mLauncher.closeFolder(this);
|
||||
Object tag = v.getTag();
|
||||
if (tag instanceof ShortcutInfo) {
|
||||
// refactor this code from Folder
|
||||
ShortcutInfo item = (ShortcutInfo) tag;
|
||||
int[] pos = new int[2];
|
||||
v.getLocationOnScreen(pos);
|
||||
item.intent.setSourceBounds(new Rect(pos[0], pos[1],
|
||||
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
|
||||
mLauncher.startActivitySafely(item.intent, item);
|
||||
} else {
|
||||
mLauncher.closeFolder(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onLongClick(View v) {
|
||||
mLauncher.closeFolder(this);
|
||||
mLauncher.showRenameDialog(mInfo);
|
||||
Object tag = v.getTag();
|
||||
if (tag instanceof ShortcutInfo) {
|
||||
// refactor this code from Folder
|
||||
ShortcutInfo item = (ShortcutInfo) tag;
|
||||
if (!v.isInTouchMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLauncher.getWorkspace().onDragStartedWithItem(v);
|
||||
mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY);
|
||||
|
||||
mLauncher.closeFolder(this);
|
||||
mDragItem = item;
|
||||
} else {
|
||||
mLauncher.closeFolder(this);
|
||||
mLauncher.showRenameDialog(mInfo);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -105,17 +159,9 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
mDragController = dragController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropCompleted(View target, Object dragInfo, boolean success) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragViewVisible() {
|
||||
}
|
||||
|
||||
void notifyDataSetChanged() {
|
||||
}
|
||||
|
||||
void setLauncher(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
@@ -128,6 +174,11 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
}
|
||||
|
||||
void onOpen() {
|
||||
// When the folder opens, we need to refresh the GridView's selection by
|
||||
// forcing a layout
|
||||
// TODO: find out if this is still necessary
|
||||
mContent.requestLayout();
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
void onClose() {
|
||||
@@ -138,5 +189,224 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL
|
||||
void bind(FolderInfo info) {
|
||||
mInfo = info;
|
||||
mCloseButton.setText(info.title);
|
||||
ArrayList<ShortcutInfo> children = info.contents;
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
ShortcutInfo child = (ShortcutInfo) children.get(i);
|
||||
if ((child.cellX == -1 && child.cellY == -1) ||
|
||||
mContent.isOccupied(child.cellX, child.cellY)) {
|
||||
findAndSetEmptyCells(child);
|
||||
}
|
||||
createAndAddShortcut((ShortcutInfo) children.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UserFolder, inflated from R.layout.user_folder.
|
||||
*
|
||||
* @param context The application's context.
|
||||
*
|
||||
* @return A new UserFolder.
|
||||
*/
|
||||
static Folder fromXml(Context context) {
|
||||
return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is intended to make the UserFolder to be visually identical in size and position
|
||||
* to its associated FolderIcon. This allows for a seamless transition into the expanded state.
|
||||
*/
|
||||
private void positionAndSizeAsIcon() {
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
|
||||
FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
|
||||
CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
lp.width = iconLp.width;
|
||||
lp.height = iconLp.height;
|
||||
lp.x = iconLp.x;
|
||||
lp.y = iconLp.y;
|
||||
|
||||
mContent.setAlpha(0f);
|
||||
mState = STATE_SMALL;
|
||||
}
|
||||
|
||||
public void animateOpen() {
|
||||
if (mState != STATE_SMALL) {
|
||||
positionAndSizeAsIcon();
|
||||
}
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
Rect r = cellLayout.getContentRect(null);
|
||||
|
||||
PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", r.width());
|
||||
PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", r.height());
|
||||
PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", 0);
|
||||
PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", 0);
|
||||
|
||||
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
|
||||
oa.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
|
||||
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
|
||||
ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.playTogether(oa, oaContentAlpha);
|
||||
set.setDuration(mExpandDuration);
|
||||
set.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mState = STATE_ANIMATING;
|
||||
}
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mState = STATE_SMALL;
|
||||
}
|
||||
});
|
||||
set.start();
|
||||
}
|
||||
|
||||
public void animateClosed() {
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
final CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
|
||||
FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
|
||||
CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width);
|
||||
PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height);
|
||||
PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x);
|
||||
PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y);
|
||||
|
||||
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
|
||||
oa.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
|
||||
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
|
||||
ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.playTogether(oa, oaContentAlpha);
|
||||
set.setDuration(mExpandDuration);
|
||||
|
||||
set.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
cellLayout.removeViewWithoutMarkingCells(Folder.this);
|
||||
mState = STATE_OPEN;
|
||||
}
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mState = STATE_ANIMATING;
|
||||
}
|
||||
});
|
||||
set.start();
|
||||
}
|
||||
|
||||
void notifyDataSetChanged() {
|
||||
// recreate all the children if the data set changes under us. We may want to do this more
|
||||
// intelligently (ie just removing the views that should no longer exist)
|
||||
mContent.removeAllViewsInLayout();
|
||||
bind(mInfo);
|
||||
}
|
||||
|
||||
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
final ItemInfo item = (ItemInfo) dragInfo;
|
||||
final int itemType = item.itemType;
|
||||
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
|
||||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
|
||||
&& item.container != mInfo.id;
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
ShortcutInfo item;
|
||||
if (dragInfo instanceof ApplicationInfo) {
|
||||
// Came from all apps -- make a copy
|
||||
item = ((ApplicationInfo)dragInfo).makeShortcut();
|
||||
item.spanX = 1;
|
||||
item.spanY = 1;
|
||||
} else {
|
||||
item = (ShortcutInfo)dragInfo;
|
||||
}
|
||||
findAndSetEmptyCells(item);
|
||||
mInfo.add(item);
|
||||
createAndAddShortcut(item);
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
||||
}
|
||||
|
||||
protected boolean findAndSetEmptyCells(ShortcutInfo item) {
|
||||
int[] emptyCell = new int[2];
|
||||
if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
|
||||
item.cellX = emptyCell[0];
|
||||
item.cellY = emptyCell[1];
|
||||
LauncherModel.addOrMoveItemInDatabase(
|
||||
mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void createAndAddShortcut(ShortcutInfo item) {
|
||||
final TextView textView =
|
||||
(TextView) mInflater.inflate(R.layout.application_boxed, this, false);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null,
|
||||
new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
|
||||
textView.setText(item.title);
|
||||
textView.setTag(item);
|
||||
|
||||
textView.setOnClickListener(this);
|
||||
textView.setOnLongClickListener(this);
|
||||
|
||||
CellLayout.LayoutParams lp =
|
||||
new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
|
||||
boolean insert = false;
|
||||
mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
|
||||
}
|
||||
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDropCompleted(View target, Object dragInfo, boolean success) {
|
||||
if (success) {
|
||||
mInfo.remove(mDragItem);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDropEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.android.launcher.R;
|
||||
* An icon that can appear on in the workspace representing an {@link UserFolder}.
|
||||
*/
|
||||
public class FolderIcon extends BubbleTextView implements DropTarget {
|
||||
private UserFolderInfo mInfo;
|
||||
private FolderInfo mInfo;
|
||||
private Launcher mLauncher;
|
||||
private Drawable mCloseIcon;
|
||||
private Drawable mOpenIcon;
|
||||
@@ -50,7 +50,7 @@ public class FolderIcon extends BubbleTextView implements DropTarget {
|
||||
}
|
||||
|
||||
static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
|
||||
UserFolderInfo folderInfo, IconCache iconCache) {
|
||||
FolderInfo folderInfo, IconCache iconCache) {
|
||||
|
||||
FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
|
||||
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.ContentValues;
|
||||
|
||||
/**
|
||||
* Represents a folder containing shortcuts or apps.
|
||||
*/
|
||||
class FolderInfo extends ItemInfo {
|
||||
|
||||
|
||||
/**
|
||||
* Whether this folder has been opened
|
||||
*/
|
||||
@@ -31,4 +34,37 @@ class FolderInfo extends ItemInfo {
|
||||
* The folder name.
|
||||
*/
|
||||
CharSequence title;
|
||||
|
||||
/**
|
||||
* The apps and shortcuts
|
||||
*/
|
||||
ArrayList<ShortcutInfo> contents = new ArrayList<ShortcutInfo>();
|
||||
|
||||
FolderInfo() {
|
||||
itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an app or shortcut
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public void add(ShortcutInfo item) {
|
||||
contents.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an app or shortcut. Does not change the DB.
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public void remove(ShortcutInfo item) {
|
||||
contents.remove(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onAddToDatabase(ContentValues values) {
|
||||
super.onAddToDatabase(values);
|
||||
values.put(LauncherSettings.Favorites.TITLE, title.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class ItemInfo {
|
||||
/**
|
||||
* One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
|
||||
* {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
|
||||
* {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, or
|
||||
* {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or
|
||||
* {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}.
|
||||
*/
|
||||
int itemType;
|
||||
|
||||
@@ -17,9 +17,13 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
import com.android.launcher2.Workspace.ShrinkState;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -63,10 +67,8 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Parcelable;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.LiveFolders;
|
||||
import android.provider.Settings;
|
||||
import android.speech.RecognizerIntent;
|
||||
import android.text.Selection;
|
||||
@@ -99,13 +101,9 @@ import android.widget.TabHost;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
import com.android.launcher2.Workspace.ShrinkState;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
@@ -131,11 +129,9 @@ public final class Launcher extends Activity
|
||||
private static final int MENU_SETTINGS = MENU_NOTIFICATIONS + 1;
|
||||
|
||||
private static final int REQUEST_CREATE_SHORTCUT = 1;
|
||||
private static final int REQUEST_CREATE_LIVE_FOLDER = 4;
|
||||
private static final int REQUEST_CREATE_APPWIDGET = 5;
|
||||
private static final int REQUEST_PICK_APPLICATION = 6;
|
||||
private static final int REQUEST_PICK_SHORTCUT = 7;
|
||||
private static final int REQUEST_PICK_LIVE_FOLDER = 8;
|
||||
private static final int REQUEST_PICK_APPWIDGET = 9;
|
||||
private static final int REQUEST_PICK_WALLPAPER = 10;
|
||||
|
||||
@@ -154,7 +150,7 @@ public final class Launcher extends Activity
|
||||
// Type: int
|
||||
private static final String RUNTIME_STATE = "launcher.state";
|
||||
// Type: long
|
||||
private static final String RUNTIME_STATE_USER_FOLDERS = "launcher.user_folder";
|
||||
private static final String RUNTIME_STATE_FOLDERS = "launcher.folder";
|
||||
// Type: int
|
||||
private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";
|
||||
// Type: int
|
||||
@@ -636,12 +632,6 @@ public final class Launcher extends Activity
|
||||
case REQUEST_CREATE_SHORTCUT:
|
||||
completeAddShortcut(args.intent, args.screen, args.cellX, args.cellY);
|
||||
break;
|
||||
case REQUEST_PICK_LIVE_FOLDER:
|
||||
addLiveFolder(args.intent);
|
||||
break;
|
||||
case REQUEST_CREATE_LIVE_FOLDER:
|
||||
completeAddLiveFolder(args.intent, args.screen, args.cellX, args.cellY);
|
||||
break;
|
||||
case REQUEST_PICK_APPWIDGET:
|
||||
addAppWidgetFromPick(args.intent);
|
||||
break;
|
||||
@@ -1471,7 +1461,7 @@ public final class Launcher extends Activity
|
||||
final FolderInfo info = folders.get(i).getInfo();
|
||||
ids[i] = info.id;
|
||||
}
|
||||
outState.putLongArray(RUNTIME_STATE_USER_FOLDERS, ids);
|
||||
outState.putLongArray(RUNTIME_STATE_FOLDERS, ids);
|
||||
} else {
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
@@ -1808,31 +1798,8 @@ public final class Launcher extends Activity
|
||||
startActivityForResult(intent, REQUEST_PICK_WALLPAPER);
|
||||
}
|
||||
|
||||
void addLiveFolderFromDrop(ComponentName componentName, int screen, int[] position) {
|
||||
resetAddInfo();
|
||||
mAddScreen = screen;
|
||||
mAddDropPosition = position;
|
||||
|
||||
Intent createFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
|
||||
createFolderIntent.setComponent(componentName);
|
||||
|
||||
addLiveFolder(createFolderIntent);
|
||||
}
|
||||
|
||||
void addLiveFolder(Intent intent) { // YYY add screen intersect etc. parameters here
|
||||
// Handle case where user selected "Folder"
|
||||
String folderName = getResources().getString(R.string.group_folder);
|
||||
String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||
|
||||
if (folderName != null && folderName.equals(shortcutName)) {
|
||||
addFolder(mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
|
||||
} else {
|
||||
startActivityForResultSafely(intent, REQUEST_CREATE_LIVE_FOLDER);
|
||||
}
|
||||
}
|
||||
|
||||
FolderIcon addFolder(int screen, int intersectCellX, int intersectCellY) {
|
||||
UserFolderInfo folderInfo = new UserFolderInfo();
|
||||
FolderInfo folderInfo = new FolderInfo();
|
||||
folderInfo.title = getText(R.string.folder_name);
|
||||
|
||||
final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
|
||||
@@ -1860,67 +1827,6 @@ public final class Launcher extends Activity
|
||||
sFolders.remove(folder.id);
|
||||
}
|
||||
|
||||
private void completeAddLiveFolder(
|
||||
Intent data, int screen, int intersectCellX, int intersectCellY) {
|
||||
final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
|
||||
final int[] cellXY = mTmpAddItemCellCoordinates;
|
||||
if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
|
||||
showOutOfSpaceMessage();
|
||||
return;
|
||||
}
|
||||
|
||||
final LiveFolderInfo info = addLiveFolder(this, data, screen, cellXY[0], cellXY[1], false);
|
||||
|
||||
if (!mRestoring) {
|
||||
final View view = LiveFolderIcon.fromXml(R.layout.live_folder_icon, this,
|
||||
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
|
||||
mWorkspace.addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
|
||||
}
|
||||
}
|
||||
|
||||
static LiveFolderInfo addLiveFolder(Context context, Intent data,
|
||||
int screen, int cellX, int cellY, boolean notify) {
|
||||
|
||||
Intent baseIntent = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT);
|
||||
String name = data.getStringExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME);
|
||||
|
||||
Drawable icon = null;
|
||||
Intent.ShortcutIconResource iconResource = null;
|
||||
|
||||
Parcelable extra = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON);
|
||||
if (extra != null && extra instanceof Intent.ShortcutIconResource) {
|
||||
try {
|
||||
iconResource = (Intent.ShortcutIconResource) extra;
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
Resources resources = packageManager.getResourcesForApplication(
|
||||
iconResource.packageName);
|
||||
final int id = resources.getIdentifier(iconResource.resourceName, null, null);
|
||||
icon = resources.getDrawable(id);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Could not load live folder icon: " + extra);
|
||||
}
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
icon = context.getResources().getDrawable(R.drawable.ic_launcher_folder);
|
||||
}
|
||||
|
||||
final LiveFolderInfo info = new LiveFolderInfo();
|
||||
info.icon = Utilities.createIconBitmap(icon, context);
|
||||
info.title = name;
|
||||
info.iconResource = iconResource;
|
||||
info.uri = data.getData();
|
||||
info.baseIntent = baseIntent;
|
||||
info.displayMode = data.getIntExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
|
||||
LiveFolders.DISPLAY_MODE_GRID);
|
||||
|
||||
LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
|
||||
screen, cellX, cellY, notify);
|
||||
sFolders.put(info.id, info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private void showNotifications() {
|
||||
final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);
|
||||
if (statusBar != null) {
|
||||
@@ -2010,19 +1916,10 @@ public final class Launcher extends Activity
|
||||
ViewGroup parent = (ViewGroup) folder.getParent().getParent();
|
||||
if (parent != null) {
|
||||
CellLayout cl = (CellLayout) parent;
|
||||
if (!(folder instanceof UserFolder)) {
|
||||
// User folders will remove themselves
|
||||
cl.removeViewWithoutMarkingCells(folder);
|
||||
}
|
||||
if (folder instanceof DropTarget) {
|
||||
// Live folders aren't DropTargets.
|
||||
mDragController.removeDropTarget((DropTarget)folder);
|
||||
}
|
||||
}
|
||||
if (folder instanceof UserFolder) {
|
||||
UserFolder uf = (UserFolder) folder;
|
||||
uf.animateClosed();
|
||||
mDragController.removeDropTarget((DropTarget)folder);
|
||||
}
|
||||
|
||||
folder.animateClosed();
|
||||
folder.onClose();
|
||||
}
|
||||
|
||||
@@ -2221,15 +2118,7 @@ public final class Launcher extends Activity
|
||||
* @param folderInfo The FolderInfo describing the folder to open.
|
||||
*/
|
||||
public void openFolder(FolderInfo folderInfo) {
|
||||
Folder openFolder;
|
||||
|
||||
if (folderInfo instanceof UserFolderInfo) {
|
||||
openFolder = UserFolder.fromXml(this);
|
||||
} else if (folderInfo instanceof LiveFolderInfo) {
|
||||
openFolder = com.android.launcher2.LiveFolder.fromXml(this, folderInfo);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
Folder openFolder = Folder.fromXml(this);
|
||||
|
||||
openFolder.setDragController(mDragController);
|
||||
openFolder.setLauncher(this);
|
||||
@@ -2238,10 +2127,7 @@ public final class Launcher extends Activity
|
||||
folderInfo.opened = true;
|
||||
|
||||
mWorkspace.addInFullScreen(openFolder, folderInfo.screen);
|
||||
if (openFolder instanceof UserFolder) {
|
||||
UserFolder uf = (UserFolder) openFolder;
|
||||
uf.animateOpen();
|
||||
}
|
||||
openFolder.animateOpen();
|
||||
|
||||
openFolder.onOpen();
|
||||
}
|
||||
@@ -3359,31 +3245,6 @@ public final class Launcher extends Activity
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_LIVE_FOLDER: {
|
||||
// Insert extra item to handle inserting folder
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
ArrayList<String> shortcutNames = new ArrayList<String>();
|
||||
shortcutNames.add(res.getString(R.string.group_folder));
|
||||
bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
|
||||
|
||||
ArrayList<ShortcutIconResource> shortcutIcons =
|
||||
new ArrayList<ShortcutIconResource>();
|
||||
shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
|
||||
R.drawable.ic_launcher_folder));
|
||||
bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
|
||||
|
||||
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
|
||||
pickIntent.putExtra(Intent.EXTRA_INTENT,
|
||||
new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
|
||||
pickIntent.putExtra(Intent.EXTRA_TITLE,
|
||||
getText(R.string.title_select_live_folder));
|
||||
pickIntent.putExtras(bundle);
|
||||
|
||||
startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
|
||||
break;
|
||||
}
|
||||
|
||||
case AddAdapter.ITEM_WALLPAPER: {
|
||||
startWallpaper();
|
||||
break;
|
||||
@@ -3521,21 +3382,13 @@ public final class Launcher extends Activity
|
||||
workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
|
||||
false);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
|
||||
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
|
||||
(UserFolderInfo) item, mIconCache);
|
||||
(FolderInfo) item, mIconCache);
|
||||
workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
|
||||
false);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
|
||||
final FolderIcon newLiveFolder = LiveFolderIcon.fromXml(
|
||||
R.layout.live_folder_icon, this,
|
||||
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
|
||||
(LiveFolderInfo) item);
|
||||
workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3604,9 +3457,9 @@ public final class Launcher extends Activity
|
||||
mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
|
||||
}
|
||||
|
||||
final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);
|
||||
if (userFolders != null) {
|
||||
for (long folderId : userFolders) {
|
||||
final long[] folders = mSavedState.getLongArray(RUNTIME_STATE_FOLDERS);
|
||||
if (folders != null) {
|
||||
for (long folderId : folders) {
|
||||
final FolderInfo info = sFolders.get(folderId);
|
||||
if (info != null) {
|
||||
openFolder(info);
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.content.Intent;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
@@ -268,8 +267,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
|
||||
"_id=? and (itemType=? or itemType=?)",
|
||||
new String[] { String.valueOf(id),
|
||||
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
|
||||
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
|
||||
String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null);
|
||||
|
||||
try {
|
||||
if (c.moveToFirst()) {
|
||||
@@ -282,11 +280,8 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
|
||||
FolderInfo folderInfo = null;
|
||||
switch (c.getInt(itemTypeIndex)) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
|
||||
folderInfo = findOrMakeUserFolder(folderList, id);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
|
||||
folderInfo = findOrMakeLiveFolder(folderList, id);
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
folderInfo = findOrMakeFolder(folderList, id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -388,7 +383,7 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
/**
|
||||
* Remove the contents of the specified folder from the database
|
||||
*/
|
||||
static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
|
||||
static void deleteFolderContentsFromDatabase(Context context, FolderInfo info) {
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
|
||||
cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
|
||||
@@ -841,8 +836,8 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
break;
|
||||
default:
|
||||
// Item is in a user folder
|
||||
UserFolderInfo folderInfo =
|
||||
findOrMakeUserFolder(mFolders, container);
|
||||
FolderInfo folderInfo =
|
||||
findOrMakeFolder(mFolders, container);
|
||||
folderInfo.add(info);
|
||||
break;
|
||||
}
|
||||
@@ -862,9 +857,9 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
break;
|
||||
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
id = c.getLong(idIndex);
|
||||
UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id);
|
||||
FolderInfo folderInfo = findOrMakeFolder(mFolders, id);
|
||||
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
folderInfo.id = id;
|
||||
@@ -887,57 +882,6 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
mFolders.put(folderInfo.id, folderInfo);
|
||||
break;
|
||||
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
|
||||
id = c.getLong(idIndex);
|
||||
Uri uri = Uri.parse(c.getString(uriIndex));
|
||||
|
||||
// Make sure the live folder exists
|
||||
final ProviderInfo providerInfo =
|
||||
context.getPackageManager().resolveContentProvider(
|
||||
uri.getAuthority(), 0);
|
||||
|
||||
if (providerInfo == null && !isSafeMode) {
|
||||
itemsToRemove.add(id);
|
||||
} else {
|
||||
LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
|
||||
intentDescription = c.getString(intentIndex);
|
||||
intent = null;
|
||||
if (intentDescription != null) {
|
||||
try {
|
||||
intent = Intent.parseUri(intentDescription, 0);
|
||||
} catch (URISyntaxException e) {
|
||||
// Ignore, a live folder might not have a base intent
|
||||
}
|
||||
}
|
||||
|
||||
liveFolderInfo.title = c.getString(titleIndex);
|
||||
liveFolderInfo.id = id;
|
||||
liveFolderInfo.uri = uri;
|
||||
container = c.getInt(containerIndex);
|
||||
liveFolderInfo.container = container;
|
||||
liveFolderInfo.screen = c.getInt(screenIndex);
|
||||
liveFolderInfo.cellX = c.getInt(cellXIndex);
|
||||
liveFolderInfo.cellY = c.getInt(cellYIndex);
|
||||
liveFolderInfo.baseIntent = intent;
|
||||
liveFolderInfo.displayMode = c.getInt(displayModeIndex);
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, liveFolderInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
|
||||
iconResourceIndex, liveFolderInfo);
|
||||
|
||||
switch (container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
|
||||
mItems.add(liveFolderInfo);
|
||||
break;
|
||||
}
|
||||
mFolders.put(liveFolderInfo.id, liveFolderInfo);
|
||||
}
|
||||
break;
|
||||
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
||||
// Read all Launcher-specific widget details
|
||||
int appWidgetId = c.getInt(appWidgetIdIndex);
|
||||
@@ -1667,38 +1611,6 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
return info;
|
||||
}
|
||||
|
||||
private void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex,
|
||||
int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
|
||||
|
||||
int iconType = c.getInt(iconTypeIndex);
|
||||
switch (iconType) {
|
||||
case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
|
||||
String packageName = c.getString(iconPackageIndex);
|
||||
String resourceName = c.getString(iconResourceIndex);
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
try {
|
||||
Resources appResources = packageManager.getResourcesForApplication(packageName);
|
||||
final int id = appResources.getIdentifier(resourceName, null, null);
|
||||
liveFolderInfo.icon = Utilities.createIconBitmap(
|
||||
mIconCache.getFullResIcon(appResources, id), context);
|
||||
} catch (Exception e) {
|
||||
Resources resources = context.getResources();
|
||||
liveFolderInfo.icon = Utilities.createIconBitmap(
|
||||
mIconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder),
|
||||
context);
|
||||
}
|
||||
liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
|
||||
liveFolderInfo.iconResource.packageName = packageName;
|
||||
liveFolderInfo.iconResource.resourceName = resourceName;
|
||||
break;
|
||||
default:
|
||||
Resources resources = context.getResources();
|
||||
liveFolderInfo.icon = Utilities.createIconBitmap(
|
||||
mIconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder),
|
||||
context);
|
||||
}
|
||||
}
|
||||
|
||||
void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) {
|
||||
// If apps can't be on SD, don't even bother.
|
||||
if (!mAppsCanBeOnExternalStorage) {
|
||||
@@ -1734,33 +1646,18 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an existing UserFolderInfo object if we have encountered this ID previously,
|
||||
* Return an existing FolderInfo object if we have encountered this ID previously,
|
||||
* or make a new one.
|
||||
*/
|
||||
private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
|
||||
private static FolderInfo findOrMakeFolder(HashMap<Long, FolderInfo> folders, long id) {
|
||||
// See if a placeholder was created for us already
|
||||
FolderInfo folderInfo = folders.get(id);
|
||||
if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
|
||||
if (folderInfo == null) {
|
||||
// No placeholder -- create a new instance
|
||||
folderInfo = new UserFolderInfo();
|
||||
folderInfo = new FolderInfo();
|
||||
folders.put(id, folderInfo);
|
||||
}
|
||||
return (UserFolderInfo) folderInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
|
||||
* new one.
|
||||
*/
|
||||
private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
|
||||
// See if a placeholder was created for us already
|
||||
FolderInfo folderInfo = folders.get(id);
|
||||
if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
|
||||
// No placeholder -- create a new instance
|
||||
folderInfo = new LiveFolderInfo();
|
||||
folders.put(id, folderInfo);
|
||||
}
|
||||
return (LiveFolderInfo) folderInfo;
|
||||
return folderInfo;
|
||||
}
|
||||
|
||||
private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.provider.BaseColumns;
|
||||
import android.net.Uri;
|
||||
import android.provider.BaseColumns;
|
||||
|
||||
/**
|
||||
* Settings related utilities.
|
||||
@@ -169,11 +169,15 @@ class LauncherSettings {
|
||||
/**
|
||||
* The favorite is a user created folder
|
||||
*/
|
||||
static final int ITEM_TYPE_USER_FOLDER = 2;
|
||||
static final int ITEM_TYPE_FOLDER = 2;
|
||||
|
||||
/**
|
||||
* The favorite is a live folder
|
||||
*/
|
||||
* The favorite is a live folder
|
||||
*
|
||||
* Note: live folders can no longer be added to Launcher, and any live folders which
|
||||
* exist within the launcher database will be ignored when loading. That said, these
|
||||
* entries in the database may still exist, and are not automatically stripped.
|
||||
*/
|
||||
static final int ITEM_TYPE_LIVE_FOLDER = 3;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.net.Uri;
|
||||
import android.provider.LiveFolders;
|
||||
import android.os.AsyncTask;
|
||||
import android.database.Cursor;
|
||||
import android.widget.GridView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
public class LiveFolder extends Folder {
|
||||
private AsyncTask<LiveFolderInfo,Void,Cursor> mLoadingTask;
|
||||
protected GridView mContent;
|
||||
|
||||
public LiveFolder(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
static LiveFolder fromXml(Context context, FolderInfo folderInfo) {
|
||||
final int layout = isDisplayModeList(folderInfo) ?
|
||||
R.layout.live_folder_list : R.layout.live_folder_grid;
|
||||
return (LiveFolder) LayoutInflater.from(context).inflate(layout, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mContent = (GridView) findViewById(R.id.folder_content);
|
||||
mContent.setOnItemClickListener(this);
|
||||
mContent.setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
private static boolean isDisplayModeList(FolderInfo folderInfo) {
|
||||
return ((LiveFolderInfo) folderInfo).displayMode ==
|
||||
LiveFolders.DISPLAY_MODE_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView parent, View v, int position, long id) {
|
||||
LiveFolderAdapter.ViewHolder holder = (LiveFolderAdapter.ViewHolder) v.getTag();
|
||||
|
||||
if (holder.useBaseIntent) {
|
||||
final Intent baseIntent = ((LiveFolderInfo) mInfo).baseIntent;
|
||||
if (baseIntent != null) {
|
||||
final Intent intent = new Intent(baseIntent);
|
||||
Uri uri = baseIntent.getData();
|
||||
uri = uri.buildUpon().appendPath(Long.toString(holder.id)).build();
|
||||
intent.setData(uri);
|
||||
mLauncher.startActivitySafely(intent, "(position=" + position + ", id=" + id + ")");
|
||||
}
|
||||
} else if (holder.intent != null) {
|
||||
mLauncher.startActivitySafely(holder.intent,
|
||||
"(position=" + position + ", id=" + id + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the adapter used to populate the content area. The adapter must only
|
||||
* contains ShortcutInfo items.
|
||||
*
|
||||
* @param adapter The list of applications to display in the folder.
|
||||
*/
|
||||
void setContentAdapter(BaseAdapter adapter) {
|
||||
mContent.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDataSetChanged() {
|
||||
((BaseAdapter) mContent.getAdapter()).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void bind(FolderInfo info) {
|
||||
super.bind(info);
|
||||
if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
mLoadingTask.cancel(true);
|
||||
}
|
||||
mLoadingTask = new FolderLoadingTask(this).execute((LiveFolderInfo) info);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onOpen() {
|
||||
super.onOpen();
|
||||
// When the folder opens, we need to refresh the GridView's selection by
|
||||
// forcing a layout
|
||||
mContent.requestLayout();
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
|
||||
mLoadingTask.cancel(true);
|
||||
}
|
||||
|
||||
// The adapter can be null if onClose() is called before FolderLoadingTask
|
||||
// is done querying the provider
|
||||
final LiveFolderAdapter adapter = (LiveFolderAdapter) mContent.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
static class FolderLoadingTask extends AsyncTask<LiveFolderInfo, Void, Cursor> {
|
||||
private final WeakReference<LiveFolder> mFolder;
|
||||
private LiveFolderInfo mInfo;
|
||||
|
||||
FolderLoadingTask(LiveFolder folder) {
|
||||
mFolder = new WeakReference<LiveFolder>(folder);
|
||||
}
|
||||
|
||||
protected Cursor doInBackground(LiveFolderInfo... params) {
|
||||
final LiveFolder folder = mFolder.get();
|
||||
if (folder != null) {
|
||||
mInfo = params[0];
|
||||
return LiveFolderAdapter.query(folder.mLauncher, mInfo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Cursor cursor) {
|
||||
if (!isCancelled()) {
|
||||
if (cursor != null) {
|
||||
final LiveFolder folder = mFolder.get();
|
||||
if (folder != null) {
|
||||
final Launcher launcher = folder.mLauncher;
|
||||
folder.setContentAdapter(new LiveFolderAdapter(launcher, mInfo, cursor));
|
||||
}
|
||||
}
|
||||
} else if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.widget.CursorAdapter;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ImageView;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.LayoutInflater;
|
||||
import android.database.Cursor;
|
||||
import android.provider.LiveFolders;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashMap;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
class LiveFolderAdapter extends CursorAdapter {
|
||||
private boolean mIsList;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>();
|
||||
private final HashMap<Long, SoftReference<Drawable>> mCustomIcons =
|
||||
new HashMap<Long, SoftReference<Drawable>>();
|
||||
private final Launcher mLauncher;
|
||||
|
||||
LiveFolderAdapter(Launcher launcher, LiveFolderInfo info, Cursor cursor) {
|
||||
super(launcher, cursor, true);
|
||||
mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST;
|
||||
mInflater = LayoutInflater.from(launcher);
|
||||
mLauncher = launcher;
|
||||
|
||||
mLauncher.startManagingCursor(getCursor());
|
||||
}
|
||||
|
||||
static Cursor query(Context context, LiveFolderInfo info) {
|
||||
return context.getContentResolver().query(info.uri, null, null,
|
||||
null, LiveFolders.NAME + " ASC");
|
||||
}
|
||||
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
View view;
|
||||
final ViewHolder holder = new ViewHolder();
|
||||
|
||||
if (!mIsList) {
|
||||
view = mInflater.inflate(R.layout.application_boxed, parent, false);
|
||||
} else {
|
||||
view = mInflater.inflate(R.layout.application_list, parent, false);
|
||||
holder.description = (TextView) view.findViewById(R.id.description);
|
||||
holder.icon = (ImageView) view.findViewById(R.id.icon);
|
||||
}
|
||||
|
||||
holder.name = (TextView) view.findViewById(R.id.name);
|
||||
|
||||
holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID);
|
||||
holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME);
|
||||
holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION);
|
||||
holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT);
|
||||
holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP);
|
||||
holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE);
|
||||
holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE);
|
||||
|
||||
view.setTag(holder);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
final ViewHolder holder = (ViewHolder) view.getTag();
|
||||
|
||||
holder.id = cursor.getLong(holder.idIndex);
|
||||
final Drawable icon = loadIcon(context, cursor, holder);
|
||||
|
||||
holder.name.setText(cursor.getString(holder.nameIndex));
|
||||
|
||||
if (!mIsList) {
|
||||
holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
|
||||
} else {
|
||||
final boolean hasIcon = icon != null;
|
||||
holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE);
|
||||
if (hasIcon) holder.icon.setImageDrawable(icon);
|
||||
|
||||
if (holder.descriptionIndex != -1) {
|
||||
final String description = cursor.getString(holder.descriptionIndex);
|
||||
if (description != null) {
|
||||
holder.description.setText(description);
|
||||
holder.description.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.description.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
holder.description.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (holder.intentIndex != -1) {
|
||||
try {
|
||||
holder.intent = Intent.parseUri(cursor.getString(holder.intentIndex), 0);
|
||||
} catch (URISyntaxException e) {
|
||||
// Ignore
|
||||
}
|
||||
} else {
|
||||
holder.useBaseIntent = true;
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) {
|
||||
Drawable icon = null;
|
||||
byte[] data = null;
|
||||
|
||||
if (holder.iconBitmapIndex != -1) {
|
||||
data = cursor.getBlob(holder.iconBitmapIndex);
|
||||
}
|
||||
|
||||
if (data != null) {
|
||||
final SoftReference<Drawable> reference = mCustomIcons.get(holder.id);
|
||||
if (reference != null) {
|
||||
icon = reference.get();
|
||||
}
|
||||
|
||||
if (icon == null) {
|
||||
final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
|
||||
final Bitmap resampled = Utilities.resampleIconBitmap(bitmap, mContext);
|
||||
if (bitmap != resampled) {
|
||||
// If we got back a different object, we don't need the old one any more.
|
||||
bitmap.recycle();
|
||||
}
|
||||
icon = new FastBitmapDrawable(resampled);
|
||||
mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon));
|
||||
}
|
||||
} else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) {
|
||||
final String resource = cursor.getString(holder.iconResourceIndex);
|
||||
icon = mIcons.get(resource);
|
||||
if (icon == null) {
|
||||
try {
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
Resources resources = packageManager.getResourcesForApplication(
|
||||
cursor.getString(holder.iconPackageIndex));
|
||||
final int id = resources.getIdentifier(resource,
|
||||
null, null);
|
||||
icon = new FastBitmapDrawable(
|
||||
Utilities.createIconBitmap(resources.getDrawable(id), mContext));
|
||||
mIcons.put(resource, icon);
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
for (Drawable icon : mIcons.values()) {
|
||||
icon.setCallback(null);
|
||||
}
|
||||
mIcons.clear();
|
||||
|
||||
for (SoftReference<Drawable> icon : mCustomIcons.values()) {
|
||||
final Drawable drawable = icon.get();
|
||||
if (drawable != null) {
|
||||
drawable.setCallback(null);
|
||||
}
|
||||
}
|
||||
mCustomIcons.clear();
|
||||
|
||||
final Cursor cursor = getCursor();
|
||||
if (cursor != null) {
|
||||
try {
|
||||
cursor.close();
|
||||
} finally {
|
||||
mLauncher.stopManagingCursor(cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView name;
|
||||
TextView description;
|
||||
ImageView icon;
|
||||
|
||||
Intent intent;
|
||||
long id;
|
||||
boolean useBaseIntent;
|
||||
|
||||
int idIndex;
|
||||
int nameIndex;
|
||||
int descriptionIndex = -1;
|
||||
int intentIndex = -1;
|
||||
int iconBitmapIndex = -1;
|
||||
int iconResourceIndex = -1;
|
||||
int iconPackageIndex = -1;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.LayoutInflater;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
public class LiveFolderIcon extends FolderIcon {
|
||||
public LiveFolderIcon(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LiveFolderIcon(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
static LiveFolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
|
||||
LiveFolderInfo folderInfo) {
|
||||
|
||||
LiveFolderIcon icon = (LiveFolderIcon)
|
||||
LayoutInflater.from(launcher).inflate(resId, group, false);
|
||||
|
||||
final Resources resources = launcher.getResources();
|
||||
Bitmap b = folderInfo.icon;
|
||||
if (b == null) {
|
||||
b = Utilities.createIconBitmap(resources.getDrawable(R.drawable.ic_launcher_folder),
|
||||
launcher);
|
||||
}
|
||||
icon.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(b), null, null);
|
||||
icon.setText(folderInfo.title);
|
||||
icon.setTag(folderInfo);
|
||||
icon.setOnClickListener(launcher);
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
|
||||
class LiveFolderInfo extends FolderInfo {
|
||||
|
||||
/**
|
||||
* The base intent, if it exists.
|
||||
*/
|
||||
Intent baseIntent;
|
||||
|
||||
/**
|
||||
* The live folder's content uri.
|
||||
*/
|
||||
Uri uri;
|
||||
|
||||
/**
|
||||
* The live folder's display type.
|
||||
*/
|
||||
int displayMode;
|
||||
|
||||
/**
|
||||
* The live folder icon.
|
||||
*/
|
||||
Bitmap icon;
|
||||
|
||||
/**
|
||||
* Reference to the live folder icon as an application's resource.
|
||||
*/
|
||||
Intent.ShortcutIconResource iconResource;
|
||||
|
||||
LiveFolderInfo() {
|
||||
itemType = LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
void onAddToDatabase(ContentValues values) {
|
||||
super.onAddToDatabase(values);
|
||||
values.put(LauncherSettings.Favorites.TITLE, title.toString());
|
||||
values.put(LauncherSettings.Favorites.URI, uri.toString());
|
||||
if (baseIntent != null) {
|
||||
values.put(LauncherSettings.Favorites.INTENT, baseIntent.toUri(0));
|
||||
}
|
||||
values.put(LauncherSettings.Favorites.ICON_TYPE, LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
|
||||
values.put(LauncherSettings.Favorites.DISPLAY_MODE, displayMode);
|
||||
if (iconResource != null) {
|
||||
values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
|
||||
values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,326 +0,0 @@
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
/**
|
||||
* Folder which contains applications or shortcuts chosen by the user.
|
||||
*
|
||||
*/
|
||||
public class UserFolder extends Folder implements DropTarget {
|
||||
private static final String TAG = "Launcher.UserFolder";
|
||||
|
||||
static final int STATE_NONE = -1;
|
||||
static final int STATE_SMALL = 0;
|
||||
static final int STATE_ANIMATING = 1;
|
||||
static final int STATE_OPEN = 2;
|
||||
|
||||
private int mExpandDuration;
|
||||
protected CellLayout mContent;
|
||||
private final LayoutInflater mInflater;
|
||||
private final IconCache mIconCache;
|
||||
private int mState = STATE_NONE;
|
||||
|
||||
public UserFolder(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache();
|
||||
mExpandDuration = getResources().getInteger(R.integer.config_folderAnimDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mContent = (CellLayout) findViewById(R.id.folder_content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new UserFolder, inflated from R.layout.user_folder.
|
||||
*
|
||||
* @param context The application's context.
|
||||
*
|
||||
* @return A new UserFolder.
|
||||
*/
|
||||
static UserFolder fromXml(Context context) {
|
||||
return (UserFolder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is intended to make the UserFolder to be visually identical in size and position
|
||||
* to its associated FolderIcon. This allows for a seamless transition into the expanded state.
|
||||
*/
|
||||
private void positionAndSizeAsIcon() {
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
|
||||
FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
|
||||
CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
lp.width = iconLp.width;
|
||||
lp.height = iconLp.height;
|
||||
lp.x = iconLp.x;
|
||||
lp.y = iconLp.y;
|
||||
|
||||
mContent.setAlpha(0f);
|
||||
mState = STATE_SMALL;
|
||||
}
|
||||
|
||||
public void animateOpen() {
|
||||
if (mState != STATE_SMALL) {
|
||||
positionAndSizeAsIcon();
|
||||
}
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
Rect r = cellLayout.getContentRect(null);
|
||||
|
||||
PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", r.width());
|
||||
PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", r.height());
|
||||
PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", 0);
|
||||
PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", 0);
|
||||
|
||||
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
|
||||
oa.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
|
||||
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
|
||||
ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.playTogether(oa, oaContentAlpha);
|
||||
set.setDuration(mExpandDuration);
|
||||
set.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mState = STATE_ANIMATING;
|
||||
}
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mState = STATE_SMALL;
|
||||
}
|
||||
});
|
||||
set.start();
|
||||
}
|
||||
|
||||
public void animateClosed() {
|
||||
if (!(getParent() instanceof CellLayoutChildren)) return;
|
||||
|
||||
CellLayoutChildren clc = (CellLayoutChildren) getParent();
|
||||
final CellLayout cellLayout = (CellLayout) clc.getParent();
|
||||
|
||||
FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
|
||||
CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width);
|
||||
PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height);
|
||||
PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x);
|
||||
PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y);
|
||||
|
||||
ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
|
||||
oa.addUpdateListener(new AnimatorUpdateListener() {
|
||||
public void onAnimationUpdate(ValueAnimator animation) {
|
||||
requestLayout();
|
||||
}
|
||||
});
|
||||
|
||||
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
|
||||
ObjectAnimator oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
|
||||
|
||||
AnimatorSet set = new AnimatorSet();
|
||||
set.playTogether(oa, oaContentAlpha);
|
||||
set.setDuration(mExpandDuration);
|
||||
|
||||
set.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
cellLayout.removeViewWithoutMarkingCells(UserFolder.this);
|
||||
mState = STATE_OPEN;
|
||||
}
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mState = STATE_ANIMATING;
|
||||
}
|
||||
});
|
||||
set.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyDataSetChanged() {
|
||||
// recreate all the children if the data set changes under us. We may want to do this more
|
||||
// intelligently (ie just removing the views that should no longer exist)
|
||||
mContent.removeAllViewsInLayout();
|
||||
bind(mInfo);
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
Object tag = v.getTag();
|
||||
if (tag instanceof ShortcutInfo) {
|
||||
// refactor this code from Folder
|
||||
ShortcutInfo item = (ShortcutInfo) tag;
|
||||
int[] pos = new int[2];
|
||||
v.getLocationOnScreen(pos);
|
||||
item.intent.setSourceBounds(new Rect(pos[0], pos[1],
|
||||
pos[0] + v.getWidth(), pos[1] + v.getHeight()));
|
||||
mLauncher.startActivitySafely(item.intent, item);
|
||||
} else {
|
||||
super.onClick(v);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onLongClick(View v) {
|
||||
Object tag = v.getTag();
|
||||
if (tag instanceof ShortcutInfo) {
|
||||
// refactor this code from Folder
|
||||
ShortcutInfo item = (ShortcutInfo) tag;
|
||||
if (!v.isInTouchMode()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mLauncher.getWorkspace().onDragStartedWithItem(v);
|
||||
mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY);
|
||||
|
||||
mLauncher.closeFolder(this);
|
||||
mDragItem = item;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return super.onLongClick(v);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
final ItemInfo item = (ItemInfo) dragInfo;
|
||||
final int itemType = item.itemType;
|
||||
return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
|
||||
itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
|
||||
&& item.container != mInfo.id;
|
||||
}
|
||||
|
||||
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
ShortcutInfo item;
|
||||
if (dragInfo instanceof ApplicationInfo) {
|
||||
// Came from all apps -- make a copy
|
||||
item = ((ApplicationInfo)dragInfo).makeShortcut();
|
||||
item.spanX = 1;
|
||||
item.spanY = 1;
|
||||
} else {
|
||||
item = (ShortcutInfo)dragInfo;
|
||||
}
|
||||
findAndSetEmptyCells(item);
|
||||
((UserFolderInfo)mInfo).add(item);
|
||||
createAndAddShortcut(item);
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
||||
}
|
||||
|
||||
protected boolean findAndSetEmptyCells(ShortcutInfo item) {
|
||||
int[] emptyCell = new int[2];
|
||||
if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
|
||||
item.cellX = emptyCell[0];
|
||||
item.cellY = emptyCell[1];
|
||||
LauncherModel.addOrMoveItemInDatabase(
|
||||
mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void createAndAddShortcut(ShortcutInfo item) {
|
||||
final TextView textView =
|
||||
(TextView) mInflater.inflate(R.layout.application_boxed, this, false);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(null,
|
||||
new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
|
||||
textView.setText(item.title);
|
||||
textView.setTag(item);
|
||||
|
||||
textView.setOnClickListener(this);
|
||||
textView.setOnLongClickListener(this);
|
||||
|
||||
CellLayout.LayoutParams lp =
|
||||
new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
|
||||
boolean insert = false;
|
||||
mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
|
||||
}
|
||||
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropCompleted(View target, Object dragInfo, boolean success) {
|
||||
if (success) {
|
||||
((UserFolderInfo)mInfo).remove(mDragItem);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDropEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void bind(FolderInfo info) {
|
||||
super.bind(info);
|
||||
ArrayList<ShortcutInfo> children = ((UserFolderInfo)info).contents;
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
ShortcutInfo child = (ShortcutInfo) children.get(i);
|
||||
if ((child.cellX == -1 && child.cellY == -1) ||
|
||||
mContent.isOccupied(child.cellX, child.cellY)) {
|
||||
findAndSetEmptyCells(child);
|
||||
}
|
||||
createAndAddShortcut((ShortcutInfo) children.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void onOpen() {
|
||||
super.onOpen();
|
||||
// When the folder opens, we need to refresh the GridView's selection by
|
||||
// forcing a layout
|
||||
// TODO: find out if this is still necessary
|
||||
mContent.requestLayout();
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2008 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.content.ContentValues;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents a folder containing shortcuts or apps.
|
||||
*/
|
||||
class UserFolderInfo extends FolderInfo {
|
||||
/**
|
||||
* The apps and shortcuts
|
||||
*/
|
||||
ArrayList<ShortcutInfo> contents = new ArrayList<ShortcutInfo>();
|
||||
|
||||
UserFolderInfo() {
|
||||
itemType = LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an app or shortcut
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public void add(ShortcutInfo item) {
|
||||
contents.add(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an app or shortcut. Does not change the DB.
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public void remove(ShortcutInfo item) {
|
||||
contents.remove(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onAddToDatabase(ContentValues values) {
|
||||
super.onAddToDatabase(values);
|
||||
values.put(LauncherSettings.Favorites.TITLE, title.toString());
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,6 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -50,7 +49,6 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Region.Op;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
@@ -3030,9 +3028,6 @@ public class Workspace extends SmoothPagedView
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
||||
mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) info, screen, touchXY);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
|
||||
mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||
mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY);
|
||||
break;
|
||||
@@ -3055,9 +3050,9 @@ public class Workspace extends SmoothPagedView
|
||||
view = mLauncher.createShortcut(R.layout.application, cellLayout,
|
||||
(ShortcutInfo) info);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
|
||||
cellLayout, (UserFolderInfo) info, mIconCache);
|
||||
cellLayout, (FolderInfo) info, mIconCache);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown item type: " + info.itemType);
|
||||
@@ -3345,8 +3340,8 @@ public class Workspace extends SmoothPagedView
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (tag instanceof UserFolderInfo) {
|
||||
final UserFolderInfo info = (UserFolderInfo) tag;
|
||||
} else if (tag instanceof FolderInfo) {
|
||||
final FolderInfo info = (FolderInfo) tag;
|
||||
final ArrayList<ShortcutInfo> contents = info.contents;
|
||||
final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1);
|
||||
final int contentsCount = contents.size();
|
||||
@@ -3374,20 +3369,6 @@ public class Workspace extends SmoothPagedView
|
||||
if (folder != null)
|
||||
folder.notifyDataSetChanged();
|
||||
}
|
||||
} else if (tag instanceof LiveFolderInfo) {
|
||||
final LiveFolderInfo info = (LiveFolderInfo) tag;
|
||||
final Uri uri = info.uri;
|
||||
final ProviderInfo providerInfo = manager.resolveContentProvider(
|
||||
uri.getAuthority(), 0);
|
||||
|
||||
if (providerInfo != null) {
|
||||
for (String packageName: packageNames) {
|
||||
if (packageName.equals(providerInfo.packageName)) {
|
||||
LauncherModel.deleteItemFromDatabase(mLauncher, info);
|
||||
childrenToRemove.add(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (tag instanceof LauncherAppWidgetInfo) {
|
||||
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
|
||||
final AppWidgetProviderInfo provider =
|
||||
|
||||
Reference in New Issue
Block a user