diff options
116 files changed, 2385 insertions, 1014 deletions
diff --git a/proguard.flags b/proguard.flags index 699f23ef5..19c8fd599 100644 --- a/proguard.flags +++ b/proguard.flags @@ -20,6 +20,17 @@ public void setHoverAlpha(float); } +-keep class com.android.launcher2.CellLayout$LayoutParams { + public void setWidth(int); + public int getWidth(); + public void setHeight(int); + public int getHeight(); + public void setX(int); + public int getX(); + public void setY(int); + public int getY(); +} + -keep class com.android.launcher2.Workspace { public float getBackgroundAlpha(); public void setBackgroundAlpha(float); diff --git a/res/drawable-hdpi/widget_resize_frame_holo.9.png b/res/drawable-hdpi/widget_resize_frame_holo.9.png Binary files differnew file mode 100644 index 000000000..8da665b7a --- /dev/null +++ b/res/drawable-hdpi/widget_resize_frame_holo.9.png diff --git a/res/drawable-hdpi/widget_resize_handle_bottom.png b/res/drawable-hdpi/widget_resize_handle_bottom.png Binary files differnew file mode 100644 index 000000000..495476b7c --- /dev/null +++ b/res/drawable-hdpi/widget_resize_handle_bottom.png diff --git a/res/drawable-hdpi/widget_resize_handle_left.png b/res/drawable-hdpi/widget_resize_handle_left.png Binary files differnew file mode 100644 index 000000000..c73cf0e2a --- /dev/null +++ b/res/drawable-hdpi/widget_resize_handle_left.png diff --git a/res/drawable-hdpi/widget_resize_handle_right.png b/res/drawable-hdpi/widget_resize_handle_right.png Binary files differnew file mode 100644 index 000000000..953230276 --- /dev/null +++ b/res/drawable-hdpi/widget_resize_handle_right.png diff --git a/res/drawable-hdpi/widget_resize_handle_top.png b/res/drawable-hdpi/widget_resize_handle_top.png Binary files differnew file mode 100644 index 000000000..a3d2f7c77 --- /dev/null +++ b/res/drawable-hdpi/widget_resize_handle_top.png diff --git a/res/drawable-mdpi/widget_resize_frame_holo.9.png b/res/drawable-mdpi/widget_resize_frame_holo.9.png Binary files differnew file mode 100644 index 000000000..0572f8999 --- /dev/null +++ b/res/drawable-mdpi/widget_resize_frame_holo.9.png diff --git a/res/drawable-mdpi/widget_resize_handle_bottom.png b/res/drawable-mdpi/widget_resize_handle_bottom.png Binary files differnew file mode 100644 index 000000000..6c9397322 --- /dev/null +++ b/res/drawable-mdpi/widget_resize_handle_bottom.png diff --git a/res/drawable-mdpi/widget_resize_handle_left.png b/res/drawable-mdpi/widget_resize_handle_left.png Binary files differnew file mode 100644 index 000000000..71394155b --- /dev/null +++ b/res/drawable-mdpi/widget_resize_handle_left.png diff --git a/res/drawable-mdpi/widget_resize_handle_right.png b/res/drawable-mdpi/widget_resize_handle_right.png Binary files differnew file mode 100644 index 000000000..442224b51 --- /dev/null +++ b/res/drawable-mdpi/widget_resize_handle_right.png diff --git a/res/drawable-mdpi/widget_resize_handle_top.png b/res/drawable-mdpi/widget_resize_handle_top.png Binary files differnew file mode 100644 index 000000000..24358849b --- /dev/null +++ b/res/drawable-mdpi/widget_resize_handle_top.png diff --git a/res/drawable-xlarge-hdpi/ic_generic_search.png b/res/drawable-xlarge-hdpi/ic_generic_search.png Binary files differnew file mode 100644 index 000000000..67bac5cc8 --- /dev/null +++ b/res/drawable-xlarge-hdpi/ic_generic_search.png diff --git a/res/drawable-xlarge-hdpi/ic_voice_search.png b/res/drawable-xlarge-hdpi/ic_voice_search.png Binary files differnew file mode 100644 index 000000000..5d2f341ea --- /dev/null +++ b/res/drawable-xlarge-hdpi/ic_voice_search.png diff --git a/res/drawable-xlarge-hdpi/widget_resize_frame_holo.9.png b/res/drawable-xlarge-hdpi/widget_resize_frame_holo.9.png Binary files differnew file mode 100644 index 000000000..7d16d7dea --- /dev/null +++ b/res/drawable-xlarge-hdpi/widget_resize_frame_holo.9.png diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_bottom.png b/res/drawable-xlarge-hdpi/widget_resize_handle_bottom.png Binary files differnew file mode 100644 index 000000000..045c15e2c --- /dev/null +++ b/res/drawable-xlarge-hdpi/widget_resize_handle_bottom.png diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_left.png b/res/drawable-xlarge-hdpi/widget_resize_handle_left.png Binary files differnew file mode 100644 index 000000000..f0fc4d65d --- /dev/null +++ b/res/drawable-xlarge-hdpi/widget_resize_handle_left.png diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_right.png b/res/drawable-xlarge-hdpi/widget_resize_handle_right.png Binary files differnew file mode 100644 index 000000000..9c1f36602 --- /dev/null +++ b/res/drawable-xlarge-hdpi/widget_resize_handle_right.png diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_top.png b/res/drawable-xlarge-hdpi/widget_resize_handle_top.png Binary files differnew file mode 100644 index 000000000..f7839ed9a --- /dev/null +++ b/res/drawable-xlarge-hdpi/widget_resize_handle_top.png diff --git a/res/drawable-xlarge-mdpi/ic_generic_search.png b/res/drawable-xlarge-mdpi/ic_generic_search.png Binary files differindex d92071b99..e3fd5a266 100644 --- a/res/drawable-xlarge-mdpi/ic_generic_search.png +++ b/res/drawable-xlarge-mdpi/ic_generic_search.png diff --git a/res/drawable-xlarge-mdpi/ic_voice_search.png b/res/drawable-xlarge-mdpi/ic_voice_search.png Binary files differindex a2fe87452..3c52e2ad8 100644 --- a/res/drawable-xlarge-mdpi/ic_voice_search.png +++ b/res/drawable-xlarge-mdpi/ic_voice_search.png diff --git a/res/drawable-xlarge-mdpi/widget_resize_frame_holo.9.png b/res/drawable-xlarge-mdpi/widget_resize_frame_holo.9.png Binary files differnew file mode 100644 index 000000000..e2e1396a1 --- /dev/null +++ b/res/drawable-xlarge-mdpi/widget_resize_frame_holo.9.png diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_bottom.png b/res/drawable-xlarge-mdpi/widget_resize_handle_bottom.png Binary files differnew file mode 100644 index 000000000..99ac1b209 --- /dev/null +++ b/res/drawable-xlarge-mdpi/widget_resize_handle_bottom.png diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_left.png b/res/drawable-xlarge-mdpi/widget_resize_handle_left.png Binary files differnew file mode 100644 index 000000000..d031ddda1 --- /dev/null +++ b/res/drawable-xlarge-mdpi/widget_resize_handle_left.png diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_right.png b/res/drawable-xlarge-mdpi/widget_resize_handle_right.png Binary files differnew file mode 100644 index 000000000..f1b689ca4 --- /dev/null +++ b/res/drawable-xlarge-mdpi/widget_resize_handle_right.png diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_top.png b/res/drawable-xlarge-mdpi/widget_resize_handle_top.png Binary files differnew file mode 100644 index 000000000..40bef020c --- /dev/null +++ b/res/drawable-xlarge-mdpi/widget_resize_handle_top.png diff --git a/res/layout-xlarge-land/all_apps_tabbed.xml b/res/layout-xlarge-land/all_apps_tabbed.xml index d03a57158..92442135a 100644 --- a/res/layout-xlarge-land/all_apps_tabbed.xml +++ b/res/layout-xlarge-land/all_apps_tabbed.xml @@ -16,6 +16,10 @@ <com.android.launcher2.AllAppsTabbed xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"> + <com.android.launcher2.AllAppsBackground + android:id="@+id/all_apps_background" + android:layout_width="match_parent" + android:layout_height="match_parent" /> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" @@ -44,16 +48,23 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="invisible"/> - <ImageView + <TextView android:id="@+id/market_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:onClick="onClickAppMarketButton"/> + android:gravity="center" + android:paddingRight="22dp" + android:text="@string/market" + android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" + android:textSize="18sp" + android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" + android:shadowDx="0.0" + android:shadowDy="0.0" + android:shadowRadius="2.0" /> </FrameLayout> <com.android.launcher2.DeleteZone android:id="@+id/all_apps_delete_zone" - android:text="@string/delete_zone_label_all_apps" android:drawablePadding="@dimen/delete_zone_drawable_padding" android:drawableLeft="@drawable/delete_zone_selector" android:layout_width="wrap_content" @@ -64,7 +75,7 @@ android:paddingRight="22dp" launcher:direction="horizontal" - android:gravity="center_horizontal|center_vertical" + android:gravity="center" android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" android:textSize="18sp" android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" diff --git a/res/layout-xlarge-land/customization_drawer.xml b/res/layout-xlarge-land/customization_drawer_tab_contents.xml index 50e7b6621..50e7b6621 100644 --- a/res/layout-xlarge-land/customization_drawer.xml +++ b/res/layout-xlarge-land/customization_drawer_tab_contents.xml diff --git a/res/layout-xlarge-land/launcher.xml b/res/layout-xlarge-land/launcher.xml deleted file mode 100644 index 957327ebf..000000000 --- a/res/layout-xlarge-land/launcher.xml +++ /dev/null @@ -1,215 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<com.android.launcher2.DragLayer - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" - - android:id="@+id/drag_layer" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <!-- The workspace contains 5 screens of cells --> - <com.android.launcher2.Workspace - android:id="@+id/workspace" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingTop="?android:attr/actionBarSize" - android:paddingBottom="10dp" - launcher:defaultScreen="2" - launcher:cellCountX="8" - launcher:cellCountY="7" - launcher:pageSpacing="50dp"> - - <include android:id="@+id/cell1" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell4" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell5" layout="@layout/workspace_screen" /> - </com.android.launcher2.Workspace> - - <include - layout="@layout/all_apps_tabbed" - android:id="@+id/all_apps_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="top" /> - - <RelativeLayout - android:id="@+id/all_apps_button_cluster" - android:layout_width="fill_parent" - android:layout_height="?android:attr/actionBarSize" - android:layout_gravity="top"> - - <!-- Global search icon --> - <ImageView - android:id="@+id/search_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:src="@drawable/ic_generic_search" - android:background="@drawable/button_bg" - android:onClick="onClickSearchButton" - android:focusable="true" - android:clickable="true" /> - - <ImageView - android:id="@+id/search_divider" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toRightOf="@id/search_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - - android:onClick="onClickSearchButton" - android:focusable="false" - android:clickable="true" /> - - <!-- Voice search icon --> - <ImageView - android:id="@+id/voice_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toRightOf="@id/search_divider" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:src="@drawable/ic_voice_search" - android:background="@drawable/button_bg" - android:onClick="onClickVoiceButton" - android:focusable="true" - android:clickable="true"/> - - <ImageView - android:id="@+id/configure_button" - android:src="@drawable/ic_home_add_holo_dark" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentRight="true" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:background="@drawable/button_bg" - - android:onClick="onClickConfigureButton" - android:focusable="true" - android:clickable="true" /> - <ImageView - android:id="@+id/divider" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toLeftOf="@id/configure_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - - android:onClick="onClickAllAppsButton" - android:focusable="false" - android:clickable="true" /> - <TextView - android:id="@+id/all_apps_button" - android:text="@string/all_apps_button_label" - android:drawablePadding="@dimen/all_apps_button_drawable_padding" - android:drawableLeft="@drawable/ic_home_all_apps_holo_dark" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toLeftOf="@id/divider" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/all_apps_button_vertical_padding" - android:paddingBottom="@dimen/all_apps_button_vertical_padding" - android:background="@drawable/button_bg" - - android:gravity="center_horizontal|center_vertical" - android:textColor="#CCFFFFFF" - android:textSize="18sp" - - android:shadowColor="#DA000000" - android:shadowDx="0.0" - android:shadowDy="0.0" - android:shadowRadius="2.5" - - android:onClick="onClickAllAppsButton" - android:focusable="true" - android:clickable="true" /> - <ImageView - android:id="@+id/divider_during_drag" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toLeftOf="@id/configure_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:visibility="gone"/> - <com.android.launcher2.DeleteZone - android:id="@+id/delete_zone" - android:text="@string/delete_zone_label_workspace" - android:drawablePadding="@dimen/delete_zone_drawable_padding" - android:drawableLeft="@drawable/delete_zone_selector" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignRight="@id/configure_button" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:background="@drawable/button_bg" - - android:gravity="center_horizontal|center_vertical" - android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" - android:textSize="18sp" - android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" - android:shadowDx="0.0" - android:shadowDy="0.0" - android:shadowRadius="2.0" - - android:visibility="gone" - launcher:direction="horizontal" /> - </RelativeLayout> - - <TabHost - android:id="@+id/customization_drawer" - android:layout_width="match_parent" - android:layout_height="480dp" - android:layout_gravity="bottom"> - <LinearLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <TabWidget - android:id="@android:id/tabs" - android:layout_width="952dp" - android:layout_height="wrap_content" - android:layout_gravity="center_horizontal" - android:background="@drawable/tab_unselected_holo" - android:tabStripEnabled="false" /> - <FrameLayout - android:id="@android:id/tabcontent" - android:layout_width="match_parent" - android:layout_height="match_parent"> - </FrameLayout> - </LinearLayout> - </TabHost> -</com.android.launcher2.DragLayer> diff --git a/res/layout-xlarge-port/all_apps_tabbed.xml b/res/layout-xlarge-port/all_apps_tabbed.xml index 269fa1275..c357d2ec5 100644 --- a/res/layout-xlarge-port/all_apps_tabbed.xml +++ b/res/layout-xlarge-port/all_apps_tabbed.xml @@ -16,6 +16,10 @@ <com.android.launcher2.AllAppsTabbed xmlns:android="http://schemas.android.com/apk/res/android" xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"> + <com.android.launcher2.AllAppsBackground + android:id="@+id/all_apps_background" + android:layout_width="match_parent" + android:layout_height="match_parent" /> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" @@ -44,16 +48,23 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="invisible"/> - <ImageView + <TextView android:id="@+id/market_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:onClick="onClickAppMarketButton"/> + android:gravity="center" + android:paddingRight="22dp" + android:text="@string/market" + android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" + android:textSize="18sp" + android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" + android:shadowDx="0.0" + android:shadowDy="0.0" + android:shadowRadius="2.0" /> </FrameLayout> <com.android.launcher2.DeleteZone android:id="@+id/all_apps_delete_zone" - android:text="@string/delete_zone_label_all_apps" android:drawablePadding="@dimen/delete_zone_drawable_padding" android:drawableLeft="@drawable/delete_zone_selector" android:layout_width="wrap_content" @@ -64,7 +75,7 @@ android:paddingRight="22dp" launcher:direction="horizontal" - android:gravity="center_horizontal|center_vertical" + android:gravity="center" android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" android:textSize="18sp" android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" diff --git a/res/layout-xlarge-port/customization_drawer.xml b/res/layout-xlarge-port/customization_drawer_tab_contents.xml index a1bc7cc8a..0381be0aa 100644 --- a/res/layout-xlarge-port/customization_drawer.xml +++ b/res/layout-xlarge-port/customization_drawer_tab_contents.xml @@ -21,7 +21,7 @@ android:layout_height="match_parent" launcher:wallpaperCellSpanX="3" launcher:wallpaperCellCountX="9" - launcher:widgetCellCountX="10" + launcher:widgetCellCountX="9" launcher:cellCountX="5" launcher:cellCountY="3" launcher:pageLayoutWidthGap="36dp" diff --git a/res/layout-xlarge-port/launcher.xml b/res/layout-xlarge-port/launcher.xml deleted file mode 100644 index a8087f450..000000000 --- a/res/layout-xlarge-port/launcher.xml +++ /dev/null @@ -1,215 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2010 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<com.android.launcher2.DragLayer - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" - - android:id="@+id/drag_layer" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <!-- The workspace contains 5 screens of cells --> - <com.android.launcher2.Workspace - android:id="@+id/workspace" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingTop="?android:attr/actionBarSize" - android:paddingBottom="10dp" - launcher:defaultScreen="2" - launcher:cellCountX="8" - launcher:cellCountY="7" - launcher:pageSpacing="64dp"> - - <include android:id="@+id/cell1" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell4" layout="@layout/workspace_screen" /> - <include android:id="@+id/cell5" layout="@layout/workspace_screen" /> - </com.android.launcher2.Workspace> - - <include - layout="@layout/all_apps_tabbed" - android:id="@+id/all_apps_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_gravity="top" /> - - <RelativeLayout - android:id="@+id/all_apps_button_cluster" - android:layout_width="fill_parent" - android:layout_height="?android:attr/actionBarSize" - android:layout_gravity="top"> - - <!-- Global search icon --> - <ImageView - android:id="@+id/search_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:src="@drawable/ic_generic_search" - android:background="@drawable/button_bg" - android:onClick="onClickSearchButton" - android:focusable="true" - android:clickable="true" /> - - <ImageView - android:id="@+id/search_divider" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toRightOf="@id/search_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - - android:onClick="onClickSearchButton" - android:focusable="false" - android:clickable="true" /> - - <!-- Voice search icon --> - <ImageView - android:id="@+id/voice_button" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toRightOf="@id/search_divider" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:src="@drawable/ic_voice_search" - android:background="@drawable/button_bg" - android:onClick="onClickVoiceButton" - android:focusable="true" - android:clickable="true"/> - - <ImageView - android:id="@+id/configure_button" - android:src="@drawable/ic_home_add_holo_dark" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentRight="true" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:background="@drawable/button_bg" - - android:onClick="onClickConfigureButton" - android:focusable="true" - android:clickable="true" /> - <ImageView - android:id="@+id/divider" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toLeftOf="@id/configure_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - - android:onClick="onClickAllAppsButton" - android:focusable="false" - android:clickable="true" /> - <TextView - android:id="@+id/all_apps_button" - android:text="@string/all_apps_button_label" - android:drawablePadding="@dimen/all_apps_button_drawable_padding" - android:drawableLeft="@drawable/ic_home_all_apps_holo_dark" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_toLeftOf="@id/divider" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/all_apps_button_vertical_padding" - android:paddingBottom="@dimen/all_apps_button_vertical_padding" - android:background="@drawable/button_bg" - - android:gravity="center_horizontal|center_vertical" - android:textColor="#CCFFFFFF" - android:textSize="18sp" - - android:shadowColor="#DA000000" - android:shadowDx="0.0" - android:shadowDy="0.0" - android:shadowRadius="2.5" - - android:onClick="onClickAllAppsButton" - android:focusable="true" - android:clickable="true" /> - <ImageView - android:id="@+id/divider_during_drag" - android:src="@drawable/divider_launcher_holo" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toLeftOf="@id/configure_button" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:visibility="gone"/> - <com.android.launcher2.DeleteZone - android:id="@+id/delete_zone" - android:text="@string/delete_zone_label_workspace" - android:drawablePadding="@dimen/delete_zone_drawable_padding" - android:drawableLeft="@drawable/delete_zone_selector" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignRight="@id/configure_button" - android:paddingLeft="@dimen/toolbar_button_horizontal_padding" - android:paddingRight="@dimen/toolbar_button_horizontal_padding" - android:paddingTop="@dimen/toolbar_button_vertical_padding" - android:paddingBottom="@dimen/toolbar_button_vertical_padding" - android:background="@drawable/button_bg" - - android:gravity="center_horizontal|center_vertical" - android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" - android:textSize="18sp" - android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" - android:shadowDx="0.0" - android:shadowDy="0.0" - android:shadowRadius="2.0" - - android:visibility="gone" - launcher:direction="horizontal" /> - </RelativeLayout> - - <TabHost - android:id="@+id/customization_drawer" - android:layout_width="match_parent" - android:layout_height="800dp" - android:layout_gravity="bottom"> - <LinearLayout - android:orientation="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <TabWidget - android:id="@android:id/tabs" - android:layout_width="700dp" - android:layout_height="wrap_content" - android:layout_gravity="center_horizontal" - android:background="@drawable/tab_unselected_holo" - android:tabStripEnabled="false" /> - <FrameLayout - android:id="@android:id/tabcontent" - android:layout_width="match_parent" - android:layout_height="650dp"> - </FrameLayout> - </LinearLayout> - </TabHost> -</com.android.launcher2.DragLayer> diff --git a/res/layout-xlarge/button_bar.xml b/res/layout-xlarge/button_bar.xml new file mode 100644 index 000000000..5c96c5ced --- /dev/null +++ b/res/layout-xlarge/button_bar.xml @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"> + + <!-- Global search icon --> + <ImageView + android:id="@+id/search_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentLeft="true" + android:paddingLeft="@dimen/toolbar_button_horizontal_padding" + android:paddingRight="@dimen/toolbar_button_horizontal_padding" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + android:src="@drawable/ic_generic_search" + android:background="@drawable/button_bg" + android:onClick="onClickSearchButton" + android:focusable="true" + android:clickable="true" /> + + <ImageView + android:id="@+id/search_divider" + android:src="@drawable/divider_launcher_holo" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toRightOf="@id/search_button" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + + android:onClick="onClickSearchButton" + android:focusable="false" + android:clickable="true" /> + + <!-- Voice search icon --> + <ImageView + android:id="@+id/voice_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toRightOf="@id/search_divider" + android:paddingLeft="@dimen/toolbar_button_horizontal_padding" + android:paddingRight="@dimen/toolbar_button_horizontal_padding" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + android:src="@drawable/ic_voice_search" + android:background="@drawable/button_bg" + android:onClick="onClickVoiceButton" + android:focusable="true" + android:clickable="true"/> + + <ImageView + android:id="@+id/configure_button" + android:src="@drawable/ic_home_add_holo_dark" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentRight="true" + android:paddingLeft="@dimen/toolbar_button_horizontal_padding" + android:paddingRight="@dimen/toolbar_button_horizontal_padding" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + android:background="@drawable/button_bg" + + android:focusable="true" + android:clickable="true" /> + <ImageView + android:id="@+id/divider" + android:src="@drawable/divider_launcher_holo" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toLeftOf="@id/configure_button" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + + android:focusable="false" + android:clickable="true" /> + <com.android.launcher2.StrokedTextView + android:id="@+id/all_apps_button" + android:text="@string/all_apps_button_label" + android:drawablePadding="@dimen/all_apps_button_drawable_padding" + android:drawableLeft="@drawable/ic_home_all_apps_holo_dark" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_toLeftOf="@id/divider" + android:paddingLeft="@dimen/toolbar_button_horizontal_padding" + android:paddingRight="@dimen/toolbar_button_horizontal_padding" + android:paddingTop="@dimen/all_apps_button_vertical_padding" + android:paddingBottom="@dimen/all_apps_button_vertical_padding" + android:background="@drawable/button_bg" + + android:gravity="center_horizontal|center_vertical" + android:textColor="#CCFFFFFF" + android:textSize="18sp" + + launcher:strokeColor="#991e3157" + launcher:strokeTextColor="#DDFFFFFF" + launcher:strokeWidth="2.5" + + android:shadowColor="#DA000000" + android:shadowDx="0.0" + android:shadowDy="0.0" + android:shadowRadius="2.5" + + android:focusable="true" + android:clickable="true" /> + <ImageView + android:id="@+id/divider_during_drag" + android:src="@drawable/divider_launcher_holo" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toLeftOf="@id/configure_button" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + android:visibility="gone" /> + <com.android.launcher2.DeleteZone + android:id="@+id/delete_zone" + android:text="@string/delete_zone_label_workspace" + android:drawablePadding="@dimen/delete_zone_drawable_padding" + android:drawableLeft="@drawable/delete_zone_selector" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignRight="@id/configure_button" + android:paddingLeft="@dimen/toolbar_button_horizontal_padding" + android:paddingRight="@dimen/toolbar_button_horizontal_padding" + android:paddingTop="@dimen/toolbar_button_vertical_padding" + android:paddingBottom="@dimen/toolbar_button_vertical_padding" + android:background="@drawable/button_bg" + + android:gravity="center_horizontal|center_vertical" + android:textColor="@color/workspace_all_apps_and_delete_zone_text_color" + android:textSize="18sp" + android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color" + android:shadowDx="0.0" + android:shadowDy="0.0" + android:shadowRadius="2.0" + + android:visibility="gone" + launcher:direction="horizontal" /> +</RelativeLayout>
\ No newline at end of file diff --git a/res/layout-xlarge/customization_drawer.xml b/res/layout-xlarge/customization_drawer.xml new file mode 100644 index 000000000..dd1234c02 --- /dev/null +++ b/res/layout-xlarge/customization_drawer.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<TabHost xmlns:android="http://schemas.android.com/apk/res/android"> + <LinearLayout + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <TabWidget + android:id="@android:id/tabs" + android:layout_width="@dimen/customization_drawer_tab_widget_width" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:background="@drawable/tab_unselected_holo" + android:tabStripEnabled="false" /> + <FrameLayout + android:id="@android:id/tabcontent" + android:layout_width="match_parent" + android:layout_height="@dimen/customization_drawer_content_height"> + </FrameLayout> + </LinearLayout> +</TabHost>
\ No newline at end of file diff --git a/res/layout-xlarge/customize_paged_view_wallpaper.xml b/res/layout-xlarge/customize_paged_view_wallpaper.xml index e3be86d87..8c5abc8d9 100644 --- a/res/layout-xlarge/customize_paged_view_wallpaper.xml +++ b/res/layout-xlarge/customize_paged_view_wallpaper.xml @@ -18,12 +18,11 @@ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" android:layout_width="wrap_content" - android:layout_height="365dp" - android:paddingLeft="12.5dp" - android:paddingRight="12.5dp" - android:paddingBottom="50dp" - android:gravity="top" + android:layout_height="match_parent" + android:layout_weight="1" android:orientation="vertical" + android:paddingRight="25dp" + android:paddingBottom="50dp" launcher:blurColor="#FF6B8CF0" launcher:outlineColor="#FF8CD2FF"> @@ -33,7 +32,8 @@ android:id="@+id/wallpaper_preview" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1.0" + android:layout_weight="1" + android:adjustViewBounds="true" android:scaleType="fitStart" /> <!-- The divider image. --> @@ -41,6 +41,7 @@ android:id="@+id/divider" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_weight="0" android:paddingTop="10dp" android:paddingBottom="10dp" android:src="@drawable/widget_divider" /> @@ -50,6 +51,7 @@ android:id="@+id/wallpaper_name" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_weight="0" android:gravity="left" android:textColor="#FFFFFFFF" diff --git a/res/layout-xlarge/customize_paged_view_widget.xml b/res/layout-xlarge/customize_paged_view_widget.xml index 3b95ebc66..c0b455251 100644 --- a/res/layout-xlarge/customize_paged_view_widget.xml +++ b/res/layout-xlarge/customize_paged_view_widget.xml @@ -18,13 +18,11 @@ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" android:layout_width="wrap_content" - android:layout_height="365dp" - android:paddingLeft="12.5dp" - android:paddingTop="12.5dp" - android:paddingRight="12.5dp" - android:paddingBottom="50dp" - android:gravity="top" + android:layout_height="match_parent" + android:layout_weight="1" android:orientation="vertical" + android:paddingRight="25dp" + android:paddingBottom="50dp" launcher:blurColor="#FF6B8CF0" launcher:outlineColor="#FF8CD2FF"> @@ -34,7 +32,8 @@ android:id="@+id/widget_preview" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="1.0" + android:layout_weight="1" + android:adjustViewBounds="true" android:scaleType="fitStart" /> <!-- The divider image. --> @@ -42,6 +41,7 @@ android:id="@+id/divider" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_weight="0" android:paddingTop="10dp" android:paddingBottom="10dp" android:src="@drawable/widget_divider" /> @@ -51,6 +51,7 @@ android:id="@+id/widget_name" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_weight="0" android:gravity="left" android:textColor="#FFFFFFFF" @@ -69,6 +70,7 @@ android:id="@+id/widget_dims" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_weight="0" android:gravity="left" android:textColor="#FF999999" diff --git a/res/layout-xlarge/launcher.xml b/res/layout-xlarge/launcher.xml new file mode 100644 index 000000000..acf62f906 --- /dev/null +++ b/res/layout-xlarge/launcher.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<com.android.launcher2.DragLayer + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" + + android:id="@+id/drag_layer" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <!-- The workspace contains 5 screens of cells --> + <com.android.launcher2.Workspace + android:id="@+id/workspace" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingTop="?android:attr/actionBarSize" + android:paddingBottom="10dp" + launcher:defaultScreen="2" + launcher:cellCountX="8" + launcher:cellCountY="7" + launcher:pageSpacing="@dimen/workspace_page_spacing"> + + <include android:id="@+id/cell1" layout="@layout/workspace_screen" /> + <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> + <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> + <include android:id="@+id/cell4" layout="@layout/workspace_screen" /> + <include android:id="@+id/cell5" layout="@layout/workspace_screen" /> + </com.android.launcher2.Workspace> + + <include + layout="@layout/all_apps_tabbed" + android:id="@+id/all_apps_view" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="top" /> + + <include layout="@layout/button_bar" + android:id="@+id/all_apps_button_cluster" + android:layout_width="fill_parent" + android:layout_height="?android:attr/actionBarSize" + android:layout_gravity="top" /> + + <include layout="@layout/customization_drawer" + android:id="@+id/customization_drawer" + android:layout_width="match_parent" + android:layout_height="@dimen/customization_drawer_height" + android:layout_gravity="bottom" /> +</com.android.launcher2.DragLayer> diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 8f955b262..df0a21089 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"تطبيقاتي"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"لم يتم العثور على ألعاب"</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"ليس لديك أي تطبيقات تم تنزيلها."</string> + <string name="market" msgid="2652226429823445833">"تسوق"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"تعذر إسقاط العنصر على هذه الشاشة الرئيسية"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"تحديد أداة للإنشاء"</string> <string name="rename_folder_label" msgid="5646236631298452787">"اسم المجلد"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"الرئيسية"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"إزالة"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"إزالة"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"إزالة التحديث"</string> <string name="menu_add" msgid="3065046628354640854">"إضافة"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"إدارة التطبيقات"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"خلفية"</string> diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml index fe9eefbec..5be82f164 100644 --- a/res/values-bg/strings.xml +++ b/res/values-bg/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Моите приложения"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Няма намерени игри."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Нямате изтеглени приложения."</string> + <string name="market" msgid="2652226429823445833">"Магазин"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Елементът не можа да се премести на началния екран"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Избор на създаващо приспособление"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Име на папка"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Начало"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Премахване"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Деинсталиране"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Деинстал. на актуализацията"</string> <string name="menu_add" msgid="3065046628354640854">"Добавяне"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Управление на приложенията"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Тапет"</string> diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 91a85cff0..56ada67fa 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Les meves aplicacions"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"No s\'ha trobat cap joc."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"No has baixat cap aplicació."</string> + <string name="market" msgid="2652226429823445833">"Botiga"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"No s\'ha pogut trasll. l\'element a la pant. d\'inici"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Selecciona un widget per crear-lo"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nom de la carpeta"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Pàgina d\'inici"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Elimina"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Desinstal·la"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Desinstal·la l\'actualització"</string> <string name="menu_add" msgid="3065046628354640854">"Afegeix"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gestiona les aplicacions"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Empaperat"</string> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 8a3063ec7..47fb726cb 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikace"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nenalezeny žádné hry."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nemáte žádné stažené aplikace."</string> + <string name="market" msgid="2652226429823445833">"Obchod"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Na tuto plochu nelze položku přetáhnout"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Vyberte widget"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Název složky"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Plocha"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Odebrat"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Odinstalovat"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Odinstalovat aktualizaci"</string> <string name="menu_add" msgid="3065046628354640854">"Přidat"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Spravovat aplikace"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Tapeta"</string> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index ae10220d0..f48123447 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mine apps"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Ingen spil."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Du har ingen downloadede applikationer."</string> + <string name="market" msgid="2652226429823445833">"Butik"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Kunne ikke slippe elementet på denne startskærm"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Vælg widget for at oprette"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mappenavn"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Start"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Fjern"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Afinstaller"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Afinstaller opdatering"</string> <string name="menu_add" msgid="3065046628354640854">"Tilføj"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Administrer programmer"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Tapet"</string> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 6532237e8..f69ee4320 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -25,7 +25,7 @@ <string name="chooser_wallpaper" msgid="5988031014201479733">"Hintergrund auswählen"</string> <string name="wallpaper_instructions" msgid="4215640646180727542">"Hintergrund festlegen"</string> <string name="pick_wallpaper" msgid="5630222540525626723">"Hintergrundbilder"</string> - <string name="activity_not_found" msgid="5591731020063337696">"Anwendung ist nicht installiert."</string> + <string name="activity_not_found" msgid="5591731020063337696">"Die Anwendung ist nicht installiert."</string> <string name="configure_wallpaper" msgid="2820186271419674623">"Konfigurieren..."</string> <string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string> <string name="folders_tab_label" msgid="1145293785541489736">"Ordner"</string> @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Meine Apps"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Keine Spiele gefunden."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Keine heruntergeladenen Anwendungen vorhanden"</string> + <string name="market" msgid="2652226429823445833">"Shop"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Element wurde nicht auf Startbildschirm abgelegt."</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Widget für Erstellung auswählen"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Ordnername"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Startseite"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Entfernen"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Deinstallieren"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Update deinstallieren"</string> <string name="menu_add" msgid="3065046628354640854">"Hinzufügen"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Apps verwalten"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Hintergrund"</string> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 5cebab77a..5e9b64492 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Οι εφαρμογές μου"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Δεν βρέθηκαν παιχνίδια."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Δεν υπάρχουν εφαρμογές από λήψη."</string> + <string name="market" msgid="2652226429823445833">"Αγορές"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Δεν έγινε η απόθ. του στοιχείου στην αρχική οθόνη"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Επιλογή γραφ. στοιχείου δημιουργίας"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Όνομα φακέλου"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Αρχική σελίδα"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Κατάργηση"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Κατάργηση εγκατάστασης"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Κατάργηση εγκατάστασης ενημέρωσης"</string> <string name="menu_add" msgid="3065046628354640854">"Προσθήκη"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Διαχείριση εφαρμογών"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Ταπετσαρία"</string> diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 5693d76ee..733413327 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"My apps"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"No games found."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"You have no downloaded applications."</string> + <string name="market" msgid="2652226429823445833">"Shop"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Could not drop item onto this home screen"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Select widget to create"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Folder name"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Home"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Remove"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Uninstall"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Uninstall update"</string> <string name="menu_add" msgid="3065046628354640854">"Add"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Manage apps"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Wallpaper"</string> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index 207d5b59b..eadcbaef4 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mis aplicaciones"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"No se encontraron juegos."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"No has descargado ninguna aplicación."</string> + <string name="market" msgid="2652226429823445833">"Comprar"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"No se pudo colocar el elemento en esta pantalla principal"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Seleccionar widget para crear"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nombre de carpeta"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Página principal"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Quitar"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Desinstalar"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Desinstalar la actualización"</string> <string name="menu_add" msgid="3065046628354640854">"Agregar"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Administrar aplicaciones"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Papel tapiz"</string> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 0592f99ec..90b4e1d7d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mis aplicaciones"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"No hay juegos."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"No tienes aplicaciones descargadas."</string> + <string name="market" msgid="2652226429823445833">"Tienda"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"No se puede soltar el elemento en este escritorio."</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Seleccionar widget"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nombre de carpeta"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Inicio"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Eliminar del escritorio"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Desinstalar"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Desinstalar actualización"</string> <string name="menu_add" msgid="3065046628354640854">"Añadir"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Administrar aplicaciones"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Fondo de pantalla"</string> diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 11b9f2de3..0d53ea5f0 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"برنامه های من"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"هیچ بازی پیدا نشد."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"شما هیچ برنامه کاربردی دانلود شده ای ندارید."</string> + <string name="market" msgid="2652226429823445833">"فروشگاه"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"نمی توان موردی در این صفحه اصلی انداخت"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"انتخاب ابزارک جهت ایجاد"</string> <string name="rename_folder_label" msgid="5646236631298452787">"نام پوشه"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"صفحه اصلی"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"حذف"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"حذف نصب"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"حذف نصب به روزرسانی"</string> <string name="menu_add" msgid="3065046628354640854">"افزودن"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"مدیریت برنامه ها"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"تصویر زمینه"</string> diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 7aee9f140..7b02c8ddb 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Omat sovellukset"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Ei pelejä."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Ei ladattuja sovelluksia."</string> + <string name="market" msgid="2652226429823445833">"Myymälä"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Kohdetta ei voi lisätä etusivulle"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Valitse luotava widget"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Kansion nimi"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Etusivu"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Poista"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Poista"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Poista päivitys"</string> <string name="menu_add" msgid="3065046628354640854">"Lisää"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Hallinnoi sovelluksia"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Taustakuva"</string> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index efcbc8a92..7ff39d77c 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mes applications"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Aucun jeu n\'a été trouvé."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Vous n\'avez téléchargé aucune application."</string> + <string name="market" msgid="2652226429823445833">"Acheter"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Impossible de déposer l\'élément sur l\'écran d\'accueil."</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Sélectionner le widget à créer"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nom du dossier"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Page d\'accueil"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Supprimer"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Désinstaller"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Désinstaller la mise à jour"</string> <string name="menu_add" msgid="3065046628354640854">"Ajouter"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gérer les applications"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Fond d\'écran"</string> diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml index 848f53909..ea09db0f4 100644 --- a/res/values-hr/strings.xml +++ b/res/values-hr/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikacije"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Igre nisu pronađene."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nemate preuzetih aplikacija"</string> + <string name="market" msgid="2652226429823445833">"Trgovina"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Nije bilo moguće spustiti stavku na početni zaslon"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Odabir widgeta za stvaranje"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Naziv mape"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Početna"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Ukloni"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Deinstaliraj"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Deinstalacija ažuriranja"</string> <string name="menu_add" msgid="3065046628354640854">"Dodaj"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Upravljaj aplikacijama"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Pozadinska slika"</string> diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml index 81be5a73c..77d9dda2f 100644 --- a/res/values-hu/strings.xml +++ b/res/values-hu/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Saját alkalmazások"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nincsenek játékok."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nincsenek letöltött alkalmazásai."</string> + <string name="market" msgid="2652226429823445833">"Bolt"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Nem lehet elhelyezni az elemet ezen a főoldalon"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"A létrehozandó modul kiválasztása"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mappa neve"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Főoldal"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Eltávolítás"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Eltávolítás"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Eltávolítja a frissítést"</string> <string name="menu_add" msgid="3065046628354640854">"Hozzáadás"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Alkalmazások kezelése"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Háttérkép"</string> diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 4abe037a1..a7ed85641 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Apl saya"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Tidak ditemukan permainan."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Anda tidak memiliki aplikasi yang diunduh."</string> + <string name="market" msgid="2652226429823445833">"Belanja"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Tidak dapat menaruh item pada layar utama ini"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Pilih widget untuk membuat"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nama map"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Rumah"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Hapus"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Copot pemasangan"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Copot pemasangan pemutakhiran"</string> <string name="menu_add" msgid="3065046628354640854">"Tambahkan"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Mengelola aplikasi"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Wallpaper"</string> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 4205973c5..003db6f3c 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Le mie applicazioni"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nessun gioco trovato."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Non hai applicazioni scaricate."</string> + <string name="market" msgid="2652226429823445833">"Acquista"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Impossibile rilasciare elemento in schermata Home"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Seleziona il widget da creare"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nome cartella"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Home"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Rimuovi"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Disinstalla"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Disinstalla aggiornamento"</string> <string name="menu_add" msgid="3065046628354640854">"Aggiungi"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gestisci applicazioni"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Sfondo"</string> diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index 8eaa4331f..75df2457c 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"היישומים שלי"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"לא נמצאו משחקים."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"לא הורדת יישומים."</string> + <string name="market" msgid="2652226429823445833">"קנה"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"אין אפשרות להניח פריט במסך בית זה"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"בחר widget כדי ליצור"</string> <string name="rename_folder_label" msgid="5646236631298452787">"שם תיקיה"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"דף הבית"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"הסר"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"הסר התקנה"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"הסר את התקנת העדכון"</string> <string name="menu_add" msgid="3065046628354640854">"הוסף"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"נהל יישומים"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"טפט"</string> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 026423230..ee6ab8326 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"マイアプリ"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"ゲームなし"</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"ダウンロードしたアプリケーションはありません。"</string> + <string name="market" msgid="2652226429823445833">"ショップ"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"このホーム画面にアイテムをドロップできませんでした"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"作成するウィジェットを選択"</string> <string name="rename_folder_label" msgid="5646236631298452787">"フォルダ名"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"ホーム"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"削除"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"アンインストール"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"アップデートをアンインストール"</string> <string name="menu_add" msgid="3065046628354640854">"追加"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"アプリの管理"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"壁紙"</string> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 41de035ea..f2b8b0c10 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"내 애플리케이션"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"게임이 없습니다."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"다운로드한 애플리케이션이 없습니다."</string> + <string name="market" msgid="2652226429823445833">"쇼핑"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"홈 화면에 항목을 드롭할 수 없습니다."</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"만들 위젯 선택"</string> <string name="rename_folder_label" msgid="5646236631298452787">"폴더 이름"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"홈"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"삭제"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"제거"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"업데이트 제거"</string> <string name="menu_add" msgid="3065046628354640854">"추가"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"애플리케이션 관리"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"배경화면"</string> diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 98817fd42..acf0e2786 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mano programos"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nerasta žaidimų."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Neturite atsisiųstų programų."</string> + <string name="market" msgid="2652226429823445833">"Parduotuvė"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Nepavyko pašalinti elemento šiame pagr. ekrane"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Pasirinkti norimą sukurti valdiklį"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Aplanko pavadinimas"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Pagrindinis"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Pašalinti"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Pašalinti"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Pašalinti naujinį"</string> <string name="menu_add" msgid="3065046628354640854">"Pridėti"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Valdyti programas"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Darbalaukio fonas"</string> diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml index fec6492ef..9c1b389dd 100644 --- a/res/values-lv/strings.xml +++ b/res/values-lv/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Manas lietotnes"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nav nevienas spēles."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nav ielādēta neviena lietojumprogramma."</string> + <string name="market" msgid="2652226429823445833">"Iepirkties"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Nevarēja nomest vienumu šajā sākumekrānā."</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Atlasīt izveidojamo logrīku"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mapes nosaukums"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Sākums"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Noņemt"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Atinstalēt"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Atinstalēt atjauninājumu"</string> <string name="menu_add" msgid="3065046628354640854">"Pievienot"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Lietotņu pārvaldība"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Fona tapete"</string> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 998812b91..ccdab7e82 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mine programmer"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Finner ingen spill."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Du har ingen nedlastede programmer."</string> + <string name="market" msgid="2652226429823445833">"Butikk"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Kunne ikke slippe elementet på denne startskjermen"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Velg modul for oppretting"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mappenavn"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Startsiden"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Fjern"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Avinstaller"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Avinstaller oppdateringen"</string> <string name="menu_add" msgid="3065046628354640854">"Legg til"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Administrer programmer"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Bakgrunnsbilde"</string> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 95ef9a060..3d7c7ac10 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mijn apps"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Geen games gevonden."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"U heeft geen gedownloade apps."</string> + <string name="market" msgid="2652226429823445833">"Winkel"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Kan item niet neerzetten op dit startscherm"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Widget selecteren om te maken"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mapnaam"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Startpagina"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Verwijderen"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Verwijderen"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Update verwijderen"</string> <string name="menu_add" msgid="3065046628354640854">"Toevoegen"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Apps beheren"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Achtergrond"</string> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index b457e5638..f1161652a 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikacje"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nie znaleziono gier."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nie masz żadnych pobranych aplikacji."</string> + <string name="market" msgid="2652226429823445833">"Sklep"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Nie można upuścić elementu na ekranie głównym"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Wybierz widżet do utworzenia"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nazwa folderu"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Ekran główny"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Usuń"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Odinstaluj"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Odinstaluj aktualizację"</string> <string name="menu_add" msgid="3065046628354640854">"Dodaj"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Zarządzaj aplikacjami"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Tapeta"</string> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 931a8eabf..a3a5a8dd7 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"As minhas aplicações"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Sem jogos."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Não existem aplicações transferidas."</string> + <string name="market" msgid="2652226429823445833">"Loja"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Não foi possível largar o item neste ecrã inicial"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Seleccionar widget a criar"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nome da pasta"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Página inicial"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Remover"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Desinstalar"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Desinstalar atualização"</string> <string name="menu_add" msgid="3065046628354640854">"Adicionar"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gerir aplicações"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Imagem de fundo"</string> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index c4fb78a80..55deb9439 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Meus aplicativos"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nenhum jogo encontrado."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Você não tem nenhum aplicativo transferido."</string> + <string name="market" msgid="2652226429823445833">"Comprar"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Não foi possível soltar o item nesta tela inicial"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Selecione um widget para criar"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nome da pasta"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Página inicial"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Remover"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Desinstalar"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Desinstalar atualização"</string> <string name="menu_add" msgid="3065046628354640854">"Adicionar"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gerenciar aplicativos"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Plano de fundo"</string> diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml index 6ac87d4fb..1b5729b7e 100644 --- a/res/values-rm/strings.xml +++ b/res/values-rm/strings.xml @@ -51,6 +51,8 @@ <skip /> <!-- no translation found for all_apps_no_downloads (2284720393234453761) --> <skip /> + <!-- no translation found for market (2652226429823445833) --> + <skip /> <!-- no translation found for external_drop_widget_error (4976816434597126575) --> <skip /> <!-- no translation found for external_drop_widget_pick_title (4481311720134376218) --> @@ -83,6 +85,8 @@ <skip /> <!-- no translation found for delete_zone_label_all_apps (6664588234817475108) --> <skip /> + <!-- no translation found for delete_zone_label_all_apps_system_app (3683920959591819044) --> + <skip /> <string name="menu_add" msgid="3065046628354640854">"Agiuntar"</string> <!-- no translation found for menu_manage_apps (2308685199463588895) --> <skip /> diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 7addc18a9..3a72c51b1 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Aplicaţiile mele"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nu s-au găsit jocuri."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nu aveţi aplicaţii descărcate."</string> + <string name="market" msgid="2652226429823445833">"Cumpăraţi"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Impos. de plasat elem. pe acest ecran de pornire"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Selectaţi obiectul widget"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Nume dosar"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Domiciliu"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Eliminaţi"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Dezinstalaţi"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Dezinstalaţi actualizarea"</string> <string name="menu_add" msgid="3065046628354640854">"Adăugaţi"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Gestionaţi aplicaţii"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Imagine de fundal"</string> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 76ef1ffbf..912c3f42f 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Мои приложения"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Игр не найдено."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"У вас нет загруженных приложений."</string> + <string name="market" msgid="2652226429823445833">"Маркет"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Не удается скопировать элемент на главный экран"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Выберите виджет"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Название папки"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Главная"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Удалить"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Удалить"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Удалить обновление"</string> <string name="menu_add" msgid="3065046628354640854">"Добавить"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Приложения"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Обои"</string> diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 90cc9ebf8..3cadf3b56 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikácie"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Nenašli sa žiadne hry."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nemáte žiadne prevzaté aplikácie."</string> + <string name="market" msgid="2652226429823445833">"Obchod"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Položku sa nepodarilo pretiahnuť na túto plochu"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Vyberte miniaplikáciu"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Názov priečinka"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Domovská stránka"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Odstrániť"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Odinštalovať"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Odinštalovať aktualizáciu"</string> <string name="menu_add" msgid="3065046628354640854">"Pridať"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Spravovať aplikácie"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Tapeta"</string> diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml index 8ceeb87bb..daf089931 100644 --- a/res/values-sl/strings.xml +++ b/res/values-sl/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moji programi"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Ni najdenih iger."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Ni prenesenih programov."</string> + <string name="market" msgid="2652226429823445833">"Nakup"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Elementa ni bilo mogoče postaviti na ta začetni zaslon"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Izberite želeni pripomoček"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Ime mape"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Začetni zaslon"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Odstrani"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Odstrani"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Odstrani posodobitev"</string> <string name="menu_add" msgid="3065046628354640854">"Dodaj"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Upravljaj programe"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Slika za ozadje"</string> diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 5c8922738..1d920807e 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Моје апликације"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Нису пронађене игре."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Немате ниједну преузету апликацију."</string> + <string name="market" msgid="2652226429823445833">"Куповина"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Ставка није пребачена на овај почетни екран"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Изаберите виџет за креирање"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Име директоријума"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Почетна"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Уклони"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Деинсталирај"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Деинсталирај ажурирања"</string> <string name="menu_add" msgid="3065046628354640854">"Додај"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Управљање апликацијама"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Позадина"</string> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index ad748857a..8094f05b5 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mina appar"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Inga spel hittades."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Du har inte hämtat några appar."</string> + <string name="market" msgid="2652226429823445833">"Butik"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Objektet kunde inte släppas på den här startsidan"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Välj en widget att skapa"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Mappnamn"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Startsida"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Ta bort"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Avinstallera"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Avinstallera uppdatering"</string> <string name="menu_add" msgid="3065046628354640854">"Lägg till"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Hantera appar"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Bakgrund"</string> diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml index 0a19cbbe2..26c33c915 100644 --- a/res/values-th/strings.xml +++ b/res/values-th/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"แอปพลิเคชันของฉัน"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"ไม่พบเกม"</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"คุณไม่ได้ดาวน์โหลดแอปพลิเคชันไว้"</string> + <string name="market" msgid="2652226429823445833">"ร้าน"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"ไม่สามารถวางรายการลงในหน้าจอหลักนี้ได้"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"เลือกวิดเจ็ตที่จะสร้าง"</string> <string name="rename_folder_label" msgid="5646236631298452787">"ชื่อโฟลเดอร์"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"บ้าน"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"นำออก"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"ถอนการติดตั้ง"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"ถอนการติดตั้งการอัปเดต"</string> <string name="menu_add" msgid="3065046628354640854">"เพิ่ม"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"จัดการแอปพลิเคชัน"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"วอลเปเปอร์"</string> diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index f131b0253..f21dc3c66 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Aking mga app"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Walang nakitang mga laro."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Wala kang mga na-download na application."</string> + <string name="market" msgid="2652226429823445833">"Mamili"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Hindi ma-drop ang item sa homescreen na ito"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Pumili ng widget na lilikhain"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Pangalan ng folder"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Home"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Alisin"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"I-uninstall"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"I-uninstall ang update"</string> <string name="menu_add" msgid="3065046628354640854">"Idagdag"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Pamahalaan ang apps"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Wallpaper"</string> diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index c27c5860c..bf80bf52b 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Uygulamalarım"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Oyun bulunamadı."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"İndirilmiş uygulamanız yok."</string> + <string name="market" msgid="2652226429823445833">"Alışveriş"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Öğe bu ana ekrana bırakılamadı"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Oluşturulacak widget\'i seç"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Klasör adı"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Ana Sayfa"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Kaldır"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Yüklemeyi Kaldır"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Güncelleme kaldırılsın mı?"</string> <string name="menu_add" msgid="3065046628354640854">"Ekle"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Uyglm yönet"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Duvar Kağıdı"</string> diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 2095bc997..267ca882f 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Мої програми"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Ігор не знайдено."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"У вас немає завантажених програм."</string> + <string name="market" msgid="2652226429823445833">"Магазин"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Неможливо помістити елемент на цей головний екран"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Вибрати віджет для створення"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Назва папки"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Головна"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Видалити"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Видалити"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Видалити оновлення"</string> <string name="menu_add" msgid="3065046628354640854">"Додати"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Керув. прогр."</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Фоновий мал."</string> diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 8e5b4c36f..d3f549f92 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Ứng dụng của tôi"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"Không tìm thấy trò chơi."</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Bạn không có ứng dụng nào được tải xuống."</string> + <string name="market" msgid="2652226429823445833">"Mua hàng"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"Không thể thả mục vào màn hình chính này"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"Chọn tiện ích để tạo"</string> <string name="rename_folder_label" msgid="5646236631298452787">"Tên thư mục"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"Màn hình trang chủ"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"Xóa"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"Gỡ cài đặt"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"Gỡ cài đặt cập nhật"</string> <string name="menu_add" msgid="3065046628354640854">"Thêm"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"Quản lý ứng dụng"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"Hình nền"</string> diff --git a/res/values-xlarge-land/dimens.xml b/res/values-xlarge-land/dimens.xml index 51037f5b0..b3d40d584 100644 --- a/res/values-xlarge-land/dimens.xml +++ b/res/values-xlarge-land/dimens.xml @@ -22,4 +22,11 @@ <!-- Width/height gap overrides for the workspace --> <dimen name="workspace_width_gap">32dp</dimen> <dimen name="workspace_height_gap">2dp</dimen> + + <dimen name="workspace_page_spacing">50dp</dimen> + + <dimen name="customization_drawer_height">480dp</dimen> + <dimen name="customization_drawer_content_height">420dp</dimen> + <dimen name="customization_drawer_content_min_width">952dp</dimen> + <dimen name="customization_drawer_tab_widget_width">952dp</dimen> </resources>
\ No newline at end of file diff --git a/res/values-xlarge-port/dimens.xml b/res/values-xlarge-port/dimens.xml index baa31aace..8a4c78bc7 100644 --- a/res/values-xlarge-port/dimens.xml +++ b/res/values-xlarge-port/dimens.xml @@ -22,4 +22,11 @@ <!-- Width/height gap overrides for the workspace --> <dimen name="workspace_width_gap">0dp</dimen> <dimen name="workspace_height_gap">32dp</dimen> + + <dimen name="workspace_page_spacing">64dp</dimen> + + <dimen name="customization_drawer_height">800dp</dimen> + <dimen name="customization_drawer_content_height">420dp</dimen> + <dimen name="customization_drawer_content_min_width">640dp</dimen> + <dimen name="customization_drawer_tab_widget_width">700dp</dimen> </resources>
\ No newline at end of file diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml index dc9d096f8..56c7bc688 100644 --- a/res/values-xlarge/config.xml +++ b/res/values-xlarge/config.xml @@ -9,7 +9,8 @@ <!-- Duration in milliseconds of the all apps / configuration zoom-in animation. --> <!-- NB: This should be less than the workspaceShrinkTime as they happen together. --> - <integer name="config_allAppsZoomInTime">1450</integer> + <integer name="config_allAppsZoomInTime">1000</integer> + <integer name="config_allAppsFadeInTime">250</integer> <!-- Duration in milliseconds of the transition between tabs in the all apps/customize tray --> @@ -25,6 +26,7 @@ <!-- Duration in milliseconds of the all apps / configuration zoom-in animation. --> <!-- NB: This should be less than the workspaceShrinkTime as they happen together. --> <integer name="config_customizeZoomInTime">800</integer> + <integer name="config_customizeFadeInTime">800</integer> <!-- Duration in milliseconds of the all apps zoom-out animation --> <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. --> @@ -35,10 +37,9 @@ <!-- Duration in milliseconds of the animations between all apps, customize, & home. NOTE: If these are changed, the toolbar animation times below should also be. --> - <integer name="config_allAppsCameraPanTime">700</integer> <integer name="config_allAppsFadeOutTime">500</integer> <integer name="config_customizeWorkspaceShrinkTime">800</integer> - <integer name="config_allAppsWorkspaceShrinkTime">1450</integer> + <integer name="config_allAppsWorkspaceShrinkTime">1000</integer> <integer name="config_workspaceUnshrinkTime">650</integer> <!-- Duration in milliseconds toolbar fade in and fade out animations. @@ -66,12 +67,6 @@ <integer name="config_screenOnDropAlphaFadeDelay">350</integer> <integer name="config_screenOnDropAlphaFadeDuration">50</integer> - <!-- Workspace screens are cached to bitmaps only when they're smaller than a certain size - (maxScaleForUsingWorkspaceScreenBitmapCache), since the bitmap cache itself is smaller - than the view itself (workspaceScreenBitmapCacheScale) --> - <integer name="config_workspaceScreenBitmapCacheScale">20</integer> - <integer name="config_maxScaleForUsingWorkspaceScreenBitmapCache">50</integer> - <!-- The slope, in percent, of the drag movement needed to drag an item out of the customization drawer (y / x * 100%) --> <integer name="config_customizationDrawerDragSlopeThreshold">150</integer> diff --git a/res/values-xlarge/dimens.xml b/res/values-xlarge/dimens.xml index c4988e42e..421c9e389 100644 --- a/res/values-xlarge/dimens.xml +++ b/res/values-xlarge/dimens.xml @@ -37,11 +37,6 @@ <dimen name="allAppsSmallScreenVerticalMarginLandscape">30dip</dimen> <dimen name="allAppsSmallScreenVerticalMarginPortrait">60dip</dimen> - <!-- Vertical spacing between edge of screen and mini cell layouts when they - are minimized to the top when the customization drawer is showing --> - <dimen name="customizeSmallScreenVerticalMarginLandscape">90dip</dimen> - <dimen name="customizeSmallScreenVerticalMarginPortrait">180dip</dimen> - <dimen name="delete_zone_drawable_padding">8dip</dimen> <dimen name="all_apps_button_drawable_padding">0dip</dimen> <dimen name="all_apps_button_vertical_padding">4dip</dimen> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index cd840c3e0..a3dc212bd 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"我的应用程序"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"未找到游戏。"</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"您没有下载任何应用程序。"</string> + <string name="market" msgid="2652226429823445833">"购买"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"无法将该项放到主屏幕上"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"选择窗口小部件进行创建"</string> <string name="rename_folder_label" msgid="5646236631298452787">"文件夹名称"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"主屏幕"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"删除"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"卸载"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"卸载更新"</string> <string name="menu_add" msgid="3065046628354640854">"添加"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"管理应用程序"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"壁纸"</string> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 0622dde18..2274274f8 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -39,6 +39,7 @@ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"我的應用程式"</string> <string name="all_apps_no_games" msgid="5293893733372793696">"找不到遊戲。"</string> <string name="all_apps_no_downloads" msgid="2284720393234453761">"您沒有下載任何應用程式。"</string> + <string name="market" msgid="2652226429823445833">"商店"</string> <string name="external_drop_widget_error" msgid="4976816434597126575">"無法將項目拖放至主螢幕上"</string> <string name="external_drop_widget_pick_title" msgid="4481311720134376218">"選取要建立的小工具"</string> <string name="rename_folder_label" msgid="5646236631298452787">"資料夾名稱"</string> @@ -66,6 +67,7 @@ <string name="all_apps_home_button_label" msgid="1022222300329398558">"主螢幕"</string> <string name="delete_zone_label_workspace" msgid="7153615831493049150">"移除"</string> <string name="delete_zone_label_all_apps" msgid="6664588234817475108">"解除安裝"</string> + <string name="delete_zone_label_all_apps_system_app" msgid="3683920959591819044">"解除安裝更新"</string> <string name="menu_add" msgid="3065046628354640854">"新增"</string> <string name="menu_manage_apps" msgid="2308685199463588895">"管理應用程式"</string> <string name="menu_wallpaper" msgid="5837429080911269832">"桌布"</string> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 5e6a2ab64..2be599955 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -61,6 +61,16 @@ </declare-styleable> + <!-- StrokedTextView specific attributes. --> + <declare-styleable name="StrokedTextView"> + <!-- The color of the stroke outline --> + <attr name="strokeColor" format="color" /> + <!-- The color of the text --> + <attr name="strokeTextColor" format="color" /> + <!-- The width of the stroke --> + <attr name="strokeWidth" format="float" /> + </declare-styleable> + <!-- PagedViewIcon specific attributes. These attributes are used to customize a PagedViewIcon view in XML files. --> <declare-styleable name="PagedViewIcon"> diff --git a/res/values/config.xml b/res/values/config.xml index 850c60922..c56a8cec2 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -25,12 +25,6 @@ <!-- The alpha value at which to show the most recent drop visualization outline. --> <integer name="config_dragOutlineMaxAlpha">128</integer> - <!-- Workspace screens are cached to bitmaps only when they're smaller than a certain size - (maxScaleForUsingWorkspaceScreenBitmapCache), since the bitmap cache it self is smaller - than the view itself (workspaceScreenBitmapCacheScale) --> - <integer name="config_workspaceScreenBitmapCacheScale">20</integer> - <integer name="config_maxScaleForUsingWorkspaceScreenBitmapCache">50</integer> - <!-- Parameters controlling the animation for when an item is dropped on the home screen, and it animates from its old position to the new one. --> @@ -39,6 +33,12 @@ <!-- The distance at which the animation should take the max duration --> <integer name="config_dropAnimMaxDist">800</integer> + <!-- Workspace screens are cached to bitmaps only when they're smaller than a certain size + (maxScaleForUsingWorkspaceScreenBitmapCache), since the bitmap cache itself is smaller + than the view itself (workspaceScreenBitmapCacheScale) --> + <integer name="config_workspaceScreenBitmapCacheScale">20</integer> + <integer name="config_maxScaleForUsingWorkspaceScreenBitmapCache">50</integer> + <style name="config_orientation"> <item name="@android:screenOrientation">nosensor</item> </style> diff --git a/res/values/strings.xml b/res/values/strings.xml index 6dcaa5748..eedbd6a9e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -72,6 +72,8 @@ <string name="all_apps_no_games">No games found.</string> <!-- Message to show when there are no downloaded apps [CHAR_LIMIT=50] --> <string name="all_apps_no_downloads">You have no downloaded applications.</string> + <!-- Market button text [CHAR LIMIT=32] --> + <string name="market">Shop</string> <!-- Customization Drawer --> <!-- The format string for the dimensions of a widget in the drawer --> @@ -149,6 +151,10 @@ device. [CHAR_LIMIT=30]--> <string name="delete_zone_label_all_apps">Uninstall</string> + <!-- Label for trash icon in All Apps, when an updated system app is selected. The update will + be uninstalled. [CHAR_LIMIT=30] --> + <string name="delete_zone_label_all_apps_system_app">Uninstall update</string> + <!-- Menus items: --> <skip /> <!-- Verb, menu item used to add an item on the desktop --> diff --git a/src/com/android/launcher2/AllApps2D.java b/src/com/android/launcher2/AllApps2D.java index 66d939589..1cbb99994 100644 --- a/src/com/android/launcher2/AllApps2D.java +++ b/src/com/android/launcher2/AllApps2D.java @@ -211,7 +211,7 @@ public class AllApps2D } @Override - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { } /** @@ -313,19 +313,9 @@ public class AllApps2D mVisibleAppsList.clear(); if (appType == AppType.ALL) { mVisibleAppsList.addAll(mAllAppsList); - } else { - int searchFlags = 0; - - if (appType == AppType.APP) { - searchFlags = ApplicationInfo.APP_FLAG; - } else if (appType == AppType.GAME) { - searchFlags = ApplicationInfo.GAME_FLAG; - } else if (appType == AppType.DOWNLOADED) { - searchFlags = ApplicationInfo.DOWNLOADED_FLAG; - } - + } else if (appType == AppType.DOWNLOADED) { for (ApplicationInfo info : mAllAppsList) { - if ((info.flags & searchFlags) != 0) { + if ((info.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) { mVisibleAppsList.add(info); } } diff --git a/src/com/android/launcher2/AllApps3D.java b/src/com/android/launcher2/AllApps3D.java index 2ecf761fd..29f49afc2 100644 --- a/src/com/android/launcher2/AllApps3D.java +++ b/src/com/android/launcher2/AllApps3D.java @@ -685,16 +685,14 @@ public class AllApps3D extends RSSurfaceView && mCurrentIconIndex >= 0 && mCurrentIconIndex < mAllAppsList.size()) { ApplicationInfo app = mAllAppsList.get(mCurrentIconIndex); - Bitmap bmp = app.iconBitmap; - final int w = bmp.getWidth(); - final int h = bmp.getHeight(); + final Bitmap bmp = app.iconBitmap; // We don't really have an accurate location to use. This will do. - int screenX = mMotionDownRawX - (w / 2); - int screenY = mMotionDownRawY - h; + int screenX = mMotionDownRawX - (bmp.getWidth() / 2); + int screenY = mMotionDownRawY - bmp.getHeight(); - mDragController.startDrag(bmp, screenX, screenY, - 0, 0, w, h, this, app, DragController.DRAG_ACTION_COPY); + mDragController.startDrag( + bmp, screenX, screenY, this, app, DragController.DRAG_ACTION_COPY); mLauncher.closeAllApps(true); } @@ -748,7 +746,7 @@ public class AllApps3D extends RSSurfaceView } @Override - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { } /** diff --git a/src/com/android/launcher2/AllAppsBackground.java b/src/com/android/launcher2/AllAppsBackground.java new file mode 100644 index 000000000..5292d0ad3 --- /dev/null +++ b/src/com/android/launcher2/AllAppsBackground.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher2; + +import com.android.launcher.R; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; + +/** + * An implementation of PagedView that populates the pages of the workspace + * with all of the user's applications. + */ +public class AllAppsBackground extends View { + private Drawable mBackground; + + public AllAppsBackground(Context context) { + this(context, null); + } + + public AllAppsBackground(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public AllAppsBackground(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mBackground = getResources().getDrawable(R.drawable.all_apps_bg_gradient); + } + + @Override + public void onDraw(Canvas canvas) { + mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(), + getMeasuredHeight()); + mBackground.draw(canvas); + } +} diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java index daa5d6403..b9b38c3d6 100644 --- a/src/com/android/launcher2/AllAppsPagedView.java +++ b/src/com/android/launcher2/AllAppsPagedView.java @@ -63,6 +63,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All private int mAppFilter = ALL_APPS_FLAG; private final LayoutInflater mInflater; + private boolean mAllowHardwareLayerCreation; public AllAppsPagedView(Context context) { @@ -79,6 +80,8 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6); mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4); mInflater = LayoutInflater.from(context); + mApps = new ArrayList<ApplicationInfo>(); + mFilteredApps = new ArrayList<ApplicationInfo>(); a.recycle(); setSoundEffectsEnabled(false); @@ -93,6 +96,22 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All mCenterPagesVertically = false; } + void allowHardwareLayerCreation() { + // This is called after the first time we launch into All Apps. Before that point, + // there's no need for hardware layers here since there's a hardware layer set on the + // parent, AllAppsTabbed, during the AllApps transition -- creating hardware layers here + // before the animation is done slows down the animation + if (mAllowHardwareLayerCreation) { + return; + } + mAllowHardwareLayerCreation = true; + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + PagedViewCellLayout page = (PagedViewCellLayout) getChildAt(i); + page.allowHardwareLayerCreation(); + } + } + @Override public void setLauncher(Launcher launcher) { mLauncher = launcher; @@ -119,8 +138,6 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All cancelLongPress(); if (isVisible()) { - getParent().bringChildToFront(this); - setVisibility(View.VISIBLE); if (animate) { startAnimation(AnimationUtils.loadAnimation(getContext(), R.anim.all_apps_2d_fade_in)); @@ -139,7 +156,6 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All protected void onAnimationEnd() { if (!isVisible()) { - setVisibility(View.GONE); mZoom = 0.0f; endChoiceMode(); @@ -201,11 +217,21 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All } } - private void setupDragMode() { + private void setupDragMode(ApplicationInfo info) { mLauncher.getWorkspace().shrink(Workspace.ShrinkState.BOTTOM_VISIBLE); - DeleteZone allAppsDeleteZone = (DeleteZone) - mLauncher.findViewById(R.id.all_apps_delete_zone); - allAppsDeleteZone.setDragAndDropEnabled(true); + + // Only show the uninstall button if the app is uninstallable. + if ((info.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) { + DeleteZone allAppsDeleteZone = (DeleteZone) + mLauncher.findViewById(R.id.all_apps_delete_zone); + allAppsDeleteZone.setDragAndDropEnabled(true); + + if ((info.flags & ApplicationInfo.UPDATED_SYSTEM_APP_FLAG) != 0) { + allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps_system_app); + } else { + allAppsDeleteZone.setText(R.string.delete_zone_label_all_apps); + } + } ApplicationInfoDropTarget allAppsInfoButton = (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target); @@ -238,12 +264,12 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All if (!v.isInTouchMode()) return false; if (!super.beginDragging(v)) return false; - // Start drag mode after the item is selected - setupDragMode(); - ApplicationInfo app = (ApplicationInfo) v.getTag(); app = new ApplicationInfo(app); + // Start drag mode after the item is selected + setupDragMode(app); + // get icon (top compound drawable, index is 1) final TextView tv = (TextView) v; final Drawable icon = tv.getCompoundDrawables()[1]; @@ -282,7 +308,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All } @Override - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { // close the choice action mode if we have a proper drop if (target != this) { endChoiceMode(); @@ -376,6 +402,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All } mFilteredApps = rebuildFilteredApps(mApps); } + @Override public void removeApps(ArrayList<ApplicationInfo> list) { removeAppsWithoutInvalidate(list); @@ -390,12 +417,14 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All } private int findAppByComponent(ArrayList<ApplicationInfo> list, ApplicationInfo item) { - ComponentName removeComponent = item.intent.getComponent(); - final int length = list.size(); - for (int i = 0; i < length; ++i) { - ApplicationInfo info = list.get(i); - if (info.intent.getComponent().equals(removeComponent)) { - return i; + if (item != null && item.intent != null) { + ComponentName removeComponent = item.intent.getComponent(); + final int length = list.size(); + for (int i = 0; i < length; ++i) { + ApplicationInfo info = list.get(i); + if (info.intent.getComponent().equals(removeComponent)) { + return i; + } } } return -1; @@ -420,12 +449,15 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All // remove any extra pages after the "last" page int extraPageDiff = curNumPages - numPages; for (int i = 0; i < extraPageDiff; ++i) { + PagedViewCellLayout page = (PagedViewCellLayout) getChildAt(numPages); removeViewAt(numPages); } // add any necessary pages for (int i = curNumPages; i < numPages; ++i) { PagedViewCellLayout layout = new PagedViewCellLayout(getContext()); - layout.enableHardwareLayers(); + if (mAllowHardwareLayerCreation) { + layout.allowHardwareLayerCreation(); + } layout.setCellCount(mCellCountX, mCellCountY); layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, mPageLayoutPaddingRight, mPageLayoutPaddingBottom); @@ -515,6 +547,7 @@ public class AllAppsPagedView extends PagedViewWithDraggableItems implements All layout.addViewToCellLayout(icon, -1, 0, new PagedViewCellLayout.LayoutParams(0, 0, 4, 1)); } + layout.createHardwareLayers(); } /* diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java index 47a5bf7fc..0dd56acff 100644 --- a/src/com/android/launcher2/AllAppsTabbed.java +++ b/src/com/android/launcher2/AllAppsTabbed.java @@ -29,16 +29,19 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.widget.TabHost; import android.widget.TabWidget; import android.widget.TextView; +import android.widget.TabHost.OnTabChangeListener; +import android.widget.TabHost.TabContentFactory; import java.util.ArrayList; /** * Implements a tabbed version of AllApps2D. */ -public class AllAppsTabbed extends TabHost implements AllAppsView { +public class AllAppsTabbed extends TabHost implements AllAppsView, LauncherTransitionable { private static final String TAG = "Launcher.AllAppsTabbed"; @@ -46,6 +49,8 @@ public class AllAppsTabbed extends TabHost implements AllAppsView { private static final String TAG_DOWNLOADED = "DOWNLOADED"; private AllAppsPagedView mAllApps; + private AllAppsBackground mBackground; + private Launcher mLauncher; private Context mContext; private final LayoutInflater mInflater; private boolean mFirstLayout = true; @@ -64,6 +69,8 @@ public class AllAppsTabbed extends TabHost implements AllAppsView { try { mAllApps = (AllAppsPagedView) findViewById(R.id.all_apps_paged_view); if (mAllApps == null) throw new Resources.NotFoundException(); + mBackground = (AllAppsBackground) findViewById(R.id.all_apps_background); + if (mBackground == null) throw new Resources.NotFoundException(); } catch (Resources.NotFoundException e) { Log.e(TAG, "Can't find necessary layout elements for AllAppsTabbed"); } @@ -120,6 +127,7 @@ public class AllAppsTabbed extends TabHost implements AllAppsView { @Override public void setLauncher(Launcher launcher) { mAllApps.setLauncher(launcher); + mLauncher = launcher; } @Override @@ -164,6 +172,44 @@ public class AllAppsTabbed extends TabHost implements AllAppsView { } @Override + public void onLauncherTransitionStart(Animator animation) { + if (animation != null) { + // Turn on hardware layers for performance + setLayerType(LAYER_TYPE_HARDWARE, null); + // Re-enable the rendering of the dimmed background in All Apps for performance reasons + // if we're fading it in + if (mLauncher.getWorkspace().getBackgroundAlpha() == 0f) { + mLauncher.getWorkspace().disableBackground(); + mBackground.setVisibility(VISIBLE); + } + // just a sanity check that we don't build a layer before a call to onLayout + if (!mFirstLayout) { + // force building the layer at the beginning of the animation, so you don't get a + // blip early in the animation + buildLayer(); + } + } + } + + @Override + public void onLauncherTransitionEnd(Animator animation) { + if (animation != null) { + setLayerType(LAYER_TYPE_NONE, null); + // To improve the performance of the first time All Apps is run, we initially keep + // hardware layers in AllAppsPagedView disabled since AllAppsTabbed itself is drawn in a + // hardware layer, and creating additional hardware layers slows down the animation. We + // create them here, after the animation is over. + } + // Move the rendering of the dimmed background to workspace after the all apps animation + // is done, so that the background is not rendered *above* the mini workspace screens + if (mBackground.getVisibility() != GONE) { + mLauncher.getWorkspace().enableBackground(); + mBackground.setVisibility(GONE); + } + mAllApps.allowHardwareLayerCreation(); + } + + @Override public void setApps(ArrayList<ApplicationInfo> list) { mAllApps.setApps(list); } diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java new file mode 100644 index 000000000..2b2662f42 --- /dev/null +++ b/src/com/android/launcher2/AppWidgetResizeFrame.java @@ -0,0 +1,342 @@ +package com.android.launcher2; + +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.appwidget.AppWidgetProviderInfo; +import android.content.Context; +import android.view.Gravity; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.android.launcher.R; + +public class AppWidgetResizeFrame extends FrameLayout { + + private ItemInfo mItemInfo; + private LauncherAppWidgetHostView mWidgetView; + private CellLayout mCellLayout; + private ImageView mLeftHandle; + private ImageView mRightHandle; + private ImageView mTopHandle; + private ImageView mBottomHandle; + + private boolean mLeftBorderActive; + private boolean mRightBorderActive; + private boolean mTopBorderActive; + private boolean mBottomBorderActive; + + private int mBaselineWidth; + private int mBaselineHeight; + private int mBaselineX; + private int mBaselineY; + private int mResizeMode; + + private int mRunningHInc; + private int mRunningVInc; + private int mMinHSpan; + private int mMinVSpan; + private int mDeltaX; + private int mDeltaY; + + private int mBackgroundPadding; + private int mTouchTargetWidth; + + private int mExpandability[] = new int[4]; + + final int SNAP_DURATION = 150; + final int BACKGROUND_PADDING = 24; + final float DIMMED_HANDLE_ALPHA = 0f; + final float RESIZE_THRESHOLD = 0.66f; + + public static final int LEFT = 0; + public static final int TOP = 1; + public static final int RIGHT = 2; + public static final int BOTTOM = 3; + + public AppWidgetResizeFrame(Context context, ItemInfo itemInfo, + LauncherAppWidgetHostView widgetView, CellLayout cellLayout) { + + super(context); + mContext = context; + mItemInfo = itemInfo; + mCellLayout = cellLayout; + mWidgetView = widgetView; + mResizeMode = widgetView.getAppWidgetInfo().resizeMode; + + final AppWidgetProviderInfo info = widgetView.getAppWidgetInfo(); + int[] result = mCellLayout.rectToCell(info.minWidth, info.minHeight, null); + mMinHSpan = result[0]; + mMinVSpan = result[1]; + + setBackgroundResource(R.drawable.widget_resize_frame_holo); + setPadding(0, 0, 0, 0); + + LayoutParams lp; + mLeftHandle = new ImageView(context); + mLeftHandle.setImageResource(R.drawable.widget_resize_handle_left); + lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, + Gravity.LEFT | Gravity.CENTER_VERTICAL); + addView(mLeftHandle, lp); + + mRightHandle = new ImageView(context); + mRightHandle.setImageResource(R.drawable.widget_resize_handle_right); + lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, + Gravity.RIGHT | Gravity.CENTER_VERTICAL); + addView(mRightHandle, lp); + + mTopHandle = new ImageView(context); + mTopHandle.setImageResource(R.drawable.widget_resize_handle_top); + lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, + Gravity.CENTER_HORIZONTAL | Gravity.TOP); + addView(mTopHandle, lp); + + mBottomHandle = new ImageView(context); + mBottomHandle.setImageResource(R.drawable.widget_resize_handle_bottom); + lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, + Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM); + addView(mBottomHandle, lp); + + if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) { + mTopHandle.setVisibility(GONE); + mBottomHandle.setVisibility(GONE); + } else if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) { + mLeftHandle.setVisibility(GONE); + mRightHandle.setVisibility(GONE); + } + + final float density = mContext.getResources().getDisplayMetrics().density; + mBackgroundPadding = (int) Math.ceil(density * BACKGROUND_PADDING); + mTouchTargetWidth = 2 * mBackgroundPadding; + } + + public boolean beginResizeIfPointInRegion(int x, int y) { + boolean horizontalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0; + boolean verticalActive = (mResizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0; + mLeftBorderActive = (x < mTouchTargetWidth) && horizontalActive; + mRightBorderActive = (x > getWidth() - mTouchTargetWidth) && horizontalActive; + mTopBorderActive = (y < mTouchTargetWidth) && verticalActive; + mBottomBorderActive = (y > getHeight() - mTouchTargetWidth) && verticalActive; + + boolean anyBordersActive = mLeftBorderActive || mRightBorderActive + || mTopBorderActive || mBottomBorderActive; + + mBaselineWidth = getMeasuredWidth(); + mBaselineHeight = getMeasuredHeight(); + mBaselineX = getLeft(); + mBaselineY = getTop(); + mRunningHInc = 0; + mRunningVInc = 0; + + if (anyBordersActive) { + mLeftHandle.setAlpha(mLeftBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); + mRightHandle.setAlpha(mRightBorderActive ? 1.0f :DIMMED_HANDLE_ALPHA); + mTopHandle.setAlpha(mTopBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); + mBottomHandle.setAlpha(mBottomBorderActive ? 1.0f : DIMMED_HANDLE_ALPHA); + } + mCellLayout.getExpandabilityArrayForView(mWidgetView, mExpandability); + + return anyBordersActive; + } + + /** + * Here we bound the deltas such that the frame cannot be stretched beyond the extents + * of the CellLayout, and such that the frame's borders can't cross. + */ + public void updateDeltas(int deltaX, int deltaY) { + if (mLeftBorderActive) { + mDeltaX = Math.max(-mBaselineX, deltaX); + mDeltaX = Math.min(mBaselineWidth - 2 * mTouchTargetWidth, mDeltaX); + } else if (mRightBorderActive) { + mDeltaX = Math.min(mCellLayout.getWidth() - (mBaselineX + mBaselineWidth), deltaX); + mDeltaX = Math.max(-mBaselineWidth + 2 * mTouchTargetWidth, mDeltaX); + } + + if (mTopBorderActive) { + mDeltaY = Math.max(-mBaselineY, deltaY); + mDeltaY = Math.min(mBaselineHeight - 2 * mTouchTargetWidth, mDeltaY); + } else if (mBottomBorderActive) { + mDeltaY = Math.min(mCellLayout.getHeight() - (mBaselineY + mBaselineHeight), deltaY); + mDeltaY = Math.max(-mBaselineHeight + 2 * mTouchTargetWidth, mDeltaY); + } + } + + /** + * Based on the deltas, we resize the frame, and, if needed, we resize the widget. + */ + public void visualizeResizeForDelta(int deltaX, int deltaY) { + updateDeltas(deltaX, deltaY); + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + if (mLeftBorderActive) { + lp.x = mBaselineX + mDeltaX; + lp.width = mBaselineWidth - mDeltaX; + } else if (mRightBorderActive) { + lp.width = mBaselineWidth + mDeltaX; + } + + if (mTopBorderActive) { + lp.y = mBaselineY + mDeltaY; + lp.height = mBaselineHeight - mDeltaY; + } else if (mBottomBorderActive) { + lp.height = mBaselineHeight + mDeltaY; + } + + resizeWidgetIfNeeded(); + requestLayout(); + } + + /** + * Based on the current deltas, we determine if and how to resize the widget. + */ + private void resizeWidgetIfNeeded() { + int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap(); + int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap(); + + float hSpanIncF = 1.0f * mDeltaX / xThreshold - mRunningHInc; + float vSpanIncF = 1.0f * mDeltaY / yThreshold - mRunningVInc; + + int hSpanInc = 0; + int vSpanInc = 0; + int cellXInc = 0; + int cellYInc = 0; + + if (Math.abs(hSpanIncF) > RESIZE_THRESHOLD) { + hSpanInc = Math.round(hSpanIncF); + } + if (Math.abs(vSpanIncF) > RESIZE_THRESHOLD) { + vSpanInc = Math.round(vSpanIncF); + } + + if (hSpanInc == 0 && vSpanInc == 0) return; + + // Before we change the widget, we clear the occupied cells associated with it. + // The new set of occupied cells is marked below, once the layout params are updated. + mCellLayout.markCellsAsUnoccupiedForView(mWidgetView); + + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams(); + + // For each border, we bound the resizing based on the minimum width, and the maximum + // expandability. + if (mLeftBorderActive) { + cellXInc = Math.max(-mExpandability[LEFT], hSpanInc); + cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc); + hSpanInc *= -1; + hSpanInc = Math.min(mExpandability[LEFT], hSpanInc); + hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc); + mRunningHInc -= hSpanInc; + } else if (mRightBorderActive) { + hSpanInc = Math.min(mExpandability[RIGHT], hSpanInc); + hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc); + mRunningHInc += hSpanInc; + } + + if (mTopBorderActive) { + cellYInc = Math.max(-mExpandability[TOP], vSpanInc); + cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc); + vSpanInc *= -1; + vSpanInc = Math.min(mExpandability[TOP], vSpanInc); + vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc); + mRunningVInc -= vSpanInc; + } else if (mBottomBorderActive) { + vSpanInc = Math.min(mExpandability[BOTTOM], vSpanInc); + vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc); + mRunningVInc += vSpanInc; + } + + // Update the widget's dimensions and position according to the deltas computed above + if (mLeftBorderActive || mRightBorderActive) { + lp.cellHSpan += hSpanInc; + lp.cellX += cellXInc; + } + + if (mTopBorderActive || mBottomBorderActive) { + lp.cellVSpan += vSpanInc; + lp.cellY += cellYInc; + } + + // Update the expandability array, as we have changed the widget's size. + mCellLayout.getExpandabilityArrayForView(mWidgetView, mExpandability); + + // Update the cells occupied by this widget + mCellLayout.markCellsAsOccupiedForView(mWidgetView); + } + + /** + * This is the final step of the resize. Here we save the new widget size and position + * to LauncherModel and animate the resize frame. + */ + public void commitResizeForDelta(int deltaX, int deltaY) { + visualizeResizeForDelta(deltaX, deltaY); + + CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams(); + LauncherModel.resizeItemInDatabase(getContext(), mItemInfo, lp.cellX, lp.cellY, + lp.cellHSpan, lp.cellVSpan); + mWidgetView.requestLayout(); + + // Once our widget resizes (hence the post), we want to snap the resize frame to it + post(new Runnable() { + public void run() { + snapToWidget(true); + } + }); + } + + public void snapToWidget(boolean animate) { + final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams(); + + int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding; + int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding; + int newX = mWidgetView.getLeft() - mBackgroundPadding; + int newY = mWidgetView.getTop() - mBackgroundPadding; + + // We need to make sure the frame stays within the bounds of the CellLayout + if (newY < 0) { + newHeight -= -newY; + newY = 0; + } + if (newY + newHeight > mCellLayout.getHeight()) { + newHeight -= newY + newHeight - mCellLayout.getHeight(); + } + + if (!animate) { + lp.width = newWidth; + lp.height = newHeight; + lp.x = newX; + lp.y = newY; + mLeftHandle.setAlpha(1.0f); + mRightHandle.setAlpha(1.0f); + mTopHandle.setAlpha(1.0f); + mBottomHandle.setAlpha(1.0f); + requestLayout(); + } else { + PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", lp.width, newWidth); + PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", lp.height, + newHeight); + PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", lp.x, newX); + PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", lp.y, newY); + ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); + ObjectAnimator leftOa = ObjectAnimator.ofFloat(mLeftHandle, "alpha", 1.0f); + ObjectAnimator rightOa = ObjectAnimator.ofFloat(mRightHandle, "alpha", 1.0f); + ObjectAnimator topOa = ObjectAnimator.ofFloat(mTopHandle, "alpha", 1.0f); + ObjectAnimator bottomOa = ObjectAnimator.ofFloat(mBottomHandle, "alpha", 1.0f); + oa.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + requestLayout(); + } + }); + AnimatorSet set = new AnimatorSet(); + if (mResizeMode == AppWidgetProviderInfo.RESIZE_VERTICAL) { + set.playTogether(oa, topOa, bottomOa); + } else if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) { + set.playTogether(oa, leftOa, rightOa); + } else { + set.playTogether(oa, leftOa, rightOa, topOa, bottomOa); + } + + set.setDuration(SNAP_DURATION); + set.start(); + } + } +} diff --git a/src/com/android/launcher2/ApplicationInfo.java b/src/com/android/launcher2/ApplicationInfo.java index 3adea373e..1d948b738 100644 --- a/src/com/android/launcher2/ApplicationInfo.java +++ b/src/com/android/launcher2/ApplicationInfo.java @@ -59,9 +59,9 @@ class ApplicationInfo extends ItemInfo { ComponentName componentName; - static final int APP_FLAG = 1; - static final int GAME_FLAG = 2; - static final int DOWNLOADED_FLAG = 4; + static final int DOWNLOADED_FLAG = 1; + static final int UPDATED_SYSTEM_APP_FLAG = 2; + int flags = 0; ApplicationInfo() { @@ -83,17 +83,12 @@ class ApplicationInfo extends ItemInfo { int appFlags = pm.getApplicationInfo(packageName, 0).flags; if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) { flags |= DOWNLOADED_FLAG; - } - if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { - flags |= DOWNLOADED_FLAG; - } - firstInstallTime = pm.getPackageInfo(packageName, 0).firstInstallTime; - // TODO: Figure out how to determine what is a game - // If it's not a game, it's an app - if ((flags & GAME_FLAG) == 0) { - flags |= APP_FLAG; + if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) { + flags |= UPDATED_SYSTEM_APP_FLAG; + } } + firstInstallTime = pm.getPackageInfo(packageName, 0).firstInstallTime; } catch (NameNotFoundException e) { Log.d(TAG, "PackageManager.getApplicationInfo failed for " + packageName); } diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java index ad01fac4f..146485489 100644 --- a/src/com/android/launcher2/BubbleTextView.java +++ b/src/com/android/launcher2/BubbleTextView.java @@ -66,6 +66,8 @@ public class BubbleTextView extends TextView implements VisibilityChangedBroadca private boolean mBackgroundSizeChanged; private Drawable mBackground; + private boolean mStayPressed; + private VisibilityChangedListener mOnVisibilityChangedListener; public BubbleTextView(Context context) { @@ -130,21 +132,30 @@ public class BubbleTextView extends TextView implements VisibilityChangedBroadca // In this case, we have already created the pressed outline on ACTION_DOWN, // so we just need to do an invalidate to trigger draw if (!mDidInvalidateForPressedState) { - invalidate(); + setCellLayoutPressedOrFocusedIcon(); } } else { // Otherwise, either clear the pressed/focused background, or create a background // for the focused state final boolean backgroundEmptyBefore = mPressedOrFocusedBackground == null; - mPressedOrFocusedBackground = null; + if (!mStayPressed) { + mPressedOrFocusedBackground = null; + } if (isFocused()) { - mPressedOrFocusedBackground = createGlowingOutline( - mTempCanvas, mFocusedGlowColor, mFocusedOutlineColor); - invalidate(); + if (mLayout == null) { + // In some cases, we get focus before we have been layed out. Set the + // background to null so that it will get created when the view is drawn. + mPressedOrFocusedBackground = null; + } else { + mPressedOrFocusedBackground = createGlowingOutline( + mTempCanvas, mFocusedGlowColor, mFocusedOutlineColor); + } + mStayPressed = false; + setCellLayoutPressedOrFocusedIcon(); } final boolean backgroundEmptyNow = mPressedOrFocusedBackground == null; if (!backgroundEmptyBefore && backgroundEmptyNow) { - invalidate(); + setCellLayoutPressedOrFocusedIcon(); } } @@ -156,9 +167,8 @@ public class BubbleTextView extends TextView implements VisibilityChangedBroadca } /** - * Draw the View v into the given Canvas. + * Draw this BubbleTextView into the given Canvas. * - * @param v the view to draw * @param destCanvas the canvas to draw on * @param padding the horizontal and vertical padding to use when drawing */ @@ -244,22 +254,32 @@ public class BubbleTextView extends TextView implements VisibilityChangedBroadca super.onVisibilityChanged(changedView, visibility); } - @Override - public void draw(Canvas canvas) { - if (mPressedOrFocusedBackground != null && (isPressed() || isFocused())) { - // The blue glow can extend outside of our clip region, so we first temporarily expand - // the canvas's clip region - canvas.save(Canvas.CLIP_SAVE_FLAG); - int padding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS / 2; - canvas.clipRect(-padding + mScrollX, -padding + mScrollY, - getWidth() + padding + mScrollX, getHeight() + padding + mScrollY, - Region.Op.REPLACE); - // draw blue glow - canvas.drawBitmap(mPressedOrFocusedBackground, - mScrollX - padding, mScrollY - padding, mTempPaint); - canvas.restore(); + void setStayPressed(boolean stayPressed) { + mStayPressed = stayPressed; + if (!stayPressed) { + mPressedOrFocusedBackground = null; } + setCellLayoutPressedOrFocusedIcon(); + } + + void setCellLayoutPressedOrFocusedIcon() { + CellLayoutChildren parent = (CellLayoutChildren) getParent(); + if (parent != null) { + CellLayout layout = (CellLayout) parent.getParent(); + layout.setPressedOrFocusedIcon((mPressedOrFocusedBackground != null) ? this : null); + } + } + + Bitmap getPressedOrFocusedBackground() { + return mPressedOrFocusedBackground; + } + + int getPressedOrFocusedBackgroundPadding() { + return HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS / 2; + } + @Override + public void draw(Canvas canvas) { final Drawable background = mBackground; if (background != null) { final int scrollX = mScrollX; diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index 6691e6447..1111c53c7 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -113,6 +113,8 @@ public class CellLayout extends ViewGroup { private int mDragOutlineCurrent = 0; private final Paint mDragOutlinePaint = new Paint(); + private BubbleTextView mPressedOrFocusedIcon; + private Drawable mCrosshairsDrawable = null; private InterruptibleInOutAnimator mCrosshairsAnimator = null; private float mCrosshairsVisibility = 0.0f; @@ -267,6 +269,27 @@ public class CellLayout extends ViewGroup { addView(mChildren); } + private void invalidateBubbleTextView(BubbleTextView icon) { + final int padding = icon.getPressedOrFocusedBackgroundPadding(); + invalidate(icon.getLeft() - padding, + icon.getTop() - padding, + icon.getRight() + padding, + icon.getBottom() + padding); + } + + void setPressedOrFocusedIcon(BubbleTextView icon) { + // We draw the pressed or focused BubbleTextView's background in CellLayout because it + // requires an expanded clip rect (due to the glow's blur radius) + BubbleTextView oldIcon = mPressedOrFocusedIcon; + mPressedOrFocusedIcon = icon; + if (oldIcon != null) { + invalidateBubbleTextView(oldIcon); + } + if (mPressedOrFocusedIcon != null) { + invalidateBubbleTextView(mPressedOrFocusedIcon); + } + } + public CellLayoutChildren getChildrenLayout() { if (getChildCount() > 0) { return (CellLayoutChildren) getChildAt(0); @@ -457,6 +480,19 @@ public class CellLayout extends ViewGroup { canvas.drawBitmap(b, p.x, p.y, paint); } } + + // We draw the pressed or focused BubbleTextView's background in CellLayout because it + // requires an expanded clip rect (due to the glow's blur radius) + if (mPressedOrFocusedIcon != null) { + final int padding = mPressedOrFocusedIcon.getPressedOrFocusedBackgroundPadding(); + final Bitmap b = mPressedOrFocusedIcon.getPressedOrFocusedBackground(); + if (b != null) { + canvas.drawBitmap(b, + mPressedOrFocusedIcon.getLeft() - padding, + mPressedOrFocusedIcon.getTop() - padding, + null); + } + } } @Override @@ -571,6 +607,10 @@ public class CellLayout extends ViewGroup { mChildren.draw(canvas); } + void buildChildrenLayer() { + mChildren.buildLayer(); + } + @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); @@ -587,11 +627,12 @@ public class CellLayout extends ViewGroup { boolean found = false; for (int i = count - 1; i >= 0; i--) { final View child = mChildren.getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if ((child.getVisibility()) == VISIBLE || child.getAnimation() != null) { + if ((child.getVisibility() == VISIBLE || child.getAnimation() != null) && + lp.isLockedToGrid) { child.getHitRect(frame); if (frame.contains(x, y)) { - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); cellInfo.cell = child; cellInfo.cellX = lp.cellX; cellInfo.cellY = lp.cellY; @@ -703,6 +744,14 @@ public class CellLayout extends ViewGroup { return mCellHeight; } + int getWidthGap() { + return mWidthGap; + } + + int getHeightGap() { + return mHeightGap; + } + int getLeftPadding() { return mLeftPadding; } @@ -1332,19 +1381,69 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { } } + /** + * Given a view, determines how much that view can be expanded in all directions, in terms of + * whether or not there are other items occupying adjacent cells. Used by the + * AppWidgetResizeFrame to determine how the widget can be resized. + */ + public void getExpandabilityArrayForView(View view, int[] expandability) { + final LayoutParams lp = (LayoutParams) view.getLayoutParams(); + boolean flag; + + expandability[AppWidgetResizeFrame.LEFT] = 0; + for (int x = lp.cellX - 1; x >= 0; x--) { + flag = false; + for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) { + if (mOccupied[x][y]) flag = true; + } + if (flag) break; + expandability[AppWidgetResizeFrame.LEFT]++; + } + + expandability[AppWidgetResizeFrame.TOP] = 0; + for (int y = lp.cellY - 1; y >= 0; y--) { + flag = false; + for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) { + if (mOccupied[x][y]) flag = true; + } + if (flag) break; + expandability[AppWidgetResizeFrame.TOP]++; + } + + expandability[AppWidgetResizeFrame.RIGHT] = 0; + for (int x = lp.cellX + lp.cellHSpan; x < mCountX; x++) { + flag = false; + for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) { + if (mOccupied[x][y]) flag = true; + } + if (flag) break; + expandability[AppWidgetResizeFrame.RIGHT]++; + } + + expandability[AppWidgetResizeFrame.BOTTOM] = 0; + for (int y = lp.cellY + lp.cellVSpan; y < mCountY; y++) { + flag = false; + for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) { + if (mOccupied[x][y]) flag = true; + } + if (flag) break; + expandability[AppWidgetResizeFrame.BOTTOM]++; + } + } + public void onMove(View view, int newCellX, int newCellY) { LayoutParams lp = (LayoutParams) view.getLayoutParams(); markCellsAsUnoccupiedForView(view); markCellsForView(newCellX, newCellY, lp.cellHSpan, lp.cellVSpan, true); } - private void markCellsAsOccupiedForView(View view) { + public void markCellsAsOccupiedForView(View view) { if (view == null || view.getParent() != mChildren) return; LayoutParams lp = (LayoutParams) view.getLayoutParams(); markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true); } - private void markCellsAsUnoccupiedForView(View view) { + public void markCellsAsUnoccupiedForView(View view) { if (view == null || view.getParent() != mChildren) return; LayoutParams lp = (LayoutParams) view.getLayoutParams(); markCellsForView(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false); @@ -1410,6 +1509,12 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { public int cellVSpan; /** + * Indicates whether the item will set its x, y, width and height parameters freely, + * or whether these will be computed based on cellX, cellY, cellHSpan and cellVSpan. + */ + public boolean isLockedToGrid = true; + + /** * Is this item currently being dragged */ public boolean isDragging; @@ -1467,19 +1572,51 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap, int hStartPadding, int vStartPadding) { + if (isLockedToGrid) { + final int myCellHSpan = cellHSpan; + final int myCellVSpan = cellVSpan; + final int myCellX = cellX; + final int myCellY = cellY; + + width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) - + leftMargin - rightMargin; + height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) - + topMargin - bottomMargin; + x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin; + y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin; + } + } - final int myCellHSpan = cellHSpan; - final int myCellVSpan = cellVSpan; - final int myCellX = cellX; - final int myCellY = cellY; + public void setWidth(int width) { + this.width = width; + } + + public int getWidth() { + return width; + } + + public void setHeight(int height) { + this.height = height; + } + + public int getHeight() { + return height; + } + + public void setX(int x) { + this.x = x; + } - width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) - - leftMargin - rightMargin; - height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) - - topMargin - bottomMargin; + public int getX() { + return x; + } + + public void setY(int y) { + this.y = y; + } - x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin; - y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin; + public int getY() { + return y; } public String toString() { diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java index 0d0a33907..04996f359 100644 --- a/src/com/android/launcher2/CellLayoutChildren.java +++ b/src/com/android/launcher2/CellLayoutChildren.java @@ -16,12 +16,14 @@ package com.android.launcher2; +import java.util.ArrayList; + import android.app.WallpaperManager; import android.content.Context; import android.graphics.Rect; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.View.MeasureSpec; public class CellLayoutChildren extends ViewGroup { static final String TAG = "CellLayoutChildren"; @@ -32,22 +34,25 @@ public class CellLayoutChildren extends ViewGroup { private final WallpaperManager mWallpaperManager; - private int mCellWidth; - private int mCellHeight; - private int mLeftPadding; private int mTopPadding; + private int mCellWidth; + private int mCellHeight; + private int mWidthGap; private int mHeightGap; + // Variables relating to resizing widgets + private final ArrayList<AppWidgetResizeFrame> mResizeFrames = + new ArrayList<AppWidgetResizeFrame>(); + private AppWidgetResizeFrame mCurrentResizeFrame; + private int mXDown, mYDown; + public CellLayoutChildren(Context context) { super(context); mWallpaperManager = WallpaperManager.getInstance(context); setLayerType(LAYER_TYPE_HARDWARE, null); - - // Disable multitouch for the workspace - setMotionEventSplittingEnabled(false); } public void setCellDimensions(int cellWidth, int cellHeight, @@ -171,4 +176,95 @@ public class CellLayoutChildren extends ViewGroup { protected void setChildrenDrawnWithCacheEnabled(boolean enabled) { super.setChildrenDrawnWithCacheEnabled(enabled); } -}
\ No newline at end of file + + public void clearAllResizeFrames() { + for (AppWidgetResizeFrame frame: mResizeFrames) { + removeView(frame); + } + mResizeFrames.clear(); + } + + public boolean hasResizeFrames() { + return mResizeFrames.size() > 0; + } + + public boolean isWidgetBeingResized() { + return mCurrentResizeFrame != null; + } + + private boolean handleTouchDown(MotionEvent ev) { + Rect hitRect = new Rect(); + + int x = (int) ev.getX(); + int y = (int) ev.getY(); + + for (AppWidgetResizeFrame child: mResizeFrames) { + child.getHitRect(hitRect); + if (hitRect.contains(x, y)) { + if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { + mCurrentResizeFrame = child; + mXDown = x; + mYDown = y; + requestDisallowInterceptTouchEvent(true); + return true; + } + } + } + return false; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + if (handleTouchDown(ev)) { + return true; + } + } + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + boolean handled = false; + int action = ev.getAction(); + + int x = (int) ev.getX(); + int y = (int) ev.getY(); + + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + if (handleTouchDown(ev)) { + return true; + } + } + } + + if (mCurrentResizeFrame != null) { + handled = true; + switch (action) { + case MotionEvent.ACTION_MOVE: + mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown); + mCurrentResizeFrame = null; + } + } + return handled; + } + + public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, + CellLayout cellLayout) { + AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), + itemInfo, widget, cellLayout); + + CellLayout.LayoutParams lp = new CellLayout.LayoutParams(-1, -1, -1, -1); + lp.isLockedToGrid = false; + + addView(resizeFrame, lp); + mResizeFrames.add(resizeFrame); + + resizeFrame.snapToWidget(false); + } +} diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java index d08bf5459..5c61b0b4a 100644 --- a/src/com/android/launcher2/CustomizePagedView.java +++ b/src/com/android/launcher2/CustomizePagedView.java @@ -38,8 +38,10 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Bitmap; -import android.graphics.Bitmap.Config; import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.Bitmap.Config; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; @@ -53,7 +55,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; import android.widget.Checkable; import android.widget.ImageView; import android.widget.LinearLayout; @@ -89,6 +91,10 @@ public class CustomizePagedView extends PagedViewWithDraggableItems // The mapping between the pages and the widgets that will be laid out on them private ArrayList<ArrayList<AppWidgetProviderInfo>> mWidgetPages; + // This is used if we want to set a min width on pages so that things inside them left align to + // a fixed size + private int mMinPageWidth; + // The max dimensions for the ImageView we use for displaying a widget private int mMaxWidgetWidth; @@ -120,9 +126,19 @@ public class CustomizePagedView extends PagedViewWithDraggableItems private final float mTmpFloatPos[] = new float[2]; private final float ANIMATION_SCALE = 0.5f; - private final int ANIMATION_DURATION = 400; + + // The duration of the translation animation that occurs during you drag and drop + private final int TRANSLATE_ANIM_DURATION = 400; + + // The duration of the scale & alpha animation that occurs during drag and drop + private final int DROP_ANIM_DURATION = 200; + private TimeInterpolator mQuintEaseOutInterpolator = new DecelerateInterpolator(2.5f); - private ScaleAlphaInterpolator mScaleAlphaInterpolator = new ScaleAlphaInterpolator(); + + // The Bitmap used to generate the drag view + private Bitmap mDragBitmap; + + private int[] mDragViewOrigin = new int[2]; public CustomizePagedView(Context context) { this(context, null, 0); @@ -154,6 +170,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems final Resources r = context.getResources(); setDragSlopeThreshold( r.getInteger(R.integer.config_customizationDrawerDragSlopeThreshold) / 100.0f); + mMinPageWidth = r.getDimensionPixelSize(R.dimen.customization_drawer_content_min_width); setVisibility(View.GONE); setSoundEffectsEnabled(false); @@ -324,38 +341,60 @@ public class CustomizePagedView extends PagedViewWithDraggableItems return mCustomizationType; } - @Override - public void onDropCompleted(View target, boolean success) { - resetCheckedGrandchildren(); + /** + * Similar to resetCheckedGrandchildren, but allows us to specify that it's not animated. + */ + private void resetCheckedItem(boolean animated) { + final Checkable checkable = getSingleCheckedGrandchild(); + if (checkable != null) { + if (checkable instanceof PagedViewWidget) { + ((PagedViewWidget) checkable).setChecked(false, animated); + } else { + ((PagedViewIcon) checkable).setChecked(false, animated); + } + } + } + + public void onDropCompleted(View target, Object dragInfo, boolean success) { + final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); + + // Create a view, identical to the drag view, that is only used for animating the + // item onto the home screen (or back to its original position, if the drop failed). + final int[] pos = mDragController.getDragView().getPosition(null); + final View animView = dragLayer.createDragView(mDragBitmap, pos[0], pos[1]); + animView.setVisibility(View.VISIBLE); + + if (success) { + resetCheckedItem(true); + animateDropOntoScreen(animView, (ItemInfo) dragInfo, DROP_ANIM_DURATION, 0); + } else { + // Animate the icon/widget back to its original position + animateIntoPosition(animView, mDragViewOrigin[0], mDragViewOrigin[1], new Runnable() { + public void run() { + resetCheckedItem(false); + dragLayer.removeView(animView); + } + }); + } mLauncher.getWorkspace().onDragStopped(success); mLauncher.unlockScreenOrientation(); + mDragBitmap = null; } @Override public void onDragViewVisible() { } - class ScaleAlphaInterpolator implements Interpolator { - public float getInterpolation(float input) { - float pivot = 0.5f; - if (input < pivot) { - return 0; - } else { - return (input - pivot)/(1 - pivot); - } - } - } - + /** + * Animates the given item onto the center of a home screen, and then scales the item to + * look as though it's disappearing onto that screen. + */ private void animateItemOntoScreen(View dragView, final CellLayout layout, final ItemInfo info) { mTmpFloatPos[0] = layout.getWidth() / 2; mTmpFloatPos[1] = layout.getHeight() / 2; mLauncher.getWorkspace().mapPointFromChildToSelf(layout, mTmpFloatPos); - final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); - final View dragCopy = dragLayer.createDragView(dragView); - dragCopy.setAlpha(1.0f); - int dragViewWidth = dragView.getMeasuredWidth(); int dragViewHeight = dragView.getMeasuredHeight(); float heightOffset = 0; @@ -374,37 +413,70 @@ public class CustomizePagedView extends PagedViewWithDraggableItems widthOffset = ANIMATION_SCALE * (dragViewWidth - f * width) / 2; } } + final float toX = mTmpFloatPos[0] - dragView.getMeasuredWidth() / 2 + widthOffset; + final float toY = mTmpFloatPos[1] - dragView.getMeasuredHeight() / 2 + heightOffset; - float toX = mTmpFloatPos[0] - dragView.getMeasuredWidth() / 2 + widthOffset; - float toY = mTmpFloatPos[1] - dragView.getMeasuredHeight() / 2 + heightOffset; + final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); + final View dragCopy = dragLayer.createDragView(dragView); + dragCopy.setAlpha(1.0f); - ObjectAnimator posAnim = ObjectAnimator.ofPropertyValuesHolder(dragCopy, - PropertyValuesHolder.ofFloat("x", toX), - PropertyValuesHolder.ofFloat("y", toY)); - posAnim.setInterpolator(mQuintEaseOutInterpolator); - posAnim.setDuration(ANIMATION_DURATION); + // Translate the item to the center of the appropriate home screen + animateIntoPosition(dragCopy, toX, toY, null); - posAnim.addListener(new AnimatorListenerAdapter() { - public void onAnimationEnd(Animator animation) { - dragLayer.removeView(dragCopy); - mLauncher.addExternalItemToScreen(info, layout); - post(new Runnable() { - public void run() { - layout.animateDrop(); - } - }); - } - }); + // The drop-onto-screen animation begins a bit later, but ends at the same time. + final int startDelay = TRANSLATE_ANIM_DURATION - DROP_ANIM_DURATION; + + // Scale down the icon and fade out the alpha + animateDropOntoScreen(dragCopy, info, DROP_ANIM_DURATION, startDelay); + } - ObjectAnimator scaleAlphaAnim = ObjectAnimator.ofPropertyValuesHolder(dragCopy, + /** + * Animation which scales the view down and animates its alpha, making it appear to disappear + * onto a home screen. + */ + private void animateDropOntoScreen( + final View view, final ItemInfo info, int duration, int delay) { + final DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer); + final CellLayout layout = mLauncher.getWorkspace().getCurrentDropLayout(); + + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f), PropertyValuesHolder.ofFloat("scaleX", ANIMATION_SCALE), PropertyValuesHolder.ofFloat("scaleY", ANIMATION_SCALE)); - scaleAlphaAnim.setInterpolator(mScaleAlphaInterpolator); - scaleAlphaAnim.setDuration(ANIMATION_DURATION); + anim.setInterpolator(new LinearInterpolator()); + if (delay > 0) { + anim.setStartDelay(delay); + } + anim.setDuration(duration); + anim.addListener(new AnimatorListenerAdapter() { + public void onAnimationEnd(Animator animation) { + dragLayer.removeView(view); + mLauncher.addExternalItemToScreen(info, layout); + info.dropPos = null; + } + }); + anim.start(); + } - posAnim.start(); - scaleAlphaAnim.start(); + /** + * Animates the x,y position of the view, and optionally execute a Runnable on animation end. + */ + private void animateIntoPosition( + View view, float toX, float toY, final Runnable endRunnable) { + ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(view, + PropertyValuesHolder.ofFloat("x", toX), + PropertyValuesHolder.ofFloat("y", toY)); + anim.setInterpolator(mQuintEaseOutInterpolator); + anim.setDuration(TRANSLATE_ANIM_DURATION); + if (endRunnable != null) { + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + endRunnable.run(); + } + }); + } + anim.start(); } @Override @@ -479,12 +551,12 @@ public class CustomizePagedView extends PagedViewWithDraggableItems } } - Bitmap drawableToBitmap(Drawable d, View v, boolean clipHeight) { - int height = clipHeight ? v.getPaddingTop() + d.getIntrinsicHeight() : v.getHeight(); - Bitmap b = Bitmap.createBitmap(v.getWidth(), height, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(b); - c.translate((v.getWidth() - d.getIntrinsicWidth()) / 2, v.getPaddingTop()); - d.draw(c); + private Bitmap drawableToBitmap(Drawable d, float scaleX, float scaleY) { + final Rect bounds = d.getBounds(); + final int w = bounds.width(); + final int h = bounds.height(); + Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + renderDrawableToBitmap(d, b, 0, 0, w, h, scaleX, scaleY); return b; } @@ -501,6 +573,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems if (isChoiceMode(CHOICE_MODE_SINGLE)) { endChoiceMode(); } + final Workspace workspace = mLauncher.getWorkspace(); boolean result = false; mLauncher.lockScreenOrientation(); switch (mCustomizationType) { @@ -509,50 +582,50 @@ public class CustomizePagedView extends PagedViewWithDraggableItems // Get the widget preview as the drag representation final LinearLayout l = (LinearLayout) v; final ImageView i = (ImageView) l.findViewById(R.id.widget_preview); - Bitmap b = drawableToBitmap(i.getDrawable(), i, true); + + // Calculate how much to scale the drag preview + RectF tmpScaleRect = new RectF(0,0,1,1); + i.getImageMatrix().mapRect(tmpScaleRect); + + mDragBitmap = drawableToBitmap(i.getDrawable(), tmpScaleRect.right, + tmpScaleRect.bottom); + i.getLocationOnScreen(mDragViewOrigin); PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) v.getTag(); - int[] spanXY = CellLayout.rectToCell( - getResources(), createWidgetInfo.minWidth, createWidgetInfo.minHeight, null); + int[] spanXY = CellLayout.rectToCell(getResources(), + createWidgetInfo.minWidth, createWidgetInfo.minHeight, null); createWidgetInfo.spanX = spanXY[0]; createWidgetInfo.spanY = spanXY[1]; - mLauncher.getWorkspace().onDragStartedWithItemSpans(spanXY[0], spanXY[1], b); - mDragController.startDrag( - i, b, this, createWidgetInfo, DragController.DRAG_ACTION_COPY, null); - b.recycle(); - result = true; - } - break; - } - case ShortcutCustomization: { - if (v instanceof PagedViewIcon) { - // get icon (top compound drawable, index is 1) - final TextView tv = (TextView) v; - final Drawable icon = tv.getCompoundDrawables()[1]; - Bitmap b = drawableToBitmap(icon, tv, false); - PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag(); - - mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b); - mDragController.startDrag(v, b, this, createItemInfo, DragController.DRAG_ACTION_COPY, - null); - b.recycle(); + workspace.onDragStartedWithItemSpans(spanXY[0], spanXY[1], mDragBitmap); + mDragController.startDrag(i, mDragBitmap, this, createWidgetInfo, + DragController.DRAG_ACTION_COPY, null); result = true; } break; } + case ShortcutCustomization: case ApplicationCustomization: { if (v instanceof PagedViewIcon) { - // Pick up the application for dropping // get icon (top compound drawable, index is 1) final TextView tv = (TextView) v; final Drawable icon = tv.getCompoundDrawables()[1]; - Bitmap b = drawableToBitmap(icon, tv, false); - ApplicationInfo app = (ApplicationInfo) v.getTag(); - app = new ApplicationInfo(app); + mDragBitmap = drawableToBitmap(icon, 1.0f, 1.0f); + + Object dragInfo = v.getTag(); + if (mCustomizationType == CustomizationType.ApplicationCustomization) { + // TODO: Not sure why we have to copy this + dragInfo = new ApplicationInfo((ApplicationInfo) dragInfo); + } + workspace.onDragStartedWithItemSpans(1, 1, mDragBitmap); - mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b); - mDragController.startDrag(v, b, this, app, DragController.DRAG_ACTION_COPY, null); - b.recycle(); + // Calculate where to place the drag view in order to align the icon pixels with + // the original view. + v.getLocationOnScreen(mDragViewOrigin); + mDragViewOrigin[0] += (v.getWidth() - icon.getIntrinsicWidth()) / 2; + mDragViewOrigin[1] += v.getPaddingTop(); + + mDragController.startDrag(mDragBitmap, mDragViewOrigin[0], mDragViewOrigin[1], + this, dragInfo, DragController.DRAG_ACTION_COPY); result = true; } break; @@ -619,11 +692,15 @@ public class CustomizePagedView extends PagedViewWithDraggableItems /** * Helper function to draw a drawable to the specified canvas with the specified bounds. */ - private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h) { + private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h, + float scaleX, float scaleY) { if (bitmap != null) mCanvas.setBitmap(bitmap); mCanvas.save(); - d.setBounds(x, y, x+w, y+h); + mCanvas.scale(scaleX, scaleY); + final Rect oldBounds = d.copyBounds(); + d.setBounds(x, y, x + w, y + h); d.draw(mCanvas); + d.setBounds(oldBounds); // Restore the bounds mCanvas.restore(); } @@ -706,7 +783,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems background = resources.getDrawable(R.drawable.default_widget_preview); } - renderDrawableToBitmap(background, bitmap, 0, 0, width, height); + renderDrawableToBitmap(background, bitmap, 0, 0, width, height, 1.0f, 1.0f); // If we don't have a custom icon, we use the app icon on the default background if (!foundCustomDrawable) { @@ -718,7 +795,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems final int iconSize = minDim / 2; final int offset = iconSize / 4; - renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize); + renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize, 1.0f, 1.0f); } catch (Resources.NotFoundException e) { // if we can't find the icon, then just don't draw it } @@ -758,7 +835,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems int height = (int) (Math.max(minDim, Math.min(maxDim, info.minHeight)) * sScaleFactor); final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); final Drawable background = resources.getDrawable(R.drawable.default_widget_preview); - renderDrawableToBitmap(background, bitmap, 0, 0, width, height); + renderDrawableToBitmap(background, bitmap, 0, 0, width, height, 1.0f, 1.0f); // Draw the icon flush left try { @@ -772,7 +849,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems final int iconSize = minDim / 2; final int offset = iconSize / 4; - renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize); + renderDrawableToBitmap(icon, null, offset, offset, iconSize, iconSize, 1.0f, 1.0f); } catch (Resources.NotFoundException e) { // if we can't find the icon, then just don't draw it } @@ -798,7 +875,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems } final Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); - renderDrawableToBitmap(drawable, bitmap, 0, 0, width, height); + renderDrawableToBitmap(drawable, bitmap, 0, 0, width, height, 1.0f, 1.0f); newDrawable = new FastBitmapDrawable(bitmap); } @@ -855,6 +932,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems PagedViewWidget l = (PagedViewWidget) mInflater.inflate( R.layout.customize_paged_view_widget, layout, false); + l.applyFromAppWidgetProviderInfo(info, icon, mMaxWidgetWidth, cellSpans, mPageViewIconCache, (numPages > 1)); l.setTag(createItemInfo); @@ -1010,10 +1088,12 @@ public class CustomizePagedView extends PagedViewWithDraggableItems @Override public void syncPages() { + boolean enforceMinimumPagedWidths = false; boolean centerPagedViewCellLayouts = false; switch (mCustomizationType) { case WidgetCustomization: syncWidgetPages(); + enforceMinimumPagedWidths = true; break; case ShortcutCustomization: syncListPages(mShortcutList); @@ -1021,6 +1101,7 @@ public class CustomizePagedView extends PagedViewWithDraggableItems break; case WallpaperCustomization: syncWallpaperPages(); + enforceMinimumPagedWidths = true; break; case ApplicationCustomization: syncAppPages(); @@ -1046,8 +1127,20 @@ public class CustomizePagedView extends PagedViewWithDraggableItems } } - // bound the current page - setCurrentPage(Math.max(0, Math.min(childCount - 1, getCurrentPage()))); + // Set a min page width for PagedView layout if we have more than a single page + if (enforceMinimumPagedWidths) { + setMinimumWidthOverride((childCount > 1) ? mMinPageWidth : 0); + } + + // Bound the current page index + requestLayout(); + post(new Runnable() { + @Override + public void run() { + setCurrentPage(Math.max(0, Math.min(childCount - 1, getCurrentPage()))); + forceUpdateAdjacentPagesAlpha(); + } + }); } @Override diff --git a/src/com/android/launcher2/CustomizeTrayTabHost.java b/src/com/android/launcher2/CustomizeTrayTabHost.java new file mode 100644 index 000000000..76cfc84e8 --- /dev/null +++ b/src/com/android/launcher2/CustomizeTrayTabHost.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher2; + +import android.animation.Animator; +import android.content.Context; +import android.util.AttributeSet; +import android.widget.TabHost; + +public class CustomizeTrayTabHost extends TabHost implements LauncherTransitionable { + private boolean mFirstLayout = true; + + public CustomizeTrayTabHost(Context context) { + super(context); + } + + public CustomizeTrayTabHost(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void onLauncherTransitionStart(Animator animation) { + if (animation != null) { + setLayerType(LAYER_TYPE_HARDWARE, null); + // just a sanity check that we don't build a layer before a call to onLayout + if (!mFirstLayout) { + // force building the layer at the beginning of the animation, so you don't get a + // blip early in the animation + buildLayer(); + } + } + } + + @Override + public void onLauncherTransitionEnd(Animator animation) { + if (animation != null) { + setLayerType(LAYER_TYPE_NONE, null); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + mFirstLayout = false; + super.onLayout(changed, l, t, r, b); + } +} diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java index 45b359dc5..cb4509b21 100644 --- a/src/com/android/launcher2/DragController.java +++ b/src/com/android/launcher2/DragController.java @@ -205,9 +205,7 @@ public class DragController { int screenX = loc[0]; int screenY = loc[1]; - startDrag(b, screenX, screenY, 0, 0, b.getWidth(), b.getHeight(), - source, dragInfo, dragAction, dragRegion); - + startDrag(b, screenX, screenY, source, dragInfo, dragAction, dragRegion); b.recycle(); if (dragAction == DRAG_ACTION_MOVE) { @@ -236,8 +234,7 @@ public class DragController { int screenX = loc[0]; int screenY = loc[1]; - startDrag(bmp, screenX, screenY, 0, 0, bmp.getWidth(), bmp.getHeight(), - source, dragInfo, dragAction, dragRegion); + startDrag(bmp, screenX, screenY, source, dragInfo, dragAction, dragRegion); if (dragAction == DRAG_ACTION_MOVE) { v.setVisibility(View.GONE); @@ -251,20 +248,14 @@ public class DragController { * enlarged size. * @param screenX The x position on screen of the left-top of the bitmap. * @param screenY The y position on screen of the left-top of the bitmap. - * @param textureLeft The left edge of the region inside b to use. - * @param textureTop The top edge of the region inside b to use. - * @param textureWidth The width of the region inside b to use. - * @param textureHeight The height of the region inside b to use. * @param source An object representing where the drag originated * @param dragInfo The data associated with the object that is being dragged * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or * {@link #DRAG_ACTION_COPY} */ public void startDrag(Bitmap b, int screenX, int screenY, - int textureLeft, int textureTop, int textureWidth, int textureHeight, DragSource source, Object dragInfo, int dragAction) { - startDrag(b, screenX, screenY, textureLeft, textureTop, textureWidth, textureHeight, - source, dragInfo, dragAction, null); + startDrag(b, screenX, screenY, source, dragInfo, dragAction, null); } /** @@ -274,10 +265,6 @@ public class DragController { * enlarged size. * @param screenX The x position on screen of the left-top of the bitmap. * @param screenY The y position on screen of the left-top of the bitmap. - * @param textureLeft The left edge of the region inside b to use. - * @param textureTop The top edge of the region inside b to use. - * @param textureWidth The width of the region inside b to use. - * @param textureHeight The height of the region inside b to use. * @param source An object representing where the drag originated * @param dragInfo The data associated with the object that is being dragged * @param dragAction The drag action: either {@link #DRAG_ACTION_MOVE} or @@ -286,7 +273,6 @@ public class DragController { * Makes dragging feel more precise, e.g. you can clip out a transparent border */ public void startDrag(Bitmap b, int screenX, int screenY, - int textureLeft, int textureTop, int textureWidth, int textureHeight, DragSource source, Object dragInfo, int dragAction, Rect dragRegion) { if (PROFILE_DRAWING_DURING_DRAG) { android.os.Debug.startMethodTracing("Launcher"); @@ -318,7 +304,7 @@ public class DragController { mVibrator.vibrate(VIBRATE_DURATION); DragView dragView = mDragView = new DragView(mContext, b, registrationX, registrationY, - textureLeft, textureTop, textureWidth, textureHeight); + 0, 0, b.getWidth(), b.getHeight()); final DragSource dragSource = source; dragView.setOnDrawRunnable(new Runnable() { @@ -400,7 +386,7 @@ public class DragController { public void cancelDrag() { if (mDragging) { // Should we also be calling onDragExit() here? - mDragSource.onDropCompleted(null, false); + mDragSource.onDropCompleted(null, mDragInfo, false); } endDrag(); } @@ -571,6 +557,9 @@ public class DragController { handleMoveEvent(screenX, screenY); break; case MotionEvent.ACTION_UP: + // Ensure that we've processed a move event at the current pointer location. + handleMoveEvent(screenX, screenY); + mHandler.removeCallbacks(mScrollRunnable); if (mDragging) { drop(screenX, screenY); @@ -585,10 +574,11 @@ public class DragController { return true; } - private boolean drop(float x, float y) { + private void drop(float x, float y) { final int[] coordinates = mCoordinatesTemp; - DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); + final DropTarget dropTarget = findDropTarget((int) x, (int) y, coordinates); + boolean accepted = false; if (dropTarget != null) { dropTarget.onDragExit(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo); @@ -596,16 +586,10 @@ public class DragController { (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo)) { dropTarget.onDrop(mDragSource, coordinates[0], coordinates[1], (int) mTouchOffsetX, (int) mTouchOffsetY, mDragView, mDragInfo); - mDragSource.onDropCompleted((View) dropTarget, true); - return true; - } else { - mDragSource.onDropCompleted((View) dropTarget, false); - return true; + accepted = true; } - } else { - mDragSource.onDropCompleted(null, false); } - return false; + mDragSource.onDropCompleted((View) dropTarget, mDragInfo, accepted); } private DropTarget findDropTarget(int x, int y, int[] dropCoordinates) { @@ -716,6 +700,10 @@ public class DragController { mDeleteRegion = region; } + DragView getDragView() { + return mDragView; + } + private class ScrollRunnable implements Runnable { private int mDirection; diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java index a9dd7e335..eb539450f 100644 --- a/src/com/android/launcher2/DragLayer.java +++ b/src/com/android/launcher2/DragLayer.java @@ -16,6 +16,8 @@ package com.android.launcher2; +import com.android.launcher.R; + import android.content.Context; import android.graphics.Bitmap; import android.util.AttributeSet; @@ -56,6 +58,24 @@ public class DragLayer extends FrameLayout { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { + // If the current CellLayoutChildren has a resize frame, we need to detect if any touch + // event has occurred which doesn't result in resizing a widget. In this case, we + // dismiss any visible resize frames. + final Workspace w = (Workspace) findViewById(R.id.workspace); + if (w != null) { + final CellLayout currentPage = (CellLayout) w.getChildAt(w.getCurrentPage()); + final CellLayoutChildren childrenLayout = currentPage.getChildrenLayout(); + + if (childrenLayout.hasResizeFrames() && !childrenLayout.isWidgetBeingResized()) { + post(new Runnable() { + public void run() { + if (!childrenLayout.isWidgetBeingResized()) { + childrenLayout.clearAllResizeFrames(); + } + } + }); + } + } return mDragController.onInterceptTouchEvent(ev); } diff --git a/src/com/android/launcher2/DragScroller.java b/src/com/android/launcher2/DragScroller.java index 6af9c3032..6ef4bd873 100644 --- a/src/com/android/launcher2/DragScroller.java +++ b/src/com/android/launcher2/DragScroller.java @@ -26,6 +26,7 @@ public interface DragScroller { /** * The touch point has entered the scroll area; a scroll is imminent. + * This event will only occur while a drag is active. * * @param direction The scroll direction */ @@ -33,6 +34,7 @@ public interface DragScroller { /** * The touch point has left the scroll area. + * NOTE: This may not be called, if a drop occurs inside the scroll area. */ void onExitScrollArea(); } diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java index 11cdcc93e..4dbdaf71a 100644 --- a/src/com/android/launcher2/DragSource.java +++ b/src/com/android/launcher2/DragSource.java @@ -31,5 +31,5 @@ public interface DragSource { */ void onDragViewVisible(); - void onDropCompleted(View target, boolean success); + void onDropCompleted(View target, Object dragInfo, boolean success); } diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java index c0776a9f2..45620b90b 100644 --- a/src/com/android/launcher2/DragView.java +++ b/src/com/android/launcher2/DragView.java @@ -245,5 +245,13 @@ public class DragView extends View { void remove() { mWindowManager.removeView(this); } + + int[] getPosition(int[] result) { + WindowManager.LayoutParams lp = mLayoutParams; + if (result == null) result = new int[2]; + result[0] = lp.x; + result[1] = lp.y; + return result; + } } diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java index cb450b99b..059e73d8b 100644 --- a/src/com/android/launcher2/Folder.java +++ b/src/com/android/launcher2/Folder.java @@ -114,7 +114,7 @@ public class Folder extends LinearLayout implements DragSource, OnItemLongClickL } @Override - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { } @Override diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java index 1efc1231f..80548fb5c 100644 --- a/src/com/android/launcher2/HolographicOutlineHelper.java +++ b/src/com/android/launcher2/HolographicOutlineHelper.java @@ -32,6 +32,7 @@ public class HolographicOutlineHelper { private final Paint mAlphaClipPaint = new Paint(); public static final int MAX_OUTER_BLUR_RADIUS; + public static final int MIN_OUTER_BLUR_RADIUS; private static final BlurMaskFilter sExtraThickOuterBlurMaskFilter; private static final BlurMaskFilter sThickOuterBlurMaskFilter; @@ -48,6 +49,7 @@ public class HolographicOutlineHelper { static { final float scale = LauncherApplication.getScreenDensity(); + MIN_OUTER_BLUR_RADIUS = (int) (scale * 1.0f); MAX_OUTER_BLUR_RADIUS = (int) (scale * 12.0f); sExtraThickOuterBlurMaskFilter = new BlurMaskFilter(scale * 12.0f, BlurMaskFilter.Blur.OUTER); diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java index 2e47adc9e..0c26bf05c 100644 --- a/src/com/android/launcher2/IconCache.java +++ b/src/com/android/launcher2/IconCache.java @@ -68,11 +68,13 @@ public class IconCache { com.android.internal.R.mipmap.sym_def_app_icon); } - public Drawable getFullResIcon(Resources resources, int iconId) { + public Drawable getFullResIcon(Resources resources, int iconId) + throws Resources.NotFoundException { return resources.getDrawableForDensity(iconId, mIconDpi); } - public Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) { + public Drawable getFullResIcon(ResolveInfo info, PackageManager packageManager) + throws Resources.NotFoundException { Resources resources; try { resources = packageManager.getResourcesForApplication( @@ -174,8 +176,14 @@ public class IconCache { if (entry.title == null) { entry.title = info.activityInfo.name; } - entry.icon = Utilities.createIconBitmap( - getFullResIcon(info, mPackageManager), mContext); + + Drawable icon; + try { + icon = getFullResIcon(info, mPackageManager); + } catch (Resources.NotFoundException e) { + icon = getFullResDefaultActivityIcon(); + } + entry.icon = Utilities.createIconBitmap(icon, mContext); } return entry; } diff --git a/src/com/android/launcher2/ItemInfo.java b/src/com/android/launcher2/ItemInfo.java index dc4575062..b3612140d 100644 --- a/src/com/android/launcher2/ItemInfo.java +++ b/src/com/android/launcher2/ItemInfo.java @@ -81,6 +81,11 @@ class ItemInfo { */ boolean isGesture = false; + /** + * The position of the item in a drag-and-drop operation. + */ + int[] dropPos = null; + ItemInfo() { } diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index df6ff366a..d7a360df6 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -26,7 +26,6 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.Activity; @@ -88,6 +87,7 @@ import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.accessibility.AccessibilityEvent; import android.view.animation.DecelerateInterpolator; @@ -181,7 +181,7 @@ public final class Launcher extends Activity private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon"; /** The different states that Launcher can be in. */ - private enum State { WORKSPACE, ALL_APPS, CUSTOMIZE, OVERVIEW, + private enum State { WORKSPACE, ALL_APPS, CUSTOMIZE, CUSTOMIZE_SPRING_LOADED, ALL_APPS_SPRING_LOADED }; private State mState = State.WORKSPACE; private AnimatorSet mStateAnimation; @@ -217,6 +217,11 @@ public final class Launcher extends Activity private TabHost mHomeCustomizationDrawer; private boolean mAutoAdvanceRunning = false; + private View mButtonCluster; + private View mAllAppsButton; + private View mDivider; + private View mConfigureButton; + private AllAppsPagedView mAllAppsPagedView = null; private CustomizePagedView mCustomizePagedView = null; @@ -245,6 +250,7 @@ public final class Launcher extends Activity private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>(); + // The "signpost" images along the bottom of the screen (only in some layouts) private ImageView mPreviousView; private ImageView mNextView; @@ -274,6 +280,19 @@ public final class Launcher extends Activity private static Drawable.ConstantState sVoiceSearchIcon; private static Drawable.ConstantState sAppMarketIcon; + private BubbleTextView mWaitingForResume; + + private static ArrayList<PendingAddArguments> sPendingAddList + = new ArrayList<PendingAddArguments>(); + + private static class PendingAddArguments { + int requestCode; + Intent intent; + int screen; + int cellX; + int cellY; + } + private CustomizationType getCustomizeFilterForTabTag(String tag) { if (tag.equals(WIDGETS_TAG)) { return CustomizationType.WidgetCustomization; @@ -321,7 +340,7 @@ public final class Launcher extends Activity // share the same customization workspace across all the tabs mCustomizePagedView = (CustomizePagedView) mInflater.inflate( - R.layout.customization_drawer, mHomeCustomizationDrawer, false); + R.layout.customization_drawer_tab_contents, mHomeCustomizationDrawer, false); TabContentFactory contentFactory = new TabContentFactory() { public View createTabContent(String tag) { return mCustomizePagedView; @@ -409,8 +428,11 @@ public final class Launcher extends Activity // If we have a saved version of these external icons, we load them up immediately if (LauncherApplication.isScreenXLarge()) { + if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) { + updateIconsAffectedByPackageManagerChanges(); + } if (sGlobalSearchIcon != null) { - updateGlobalSearchIcon(sGlobalSearchIcon); + updateGlobalSearchIcon(sGlobalSearchIcon); } if (sVoiceSearchIcon != null) { updateVoiceSearchIcon(sVoiceSearchIcon); @@ -695,8 +717,38 @@ public final class Launcher extends Activity } } + private void completeAdd(PendingAddArguments args) { + switch (args.requestCode) { + case REQUEST_PICK_APPLICATION: + completeAddApplication(args.intent, args.screen, args.cellX, args.cellY); + break; + case REQUEST_PICK_SHORTCUT: + processShortcut(args.intent); + break; + case REQUEST_CREATE_SHORTCUT: + completeAddShortcut(args.intent, args.screen, args.cellX, args.cellY); + break; + case REQUEST_PICK_LIVE_FOLDER: + addLiveFolder(args.intent); + break; + case REQUEST_CREATE_LIVE_FOLDER: + completeAddLiveFolder(args.intent, args.screen, args.cellX, args.cellY); + break; + case REQUEST_PICK_APPWIDGET: + addAppWidgetFromPick(args.intent); + break; + case REQUEST_CREATE_APPWIDGET: + int appWidgetId = args.intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); + completeAddAppWidget(appWidgetId, args.screen); + break; + case REQUEST_PICK_WALLPAPER: + // We just wanted the activity result here so we can clear mWaitingForResult + break; + } + } + @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + protected void onActivityResult(final int requestCode, int resultCode, final Intent data) { mWaitingForResult = false; // The pattern used here is that a user PICKs a specific application, @@ -706,33 +758,18 @@ public final class Launcher extends Activity // launch over to the Music app to actually CREATE_SHORTCUT. if (resultCode == RESULT_OK && mAddScreen != -1) { - switch (requestCode) { - case REQUEST_PICK_APPLICATION: - completeAddApplication( - this, data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY); - break; - case REQUEST_PICK_SHORTCUT: - processShortcut(data); - break; - case REQUEST_CREATE_SHORTCUT: - completeAddShortcut(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY); - break; - case REQUEST_PICK_LIVE_FOLDER: - addLiveFolder(data); - break; - case REQUEST_CREATE_LIVE_FOLDER: - completeAddLiveFolder(data, mAddScreen, mAddIntersectCellX, mAddIntersectCellY); - break; - case REQUEST_PICK_APPWIDGET: - addAppWidgetFromPick(data); - break; - case REQUEST_CREATE_APPWIDGET: - int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); - completeAddAppWidget(appWidgetId, mAddScreen); - break; - case REQUEST_PICK_WALLPAPER: - // We just wanted the activity result here so we can clear mWaitingForResult - break; + final PendingAddArguments args = new PendingAddArguments(); + args.requestCode = requestCode; + args.intent = data; + args.screen = mAddScreen; + args.cellX = mAddIntersectCellX; + args.cellY = mAddIntersectCellY; + + // If the loader is still running, defer the add until it is done. + if (isWorkspaceLocked()) { + sPendingAddList.add(args); + } else { + completeAdd(args); } } else if ((requestCode == REQUEST_PICK_APPWIDGET || requestCode == REQUEST_CREATE_APPWIDGET) && resultCode == RESULT_CANCELED && @@ -755,6 +792,9 @@ public final class Launcher extends Activity mRestoring = false; mOnResumeNeedsLoad = false; } + if (mWaitingForResume != null) { + mWaitingForResume.setStayPressed(false); + } // When we resume Launcher, a different Activity might be responsible for the app // market intent, so refresh the icon updateAppMarketIcon(); @@ -1027,6 +1067,11 @@ public final class Launcher extends Activity View marketButton = findViewById(R.id.market_button); if (marketButton != null) { allAppsInfoTarget.setOverlappingView(marketButton); + marketButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onClickAppMarketButton(v); + } + }); } } @@ -1043,6 +1088,36 @@ public final class Launcher extends Activity if (allAppsDeleteZone != null) { dragController.addDropTarget(allAppsDeleteZone); } + mButtonCluster = findViewById(R.id.all_apps_button_cluster); + + mAllAppsButton = findViewById(R.id.all_apps_button); + mDivider = findViewById(R.id.divider); + mConfigureButton = findViewById(R.id.configure_button); + + // We had previously set these click handlers in XML, but the first time we launched + // Configure or All Apps we had an extra 50ms of delay while the java reflection methods + // found the right handler. Setting the handlers directly here eliminates that cost. + if (mConfigureButton != null) { + mConfigureButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onClickConfigureButton(v); + } + }); + } + if (mDivider != null) { + mDivider.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onClickAllAppsButton(v); + } + }); + } + if (mAllAppsButton != null) { + mAllAppsButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onClickAllAppsButton(v); + } + }); + } } @SuppressWarnings({"UnusedDeclaration"}) @@ -1114,7 +1189,7 @@ public final class Launcher extends Activity * @param data The intent describing the application. * @param cellInfo The position on screen where to create the shortcut. */ - void completeAddApplication(Context context, Intent data, int screen, + void completeAddApplication(Intent data, int screen, int intersectCellX, int intersectCellY) { final int[] cellXY = mTmpAddItemCellCoordinates; final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen); @@ -1124,8 +1199,7 @@ public final class Launcher extends Activity return; } - final ShortcutInfo info = mModel.getShortcutInfo(context.getPackageManager(), - data, context); + final ShortcutInfo info = mModel.getShortcutInfo(getPackageManager(), data, this); if (info != null) { info.setActivity(data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK | @@ -1182,7 +1256,7 @@ public final class Launcher extends Activity * @param appWidgetId The app widget id * @param cellInfo The position on screen where to create the widget. */ - private void completeAddAppWidget(int appWidgetId, int screen) { + private void completeAddAppWidget(final int appWidgetId, int screen) { AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); // Calculate the grid spans needed to fit this widget @@ -1212,7 +1286,16 @@ public final class Launcher extends Activity } if (!foundCellSpan) { - if (appWidgetId != -1) mAppWidgetHost.deleteAppWidgetId(appWidgetId); + if (appWidgetId != -1) { + // Deleting an app widget ID is a void call but writes to disk before returning + // to the caller... + final LauncherAppWidgetHost appWidgetHost = mAppWidgetHost; + new Thread("deleteAppWidgetId") { + public void run() { + mAppWidgetHost.deleteAppWidgetId(appWidgetId); + } + }.start(); + } showOutOfSpaceMessage(); return; } @@ -1402,16 +1485,15 @@ public final class Launcher extends Activity boolean alreadyOnHome = ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); - // in all these cases, only animate if we're already on home + // In all these cases, only animate if we're already on home + if (LauncherApplication.isScreenXLarge()) { mWorkspace.unshrink(alreadyOnHome); } - if (!mWorkspace.isDefaultPageShowing()) { - // on the phone, we don't animate the change to the workspace if all apps is visible - boolean animate = alreadyOnHome && - (LauncherApplication.isScreenXLarge() || mState != State.ALL_APPS); - mWorkspace.moveToDefaultScreen(animate); - if (!animate) mWorkspace.updateWallpaperOffsetImmediately(); + + mWorkspace.exitWidgetResizeMode(); + if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive()) { + mWorkspace.moveToDefaultScreen(true); } showWorkspace(alreadyOnHome); @@ -1643,6 +1725,12 @@ public final class Launcher extends Activity return mWorkspaceLoading || mWaitingForResult; } + // Is the workspace preview (brought up by long-pressing on a signpost icon) visible? + private boolean isPreviewVisible() { + return (mPreviousView != null && mPreviousView.getTag() != null) || + (mNextView != null && mNextView.getTag() != null); + } + private void addItems() { if (LauncherApplication.isScreenXLarge()) { // Animate the widget chooser up from the bottom of the screen @@ -1936,13 +2024,16 @@ public final class Launcher extends Activity public void onBackPressed() { if (mState == State.ALL_APPS || mState == State.CUSTOMIZE) { showWorkspace(true); - } else { + } else if (mWorkspace.getOpenFolder() != null) { closeFolder(); - } - // Some launcher layouts don't have a previous and next view - if (mPreviousView != null) { + } else if (isPreviewVisible()) { dismissPreview(mPreviousView); dismissPreview(mNextView); + } else { + mWorkspace.exitWidgetResizeMode(); + + // Back button is a no-op here, but give at least some feedback for the button press + mWorkspace.showOutlinesTemporarily(); } } @@ -1971,7 +2062,9 @@ public final class Launcher extends Activity * Re-listen when widgets are reset. */ private void onAppWidgetReset() { - mAppWidgetHost.startListening(); + if (mAppWidgetHost != null) { + mAppWidgetHost.startListening(); + } } /** @@ -1999,7 +2092,12 @@ public final class Launcher extends Activity v.getLocationOnScreen(pos); intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); - startActivitySafely(intent, tag); + boolean success = startActivitySafely(intent, tag); + + if (success && v instanceof BubbleTextView) { + mWaitingForResume = (BubbleTextView) v; + mWaitingForResume.setStayPressed(true); + } } else if (tag instanceof FolderInfo) { handleFolderClick((FolderInfo) tag); } else if (v == mHandleView) { @@ -2092,10 +2190,11 @@ public final class Launcher extends Activity } } - void startActivitySafely(Intent intent, Object tag) { + boolean startActivitySafely(Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { startActivity(intent); + return true; } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e); @@ -2106,6 +2205,7 @@ public final class Launcher extends Activity "or use the exported attribute for this activity. " + "tag="+ tag + " intent=" + intent, e); } + return false; } void startActivityForResultSafely(Intent intent, int requestCode) { @@ -2175,6 +2275,10 @@ public final class Launcher extends Activity } public boolean onLongClick(View v) { + if (mState != State.WORKSPACE) { + return false; + } + switch (v.getId()) { case R.id.previous_screen: if (mState != State.ALL_APPS) { @@ -2207,7 +2311,6 @@ public final class Launcher extends Activity v = (View) v.getParent().getParent(); } - resetAddInfo(); CellLayout.CellInfo longClickCellInfo = (CellLayout.CellInfo) v.getTag(); // This happens when long clicking an item with the dpad/trackball @@ -2379,6 +2482,10 @@ public final class Launcher extends Activity return mWorkspace; } + TabHost getCustomizationDrawer() { + return mHomeCustomizationDrawer; + } + @Override protected Dialog onCreateDialog(int id) { switch (id) { @@ -2536,7 +2643,7 @@ public final class Launcher extends Activity } } - private void showToolbarButton(View button) { + private void showAndEnableToolbarButton(View button) { button.setVisibility(View.VISIBLE); button.setFocusable(true); button.setClickable(true); @@ -2546,6 +2653,9 @@ public final class Launcher extends Activity button.setAlpha(0.0f); // We can't set it to GONE, otherwise the RelativeLayout gets screwed up button.setVisibility(View.INVISIBLE); + } + + private void disableToolbarButton(View button) { button.setFocusable(false); button.setClickable(false); } @@ -2567,12 +2677,18 @@ public final class Launcher extends Activity getResources().getInteger(R.integer.config_toolbarButtonFadeOutTime); if (seq != null) { - Animator anim = ObjectAnimator.ofFloat(view, "alpha", show ? 1.0f : 0.0f); + ValueAnimator anim = ValueAnimator.ofFloat(view.getAlpha(), show ? 1.0f : 0.0f); anim.setDuration(duration); + anim.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + view.setAlpha((Float) animation.getAnimatedValue()); + } + }); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { - if (showing) showToolbarButton(view); + if (showing) showAndEnableToolbarButton(view); + if (hiding) disableToolbarButton(view); } @Override public void onAnimationEnd(Animator animation) { @@ -2582,9 +2698,10 @@ public final class Launcher extends Activity seq.play(anim); } else { if (showing) { - showToolbarButton(view); + showAndEnableToolbarButton(view); view.setAlpha(1f); } else { + disableToolbarButton(view); hideToolbarButton(view); } } @@ -2599,26 +2716,21 @@ public final class Launcher extends Activity * @param hideSeq AnimatorSet in which to put "hide" animations, or null. */ private void hideAndShowToolbarButtons(State newState, AnimatorSet showSeq, AnimatorSet hideSeq) { - final View buttonCluster = findViewById(R.id.all_apps_button_cluster); - - final View allAppsButton = findViewById(R.id.all_apps_button); - final View divider = findViewById(R.id.divider); - final View configureButton = findViewById(R.id.configure_button); - switch (newState) { case WORKSPACE: - hideOrShowToolbarButton(true, buttonCluster, showSeq); - mDeleteZone.setOverlappingViews(new View[] { allAppsButton, divider, configureButton }); + hideOrShowToolbarButton(true, mButtonCluster, showSeq); + mDeleteZone.setOverlappingViews( + new View[] { mAllAppsButton, mDivider, mConfigureButton }); mDeleteZone.setDragAndDropEnabled(true); mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_workspace)); break; case ALL_APPS: - hideOrShowToolbarButton(false, buttonCluster, hideSeq); + hideOrShowToolbarButton(false, mButtonCluster, hideSeq); mDeleteZone.setDragAndDropEnabled(false); mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_all_apps)); break; case CUSTOMIZE: - hideOrShowToolbarButton(false, buttonCluster, hideSeq); + hideOrShowToolbarButton(false, mButtonCluster, hideSeq); mDeleteZone.setDragAndDropEnabled(false); break; } @@ -2659,6 +2771,9 @@ public final class Launcher extends Activity final int duration = toAllApps ? res.getInteger(R.integer.config_allAppsZoomInTime) : res.getInteger(R.integer.config_customizeZoomInTime); + final int fadeDuration = toAllApps ? + res.getInteger(R.integer.config_allAppsFadeInTime) : + res.getInteger(R.integer.config_customizeFadeInTime); final float scale = toAllApps ? (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor) : @@ -2675,7 +2790,7 @@ public final class Launcher extends Activity } if (animated) { - ValueAnimator scaleAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration); + final ValueAnimator scaleAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration); scaleAnim.setInterpolator(new Workspace.ZoomOutInterpolator()); scaleAnim.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { @@ -2688,8 +2803,8 @@ public final class Launcher extends Activity }); if (toAllApps) { - toView.setAlpha(0f); - ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration); + toView.setFastAlpha(0f); + ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(fadeDuration); alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); alphaAnim.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { @@ -2702,9 +2817,8 @@ public final class Launcher extends Activity alphaAnim.start(); } - // Only use hardware layers in portrait mode, they don't give any gains in landscape - if (mWorkspace.getWidth() < mWorkspace.getHeight()) { - toView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + if (toView instanceof LauncherTransitionable) { + ((LauncherTransitionable) toView).onLauncherTransitionStart(scaleAnim); } scaleAnim.addListener(new AnimatorListenerAdapter() { @Override @@ -2714,7 +2828,7 @@ public final class Launcher extends Activity toView.setTranslationY(0.0f); toView.setVisibility(View.VISIBLE); if (!toAllApps) { - toView.setAlpha(1.0f); + toView.setFastAlpha(1.0f); } } @Override @@ -2722,9 +2836,11 @@ public final class Launcher extends Activity // If we don't set the final scale values here, if this animation is cancelled // it will have the wrong scale value and subsequent cameraPan animations will // not fix that - toView.setLayerType(View.LAYER_TYPE_NONE, null); toView.setScaleX(1.0f); toView.setScaleY(1.0f); + if (toView instanceof LauncherTransitionable) { + ((LauncherTransitionable) toView).onLauncherTransitionEnd(scaleAnim); + } } }); @@ -2750,6 +2866,10 @@ public final class Launcher extends Activity toView.setScaleX(1.0f); toView.setScaleY(1.0f); toView.setVisibility(View.VISIBLE); + if (toView instanceof LauncherTransitionable) { + ((LauncherTransitionable) toView).onLauncherTransitionStart(null); + ((LauncherTransitionable) toView).onLauncherTransitionEnd(null); + } hideAndShowToolbarButtons(toState, null, null); } } @@ -2805,7 +2925,7 @@ public final class Launcher extends Activity fromView.setFastScaleY(a * oldScaleY + b * scaleFactor); } }); - ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f); + final ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f); alphaAnim.setDuration(res.getInteger(R.integer.config_allAppsFadeOutTime)); alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f)); alphaAnim.addUpdateListener(new AnimatorUpdateListener() { @@ -2816,13 +2936,16 @@ public final class Launcher extends Activity fromView.setFastAlpha(a * 1f + b * 0f); } }); - - fromView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + if (fromView instanceof LauncherTransitionable) { + ((LauncherTransitionable) fromView).onLauncherTransitionStart(alphaAnim); + } alphaAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { fromView.setVisibility(View.GONE); - fromView.setLayerType(View.LAYER_TYPE_NONE, null); + if (fromView instanceof LauncherTransitionable) { + ((LauncherTransitionable) fromView).onLauncherTransitionEnd(alphaAnim); + } } }); @@ -2841,100 +2964,23 @@ public final class Launcher extends Activity mStateAnimation.start(); } else { fromView.setVisibility(View.GONE); + if (fromView instanceof LauncherTransitionable) { + ((LauncherTransitionable) fromView).onLauncherTransitionStart(null); + ((LauncherTransitionable) fromView).onLauncherTransitionEnd(null); + } if (!springLoaded) { hideAndShowToolbarButtons(State.WORKSPACE, null, null); } } } - /** - * Pan the camera in the vertical plane between 'fromView' and 'toView'. - * This is the transition used on xlarge screens to go between all apps and - * the home customization drawer. - * @param fromState The view to pan away from. Must be ALL_APPS or CUSTOMIZE. - * @param toState The view to pan into the frame. Must be ALL_APPS or CUSTOMIZE. - * @param animated If true, the transition will be animated. - */ - private void cameraPan(State fromState, State toState, boolean animated) { - final Resources res = getResources(); - final int duration = res.getInteger(R.integer.config_allAppsCameraPanTime); - final int workspaceHeight = mWorkspace.getHeight(); - - final boolean fromAllApps = (fromState == State.ALL_APPS); - final View fromView = fromAllApps ? (View) mAllAppsGrid : mHomeCustomizationDrawer; - final View toView = fromAllApps ? mHomeCustomizationDrawer : (View) mAllAppsGrid; - - final float fromViewStartY = fromAllApps ? 0.0f : fromView.getY(); - final float fromViewEndY = fromAllApps ? -fromView.getHeight() * 2 : workspaceHeight * 2; - final float toViewStartY = fromAllApps ? workspaceHeight * 2 : -toView.getHeight() * 2; - final float toViewEndY = fromAllApps ? workspaceHeight - toView.getHeight() : 0.0f; - - mCustomizePagedView.endChoiceMode(); - mAllAppsPagedView.endChoiceMode(); - - if (toState == State.ALL_APPS) { - mWorkspace.shrink(Workspace.ShrinkState.BOTTOM_HIDDEN, animated); - } else { - mWorkspace.shrink(Workspace.ShrinkState.TOP, animated); - } - - if (animated) { - if (mStateAnimation != null) mStateAnimation.cancel(); - mStateAnimation = new AnimatorSet(); - mStateAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - toView.setVisibility(View.VISIBLE); - toView.setY(toViewStartY); - toView.setAlpha(1.0f); - } - @Override - public void onAnimationEnd(Animator animation) { - fromView.setVisibility(View.GONE); - } - }); - - AnimatorSet toolbarHideAnim = new AnimatorSet(); - AnimatorSet toolbarShowAnim = new AnimatorSet(); - hideAndShowToolbarButtons(toState, toolbarShowAnim, toolbarHideAnim); - - ObjectAnimator fromAnim = ObjectAnimator.ofFloat(fromView, "y", - fromViewStartY, fromViewEndY); - fromAnim.setDuration(duration); - ObjectAnimator toAnim = ObjectAnimator.ofPropertyValuesHolder(toView, - PropertyValuesHolder.ofFloat("y", toViewStartY, toViewEndY), - PropertyValuesHolder.ofFloat("scaleX", toView.getScaleX(), 1.0f), - PropertyValuesHolder.ofFloat("scaleY", toView.getScaleY(), 1.0f) - ); - fromAnim.setDuration(duration); - mStateAnimation.playTogether(toolbarHideAnim, fromAnim, toAnim); - - // Show the new toolbar buttons just as the main animation is ending - final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime); - mStateAnimation.play(toolbarShowAnim).after(duration - fadeInTime); - mStateAnimation.start(); - } else { - fromView.setY(fromViewEndY); - fromView.setVisibility(View.GONE); - toView.setY(toViewEndY); - toView.setScaleX(1.0f); - toView.setScaleY(1.0f); - toView.setVisibility(View.VISIBLE); - hideAndShowToolbarButtons(toState, null, null); - } - } - void showAllApps(boolean animated) { - if (mState == State.ALL_APPS) { + if (mState != State.WORKSPACE) { return; } if (LauncherApplication.isScreenXLarge()) { - if (mState == State.CUSTOMIZE) { - cameraPan(State.CUSTOMIZE, State.ALL_APPS, animated); - } else { - cameraZoomOut(State.ALL_APPS, animated); - } + cameraZoomOut(State.ALL_APPS, animated); } else { mAllAppsGrid.zoom(1.0f, animated); } @@ -3074,11 +3120,12 @@ public final class Launcher extends Activity // Show the customization drawer (only exists in x-large configuration) private void showCustomizationDrawer(boolean animated) { - if (mState == State.ALL_APPS) { - cameraPan(State.ALL_APPS, State.CUSTOMIZE, animated); - } else { - cameraZoomOut(State.CUSTOMIZE, animated); + if (mState != State.WORKSPACE) { + return; } + + cameraZoomOut(State.CUSTOMIZE, animated); + // Change the state *after* we've called all the transition code mState = State.CUSTOMIZE; @@ -3094,9 +3141,15 @@ public final class Launcher extends Activity } } - void addExternalItemToScreen(ItemInfo itemInfo, CellLayout layout) { + /** + * Add an item from all apps or customize onto the given workspace screen. + * If layout is null, add to the current screen. + */ + void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) { if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) { showOutOfSpaceMessage(); + } else { + layout.animateDrop(); } } @@ -3104,11 +3157,7 @@ public final class Launcher extends Activity showWorkspace(true, layout); } - // if successful in getting icon, return it; otherwise, set button to use default drawable - private Drawable.ConstantState updateButtonWithIconFromExternalActivity( - int buttonId, ComponentName activityName, int fallbackDrawableId) { - ImageView button = (ImageView) findViewById(buttonId); - Drawable toolbarIcon = null; + private Drawable getExternalPackageToolbarIcon(ComponentName activityName) { try { PackageManager packageManager = getPackageManager(); // Look for the toolbar icon specified in the activity meta-data @@ -3118,12 +3167,37 @@ public final class Launcher extends Activity int iconResId = metaData.getInt(TOOLBAR_ICON_METADATA_NAME); if (iconResId != 0) { Resources res = packageManager.getResourcesForActivity(activityName); - toolbarIcon = res.getDrawable(iconResId); + return res.getDrawable(iconResId); } } } catch (NameNotFoundException e) { // Do nothing } + return null; + } + + // if successful in getting icon, return it; otherwise, set button to use default drawable + private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity( + int buttonId, ComponentName activityName, int fallbackDrawableId) { + TextView button = (TextView) findViewById(buttonId); + Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName); + + // If we were unable to find the icon via the meta-data, use a generic one + if (toolbarIcon == null) { + button.setCompoundDrawablesWithIntrinsicBounds(fallbackDrawableId, 0, 0, 0); + return null; + } else { + button.setCompoundDrawablesWithIntrinsicBounds(toolbarIcon, null, null, null); + return toolbarIcon.getConstantState(); + } + } + + // if successful in getting icon, return it; otherwise, set button to use default drawable + private Drawable.ConstantState updateButtonWithIconFromExternalActivity( + int buttonId, ComponentName activityName, int fallbackDrawableId) { + ImageView button = (ImageView) findViewById(buttonId); + Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName); + // If we were unable to find the icon via the meta-data, use a generic one if (toolbarIcon == null) { button.setImageResource(fallbackDrawableId); @@ -3134,6 +3208,11 @@ public final class Launcher extends Activity } } + private void updateTextButtonWithDrawable(int buttonId, Drawable.ConstantState d) { + TextView button = (TextView) findViewById(buttonId); + button.setCompoundDrawables(d.newDrawable(getResources()), null, null, null); + } + private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) { ImageView button = (ImageView) findViewById(buttonId); button.setImageDrawable(d.newDrawable(getResources())); @@ -3185,14 +3264,14 @@ public final class Launcher extends Activity ComponentName activityName = intent.resolveActivity(getPackageManager()); if (activityName != null) { mAppMarketIntent = intent; - sAppMarketIcon = updateButtonWithIconFromExternalActivity( + sAppMarketIcon = updateTextButtonWithIconFromExternalActivity( R.id.market_button, activityName, R.drawable.app_market_generic); } } } private void updateAppMarketIcon(Drawable.ConstantState d) { - updateButtonWithDrawable(R.id.market_button, d); + updateTextButtonWithDrawable(R.id.market_button, d); } /** @@ -3536,6 +3615,13 @@ public final class Launcher extends Activity } mWorkspaceLoading = false; + + // If we received the result of any pending adds while the loader was running (e.g. the + // widget configuration forced an orientation change), process them now. + for (int i = 0; i < sPendingAddList.size(); i++) { + completeAdd(sPendingAddList.get(i)); + } + sPendingAddList.clear(); } /** @@ -3584,8 +3670,12 @@ public final class Launcher extends Activity public void bindAppsUpdated(ArrayList<ApplicationInfo> apps) { setLoadOnResume(); removeDialog(DIALOG_CREATE_SHORTCUT); - mWorkspace.updateShortcuts(apps); - mAllAppsGrid.updateApps(apps); + if (mWorkspace != null) { + mWorkspace.updateShortcuts(apps); + } + if (mAllAppsGrid != null) { + mAllAppsGrid.updateApps(apps); + } if (mCustomizePagedView != null) { mCustomizePagedView.updateApps(apps); } @@ -3679,3 +3769,8 @@ public final class Launcher extends Activity Log.d(TAG, "END launcher2 dump state"); } } + +interface LauncherTransitionable { + void onLauncherTransitionStart(Animator animation); + void onLauncherTransitionEnd(Animator animation); +} diff --git a/src/com/android/launcher2/LauncherAppWidgetHostView.java b/src/com/android/launcher2/LauncherAppWidgetHostView.java index 85a80f943..7f60cac3d 100644 --- a/src/com/android/launcher2/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher2/LauncherAppWidgetHostView.java @@ -72,7 +72,7 @@ public class LauncherAppWidgetHostView extends AppWidgetHostView // Otherwise continue letting touch events fall through to children return false; } - + class CheckForLongPress implements Runnable { private int mOriginalWindowAttachCount; diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 005273749..c09874901 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -44,6 +44,7 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.Parcelable; @@ -65,6 +66,7 @@ public class LauncherModel extends BroadcastReceiver { static final String TAG = "Launcher.Model"; private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons + private final boolean mAppsCanBeOnExternalStorage; private int mBatchSize; // 0 is all apps at once private int mAllAppsLoadDelay; // milliseconds between batches @@ -115,6 +117,7 @@ public class LauncherModel extends BroadcastReceiver { } LauncherModel(LauncherApplication app, IconCache iconCache) { + mAppsCanBeOnExternalStorage = !Environment.isExternalStorageEmulated(); mApp = app; mAllAppsList = new AllAppsList(iconCache); mIconCache = iconCache; @@ -174,6 +177,33 @@ public class LauncherModel extends BroadcastReceiver { } /** + * Resize an item in the DB to a new <spanX, spanY, cellX, cellY> + */ + static void resizeItemInDatabase(Context context, ItemInfo item, int cellX, int cellY, + int spanX, int spanY) { + item.spanX = spanX; + item.spanY = spanY; + item.cellX = cellX; + item.cellY = cellY; + + final Uri uri = LauncherSettings.Favorites.getContentUri(item.id, false); + final ContentValues values = new ContentValues(); + final ContentResolver cr = context.getContentResolver(); + + values.put(LauncherSettings.Favorites.CONTAINER, item.container); + values.put(LauncherSettings.Favorites.SPANX, spanX); + values.put(LauncherSettings.Favorites.SPANY, spanY); + values.put(LauncherSettings.Favorites.CELLX, cellX); + values.put(LauncherSettings.Favorites.CELLY, cellY); + + sWorker.post(new Runnable() { + public void run() { + cr.update(uri, values, null, null); + } + }); + } + + /** * Returns true if the shortcuts already exists in the database. * we identify a shortcut by its title and intent. */ @@ -794,8 +824,6 @@ public class LauncherModel extends BroadcastReceiver { } if (info != null) { - updateSavedIcon(context, info, c, iconIndex); - info.intent = intent; info.id = c.getLong(idIndex); container = c.getInt(containerIndex); @@ -820,6 +848,10 @@ public class LauncherModel extends BroadcastReceiver { folderInfo.add(info); break; } + + // now that we've loaded everthing re-save it with the + // icon in case it disappears somehow. + updateSavedIcon(context, info, c, iconIndex); } else { // Failed to load the shortcut, probably because the // activity manager couldn't resolve it (maybe the app @@ -1669,6 +1701,10 @@ public class LauncherModel extends BroadcastReceiver { } void updateSavedIcon(Context context, ShortcutInfo info, Cursor c, int iconIndex) { + // If apps can't be on SD, don't even bother. + if (!mAppsCanBeOnExternalStorage) { + return; + } // If this icon doesn't have a custom icon, check to see // what's stored in the DB, and if it doesn't match what // we're going to show, store what we are going to show back @@ -1691,9 +1727,8 @@ public class LauncherModel extends BroadcastReceiver { } if (needSave) { Log.d(TAG, "going to save icon bitmap for info=" + info); - // This is slower than is ideal, but this only happens either - // after the froyo OTA or when the app is updated with a new - // icon. + // This is slower than is ideal, but this only happens once + // or when the app is updated with a new icon. updateItemInDatabase(context, info); } } diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java index e4cdd59fc..e7ecb9914 100644 --- a/src/com/android/launcher2/PagedView.java +++ b/src/com/android/launcher2/PagedView.java @@ -30,6 +30,8 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.view.ActionMode; +import android.view.InputDevice; +import android.view.KeyEvent; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; @@ -61,6 +63,7 @@ public abstract class PagedView extends ViewGroup { private static final float OVERSCROLL_DAMP_FACTOR = 0.08f; private static final int MINIMUM_SNAP_VELOCITY = 2200; private static final int MIN_FLING_VELOCITY = 250; + private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f; // the velocity at which a fling gesture will cause us to snap to the next page protected int mSnapVelocity = 500; @@ -81,6 +84,7 @@ public abstract class PagedView extends ViewGroup { protected float mLastMotionX; protected float mLastMotionXRemainder; protected float mLastMotionY; + protected float mTotalMotionX; private int mLastScreenCenter = -1; protected final static int TOUCH_STATE_REST = 0; @@ -98,6 +102,7 @@ public abstract class PagedView extends ViewGroup { protected int mTouchSlop; private int mPagingTouchSlop; private int mMaximumVelocity; + private int mMinimumWidth; protected int mPageSpacing; protected int mPageLayoutPaddingTop; protected int mPageLayoutPaddingBottom; @@ -173,13 +178,13 @@ public abstract class PagedView extends ViewGroup { R.styleable.PagedView, defStyle, 0); mPageSpacing = a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0); mPageLayoutPaddingTop = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingTop, 10); + R.styleable.PagedView_pageLayoutPaddingTop, 0); mPageLayoutPaddingBottom = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingBottom, 10); + R.styleable.PagedView_pageLayoutPaddingBottom, 0); mPageLayoutPaddingLeft = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingLeft, 10); + R.styleable.PagedView_pageLayoutPaddingLeft, 0); mPageLayoutPaddingRight = a.getDimensionPixelSize( - R.styleable.PagedView_pageLayoutPaddingRight, 10); + R.styleable.PagedView_pageLayoutPaddingRight, 0); mPageLayoutWidthGap = a.getDimensionPixelSize( R.styleable.PagedView_pageLayoutWidthGap, -1); mPageLayoutHeightGap = a.getDimensionPixelSize( @@ -498,6 +503,11 @@ public abstract class PagedView extends ViewGroup { } } + protected void forceUpdateAdjacentPagesAlpha() { + mDirtyPageAlpha = true; + updateAdjacentPagesAlpha(); + } + protected void updateAdjacentPagesAlpha() { if (mFadeInAdjacentScreens) { if (mDirtyPageAlpha || (mTouchState == TOUCH_STATE_SCROLLING) || !mScroller.isFinished()) { @@ -544,6 +554,11 @@ public abstract class PagedView extends ViewGroup { alpha = 1.0f; } + // Due to the way we're setting alpha on our children in PagedViewCellLayout, + // this optimization causes alpha to not be properly updated sometimes (repro + // case: in xlarge mode, swipe to second page in All Apps, then click on "My + // Apps" tab. the page will have alpha 0 until you swipe it). Removing + // optimization fixes the issue, but we should fix this in a better manner //if (Float.compare(alpha, layout.getAlpha()) != 0) { layout.setAlpha(alpha); //} @@ -596,21 +611,7 @@ public abstract class PagedView extends ViewGroup { canvas.clipRect(mScrollX, mScrollY, mScrollX + mRight - mLeft, mScrollY + mBottom - mTop); - for (int i = 0; i < pageCount; i++) { - View child = getChildAt(i); - if (child != null && child instanceof PagedViewCellLayout) { - boolean willBeDrawn = i >= leftScreen && i <= rightScreen; - if (!willBeDrawn) { - ((PagedViewCellLayout)child).destroyHardwareLayers(); - } - } - } - for (int i = leftScreen; i <= rightScreen; i++) { - View child = getChildAt(i); - if (child != null && child instanceof PagedViewCellLayout) { - ((PagedViewCellLayout)child).createHardwareLayers(); - } drawChild(canvas, getChildAt(i), drawingTime); } canvas.restore(); @@ -737,6 +738,7 @@ public abstract class PagedView extends ViewGroup { * If we return true, onTouchEvent will be called and we do the actual * scrolling there. */ + acquireVelocityTrackerAndAddMovement(ev); // Skip touch handling if there are no pages to swipe if (getChildCount() <= 0) return super.onInterceptTouchEvent(ev); @@ -777,6 +779,7 @@ public abstract class PagedView extends ViewGroup { mLastMotionX = x; mLastMotionY = y; mLastMotionXRemainder = 0; + mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); mAllowLongPress = true; @@ -814,10 +817,12 @@ public abstract class PagedView extends ViewGroup { mTouchState = TOUCH_STATE_REST; mAllowLongPress = false; mActivePointerId = INVALID_POINTER; + releaseVelocityTracker(); break; case MotionEvent.ACTION_POINTER_UP: onSecondaryPointerUp(ev); + releaseVelocityTracker(); break; } @@ -869,6 +874,7 @@ public abstract class PagedView extends ViewGroup { if (mUsePagingTouchSlop ? xPaged : xMoved) { // Scroll if the user moved far enough along the X axis mTouchState = TOUCH_STATE_SCROLLING; + mTotalMotionX += Math.abs(mLastMotionX - x); mLastMotionX = x; mLastMotionXRemainder = 0; mTouchX = mScrollX; @@ -952,6 +958,7 @@ public abstract class PagedView extends ViewGroup { // Remember where the motion event started mDownMotionX = mLastMotionX = ev.getX(); mLastMotionXRemainder = 0; + mTotalMotionX = 0; mActivePointerId = ev.getPointerId(0); if (mTouchState == TOUCH_STATE_SCROLLING) { pageBeginMoving(); @@ -965,6 +972,8 @@ public abstract class PagedView extends ViewGroup { final float x = ev.getX(pointerIndex); final float deltaX = mLastMotionX + mLastMotionXRemainder - x; + mTotalMotionX += Math.abs(deltaX); + // Only scroll and update mLastMotionX if we have moved some discrete amount. We // keep the remainder because we are actually testing if we've moved from the last // scrolled position (which is discrete). @@ -995,17 +1004,37 @@ public abstract class PagedView extends ViewGroup { velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int velocityX = (int) velocityTracker.getXVelocity(activePointerId); final int deltaX = (int) (x - mDownMotionX); - boolean isfling = Math.abs(deltaX) > MIN_LENGTH_FOR_FLING; boolean isSignificantMove = Math.abs(deltaX) > MIN_LENGTH_FOR_MOVE; - final int snapVelocity = mSnapVelocity; - if ((isSignificantMove && deltaX > 0 || - (isfling && velocityX > snapVelocity)) && mCurrentPage > 0) { - snapToPageWithVelocity(mCurrentPage - 1, velocityX); - } else if ((isSignificantMove && deltaX < 0 || - (isfling && velocityX < -snapVelocity)) && + + mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x); + + // In the case that the page is moved far to one direction and then is flung + // in the opposite direction, we use a threshold to determine whether we should + // just return to the starting page, or if we should skip one further. + boolean returnToOriginalPage = false; + final int pageWidth = getScaledMeasuredWidth(getChildAt(mCurrentPage)); + if (Math.abs(deltaX) > pageWidth * RETURN_TO_ORIGINAL_PAGE_THRESHOLD && + Math.signum(velocityX) != Math.signum(deltaX)) { + returnToOriginalPage = true; + } + + boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING && + Math.abs(velocityX) > snapVelocity; + + int finalPage; + // We give flings precedence over large moves, which is why we short-circuit our + // test for a large move if a fling has been registered. That is, a large + // move to the left and fling to the right will register as a fling to the right. + if (((isSignificantMove && deltaX > 0 && !isFling) || + (isFling && velocityX > 0)) && mCurrentPage > 0) { + finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1; + snapToPageWithVelocity(finalPage, velocityX); + } else if (((isSignificantMove && deltaX < 0 && !isFling) || + (isFling && velocityX < 0)) && mCurrentPage < getChildCount() - 1) { - snapToPageWithVelocity(mCurrentPage + 1, velocityX); + finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1; + snapToPageWithVelocity(finalPage, velocityX); } else { snapToDestination(); } @@ -1054,6 +1083,35 @@ public abstract class PagedView extends ViewGroup { return true; } + @Override + public boolean onGenericMotionEvent(MotionEvent event) { + if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { + switch (event.getAction()) { + case MotionEvent.ACTION_SCROLL: { + // Handle mouse (or ext. device) by shifting the page depending on the scroll + final float vscroll; + final float hscroll; + if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) { + vscroll = 0; + hscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL); + } else { + vscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL); + hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL); + } + if (hscroll != 0 || vscroll != 0) { + if (hscroll > 0 || vscroll > 0) { + scrollRight(); + } else { + scrollLeft(); + } + return true; + } + } + } + } + return super.onGenericMotionEvent(event); + } + private void acquireVelocityTrackerAndAddMovement(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); @@ -1116,8 +1174,16 @@ public abstract class PagedView extends ViewGroup { return -1; } + protected void setMinimumWidthOverride(int minimumWidth) { + mMinimumWidth = minimumWidth; + } + + protected int getChildWidth(int index) { + return Math.max(mMinimumWidth, getChildAt(index).getMeasuredWidth()); + } + protected int getRelativeChildOffset(int index) { - return (getMeasuredWidth() - getChildAt(index).getMeasuredWidth()) / 2; + return (getMeasuredWidth() - getChildWidth(index)) / 2; } protected int getChildOffset(int index) { @@ -1132,7 +1198,7 @@ public abstract class PagedView extends ViewGroup { } protected int getScaledMeasuredWidth(View child) { - return (int) (child.getMeasuredWidth() * mLayoutScale + 0.5f); + return (int) (Math.max(mMinimumWidth, child.getMeasuredWidth()) * mLayoutScale + 0.5f); } int getPageNearestToCenterOfScreen() { @@ -1398,7 +1464,7 @@ public abstract class PagedView extends ViewGroup { * Otherwise, returns null. */ protected Checkable getSingleCheckedGrandchild() { - if (mChoiceMode == CHOICE_MODE_SINGLE) { + if (mChoiceMode != CHOICE_MODE_MULTIPLE) { final int childCount = getChildCount(); for (int i = 0; i < childCount; ++i) { Page layout = (Page) getChildAt(i); @@ -1414,14 +1480,6 @@ public abstract class PagedView extends ViewGroup { return null; } - public Object getChosenItem() { - View checkedView = (View) getSingleCheckedGrandchild(); - if (checkedView != null) { - return checkedView.getTag(); - } - return null; - } - protected void resetCheckedGrandchildren() { // loop through children, and set all of their children to _not_ be checked final ArrayList<Checkable> checked = getCheckedGrandchildren(); diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java index d64f3c901..28bb78b9a 100644 --- a/src/com/android/launcher2/PagedViewCellLayout.java +++ b/src/com/android/launcher2/PagedViewCellLayout.java @@ -40,7 +40,8 @@ public class PagedViewCellLayout extends ViewGroup implements Page { private static int sDefaultCellDimensions = 96; protected PagedViewCellLayoutChildren mChildren; private PagedViewCellLayoutChildren mHolographicChildren; - private boolean mUseHardwareLayers = false; + private boolean mAllowHardwareLayerCreation = false; + private boolean mCreateHardwareLayersIfAllowed = false; public PagedViewCellLayout(Context context) { this(context, null); @@ -74,8 +75,17 @@ public class PagedViewCellLayout extends ViewGroup implements Page { addView(mHolographicChildren); } - public void enableHardwareLayers() { - mUseHardwareLayers = true; + public void allowHardwareLayerCreation() { + // This is called after the first time we launch into All Apps. Before that point, + // there's no need for hardware layers here since there's a hardware layer set on the + // parent, AllAppsTabbed, during the AllApps transition -- creating hardware layers here + // before the animation is done slows down the animation + if (!mAllowHardwareLayerCreation) { + mAllowHardwareLayerCreation = true; + if (mCreateHardwareLayersIfAllowed) { + createHardwareLayers(); + } + } } @Override @@ -85,13 +95,18 @@ public class PagedViewCellLayout extends ViewGroup implements Page { } void destroyHardwareLayers() { - if (mUseHardwareLayers) { + // called when a page is no longer visible (triggered by loadAssociatedPages -> + // removeAllViewsOnPage) + mCreateHardwareLayersIfAllowed = false; + if (mAllowHardwareLayerCreation) { mChildren.destroyHardwareLayer(); mHolographicChildren.destroyHardwareLayer(); } } void createHardwareLayers() { - if (mUseHardwareLayers) { + // called when a page is visible (triggered by loadAssociatedPages -> syncPageItems) + mCreateHardwareLayersIfAllowed = true; + if (mAllowHardwareLayerCreation) { mChildren.createHardwareLayer(); mHolographicChildren.createHardwareLayer(); } @@ -127,7 +142,7 @@ public class PagedViewCellLayout extends ViewGroup implements Page { if (child instanceof PagedViewIcon) { PagedViewIcon pagedViewIcon = (PagedViewIcon) child; - if (mUseHardwareLayers) { + if (mAllowHardwareLayerCreation) { pagedViewIcon.disableCache(); } mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(), index, lp); @@ -141,6 +156,7 @@ public class PagedViewCellLayout extends ViewGroup implements Page { public void removeAllViewsOnPage() { mChildren.removeAllViews(); mHolographicChildren.removeAllViews(); + destroyHardwareLayers(); } @Override diff --git a/src/com/android/launcher2/PagedViewCellLayoutChildren.java b/src/com/android/launcher2/PagedViewCellLayoutChildren.java index 27da02af5..92ff46184 100644 --- a/src/com/android/launcher2/PagedViewCellLayoutChildren.java +++ b/src/com/android/launcher2/PagedViewCellLayoutChildren.java @@ -139,12 +139,12 @@ public class PagedViewCellLayoutChildren extends ViewGroup { } void destroyHardwareLayer() { - if (getLayerType() == LAYER_TYPE_HARDWARE) { + if (getLayerType() != LAYER_TYPE_NONE) { setLayerType(LAYER_TYPE_NONE, null); } } void createHardwareLayer() { - if (getLayerType() == LAYER_TYPE_NONE) { + if (getLayerType() != LAYER_TYPE_HARDWARE) { setLayerType(LAYER_TYPE_HARDWARE, null); } } diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java index 1366619f8..bde65593a 100644 --- a/src/com/android/launcher2/PagedViewIcon.java +++ b/src/com/android/launcher2/PagedViewIcon.java @@ -141,13 +141,15 @@ public class PagedViewIcon extends CachedTextView implements Checkable { return mHolographicOutline; } - private void queueHolographicOutlineCreation() { + private boolean queueHolographicOutlineCreation() { // Generate the outline in the background if (mHolographicOutline == null) { Message m = sWorker.obtainMessage(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE); m.obj = this; sWorker.sendMessage(m); + return true; } + return false; } public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache, @@ -161,7 +163,9 @@ public class PagedViewIcon extends CachedTextView implements Checkable { mIconCache = cache; mIconCacheKey = new PagedViewIconCache.Key(info); mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - queueHolographicOutlineCreation(); + if (!queueHolographicOutlineCreation()) { + getHolographicOutlineView().invalidate(); + } } } @@ -177,7 +181,9 @@ public class PagedViewIcon extends CachedTextView implements Checkable { mIconCache = cache; mIconCacheKey = new PagedViewIconCache.Key(info); mHolographicOutline = mIconCache.getOutline(mIconCacheKey); - queueHolographicOutlineCreation(); + if (!queueHolographicOutlineCreation()) { + getHolographicOutlineView().invalidate(); + } } } @@ -243,8 +249,7 @@ public class PagedViewIcon extends CachedTextView implements Checkable { return mIsChecked; } - @Override - public void setChecked(boolean checked) { + void setChecked(boolean checked, boolean animate) { if (mIsChecked != checked) { mIsChecked = checked; @@ -262,15 +267,24 @@ public class PagedViewIcon extends CachedTextView implements Checkable { if (mCheckedAlphaAnimator != null) { mCheckedAlphaAnimator.cancel(); } - mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); - mCheckedAlphaAnimator.setDuration(duration); - mCheckedAlphaAnimator.start(); + if (animate) { + mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); + mCheckedAlphaAnimator.setDuration(duration); + mCheckedAlphaAnimator.start(); + } else { + setAlpha(alpha); + } invalidate(); } } @Override + public void setChecked(boolean checked) { + setChecked(checked, true); + } + + @Override public void toggle() { setChecked(!mIsChecked); } diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java index 9b83f4823..72f928b54 100644 --- a/src/com/android/launcher2/PagedViewWidget.java +++ b/src/com/android/launcher2/PagedViewWidget.java @@ -27,7 +27,11 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.PorterDuff; import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; +import android.graphics.RectF; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; @@ -52,6 +56,10 @@ public class PagedViewWidget extends LinearLayout implements Checkable { private Bitmap mHolographicOutline; private final Canvas mHolographicOutlineCanvas = new Canvas(); private FastBitmapDrawable mPreview; + private ImageView mPreviewImageView; + private final RectF mTmpScaleRect = new RectF(); + private final Rect mEraseStrokeRect = new Rect(); + private final Paint mEraseStrokeRectPaint = new Paint(); private PagedViewIconCache.Key mIconCacheKey; private PagedViewIconCache mIconCache; @@ -81,8 +89,11 @@ public class PagedViewWidget extends LinearLayout implements Checkable { public void handleMessage(Message msg) { final PagedViewWidget widget = (PagedViewWidget) msg.obj; final int prevAlpha = widget.mPreview.getAlpha(); - final Bitmap outline = Bitmap.createBitmap(widget.getWidth(), widget.getHeight(), - Bitmap.Config.ARGB_8888); + final int width = Math.max(widget.mPreview.getIntrinsicWidth(), + widget.getMeasuredWidth()); + final int height = Math.max(widget.mPreview.getIntrinsicHeight(), + widget.getMeasuredHeight()); + final Bitmap outline = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); widget.mHolographicOutlineCanvas.setBitmap(outline); widget.mHolographicOutlineCanvas.save(); @@ -94,6 +105,12 @@ public class PagedViewWidget extends LinearLayout implements Checkable { widget.mHolographicOutlineCanvas.drawColor(Color.argb(156, 0, 0, 0), Mode.SRC_OVER); widget.mHolographicOutlineCanvas.restore(); + // To account for the fact that some previews run up straight to the edge (we subtract + // the edge from the holographic preview (before we apply the holograph) + widget.mEraseStrokeRect.set(0, 0, width, height); + widget.mHolographicOutlineCanvas.drawRect(widget.mEraseStrokeRect, + widget.mEraseStrokeRectPaint); + sHolographicOutlineHelper.applyThickExpensiveOutlineWithBlur(outline, widget.mHolographicOutlineCanvas, widget.mHoloBlurColor, widget.mHoloOutlineColor); @@ -123,6 +140,11 @@ public class PagedViewWidget extends LinearLayout implements Checkable { defStyle, 0); mHoloBlurColor = a.getColor(R.styleable.PagedViewWidget_blurColor, 0); mHoloOutlineColor = a.getColor(R.styleable.PagedViewWidget_outlineColor, 0); + mEraseStrokeRectPaint.setStyle(Paint.Style.STROKE); + mEraseStrokeRectPaint.setStrokeWidth(HolographicOutlineHelper.MIN_OUTER_BLUR_RADIUS); + mEraseStrokeRectPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + mEraseStrokeRectPaint.setFilterBitmap(true); + mEraseStrokeRectPaint.setAntiAlias(true); a.recycle(); if (sHolographicOutlineHelper == null) { @@ -158,6 +180,7 @@ public class PagedViewWidget extends LinearLayout implements Checkable { final ImageView image = (ImageView) findViewById(R.id.widget_preview); image.setMaxWidth(maxWidth); image.setImageDrawable(preview); + mPreviewImageView = image; final TextView name = (TextView) findViewById(R.id.widget_name); name.setText(info.label); name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); @@ -179,6 +202,7 @@ public class PagedViewWidget extends LinearLayout implements Checkable { ImageView image = (ImageView) findViewById(R.id.wallpaper_preview); image.setMaxWidth(maxWidth); image.setImageDrawable(preview); + mPreviewImageView = image; TextView name = (TextView) findViewById(R.id.wallpaper_name); name.setText(info.loadLabel(packageManager)); name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); @@ -211,8 +235,15 @@ public class PagedViewWidget extends LinearLayout implements Checkable { // draw any blended overlays if (mHolographicOutline != null && mHolographicAlpha > 0) { + // Calculate how much to scale the holographic preview + mTmpScaleRect.set(0,0,1,1); + mPreviewImageView.getImageMatrix().mapRect(mTmpScaleRect); + mPaint.setAlpha(mHolographicAlpha); + canvas.save(); + canvas.scale(mTmpScaleRect.right, mTmpScaleRect.bottom); canvas.drawBitmap(mHolographicOutline, 0, 0, mPaint); + canvas.restore(); } } @@ -257,8 +288,7 @@ public class PagedViewWidget extends LinearLayout implements Checkable { sWorker.removeMessages(MESSAGE_CREATE_HOLOGRAPHIC_OUTLINE, this); } - @Override - public void setChecked(boolean checked) { + void setChecked(boolean checked, boolean animate) { if (mIsChecked != checked) { mIsChecked = checked; @@ -276,15 +306,24 @@ public class PagedViewWidget extends LinearLayout implements Checkable { if (mCheckedAlphaAnimator != null) { mCheckedAlphaAnimator.cancel(); } - mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); - mCheckedAlphaAnimator.setDuration(duration); - mCheckedAlphaAnimator.start(); + if (animate) { + mCheckedAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", getAlpha(), alpha); + mCheckedAlphaAnimator.setDuration(duration); + mCheckedAlphaAnimator.start(); + } else { + setAlpha(alpha); + } invalidate(); } } @Override + public void setChecked(boolean checked) { + setChecked(checked, true); + } + + @Override public boolean isChecked() { return mIsChecked; } diff --git a/src/com/android/launcher2/StrokedTextView.java b/src/com/android/launcher2/StrokedTextView.java new file mode 100644 index 000000000..20f9f48a0 --- /dev/null +++ b/src/com/android/launcher2/StrokedTextView.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher2; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.widget.TextView; + +import com.android.launcher.R; + +/** + * This class adds a stroke to the generic TextView allowing the text to stand out better against + * the background (ie. in the AllApps button). + */ +public class StrokedTextView extends TextView { + private final Canvas mCanvas = new Canvas(); + private final Paint mPaint = new Paint(); + private Bitmap mCache; + private boolean mUpdateCachedBitmap; + private int mStrokeColor; + private float mStrokeWidth; + private int mTextColor; + + public StrokedTextView(Context context) { + super(context); + init(context, null, 0); + } + + public StrokedTextView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs, 0); + } + + public StrokedTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs, defStyle); + } + + private void init(Context context, AttributeSet attrs, int defStyle) { + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StrokedTextView, + defStyle, 0); + mStrokeColor = a.getColor(R.styleable.StrokedTextView_strokeColor, 0xFF000000); + mStrokeWidth = a.getFloat(R.styleable.StrokedTextView_strokeWidth, 0.0f); + mTextColor = a.getColor(R.styleable.StrokedTextView_strokeTextColor, 0xFFFFFFFF); + a.recycle(); + mUpdateCachedBitmap = true; + + // Setup the text paint + mPaint.setAntiAlias(true); + mPaint.setStyle(Paint.Style.FILL_AND_STROKE); + } + + protected void onTextChanged(CharSequence text, int start, int before, int after) { + super.onTextChanged(text, start, before, after); + mUpdateCachedBitmap = true; + } + + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + if (w > 0 && h > 0) { + mUpdateCachedBitmap = true; + mCache = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + } else { + mCache = null; + } + } + + protected void onDraw(Canvas canvas) { + if (mCache != null) { + if (mUpdateCachedBitmap) { + final int gap = getCompoundDrawablePadding(); + final int w = getMeasuredWidth(); + final int h = getMeasuredHeight(); + final String text = getText().toString(); + final Rect textBounds = new Rect(); + final Paint textPaint = getPaint(); + final int textWidth = (int) textPaint.measureText(text); + textPaint.getTextBounds("x", 0, 1, textBounds); + + // Clear the old cached image + mCanvas.setBitmap(mCache); + mCanvas.drawColor(0, PorterDuff.Mode.CLEAR); + + // Draw the drawable + final int drawableLeft = getPaddingLeft(); + final int drawableTop = getPaddingTop(); + final Drawable[] drawables = getCompoundDrawables(); + for (int i = 0; i < drawables.length; ++i) { + if (drawables[i] != null) { + drawables[i].setBounds(drawableLeft, drawableTop, + drawableLeft + drawables[i].getIntrinsicWidth(), + drawableTop + drawables[i].getIntrinsicHeight()); + drawables[i].draw(mCanvas); + } + } + + final int left = w - getPaddingRight() - textWidth; + final int bottom = (h + textBounds.height()) / 2; + + // Draw the outline of the text + mPaint.setStrokeWidth(mStrokeWidth); + mPaint.setColor(mStrokeColor); + mPaint.setTextSize(getTextSize()); + mCanvas.drawText(text, left, bottom, mPaint); + + // Draw the text itself + mPaint.setStrokeWidth(0); + mPaint.setColor(mTextColor); + mCanvas.drawText(text, left, bottom, mPaint); + + mUpdateCachedBitmap = false; + } + canvas.drawBitmap(mCache, 0, 0, mPaint); + } else { + super.onDraw(canvas); + } + } +} diff --git a/src/com/android/launcher2/UserFolder.java b/src/com/android/launcher2/UserFolder.java index b362fbdf1..251b3f95a 100644 --- a/src/com/android/launcher2/UserFolder.java +++ b/src/com/android/launcher2/UserFolder.java @@ -64,7 +64,7 @@ public class UserFolder extends Folder implements DropTarget { } @Override - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { if (success) { ShortcutsAdapter adapter = (ShortcutsAdapter)mContent.getAdapter(); adapter.remove(mDragItem); diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 0daed37f8..e7865d26f 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -23,7 +23,6 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.animation.Animator.AnimatorListener; @@ -62,6 +61,8 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; +import android.widget.TabHost; +import android.widget.TabWidget; import android.widget.TextView; import android.widget.Toast; @@ -75,7 +76,8 @@ import java.util.List; * interact with. A workspace is meant to be used with a fixed width only. */ public class Workspace extends SmoothPagedView - implements DropTarget, DragSource, DragScroller, View.OnTouchListener { + implements DropTarget, DragSource, DragScroller, View.OnTouchListener, + View.OnClickListener { @SuppressWarnings({"UnusedDeclaration"}) private static final String TAG = "Launcher.Workspace"; @@ -108,10 +110,11 @@ public class Workspace extends SmoothPagedView private float mChildrenOutlineAlpha = 0; // These properties refer to the background protection gradient used for AllApps and Customize - private ObjectAnimator mBackgroundFadeInAnimation; - private ObjectAnimator mBackgroundFadeOutAnimation; + private ValueAnimator mBackgroundFadeInAnimation; + private ValueAnimator mBackgroundFadeOutAnimation; private Drawable mBackground; private Drawable mCustomizeTrayBackground; + boolean mDrawBackground = true; private boolean mDrawCustomizeTrayBackground; private float mBackgroundAlpha = 0; private float mOverScrollMaxBackgroundAlpha = 0.0f; @@ -123,6 +126,7 @@ public class Workspace extends SmoothPagedView private float[] mCustomizationDrawerTransformedPos = new float[2]; private final WallpaperManager mWallpaperManager; + private IBinder mWindowToken; private int mDefaultPage; @@ -224,9 +228,6 @@ public class Workspace extends SmoothPagedView final static float MAX_SWIPE_ANGLE = (float) Math.PI / 3; final static float TOUCH_SLOP_DAMPING_FACTOR = 4; - int mSpringLoadedDropX; - int mSpringLoadedDropY; - /** * Used to inflate the Workspace from XML. * @@ -265,6 +266,9 @@ public class Workspace extends SmoothPagedView setHapticFeedbackEnabled(false); initWorkspace(); + + // Disable multitouch across the workspace/all apps/customize tray + setMotionEventSplittingEnabled(true); } /** @@ -342,6 +346,8 @@ public class Workspace extends SmoothPagedView throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } ((CellLayout) child).setOnInterceptTouchListener(this); + child.setOnClickListener(this); + child.setClickable(true); super.addView(child, index, params); } @@ -351,6 +357,8 @@ public class Workspace extends SmoothPagedView throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } ((CellLayout) child).setOnInterceptTouchListener(this); + child.setOnClickListener(this); + child.setClickable(true); super.addView(child); } @@ -360,6 +368,8 @@ public class Workspace extends SmoothPagedView throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } ((CellLayout) child).setOnInterceptTouchListener(this); + child.setOnClickListener(this); + child.setClickable(true); super.addView(child, index); } @@ -369,6 +379,8 @@ public class Workspace extends SmoothPagedView throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } ((CellLayout) child).setOnInterceptTouchListener(this); + child.setOnClickListener(this); + child.setClickable(true); super.addView(child, width, height); } @@ -378,6 +390,8 @@ public class Workspace extends SmoothPagedView throw new IllegalArgumentException("A Workspace can only have CellLayout children."); } ((CellLayout) child).setOnInterceptTouchListener(this); + child.setOnClickListener(this); + child.setClickable(true); super.addView(child, params); } @@ -418,8 +432,8 @@ public class Workspace extends SmoothPagedView return folders; } - boolean isDefaultPageShowing() { - return mCurrentPage == mDefaultPage; + boolean isTouchActive() { + return mTouchState != TOUCH_STATE_REST; } /** @@ -520,16 +534,25 @@ public class Workspace extends SmoothPagedView return hitsPage(current + 1, x, y); } + /** + * Called directly from a CellLayout (not by the framework), after we've been added as a + * listener via setOnInterceptTouchEventListener(). This allows us to tell the CellLayout + * that it should intercept touch events, which is not something that is normally supported. + */ + @Override public boolean onTouch(View v, MotionEvent event) { - // this is an intercepted event being forwarded from a cell layout - if (mIsSmall || mIsInUnshrinkAnimation) { - // Only allow clicks on a CellLayout if it is visible - if (mShrinkState != ShrinkState.BOTTOM_HIDDEN) { - mLauncher.onWorkspaceClick((CellLayout) v); - } - return true; + return (mIsSmall || mIsInUnshrinkAnimation); + } + + /** + * Handle a click event on a CellLayout. + */ + @Override + public void onClick(View cellLayout) { + // Only allow clicks on a CellLayout if it is shrunken and visible. + if ((mIsSmall || mIsInUnshrinkAnimation) && mShrinkState != ShrinkState.BOTTOM_HIDDEN) { + mLauncher.onWorkspaceClick((CellLayout) cellLayout); } - return false; } protected void onWindowVisibilityChanged (int visibility) { @@ -553,8 +576,7 @@ public class Workspace extends SmoothPagedView } if (mIsSmall || mIsInUnshrinkAnimation) { - if (mLauncher.isAllAppsVisible() && - mShrinkState == ShrinkState.BOTTOM_HIDDEN) { + if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) { // Intercept this event so we can show the workspace in full view // when it is clicked on and it is small AllAppsPagedView allApps = (AllAppsPagedView) @@ -689,7 +711,11 @@ public class Workspace extends SmoothPagedView // parallax effects mWallpaperWidth = (int) (maxDim * wallpaperTravelToScreenWidthRatio(maxDim, minDim)); mWallpaperHeight = (int)(maxDim * wallpaperTravelToScreenHeightRatio(maxDim, minDim)); - mWallpaperManager.suggestDesiredDimensions(mWallpaperWidth, mWallpaperHeight); + new Thread("setWallpaperDimension") { + public void run() { + mWallpaperManager.suggestDesiredDimensions(mWallpaperWidth, mWallpaperHeight); + } + }.start(); } public void setVerticalWallpaperOffset(float offset) { @@ -707,11 +733,15 @@ public class Workspace extends SmoothPagedView private float wallpaperOffsetForCurrentScroll() { Display display = mLauncher.getWindowManager().getDefaultDisplay(); + final boolean isStaticWallpaper = (mWallpaperManager.getWallpaperInfo() == null); // The wallpaper travel width is how far, from left to right, the wallpaper will move // at this orientation (for example, in portrait mode we don't move all the way to the // edges of the wallpaper, or otherwise the parallax effect would be too strong) int wallpaperTravelWidth = (int) (display.getWidth() * wallpaperTravelToScreenWidthRatio(display.getWidth(), display.getHeight())); + if (!isStaticWallpaper) { + wallpaperTravelWidth = mWallpaperWidth; + } // Set wallpaper offset steps (1 / (number of screens - 1)) // We have 3 vertical offset states (centered, and then top/bottom aligned @@ -725,7 +755,6 @@ public class Workspace extends SmoothPagedView // you overscroll as far as you can in landscape mode. Only do this for static wallpapers // because live wallpapers (and probably 3rd party wallpaper providers) rely on the offset // being even intervals from 0 to 1 (eg [0, 0.25, 0.5, 0.75, 1]) - final boolean isStaticWallpaper = (mWallpaperManager.getWallpaperInfo() == null); if (isStaticWallpaper) { int overscrollOffset = (int) (maxOverScroll() * display.getWidth()); scrollProgressOffset += overscrollOffset / (float) getScrollRange(); @@ -735,7 +764,7 @@ public class Workspace extends SmoothPagedView float scrollProgress = mScrollX / (float) scrollRange + scrollProgressOffset; float offsetInDips = wallpaperTravelWidth * scrollProgress + - (mWallpaperWidth - wallpaperTravelWidth) / 2; + (mWallpaperWidth - wallpaperTravelWidth) / 2; // center it float offset = offsetInDips / (float) mWallpaperWidth; return offset; } @@ -761,14 +790,13 @@ public class Workspace extends SmoothPagedView updateNow = keepUpdating = mWallpaperOffset.computeScrollOffset(); } if (updateNow) { - IBinder token = getWindowToken(); - if (token != null) { - mWallpaperManager.setWallpaperOffsets(getWindowToken(), + if (mWindowToken != null) { + mWallpaperManager.setWallpaperOffsets(mWindowToken, mWallpaperOffset.getCurrX(), mWallpaperOffset.getCurrY()); } } if (keepUpdating) { - invalidate(); + fastInvalidate(); } } @@ -891,7 +919,7 @@ public class Workspace extends SmoothPagedView } } - public void showOutlines() { + void showOutlines() { if (!mIsSmall && !mIsInUnshrinkAnimation) { if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); @@ -901,7 +929,7 @@ public class Workspace extends SmoothPagedView } } - public void hideOutlines() { + void hideOutlines() { if (!mIsSmall && !mIsInUnshrinkAnimation) { if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel(); if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel(); @@ -912,6 +940,12 @@ public class Workspace extends SmoothPagedView } } + public void showOutlinesTemporarily() { + if (!mIsPageMoving && !isTouchActive()) { + snapToPage(mCurrentPage); + } + } + public void setChildrenOutlineAlpha(float alpha) { mChildrenOutlineAlpha = alpha; for (int i = 0; i < getChildCount(); i++) { @@ -924,6 +958,13 @@ public class Workspace extends SmoothPagedView return mChildrenOutlineAlpha; } + void disableBackground() { + mDrawBackground = false; + } + void enableBackground() { + mDrawBackground = true; + } + private void showBackgroundGradientForAllApps() { showBackgroundGradient(); mDrawCustomizeTrayBackground = false; @@ -938,7 +979,12 @@ public class Workspace extends SmoothPagedView if (mBackground == null) return; if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); - mBackgroundFadeInAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 1.0f); + mBackgroundFadeInAnimation = ValueAnimator.ofFloat(getBackgroundAlpha(), 1f); + mBackgroundFadeInAnimation.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + setBackgroundAlpha(((Float) animation.getAnimatedValue()).floatValue()); + } + }); mBackgroundFadeInAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); mBackgroundFadeInAnimation.setDuration(BACKGROUND_FADE_IN_DURATION); mBackgroundFadeInAnimation.start(); @@ -948,15 +994,22 @@ public class Workspace extends SmoothPagedView if (mBackground == null) return; if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); - mBackgroundFadeOutAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 0.0f); + mBackgroundFadeOutAnimation = ValueAnimator.ofFloat(getBackgroundAlpha(), 0f); + mBackgroundFadeOutAnimation.addUpdateListener(new AnimatorUpdateListener() { + public void onAnimationUpdate(ValueAnimator animation) { + setBackgroundAlpha(((Float) animation.getAnimatedValue()).floatValue()); + } + }); mBackgroundFadeOutAnimation.setInterpolator(new DecelerateInterpolator(1.5f)); mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION); mBackgroundFadeOutAnimation.start(); } public void setBackgroundAlpha(float alpha) { - mBackgroundAlpha = alpha; - invalidate(); + if (alpha != mBackgroundAlpha) { + mBackgroundAlpha = alpha; + invalidate(); + } } public float getBackgroundAlpha() { @@ -1050,8 +1103,13 @@ public class Workspace extends SmoothPagedView protected void onAttachedToWindow() { super.onAttachedToWindow(); + mWindowToken = getWindowToken(); computeScroll(); - mDragController.setWindowToken(getWindowToken()); + mDragController.setWindowToken(mWindowToken); + } + + protected void onDetachedFromWindow() { + mWindowToken = null; } @Override @@ -1086,7 +1144,7 @@ public class Workspace extends SmoothPagedView updateWallpaperOffsets(); // Draw the background gradient if necessary - if (mBackground != null && mBackgroundAlpha > 0.0f) { + if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) { int alpha = (int) (mBackgroundAlpha * 255); if (mDrawCustomizeTrayBackground) { // Find out where to offset the gradient for the customization tray content @@ -1126,9 +1184,11 @@ public class Workspace extends SmoothPagedView final int pageCount = getChildCount(); final long drawingTime = getDrawingTime(); for (int i = 0; i < pageCount; i++) { - final View page = (View) getChildAt(i); - - drawChild(canvas, page, drawingTime); + final CellLayout page = (CellLayout) getChildAt(i); + if (page.getVisibility() == VISIBLE + && (page.getAlpha() != 0f || page.getBackgroundAlpha() != 0f)) { + drawChild(canvas, page, drawingTime); + } } } else { super.dispatchDraw(canvas); @@ -1317,6 +1377,19 @@ public class Workspace extends SmoothPagedView shrink(shrinkState, true); } + private int getCustomizeDrawerHeight() { + TabHost customizationDrawer = mLauncher.getCustomizationDrawer(); + int height = customizationDrawer.getHeight(); + TabWidget tabWidget = (TabWidget) + customizationDrawer.findViewById(com.android.internal.R.id.tabs); + if (tabWidget.getTabCount() > 0) { + TextView tabText = (TextView) tabWidget.getChildTabViewAt(0); + // subtract the empty space above the tab text + height -= ((tabWidget.getHeight() - tabText.getLineHeight())) / 2; + } + return height; + } + // we use this to shrink the workspace for the all apps view and the customize view public void shrink(ShrinkState shrinkState, boolean animated) { // In the launcher interaction model, we're never in the state where we're shrunken and @@ -1393,9 +1466,7 @@ public class Workspace extends SmoothPagedView y = screenHeight / 2 - scaledPageHeight / 2; finalAlpha = 1.0f; } else if (shrinkState == ShrinkState.TOP) { - y = (isPortrait ? - getResources().getDimension(R.dimen.customizeSmallScreenVerticalMarginPortrait) : - getResources().getDimension(R.dimen.customizeSmallScreenVerticalMarginLandscape)); + y = (screenHeight - getCustomizeDrawerHeight() - scaledPageHeight) / 2; } int duration; @@ -1446,6 +1517,11 @@ public class Workspace extends SmoothPagedView oldAlphas[i] = cl.getAlpha(); newAlphas[i] = finalAlpha; + if (animated && (oldAlphas[i] != 0f || newAlphas[i] != 0f)) { + // if the CellLayout will be visible during the animation, force building its + // hardware layer immediately so we don't see a blip later in the animation + cl.buildChildrenLayer(); + } if (animated) { oldXs[i] = cl.getX(); oldYs[i] = cl.getY(); @@ -1517,9 +1593,13 @@ public class Workspace extends SmoothPagedView final float newVerticalWallpaperOffset = wallpaperOffset; animWithInterpolator.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { - fastInvalidate(); final float b = (Float) animation.getAnimatedValue(); final float a = 1f - b; + if (b == 0f) { + // an optimization, and required for correct behavior. + return; + } + fastInvalidate(); setHorizontalWallpaperOffset( a * oldHorizontalWallpaperOffset + b * newHorizontalWallpaperOffset); setVerticalWallpaperOffset( @@ -1719,6 +1799,11 @@ public class Workspace extends SmoothPagedView } } + public void exitWidgetResizeMode() { + final CellLayout currentLayout = (CellLayout) getChildAt(getCurrentPage()); + currentLayout.getChildrenLayout().clearAllResizeFrames(); + } + void unshrink(boolean animated) { unshrink(animated, false); } @@ -1847,9 +1932,13 @@ public class Workspace extends SmoothPagedView final float newVerticalWallpaperOffset = 0.5f; animWithInterpolator.addUpdateListener(new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { - fastInvalidate(); final float b = (Float) animation.getAnimatedValue(); final float a = 1f - b; + if (b == 0f) { + // an optimization, but not required + return; + } + fastInvalidate(); setHorizontalWallpaperOffset( a * oldHorizontalWallpaperOffset + b * newHorizontalWallpaperOffset); setVerticalWallpaperOffset( @@ -1880,6 +1969,10 @@ public class Workspace extends SmoothPagedView // don't invalidate workspace because we did it above final float b = (Float) animation.getAnimatedValue(); final float a = 1f - b; + if (b == 0f) { + // an optimization, but not required + return; + } for (int i = 0; i < screenCount; i++) { final CellLayout cl = (CellLayout) getChildAt(i); cl.setFastRotationY(a * oldRotationYs[i] + b * newRotationYs[i]); @@ -2051,8 +2144,8 @@ public class Workspace extends SmoothPagedView final int screenX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2; final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2; mLauncher.lockScreenOrientation(); - mDragController.startDrag(b, screenX, screenY, 0, 0, bmpWidth, bmpHeight, this, - child.getTag(), DragController.DRAG_ACTION_MOVE, null); + mDragController.startDrag( + b, screenX, screenY, this, child.getTag(), DragController.DRAG_ACTION_MOVE); b.recycle(); } @@ -2180,9 +2273,9 @@ public class Workspace extends SmoothPagedView public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo) { - - int originX = x - xOffset; - int originY = y - yOffset; + boolean largeOrSpringLoaded = !mIsSmall || mWasSpringLoadedOnDragExit; + int originX = largeOrSpringLoaded ? x - xOffset : x - xOffset + dragView.getWidth() / 2; + int originY = largeOrSpringLoaded ? y - yOffset : y - yOffset + dragView.getHeight() / 2; if (mIsSmall || mIsInUnshrinkAnimation) { // get originX and originY in the local coordinate system of the screen @@ -2191,6 +2284,10 @@ public class Workspace extends SmoothPagedView mapPointFromSelfToChild(mDragTargetLayout, mTempOriginXY); originX = (int)mTempOriginXY[0]; originY = (int)mTempOriginXY[1]; + if (!largeOrSpringLoaded) { + originX -= mDragTargetLayout.getCellWidth() / 2; + originY -= mDragTargetLayout.getCellHeight() / 2; + } } // When you are in customization mode and drag to a particular screen, make that the @@ -2203,13 +2300,14 @@ public class Workspace extends SmoothPagedView } if (source != this) { - if (!mIsSmall || mWasSpringLoadedOnDragExit) { - onDropExternal(originX, originY, dragInfo, mDragTargetLayout, false); - } else { - // if we drag and drop to small screens, don't pass the touch x/y coords (when we - // enable spring-loaded adding, however, we do want to pass the touch x/y coords) - onDropExternal(-1, -1, dragInfo, mDragTargetLayout, false); + final int[] touchXY = new int[] { originX, originY }; + if ((mIsSmall || mIsInUnshrinkAnimation) && !mLauncher.isAllAppsVisible()) { + // When the workspace is shrunk and the drop comes from customize, don't actually + // add the item to the screen -- customize will do this itself + ((ItemInfo) dragInfo).dropPos = touchXY; + return; } + onDropExternal(touchXY, dragInfo, mDragTargetLayout, false); } else if (mDragInfo != null) { final View cell = mDragInfo.cell; CellLayout dropTargetLayout = mDragTargetLayout; @@ -2254,6 +2352,24 @@ public class Workspace extends SmoothPagedView cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen, mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY)); + if (cell instanceof LauncherAppWidgetHostView) { + final CellLayoutChildren children = dropTargetLayout.getChildrenLayout(); + final CellLayout cellLayout = dropTargetLayout; + // We post this call so that the widget has a chance to be placed + // in its final location + + final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell; + AppWidgetProviderInfo pinfo = hostView.getAppWidgetInfo(); + if (pinfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE) { + post(new Runnable() { + public void run() { + children.addResizeFrame(info, hostView, + cellLayout); + } + }); + } + } + LauncherModel.moveItemInDatabase(mLauncher, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, lp.cellX, lp.cellY); @@ -2292,7 +2408,7 @@ public class Workspace extends SmoothPagedView // would land in a cell occupied by a DragTarget (e.g. a Folder), // then drag events should be handled by that child. - ItemInfo item = (ItemInfo)dragInfo; + ItemInfo item = (ItemInfo) dragInfo; CellLayout currentLayout = getCurrentDropLayout(); int dragPointX, dragPointY; @@ -2418,7 +2534,7 @@ public class Workspace extends SmoothPagedView if (isShortcut) { final Intent intent = data.getItemAt(index).getIntent(); Object info = model.infoFromShortcutIntent(mContext, intent, data.getIcon()); - onDropExternal(x, y, info, layout, false); + onDropExternal(new int[] { x, y }, info, layout, false); } else { if (widgets.size() == 1) { // If there is only one item, then go ahead and add and configure @@ -2622,7 +2738,13 @@ public class Workspace extends SmoothPagedView mSpringLoadedDragController.onDragExit(); } mDragTargetLayout = layout; - if (mDragTargetLayout != null && mDragTargetLayout.getAcceptsDrops()) { + // In spring-loaded mode, we still want the user to be able to hover over a + // full screen (which is traditionally set to not accept drops) if they want to + // get to pages beyond the screen that is full. + boolean allowDragOver = (mDragTargetLayout != null) && + (mDragTargetLayout.getAcceptsDrops() || + (mShrinkState == ShrinkState.SPRING_LOADED)); + if (allowDragOver) { mDragTargetLayout.setIsDragOverlapping(true); mSpringLoadedDragController.onDragEnter( mDragTargetLayout, mShrinkState == ShrinkState.SPRING_LOADED); @@ -2681,8 +2803,6 @@ public class Workspace extends SmoothPagedView final View child = (mDragInfo == null) ? null : mDragInfo.cell; float[] localOrigin = { originX, originY }; mapPointFromSelfToChild(mDragTargetLayout, localOrigin, null); - mSpringLoadedDropX = (int) localOrigin[0]; - mSpringLoadedDropY = (int) localOrigin[1]; mDragTargetLayout.visualizeDropLocation(child, mDragOutline, (int) localOrigin[0], (int) localOrigin[1], item.spanX, item.spanY); } @@ -2723,7 +2843,7 @@ public class Workspace extends SmoothPagedView */ public boolean addExternalItemToScreen(ItemInfo dragInfo, CellLayout layout) { if (layout.findCellForSpan(mTempEstimate, dragInfo.spanX, dragInfo.spanY)) { - onDropExternal(-1, -1, (ItemInfo) dragInfo, (CellLayout) layout, false); + onDropExternal(dragInfo.dropPos, (ItemInfo) dragInfo, (CellLayout) layout, false); return true; } mLauncher.showOutOfSpaceMessage(); @@ -2738,17 +2858,13 @@ public class Workspace extends SmoothPagedView * NOTE: This can also be called when we are outside of a drag event, when we want * to add an item to one of the workspace screens. */ - private void onDropExternal(int x, int y, Object dragInfo, + private void onDropExternal(int[] touchXY, Object dragInfo, CellLayout cellLayout, boolean insertAtFirst) { int screen = indexOfChild(cellLayout); if (dragInfo instanceof PendingAddItemInfo) { PendingAddItemInfo info = (PendingAddItemInfo) dragInfo; // When dragging and dropping from customization tray, we deal with creating // widgets/shortcuts/folders in a slightly different way - // Only set touchXY if you are supporting spring loaded adding of items - int[] touchXY = new int[2]; - touchXY[0] = mSpringLoadedDropX; - touchXY[1] = mSpringLoadedDropY; switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) info, screen, touchXY); @@ -2787,14 +2903,9 @@ public class Workspace extends SmoothPagedView } mTargetCell = new int[2]; - if (x != -1 && y != -1) { + if (touchXY != null) { // when dragging and dropping, just find the closest free spot - - // When we get a drop in Spring Loaded mode, at this point we've already called - // onDragExit, which starts us shrinking again and screws up the transforms we - // need to get the right value. Instead, as a temporary solution, we've saved the - // proper point, mSpringLoadedDropX/Y, from the last onDragOver - cellLayout.findNearestVacantArea(mSpringLoadedDropX, mSpringLoadedDropY, 1, 1, mTargetCell); + cellLayout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, mTargetCell); } else { cellLayout.findCellForSpan(mTargetCell, 1, 1); } @@ -2815,11 +2926,8 @@ public class Workspace extends SmoothPagedView * Return the current {@link CellLayout}, correctly picking the destination * screen while a scroll is in progress. */ - private CellLayout getCurrentDropLayout() { - // if we're currently small, use findMatchingPageForDragOver instead - if (mIsSmall) return null; - int index = mScroller.isFinished() ? mCurrentPage : mNextPage; - return (CellLayout) getChildAt(index); + public CellLayout getCurrentDropLayout() { + return (CellLayout) getChildAt(mNextPage == INVALID_PAGE ? mCurrentPage : mNextPage); } /** @@ -2864,7 +2972,7 @@ public class Workspace extends SmoothPagedView /** * Called at the end of a drag which originated on the workspace. */ - public void onDropCompleted(View target, boolean success) { + public void onDropCompleted(View target, Object dragInfo, boolean success) { if (success) { if (target != this && mDragInfo != null) { final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); @@ -2931,6 +3039,10 @@ public class Workspace extends SmoothPagedView mDragTargetLayout.onDragExit(); mDragTargetLayout = null; } + // In portrait, need to redraw the edge glow when entering the scroll area + if (getHeight() > getWidth()) { + invalidate(); + } } } } @@ -2941,6 +3053,12 @@ public class Workspace extends SmoothPagedView ((CellLayout) getChildAt(i)).setIsDragOverlapping(false); } mSpringLoadedDragController.onDragExit(); + + // In portrait, workspace is responsible for drawing the edge glow on adjacent pages, + // so we need to redraw the workspace when this may have changed. + if (getHeight() > getWidth()) { + invalidate(); + } } @Override |