First cut at new home screen customization for xlarge displays.
- Add new layout for xlarge, removing hotseat, next/prev page, etc. - Add a "+" button in top right which switches to customization mode - Add a widget chooser which slides up from bottom of screen - Initial support for dragging widgets onto home screen Change-Id: I14e2e013ccceff4066fcb7c4492b4f6bef6595e7
This commit is contained in:
parent
ff68ed0595
commit
af44209bfa
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 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.
|
||||
-->
|
||||
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:fromXDelta="0%p"
|
||||
android:toXDelta="0%p"
|
||||
android:fromYDelta="100%p"
|
||||
android:toYDelta="0%p"
|
||||
|
||||
android:duration="500"
|
||||
android:fillAfter="true" />
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2007 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.
|
||||
-->
|
||||
|
||||
<com.android.launcher2.DragLayer
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
|
||||
|
||||
android:id="@+id/drag_layer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/all_apps" />
|
||||
|
||||
<!-- The workspace contains 5 screens of cells -->
|
||||
<com.android.launcher2.Workspace
|
||||
android:id="@+id/workspace"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
launcher:defaultScreen="2">
|
||||
|
||||
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
|
||||
|
||||
</com.android.launcher2.Workspace>
|
||||
|
||||
<com.android.launcher2.DeleteZone
|
||||
android:id="@+id/delete_zone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/delete_zone_padding"
|
||||
android:layout_gravity="top|right"
|
||||
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/delete_zone_selector"
|
||||
android:visibility="gone"
|
||||
launcher:direction="horizontal"
|
||||
/>
|
||||
<ImageView
|
||||
android:id="@+id/add_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/delete_zone_padding"
|
||||
android:layout_gravity="top|right"
|
||||
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/add_button"
|
||||
|
||||
android:onClick="onClickAddButton"
|
||||
android:focusable="true"
|
||||
android:clickable="true" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/all_apps_button_cluster"
|
||||
android:layout_width="@dimen/button_bar_height"
|
||||
android:layout_height="@dimen/button_bar_height"
|
||||
android:layout_gravity="top|left"
|
||||
android:paddingTop="2dip"
|
||||
>
|
||||
<com.android.launcher2.HandleView
|
||||
style="@style/HotseatButton"
|
||||
android:id="@+id/all_apps_button"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
|
||||
android:src="@drawable/all_apps_button"
|
||||
launcher:direction="horizontal"
|
||||
/>
|
||||
</RelativeLayout>
|
||||
<com.android.launcher2.WidgetChooser
|
||||
android:id="@+id/widget_chooser"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dip"
|
||||
android:layout_gravity="bottom"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</com.android.launcher2.DragLayer>
|
|
@ -0,0 +1,22 @@
|
|||
<?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.
|
||||
-->
|
||||
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="?android:attr/galleryItemBackground"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="fitXY"
|
||||
android:focusable="true" />
|
|
@ -158,67 +158,72 @@ public class CellLayout extends ViewGroup {
|
|||
mCellInfo.screen = ((ViewGroup) getParent()).indexOfChild(this);
|
||||
}
|
||||
|
||||
public void setTagToCellInfoForPoint(int touchX, int touchY) {
|
||||
final CellInfo cellInfo = mCellInfo;
|
||||
final Rect frame = mRect;
|
||||
final int x = touchX + mScrollX;
|
||||
final int y = touchY + mScrollY;
|
||||
final int count = getChildCount();
|
||||
|
||||
boolean found = false;
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
final View child = getChildAt(i);
|
||||
|
||||
if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) {
|
||||
child.getHitRect(frame);
|
||||
if (frame.contains(x, y)) {
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
cellInfo.cell = child;
|
||||
cellInfo.cellX = lp.cellX;
|
||||
cellInfo.cellY = lp.cellY;
|
||||
cellInfo.spanX = lp.cellHSpan;
|
||||
cellInfo.spanY = lp.cellVSpan;
|
||||
cellInfo.valid = true;
|
||||
found = true;
|
||||
mDirtyTag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLastDownOnOccupiedCell = found;
|
||||
|
||||
if (!found) {
|
||||
int cellXY[] = mCellXY;
|
||||
pointToCellExact(x, y, cellXY);
|
||||
|
||||
final boolean portrait = mPortrait;
|
||||
final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
|
||||
final boolean[][] occupied = mOccupied;
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
cellInfo.cell = null;
|
||||
cellInfo.cellX = cellXY[0];
|
||||
cellInfo.cellY = cellXY[1];
|
||||
cellInfo.spanX = 1;
|
||||
cellInfo.spanY = 1;
|
||||
cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
|
||||
cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
|
||||
|
||||
// Instead of finding the interesting vacant cells here, wait until a
|
||||
// caller invokes getTag() to retrieve the result. Finding the vacant
|
||||
// cells is a bit expensive and can generate many new objects, it's
|
||||
// therefore better to defer it until we know we actually need it.
|
||||
|
||||
mDirtyTag = true;
|
||||
}
|
||||
setTag(cellInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
final int action = ev.getAction();
|
||||
final CellInfo cellInfo = mCellInfo;
|
||||
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
final Rect frame = mRect;
|
||||
final int x = (int) ev.getX() + mScrollX;
|
||||
final int y = (int) ev.getY() + mScrollY;
|
||||
final int count = getChildCount();
|
||||
|
||||
boolean found = false;
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
final View child = getChildAt(i);
|
||||
|
||||
if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) {
|
||||
child.getHitRect(frame);
|
||||
if (frame.contains(x, y)) {
|
||||
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
cellInfo.cell = child;
|
||||
cellInfo.cellX = lp.cellX;
|
||||
cellInfo.cellY = lp.cellY;
|
||||
cellInfo.spanX = lp.cellHSpan;
|
||||
cellInfo.spanY = lp.cellVSpan;
|
||||
cellInfo.valid = true;
|
||||
found = true;
|
||||
mDirtyTag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLastDownOnOccupiedCell = found;
|
||||
|
||||
if (!found) {
|
||||
int cellXY[] = mCellXY;
|
||||
pointToCellExact(x, y, cellXY);
|
||||
|
||||
final boolean portrait = mPortrait;
|
||||
final int xCount = portrait ? mShortAxisCells : mLongAxisCells;
|
||||
final int yCount = portrait ? mLongAxisCells : mShortAxisCells;
|
||||
|
||||
final boolean[][] occupied = mOccupied;
|
||||
findOccupiedCells(xCount, yCount, occupied, null);
|
||||
|
||||
cellInfo.cell = null;
|
||||
cellInfo.cellX = cellXY[0];
|
||||
cellInfo.cellY = cellXY[1];
|
||||
cellInfo.spanX = 1;
|
||||
cellInfo.spanY = 1;
|
||||
cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount &&
|
||||
cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]];
|
||||
|
||||
// Instead of finding the interesting vacant cells here, wait until a
|
||||
// caller invokes getTag() to retrieve the result. Finding the vacant
|
||||
// cells is a bit expensive and can generate many new objects, it's
|
||||
// therefore better to defer it until we know we actually need it.
|
||||
|
||||
mDirtyTag = true;
|
||||
}
|
||||
setTag(cellInfo);
|
||||
setTagToCellInfoForPoint((int) ev.getX(), (int) ev.getY());
|
||||
} else if (action == MotionEvent.ACTION_UP) {
|
||||
cellInfo.cell = null;
|
||||
cellInfo.cellX = -1;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.launcher2;
|
||||
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
|
@ -24,6 +25,8 @@ import android.app.Dialog;
|
|||
import android.app.SearchManager;
|
||||
import android.app.StatusBarManager;
|
||||
import android.app.WallpaperManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
|
@ -31,9 +34,8 @@ import android.content.ContentResolver;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -41,10 +43,10 @@ import android.content.res.Resources;
|
|||
import android.content.res.TypedArray;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
@ -66,25 +68,22 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.LinearLayout;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.DataInputStream;
|
||||
|
||||
import com.android.launcher.R;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
|
@ -182,6 +181,7 @@ public final class Launcher extends Activity
|
|||
private DeleteZone mDeleteZone;
|
||||
private HandleView mHandleView;
|
||||
private AllAppsView mAllAppsGrid;
|
||||
private WidgetChooser mWidgetChooser;
|
||||
|
||||
private Bundle mSavedState;
|
||||
|
||||
|
@ -536,10 +536,13 @@ public final class Launcher extends Activity
|
|||
completeAddLiveFolder(data, mAddItemCellInfo);
|
||||
break;
|
||||
case REQUEST_PICK_APPWIDGET:
|
||||
addAppWidget(data);
|
||||
addAppWidgetFromPick(data);
|
||||
break;
|
||||
case REQUEST_CREATE_APPWIDGET:
|
||||
completeAddAppWidget(data, mAddItemCellInfo);
|
||||
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
|
||||
// TODO: Is this log message meaningful?
|
||||
if (LOGD) Log.d(TAG, "dumping extras content=" + data.getExtras());
|
||||
completeAddAppWidget(appWidgetId, mAddItemCellInfo);
|
||||
break;
|
||||
case REQUEST_PICK_WALLPAPER:
|
||||
// We just wanted the activity result here so we can clear mWaitingForResult
|
||||
|
@ -572,8 +575,11 @@ public final class Launcher extends Activity
|
|||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
dismissPreview(mPreviousView);
|
||||
dismissPreview(mNextView);
|
||||
// Some launcher layouts don't have a previous and next view
|
||||
if (mPreviousView != null) {
|
||||
dismissPreview(mPreviousView);
|
||||
dismissPreview(mNextView);
|
||||
}
|
||||
mDragController.cancelDrag();
|
||||
}
|
||||
|
||||
|
@ -720,24 +726,30 @@ public final class Launcher extends Activity
|
|||
mHandleView.setOnClickListener(this);
|
||||
mHandleView.setOnLongClickListener(this);
|
||||
|
||||
ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left);
|
||||
hotseatLeft.setContentDescription(mHotseatLabels[0]);
|
||||
hotseatLeft.setImageDrawable(mHotseatIcons[0]);
|
||||
ImageView hotseatRight = (ImageView) findViewById(R.id.hotseat_right);
|
||||
hotseatRight.setContentDescription(mHotseatLabels[1]);
|
||||
hotseatRight.setImageDrawable(mHotseatIcons[1]);
|
||||
mWidgetChooser = (WidgetChooser) findViewById(R.id.widget_chooser);
|
||||
if (mWidgetChooser != null) {
|
||||
mWidgetChooser.setDragController(dragController);
|
||||
mWidgetChooser.setLauncher(this);
|
||||
} else {
|
||||
ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left);
|
||||
hotseatLeft.setContentDescription(mHotseatLabels[0]);
|
||||
hotseatLeft.setImageDrawable(mHotseatIcons[0]);
|
||||
ImageView hotseatRight = (ImageView) findViewById(R.id.hotseat_right);
|
||||
hotseatRight.setContentDescription(mHotseatLabels[1]);
|
||||
hotseatRight.setImageDrawable(mHotseatIcons[1]);
|
||||
|
||||
mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
|
||||
mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
|
||||
mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
|
||||
mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
|
||||
|
||||
Drawable previous = mPreviousView.getDrawable();
|
||||
Drawable next = mNextView.getDrawable();
|
||||
mWorkspace.setIndicators(previous, next);
|
||||
Drawable previous = mPreviousView.getDrawable();
|
||||
Drawable next = mNextView.getDrawable();
|
||||
mWorkspace.setIndicators(previous, next);
|
||||
|
||||
mPreviousView.setHapticFeedbackEnabled(false);
|
||||
mPreviousView.setOnLongClickListener(this);
|
||||
mNextView.setHapticFeedbackEnabled(false);
|
||||
mNextView.setOnLongClickListener(this);
|
||||
mPreviousView.setHapticFeedbackEnabled(false);
|
||||
mPreviousView.setOnLongClickListener(this);
|
||||
mNextView.setHapticFeedbackEnabled(false);
|
||||
mNextView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
workspace.setOnLongClickListener(this);
|
||||
workspace.setDragController(dragController);
|
||||
|
@ -745,7 +757,8 @@ public final class Launcher extends Activity
|
|||
|
||||
deleteZone.setLauncher(this);
|
||||
deleteZone.setDragController(dragController);
|
||||
deleteZone.setHandle(findViewById(R.id.all_apps_button_cluster));
|
||||
int deleteZoneHandleId = isScreenXLarge() ? R.id.add_button : R.id.all_apps_button_cluster;
|
||||
deleteZone.setHandle(findViewById(deleteZoneHandleId));
|
||||
|
||||
dragController.setDragScoller(workspace);
|
||||
dragController.setDragListener(deleteZone);
|
||||
|
@ -876,12 +889,7 @@ public final class Launcher extends Activity
|
|||
* @param data The intent describing the appWidgetId.
|
||||
* @param cellInfo The position on screen where to create the widget.
|
||||
*/
|
||||
private void completeAddAppWidget(Intent data, CellLayout.CellInfo cellInfo) {
|
||||
Bundle extras = data.getExtras();
|
||||
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
|
||||
|
||||
if (LOGD) Log.d(TAG, "dumping extras content=" + extras.toString());
|
||||
|
||||
private void completeAddAppWidget(int appWidgetId, CellLayout.CellInfo cellInfo) {
|
||||
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
// Calculate the grid spans needed to fit this widget
|
||||
|
@ -1171,9 +1179,27 @@ public final class Launcher extends Activity
|
|||
showAddDialog(mMenuAddInfo);
|
||||
}
|
||||
|
||||
void addAppWidget(Intent data) {
|
||||
boolean isScreenXLarge() {
|
||||
int screenLayout = getResources().getConfiguration().screenLayout;
|
||||
return (screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
}
|
||||
|
||||
void addAppWidgetFromDrop(ComponentName appWidgetProvider, CellLayout.CellInfo cellInfo) {
|
||||
mAddItemCellInfo = cellInfo;
|
||||
int appWidgetId = getAppWidgetHost().allocateAppWidgetId();
|
||||
AppWidgetManager.getInstance(this).bindAppWidgetId(appWidgetId, appWidgetProvider);
|
||||
addAppWidgetImpl(appWidgetId);
|
||||
}
|
||||
|
||||
void addAppWidgetFromPick(Intent data) {
|
||||
// TODO: catch bad widget exception when sent
|
||||
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
|
||||
// TODO: Is this log message meaningful?
|
||||
if (LOGD) Log.d(TAG, "dumping extras content=" + data.getExtras());
|
||||
addAppWidgetImpl(appWidgetId);
|
||||
}
|
||||
|
||||
void addAppWidgetImpl(int appWidgetId) {
|
||||
AppWidgetProviderInfo appWidget = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
if (appWidget.configure != null) {
|
||||
|
@ -1185,7 +1211,7 @@ public final class Launcher extends Activity
|
|||
startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET);
|
||||
} else {
|
||||
// Otherwise just add it
|
||||
onActivityResult(REQUEST_CREATE_APPWIDGET, Activity.RESULT_OK, data);
|
||||
completeAddAppWidget(appWidgetId, mAddItemCellInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1389,8 +1415,11 @@ public final class Launcher extends Activity
|
|||
} else {
|
||||
closeFolder();
|
||||
}
|
||||
dismissPreview(mPreviousView);
|
||||
dismissPreview(mNextView);
|
||||
// Some launcher layouts don't have a previous and next view
|
||||
if (mPreviousView != null) {
|
||||
dismissPreview(mPreviousView);
|
||||
dismissPreview(mNextView);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeFolder() {
|
||||
|
@ -1456,6 +1485,24 @@ public final class Launcher extends Activity
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for the "plus" button that appears on the home screen, which
|
||||
* enters home screen customization mode.
|
||||
*
|
||||
* @param v The view that was clicked.
|
||||
*/
|
||||
public void onClickAddButton(View v) {
|
||||
View widgetChooser = findViewById(R.id.widget_chooser);
|
||||
widgetChooser.setVisibility(View.VISIBLE);
|
||||
|
||||
// Animate the widget chooser up from the bottom of the screen
|
||||
widgetChooser.startAnimation(AnimationUtils.loadAnimation(this, R.anim.widget_chooser_slide_up));
|
||||
}
|
||||
|
||||
public void onClickAllAppsButton(View w) {
|
||||
showAllApps(true);
|
||||
}
|
||||
|
||||
void startActivitySafely(Intent intent, Object tag) {
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
try {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.launcher2;
|
||||
|
||||
import android.appwidget.AppWidgetHostView;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
|
||||
/**
|
||||
|
@ -29,6 +30,7 @@ class LauncherAppWidgetInfo extends ItemInfo {
|
|||
* {@link android.appwidget.AppWidgetManager} for updates.
|
||||
*/
|
||||
int appWidgetId;
|
||||
ComponentName providerName;
|
||||
|
||||
/**
|
||||
* View that holds this widget after it's been created. This view isn't created
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.android.launcher2;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Gallery;
|
||||
|
||||
public class WidgetChooser extends Gallery
|
||||
implements Gallery.OnItemLongClickListener, DragSource {
|
||||
|
||||
Context mContext;
|
||||
|
||||
private Launcher mLauncher;
|
||||
private DragController mDragController;
|
||||
private WidgetGalleryAdapter mWidgetGalleryAdapter;
|
||||
|
||||
private int mMotionDownRawX;
|
||||
private int mMotionDownRawY;
|
||||
|
||||
public WidgetChooser(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setLongClickable(true);
|
||||
setOnItemLongClickListener(this);
|
||||
mContext = context;
|
||||
|
||||
setCallbackDuringFling(false);
|
||||
|
||||
mWidgetGalleryAdapter = new WidgetGalleryAdapter(context);
|
||||
setAdapter(mWidgetGalleryAdapter);
|
||||
}
|
||||
|
||||
public void onDropCompleted(View target, boolean success) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setDragController(DragController dragger) {
|
||||
mDragController = dragger;
|
||||
}
|
||||
|
||||
public void setLauncher(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
AppWidgetProviderInfo info = (AppWidgetProviderInfo)mWidgetGalleryAdapter.getItem(position);
|
||||
try {
|
||||
Resources r = mContext.getPackageManager().getResourcesForApplication(info.provider.getPackageName());
|
||||
|
||||
Bitmap bmp = BitmapFactory.decodeResource(r, info.icon);
|
||||
final int w = bmp.getWidth();
|
||||
final int h = bmp.getHeight();
|
||||
|
||||
// We don't really have an accurate location to use. This will do.
|
||||
int screenX = mMotionDownRawX - (w / 2);
|
||||
int screenY = mMotionDownRawY - h;
|
||||
|
||||
LauncherAppWidgetInfo dragInfo = new LauncherAppWidgetInfo(-1);
|
||||
dragInfo.providerName = info.provider;
|
||||
mDragController.startDrag(bmp, screenX, screenY,
|
||||
0, 0, w, h, this, dragInfo, DragController.DRAG_ACTION_COPY);
|
||||
return true;
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN && mLauncher.isAllAppsVisible()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
super.onTouchEvent(ev);
|
||||
|
||||
int x = (int) ev.getX();
|
||||
int y = (int) ev.getY();
|
||||
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mMotionDownRawX = (int) ev.getRawX();
|
||||
mMotionDownRawY = (int) ev.getRawY();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WidgetGalleryAdapter extends BaseAdapter {
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private PackageManager mPackageManager;
|
||||
private List<AppWidgetProviderInfo> mWidgets;
|
||||
|
||||
WidgetGalleryAdapter(Context context) {
|
||||
mLayoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
|
||||
mWidgets = widgetManager.getInstalledProviders();
|
||||
mPackageManager = context.getPackageManager();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mWidgets.size();
|
||||
}
|
||||
|
||||
public Object getItem(int position) {
|
||||
return mWidgets.get(position);
|
||||
}
|
||||
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ImageView imageView;
|
||||
|
||||
if (convertView == null) {
|
||||
imageView = (ImageView) mLayoutInflater.inflate(R.layout.widget_item, parent, false);
|
||||
} else {
|
||||
imageView = (ImageView) convertView;
|
||||
}
|
||||
|
||||
AppWidgetProviderInfo info = mWidgets.get(position);
|
||||
Drawable drawable = mPackageManager.getDrawable(info.provider.getPackageName(), info.icon, null);
|
||||
imageView.setImageDrawable(drawable);
|
||||
|
||||
return imageView;
|
||||
}
|
||||
}
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import com.android.launcher.R;
|
||||
|
||||
import android.app.WallpaperManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
|
@ -47,7 +46,8 @@ import android.view.animation.Interpolator;
|
|||
import android.widget.Scroller;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher.R;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* The workspace is a wide area with a wallpaper and a finite number of screens. Each
|
||||
|
@ -450,8 +450,10 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
postInvalidate();
|
||||
} else if (mNextScreen != INVALID_SCREEN) {
|
||||
mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
|
||||
mPreviousIndicator.setLevel(mCurrentScreen);
|
||||
mNextIndicator.setLevel(mCurrentScreen);
|
||||
if (mPreviousIndicator != null) {
|
||||
mPreviousIndicator.setLevel(mCurrentScreen);
|
||||
mNextIndicator.setLevel(mCurrentScreen);
|
||||
}
|
||||
Launcher.setScreen(mCurrentScreen);
|
||||
mNextScreen = INVALID_SCREEN;
|
||||
clearChildrenCache();
|
||||
|
@ -963,8 +965,10 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
mNextScreen = whichScreen;
|
||||
|
||||
if (mPreviousIndicator != null) {
|
||||
mPreviousIndicator.setLevel(mNextScreen);
|
||||
mNextIndicator.setLevel(mNextScreen);
|
||||
}
|
||||
|
||||
View focusedChild = getFocusedChild();
|
||||
if (focusedChild != null && whichScreen != mCurrentScreen &&
|
||||
|
@ -1098,7 +1102,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
// Drag from somewhere else
|
||||
ItemInfo info = (ItemInfo) dragInfo;
|
||||
|
||||
View view;
|
||||
View view = null;
|
||||
|
||||
switch (info.itemType) {
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||
|
@ -1113,23 +1117,31 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
|
||||
(ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info));
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
||||
cellLayout.setTagToCellInfoForPoint(x, y);
|
||||
mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, cellLayout.getTag());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown item type: " + info.itemType);
|
||||
}
|
||||
|
||||
cellLayout.addView(view, insertAtFirst ? 0 : -1);
|
||||
view.setHapticFeedbackEnabled(false);
|
||||
view.setOnLongClickListener(mLongClickListener);
|
||||
if (view instanceof DropTarget) {
|
||||
mDragController.addDropTarget((DropTarget) view);
|
||||
// addAppWidgetFromDrop already took care of attaching the widget view to the appropriate cell
|
||||
// TODO why aren't we calling addInScreen here?
|
||||
if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) {
|
||||
cellLayout.addView(view, insertAtFirst ? 0 : -1);
|
||||
view.setHapticFeedbackEnabled(false);
|
||||
view.setOnLongClickListener(mLongClickListener);
|
||||
if (view instanceof DropTarget) {
|
||||
mDragController.addDropTarget((DropTarget) view);
|
||||
}
|
||||
|
||||
mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(view, mTargetCell);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
|
||||
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
|
||||
}
|
||||
|
||||
mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(view, mTargetCell);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
|
||||
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue