diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:05 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:05 -0800 |
commit | 15a8880cb1b9010ce4503c10c1666568d49415b1 (patch) | |
tree | 29fa05cbaa19101da95b010de82290cebfb6d092 | |
parent | bb96f41aa99687260370cf8cdee7683653e538a7 (diff) | |
download | packages_apps_trebuchet-15a8880cb1b9010ce4503c10c1666568d49415b1.zip packages_apps_trebuchet-15a8880cb1b9010ce4503c10c1666568d49415b1.tar.gz packages_apps_trebuchet-15a8880cb1b9010ce4503c10c1666568d49415b1.tar.bz2 |
auto import from //branches/cupcake/...@130745
73 files changed, 1307 insertions, 819 deletions
diff --git a/res/drawable/bg_gadget_error.9.png b/res/drawable/bg_gadget_error.9.png Binary files differnew file mode 100644 index 0000000..5077424 --- /dev/null +++ b/res/drawable/bg_gadget_error.9.png diff --git a/res/drawable/ic_launcher_alarmclock.png b/res/drawable/ic_launcher_alarmclock.png Binary files differdeleted file mode 100755 index 30ff267..0000000 --- a/res/drawable/ic_launcher_alarmclock.png +++ /dev/null diff --git a/res/drawable/ic_launcher_application.png b/res/drawable/ic_launcher_application.png Binary files differnew file mode 100644 index 0000000..7502484 --- /dev/null +++ b/res/drawable/ic_launcher_application.png diff --git a/res/drawable/ic_launcher_empty.png b/res/drawable/ic_launcher_empty.png Binary files differnew file mode 100644 index 0000000..59bb6c5 --- /dev/null +++ b/res/drawable/ic_launcher_empty.png diff --git a/res/drawable/ic_launcher_gadget.png b/res/drawable/ic_launcher_gadget.png Binary files differnew file mode 100644 index 0000000..cb40a19 --- /dev/null +++ b/res/drawable/ic_launcher_gadget.png diff --git a/res/drawable/wallpaper.jpg b/res/drawable/wallpaper.jpg Binary files differdeleted file mode 100644 index d19b642..0000000 --- a/res/drawable/wallpaper.jpg +++ /dev/null diff --git a/res/drawable/wallpaper_beach.jpg b/res/drawable/wallpaper_beach.jpg Binary files differindex c059cc3..bdcece0 100644 --- a/res/drawable/wallpaper_beach.jpg +++ b/res/drawable/wallpaper_beach.jpg diff --git a/res/drawable/wallpaper_beach_small.jpg b/res/drawable/wallpaper_beach_small.jpg Binary files differindex 3508509..46051cc 100644 --- a/res/drawable/wallpaper_beach_small.jpg +++ b/res/drawable/wallpaper_beach_small.jpg diff --git a/res/drawable/wallpaper_blue.jpg b/res/drawable/wallpaper_blue.jpg Binary files differindex 032f598..0edd6bd 100644 --- a/res/drawable/wallpaper_blue.jpg +++ b/res/drawable/wallpaper_blue.jpg diff --git a/res/drawable/wallpaper_blue_small.jpg b/res/drawable/wallpaper_blue_small.jpg Binary files differindex e987c69..5cf585a 100644 --- a/res/drawable/wallpaper_blue_small.jpg +++ b/res/drawable/wallpaper_blue_small.jpg diff --git a/res/drawable/wallpaper_green.jpg b/res/drawable/wallpaper_green.jpg Binary files differindex 89b308b..36c9e08 100644 --- a/res/drawable/wallpaper_green.jpg +++ b/res/drawable/wallpaper_green.jpg diff --git a/res/drawable/wallpaper_green_small.jpg b/res/drawable/wallpaper_green_small.jpg Binary files differindex 16790d2..d7c28ec 100644 --- a/res/drawable/wallpaper_green_small.jpg +++ b/res/drawable/wallpaper_green_small.jpg diff --git a/res/drawable/wallpaper_grey.jpg b/res/drawable/wallpaper_grey.jpg Binary files differindex 7898568..ca48e6a 100644 --- a/res/drawable/wallpaper_grey.jpg +++ b/res/drawable/wallpaper_grey.jpg diff --git a/res/drawable/wallpaper_grey_small.jpg b/res/drawable/wallpaper_grey_small.jpg Binary files differindex 12ca3e2..1734d2e 100644 --- a/res/drawable/wallpaper_grey_small.jpg +++ b/res/drawable/wallpaper_grey_small.jpg diff --git a/res/drawable/wallpaper_jellyfish.jpg b/res/drawable/wallpaper_jellyfish.jpg Binary files differindex 659228b..f327399 100644 --- a/res/drawable/wallpaper_jellyfish.jpg +++ b/res/drawable/wallpaper_jellyfish.jpg diff --git a/res/drawable/wallpaper_jellyfish_small.jpg b/res/drawable/wallpaper_jellyfish_small.jpg Binary files differindex e140597..4e5d134 100644 --- a/res/drawable/wallpaper_jellyfish_small.jpg +++ b/res/drawable/wallpaper_jellyfish_small.jpg diff --git a/res/drawable/wallpaper_lake.jpg b/res/drawable/wallpaper_lake.jpg Binary files differindex 5ba522f..874bb3b 100644 --- a/res/drawable/wallpaper_lake.jpg +++ b/res/drawable/wallpaper_lake.jpg diff --git a/res/drawable/wallpaper_lake_small.jpg b/res/drawable/wallpaper_lake_small.jpg Binary files differindex 179b26a..36d56cc 100644 --- a/res/drawable/wallpaper_lake_small.jpg +++ b/res/drawable/wallpaper_lake_small.jpg diff --git a/res/drawable/wallpaper_mountain.jpg b/res/drawable/wallpaper_mountain.jpg Binary files differindex 1376177..af4a3b1 100644 --- a/res/drawable/wallpaper_mountain.jpg +++ b/res/drawable/wallpaper_mountain.jpg diff --git a/res/drawable/wallpaper_mountain_small.jpg b/res/drawable/wallpaper_mountain_small.jpg Binary files differindex 2416474..e2d5ac2 100644 --- a/res/drawable/wallpaper_mountain_small.jpg +++ b/res/drawable/wallpaper_mountain_small.jpg diff --git a/res/drawable/wallpaper_path.jpg b/res/drawable/wallpaper_path.jpg Binary files differindex f4cb02c..c8d610e 100644 --- a/res/drawable/wallpaper_path.jpg +++ b/res/drawable/wallpaper_path.jpg diff --git a/res/drawable/wallpaper_path_small.jpg b/res/drawable/wallpaper_path_small.jpg Binary files differindex a1af4cd..f47d7a7 100644 --- a/res/drawable/wallpaper_path_small.jpg +++ b/res/drawable/wallpaper_path_small.jpg diff --git a/res/drawable/wallpaper_pink.jpg b/res/drawable/wallpaper_pink.jpg Binary files differindex 1b9f226..74403e5 100644 --- a/res/drawable/wallpaper_pink.jpg +++ b/res/drawable/wallpaper_pink.jpg diff --git a/res/drawable/wallpaper_pink_small.jpg b/res/drawable/wallpaper_pink_small.jpg Binary files differindex 7b7ad58..42b1770 100644 --- a/res/drawable/wallpaper_pink_small.jpg +++ b/res/drawable/wallpaper_pink_small.jpg diff --git a/res/drawable/wallpaper_ripples.jpg b/res/drawable/wallpaper_ripples.jpg Binary files differindex 8624c86..4d740a4 100644 --- a/res/drawable/wallpaper_ripples.jpg +++ b/res/drawable/wallpaper_ripples.jpg diff --git a/res/drawable/wallpaper_ripples_small.jpg b/res/drawable/wallpaper_ripples_small.jpg Binary files differindex ce07d38..c690d9c 100644 --- a/res/drawable/wallpaper_ripples_small.jpg +++ b/res/drawable/wallpaper_ripples_small.jpg diff --git a/res/drawable/wallpaper_road.jpg b/res/drawable/wallpaper_road.jpg Binary files differindex 88611a4..3aaa639 100644 --- a/res/drawable/wallpaper_road.jpg +++ b/res/drawable/wallpaper_road.jpg diff --git a/res/drawable/wallpaper_road_small.jpg b/res/drawable/wallpaper_road_small.jpg Binary files differindex 0b0c390..6bf401a 100644 --- a/res/drawable/wallpaper_road_small.jpg +++ b/res/drawable/wallpaper_road_small.jpg diff --git a/res/drawable/wallpaper_snow_leopard.jpg b/res/drawable/wallpaper_snow_leopard.jpg Binary files differindex 0d33157..ffb5d09 100644 --- a/res/drawable/wallpaper_snow_leopard.jpg +++ b/res/drawable/wallpaper_snow_leopard.jpg diff --git a/res/drawable/wallpaper_snow_leopard_small.jpg b/res/drawable/wallpaper_snow_leopard_small.jpg Binary files differindex ec976aa..99db5c6 100644 --- a/res/drawable/wallpaper_snow_leopard_small.jpg +++ b/res/drawable/wallpaper_snow_leopard_small.jpg diff --git a/res/drawable/wallpaper_sunrise.jpg b/res/drawable/wallpaper_sunrise.jpg Binary files differindex 4ee8d5d..e00f45c 100644 --- a/res/drawable/wallpaper_sunrise.jpg +++ b/res/drawable/wallpaper_sunrise.jpg diff --git a/res/drawable/wallpaper_sunrise_small.jpg b/res/drawable/wallpaper_sunrise_small.jpg Binary files differindex aadd980..248b7e7 100644 --- a/res/drawable/wallpaper_sunrise_small.jpg +++ b/res/drawable/wallpaper_sunrise_small.jpg diff --git a/res/drawable/wallpaper_sunset.jpg b/res/drawable/wallpaper_sunset.jpg Binary files differindex bcfd8d4..bb2af6e 100644 --- a/res/drawable/wallpaper_sunset.jpg +++ b/res/drawable/wallpaper_sunset.jpg diff --git a/res/drawable/wallpaper_sunset_small.jpg b/res/drawable/wallpaper_sunset_small.jpg Binary files differindex eff8f0d..d5e5add 100644 --- a/res/drawable/wallpaper_sunset_small.jpg +++ b/res/drawable/wallpaper_sunset_small.jpg diff --git a/res/drawable/wallpaper_zanzibar.jpg b/res/drawable/wallpaper_zanzibar.jpg Binary files differindex fb13374..75d175d 100644 --- a/res/drawable/wallpaper_zanzibar.jpg +++ b/res/drawable/wallpaper_zanzibar.jpg diff --git a/res/drawable/wallpaper_zanzibar_small.jpg b/res/drawable/wallpaper_zanzibar_small.jpg Binary files differindex 7307a73..700a7fe 100644 --- a/res/drawable/wallpaper_zanzibar_small.jpg +++ b/res/drawable/wallpaper_zanzibar_small.jpg diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 11a81fd..e92c8dc 100644 --- a/res/layout-land/launcher.xml +++ b/res/layout-land/launcher.xml @@ -16,7 +16,6 @@ <com.android.launcher.DragLayer xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" android:id="@+id/drag_layer" @@ -37,15 +36,15 @@ </com.android.launcher.Workspace> - <com.android.internal.widget.SlidingDrawer + <SlidingDrawer android:id="@+id/drawer" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" - androidprv:bottomOffset="7px" - androidprv:handle="@+id/all_apps" - androidprv:content="@+id/content"> + android:bottomOffset="7dip" + android:handle="@+id/all_apps" + android:content="@+id/content"> <com.android.launcher.HandleView android:id="@id/all_apps" @@ -81,7 +80,7 @@ android:verticalSpacing="10dip" android:numColumns="5" /> - </com.android.internal.widget.SlidingDrawer> + </SlidingDrawer> <com.android.launcher.DeleteZone android:id="@+id/delete_zone" diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index 167331e..1ba524b 100644 --- a/res/layout-port/launcher.xml +++ b/res/layout-port/launcher.xml @@ -16,7 +16,6 @@ <com.android.launcher.DragLayer xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" android:id="@+id/drag_layer" @@ -37,15 +36,15 @@ </com.android.launcher.Workspace> - <com.android.internal.widget.SlidingDrawer + <SlidingDrawer android:id="@+id/drawer" android:layout_width="fill_parent" android:layout_height="fill_parent" - androidprv:topOffset="5px" - androidprv:bottomOffset="7px" - androidprv:handle="@+id/all_apps" - androidprv:content="@+id/content"> + android:topOffset="5dip" + android:bottomOffset="7dip" + android:handle="@+id/all_apps" + android:content="@+id/content"> <com.android.launcher.HandleView android:id="@id/all_apps" @@ -81,7 +80,7 @@ android:verticalSpacing="10dip" android:numColumns="4" /> - </com.android.internal.widget.SlidingDrawer> + </SlidingDrawer> <com.android.launcher.DeleteZone android:id="@+id/delete_zone" diff --git a/res/layout/add_list_item.xml b/res/layout/add_list_item.xml new file mode 100644 index 0000000..f276511 --- /dev/null +++ b/res/layout/add_list_item.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeight" + android:textAppearance="?android:attr/textAppearanceLargeInverse" + android:gravity="center_vertical" + android:drawablePadding="14dip" + android:paddingLeft="15dip" + android:paddingRight="15dip" /> diff --git a/res/layout/create_shortcut_list.xml b/res/layout/create_shortcut_list.xml index 63ca2b8..aa16733 100644 --- a/res/layout/create_shortcut_list.xml +++ b/res/layout/create_shortcut_list.xml @@ -17,11 +17,10 @@ ** limitations under the License. */ --> -<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android" +<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:layout_marginTop="5px" + android:layout_marginTop="5dip" android:cacheColorHint="@null" - android:childDivider="@android:drawable/divider_horizontal_bright" android:divider="@android:drawable/divider_horizontal_bright" android:scrollbars="vertical" /> diff --git a/res/layout/gadget_error.xml b/res/layout/gadget_error.xml new file mode 100644 index 0000000..bde07af --- /dev/null +++ b/res/layout/gadget_error.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="10dip" + android:paddingBottom="10dip" + android:paddingLeft="20dip" + android:paddingRight="20dip" + android:gravity="center" + android:background="@drawable/bg_gadget_error" + android:textAppearance="?android:attr/textAppearanceMediumInverse" + android:textColor="@color/gadget_error_color" + android:text="@string/gadget_error_text" + /> diff --git a/res/layout/widget_search.xml b/res/layout/widget_search.xml index 27e591d..dcc83a5 100644 --- a/res/layout/widget_search.xml +++ b/res/layout/widget_search.xml @@ -36,7 +36,7 @@ android:singleLine="true" android:selectAllOnFocus="true" android:completionThreshold="1" - android:inputType="textAutoComplete|textSearchString" + android:inputType="textAutoComplete|textSearch" /> <ImageButton android:id="@+id/search_go_btn" @@ -46,4 +46,10 @@ android:src="@*android:drawable/ic_btn_search" /> + <ImageButton android:id="@+id/search_voice_btn" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@android:drawable/ic_btn_speak_now" + /> + </com.android.launcher.Search> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index c5afda2..d7d98e9 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Přidat na plochu"</string> <string name="group_applications">"Aplikace"</string> <string name="group_shortcuts">"Zástupce"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Složka Live"</string> <string name="group_widgets">"Miniaplikace"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Tapeta"</string> <string name="add_folder">"Složka"</string> <string name="add_clock">"Hodiny"</string> <string name="add_photo_frame">"Rámeček fotografie"</string> <string name="add_search">"Vyhledávání"</string> <string name="out_of_space">"Na této ploše již není místo."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Přidat"</string> <string name="menu_wallpaper">"Tapeta"</string> <string name="menu_search">"Hledat"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"zápis nastavení a odkazů plochy"</string> <string name="permdesc_write_settings">"Povoluje aplikaci změnit nastavení a odkazy plochy."</string> <string name="search_hint">"Vyhledávání Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 3f0c42a..f8c4b61 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Zur Startseite hinzufügen"</string> <string name="group_applications">"Anwendung"</string> <string name="group_shortcuts">"Verknüpfung"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Live-Ordner"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Hintergrund"</string> <string name="add_folder">"Ordner"</string> <string name="add_clock">"Uhr"</string> <string name="add_photo_frame">"Bildrahmen"</string> <string name="add_search">"Suchen"</string> <string name="out_of_space">"Auf der Startseite ist kein Platz mehr vorhanden."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Hinzufügen"</string> <string name="menu_wallpaper">"Hintergrund"</string> <string name="menu_search">"Suchen"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"Einstellungen und Shortcuts für Startseite schreiben"</string> <string name="permdesc_write_settings">"Ermöglicht einer Anwendung, die Einstellungen und Shortcuts auf der Startseite zu ändern."</string> <string name="search_hint">"Google-Suche"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 161616d..96dbfa2 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Añadir a pantalla de página principal"</string> <string name="group_applications">"Aplicación"</string> <string name="group_shortcuts">"Acceso directo"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Carpeta activa"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Papel tapiz"</string> <string name="add_folder">"Carpeta"</string> <string name="add_clock">"Reloj"</string> <string name="add_photo_frame">"Picture frame"</string> <string name="add_search">"Búsqueda de Google"</string> <string name="out_of_space">"No queda espacio en esta pantalla de página principal."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Añadir"</string> <string name="menu_wallpaper">"Papel tapiz"</string> <string name="menu_search">"Búsqueda de Google"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"escribir información de accesos directos y de configuración de la página principal"</string> <string name="permdesc_write_settings">"Permite que una aplicación modifique la configuración y los accesos directos de la página principal."</string> <string name="search_hint">"Búsqueda de Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index effdc7a..3d14a22 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Ajouter à l\'écran d\'accueil"</string> <string name="group_applications">"Application"</string> <string name="group_shortcuts">"Raccourci"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Dossier live"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Arrière-plan"</string> <string name="add_folder">"Dossier"</string> <string name="add_clock">"Horloge"</string> <string name="add_photo_frame">"Cadre d\'image"</string> <string name="add_search">"Rechercher"</string> <string name="out_of_space">"Plus d\'espace libre sur l\'écran Accueil."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Ajouter"</string> <string name="menu_wallpaper">"Arrière-plan"</string> <string name="menu_search">"Rechercher"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"écrire les paramètres de la page d\'accueil et des raccourcis"</string> <string name="permdesc_write_settings">"Permet à une application de modifier les paramètres et les raccourcis de la page d\'accueil."</string> <string name="search_hint">"Recherche Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index d38fa30..8c79d13 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Aggiungi a schermata Home"</string> <string name="group_applications">"Applicazione"</string> <string name="group_shortcuts">"Collegamento"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Cartella dinamica"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Sfondo"</string> <string name="add_folder">"Cartella"</string> <string name="add_clock">"Orologio"</string> <string name="add_photo_frame">"Cornice immagini"</string> <string name="add_search">"Ricerca"</string> <string name="out_of_space">"Spazio nella schermata Home esaurito."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Aggiungi"</string> <string name="menu_wallpaper">"Sfondo"</string> <string name="menu_search">"Cerca"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"creare impostazioni e collegamenti in Home"</string> <string name="permdesc_write_settings">"Consente a un\'applicazione di modificare le impostazioni e i collegamenti in Home."</string> <string name="search_hint">"Ricerca Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index c3b1ff8..0e75314 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"ホーム画面に追加"</string> <string name="group_applications">"アプリケーション"</string> <string name="group_shortcuts">"ショートカット"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"ライブフォルダ"</string> <string name="group_widgets">"ウィジェット"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"壁紙"</string> <string name="add_folder">"フォルダ"</string> <string name="add_clock">"時計"</string> <string name="add_photo_frame">"写真フレーム"</string> <string name="add_search">"検索"</string> <string name="out_of_space">"このホーム画面には空きスペースがありません。"</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"追加"</string> <string name="menu_wallpaper">"壁紙"</string> <string name="menu_search">"検索"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"ホームの設定とショートカットの書き込み"</string> <string name="permdesc_write_settings">"ホームの設定とショートカットの変更をアプリケーションに許可します。"</string> <string name="search_hint">"Google検索"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml new file mode 100644 index 0000000..29cb53a --- /dev/null +++ b/res/values-ko/strings.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2009 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="application_name">"홈"</string> + <string name="folder_name">"폴더"</string> + <string name="chooser_wallpaper">"배경화면 선택"</string> + <string name="wallpaper_instructions">"배경화면 설정"</string> + <string name="pick_wallpaper">"배경화면 갤러리"</string> + <string name="activity_not_found">"전화기에 설치되어 있지 않은 응용프로그램입니다."</string> + <string name="rename_folder_label">"폴더 이름"</string> + <string name="rename_folder_title">"폴더 이름 바꾸기"</string> + <string name="rename_action">"확인"</string> + <string name="cancel_action">"취소"</string> + <string name="menu_item_add_item">"홈 화면에 추가"</string> + <string name="group_applications">"응용프로그램"</string> + <string name="group_shortcuts">"바로가기"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> + <string name="group_live_folders">"라이브 폴더"</string> + <string name="group_widgets">"위젯"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> + <string name="group_wallpapers">"배경화면"</string> + <string name="add_folder">"폴더"</string> + <string name="add_clock">"시계"</string> + <string name="add_photo_frame">"사진 프레임"</string> + <string name="add_search">"검색"</string> + <string name="out_of_space">"홈 화면에 더 이상 공간이 없습니다."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> + <string name="menu_add">"추가"</string> + <string name="menu_wallpaper">"배경화면"</string> + <string name="menu_search">"검색"</string> + <string name="menu_notifications">"알림"</string> + <string name="menu_settings">"설정"</string> + <string name="permlab_install_shortcut">"바로가기 설치"</string> + <string name="permdesc_install_shortcut">"응용프로그램이 사용자의 작업 없이 바로가기를 추가할 수 있도록 합니다."</string> + <string name="permlab_uninstall_shortcut">"바로가기 제거"</string> + <string name="permdesc_uninstall_shortcut">"응용프로그램이 사용자의 작업 없이 바로가기를 제거할 수 있도록 합니다."</string> + <string name="permlab_read_settings">"홈 설정 및 바로가기 읽기"</string> + <string name="permdesc_read_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 읽을 수 있습니다."</string> + <string name="permlab_write_settings">"홈 설정 및 바로가기 쓰기"</string> + <string name="permdesc_write_settings">"응용프로그램이 홈에 있는 설정 및 바로가기를 변경할 수 있습니다."</string> + <string name="search_hint">"Google 검색"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> +</resources> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml new file mode 100644 index 0000000..c485e6b --- /dev/null +++ b/res/values-nb/strings.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2009 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="application_name">"Hjem"</string> + <string name="folder_name">"Mappe"</string> + <string name="chooser_wallpaper">"Velg bakgrunnsbilde fra"</string> + <string name="wallpaper_instructions">"Velg bakgrunnsbilde"</string> + <string name="pick_wallpaper">"Bildegalleri"</string> + <string name="activity_not_found">"Applikasjonen er ikke installert."</string> + <string name="rename_folder_label">"Mappenavn"</string> + <string name="rename_folder_title">"Gi nytt navn til mappe"</string> + <string name="rename_action">"OK"</string> + <string name="cancel_action">"Avbryt"</string> + <string name="menu_item_add_item">"Legg til skrivebord"</string> + <string name="group_applications">"Applikasjon"</string> + <string name="group_shortcuts">"Snarvei"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> + <string name="group_live_folders">"Aktiv mappe"</string> + <string name="group_widgets">"Skrivebordselement"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> + <string name="group_wallpapers">"Bakgrunnsbilde"</string> + <string name="add_folder">"Mappe"</string> + <string name="add_clock">"Klokke"</string> + <string name="add_photo_frame">"Bilderamme"</string> + <string name="add_search">"Søk"</string> + <string name="out_of_space">"Ikke nok plass på skrivebordet."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> + <string name="menu_add">"Legg til"</string> + <string name="menu_wallpaper">"Bakgrunnsbilde"</string> + <string name="menu_search">"Søk"</string> + <string name="menu_notifications">"Varslinger"</string> + <string name="menu_settings">"Innstillinger"</string> + <string name="permlab_install_shortcut">"shortcuts"</string> + <string name="permdesc_install_shortcut">"Allows an application to add shortcuts without user intervention."</string> + <string name="permlab_uninstall_shortcut">"uninstall shortcuts"</string> + <string name="permdesc_uninstall_shortcut">"Allows an application to remove shortcuts without user intervention."</string> + <string name="permlab_read_settings">"read Home settings and shortcuts"</string> + <string name="permdesc_read_settings">"Allows an application to read the settings and shortcuts in Home."</string> + <string name="permlab_write_settings">"write Home settings and shortcuts"</string> + <string name="permdesc_write_settings">"Allows an application to change the settings and shortcuts in Home."</string> + <string name="search_hint">"Google-søk"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> +</resources> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 9e55d8f..bcb13ee 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Toevoegen aan startpagina"</string> <string name="group_applications">"Toepassing"</string> <string name="group_shortcuts">"Snelkoppeling"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Live map"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Achtergrond"</string> <string name="add_folder">"Map"</string> <string name="add_clock">"Klok"</string> <string name="add_photo_frame">"Fotolijstje"</string> <string name="add_search">"Zoeken"</string> <string name="out_of_space">"Er is geen ruimte meer op dit startscherm."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Toevoegen"</string> <string name="menu_wallpaper">"Achtergrond"</string> <string name="menu_search">"Zoeken"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"instellingen en snelkoppelingen voor de startpagina schrijven"</string> <string name="permdesc_write_settings">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string> <string name="search_hint">"Zoeken met Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 9356954..f5d4ca9 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -15,7 +15,7 @@ --> <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="application_name">"Strona główna"</string> + <string name="application_name">"Sieć"</string> <string name="folder_name">"Folder"</string> <string name="chooser_wallpaper">"Wybierz tapetę"</string> <string name="wallpaper_instructions">"Ustaw tapetę"</string> @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Dodaj do strony głównej"</string> <string name="group_applications">"Aplikacja"</string> <string name="group_shortcuts">"Skrót"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Folder Live"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Tapeta"</string> <string name="add_folder">"Folder"</string> <string name="add_clock">"Zegar"</string> <string name="add_photo_frame">"Ramka obrazu"</string> <string name="add_search">"Szukaj"</string> <string name="out_of_space">"Brak miejsca na tej stronie głównej"</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Dodaj"</string> <string name="menu_wallpaper">"Tapeta"</string> <string name="menu_search">"Szukaj"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"zapisywanie ustawień i skrótów strony głównej"</string> <string name="permdesc_write_settings">"Umożliwia aplikacji zmianę ustawień i skrótów strony głównej."</string> <string name="search_hint">"Szukaj w Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 9bb4787..d720e3b 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"Добавление на главный экран"</string> <string name="group_applications">"Приложение"</string> <string name="group_shortcuts">"Ярлык"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"Динамическая папка"</string> <string name="group_widgets">"Виджет"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"Фоновый рисунок"</string> <string name="add_folder">"Папка"</string> <string name="add_clock">"Часы"</string> <string name="add_photo_frame">"Рамка для картинки"</string> <string name="add_search">"Поиск"</string> <string name="out_of_space">"На главном экране больше нет места."</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"Добавить"</string> <string name="menu_wallpaper">"Фоновый рисунок"</string> <string name="menu_search">"Искать"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"записывать ярлыки и настройки главного экрана"</string> <string name="permdesc_write_settings">"Позволяет приложению изменять настройки и ярлыки на главном экране."</string> <string name="search_hint">"Поиск Google"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 72ffcf4..ec75139 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"添加到“主页”屏幕"</string> <string name="group_applications">"应用程序"</string> <string name="group_shortcuts">"快捷键"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"活动的文件夹"</string> <string name="group_widgets">"小工具"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"壁纸"</string> <string name="add_folder">"文件夹"</string> <string name="add_clock">"时钟"</string> <string name="add_photo_frame">"相框"</string> <string name="add_search">"搜索"</string> <string name="out_of_space">"该“主页”屏幕上没有多余空间。"</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"添加"</string> <string name="menu_wallpaper">"壁纸"</string> <string name="menu_search">"搜索"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"写入“主页”设置和快捷键"</string> <string name="permdesc_write_settings">"允许应用程序更改“主页”中的设置和快捷键。"</string> <string name="search_hint">"Google 搜索"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 35db622..aa4f951 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -28,14 +28,24 @@ <string name="menu_item_add_item">"新增至首頁畫面"</string> <string name="group_applications">"應用程式"</string> <string name="group_shortcuts">"捷徑"</string> + <!-- no translation found for group_search (5905328940867162196) --> + <skip /> + <!-- no translation found for group_folder (236213814675135523) --> + <skip /> <string name="group_live_folders">"使用中的資料夾"</string> <string name="group_widgets">"Widget"</string> + <!-- no translation found for group_gadgets (7795333306847768497) --> + <skip /> <string name="group_wallpapers">"桌布"</string> <string name="add_folder">"資料夾"</string> <string name="add_clock">"時鐘"</string> <string name="add_photo_frame">"相框"</string> <string name="add_search">"搜尋"</string> <string name="out_of_space">"首頁已無空間"</string> + <!-- no translation found for title_select_shortcut (2858897527672831763) --> + <skip /> + <!-- no translation found for title_select_live_folder (441136484932944782) --> + <skip /> <string name="menu_add">"新增"</string> <string name="menu_wallpaper">"桌布"</string> <string name="menu_search">"搜尋"</string> @@ -50,4 +60,6 @@ <string name="permlab_write_settings">"寫入首頁設定和捷徑"</string> <string name="permdesc_write_settings">"允許應用程式變更首頁中的設定和捷徑。"</string> <string name="search_hint">"Google 搜尋"</string> + <!-- no translation found for gadget_error_text (7654995305187314446) --> + <skip /> </resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index d4051f0..4a2aba3 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -22,4 +22,6 @@ <color name="grid_dark_background">#EB191919</color> <color name="bubble_dark_background">#B2191919</color> <color name="delete_color_filter">#A5FF0000</color> + + <color name="gadget_error_color">#fccc</color> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index c1d3455..ff41798 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -52,9 +52,16 @@ <string name="group_applications">Application</string> <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all shortcuts --> <string name="group_shortcuts">Shortcut</string> + <!-- Options in "Add to Home" dialog box; Title of the search gadget --> + <string name="group_search">Search</string> + <!-- Options in "Add to Home" dialog box; Title of the folder gadget --> + <string name="group_folder">Folder</string> + <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all live folders --> <string name="group_live_folders">Live folder</string> <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all widgets --> <string name="group_widgets">Widget</string> + <!-- Options in "Add to Home" dialog box; Title of the group containing the list of all gadgets --> + <string name="group_gadgets">Gadget</string> <!-- Options in "Add to Home" dialog box; Title of the group containing the list of apps that can set the wallpaper--> <string name="group_wallpapers">Wallpaper</string> <!-- Options in "Add to Home" dialog box; Name of the Folder widget--> @@ -68,6 +75,11 @@ <!-- Error message when user has filled a home screen, possibly not used --> <string name="out_of_space">No more room on this Home screen.</string> + <!-- Title of dialog when user is selecting shortcut to add to homescreen --> + <string name="title_select_shortcut">Select shortcut</string> + <!-- Title of dialog when user is selecting live folder to add to homescreen --> + <string name="title_select_live_folder">Select live folder</string> + <!-- Menus items: --> <skip /> <!-- Verb, menu item used to add an item on the desktop --> @@ -101,5 +113,8 @@ This translation SHOULD MATCH the string "search_hint" which is found in GoogleSearch/res/values/strings.xml --> <string name="search_hint">Google Search</string> - + + <!-- Text to show user in place of a gadget when we can't display it properly --> + <string name="gadget_error_text">Problem loading gadget</string> + </resources> diff --git a/src/com/android/launcher/AddAdapter.java b/src/com/android/launcher/AddAdapter.java index 8eebe39..1410708 100644 --- a/src/com/android/launcher/AddAdapter.java +++ b/src/com/android/launcher/AddAdapter.java @@ -16,456 +16,111 @@ package com.android.launcher; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.BaseAdapter; import android.widget.TextView; -import android.widget.BaseExpandableListAdapter; -import android.graphics.drawable.Drawable; -import android.provider.LiveFolders; import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** - * Shows a list of all the items that can be added to the workspace. + * Adapter showing the types of items that can be added to a {@link Workspace}. */ -public final class AddAdapter extends BaseExpandableListAdapter { - private static final int GROUP_APPLICATIONS = 0; - private static final int GROUP_SHORTCUTS = 1; - private static final int GROUP_WIDGETS = 2; - private static final int GROUP_LIVE_FOLDERS = 3; - private static final int GROUP_WALLPAPERS = 4; - - private final Intent mCreateShortcutIntent; - private final Intent mCreateLiveFolderIntent; - private Intent mSetWallpaperIntent; +public class AddAdapter extends BaseAdapter { + + private final Launcher mLauncher; private final LayoutInflater mInflater; - private Launcher mLauncher; - private Group[] mGroups; - - /** - * Abstract class representing one thing that can be added - */ - public abstract class AddAction implements Runnable { - protected final Context mContext; - - AddAction(Context context) { - mContext = context; - } - - Drawable getIcon(int resource) { - return mContext.getResources().getDrawable(resource); - } - - public abstract void bindView(View v); - } - - /** - * Class representing an action that will create set the wallpaper. - */ - public class SetWallpaperAction extends CreateShortcutAction { - SetWallpaperAction(Context context, ResolveInfo info) { - super(context, info); - } - - public void run() { - Intent intent = new Intent(mSetWallpaperIntent); - ActivityInfo activityInfo = mInfo.activityInfo; - intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName, - activityInfo.name)); - mLauncher.startActivity(intent); - } - } + + private final ArrayList<ListItem> mItems = new ArrayList<ListItem>(); + + public static final int ITEM_APPLICATION = 0; + public static final int ITEM_SHORTCUT = 1; + public static final int ITEM_SEARCH = 2; + public static final int ITEM_GADGET = 3; + public static final int ITEM_LIVE_FOLDER = 4; + public static final int ITEM_FOLDER = 5; + public static final int ITEM_WALLPAPER = 6; /** - * Class representing an action that will create a specific type - * of shortcut + * Specific item in our list. */ - public class CreateShortcutAction extends AddAction { + public class ListItem { + public final CharSequence text; + public final Drawable image; + public final int actionTag; - ResolveInfo mInfo; - private CharSequence mLabel; - private Drawable mIcon; - - CreateShortcutAction(Context context, ResolveInfo info) { - super(context); - mInfo = info; - } - - @Override - public void bindView(View view) { - ResolveInfo info = mInfo; - TextView text = (TextView) view; - - PackageManager pm = mLauncher.getPackageManager(); - - if (mLabel == null) { - mLabel = info.loadLabel(pm); - if (mLabel == null) { - mLabel = info.activityInfo.name; - } + public ListItem(Resources res, int textResourceId, int imageResourceId, int actionTag) { + text = res.getString(textResourceId); + if (imageResourceId != -1) { + image = res.getDrawable(imageResourceId); + } else { + image = null; } - - if (mIcon == null) { - mIcon = Utilities.createIconThumbnail(info.loadIcon(pm), mContext); - } - - text.setText(mLabel); - text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null); - } - - public void run() { - Intent intent = new Intent(mCreateShortcutIntent); - ActivityInfo activityInfo = mInfo.activityInfo; - intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName, - activityInfo.name)); - mLauncher.addShortcut(intent); - } - } - - /** - * Class representing an action that will create a specific type - * of live folder - */ - public class CreateLiveFolderAction extends CreateShortcutAction { - CreateLiveFolderAction(Context context, ResolveInfo info) { - super(context, info); - } - - @Override - public void run() { - Intent intent = new Intent(mCreateLiveFolderIntent); - ActivityInfo activityInfo = mInfo.activityInfo; - intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName, - activityInfo.name)); - mLauncher.addLiveFolder(intent); - } - } - - /** - * Class representing an action that will add a folder - */ - public class CreateFolderAction extends AddAction { - private Drawable mIcon; - - CreateFolderAction(Context context) { - super(context); - } - - @Override - public void bindView(View view) { - TextView text = (TextView) view; - text.setText(R.string.add_folder); - if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_folder); - text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null); - } - - public void run() { - mLauncher.addFolder(); - } - } - - /** - * Class representing an action that will add a folder - */ - public class CreateClockAction extends AddAction { - - CreateClockAction(Context context) { - super(context); - } - - @Override - public void bindView(View view) { - TextView text = (TextView) view; - text.setText(R.string.add_clock); - Drawable icon = getIcon(R.drawable.ic_launcher_alarmclock); - text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); - } - - public void run() { - mLauncher.addClock(); - } - } - - /** - * Class representing an action that will add a PhotoFrame - */ - public class CreatePhotoFrameAction extends AddAction { - private Drawable mIcon; - - CreatePhotoFrameAction(Context context) { - super(context); - } - - @Override - public void bindView(View view) { - TextView text = (TextView) view; - text.setText(R.string.add_photo_frame); - if (mIcon == null) mIcon = getIcon(R.drawable.ic_launcher_gallery); - text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null); - } - - public void run() { - mLauncher.getPhotoForPhotoFrame(); - } - } - - - /** - * Class representing an action that will add a Search widget - */ - public class CreateSearchAction extends AddAction { - private Drawable mIcon; - - CreateSearchAction(Context context) { - super(context); - } - - @Override - public void bindView(View view) { - TextView text = (TextView) view; - text.setText(R.string.add_search); - if (mIcon == null) mIcon = getIcon(R.drawable.ic_search_gadget); - text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null); - } - - public void run() { - mLauncher.addSearch(); + this.actionTag = actionTag; } } - private class Group { - private String mName; - private ArrayList<AddAction> mList; - - Group(String name) { - mName = name; - mList = new ArrayList<AddAction>(); - } - - void add(AddAction action) { - mList.add(action); - } - - int size() { - return mList.size(); - } - - String getName() { - return mName; - } - - void run(int position) { - mList.get(position).run(); - } - - void bindView(int childPosition, View view) { - mList.get(childPosition).bindView(view); - } - - public Object get(int childPosition) { - return mList.get(childPosition); - } - } - - private class ApplicationsGroup extends Group { - private final Launcher mLauncher; - private final ArrayList<ApplicationInfo> mApplications; - - ApplicationsGroup(Launcher launcher, String name) { - super(name); - mLauncher = launcher; - mApplications = Launcher.getModel().getApplications(); - } - - @Override - int size() { - return mApplications == null ? 0 : mApplications.size(); - } - - @Override - void add(AddAction action) { - } - - @Override - void run(int position) { - final ApplicationInfo info = mApplications.get(position); - mLauncher.addApplicationShortcut(info); - } - - @Override - void bindView(int childPosition, View view) { - TextView text = (TextView) view.findViewById(R.id.title); - - final ApplicationInfo info = mApplications.get(childPosition); - text.setText(info.title); - if (!info.filtered) { - info.icon = Utilities.createIconThumbnail(info.icon, mLauncher); - info.filtered = true; - } - text.setCompoundDrawablesWithIntrinsicBounds(info.icon, null, null, null); - } - - @Override - public Object get(int childPosition) { - return mApplications.get(childPosition); - } - } - - public AddAdapter(Launcher launcher, boolean forFolder) { - mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); - mCreateShortcutIntent.setComponent(null); - - mCreateLiveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER); - mCreateLiveFolderIntent.setComponent(null); - - mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER); - mSetWallpaperIntent.setComponent(null); - + public AddAdapter(Launcher launcher) { + super(); + mLauncher = launcher; - mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - mGroups = new Group[forFolder ? 2 : 5]; - final Group[] groups = mGroups; - groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher, - mLauncher.getString(R.string.group_applications)); - groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts)); - groups[GROUP_LIVE_FOLDERS] = new Group(mLauncher.getString(R.string.group_live_folders)); - - if (!forFolder) { - groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers)); - groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher)); - groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets)); - - final Group widgets = groups[GROUP_WIDGETS]; - widgets.add(new CreateClockAction(launcher)); - widgets.add(new CreatePhotoFrameAction(launcher)); - widgets.add(new CreateSearchAction(launcher)); - } + mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - PackageManager packageManager = launcher.getPackageManager(); - - List<ResolveInfo> list = findTargetsForIntent(mCreateShortcutIntent, packageManager); - if (list != null && list.size() > 0) { - int count = list.size(); - final Group shortcuts = groups[GROUP_SHORTCUTS]; - for (int i = 0; i < count; i++) { - ResolveInfo resolveInfo = list.get(i); - shortcuts.add(new CreateShortcutAction(launcher, resolveInfo)); - } - } - - list = findTargetsForIntent(mCreateLiveFolderIntent, packageManager); - if (list != null && list.size() > 0) { - int count = list.size(); - final Group shortcuts = groups[GROUP_LIVE_FOLDERS]; - for (int i = 0; i < count; i++) { - ResolveInfo resolveInfo = list.get(i); - shortcuts.add(new CreateLiveFolderAction(launcher, resolveInfo)); - } - } - - list = findTargetsForIntent(mSetWallpaperIntent, packageManager); - if (list != null && list.size() > 0) { - int count = list.size(); - final Group shortcuts = groups[GROUP_WALLPAPERS]; - for (int i = 0; i < count; i++) { - ResolveInfo resolveInfo = list.get(i); - shortcuts.add(new SetWallpaperAction(launcher, resolveInfo)); - } - } - } - - private List<ResolveInfo> findTargetsForIntent(Intent intent, PackageManager packageManager) { - List<ResolveInfo> list = packageManager.queryIntentActivities(intent, - PackageManager.MATCH_DEFAULT_ONLY); - if (list != null) { - int count = list.size(); - if (count > 1) { - // Only display the first matches that are either of equal - // priority or have asked to be default options. - ResolveInfo firstInfo = list.get(0); - for (int i=1; i<count; i++) { - ResolveInfo resolveInfo = list.get(i); - if (firstInfo.priority != resolveInfo.priority || - firstInfo.isDefault != resolveInfo.isDefault) { - while (i < count) { - list.remove(i); - count--; - } - } - } - Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager)); - } - } - return list; - } - - public int getGroupCount() { - return mGroups.length; - } - - public int getChildrenCount(int groupPosition) { - return mGroups[groupPosition].size(); - } - - public Object getGroup(int groupPosition) { - return mGroups[groupPosition].getName(); - } - - public Object getChild(int groupPosition, int childPosition) { - return mGroups[groupPosition].get(childPosition); - } - - public long getGroupId(int groupPosition) { - return groupPosition; - } - - public long getChildId(int groupPosition, int childPosition) { - return (groupPosition << 16) | childPosition; - } + // Create default actions + Resources res = launcher.getResources(); + + mItems.add(new ListItem(res, R.string.group_applications, + R.drawable.ic_launcher_application, ITEM_APPLICATION)); + + mItems.add(new ListItem(res, R.string.group_shortcuts, + R.drawable.ic_launcher_empty, ITEM_SHORTCUT)); + + mItems.add(new ListItem(res, R.string.group_search, + R.drawable.ic_search_gadget, ITEM_SEARCH)); + + mItems.add(new ListItem(res, R.string.group_gadgets, + R.drawable.ic_launcher_gadget, ITEM_GADGET)); + + mItems.add(new ListItem(res, R.string.group_live_folders, + R.drawable.ic_launcher_empty, ITEM_LIVE_FOLDER)); + + mItems.add(new ListItem(res, R.string.group_folder, + R.drawable.ic_launcher_folder, ITEM_FOLDER)); + + mItems.add(new ListItem(res, R.string.group_wallpapers, + R.drawable.ic_launcher_gallery, ITEM_WALLPAPER)); - public boolean hasStableIds() { - return true; } - public View getGroupView(int groupPosition, boolean isExpanded, - View convertView, ViewGroup parent) { - View view; + public View getView(int position, View convertView, ViewGroup parent) { + ListItem item = (ListItem) getItem(position); + if (convertView == null) { - view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false); - } else { - view = convertView; + convertView = mInflater.inflate(R.layout.add_list_item, parent, false); } - ((TextView) view).setText(mGroups[groupPosition].getName()); - return view; + + TextView textView = (TextView) convertView; + textView.setTag(item); + textView.setText(item.text); + textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null); + + return convertView; } - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, - View convertView, ViewGroup parent) { - View view; - if (convertView == null) { - view = mInflater.inflate(R.layout.create_shortcut_list_item, parent, false); - } else { - view = convertView; - } - mGroups[groupPosition].bindView(childPosition, view); - return view; + public int getCount() { + return mItems.size(); } - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; + public Object getItem(int position) { + return mItems.get(position); } - void performAction(int groupPosition, int childPosition) { - mGroups[groupPosition].run(childPosition); + public long getItemId(int position) { + return position; } + } diff --git a/src/com/android/launcher/BubbleTextView.java b/src/com/android/launcher/BubbleTextView.java index f2c31e9..3782454 100644 --- a/src/com/android/launcher/BubbleTextView.java +++ b/src/com/android/launcher/BubbleTextView.java @@ -40,6 +40,9 @@ public class BubbleTextView extends TextView { private boolean mBackgroundSizeChanged; private Drawable mBackground; + private float mCornerRadius; + private float mPaddingH; + private float mPaddingV; public BubbleTextView(Context context) { super(context); @@ -64,6 +67,12 @@ public class BubbleTextView extends TextView { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(getContext().getResources().getColor(R.color.bubble_dark_background)); + + final float scale = getContext().getResources().getDisplayMetrics().density; + mCornerRadius = CORNER_RADIUS * scale; + mPaddingH = PADDING_H * scale; + //noinspection PointlessArithmeticExpression + mPaddingV = PADDING_V * scale; } @Override @@ -114,11 +123,11 @@ public class BubbleTextView extends TextView { final int left = getCompoundPaddingLeft(); final int top = getExtendedPaddingTop(); - rect.set(left + layout.getLineLeft(0) - PADDING_H, - top + layout.getLineTop(0) - PADDING_V, - Math.min(left + layout.getLineRight(0) + PADDING_H, mScrollX + mRight - mLeft), - top + layout.getLineBottom(0) + PADDING_V); - canvas.drawRoundRect(rect, CORNER_RADIUS, CORNER_RADIUS, mPaint); + rect.set(left + layout.getLineLeft(0) - mPaddingH, + top + layout.getLineTop(0) - mPaddingV, + Math.min(left + layout.getLineRight(0) + mPaddingH, mScrollX + mRight - mLeft), + top + layout.getLineBottom(0) + mPaddingV); + canvas.drawRoundRect(rect, mCornerRadius, mCornerRadius, mPaint); super.draw(canvas); } diff --git a/src/com/android/launcher/CellLayout.java b/src/com/android/launcher/CellLayout.java index 02646bf..3e5a74a 100644 --- a/src/com/android/launcher/CellLayout.java +++ b/src/com/android/launcher/CellLayout.java @@ -56,6 +56,8 @@ public class CellLayout extends ViewGroup { private RectF mDragRect = new RectF(); + private boolean mDirtyTag; + public CellLayout(Context context) { this(context, null); } @@ -157,6 +159,7 @@ public class CellLayout extends ViewGroup { cellInfo.spanY = lp.cellVSpan; cellInfo.valid = true; found = true; + mDirtyTag = false; break; } } @@ -181,10 +184,12 @@ public class CellLayout extends ViewGroup { cellInfo.valid = cellXY[0] >= 0 && cellXY[1] >= 0 && cellXY[0] < xCount && cellXY[1] < yCount && !occupied[cellXY[0]][cellXY[1]]; - if (cellInfo.valid) { - findIntersectingVacantCells(cellInfo, cellXY[0], cellXY[1], - xCount, yCount, occupied); - } + // Instead of finding the interesting vacant cells here, wait until a + // caller invokes getTag() to retrieve the result. Finding the vacant + // cells is a bit expensive and can generate many new objects, it's + // therefore better to defer it until we know we actually need it. + + mDirtyTag = true; } setTag(cellInfo); } else if (action == MotionEvent.ACTION_UP) { @@ -194,12 +199,31 @@ public class CellLayout extends ViewGroup { cellInfo.spanX = 0; cellInfo.spanY = 0; cellInfo.valid = false; + mDirtyTag = false; setTag(cellInfo); } return false; } + @Override + public CellInfo getTag() { + final CellInfo info = (CellInfo) super.getTag(); + if (mDirtyTag && info.valid) { + final boolean portrait = mPortrait; + final int xCount = portrait ? mShortAxisCells : mLongAxisCells; + final int yCount = portrait ? mLongAxisCells : mShortAxisCells; + + final boolean[][] occupied = mOccupied; + findOccupiedCells(xCount, yCount, occupied); + + findIntersectingVacantCells(info, info.cellX, info.cellY, xCount, yCount, occupied); + + mDirtyTag = false; + } + return info; + } + private static void findIntersectingVacantCells(CellInfo cellInfo, int x, int y, int xCount, int yCount, boolean[][] occupied) { @@ -207,14 +231,15 @@ public class CellLayout extends ViewGroup { cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE; - cellInfo.vacantCells = new ArrayList<CellInfo.VacantCell>(); + cellInfo.clearVacantCells(); if (occupied[x][y]) { return; } - Rect current = new Rect(x, y, x, y); - findVacantCell(current, xCount, yCount, occupied, cellInfo); + cellInfo.current.set(x, y, x, y); + + findVacantCell(cellInfo.current, xCount, yCount, occupied, cellInfo); } private static void findVacantCell(Rect current, int xCount, int yCount, boolean[][] occupied, @@ -256,7 +281,7 @@ public class CellLayout extends ViewGroup { } private static void addVacantCell(Rect current, CellInfo cellInfo) { - CellInfo.VacantCell cell = new CellInfo.VacantCell(); + CellInfo.VacantCell cell = CellInfo.VacantCell.acquire(); cell.cellX = current.left; cell.cellY = current.top; cell.spanX = current.right - current.left + 1; @@ -317,10 +342,9 @@ public class CellLayout extends ViewGroup { cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanY = Integer.MIN_VALUE; cellInfo.maxVacantSpanYSpanX = Integer.MIN_VALUE; - cellInfo.vacantCells = new ArrayList<CellInfo.VacantCell>(); cellInfo.screen = mCellInfo.screen; - Rect current = new Rect(); + Rect current = cellInfo.current; for (int x = 0; x < xCount; x++) { for (int y = 0; y < yCount; y++) { @@ -634,6 +658,26 @@ public class CellLayout extends ViewGroup { dragRect.set(x, y, x + width, y + height); } + + /** + * Computes the required horizontal and vertical cell spans to always + * fit the given rectangle. + * + * @param width Width in pixels + * @param height Height in pixels + * @param cellInfo {@link CellInfo} to fill with calculated span parameters + */ + public void rectToCell(int width, int height, CellInfo cellInfo) { + // Always assume we're working with the smallest span to make sure we + // reserve enough space in both orientations. + int actualWidth = mCellWidth + mWidthGap; + int actualHeight = mCellHeight + mHeightGap; + int smallerSize = Math.min(actualWidth, actualHeight); + + // Always round up to next largest cell + cellInfo.spanX = (width + smallerSize) / smallerSize; + cellInfo.spanY = (height + smallerSize) / smallerSize; + } /** * Find the first vacant cell, if there is one. @@ -811,12 +855,54 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { } static final class CellInfo implements ContextMenu.ContextMenuInfo { + /** + * See View.AttachInfo.InvalidateInfo for futher explanations about + * the recycling mechanism. In this case, we recycle the vacant cells + * instances because up to several hundreds can be instanciated when + * the user long presses an empty cell. + */ static final class VacantCell { int cellX; int cellY; int spanX; int spanY; + // We can create up to 523 vacant cells on a 4x4 grid, 100 seems + // like a reasonable compromise given the size of a VacantCell and + // the fact that the user is not likely to touch an empty 4x4 grid + // very often + private static final int POOL_LIMIT = 100; + private static final Object sLock = new Object(); + + private static int sAcquiredCount = 0; + private static VacantCell sRoot; + + private VacantCell next; + + static VacantCell acquire() { + synchronized (sLock) { + if (sRoot == null) { + return new VacantCell(); + } + + VacantCell info = sRoot; + sRoot = info.next; + sAcquiredCount--; + + return info; + } + } + + void release() { + synchronized (sLock) { + if (sAcquiredCount < POOL_LIMIT) { + sAcquiredCount++; + next = sRoot; + sRoot = this; + } + } + } + @Override public String toString() { return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX=" + spanX + @@ -832,17 +918,27 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { int screen; boolean valid; - ArrayList<VacantCell> vacantCells; + final ArrayList<VacantCell> vacantCells = new ArrayList<VacantCell>(VacantCell.POOL_LIMIT); int maxVacantSpanX; int maxVacantSpanXSpanY; int maxVacantSpanY; int maxVacantSpanYSpanX; + final Rect current = new Rect(); + + private void clearVacantCells() { + final ArrayList<VacantCell> list = vacantCells; + final int count = list.size(); + + for (int i = 0; i < count; i++) list.get(i).release(); + + list.clear(); + } void findVacantCellsFromOccupied(boolean[] occupied, int xCount, int yCount) { if (cellX < 0 || cellY < 0) { maxVacantSpanX = maxVacantSpanXSpanY = Integer.MIN_VALUE; maxVacantSpanY = maxVacantSpanYSpanX = Integer.MIN_VALUE; - vacantCells = new ArrayList<VacantCell>(); + clearVacantCells(); return; } @@ -855,26 +951,40 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { CellLayout.findIntersectingVacantCells(this, cellX, cellY, xCount, yCount, unflattened); } + /** + * This method can be called only once! Calling #findVacantCellsFromOccupied will + * restore the ability to call this method. + * + * Finds the upper-left coordinate of the first rectangle in the grid that can + * hold a cell of the specified dimensions. + * + * @param cellXY The array that will contain the position of a vacant cell if such a cell + * can be found. + * @param spanX The horizontal span of the cell we want to find. + * @param spanY The vertical span of the cell we want to find. + * + * @return True if a vacant cell of the specified dimension was found, false otherwise. + */ boolean findCellForSpan(int[] cellXY, int spanX, int spanY) { - if (vacantCells == null) { - return false; - } + final ArrayList<VacantCell> list = vacantCells; + final int count = list.size(); + + boolean found = false; if (this.spanX >= spanX && this.spanY >= spanY) { cellXY[0] = cellX; cellXY[1] = cellY; - return true; + found = true; } - final ArrayList<VacantCell> list = vacantCells; - final int count = list.size(); // Look for an exact match first for (int i = 0; i < count; i++) { VacantCell cell = list.get(i); if (cell.spanX == spanX && cell.spanY == spanY) { cellXY[0] = cell.cellX; cellXY[1] = cell.cellY; - return true; + found = true; + break; } } @@ -884,11 +994,14 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { if (cell.spanX >= spanX && cell.spanY >= spanY) { cellXY[0] = cell.cellX; cellXY[1] = cell.cellY; - return true; + found = true; + break; } } - return false; + clearVacantCells(); + + return found; } @Override diff --git a/src/com/android/launcher/DeleteZone.java b/src/com/android/launcher/DeleteZone.java index 798cf0d..6f67884 100644 --- a/src/com/android/launcher/DeleteZone.java +++ b/src/com/android/launcher/DeleteZone.java @@ -97,6 +97,12 @@ public class DeleteZone extends ImageView implements DropTarget, DragController. final UserFolderInfo userFolderInfo = (UserFolderInfo)item; LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo); model.removeUserFolder(userFolderInfo); + } else if (item instanceof LauncherGadgetInfo) { + final LauncherGadgetInfo launcherGadgetInfo = (LauncherGadgetInfo)item; + final LauncherGadgetHost gadgetHost = mLauncher.getGadgetHost(); + if (gadgetHost != null) { + gadgetHost.deleteGadgetId(launcherGadgetInfo.gadgetId); + } } LauncherModel.deleteItemFromDatabase(mLauncher, item); } diff --git a/src/com/android/launcher/DragLayer.java b/src/com/android/launcher/DragLayer.java index 56140dd..aa6615a 100644 --- a/src/com/android/launcher/DragLayer.java +++ b/src/com/android/launcher/DragLayer.java @@ -320,40 +320,33 @@ public class DragLayer extends FrameLayout implements DragController { break; case MotionEvent.ACTION_MOVE: - if (Launcher.sOpenGlEnabled) { - mLastMotionX = x; - mLastMotionY = y; + final int scrollX = mScrollX; + final int scrollY = mScrollY; - invalidate(); - } else { - final int scrollX = mScrollX; - final int scrollY = mScrollY; + final float touchX = mTouchOffsetX; + final float touchY = mTouchOffsetY; - final float touchX = mTouchOffsetX; - final float touchY = mTouchOffsetY; + final int offsetX = mBitmapOffsetX; + final int offsetY = mBitmapOffsetY; - final int offsetX = mBitmapOffsetX; - final int offsetY = mBitmapOffsetY; + int left = (int) (scrollX + mLastMotionX - touchX - offsetX); + int top = (int) (scrollY + mLastMotionY - touchY - offsetY); - int left = (int) (scrollX + mLastMotionX - touchX - offsetX); - int top = (int) (scrollY + mLastMotionY - touchY - offsetY); + final Bitmap dragBitmap = mDragBitmap; + final int width = dragBitmap.getWidth(); + final int height = dragBitmap.getHeight(); - final Bitmap dragBitmap = mDragBitmap; - final int width = dragBitmap.getWidth(); - final int height = dragBitmap.getHeight(); + final Rect rect = mRect; + rect.set(left - 1, top - 1, left + width + 1, top + height + 1); - final Rect rect = mRect; - rect.set(left - 1, top - 1, left + width + 1, top + height + 1); - - mLastMotionX = x; - mLastMotionY = y; + mLastMotionX = x; + mLastMotionY = y; - left = (int) (scrollX + x - touchX - offsetX); - top = (int) (scrollY + y - touchY - offsetY); + left = (int) (scrollX + x - touchX - offsetX); + top = (int) (scrollY + y - touchY - offsetY); - rect.union(left - 1, top - 1, left + width + 1, top + height + 1); - invalidate(rect); - } + rect.union(left - 1, top - 1, left + width + 1, top + height + 1); + invalidate(rect); final int[] coordinates = mDropCoordinates; DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); diff --git a/src/com/android/launcher/ItemInfo.java b/src/com/android/launcher/ItemInfo.java index 61745dd..8899f44 100644 --- a/src/com/android/launcher/ItemInfo.java +++ b/src/com/android/launcher/ItemInfo.java @@ -38,10 +38,8 @@ class ItemInfo { /** * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION}, * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT}, - * {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, - * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_CLOCK}, - * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_SEARCH} or - * {@link LauncherSettings.Favorites#ITEM_TYPE_WIDGET_PHOTO_FRAME}, + * {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, or + * {@link LauncherSettings.Favorites#ITEM_TYPE_GADGET}. */ int itemType; diff --git a/src/com/android/launcher/Launcher.java b/src/com/android/launcher/Launcher.java index 465400b..293abe8 100644 --- a/src/com/android/launcher/Launcher.java +++ b/src/com/android/launcher/Launcher.java @@ -24,16 +24,21 @@ import android.app.SearchManager; import android.app.StatusBarManager; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.Configuration; import android.database.ContentObserver; +import android.gadget.GadgetInfo; +import android.gadget.GadgetManager; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -64,16 +69,15 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.View.OnLongClickListener; import android.view.inputmethod.InputMethodManager; +import android.widget.AdapterView; import android.widget.EditText; -import android.widget.ExpandableListView; -import android.widget.ImageView; +import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.GridView; +import android.widget.SlidingDrawer; import android.app.IWallpaperService; -import com.android.internal.widget.SlidingDrawer; - import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -86,8 +90,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On private static final boolean PROFILE_STARTUP = false; private static final boolean DEBUG_USER_INTERFACE = false; - private static final boolean REMOVE_SHORTCUT_ON_PACKAGE_REMOVE = false; - private static final int WALLPAPER_SCREENS_SPAN = 2; private static final int MENU_GROUP_ADD = 1; @@ -98,9 +100,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On private static final int MENU_SETTINGS = MENU_NOTIFICATIONS + 1; private static final int REQUEST_CREATE_SHORTCUT = 1; - private static final int REQUEST_CHOOSE_PHOTO = 2; - private static final int REQUEST_UPDATE_PHOTO = 3; private static final int REQUEST_CREATE_LIVE_FOLDER = 4; + private static final int REQUEST_CREATE_GADGET = 5; + private static final int REQUEST_PICK_APPLICATION = 6; + private static final int REQUEST_PICK_SHORTCUT = 7; + private static final int REQUEST_PICK_LIVE_FOLDER = 8; + private static final int REQUEST_PICK_GADGET = 9; static final String EXTRA_SHORTCUT_DUPLICATE = "duplicate"; @@ -148,10 +153,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On private static Bitmap sWallpaper; - // Indicates whether the OpenGL pipeline was enabled, either through - // USE_OPENGL_BY_DEFAULT or the system property launcher.opengl - static boolean sOpenGlEnabled; - private static final Object sLock = new Object(); private static int sScreen = DEFAULT_SCREN; @@ -164,7 +165,12 @@ public final class Launcher extends Activity implements View.OnClickListener, On private DragLayer mDragLayer; private Workspace mWorkspace; - + + private GadgetManager mGadgetManager; + private LauncherGadgetHost mGadgetHost; + + private static final int GADGET_HOST_ID = 1024; + private CellLayout.CellInfo mAddItemCellInfo; private CellLayout.CellInfo mMenuAddInfo; private final int[] mCellCoordinates = new int[2]; @@ -189,6 +195,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mInflater = getLayoutInflater(); + + mGadgetManager = GadgetManager.getInstance(this); + mGadgetHost = new LauncherGadgetHost(this, GADGET_HOST_ID); + + // TODO: figure out if this is first launch and correctly clear GadgetHost database if (PROFILE_STARTUP) { android.os.Debug.startMethodTracing("/sdcard/launcher"); @@ -223,6 +234,18 @@ public final class Launcher extends Activity implements View.OnClickListener, On Selection.setSelection(mDefaultKeySsb, 0); } + @Override + protected void onStart() { + super.onStart(); + mGadgetHost.startListening(); + } + + @Override + protected void onStop() { + super.onStop(); + mGadgetHost.stopListening(); + } + private void checkForLocaleChange() { final SharedPreferences preferences = getSharedPreferences(PREFERENCES, MODE_PRIVATE); final Configuration configuration = getResources().getConfiguration(); @@ -283,20 +306,42 @@ public final class Launcher extends Activity implements View.OnClickListener, On @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + // The pattern used here is that a user PICKs a specific application, + // which, depending on the target, might need to CREATE the actual target. + + // For example, the user would PICK_SHORTCUT for "Music playlist", and we + // launch over to the Music app to actually CREATE_SHORTCUT. + if (resultCode == RESULT_OK && mAddItemCellInfo != null) { switch (requestCode) { + case REQUEST_PICK_APPLICATION: + completeAddApplication(this, data, mAddItemCellInfo); + break; + case REQUEST_PICK_SHORTCUT: + addShortcut(data); + break; case REQUEST_CREATE_SHORTCUT: completeAddShortcut(data, mAddItemCellInfo, !mDesktopLocked); break; - case REQUEST_CHOOSE_PHOTO: - completeAddPhotoFrame(data, mAddItemCellInfo); - break; - case REQUEST_UPDATE_PHOTO: - completeUpdatePhotoFrame(data, mAddItemCellInfo); + case REQUEST_PICK_LIVE_FOLDER: + addLiveFolder(data); break; case REQUEST_CREATE_LIVE_FOLDER: completeAddLiveFolder(data, mAddItemCellInfo, !mDesktopLocked); break; + case REQUEST_PICK_GADGET: + addGadget(data); + break; + case REQUEST_CREATE_GADGET: + completeAddGadget(data, mAddItemCellInfo, !mDesktopLocked); + break; + } + } else if (requestCode == REQUEST_PICK_GADGET && + resultCode == RESULT_CANCELED && data != null) { + // Clean up the gadgetId if we canceled + int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1); + if (gadgetId != -1) { + mGadgetHost.deleteGadgetId(gadgetId); } } mWaitingForResult = false; @@ -398,7 +443,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On mRestoring = true; } - boolean renameFolder = savedState.getBoolean(RUNTIME_STATE_PENDING_FOLDER_RENAME, false); if (renameFolder) { long id = savedState.getLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID); @@ -439,10 +483,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On grid.setTextFilterEnabled(true); grid.setDragger(dragLayer); grid.setLauncher(this); - if (sOpenGlEnabled) { - grid.setScrollingCacheEnabled(false); - grid.setFadingEdgeLength(0); - } workspace.setOnLongClickListener(this); workspace.setDragger(dragLayer); @@ -456,18 +496,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On dragLayer.setIgnoredDropTarget(grid); dragLayer.setDragScoller(workspace); dragLayer.setDragListener(deleteZone); - - if (DEBUG_USER_INTERFACE) { - android.widget.Button finishButton = new android.widget.Button(this); - finishButton.setText("Finish"); - workspace.addInScreen(finishButton, 1, 0, 0, 1, 1); - - finishButton.setOnClickListener(new android.widget.Button.OnClickListener() { - public void onClick(View v) { - finish(); - } - }); - } } /** @@ -507,11 +535,42 @@ public final class Launcher extends Activity implements View.OnClickListener, On return favorite; } - void addApplicationShortcut(ApplicationInfo info) { - mAddItemCellInfo.screen = mWorkspace.getCurrentScreen(); - mWorkspace.addApplicationShortcut(info, mAddItemCellInfo); - } + /** + * Add an application shortcut to the workspace. + * + * @param data The intent describing the application. + * @param cellInfo The position on screen where to create the shortcut. + */ + void completeAddApplication(Context context, Intent data, CellLayout.CellInfo cellInfo) { + cellInfo.screen = mWorkspace.getCurrentScreen(); + // Find details for this application + ComponentName component = data.getComponent(); + PackageManager packageManager = context.getPackageManager(); + ActivityInfo activityInfo = null; + try { + activityInfo = packageManager.getActivityInfo(component, 0 /* no flags */); + } catch (NameNotFoundException e) { + Log.e(LOG_TAG, "Couldn't find ActivityInfo for selected application", e); + } + + if (activityInfo != null) { + ApplicationInfo itemInfo = new ApplicationInfo(); + + itemInfo.title = activityInfo.loadLabel(packageManager); + if (itemInfo.title == null) { + itemInfo.title = activityInfo.name; + } + + itemInfo.setActivity(component, Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + itemInfo.icon = activityInfo.loadIcon(packageManager); + itemInfo.container = ItemInfo.NO_ID; + + mWorkspace.addApplicationShortcut(itemInfo, mAddItemCellInfo); + } + } + /** * Add a shortcut to the workspace. * @@ -535,6 +594,74 @@ public final class Launcher extends Activity implements View.OnClickListener, On } } + + /** + * Add a gadget to the workspace. + * + * @param data The intent describing the gadgetId. + * @param cellInfo The position on screen where to create the shortcut. + * @param insertAtFirst + */ + private void completeAddGadget(Intent data, CellLayout.CellInfo cellInfo, + boolean insertAtFirst) { + + Bundle extras = data.getExtras(); + int gadgetId = extras.getInt(GadgetManager.EXTRA_GADGET_ID, -1); + + Log.d(LOG_TAG, "dumping extras content="+extras.toString()); + + GadgetInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId); + + // Calculate the grid spans needed to fit this gadget + CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen); + layout.rectToCell(gadgetInfo.minWidth, gadgetInfo.minHeight, cellInfo); + + // Try finding open space on Launcher screen + final int[] xy = mCellCoordinates; + if (!findSlot(cellInfo, xy, cellInfo.spanX, cellInfo.spanY)) return; + + // Build Launcher-specific Gadget info and save to database + LauncherGadgetInfo launcherInfo = new LauncherGadgetInfo(gadgetId); + launcherInfo.spanX = cellInfo.spanX; + launcherInfo.spanY = cellInfo.spanY; + + LauncherModel.addItemToDatabase(this, launcherInfo, + LauncherSettings.Favorites.CONTAINER_DESKTOP, + mWorkspace.getCurrentScreen(), xy[0], xy[1], false); + + if (!mRestoring) { + sModel.addDesktopItem(launcherInfo); + + // Perform actual inflation because we're live + launcherInfo.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo); + + launcherInfo.hostView.setGadget(gadgetId, gadgetInfo); + launcherInfo.hostView.setTag(launcherInfo); + + mWorkspace.addInCurrentScreen(launcherInfo.hostView, xy[0], xy[1], + launcherInfo.spanX, launcherInfo.spanY, insertAtFirst); + } else if (sModel.isDesktopLoaded()) { + sModel.addDesktopItem(launcherInfo); + } + + // Request fresh update if we needed to config this gadget to + // remove the stale UPDATE from the initial bind + if (!extras.containsKey(SKIP_CONFIG) || true) { + // TODO: move this down into GadgetManager to prevent abuse? (anyone + // could force a specific gadget into the ground through flooding) + Log.d(LOG_TAG, "requesting new gadget update because we had a config step"); + Intent intent = new Intent(GadgetManager.GADGET_UPDATE_ACTION); + intent.putExtra(GadgetManager.EXTRA_GADGET_IDS, new int[] { gadgetId }); + intent.setComponent(gadgetInfo.provider); + sendBroadcast(intent); + } + + } + + public LauncherGadgetHost getGadgetHost() { + return mGadgetHost; + } + static ApplicationInfo addShortcut(Context context, Intent data, CellLayout.CellInfo cellInfo, boolean notify) { @@ -584,107 +711,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On return info; } - /** - * Add a PhotFrame to the workspace. - * - * @param data The intent describing the photo. - * @param cellInfo The position on screen where to create the shortcut. - */ - private void completeAddPhotoFrame(Intent data, CellLayout.CellInfo cellInfo) { - final Bundle extras = data.getExtras(); - if (extras != null) { - Bitmap photo = extras.getParcelable("data"); - - Widget info = Widget.makePhotoFrame(); - info.photo = photo; - - final int[] xy = mCellCoordinates; - if (!findSlot(cellInfo, xy, info.spanX, info.spanY)) return; - - LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, - mWorkspace.getCurrentScreen(), xy[0], xy[1], false); - - if (!mRestoring) { - sModel.addDesktopItem(info); - - final PhotoFrame view = (PhotoFrame) mInflater.inflate(info.layoutResource, null); - view.setImageBitmap(photo); - view.setTag(info); - - mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, info.spanY); - } else if (sModel.isDesktopLoaded()) { - sModel.addDesktopItem(info); - } - } - } - - /** - * Updates a workspace PhotoFrame. - * - * @param data The intent describing the photo. - * @param cellInfo The position on screen of the PhotoFrame to update. - */ - private void completeUpdatePhotoFrame(Intent data, CellLayout.CellInfo cellInfo) { - final Bundle extras = data.getExtras(); - if (extras != null) { - Widget info; - Bitmap photo = extras.getParcelable("data"); - - if (!mRestoring) { - final CellLayout layout = (CellLayout) mWorkspace.getChildAt(cellInfo.screen); - final PhotoFrame view = (PhotoFrame) layout.findCell(cellInfo.cellX, cellInfo.cellY, - cellInfo.spanX, cellInfo.spanY, null); - view.setImageBitmap(photo); - info = (Widget) view.getTag(); - } else { - info = LauncherModel.getPhotoFrameInfo(this, cellInfo.screen, - cellInfo.cellX, cellInfo.cellY); - } - - info.photo = photo; - LauncherModel.updateItemInDatabase(this, info); - } - } - - /** - * Starts a new Intent to let the user update the PhotoFrame defined by the - * specified Widget. - * - * @param widget The Widget info defining which PhotoFrame to update. - */ - void updatePhotoFrame(Widget widget) { - CellLayout.CellInfo info = new CellLayout.CellInfo(); - info.screen = widget.screen; - info.cellX = widget.cellX; - info.cellY = widget.cellY; - info.spanX = widget.spanX; - info.spanY = widget.spanY; - mAddItemCellInfo = info; - - startActivityForResult(createPhotoPickIntent(), Launcher.REQUEST_UPDATE_PHOTO); - } - - /** - * Creates an Intent used to let the user pick a photo for a PhotoFrame. - * - * @return The Intent to pick a photo suited for a PhotoFrame. - */ - private static Intent createPhotoPickIntent() { - // TODO: Move this method to PhotoFrame? - // TODO: get these values from constants somewhere - // TODO: Adjust the PhotoFrame's image size to avoid on the fly scaling - Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); - intent.setType("image/*"); - intent.putExtra("crop", "true"); - intent.putExtra("aspectX", 1); - intent.putExtra("aspectY", 1); - intent.putExtra("outputX", 192); - intent.putExtra("outputY", 192); - intent.putExtra("noFaceDetection", true); - intent.putExtra("return-data", true); - return intent; - } - @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -871,10 +897,51 @@ public final class Launcher extends Activity implements View.OnClickListener, On private void removeShortcutsForPackage(String packageName) { if (packageName != null && packageName.length() > 0) { - android.util.Log.d(LOG_TAG, packageName); mWorkspace.removeShortcutsForPackage(packageName); } } + + static final String SKIP_CONFIG = "skip_config"; + + void addGadget(Intent data) { + int gadgetId = data.getIntExtra(GadgetManager.EXTRA_GADGET_ID, -1); + GadgetInfo gadget = mGadgetManager.getGadgetInfo(gadgetId); + + if (gadget.configure != null) { + // Launch over to configure gadget, if needed + Intent intent = new Intent(GadgetManager.GADGET_CONFIGURE_ACTION); + intent.setComponent(gadget.configure); + intent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId); + + startActivityForResult(intent, REQUEST_CREATE_GADGET); + } else { + // Otherwise just add it + Log.d(LOG_TAG, "dumping extras content="+data.getExtras().toString()); + data.putExtra(SKIP_CONFIG, true); + Log.d(LOG_TAG, "dumping extras content="+data.getExtras().toString()); + onActivityResult(REQUEST_CREATE_GADGET, Activity.RESULT_OK, data); + } + } + + void addSearch() { + final Widget info = Widget.makeSearch(); + final CellLayout.CellInfo cellInfo = mAddItemCellInfo; + + final int[] xy = mCellCoordinates; + final int spanX = info.spanX; + final int spanY = info.spanY; + + if (!findSlot(cellInfo, xy, spanX, spanY)) return; + + sModel.addDesktopItem(info); + LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, + mWorkspace.getCurrentScreen(), xy[0], xy[1], false); + + final View view = mInflater.inflate(info.layoutResource, null); + view.setTag(info); + + mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY); + } void addShortcut(Intent intent) { startActivityForResult(intent, REQUEST_CREATE_SHORTCUT); @@ -964,39 +1031,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On return info; } - void getPhotoForPhotoFrame() { - startActivityForResult(createPhotoPickIntent(), REQUEST_CHOOSE_PHOTO); - } - - void addClock() { - final Widget info = Widget.makeClock(); - addWidget(info); - } - - void addSearch() { - final Widget info = Widget.makeSearch(); - addWidget(info); - } - - private void addWidget(final Widget info) { - final CellLayout.CellInfo cellInfo = mAddItemCellInfo; - - final int[] xy = mCellCoordinates; - final int spanX = info.spanX; - final int spanY = info.spanY; - - if (!findSlot(cellInfo, xy, spanX, spanY)) return; - - sModel.addDesktopItem(info); - LauncherModel.addItemToDatabase(this, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, - mWorkspace.getCurrentScreen(), xy[0], xy[1], false); - - final View view = mInflater.inflate(info.layoutResource, null); - view.setTag(info); - - mWorkspace.addInCurrentScreen(view, xy[0], xy[1], info.spanX, spanY); - } - private boolean findSlot(CellLayout.CellInfo cellInfo, int[] xy, int spanX, int spanY) { if (!cellInfo.findCellForSpan(xy, spanX, spanY)) { boolean[] occupied = mSavedState != null ? @@ -1136,6 +1170,18 @@ public final class Launcher extends Activity implements View.OnClickListener, On for (int i = 0; i < count; i++) { ((ViewGroup) workspace.getChildAt(i)).removeAllViewsInLayout(); } + + if (DEBUG_USER_INTERFACE) { + android.widget.Button finishButton = new android.widget.Button(this); + finishButton.setText("Finish"); + workspace.addInScreen(finishButton, 1, 0, 0, 1, 1); + + finishButton.setOnClickListener(new android.widget.Button.OnClickListener() { + public void onClick(View v) { + finish(); + } + }); + } count = shortcuts.size(); @@ -1176,11 +1222,41 @@ public final class Launcher extends Activity implements View.OnClickListener, On workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1, !desktopLocked); break; - default: + case LauncherSettings.Favorites.ITEM_TYPE_GADGET: + final LauncherGadgetInfo launcherInfo = (LauncherGadgetInfo) item; + + final int gadgetId = launcherInfo.gadgetId; + GadgetInfo gadgetInfo = mGadgetManager.getGadgetInfo(gadgetId); + launcherInfo.hostView = mGadgetHost.createView(this, gadgetId, gadgetInfo); + + Log.d(LOG_TAG, "about to setGadget during desktop bind"); + launcherInfo.hostView.setGadget(gadgetId, gadgetInfo); + launcherInfo.hostView.setTag(launcherInfo); + + workspace.addInScreen(launcherInfo.hostView, item.screen, item.cellX, + item.cellY, item.spanX, item.spanY, !desktopLocked); + + // Now that we've bound the item, request an update for it + if (gadgetInfo != null) { + if (gadgetInfo.provider != null) { + Intent intent = new Intent(GadgetManager.GADGET_UPDATE_ACTION); + intent.putExtra(GadgetManager.EXTRA_GADGET_IDS, new int[] { gadgetId }); + intent.setComponent(gadgetInfo.provider); + sendBroadcast(intent); + } + } + + break; + case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH: + final int screen = workspace.getCurrentScreen(); + final View view = mInflater.inflate(R.layout.widget_search, + (ViewGroup) workspace.getChildAt(screen), false); + final Widget widget = (Widget) item; - final View view = createWidget(mInflater, widget); view.setTag(widget); + workspace.addWidget(view, widget, !desktopLocked); + break; } } @@ -1226,17 +1302,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On mDrawer.unlock(); } - private View createWidget(LayoutInflater inflater, Widget widget) { - final Workspace workspace = mWorkspace; - final int screen = workspace.getCurrentScreen(); - View v = inflater.inflate(widget.layoutResource, - (ViewGroup) workspace.getChildAt(screen), false); - if (widget.itemType == LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME) { - ((ImageView)v).setImageBitmap(widget.photo); - } - return v; - } - DragController getDragController() { return mDragLayer; } @@ -1263,6 +1328,11 @@ public final class Launcher extends Activity implements View.OnClickListener, On startActivity(intent); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); + } catch (SecurityException e) { + Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); + Log.e(LOG_TAG, "Launcher does not have the permission to launch " + intent + + ". Make sure to create a MAIN intent-filter for the corresponding activity " + + "or use the exported attribute for this activity.", e); } } @@ -1508,24 +1578,24 @@ public final class Launcher extends Activity implements View.OnClickListener, On * Displays the shortcut creation dialog and launches, if necessary, the * appropriate activity. */ - private class CreateShortcut implements ExpandableListView.OnChildClickListener, - DialogInterface.OnCancelListener, ExpandableListView.OnGroupExpandListener { + private class CreateShortcut implements AdapterView.OnItemClickListener, + DialogInterface.OnCancelListener { private AddAdapter mAdapter; - private ExpandableListView mList; - + private ListView mList; + Dialog createDialog() { mWaitingForResult = true; - mAdapter = new AddAdapter(Launcher.this, false); + + mAdapter = new AddAdapter(Launcher.this); final AlertDialog.Builder builder = new AlertDialog.Builder(Launcher.this); builder.setTitle(getString(R.string.menu_item_add_item)); builder.setIcon(0); - mList = (ExpandableListView) + mList = (ListView) View.inflate(Launcher.this, R.layout.create_shortcut_list, null); mList.setAdapter(mAdapter); - mList.setOnChildClickListener(this); - mList.setOnGroupExpandListener(this); + mList.setOnItemClickListener(this); builder.setView(mList); builder.setInverseBackgroundForced(true); @@ -1539,13 +1609,6 @@ public final class Launcher extends Activity implements View.OnClickListener, On return dialog; } - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, - int childPosition, long id) { - mAdapter.performAction(groupPosition, childPosition); - cleanup(); - return true; - } - public void onCancel(DialogInterface dialog) { mWaitingForResult = false; cleanup(); @@ -1556,10 +1619,76 @@ public final class Launcher extends Activity implements View.OnClickListener, On dismissDialog(DIALOG_CREATE_SHORTCUT); } - public void onGroupExpand(int groupPosition) { - long packged = ExpandableListView.getPackedPositionForGroup(groupPosition); - int position = mList.getFlatListPosition(packged); - mList.setSelectionFromTop(position, 0); + public void onItemClick(AdapterView parent, View view, int position, long id) { + // handle which item was clicked based on position + // this will launch off pick intent + + Object tag = view.getTag(); + if (tag instanceof AddAdapter.ListItem) { + AddAdapter.ListItem item = (AddAdapter.ListItem) tag; + cleanup(); + switch (item.actionTag) { + case AddAdapter.ITEM_APPLICATION: { + Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); + mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + + Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY); + pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent); + startActivityForResult(pickIntent, REQUEST_PICK_APPLICATION); + break; + } + + case AddAdapter.ITEM_SHORTCUT: { + Intent shortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); + + Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY); + pickIntent.putExtra(Intent.EXTRA_INTENT, shortcutIntent); + pickIntent.putExtra(Intent.EXTRA_TITLE, + getText(R.string.title_select_shortcut)); + startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT); + break; + } + + case AddAdapter.ITEM_SEARCH: { + addSearch(); + break; + } + + case AddAdapter.ITEM_GADGET: { + int gadgetId = Launcher.this.mGadgetHost.allocateGadgetId(); + + Intent pickIntent = new Intent(GadgetManager.GADGET_PICK_ACTION); + pickIntent.putExtra(GadgetManager.EXTRA_HOST_ID, GADGET_HOST_ID); + pickIntent.putExtra(GadgetManager.EXTRA_GADGET_ID, gadgetId); + startActivityForResult(pickIntent, REQUEST_PICK_GADGET); + break; + } + + case AddAdapter.ITEM_LIVE_FOLDER: { + Intent liveFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER); + + Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY); + pickIntent.putExtra(Intent.EXTRA_INTENT, liveFolderIntent); + pickIntent.putExtra(Intent.EXTRA_TITLE, + getText(R.string.title_select_live_folder)); + startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER); + break; + } + + case AddAdapter.ITEM_FOLDER: { + addFolder(); + dismissDialog(DIALOG_CREATE_SHORTCUT); + break; + } + + case AddAdapter.ITEM_WALLPAPER: { + startWallpaper(); + break; + } + + } + + } } } @@ -1569,13 +1698,20 @@ public final class Launcher extends Activity implements View.OnClickListener, On private class ApplicationsIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - //noinspection ConstantConditions - if (REMOVE_SHORTCUT_ON_PACKAGE_REMOVE && - Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { - removeShortcutsForPackage(intent.getData().getSchemeSpecificPart()); + boolean reloadWorkspace = false; + if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { + if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + removeShortcutsForPackage(intent.getData().getSchemeSpecificPart()); + } else { + reloadWorkspace = true; + } } removeDialog(DIALOG_CREATE_SHORTCUT); - sModel.loadApplications(false, Launcher.this, false); + if (!reloadWorkspace) { + sModel.loadApplications(false, Launcher.this, false); + } else { + sModel.loadUserItems(false, Launcher.this, false, true); + } } } diff --git a/src/com/android/launcher/LauncherGadgetHost.java b/src/com/android/launcher/LauncherGadgetHost.java new file mode 100644 index 0000000..4f7e8f2 --- /dev/null +++ b/src/com/android/launcher/LauncherGadgetHost.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher; + +import android.content.Context; +import android.gadget.GadgetHost; +import android.gadget.GadgetHostView; +import android.gadget.GadgetInfo; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewConfiguration; +import android.widget.TextView; + +/** + * Specific {@link GadgetHost} that creates our {@link LauncherGadgetHostView} which correctly + * captures all long-press events. This ensures that users can always pick up and move gadgets. + */ +public class LauncherGadgetHost extends GadgetHost { + public LauncherGadgetHost(Context context, int hostId) { + super(context, hostId); + } + + protected GadgetHostView onCreateView(Context context, int gadgetId, GadgetInfo gadget) { + return new LauncherGadgetHostView(context); + } + + /** + * {@inheritDoc} + */ + public class LauncherGadgetHostView extends GadgetHostView { + static final String TAG = "LauncherGadgetHostView"; + + private boolean mHasPerformedLongPress; + + private CheckForLongPress mPendingCheckForLongPress; + + private LayoutInflater mInflater; + + public LauncherGadgetHostView(Context context) { + super(context); + + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + // Prepare our default transition animations + setAnimateFirstView(true); + setInAnimation(context, android.R.anim.fade_in); + setOutAnimation(context, android.R.anim.fade_out); + } + + @Override + protected View getErrorView() { + return mInflater.inflate(R.layout.gadget_error, this, false); + } + + public boolean onInterceptTouchEvent(MotionEvent ev) { + + // Consume any touch events for ourselves after longpress is triggered + if (mHasPerformedLongPress) { + mHasPerformedLongPress = false; + return true; + } + + // Watch for longpress events at this level to make sure + // users can always pick up this Gadget + switch (ev.getAction()) { + case MotionEvent.ACTION_DOWN: { + postCheckForLongClick(); + break; + } + + case MotionEvent.ACTION_UP: { + mHasPerformedLongPress = false; + if (mPendingCheckForLongPress != null) { + removeCallbacks(mPendingCheckForLongPress); + } + break; + } + } + + // Otherwise continue letting touch events fall through to children + return false; + } + + class CheckForLongPress implements Runnable { + private int mOriginalWindowAttachCount; + + public void run() { + if ((mParent != null) && hasWindowFocus() + && mOriginalWindowAttachCount == getWindowAttachCount() + && !mHasPerformedLongPress) { + if (performLongClick()) { + mHasPerformedLongPress = true; + } + } + } + + public void rememberWindowAttachCount() { + mOriginalWindowAttachCount = getWindowAttachCount(); + } + } + + private void postCheckForLongClick() { + mHasPerformedLongPress = false; + + if (mPendingCheckForLongPress == null) { + mPendingCheckForLongPress = new CheckForLongPress(); + } + mPendingCheckForLongPress.rememberWindowAttachCount(); + postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout()); + } + + } + +} + diff --git a/src/com/android/launcher/LauncherGadgetInfo.java b/src/com/android/launcher/LauncherGadgetInfo.java new file mode 100644 index 0000000..65fa774 --- /dev/null +++ b/src/com/android/launcher/LauncherGadgetInfo.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher; + +import android.content.ContentValues; +import android.gadget.GadgetHostView; + +/** + * Represents a gadget, which just contains an identifier. + */ +class LauncherGadgetInfo extends ItemInfo { + + /** + * Identifier for this gadget when talking with {@link GadgetManager} for updates. + */ + int gadgetId; + + /** + * View that holds this gadget after it's been created. This view isn't created + * until Launcher knows it's needed. + */ + GadgetHostView hostView = null; + + LauncherGadgetInfo(int gadgetId) { + itemType = LauncherSettings.Favorites.ITEM_TYPE_GADGET; + this.gadgetId = gadgetId; + } + + @Override + void onAddToDatabase(ContentValues values) { + super.onAddToDatabase(values); + values.put(LauncherSettings.Favorites.GADGET_ID, gadgetId); + } + + @Override + public String toString() { + return Integer.toString(gadgetId); + } +} diff --git a/src/com/android/launcher/LauncherModel.java b/src/com/android/launcher/LauncherModel.java index 314a502..5d01796 100644 --- a/src/com/android/launcher/LauncherModel.java +++ b/src/com/android/launcher/LauncherModel.java @@ -272,7 +272,8 @@ public class LauncherModel { try { while (c.moveToNext()) { try { - if (c.getInt(itemTypeIndex) != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { + if (c.getInt(itemTypeIndex) != + LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) { continue; } @@ -374,15 +375,19 @@ public class LauncherModel { final int iconResourceIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ICON_RESOURCE); final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER); final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE); + final int gadgetIdIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.GADGET_ID); final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN); final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX); final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY); + final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); + final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); final int uriIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.URI); final int displayModeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.DISPLAY_MODE); ApplicationInfo info; String intentDescription; Widget widgetInfo = null; + LauncherGadgetInfo gadgetInfo = null; int container; long id; Intent intent; @@ -494,41 +499,44 @@ public class LauncherModel { break; } break; - case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK: case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH: - case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME: - switch (itemType) { - case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK: - widgetInfo = Widget.makeClock(); - break; - case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_SEARCH: - widgetInfo = Widget.makeSearch(); - break; - case LauncherSettings.Favorites.ITEM_TYPE_WIDGET_PHOTO_FRAME: - widgetInfo = Widget.makePhotoFrame(); - byte[] data = c.getBlob(iconIndex); - if (data != null) { - widgetInfo.photo = - BitmapFactory.decodeByteArray(data, 0, data.length); - } - break; - } + widgetInfo = Widget.makeSearch(); - if (widgetInfo != null) { - container = c.getInt(containerIndex); - if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { - Log.e(Launcher.LOG_TAG, "Widget found where container " - + "!= CONTAINER_DESKTOP -- ignoring!"); - continue; - } - widgetInfo.id = c.getLong(idIndex); - widgetInfo.screen = c.getInt(screenIndex); - widgetInfo.container = container; - widgetInfo.cellX = c.getInt(cellXIndex); - widgetInfo.cellY = c.getInt(cellYIndex); + container = c.getInt(containerIndex); + if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { + Log.e(Launcher.LOG_TAG, "Widget found where container " + + "!= CONTAINER_DESKTOP ignoring!"); + continue; + } + + widgetInfo.id = c.getLong(idIndex); + widgetInfo.screen = c.getInt(screenIndex); + widgetInfo.container = container; + widgetInfo.cellX = c.getInt(cellXIndex); + widgetInfo.cellY = c.getInt(cellYIndex); + + desktopItems.add(widgetInfo); + break; + case LauncherSettings.Favorites.ITEM_TYPE_GADGET: + // Read all Launcher-specific gadget details + int gadgetId = c.getInt(gadgetIdIndex); + gadgetInfo = new LauncherGadgetInfo(gadgetId); + gadgetInfo.id = c.getLong(idIndex); + gadgetInfo.screen = c.getInt(screenIndex); + gadgetInfo.cellX = c.getInt(cellXIndex); + gadgetInfo.cellY = c.getInt(cellYIndex); + gadgetInfo.spanX = c.getInt(spanXIndex); + gadgetInfo.spanY = c.getInt(spanYIndex); - desktopItems.add(widgetInfo); + container = c.getInt(containerIndex); + if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { + Log.e(Launcher.LOG_TAG, "Gadget found where container " + + "!= CONTAINER_DESKTOP -- ignoring!"); + continue; } + gadgetInfo.container = c.getInt(containerIndex); + + desktopItems.add(gadgetInfo); break; } } catch (Exception e) { @@ -972,7 +980,7 @@ public class LauncherModel { final ContentResolver cr = context.getContentResolver(); cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); - cr.delete(LauncherSettings.Favorites.CONTENT_URI, LauncherSettings.Favorites.CONTAINER + "=" + info.id, - null); + cr.delete(LauncherSettings.Favorites.CONTENT_URI, + LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); } } diff --git a/src/com/android/launcher/LauncherProvider.java b/src/com/android/launcher/LauncherProvider.java index a3e529d..47db647 100644 --- a/src/com/android/launcher/LauncherProvider.java +++ b/src/com/android/launcher/LauncherProvider.java @@ -29,6 +29,7 @@ import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.database.Cursor; +import android.database.SQLException; import android.util.Log; import android.util.Xml; import android.net.Uri; @@ -49,7 +50,8 @@ public class LauncherProvider extends ContentProvider { private static final String LOG_TAG = "LauncherSettingsProvider"; private static final String DATABASE_NAME = "launcher.db"; - private static final int DATABASE_VERSION = 1; + + private static final int DATABASE_VERSION = 2; static final String AUTHORITY = "com.android.launcher.settings"; @@ -187,6 +189,7 @@ public class LauncherProvider extends ContentProvider { "spanX INTEGER," + "spanY INTEGER," + "itemType INTEGER," + + "gadgetId INTEGER NOT NULL DEFAULT -1," + "isShortcut INTEGER," + "iconType INTEGER," + "iconPackage TEXT," + @@ -196,6 +199,11 @@ public class LauncherProvider extends ContentProvider { "displayMode INTEGER" + ");"); + // TODO: During first database creation, trigger wipe of any gadgets that + // might have been left around during a wipe-data. +// GadgetManager gadgetManager = GadgetManager.getInstance(mContext); + + if (!convertDatabase(db)) { // Populate favorites table with initial favorites loadFavorites(db, DEFAULT_FAVORITES_PATH); @@ -206,7 +214,7 @@ public class LauncherProvider extends ContentProvider { boolean converted = false; final Uri uri = Uri.parse("content://" + Settings.AUTHORITY + - "/favorites?notify=true"); + "/old_favorites?notify=true"); final ContentResolver resolver = mContext.getContentResolver(); Cursor cursor = null; @@ -261,6 +269,7 @@ public class LauncherProvider extends ContentProvider { values.put(LauncherSettings.Favorites.ICON_RESOURCE, c.getString(iconResourceIndex)); values.put(LauncherSettings.Favorites.CONTAINER, c.getInt(containerIndex)); values.put(LauncherSettings.Favorites.ITEM_TYPE, c.getInt(itemTypeIndex)); + values.put(LauncherSettings.Favorites.GADGET_ID, -1); values.put(LauncherSettings.Favorites.SCREEN, c.getInt(screenIndex)); values.put(LauncherSettings.Favorites.CELLX, c.getInt(cellXIndex)); values.put(LauncherSettings.Favorites.CELLY, c.getInt(cellYIndex)); @@ -290,11 +299,31 @@ public class LauncherProvider extends ContentProvider { @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to " + - newVersion + ", which will destroy all old data"); - - db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES); - onCreate(db); + int version = oldVersion; + if (version == 1) { + // upgrade 1 -> 2 added gadgetId column + db.beginTransaction(); + try { + // TODO: convert any existing widgets for search and clock + // this might involve a FORCE_ADD_GADGET permission in GadgetManager that + // Launcher could then use to add these gadgets without user interaction + db.execSQL("ALTER TABLE favorites " + + "ADD COLUMN gadgetId INTEGER NOT NULL DEFAULT -1;"); + db.setTransactionSuccessful(); + version = 2; + } catch (SQLException ex) { + // Old version remains, which means we wipe old data + Log.e(LOG_TAG, ex.getMessage(), ex); + } finally { + db.endTransaction(); + } + } + + if (version != DATABASE_VERSION) { + Log.w(LOG_TAG, "Destroying all old data."); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES); + onCreate(db); + } } @@ -370,20 +399,7 @@ public class LauncherProvider extends ContentProvider { } catch (IOException e) { Log.w(LOG_TAG, "Got exception parsing favorites.", e); } - - // Add a clock - values.clear(); - values.put(LauncherSettings.Favorites.CONTAINER, - LauncherSettings.Favorites.CONTAINER_DESKTOP); - values.put(LauncherSettings.Favorites.ITEM_TYPE, - LauncherSettings.Favorites.ITEM_TYPE_WIDGET_CLOCK); - values.put(LauncherSettings.Favorites.SCREEN, 1); - values.put(LauncherSettings.Favorites.CELLX, 1); - values.put(LauncherSettings.Favorites.CELLY, 0); - values.put(LauncherSettings.Favorites.SPANX, 2); - values.put(LauncherSettings.Favorites.SPANY, 2); - db.insert(TABLE_FAVORITES, null, values); - + // Add a search box values.clear(); values.put(LauncherSettings.Favorites.CONTAINER, @@ -396,6 +412,9 @@ public class LauncherProvider extends ContentProvider { values.put(LauncherSettings.Favorites.SPANX, 4); values.put(LauncherSettings.Favorites.SPANY, 1); db.insert(TABLE_FAVORITES, null, values); + + // TODO: automatically add clock and search gadget to + // default locations. this might need the FORCE permission mentioned above return i; } diff --git a/src/com/android/launcher/LauncherSettings.java b/src/com/android/launcher/LauncherSettings.java index c5dfd1f..77bdc73 100644 --- a/src/com/android/launcher/LauncherSettings.java +++ b/src/com/android/launcher/LauncherSettings.java @@ -147,6 +147,11 @@ class LauncherSettings { static final int ITEM_TYPE_LIVE_FOLDER = 3; /** + * The favorite is a gadget + */ + static final int ITEM_TYPE_GADGET = 4; + + /** * The favorite is a clock */ static final int ITEM_TYPE_WIDGET_CLOCK = 1000; @@ -162,6 +167,13 @@ class LauncherSettings { static final int ITEM_TYPE_WIDGET_PHOTO_FRAME = 1002; /** + * The gadgetId of the gadget + * + * <P>Type: INTEGER</P> + */ + static final String GADGET_ID = "gadgetId"; + + /** * Indicates whether this favorite is an application-created shortcut or not. * If the value is 0, the favorite is not an application-created shortcut, if the * value is 1, it is an application-created shortcut. diff --git a/src/com/android/launcher/PhotoFrame.java b/src/com/android/launcher/PhotoFrame.java deleted file mode 100644 index 1151322..0000000 --- a/src/com/android/launcher/PhotoFrame.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 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.launcher; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.ImageView; - - -/** - * Desktop widget that holds a user folder - * - */ -public class PhotoFrame extends ImageView implements OnClickListener { - - public PhotoFrame(Context context, AttributeSet attrs) { - super(context, attrs); - setClickable(true); - setOnClickListener(this); - setWillNotCacheDrawing(true); - } - - public void onClick(View v) { - ((Launcher) mContext).updatePhotoFrame((Widget) getTag()); - } -} diff --git a/src/com/android/launcher/Search.java b/src/com/android/launcher/Search.java index 41d6562..449caf9 100644 --- a/src/com/android/launcher/Search.java +++ b/src/com/android/launcher/Search.java @@ -16,8 +16,6 @@ package com.android.launcher; -import java.util.List; - import android.app.ISearchManager; import android.app.SearchManager; import android.content.ActivityNotFoundException; @@ -59,6 +57,8 @@ import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; +import java.util.List; + public class Search extends LinearLayout implements OnClickListener, OnKeyListener, OnLongClickListener, TextWatcher, OnItemClickListener, OnItemSelectedListener { @@ -66,6 +66,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen private AutoCompleteTextView mSearchText; private ImageButton mGoButton; + private ImageButton mVoiceButton; private OnLongClickListener mLongClickListener; // Support for suggestions @@ -76,6 +77,9 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen private String mSuggestionQuery = null; private int mItemSelected = -1; + // For voice searching + private Intent mVoiceSearchIntent; + private Rect mTempRect = new Rect(); /** @@ -86,6 +90,10 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen */ public Search(Context context, AttributeSet attrs) { super(context, attrs); + + mVoiceSearchIntent = new Intent(android.speech.RecognizerIntent.ACTION_WEB_SEARCH); + mVoiceSearchIntent.putExtra(android.speech.RecognizerIntent.EXTRA_LANGUAGE_MODEL, + android.speech.RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH); } /** @@ -94,6 +102,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen public void onClick(View v) { if (v == mGoButton) { query(); + } else if (v == mVoiceButton) { + try { + getContext().startActivity(mVoiceSearchIntent); + } catch (ActivityNotFoundException ex) { + // Should not happen, since we check the availability of + // voice search before showing the button. But just in case... + Log.w(TAG, "Could not find voice search activity"); + } } } @@ -206,7 +222,7 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen return true; } } - } else if (v == mGoButton) { + } else if (v == mGoButton || v == mVoiceButton) { boolean handled = false; if (!event.isSystem() && (keyCode != KeyEvent.KEYCODE_DPAD_UP) && @@ -243,7 +259,14 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - requestFocusFromTouch(); + // Request focus unless the user tapped on the voice search button + final int x = (int) ev.getX(); + final int y = (int) ev.getY(); + final Rect frame = mTempRect; + mVoiceButton.getHitRect(frame); + if (!frame.contains(x, y)) { + requestFocusFromTouch(); + } return super.onInterceptTouchEvent(ev); } @@ -268,26 +291,29 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen mSearchText.addTextChangedListener(this); mGoButton = (ImageButton) findViewById(R.id.search_go_btn); + mVoiceButton = (ImageButton) findViewById(R.id.search_voice_btn); mGoButton.setOnClickListener(this); + mVoiceButton.setOnClickListener(this); mGoButton.setOnKeyListener(this); + mVoiceButton.setOnKeyListener(this); mSearchText.setOnLongClickListener(this); mGoButton.setOnLongClickListener(this); + mVoiceButton.setOnLongClickListener(this); // disable the button since we start out w/empty input mGoButton.setEnabled(false); mGoButton.setFocusable(false); + configureSearchableInfo(); configureSuggestions(); + configureVoiceSearchButton(); } - /** The rest of the class deals with providing search suggestions */ - /** - * Set up the suggestions provider mechanism + * Read the searchable info from the search manager */ - private void configureSuggestions() { - // get SearchableInfo + private void configureSearchableInfo() { ISearchManager sms; SearchableInfo searchable; sms = ISearchManager.Stub.asInterface(ServiceManager.getService(Context.SEARCH_SERVICE)); @@ -303,6 +329,36 @@ public class Search extends LinearLayout implements OnClickListener, OnKeyListen return; } mSearchable = searchable; + } + + /** + * If appropriate & available, configure voice search + * + * Note: Because the home screen search widget is always web search, we only check for + * getVoiceSearchLaunchWebSearch() modes. We don't support the alternate form of app-specific + * voice search. + */ + private void configureVoiceSearchButton() { + boolean voiceSearchVisible = false; + if (mSearchable.getVoiceSearchEnabled() && mSearchable.getVoiceSearchLaunchWebSearch()) { + // Enable the voice search button if there is an activity that can handle it + PackageManager pm = getContext().getPackageManager(); + List<ResolveInfo> list = pm.queryIntentActivities(mVoiceSearchIntent, + PackageManager.MATCH_DEFAULT_ONLY); + voiceSearchVisible = list.size() > 0; + } + + // finally, set visible state of voice search button, as appropriate + mVoiceButton.setVisibility(voiceSearchVisible ? View.VISIBLE : View.GONE); + } + + /** The rest of the class deals with providing search suggestions */ + + /** + * Set up the suggestions provider mechanism + */ + private void configureSuggestions() { + // get SearchableInfo mSearchText.setOnItemClickListener(this); mSearchText.setOnItemSelectedListener(this); diff --git a/src/com/android/launcher/WallpaperChooser.java b/src/com/android/launcher/WallpaperChooser.java index afbe6f3..1eb8d0c 100644 --- a/src/com/android/launcher/WallpaperChooser.java +++ b/src/com/android/launcher/WallpaperChooser.java @@ -123,9 +123,6 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele final String[] extras = resources.getStringArray(R.array.extra_wallpapers); final String packageName = getApplication().getPackageName(); - final ArrayList<Integer> images = mImages; - final ArrayList<Integer> thumbs = mThumbs; - for (String extra : extras) { int res = resources.getIdentifier(extra, "drawable", packageName); if (res != 0) { @@ -133,8 +130,8 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele "drawable", packageName); if (thumbRes != 0) { - images.add(res); - thumbs.add(res); + mThumbs.add(res); + mImages.add(res); } } } @@ -148,7 +145,7 @@ public class WallpaperChooser extends Activity implements AdapterView.OnItemSele public void onItemSelected(AdapterView parent, View v, int position, long id) { final ImageView view = mImageView; - Bitmap b = BitmapFactory.decodeResource(getResources(), IMAGE_IDS[position], mOptions); + Bitmap b = BitmapFactory.decodeResource(getResources(), mImages.get(position), mOptions); view.setImageBitmap(b); // Help the GC diff --git a/src/com/android/launcher/Workspace.java b/src/com/android/launcher/Workspace.java index 0ca1b5a..510dad4 100644 --- a/src/com/android/launcher/Workspace.java +++ b/src/com/android/launcher/Workspace.java @@ -89,6 +89,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag private boolean mAllowLongPress; private boolean mLocked; + private int mTouchSlop; + /** * Used to inflate the Workspace from XML. * @@ -126,6 +128,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag mPaint = new Paint(); mPaint.setDither(false); + + mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } /** @@ -626,8 +630,8 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag */ final int xDiff = (int) Math.abs(x - mLastMotionX); final int yDiff = (int) Math.abs(y - mLastMotionY); - final int touchSlop = ViewConfiguration.getTouchSlop(); - + + final int touchSlop = mTouchSlop; boolean xMoved = xDiff > touchSlop; boolean yMoved = yDiff > touchSlop; @@ -1155,6 +1159,10 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag } } } + + // TODO: remove gadgets when gadgetmanager tells us they're gone +// void removeGadgetsForProvider() { +// } void moveToDefaultScreen() { snapToScreen(mDefaultScreen); |