diff --git a/res/layout-xlarge-land/customization_drawer.xml b/res/layout-xlarge-land/customization_drawer.xml
index 9115259613..304aaf70a8 100644
--- a/res/layout-xlarge-land/customization_drawer.xml
+++ b/res/layout-xlarge-land/customization_drawer.xml
@@ -19,6 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:wallpaperCellSpanX="4"
launcher:widgetCellCountX="16"
launcher:cellCountX="8"
launcher:cellCountY="3"
diff --git a/res/layout-xlarge-port/customization_drawer.xml b/res/layout-xlarge-port/customization_drawer.xml
index 28127ea67a..a9e1c0df33 100644
--- a/res/layout-xlarge-port/customization_drawer.xml
+++ b/res/layout-xlarge-port/customization_drawer.xml
@@ -19,6 +19,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
+ launcher:wallpaperCellSpanX="4"
launcher:widgetCellCountX="10"
launcher:cellCountX="5"
launcher:cellCountY="3"
diff --git a/res/layout-xlarge/customize_paged_view_wallpaper.xml b/res/layout-xlarge/customize_paged_view_wallpaper.xml
new file mode 100644
index 0000000000..6cf248ad2a
--- /dev/null
+++ b/res/layout-xlarge/customize_paged_view_wallpaper.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout-xlarge/customize_paged_view_widget.xml b/res/layout-xlarge/customize_paged_view_widget.xml
index fab2a9b87e..deeeb3d52c 100644
--- a/res/layout-xlarge/customize_paged_view_widget.xml
+++ b/res/layout-xlarge/customize_paged_view_widget.xml
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
+
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index e938b73d90..22d1b63684 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -37,9 +37,11 @@
"Aplikace"
"Hry"
"Stažené"
-
+ "Nenalezeny žádné hry."
+ "Žádné stažené aplikace."
+
-
+
"Název složky"
"Přejmenovat složku"
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 576abce027..6806993144 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -37,9 +37,11 @@
"Programmer"
"Spil"
"Downloadet"
-
+ "Ingen spil."
+ "Ingen hentede programmer."
+
-
+
"Mappenavn"
"Omdøb mappe"
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 575db07149..e60eb348c6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -37,9 +37,11 @@
"Apps"
"Spiele"
"Heruntergeladen"
-
+ "Keine Spiele gefunden."
+ "Keine heruntergeladenen Apps"
+
-
+
"Ordnername"
"Ordner umbenennen"
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 0937c5b587..0298d91735 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -37,9 +37,11 @@
"Εφαρμογές"
"Παιχνίδια"
"Η λήψη ολοκληρώθηκε"
-
+ "Δεν βρέθηκαν παιχνίδια."
+ "Δεν βρέθηκαν ληφθ. εφαρμ."
+
-
+
"Όνομα φακέλου"
"Μετονομασία φακέλου"
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index d718936230..9158dbcb85 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -37,8 +37,12 @@
"Google Apps"
"Juegos"
"Descargado"
- "No"
- "No Google Apps"
+ "No se encontraron juegos."
+ "No se encontraron apps."
+
+
+
+
"Nombre de carpeta"
"Cambiar nombre de carpeta"
"Aceptar"
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index ab0485a090..f9d8b1585c 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -37,9 +37,11 @@
"Aplicaciones"
"Juegos"
"Descargadas"
-
+ "No hay juegos."
+ "Sin aplicaciones descarg."
+
-
+
"Nombre de carpeta"
"Cambiar nombre de carpeta"
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 35ee775bec..5827611d90 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -37,9 +37,11 @@
"Applications"
"Jeux"
"Téléchargées"
-
+ "Aucun jeu n\'a été trouvé."
+ "Pas d\'application téléchargée"
+
-
+
"Nom du dossier"
"Renommer le dossier"
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7705763ce0..5b40b98893 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -37,9 +37,11 @@
"Applicazioni"
"Giochi"
"Scaricate"
-
+ "Nessun gioco trovato."
+ "Nessuna appl. scaricata"
+
-
+
"Nome cartella"
"Rinomina cartella"
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2a7a218c46..5932429082 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -37,9 +37,11 @@
"アプリ"
"ゲーム"
"ダウンロード済み"
-
+ "ゲームなし"
+ "ダウンロードアプリなし"
+
-
+
"フォルダ名"
"フォルダ名を変更"
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index b23450d434..6dc4a60185 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -37,9 +37,11 @@
"애플리케이션"
"게임"
"다운로드앱"
-
+ "게임이 없습니다."
+ "다운로드한 애플리케이션이 없습니다."
+
-
+
"폴더 이름"
"폴더 이름 바꾸기"
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 5026744f97..40cbbba13b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -37,9 +37,11 @@
"Programmer"
"Spill"
"Nedlastet"
-
+ "Finner ingen spill."
+ "Finner ingen nedl.prog."
+
-
+
"Mappenavn"
"Gi nytt navn til mappe"
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 65625294bb..fa19eeae6c 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -37,9 +37,11 @@
"Toepassingen"
"Games"
"Gedownload"
-
+ "Geen games gevonden."
+ "Geen gedownl. apps gevond."
+
-
+
"Mapnaam"
"Naam van map wijzigen"
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index f2ac81daaf..cdfb0a93d5 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -37,9 +37,11 @@
"Aplikacje"
"Gry"
"Pobrane"
-
+ "Nie znaleziono gier."
+ "Brak pobranych aplikacji."
+
-
+
"Nazwa folderu"
"Zmień nazwę folderu"
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index a3c432d6b9..59effc796d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -37,9 +37,11 @@
"Aplicações"
"Jogos"
"Transferidas"
-
+ "Sem jogos."
+ "Sem aplic. transferidas."
+
-
+
"Nome da pasta"
"Mudar o nome da pasta"
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 3941c4f606..7f947a6477 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -37,9 +37,11 @@
"Aplicativos"
"Jogos"
"Download concluído"
-
+ "Nenhum jogo encontrado."
+ "Nenhum aplic. encontrado."
+
-
+
"Nome da pasta"
"Renomear pasta"
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 10cbc4ae6c..5e7b1e7868 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -51,6 +51,10 @@
+
+
+
+
"Num da l\'ordinatur"
"Renumnar l\'ordinatur"
"OK"
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index fd5b35dcd6..acfa352fca 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -37,9 +37,11 @@
"Приложения"
"Игры"
"Загруженные"
-
+ "Игр не найдено."
+ "Нет загруженных приложений."
+
-
+
"Название папки"
"Переименовать папку"
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 17a6cdce02..724863530a 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -37,9 +37,11 @@
"Program"
"Spel"
"Hämtade"
-
+ "Inga spel hittades."
+ "Inga hämtade appar."
+
-
+
"Mappnamn"
"Byt namn på mapp"
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 19417f0fd6..9716ea76ea 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -37,9 +37,11 @@
"Uygulamalar"
"Oyunlar"
"İndirilenler"
-
+ "Oyun bulunamadı."
+ "İndirilmş uyg bulunamadı."
+
-
+
"Klasör adı"
"Klasörü yeniden adlandır"
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 751474b193..22bba844d3 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -37,9 +37,11 @@
"应用程序"
"游戏"
"已下载"
-
+ "未找到游戏。"
+ "未找到已下载的应用程序。"
+
-
+
"文件夹名称"
"重命名文件夹"
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 824ec64a25..6cc7c32c3f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -37,9 +37,11 @@
"應用程式"
"遊戲"
"下載內容"
-
+ "找不到遊戲。"
+ "找不到已下載的應用程式。"
+
-
+
"資料夾名稱"
"重新命名資料夾"
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5d6773c482..975548e9ce 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -74,15 +74,6 @@
-
-
-
-
-
-
-
-
@@ -105,6 +96,8 @@
+
+
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index c432f37c1a..14b2429453 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -77,12 +77,18 @@ public class CustomizePagedView extends PagedView
// The mapping between the pages and the widgets that will be laid out on them
private ArrayList> mWidgetPages;
- // The max dimensions for the ImageView we use for displaying the widget
+ // The max dimensions for the ImageView we use for displaying a widget
private int mMaxWidgetWidth;
- // The max number of widget cells to take a "page" of widget
+ // The max number of widget cells to take a "page" of widgets
private int mMaxWidgetsCellHSpan;
+ // The size of the items on the wallpaper tab
+ private int mWallpaperCellHSpan;
+
+ // The max dimensions for the ImageView we use for displaying a wallpaper
+ private int mMaxWallpaperWidth;
+
// The raw sources of data for each of the different tabs of the customization page
private List mWidgetList;
private List mShortcutList;
@@ -112,15 +118,15 @@ public class CustomizePagedView extends PagedView
super(context, attrs, defStyle);
TypedArray a;
- a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView,
- defStyle, 0);
+ a = context.obtainStyledAttributes(attrs, R.styleable.CustomizePagedView, defStyle, 0);
+ mWallpaperCellHSpan = a.getInt(R.styleable.CustomizePagedView_wallpaperCellSpanX, 4);
mMaxWidgetsCellHSpan = a.getInt(R.styleable.CustomizePagedView_widgetCellCountX, 8);
a.recycle();
a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, defStyle, 0);
mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 7);
mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
-
a.recycle();
+
mCustomizationType = CustomizationType.WidgetCustomization;
mWidgetPages = new ArrayList>();
mWorkspaceWidgetLayout = new PagedViewCellLayout(context);
@@ -449,21 +455,58 @@ public class CustomizePagedView extends PagedView
/**
* Helper function to draw a drawable to the specified canvas with the specified bounds.
*/
- private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int l, int t, int r, int b) {
+ private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) {
if (bitmap != null) mCanvas.setBitmap(bitmap);
mCanvas.save();
- d.setBounds(l, t, r, b);
+ d.setBounds(x, y, x+w, y+h);
d.draw(mCanvas);
mCanvas.restore();
}
+ /**
+ * This method will extract the preview image specified by the wallpaper source provider (if it
+ * exists) otherwise, it will try to generate a default image preview.
+ */
+ private Drawable getWallpaperPreview(ResolveInfo info) {
+ // To be implemented later: resolving the up-to-date wallpaper thumbnail
+
+ final int minDim = mWorkspaceWidgetLayout.estimateCellWidth(1);
+ final int dim = mWorkspaceWidgetLayout.estimateCellWidth(mWallpaperCellHSpan);
+ Resources resources = mLauncher.getResources();
+
+ // Create a new bitmap to hold the widget preview
+ int width = (int) (dim * sScaleFactor);
+ int height = (int) (dim * sScaleFactor);
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
+ final Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
+ renderDrawableToBitmap(background, bitmap, 0, 0, width, height);
+
+ // Draw the icon flush left
+ try {
+ final IconCache iconCache =
+ ((LauncherApplication) mLauncher.getApplication()).getIconCache();
+ Drawable icon = new FastBitmapDrawable(Utilities.createIconBitmap(
+ iconCache.getFullResIcon(info, mPackageManager), mContext));
+
+ final int iconSize = minDim / 2;
+ final int offset = iconSize / 4;
+ renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize);
+ } catch (Resources.NotFoundException e) {
+ // if we can't find the icon, then just don't draw it
+ }
+
+ Drawable drawable = new FastBitmapDrawable(bitmap);
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+ return drawable;
+ }
+
/**
* This method will extract the preview image specified by the widget developer (if it exists),
* otherwise, it will try to generate a default image preview with the widget's package icon.
- * @return the drawable will be used and sized in the ImageView to represent the widget
+ * @return the drawable that will be used and sized in the ImageView to represent the widget
*/
private Drawable getWidgetPreview(AppWidgetProviderInfo info) {
- PackageManager packageManager = mLauncher.getPackageManager();
+ final PackageManager packageManager = mPackageManager;
String packageName = info.provider.getPackageName();
Drawable drawable = null;
if (info.previewImage != 0) {
@@ -487,9 +530,8 @@ public class CustomizePagedView extends PagedView
final Drawable background = resources.getDrawable(R.drawable.default_widget_preview);
renderDrawableToBitmap(background, bitmap, 0, 0, width, height);
- // Draw the icon vertically centered, flush left
+ // Draw the icon flush left
try {
- Rect tmpRect = new Rect();
Drawable icon = null;
if (info.icon > 0) {
icon = packageManager.getDrawable(packageName, info.icon, null);
@@ -497,12 +539,10 @@ public class CustomizePagedView extends PagedView
if (icon == null) {
icon = resources.getDrawable(R.drawable.ic_launcher_application);
}
- background.getPadding(tmpRect);
final int iconSize = minDim / 2;
final int offset = iconSize / 4;
- final int offsetIconSize = offset + iconSize;
- renderDrawableToBitmap(icon, null, offset, offset, offsetIconSize, offsetIconSize);
+ renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize);
} catch (Resources.NotFoundException e) {
// if we can't find the icon, then just don't draw it
}
@@ -548,6 +588,7 @@ public class CustomizePagedView extends PagedView
mWorkspaceWidgetLayout.setPadding(20, 10, 20, 0);
mMaxWidgetWidth = mWorkspaceWidgetLayout.estimateCellWidth(sMaxWidgetCellHSpan);
+ mMaxWallpaperWidth = mWorkspaceWidgetLayout.estimateCellWidth(mWallpaperCellHSpan);
}
private void syncWidgetPages() {
@@ -557,7 +598,7 @@ public class CustomizePagedView extends PagedView
removeAllViews();
int numPages = relayoutWidgets();
for (int i = 0; i < numPages; ++i) {
- LinearLayout layout = new PagedViewWidgetLayout(getContext());
+ LinearLayout layout = new PagedViewExtendedLayout(getContext());
layout.setGravity(Gravity.CENTER_HORIZONTAL);
layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
@@ -610,6 +651,58 @@ public class CustomizePagedView extends PagedView
}
}
+ private void syncWallpaperPages() {
+ if (mWallpaperList == null) return;
+
+ // We need to repopulate the LinearLayout for the wallpaper pages
+ removeAllViews();
+ int numPages = (int) Math.ceil((float) (mWallpaperList.size() * mWallpaperCellHSpan) /
+ mMaxWidgetsCellHSpan);
+ for (int i = 0; i < numPages; ++i) {
+ LinearLayout layout = new PagedViewExtendedLayout(getContext());
+ layout.setGravity(Gravity.CENTER_HORIZONTAL);
+ layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+ mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+
+ // Temporary change to prevent the last page from being too small (and items bleeding
+ // onto it). We can remove this once we properly fix the fading algorithm
+ if (i < numPages - 1) {
+ addView(layout, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.MATCH_PARENT));
+ } else {
+ addView(layout, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT));
+ }
+ }
+ }
+
+ private void syncWallpaperPageItems(int page) {
+ // Load the items on to the pages
+ LinearLayout layout = (LinearLayout) getChildAt(page);
+ layout.removeAllViews();
+ final int count = mWallpaperList.size();
+ for (int i = 0; i < count; ++i) {
+ final ResolveInfo info = mWallpaperList.get(i);
+
+ LinearLayout l = (LinearLayout) mInflater.inflate(
+ R.layout.customize_paged_view_wallpaper, layout, false);
+ l.setTag(info);
+ l.setOnClickListener(this);
+
+ final Drawable icon = getWallpaperPreview(info);
+
+ ImageView image = (ImageView) l.findViewById(R.id.wallpaper_preview);
+ image.setMaxWidth(mMaxWidgetWidth);
+ image.setImageDrawable(icon);
+ TextView name = (TextView) l.findViewById(R.id.wallpaper_name);
+ name.setText(info.loadLabel(mPackageManager));
+
+ layout.addView(l);
+ }
+ }
+
private void syncListPages(List list) {
// we need to repopulate with PagedViewCellLayouts
removeAllViews();
@@ -716,8 +809,7 @@ public class CustomizePagedView extends PagedView
centerPagedViewCellLayouts = true;
break;
case WallpaperCustomization:
- syncListPages(mWallpaperList);
- centerPagedViewCellLayouts = true;
+ syncWallpaperPages();
break;
case ApplicationCustomization:
syncAppPages();
@@ -757,7 +849,7 @@ public class CustomizePagedView extends PagedView
syncListPageItems(page, mShortcutList);
break;
case WallpaperCustomization:
- syncListPageItems(page, mWallpaperList);
+ syncWallpaperPageItems(page);
break;
case ApplicationCustomization:
syncAppPageItems(page);
diff --git a/src/com/android/launcher2/FastBitmapDrawable.java b/src/com/android/launcher2/FastBitmapDrawable.java
index 1cafa09a7b..1aa8b35221 100644
--- a/src/com/android/launcher2/FastBitmapDrawable.java
+++ b/src/com/android/launcher2/FastBitmapDrawable.java
@@ -16,12 +16,13 @@
package com.android.launcher2;
-import android.graphics.drawable.Drawable;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
class FastBitmapDrawable extends Drawable {
private Bitmap mBitmap;
@@ -41,7 +42,8 @@ class FastBitmapDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
- canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
+ final Rect r = getBounds();
+ canvas.drawBitmap(mBitmap, r.left, r.top, mPaint);
}
@Override
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 549303d034..4f6f7d8f5c 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -47,12 +47,12 @@ 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.Intent.ShortcutIconResource;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -67,6 +67,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
+import android.os.Message;
import android.os.Parcelable;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -85,25 +86,27 @@ 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;
+import android.widget.Advanceable;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TabHost;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TabHost.TabContentFactory;
import android.widget.TextView;
import android.widget.Toast;
+import android.widget.TabHost.OnTabChangeListener;
+import android.widget.TabHost.TabContentFactory;
import com.android.common.Search;
import com.android.launcher.R;
+
/**
* Default launcher application.
*/
@@ -205,6 +208,7 @@ public final class Launcher extends Activity
private HandleView mHandleView;
private AllAppsView mAllAppsGrid;
private TabHost mHomeCustomizationDrawer;
+ private boolean mAutoAdvanceRunning = false;
private PagedView mAllAppsPagedView = null;
private CustomizePagedView mCustomizePagedView = null;
@@ -228,6 +232,7 @@ public final class Launcher extends Activity
private static LocaleConfiguration sLocaleConfiguration = null;
private ArrayList mDesktopItems = new ArrayList();
+
private static HashMap sFolders = new HashMap();
private ImageView mPreviousView;
@@ -241,6 +246,15 @@ public final class Launcher extends Activity
private Intent mAppMarketIntent = null;
+ // Related to the auto-advancing of widgets
+ private final int ADVANCE_MSG = 1;
+ private final int mAdvanceInterval = 20000;
+ private final int mAdvanceStagger = 250;
+ private long mAutoAdvanceSentTime;
+ private long mAutoAdvanceTimeLeft = -1;
+ private HashMap mWidgetsToAdvance =
+ new HashMap();
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -1060,7 +1074,6 @@ public final class Launcher extends Activity
}
}
-
/**
* Add a widget to the workspace.
*
@@ -1133,18 +1146,128 @@ public final class Launcher extends Activity
mWorkspace.addInScreen(launcherInfo.hostView, screen, cellXY[0], cellXY[1],
launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked());
+
+ addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo);
}
}
- void showOutOfSpaceMessage() {
- Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+ private boolean mUserPresent = true;
+ private boolean mVisible = false;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+ mUserPresent = false;
+ updateRunning();
+ } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
+ mUserPresent = true;
+ updateRunning();
+ }
+ }
+ };
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ // Listen for broadcasts related to user-presence
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(Intent.ACTION_USER_PRESENT);
+ registerReceiver(mReceiver, filter);
+
+ mVisible = true;
+ }
+
+ @Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mVisible = false;
+
+ unregisterReceiver(mReceiver);
+ updateRunning();
+ }
+
+ public void onWindowVisibilityChanged(int visibility) {
+ mVisible = visibility == View.VISIBLE;
+ updateRunning();
+ }
+
+ private void sendAdvanceMessage(long delay) {
+ mHandler.removeMessages(ADVANCE_MSG);
+ Message msg = mHandler.obtainMessage(ADVANCE_MSG);
+ mHandler.sendMessageDelayed(msg, delay);
+ mAutoAdvanceSentTime = System.currentTimeMillis();
+ }
+
+ private void updateRunning() {
+ boolean autoAdvanceRunning = mVisible && mUserPresent && !mWidgetsToAdvance.isEmpty();
+ if (autoAdvanceRunning != mAutoAdvanceRunning) {
+ mAutoAdvanceRunning = autoAdvanceRunning;
+ if (autoAdvanceRunning) {
+ long delay = mAutoAdvanceTimeLeft == -1 ? mAdvanceInterval : mAutoAdvanceTimeLeft;
+ sendAdvanceMessage(delay);
+ } else {
+ if (!mWidgetsToAdvance.isEmpty()) {
+ mAutoAdvanceTimeLeft = Math.max(0, mAdvanceInterval -
+ (System.currentTimeMillis() - mAutoAdvanceSentTime));
+ }
+ mHandler.removeMessages(ADVANCE_MSG);
+ }
+ }
+ }
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == ADVANCE_MSG) {
+ int i = 0;
+ for (View key: mWidgetsToAdvance.keySet()) {
+ final View v = key.findViewById(mWidgetsToAdvance.get(key).autoAdvanceViewId);
+ final int delay = mAdvanceStagger * i;
+ if (v instanceof Advanceable) {
+ postDelayed(new Runnable() {
+ public void run() {
+ ((Advanceable) v).advance();
+ }
+ }, delay);
+ }
+ i++;
+ }
+ sendAdvanceMessage(mAdvanceInterval);
+ }
+ }
+ };
+
+ void addWidgetToAutoAdvanceIfNeeded(View hostView, AppWidgetProviderInfo appWidgetInfo) {
+ if (appWidgetInfo.autoAdvanceViewId == -1) return;
+ View v = hostView.findViewById(appWidgetInfo.autoAdvanceViewId);
+ if (v instanceof Advanceable) {
+ mWidgetsToAdvance.put(hostView, appWidgetInfo);
+ ((Advanceable) v).willBeAdvancedByHost();
+ updateRunning();
+ }
+ }
+
+ void removeWidgetToAutoAdvance(View hostView) {
+ if (mWidgetsToAdvance.containsKey(hostView)) {
+ mWidgetsToAdvance.remove(hostView);
+ updateRunning();
+ }
}
public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) {
mDesktopItems.remove(launcherInfo);
+ removeWidgetToAutoAdvance(launcherInfo.hostView);
launcherInfo.hostView = null;
}
+ void showOutOfSpaceMessage() {
+ Toast.makeText(this, getString(R.string.out_of_space), Toast.LENGTH_SHORT).show();
+ }
+
public LauncherAppWidgetHost getAppWidgetHost() {
return mAppWidgetHost;
}
@@ -3064,6 +3187,8 @@ public final class Launcher extends Activity
workspace.addInScreen(item.hostView, item.screen, item.cellX,
item.cellY, item.spanX, item.spanY, false);
+ addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo);
+
workspace.requestLayout();
mDesktopItems.add(item);
diff --git a/src/com/android/launcher2/LauncherAppWidgetInfo.java b/src/com/android/launcher2/LauncherAppWidgetInfo.java
index 32c92aabd6..844abb5190 100644
--- a/src/com/android/launcher2/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher2/LauncherAppWidgetInfo.java
@@ -37,7 +37,7 @@ class LauncherAppWidgetInfo extends ItemInfo {
int appWidgetId = NO_ID;
ComponentName providerName;
-
+
// TODO: Are these necessary here?
int minWidth = -1;
int minHeight = -1;
@@ -65,7 +65,7 @@ class LauncherAppWidgetInfo extends ItemInfo {
itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
this.appWidgetId = appWidgetId;
}
-
+
@Override
void onAddToDatabase(ContentValues values) {
super.onAddToDatabase(values);
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 0622aaea01..70746b38b2 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -621,6 +621,9 @@ public abstract class PagedView extends ViewGroup {
* scrolling there.
*/
+ // Skip touch handling if there are no pages to swipe
+ if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev);
+
/*
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
@@ -775,6 +778,9 @@ public abstract class PagedView extends ViewGroup {
@Override
public boolean onTouchEvent(MotionEvent ev) {
+ // Skip touch handling if there are no pages to swipe
+ if (getChildCount() <= 0) return super.onTouchEvent(ev);
+
acquireVelocityTrackerAndAddMovement(ev);
final int action = ev.getAction();
diff --git a/src/com/android/launcher2/PagedViewWidgetLayout.java b/src/com/android/launcher2/PagedViewExtendedLayout.java
similarity index 85%
rename from src/com/android/launcher2/PagedViewWidgetLayout.java
rename to src/com/android/launcher2/PagedViewExtendedLayout.java
index 4666873ce7..52df9f1ed4 100644
--- a/src/com/android/launcher2/PagedViewWidgetLayout.java
+++ b/src/com/android/launcher2/PagedViewExtendedLayout.java
@@ -22,20 +22,20 @@ import android.view.MotionEvent;
import android.widget.LinearLayout;
/**
- * The linear layout used strictly for the widget tab of the customization tray
+ * The linear layout used strictly for the widget/wallpaper tab of the customization tray
*/
-public class PagedViewWidgetLayout extends LinearLayout {
+public class PagedViewExtendedLayout extends LinearLayout {
static final String TAG = "PagedViewWidgetLayout";
- public PagedViewWidgetLayout(Context context) {
+ public PagedViewExtendedLayout(Context context) {
this(context, null);
}
- public PagedViewWidgetLayout(Context context, AttributeSet attrs) {
+ public PagedViewExtendedLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public PagedViewWidgetLayout(Context context, AttributeSet attrs, int defStyle) {
+ public PagedViewExtendedLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
diff --git a/src/com/android/launcher2/PagedViewWidgetIcon.java b/src/com/android/launcher2/PagedViewWidgetIcon.java
deleted file mode 100644
index f285dab7fe..0000000000
--- a/src/com/android/launcher2/PagedViewWidgetIcon.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.Checkable;
-import android.widget.LinearLayout;
-
-import com.android.launcher.R;
-
-/**
- * An widget icon for use specifically in the CustomizePagedView. In class form so that
- * we can add logic for how it will look when checked/unchecked.
- */
-public class PagedViewWidgetIcon extends LinearLayout implements Checkable {
- private static final String TAG = "PagedViewIcon";
-
- // Holographic outline
- private final Paint mPaint = new Paint();
- private static HolographicOutlineHelper sHolographicOutlineHelper;
- private final Paint mErasePaint = new Paint();
- private Bitmap mCheckedOutline;
- private Canvas mHolographicOutlineCanvas;
- private boolean mIsHolographicUpdatePass;
-
- private int mAlpha;
-
- private boolean mIsChecked;
-
- // Highlight colours
- private int mCheckedBlurColor;
- private int mCheckedOutlineColor;
-
-
- public PagedViewWidgetIcon(Context context) {
- this(context, null);
- }
-
- public PagedViewWidgetIcon(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public PagedViewWidgetIcon(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedViewWidgetIcon,
- defStyle, 0);
- mCheckedBlurColor = a.getColor(R.styleable.PagedViewWidgetIcon_checkedBlurColor, 0);
- mCheckedOutlineColor = a.getColor(R.styleable.PagedViewWidgetIcon_checkedOutlineColor, 0);
- mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
- mErasePaint.setFilterBitmap(true);
- a.recycle();
-
- if (sHolographicOutlineHelper == null) {
- sHolographicOutlineHelper = new HolographicOutlineHelper();
- }
-
- setWillNotDraw(false);
- }
-
- public void invalidateCheckedImage() {
- if (mCheckedOutline != null) {
- mCheckedOutline.recycle();
- mCheckedOutline = null;
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- // Draw the view itself
- if (mIsHolographicUpdatePass) {
- canvas.save();
- final float alpha = getAlpha();
- super.setAlpha(1.0f);
- super.onDraw(canvas);
- super.setAlpha(alpha);
- canvas.restore();
- } else {
- if (mAlpha > 0) {
- super.onDraw(canvas);
- }
- }
-
- // Draw the holographic checked overlay if necessary
- if (!mIsHolographicUpdatePass) {
- if (mCheckedOutline != null) {
- mPaint.setAlpha(255);
- canvas.drawBitmap(mCheckedOutline, 0, 0, mPaint);
- }
- }
- }
-
- @Override
- public boolean isChecked() {
- return mIsChecked;
- }
-
- @Override
- public void setChecked(boolean checked) {
- if (mIsChecked != checked) {
- mIsChecked = checked;
-
- if (mIsChecked) {
- // set a flag to indicate that we are going to draw the view at full alpha
- mIsHolographicUpdatePass = true;
- final int width = getMeasuredWidth();
- final int height = getMeasuredHeight();
- mCheckedOutline = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- mHolographicOutlineCanvas = new Canvas(mCheckedOutline);
- mHolographicOutlineCanvas.concat(getMatrix());
- draw(mHolographicOutlineCanvas);
- sHolographicOutlineHelper.applyExpensiveOutlineWithBlur(mCheckedOutline,
- mHolographicOutlineCanvas, mCheckedBlurColor, mCheckedOutlineColor);
-
- // Unlike PagedViewIcon, we can't seem to properly set the clip rect for all the
- // children to respect when drawing... so for now, we erase over those parts in the
- // checked highlight image
- mHolographicOutlineCanvas.drawRect(0, findViewById(R.id.divider).getTop(),
- width, height, mErasePaint);
-
- mIsHolographicUpdatePass = false;
- mHolographicOutlineCanvas = null;
- } else {
- invalidateCheckedImage();
- }
-
- invalidate();
- }
- }
-
- @Override
- public void toggle() {
- setChecked(!mIsChecked);
- }
-}
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index df3d2de528..e068a76830 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -426,6 +426,10 @@ public class Workspace extends SmoothPagedView
return false;
}
+ protected void onWindowVisibilityChanged (int visibility) {
+ mLauncher.onWindowVisibilityChanged(visibility);
+ }
+
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
if (mIsSmall || mIsInUnshrinkAnimation) {