auto import from //branches/cupcake/...@130745
After Width: | Height: | Size: 918 B |
Before Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 196 B |
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 667 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 695 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 669 B |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 578 B |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.5 KiB |
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" />
|
|
@ -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" />
|
||||
|
|
|
@ -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"
|
||||
/>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
mInflater = (LayoutInflater) mLauncher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
// 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));
|
||||
|
||||
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));
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ListItem item = (ListItem) getItem(position);
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = mInflater.inflate(R.layout.add_list_item, parent, false);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
TextView textView = (TextView) convertView;
|
||||
textView.setTag(item);
|
||||
textView.setText(item.text);
|
||||
textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
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 getCount() {
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
public int getGroupCount() {
|
||||
return mGroups.length;
|
||||
public Object getItem(int position) {
|
||||
return mItems.get(position);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public View getGroupView(int groupPosition, boolean isExpanded,
|
||||
View convertView, ViewGroup parent) {
|
||||
View view;
|
||||
if (convertView == null) {
|
||||
view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false);
|
||||
} else {
|
||||
view = convertView;
|
||||
}
|
||||
((TextView) view).setText(mGroups[groupPosition].getName());
|
||||
return view;
|
||||
}
|
||||
|
||||
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 boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void performAction(int groupPosition, int childPosition) {
|
||||
mGroups[groupPosition].run(childPosition);
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
||||
desktopItems.add(widgetInfo);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,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
|
||||
*/
|
||||
|
@ -161,6 +166,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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|