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) {