Merge branch 'master' into honeycomb-release
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 413 B |
Binary file not shown.
|
After Width: | Height: | Size: 415 B |
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp">
|
||||
<ImageView
|
||||
android:id="@+id/provider_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:maxWidth="32dp"
|
||||
android:maxHeight="32dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_launcher_application" />
|
||||
<TextView
|
||||
android:id="@+id/provider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="18sp" />
|
||||
</LinearLayout>
|
||||
@@ -15,6 +15,10 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- the area at the edge of the screen that makes the workspace go left
|
||||
or right while you're dragging. -->
|
||||
<dimen name="scroll_zone">40dp</dimen>
|
||||
|
||||
<!-- Width/height gap overrides for the workspace -->
|
||||
<dimen name="workspace_width_gap">0dp</dimen>
|
||||
<dimen name="workspace_height_gap">32dp</dimen>
|
||||
|
||||
@@ -77,6 +77,13 @@
|
||||
<!-- The format string for the dimensions of a widget in the drawer -->
|
||||
<string name="widget_dims_format" translatable="false">%1$d x %2$d</string>
|
||||
|
||||
<!-- External-drop widget pick label format string [CHAR_LIMIT=25] -->
|
||||
<string name="external_drop_widget_pick_format" translatable="false">%1$s (%2$d x %3$d)</string>
|
||||
<!-- External-drop widget error string -->
|
||||
<string name="external_drop_widget_error">Could not install clipboard item</string>
|
||||
<!-- External-drop widget pick title -->
|
||||
<string name="external_drop_widget_pick_title">Select widget to create</string>
|
||||
|
||||
<!-- Folders -->
|
||||
<skip />
|
||||
<!-- Label of Folder name field in Rename folder dialog box -->
|
||||
|
||||
@@ -327,6 +327,10 @@ public class CellLayout extends ViewGroup implements Dimmable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getHover() {
|
||||
return mHover;
|
||||
}
|
||||
|
||||
public void drawChildren(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
}
|
||||
|
||||
@@ -581,12 +581,8 @@ public class CustomizePagedView extends PagedView
|
||||
final int count = list.size();
|
||||
layout.removeAllViews();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i);
|
||||
PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo();
|
||||
createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
|
||||
createItemInfo.componentName = info.provider;
|
||||
createItemInfo.minWidth = info.minWidth;
|
||||
createItemInfo.minHeight = info.minHeight;
|
||||
final AppWidgetProviderInfo info = (AppWidgetProviderInfo) list.get(i);
|
||||
final PendingAddWidgetInfo createItemInfo = new PendingAddWidgetInfo(info, null, null);
|
||||
|
||||
LinearLayout l = (LinearLayout) mInflater.inflate(
|
||||
R.layout.customize_paged_view_widget, layout, false);
|
||||
|
||||
@@ -29,6 +29,10 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
||||
public static final String ACTION_INSTALL_SHORTCUT =
|
||||
"com.android.launcher.action.INSTALL_SHORTCUT";
|
||||
|
||||
// A mime-type representing shortcut data
|
||||
public static final String SHORTCUT_MIMETYPE =
|
||||
"com.android.launcher/shortcut";
|
||||
|
||||
private final int[] mCoordinates = new int[2];
|
||||
|
||||
public void onReceive(Context context, Intent data) {
|
||||
|
||||
@@ -16,6 +16,25 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.database.DataSetObserver;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
|
||||
/**
|
||||
* We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
|
||||
@@ -24,11 +43,153 @@ package com.android.launcher2;
|
||||
public class InstallWidgetReceiver {
|
||||
public static final String ACTION_INSTALL_WIDGET =
|
||||
"com.android.launcher.action.INSTALL_WIDGET";
|
||||
public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE =
|
||||
"com.android.launcher.action.SUPPORTS_CLIPDATA_MIMETYPE";
|
||||
|
||||
// Currently not exposed. Put into Intent when we want to make it public.
|
||||
// TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"?
|
||||
public static final String EXTRA_APPWIDGET_COMPONENT =
|
||||
"com.android.launcher.extra.widget.COMPONENT";
|
||||
public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE =
|
||||
"com.android.launcher.extra.widget.CONFIGURATION_DATA_MIME_TYPE";
|
||||
public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA =
|
||||
"com.android.launcher.extra.widget.CONFIGURATION_DATA";
|
||||
|
||||
/**
|
||||
* A simple data class that contains per-item information that the adapter below can reference.
|
||||
*/
|
||||
public static class WidgetMimeTypeHandlerData {
|
||||
public ResolveInfo resolveInfo;
|
||||
public AppWidgetProviderInfo widgetInfo;
|
||||
|
||||
public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) {
|
||||
resolveInfo = rInfo;
|
||||
widgetInfo = wInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ListAdapter which presents all the valid widgets that can be created for a given drop.
|
||||
*/
|
||||
public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener {
|
||||
private LayoutInflater mInflater;
|
||||
private Launcher mLauncher;
|
||||
private String mMimeType;
|
||||
private ClipData mClipData;
|
||||
private List<WidgetMimeTypeHandlerData> mActivities;
|
||||
private CellLayout mTargetLayout;
|
||||
private int mTargetLayoutScreen;
|
||||
private int[] mTargetLayoutPos;
|
||||
|
||||
public WidgetListAdapter(Launcher l, String mimeType, ClipData data,
|
||||
List<WidgetMimeTypeHandlerData> list, CellLayout target,
|
||||
int targetScreen, int[] targetPos) {
|
||||
mLauncher = l;
|
||||
mMimeType = mimeType;
|
||||
mClipData = data;
|
||||
mActivities = list;
|
||||
mTargetLayout = target;
|
||||
mTargetLayoutScreen = targetScreen;
|
||||
mTargetLayoutPos = targetPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDataSetObserver(DataSetObserver observer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterDataSetObserver(DataSetObserver observer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mActivities.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
final Context context = parent.getContext();
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
|
||||
// Lazy-create inflater
|
||||
if (mInflater == null) {
|
||||
mInflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
// Use the convert-view where possible
|
||||
if (convertView == null) {
|
||||
convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent,
|
||||
false);
|
||||
}
|
||||
|
||||
final WidgetMimeTypeHandlerData data = mActivities.get(position);
|
||||
final ResolveInfo resolveInfo = data.resolveInfo;
|
||||
final AppWidgetProviderInfo widgetInfo = data.widgetInfo;
|
||||
|
||||
// Set the icon
|
||||
Drawable d = resolveInfo.loadIcon(packageManager);
|
||||
ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon);
|
||||
i.setImageDrawable(d);
|
||||
|
||||
// Set the text
|
||||
final CharSequence component = resolveInfo.loadLabel(packageManager);
|
||||
final int[] widgetSpan = new int[2];
|
||||
mTargetLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan);
|
||||
TextView t = (TextView) convertView.findViewById(R.id.provider);
|
||||
t.setText(context.getString(R.string.external_drop_widget_pick_format,
|
||||
component, widgetSpan[0], widgetSpan[1]));
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return mActivities.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areAllItemsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final LauncherModel model = mLauncher.getModel();
|
||||
final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo;
|
||||
|
||||
final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType,
|
||||
mClipData);
|
||||
mLauncher.addAppWidgetFromDrop(createInfo, mTargetLayoutScreen, mTargetLayoutPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,13 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
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.AnimatorSet;
|
||||
@@ -35,17 +40,19 @@ import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
@@ -78,9 +85,9 @@ import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.animation.AccelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -89,18 +96,13 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.TabHost.OnTabChangeListener;
|
||||
import android.widget.TabHost.TabContentFactory;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
@@ -1461,8 +1463,33 @@ public final class Launcher extends Activity
|
||||
intent.setComponent(appWidget.configure);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
if (info != null) {
|
||||
intent.putExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA,
|
||||
info.configurationData);
|
||||
if (info.mimeType != null && !info.mimeType.isEmpty()) {
|
||||
intent.putExtra(
|
||||
InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE,
|
||||
info.mimeType);
|
||||
|
||||
final String mimeType = info.mimeType;
|
||||
final ClipData clipData = (ClipData) info.configurationData;
|
||||
final ClipDescription clipDesc = clipData.getDescription();
|
||||
for (int i = 0; i < clipDesc.getMimeTypeCount(); ++i) {
|
||||
if (clipDesc.getMimeType(i).equals(mimeType)) {
|
||||
final ClipData.Item item = clipData.getItem(i);
|
||||
final CharSequence stringData = item.getText();
|
||||
final Uri uriData = item.getUri();
|
||||
final Intent intentData = item.getIntent();
|
||||
final String key =
|
||||
InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA;
|
||||
if (uriData != null) {
|
||||
intent.putExtra(key, uriData);
|
||||
} else if (intentData != null) {
|
||||
intent.putExtra(key, intentData);
|
||||
} else if (stringData != null) {
|
||||
intent.putExtra(key, stringData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
|
||||
|
||||
@@ -16,7 +16,14 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.launcher.R;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
@@ -45,14 +52,8 @@ import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import com.android.launcher.R;
|
||||
import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
|
||||
|
||||
/**
|
||||
* Maintains in-memory state of the Launcher. It is expected that there should be only one
|
||||
@@ -1528,28 +1529,6 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a given shortcut intent actually has all the fields that we need to create a
|
||||
* proper ShortcutInfo.
|
||||
*/
|
||||
boolean validateShortcutIntent(Intent data) {
|
||||
// We don't require Intent.EXTRA_SHORTCUT_ICON, since we can pull a default fallback icon
|
||||
return InstallShortcutReceiver.ACTION_INSTALL_SHORTCUT.equals(data.getAction()) &&
|
||||
(data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME) != null) &&
|
||||
(data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that a given widget intent actually has all the fields that we need to create a
|
||||
* proper widget.
|
||||
*/
|
||||
boolean validateWidgetIntent(Intent data) {
|
||||
// We don't require Intent.EXTRA_APPWIDGET_CONFIGURATION_DATA, since that will just be
|
||||
// forwarded onto the widget's configuration activity if it exists
|
||||
return InstallWidgetReceiver.ACTION_INSTALL_WIDGET.equals(data.getAction()) &&
|
||||
(data.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find an AppWidgetProviderInfo that matches the given component.
|
||||
*/
|
||||
@@ -1565,6 +1544,44 @@ public class LauncherModel extends BroadcastReceiver {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the widgets that can handle configuration with a particular mimeType.
|
||||
*/
|
||||
List<WidgetMimeTypeHandlerData> resolveWidgetsForMimeType(Context context, String mimeType) {
|
||||
final PackageManager packageManager = context.getPackageManager();
|
||||
final List<WidgetMimeTypeHandlerData> supportedConfigurationActivities =
|
||||
new ArrayList<WidgetMimeTypeHandlerData>();
|
||||
|
||||
final Intent supportsIntent =
|
||||
new Intent(InstallWidgetReceiver.ACTION_SUPPORTS_CLIPDATA_MIMETYPE);
|
||||
supportsIntent.setType(mimeType);
|
||||
|
||||
// Create a set of widget configuration components that we can test against
|
||||
final List<AppWidgetProviderInfo> widgets =
|
||||
AppWidgetManager.getInstance(context).getInstalledProviders();
|
||||
final HashMap<ComponentName, AppWidgetProviderInfo> configurationComponentToWidget =
|
||||
new HashMap<ComponentName, AppWidgetProviderInfo>();
|
||||
for (AppWidgetProviderInfo info : widgets) {
|
||||
configurationComponentToWidget.put(info.configure, info);
|
||||
}
|
||||
|
||||
// Run through each of the intents that can handle this type of clip data, and cross
|
||||
// reference them with the components that are actual configuration components
|
||||
final List<ResolveInfo> activities = packageManager.queryIntentActivities(supportsIntent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
for (ResolveInfo info : activities) {
|
||||
final ActivityInfo activityInfo = info.activityInfo;
|
||||
final ComponentName infoComponent = new ComponentName(activityInfo.packageName,
|
||||
activityInfo.name);
|
||||
if (configurationComponentToWidget.containsKey(infoComponent)) {
|
||||
supportedConfigurationActivities.add(
|
||||
new InstallWidgetReceiver.WidgetMimeTypeHandlerData(info,
|
||||
configurationComponentToWidget.get(infoComponent)));
|
||||
}
|
||||
}
|
||||
return supportedConfigurationActivities;
|
||||
}
|
||||
|
||||
ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
|
||||
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
|
||||
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ComponentName;
|
||||
import android.os.Parcelable;
|
||||
|
||||
@@ -35,5 +36,17 @@ class PendingAddWidgetInfo extends PendingAddItemInfo {
|
||||
|
||||
// Any configuration data that we want to pass to a configuration activity when
|
||||
// starting up a widget
|
||||
String mimeType;
|
||||
Parcelable configurationData;
|
||||
|
||||
public PendingAddWidgetInfo(AppWidgetProviderInfo i, String dataMimeType, Parcelable data) {
|
||||
itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
|
||||
componentName = i.provider;
|
||||
minWidth = i.minWidth;
|
||||
minHeight = i.minHeight;
|
||||
if (dataMimeType != null && data != null) {
|
||||
mimeType = dataMimeType;
|
||||
configurationData = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,20 @@
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.launcher.R;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.animation.Animator.AnimatorListener;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.WallpaperManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
@@ -59,8 +62,8 @@ import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import com.android.launcher.R;
|
||||
import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
|
||||
|
||||
/**
|
||||
* The workspace is a wide area with a wallpaper and a finite number of pages.
|
||||
@@ -602,6 +605,30 @@ public class Workspace extends SmoothPagedView
|
||||
} else {
|
||||
super.dispatchDraw(canvas);
|
||||
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
|
||||
// In portrait orientation, draw the glowing edge when dragging to adjacent screens
|
||||
if (mInScrollArea && (height > width)) {
|
||||
final int pageHeight = getChildAt(0).getHeight();
|
||||
|
||||
// This determines the height of the glowing edge: 90% of the page height
|
||||
final int padding = (int) ((height - pageHeight) * 0.5f + pageHeight * 0.1f);
|
||||
|
||||
final CellLayout leftPage = (CellLayout) getChildAt(mCurrentPage - 1);
|
||||
final CellLayout rightPage = (CellLayout) getChildAt(mCurrentPage + 1);
|
||||
|
||||
if (leftPage != null && leftPage.getHover()) {
|
||||
final Drawable d = getResources().getDrawable(R.drawable.page_hover_left);
|
||||
d.setBounds(mScrollX, padding, mScrollX + d.getIntrinsicWidth(), height - padding);
|
||||
d.draw(canvas);
|
||||
} else if (rightPage != null && rightPage.getHover()) {
|
||||
final Drawable d = getResources().getDrawable(R.drawable.page_hover_right);
|
||||
d.setBounds(mScrollX + width - d.getIntrinsicWidth(), padding, mScrollX + width, height - padding);
|
||||
d.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
if (mDropView != null) {
|
||||
// We are animating an item that was just dropped on the home screen.
|
||||
// Render its View in the current animation position.
|
||||
@@ -1371,6 +1398,7 @@ public class Workspace extends SmoothPagedView
|
||||
*/
|
||||
@Override
|
||||
public boolean onDragEvent(DragEvent event) {
|
||||
final ClipDescription desc = event.getClipDescription();
|
||||
final CellLayout layout = (CellLayout) getChildAt(mCurrentPage);
|
||||
final int[] pos = new int[2];
|
||||
layout.getLocationOnScreen(pos);
|
||||
@@ -1387,23 +1415,19 @@ public class Workspace extends SmoothPagedView
|
||||
return false;
|
||||
}
|
||||
|
||||
ClipDescription desc = event.getClipDescription();
|
||||
if (desc.filterMimeTypes(ClipDescription.MIMETYPE_TEXT_INTENT) != null) {
|
||||
// Create the drag outline
|
||||
// We need to add extra padding to the bitmap to make room for the glow effect
|
||||
final Canvas canvas = new Canvas();
|
||||
final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS;
|
||||
mDragOutline = createExternalDragOutline(canvas, bitmapPadding);
|
||||
// Create the drag outline
|
||||
// We need to add extra padding to the bitmap to make room for the glow effect
|
||||
final Canvas canvas = new Canvas();
|
||||
final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS;
|
||||
mDragOutline = createExternalDragOutline(canvas, bitmapPadding);
|
||||
|
||||
// Show the current page outlines to indicate that we can accept this drop
|
||||
showOutlines();
|
||||
layout.setHover(true);
|
||||
layout.onDragEnter();
|
||||
layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
|
||||
// Show the current page outlines to indicate that we can accept this drop
|
||||
showOutlines();
|
||||
layout.setHover(true);
|
||||
layout.onDragEnter();
|
||||
layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
return true;
|
||||
case DragEvent.ACTION_DRAG_LOCATION:
|
||||
// Visualize the drop location
|
||||
layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
|
||||
@@ -1420,39 +1444,58 @@ public class Workspace extends SmoothPagedView
|
||||
int newDropCount = 0;
|
||||
final LauncherModel model = mLauncher.getModel();
|
||||
final ClipData data = event.getClipData();
|
||||
final int itemCount = data.getItemCount();
|
||||
for (int i = 0; i < itemCount; ++i) {
|
||||
final Intent intent = data.getItem(i).getIntent();
|
||||
if (intent != null) {
|
||||
Object info = null;
|
||||
if (model.validateShortcutIntent(intent)) {
|
||||
info = model.infoFromShortcutIntent(mContext, intent, data.getIcon());
|
||||
} else if (model.validateWidgetIntent(intent)) {
|
||||
final ComponentName component = ComponentName.unflattenFromString(
|
||||
intent.getStringExtra(InstallWidgetReceiver.EXTRA_APPWIDGET_COMPONENT));
|
||||
final AppWidgetProviderInfo appInfo =
|
||||
model.findAppWidgetProviderInfoWithComponent(mContext, component);
|
||||
|
||||
PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo();
|
||||
createInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
|
||||
createInfo.componentName = appInfo.provider;
|
||||
createInfo.minWidth = appInfo.minWidth;
|
||||
createInfo.minHeight = appInfo.minHeight;
|
||||
createInfo.configurationData = intent.getParcelableExtra(
|
||||
InstallWidgetReceiver.EXTRA_APPWIDGET_CONFIGURATION_DATA);
|
||||
info = createInfo;
|
||||
}
|
||||
// We assume that the mime types are ordered in descending importance of
|
||||
// representation. So we enumerate the list of mime types and alert the
|
||||
// user if any widgets can handle the drop. Only the most preferred
|
||||
// representation will be handled.
|
||||
pos[0] = x;
|
||||
pos[1] = y;
|
||||
final int mimeTypeCount = desc.getMimeTypeCount();
|
||||
for (int j = 0; j < mimeTypeCount; ++j) {
|
||||
final String mimeType = desc.getMimeType(j);
|
||||
|
||||
if (info != null) {
|
||||
onDropExternal(x, y, info, layout);
|
||||
newDropCount++;
|
||||
if (mimeType.equals(InstallShortcutReceiver.SHORTCUT_MIMETYPE)) {
|
||||
final Intent intent = data.getItem(j).getIntent();
|
||||
Object info = model.infoFromShortcutIntent(mContext, intent, data.getIcon());
|
||||
onDropExternal(x, y, info, layout);
|
||||
} else {
|
||||
final List<WidgetMimeTypeHandlerData> widgets =
|
||||
model.resolveWidgetsForMimeType(mContext, mimeType);
|
||||
final int numWidgets = widgets.size();
|
||||
|
||||
if (numWidgets == 0) {
|
||||
continue;
|
||||
} else if (numWidgets == 1) {
|
||||
// If there is only one item, then go ahead and add and configure
|
||||
// that widget
|
||||
final AppWidgetProviderInfo widgetInfo = widgets.get(0).widgetInfo;
|
||||
final PendingAddWidgetInfo createInfo =
|
||||
new PendingAddWidgetInfo(widgetInfo, mimeType, data);
|
||||
mLauncher.addAppWidgetFromDrop(createInfo, mCurrentPage, pos);
|
||||
} else if (numWidgets > 1) {
|
||||
// Show the widget picker dialog if there is more than one widget
|
||||
// that can handle this data type
|
||||
final InstallWidgetReceiver.WidgetListAdapter adapter =
|
||||
new InstallWidgetReceiver.WidgetListAdapter(mLauncher, mimeType,
|
||||
data, widgets, layout, mCurrentPage, pos);
|
||||
final AlertDialog.Builder builder =
|
||||
new AlertDialog.Builder(mContext);
|
||||
builder.setAdapter(adapter, adapter);
|
||||
builder.setCancelable(true);
|
||||
builder.setTitle(mContext.getString(
|
||||
R.string.external_drop_widget_pick_title));
|
||||
builder.setIcon(R.drawable.ic_no_applications);
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
newDropCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
// Show error message if we couldn't accept any of the items
|
||||
if (newDropCount <= 0) {
|
||||
Toast.makeText(mContext, "Only Shortcut Intents accepted.",
|
||||
Toast.makeText(mContext, mContext.getString(R.string.external_drop_widget_error),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@@ -1890,11 +1933,11 @@ public class Workspace extends SmoothPagedView
|
||||
final int screen = getCurrentPage() + ((direction == DragController.SCROLL_LEFT) ? -1 : 1);
|
||||
if (0 <= screen && screen < getChildCount()) {
|
||||
((CellLayout) getChildAt(screen)).setHover(true);
|
||||
}
|
||||
|
||||
if (mDragTargetLayout != null) {
|
||||
mDragTargetLayout.onDragExit();
|
||||
mDragTargetLayout = null;
|
||||
if (mDragTargetLayout != null) {
|
||||
mDragTargetLayout.onDragExit();
|
||||
mDragTargetLayout = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user