merge in ics-release history after reset to master
diff --git a/res/drawable-large-hdpi/portal_ring_inner_holo.png b/res/drawable-large-hdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..1e89e78
--- /dev/null
+++ b/res/drawable-large-hdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-large-hdpi/portal_ring_outer_holo.png b/res/drawable-large-hdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..2757779
--- /dev/null
+++ b/res/drawable-large-hdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_container_holo.9.png b/res/drawable-large-mdpi/portal_container_holo.9.png
deleted file mode 100644
index 7eef5d7..0000000
--- a/res/drawable-large-mdpi/portal_container_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_ring_inner_holo.png b/res/drawable-large-mdpi/portal_ring_inner_holo.png
index c22224f..c787b01 100644
--- a/res/drawable-large-mdpi/portal_ring_inner_holo.png
+++ b/res/drawable-large-mdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-large-mdpi/portal_ring_outer_holo.png b/res/drawable-large-mdpi/portal_ring_outer_holo.png
index b94c948..1cac453 100644
--- a/res/drawable-large-mdpi/portal_ring_outer_holo.png
+++ b/res/drawable-large-mdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-large-xhdpi/portal_ring_inner_holo.png b/res/drawable-large-xhdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..f937012
--- /dev/null
+++ b/res/drawable-large-xhdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-large-xhdpi/portal_ring_outer_holo.png b/res/drawable-large-xhdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..f347061
--- /dev/null
+++ b/res/drawable-large-xhdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/layout-large/workspace.xml b/res/layout-large/workspace.xml
index abed5a8..327afaf 100644
--- a/res/layout-large/workspace.xml
+++ b/res/layout-large/workspace.xml
@@ -15,11 +15,11 @@
-->
<!-- The workspace contains 5 screens of cells -->
+
<com.android.launcher2.Workspace
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
- android:paddingTop="?android:attr/actionBarSize"
- android:paddingBottom="10dp"
+ android:paddingTop="@dimen/workspace_content_large_only_top_margin"
launcher:defaultScreen="2"
launcher:pageSpacing="@dimen/workspace_page_spacing">
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 2f8d995..8a5d4ae 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -51,6 +51,8 @@
android:id="@+id/workspace"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:paddingTop="@dimen/qsb_bar_height"
+ android:paddingBottom="@dimen/button_bar_height"
launcher:defaultScreen="2"
launcher:cellCountX="4"
launcher:cellCountY="4"
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index ede0d99..c7d30ce 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -17,9 +17,8 @@
<com.android.launcher2.CellLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ style="@style/WorkspaceScreen"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
android:paddingLeft="@dimen/workspace_left_padding"
android:paddingRight="@dimen/workspace_right_padding"
android:paddingTop="@dimen/workspace_top_padding"
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index c715bfb..b413c53 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -20,8 +20,11 @@
<dimen name="toolbar_button_horizontal_padding">10dip</dimen>
<!-- Workspace -->
- <dimen name="workspace_left_padding">@dimen/qsb_bar_height</dimen>
- <dimen name="workspace_right_padding">@dimen/button_bar_height</dimen>
+ <!-- Block spacing on each side of the screen -->
+ <dimen name="workspace_left_padding">12dp</dimen>
+ <dimen name="workspace_right_padding">12dp</dimen>
+ <!-- We need top/bottom padding for portals to look right, but
+ really only in spring loaded mode... -->
<dimen name="workspace_top_padding">0dp</dimen>
<dimen name="workspace_bottom_padding">0dp</dimen>
<dimen name="workspace_page_spacing">8dp</dimen>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index ea79a5a..437a511 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -18,6 +18,11 @@
-->
<resources>
+<!-- Workspace -->
+ <style name="WorkspaceScreen">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">match_parent</item>
+ </style>
<!-- Search Bar -->
<style name="SearchDropTargetBar">
<item name="android:orientation">vertical</item>
diff --git a/res/values-large-land/dimens.xml b/res/values-large-land/dimens.xml
index 12fc8b3..4358ff9 100644
--- a/res/values-large-land/dimens.xml
+++ b/res/values-large-land/dimens.xml
@@ -16,10 +16,11 @@
<resources>
<!-- Workspace -->
- <dimen name="workspace_left_padding">25dip</dimen>
- <dimen name="workspace_right_padding">25dip</dimen>
- <dimen name="workspace_top_padding">15dip</dimen>
- <dimen name="workspace_bottom_padding">15dip</dimen>
+ <dimen name="workspace_left_padding">24dip</dimen>
+ <dimen name="workspace_right_padding">24dip</dimen>
+ <!-- We need padding on the screens for portals to look right -->
+ <dimen name="workspace_top_padding">12dip</dimen>
+ <dimen name="workspace_bottom_padding">12dip</dimen>
<dimen name="workspace_width_gap">32dp</dimen>
<dimen name="workspace_height_gap">2dp</dimen>
<dimen name="workspace_page_spacing">50dp</dimen>
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index a0fc814..234fcdb 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -21,9 +21,13 @@
<!-- Workspace -->
<dimen name="qsb_bar_height">56dp</dimen>
-
+ <!-- This should be @dimen/qsb_bar_height - @dimen/workspace_top_padding
+ to fix the extra space given to draw portals -->
+ <dimen name="workspace_content_large_only_top_margin">36dp</dimen>
<dimen name="workspace_cell_width">96dip</dimen>
<dimen name="workspace_cell_height">96dip</dimen>
+ <dimen name="folder_cell_width">96dp</dimen>
+ <dimen name="folder_cell_height">96dp</dimen>
<!-- AppsCustomize -->
<dimen name="apps_customize_tab_bar_height">56dp</dimen>
diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml
index 2d27321..9add357 100644
--- a/res/values-port/dimens.xml
+++ b/res/values-port/dimens.xml
@@ -18,10 +18,10 @@
<!-- Workspace -->
<dimen name="workspace_left_padding">0dp</dimen>
<dimen name="workspace_right_padding">0dp</dimen>
- <!-- We use the qsb_bar_height (48dp) + 12dp extra padding -->
- <dimen name="workspace_top_padding">60dp</dimen>
- <!-- We use the button_bar_height (80dp) + 12dp extra padding -->
- <dimen name="workspace_bottom_padding">96dp</dimen>
+ <!-- Block spacing on each side of the screen. And also padding
+ for the portals to look right. -->
+ <dimen name="workspace_top_padding">12dp</dimen>
+ <dimen name="workspace_bottom_padding">12dp</dimen>
<dimen name="workspace_page_spacing">8dp</dimen>
<integer name="apps_customize_cellCountX">4</integer>
diff --git a/res/values-port/styles.xml b/res/values-port/styles.xml
new file mode 100644
index 0000000..66a4ca7
--- /dev/null
+++ b/res/values-port/styles.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2011 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.
+*/
+-->
+
+<resources>
+<!-- Workspace -->
+ <style name="WorkspaceScreen">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_height">wrap_content</item>
+ </style>
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 309bf6d..cb354b4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -21,7 +21,7 @@
<dimen name="workspace_cell_height">80dp</dimen>
<dimen name="workspace_width_gap">-1dp</dimen>
<dimen name="workspace_height_gap">-1dp</dimen>
- <dimen name="workspace_max_gap">8dp</dimen>
+ <dimen name="workspace_max_gap">16dp</dimen>
<dimen name="folder_cell_width">74dp</dimen>
<dimen name="folder_cell_height">80dp</dimen>
<dimen name="workspace_divider_padding_left">12dp</dimen>
diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml
index 0e96a67..d509490 100644
--- a/res/xml/default_workspace.xml
+++ b/res/xml/default_workspace.xml
@@ -61,5 +61,4 @@
launcher:screen="3"
launcher:x="3"
launcher:y="0" />
-
</favorites>
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index d07b321..cb60034 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -39,6 +39,7 @@
import android.os.Process;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -943,10 +944,11 @@
int ix = i % cellCountX;
int iy = i / cellCountX;
GridLayout.LayoutParams lp = new GridLayout.LayoutParams(
- GridLayout.spec(iy, GridLayout.LEFT, GridLayout.CAN_STRETCH),
- GridLayout.spec(ix, GridLayout.TOP, GridLayout.CAN_STRETCH));
+ GridLayout.spec(iy, GridLayout.LEFT),
+ GridLayout.spec(ix, GridLayout.TOP));
lp.width = cellWidth;
lp.height = cellHeight;
+ lp.setGravity(Gravity.TOP | Gravity.LEFT);
if (ix > 0) lp.leftMargin = mWidgetWidthGap;
if (iy > 0) lp.topMargin = mWidgetHeightGap;
layout.addView(widget, lp);
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index c2d1341..b6bc5dc 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -183,7 +183,9 @@
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(android.animation.Animator animation) {
- mAppsCustomizePane.flashScrollingIndicator();
+ if (!LauncherApplication.isScreenLarge()) {
+ mAppsCustomizePane.flashScrollingIndicator();
+ }
}
});
anim.start();
@@ -250,7 +252,7 @@
setLayerType(LAYER_TYPE_NONE, null);
}
- if (!toWorkspace) {
+ if (!toWorkspace && !LauncherApplication.isScreenLarge()) {
mAppsCustomizePane.flashScrollingIndicator();
}
}
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 518c79f..9440b89 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -906,11 +906,6 @@
int vFreeSpace = vSpace - (mCountY * mOriginalCellHeight);
mWidthGap = Math.min(mMaxGap, numWidthGaps > 0 ? (hFreeSpace / numWidthGaps) : 0);
mHeightGap = Math.min(mMaxGap,numHeightGaps > 0 ? (vFreeSpace / numHeightGaps) : 0);
- int remainingHSpace = hFreeSpace - (numWidthGaps * mWidthGap);
- int remainingVSpace = vFreeSpace - (numHeightGaps * mHeightGap);
- mCellWidth = mOriginalCellWidth + remainingHSpace / mCountX;
- mCellHeight = mOriginalCellHeight + remainingVSpace / mCountY;
-
mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
} else {
mWidthGap = mOriginalWidthGap;
diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
index 3783d56..f97492b 100644
--- a/src/com/android/launcher2/FocusHelper.java
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -139,6 +139,9 @@
final int action = e.getAction();
final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
PagedViewGridLayout newParent = null;
+ // Now that we load items in the bg asynchronously, we can't just focus
+ // child siblings willy-nilly
+ View child = null;
boolean wasHandled = false;
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
@@ -150,7 +153,8 @@
if (pageIndex > 0) {
newParent = (PagedViewGridLayout)
container.getChildAt(pageIndex - 1);
- newParent.getChildAt(newParent.getChildCount() - 1).requestFocus();
+ child = newParent.getChildAt(newParent.getChildCount() - 1);
+ if (child != null) child.requestFocus();
}
}
}
@@ -165,7 +169,8 @@
if (pageIndex < (pageCount - 1)) {
newParent = (PagedViewGridLayout)
container.getChildAt(pageIndex + 1);
- newParent.getChildAt(0).requestFocus();
+ child = newParent.getChildAt(0);
+ if (child != null) child.requestFocus();
}
}
}
@@ -176,7 +181,8 @@
// Select the closest icon in the previous row, otherwise select the tab bar
if (y > 0) {
int newWidgetIndex = ((y - 1) * cellCountX) + x;
- parent.getChildAt(newWidgetIndex).requestFocus();
+ child = parent.getChildAt(newWidgetIndex);
+ if (child != null) child.requestFocus();
} else {
tabs.requestFocus();
}
@@ -188,7 +194,8 @@
// Select the closest icon in the previous row, otherwise do nothing
if (y < (cellCountY - 1)) {
int newWidgetIndex = Math.min(widgetCount - 1, ((y + 1) * cellCountX) + x);
- parent.getChildAt(newWidgetIndex).requestFocus();
+ child = parent.getChildAt(newWidgetIndex);
+ if (child != null) child.requestFocus();
}
}
wasHandled = true;
@@ -208,10 +215,11 @@
// if there is no previous page
if (pageIndex > 0) {
newParent = (PagedViewGridLayout) container.getChildAt(pageIndex - 1);
- newParent.getChildAt(0).requestFocus();
+ child = newParent.getChildAt(0);
} else {
- parent.getChildAt(0).requestFocus();
+ child = parent.getChildAt(0);
}
+ if (child != null) child.requestFocus();
}
wasHandled = true;
break;
@@ -221,17 +229,19 @@
// if there is no next page
if (pageIndex < (pageCount - 1)) {
newParent = (PagedViewGridLayout) container.getChildAt(pageIndex + 1);
- newParent.getChildAt(0).requestFocus();
+ child = newParent.getChildAt(0);
} else {
- parent.getChildAt(widgetCount - 1).requestFocus();
+ child = parent.getChildAt(widgetCount - 1);
}
+ if (child != null) child.requestFocus();
}
wasHandled = true;
break;
case KeyEvent.KEYCODE_MOVE_HOME:
if (handleKeyEvent) {
// Select the first item on this page
- parent.getChildAt(0).requestFocus();
+ child = parent.getChildAt(0);
+ if (child != null) child.requestFocus();
}
wasHandled = true;
break;
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index 014356b..780d0ed 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -100,6 +100,10 @@
private Rect mTempRect = new Rect();
private boolean mFirstOpen = true;
+ // Internal variable to track whether the folder was destroyed due to only a single
+ // item remaining
+ private boolean mDestroyed = false;
+
private boolean mIsEditingName = false;
private InputMethodManager mInputMethodManager;
@@ -514,7 +518,8 @@
// by another item. If it is, we need to find the next available slot and assign
// it that position. This is an issue when upgrading from the old Folders implementation
// which could contain an unlimited number of items.
- if (mContent.getChildAt(item.cellX, item.cellY) != null) {
+ if (mContent.getChildAt(item.cellX, item.cellY) != null ||
+ item.cellX < 0 || item.cellY < 0) {
if (!findAndSetEmptyCells(item)) {
return false;
}
@@ -658,17 +663,16 @@
mCurrentDragInfo = null;
mCurrentDragView = null;
mSuppressOnAdd = false;
+ if (target != this) {
+ mOnExitAlarm.cancelAlarm();
+ completeDragExit();
+ }
+
if (!success) {
- if (d.dragView != null) {
- if (target instanceof CellLayout) {
- // TODO: we should animate the item back to the folder in this case
- }
- }
- // TODO: if the drag fails, we need to re-add the item
- } else {
- if (target != this) {
- mOnExitAlarm.cancelAlarm();
- completeDragExit();
+ if (!mDestroyed) {
+ mFolderIcon.onDrop(d);
+ } else {
+ // TODO: if the folder was removed, recreate it
}
}
}
@@ -842,6 +846,7 @@
private void replaceFolderWithFinalItem() {
ItemInfo finalItem = null;
+ mDestroyed = true;
if (getItemCount() == 1) {
finalItem = mInfo.contents.get(0);
}
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 1cf558b..400c881 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -51,6 +51,7 @@
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -641,7 +642,6 @@
final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1);
final int pendingAddScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1);
-
if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) {
mPendingAddInfo.container = pendingAddContainer;
mPendingAddInfo.screen = pendingAddScreen;
@@ -2040,6 +2040,7 @@
// Shrink workspaces away if going to AppsCustomize from workspace
mWorkspace.shrink(Workspace.State.SMALL, animated);
+ hideHotseat(animated);
if (animated) {
final ValueAnimator scaleAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
@@ -2141,6 +2142,7 @@
if (!springLoaded) {
mWorkspace.unshrink(animated);
}
+ showHotseat(animated);
if (animated) {
if (mStateAnimation != null) mStateAnimation.cancel();
mStateAnimation = new AnimatorSet();
@@ -2297,7 +2299,6 @@
// Hide the search bar and hotseat
mSearchDeleteBar.hideSearchBar(animated);
- hideHotseat(animated);
// Change the state *after* we've called all the transition code
mState = State.APPS_CUSTOMIZE;
@@ -2357,7 +2358,6 @@
// Show the search bar and hotseat
mSearchDeleteBar.showSearchBar(animated);
- showHotseat(animated);
// Set focus to the AppsCustomize button
if (mAllAppsButton != null) {
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index 94163ac..9b24587 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -19,6 +19,7 @@
import android.app.Application;
import android.app.SearchManager;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
@@ -116,6 +117,11 @@
return sIsScreenLarge;
}
+ public static boolean isScreenLandscape(Context context) {
+ return context.getResources().getConfiguration().orientation ==
+ Configuration.ORIENTATION_LANDSCAPE;
+ }
+
public static float getScreenDensity() {
return sScreenDensity;
}
diff --git a/src/com/android/launcher2/LauncherProvider.java b/src/com/android/launcher2/LauncherProvider.java
index 96cc63c..6ca16de 100644
--- a/src/com/android/launcher2/LauncherProvider.java
+++ b/src/com/android/launcher2/LauncherProvider.java
@@ -20,46 +20,45 @@
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
-import android.content.ContentProvider;
-import android.content.Context;
-import android.content.ContentValues;
-import android.content.Intent;
import android.content.ComponentName;
-import android.content.ContentUris;
+import android.content.ContentProvider;
import android.content.ContentResolver;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.content.res.TypedArray;
-import android.content.pm.PackageManager;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.content.SharedPreferences;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteStatement;
-import android.database.sqlite.SQLiteQueryBuilder;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.database.sqlite.SQLiteStatement;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
-import android.util.AttributeSet;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.provider.Settings;
+
+import com.android.internal.util.XmlUtils;
+import com.android.launcher.R;
+import com.android.launcher2.LauncherSettings.Favorites;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.List;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParser;
-
-import com.android.internal.util.XmlUtils;
-import com.android.launcher2.LauncherSettings.Favorites;
-
-import com.android.launcher.R;
-
public class LauncherProvider extends ContentProvider {
private static final String TAG = "Launcher.LauncherProvider";
private static final boolean LOGD = false;
@@ -123,6 +122,12 @@
return db.insert(table, nullColumnHack, values);
}
+ private static void deleteId(SQLiteDatabase db, long id) {
+ Uri uri = LauncherSettings.Favorites.getContentUri(id, false);
+ SqlArguments args = new SqlArguments(uri, null, null);
+ db.delete(args.table, args.where, args.args);
+ }
+
@Override
public Uri insert(Uri uri, ContentValues initialValues) {
SqlArguments args = new SqlArguments(uri);
@@ -199,6 +204,7 @@
private static final String TAG_SEARCH = "search";
private static final String TAG_APPWIDGET = "appwidget";
private static final String TAG_SHORTCUT = "shortcut";
+ private static final String TAG_FOLDER = "folder";
private final Context mContext;
private final AppWidgetHost mAppWidgetHost;
@@ -741,10 +747,9 @@
values.put(LauncherSettings.Favorites.CELLX, x);
values.put(LauncherSettings.Favorites.CELLY, y);
- System.out.println("Adding item to container: " + container);
-
if (TAG_FAVORITE.equals(name)) {
- added = addAppShortcut(db, values, a, packageManager, intent);
+ long id = addAppShortcut(db, values, a, packageManager, intent);
+ added = id >= 0;
} else if (TAG_SEARCH.equals(name)) {
added = addSearchWidget(db, values);
} else if (TAG_CLOCK.equals(name)) {
@@ -752,12 +757,66 @@
} else if (TAG_APPWIDGET.equals(name)) {
added = addAppWidget(db, values, a, packageManager);
} else if (TAG_SHORTCUT.equals(name)) {
- added = addUriShortcut(db, values, a);
+ long id = addUriShortcut(db, values, a);
+ added = id >= 0;
+ } else if (TAG_FOLDER.equals(name)) {
+ String title;
+ int titleResId = a.getResourceId(R.styleable.Favorite_title, -1);
+ if (titleResId != -1) {
+ title = mContext.getResources().getString(titleResId);
+ } else {
+ title = mContext.getResources().getString(R.string.folder_name);
+ }
+ values.put(LauncherSettings.Favorites.TITLE, title);
+ long folderId = addFolder(db, values);
+ added = folderId >= 0;
+
+ ArrayList<Long> folderItems = new ArrayList<Long>();
+
+ int folderDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > folderDepth) {
+ if (type != XmlPullParser.START_TAG) {
+ continue;
+ }
+ final String folder_item_name = parser.getName();
+
+ TypedArray ar = mContext.obtainStyledAttributes(attrs,
+ R.styleable.Favorite);
+ values.clear();
+ values.put(LauncherSettings.Favorites.CONTAINER, folderId);
+
+ if (TAG_FAVORITE.equals(folder_item_name) && folderId >= 0) {
+ long id =
+ addAppShortcut(db, values, ar, packageManager, intent);
+ if (id >= 0) {
+ folderItems.add(id);
+ }
+ } else if (TAG_SHORTCUT.equals(folder_item_name) && folderId >= 0) {
+ long id = addUriShortcut(db, values, ar);
+ if (id >= 0) {
+ folderItems.add(id);
+ }
+ } else {
+ throw new RuntimeException("Folders can " +
+ "contain only shortcuts");
+ }
+ ar.recycle();
+ }
+ // We can only have folders with >= 2 items, so we need to remove the
+ // folder and clean up if less than 2 items were included, or some
+ // failed to add, and less than 2 were actually added
+ if (folderItems.size() < 2 && folderId >= 0) {
+ // We just delete the folder and any items that made it
+ deleteId(db, folderId);
+ if (folderItems.size() > 0) {
+ deleteId(db, folderItems.get(0));
+ }
+ added = false;
+ }
}
}
-
if (added) i++;
-
a.recycle();
}
} catch (XmlPullParserException e) {
@@ -771,9 +830,9 @@
return i;
}
- private boolean addAppShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
+ private long addAppShortcut(SQLiteDatabase db, ContentValues values, TypedArray a,
PackageManager packageManager, Intent intent) {
-
+ long id = -1;
ActivityInfo info;
String packageName = a.getString(R.styleable.Favorite_packageName);
String className = a.getString(R.styleable.Favorite_className);
@@ -788,7 +847,7 @@
cn = new ComponentName(packages[0], className);
info = packageManager.getActivityInfo(cn, 0);
}
-
+ id = generateNewId();
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
@@ -798,13 +857,27 @@
values.put(Favorites.SPANX, 1);
values.put(Favorites.SPANY, 1);
values.put(Favorites._ID, generateNewId());
- dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values);
+ if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
+ return -1;
+ }
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Unable to add favorite: " + packageName +
"/" + className, e);
- return false;
}
- return true;
+ return id;
+ }
+
+ private long addFolder(SQLiteDatabase db, ContentValues values) {
+ values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
+ values.put(Favorites.SPANX, 1);
+ values.put(Favorites.SPANY, 1);
+ long id = generateNewId();
+ values.put(Favorites._ID, id);
+ if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) <= 0) {
+ return -1;
+ } else {
+ return id;
+ }
}
private ComponentName getSearchWidgetProvider() {
@@ -843,7 +916,7 @@
"com.android.alarmclock.AnalogAppWidgetProvider");
return addAppWidget(db, values, cn, 2, 2);
}
-
+
private boolean addAppWidget(SQLiteDatabase db, ContentValues values, TypedArray a,
PackageManager packageManager) {
@@ -902,8 +975,8 @@
return allocatedAppWidgets;
}
-
- private boolean addUriShortcut(SQLiteDatabase db, ContentValues values,
+
+ private long addUriShortcut(SQLiteDatabase db, ContentValues values,
TypedArray a) {
Resources r = mContext.getResources();
@@ -917,14 +990,15 @@
intent = Intent.parseUri(uri, 0);
} catch (URISyntaxException e) {
Log.w(TAG, "Shortcut has malformed uri: " + uri);
- return false; // Oh well
+ return -1; // Oh well
}
if (iconResId == 0 || titleResId == 0) {
Log.w(TAG, "Shortcut is missing title or icon resource ID");
- return false;
+ return -1;
}
+ long id = generateNewId();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
values.put(Favorites.INTENT, intent.toUri(0));
values.put(Favorites.TITLE, r.getString(titleResId));
@@ -934,10 +1008,12 @@
values.put(Favorites.ICON_TYPE, Favorites.ICON_TYPE_RESOURCE);
values.put(Favorites.ICON_PACKAGE, mContext.getPackageName());
values.put(Favorites.ICON_RESOURCE, r.getResourceName(iconResId));
- values.put(Favorites._ID, generateNewId());
- dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values);
+ values.put(Favorites._ID, id);
- return true;
+ if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
+ return -1;
+ }
+ return id;
}
}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 292ccd7..48360fe 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -578,9 +578,9 @@
protected void updateAdjacentPagesAlpha() {
if (mFadeInAdjacentScreens) {
if (mDirtyPageAlpha || (mTouchState == TOUCH_STATE_SCROLLING) || !mScroller.isFinished()) {
- int screenWidth = getMeasuredWidth();
+ int screenWidth = getMeasuredWidth() - mPaddingLeft - mPaddingRight;
int halfScreenSize = screenWidth / 2;
- int screenCenter = mScrollX + halfScreenSize;
+ int screenCenter = mScrollX + halfScreenSize + mPaddingLeft;
final int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
View layout = (View) getChildAt(i);
@@ -1265,11 +1265,13 @@
}
protected int getRelativeChildOffset(int index) {
- return (getMeasuredWidth() - getChildWidth(index)) / 2;
+ int padding = mPaddingLeft + mPaddingRight;
+ return mPaddingLeft + (getMeasuredWidth() - padding - getChildWidth(index)) / 2;
}
-
protected int getScaledRelativeChildOffset(int index) {
- return (getMeasuredWidth() - getScaledMeasuredWidth(getChildAt(index))) / 2;
+ int padding = mPaddingLeft + mPaddingRight;
+ return mPaddingLeft + (getMeasuredWidth() - padding -
+ getScaledMeasuredWidth(getChildAt(index))) / 2;
}
protected int getChildOffset(int index) {
@@ -1762,7 +1764,7 @@
int numPages = getChildCount();
int pageWidth = getMeasuredWidth();
- int maxPageWidth = (numPages * getMeasuredWidth()) + ((numPages - 1) * mPageSpacing);
+ int maxPageWidth = (numPages * getChildWidth(0)) + ((numPages - 1) * mPageSpacing);
int trackWidth = pageWidth - mScrollIndicatorPaddingLeft - mScrollIndicatorPaddingRight;
int indicatorWidth = mScrollIndicator.getMeasuredWidth() -
mScrollIndicator.getPaddingLeft() - mScrollIndicator.getPaddingRight();
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 10b218a..ecc5483 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -261,7 +261,10 @@
setDataIsReady();
if (!LauncherApplication.isScreenLarge()) {
- mFadeInAdjacentScreens = false;
+ mCenterPagesVertically = false;
+ if (!LauncherApplication.isScreenLandscape(context)) {
+ mFadeInAdjacentScreens = false;
+ }
}
mWallpaperManager = WallpaperManager.getInstance(context);
@@ -1335,7 +1338,7 @@
}
// we use this to shrink the workspace for the all apps view and the customize view
- public void shrink(State shrinkState, boolean animated) {
+ public void shrink(final State shrinkState, boolean animated) {
if (mFirstLayout) {
// (mFirstLayout == "first layout has not happened yet")
// if we get a call to shrink() as part of our initialization (for example, if
@@ -1527,6 +1530,14 @@
cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
cl.setFastRotationY(a * mOldRotationYs[i] + b * mNewRotationYs[i]);
}
+
+ // Shrink the hotset the same amount we are shrinking the screens
+ if (shrinkState == State.SPRING_LOADED && mLauncher.getHotseat() != null) {
+ View hotseat = mLauncher.getHotseat().getLayout();
+ hotseat.fastInvalidate();
+ hotseat.setFastScaleX(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
+ hotseat.setFastScaleY(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
+ }
}
});
mAnimator.playTogether(animWithInterpolator);
@@ -1705,7 +1716,7 @@
mNewRotationYs = new float[childCount];
}
- void unshrink(boolean animated, boolean springLoaded) {
+ void unshrink(boolean animated, final boolean springLoaded) {
if (mFirstLayout) {
// (mFirstLayout == "first layout has not happened yet")
// cancel any pending shrinks that were set earlier
@@ -1742,18 +1753,22 @@
final CellLayout cl = (CellLayout)getChildAt(i);
float finalAlphaValue = 0f;
float rotation = 0f;
- if (LauncherApplication.isScreenLarge()) {
- finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
+ // Set the final alpha depending on whether we are fading side pages. On phone ui,
+ // we don't do any of the rotation, or the fading alpha in portrait. See the
+ // ctor and screenScrolled().
+ if (mFadeInAdjacentScreens) {
+ finalAlphaValue = (i == mCurrentPage) ? 1f : 0f;
+ } else {
+ finalAlphaValue = 1f;
+ }
+
+ if (LauncherApplication.isScreenLarge()) {
if (i < mCurrentPage) {
rotation = WORKSPACE_ROTATION;
} else if (i > mCurrentPage) {
rotation = -WORKSPACE_ROTATION;
}
- } else {
- // Don't hide the side panes on the phone if we don't also update the side pages
- // alpha. See screenScrolled().
- finalAlphaValue = 1f;
}
float finalAlphaMultiplierValue = 1f;
@@ -1864,6 +1879,14 @@
b * mNewBackgroundAlphaMultipliers[i]);
cl.setFastAlpha(a * mOldAlphas[i] + b * mNewAlphas[i]);
}
+
+ // Unshrink the hotset the same amount we are unshrinking the screens
+ if (mLauncher.getHotseat() != null) {
+ View hotseat = mLauncher.getHotseat().getLayout();
+ hotseat.fastInvalidate();
+ hotseat.setFastScaleX(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
+ hotseat.setFastScaleY(a * mOldScaleXs[0] + b * mNewScaleXs[0]);
+ }
}
});
@@ -2259,7 +2282,8 @@
// new current/default screen, so any subsequent taps add items to that screen
if (!mLauncher.isAllAppsVisible()) {
int dragTargetIndex = indexOfChild(mDragTargetLayout);
- if (mCurrentPage != dragTargetIndex && (isSmall() || mIsSwitchingState)) {
+ if (dragTargetIndex > -1 && mCurrentPage != dragTargetIndex &&
+ (isSmall() || mIsSwitchingState)) {
scrollToNewPageWithoutMovingPages(dragTargetIndex);
}
}
@@ -2767,19 +2791,27 @@
if (mInScrollArea) return;
if (mIsSwitchingState) return;
+ Rect r = new Rect();
CellLayout layout = null;
ItemInfo item = (ItemInfo) d.dragInfo;
// Ensure that we have proper spans for the item that we are dropping
if (item.spanX < 0 || item.spanY < 0) throw new RuntimeException("Improper spans found");
-
mDragViewVisualCenter = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset,
- d.dragView, mDragViewVisualCenter);
+ d.dragView, mDragViewVisualCenter);
// Identify whether we have dragged over a side page
if (isSmall()) {
- layout = findMatchingPageForDragOver(d.dragView, mDragViewVisualCenter[0],
+ if (mLauncher.getHotseat() != null) {
+ mLauncher.getHotseat().getHitRect(r);
+ if (r.contains(d.x, d.y)) {
+ layout = mLauncher.getHotseat().getLayout();
+ }
+ }
+ if (layout == null) {
+ layout = findMatchingPageForDragOver(d.dragView, mDragViewVisualCenter[0],
mDragViewVisualCenter[1], true);
+ }
if (layout != mDragTargetLayout) {
// Cancel all intermediate folder states
cleanupFolderCreation(d);
@@ -2798,12 +2830,15 @@
boolean isInSpringLoadedMode = (mState == State.SPRING_LOADED);
if (isInSpringLoadedMode) {
- mSpringLoadedDragController.setAlarm(mDragTargetLayout);
+ if (mLauncher.isHotseatLayout(layout)) {
+ mSpringLoadedDragController.cancel();
+ } else {
+ mSpringLoadedDragController.setAlarm(mDragTargetLayout);
+ }
}
}
} else {
// Test to see if we are over the hotseat otherwise just use the current page
- Rect r = new Rect();
if (mLauncher.getHotseat() != null) {
mLauncher.getHotseat().getHitRect(r);
if (r.contains(d.x, d.y)) {