Reconcile with gingerbread-release honeycomb-release honeycomb-mr1-release
Change-Id: I91591a34a635eab5a75caa9841fff830987c85be
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 444dbd8..f78a1b2 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -45,7 +45,9 @@
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/Launcher2_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
-# ************************************************
\ No newline at end of file
+# ************************************************
diff --git a/proguard.flags b/proguard.flags
index 699f23e..c2b2c65 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -20,6 +20,28 @@
public void setHoverAlpha(float);
}
+-keep class com.android.launcher2.DragLayer$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.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/anim/all_apps_2d_fade_in.xml b/res/anim/all_apps_2d_fade_in.xml
index 0f1e4f4..9d2171a 100644
--- a/res/anim/all_apps_2d_fade_in.xml
+++ b/res/anim/all_apps_2d_fade_in.xml
@@ -20,4 +20,4 @@
android:fromAlpha="0.0"
android:toAlpha="1.0"
- android:duration="@integer/config_allAppsFadeInTime" />
+ android:duration="@integer/config_appsCustomizeFadeInTime" />
diff --git a/res/anim/all_apps_2d_fade_out.xml b/res/anim/all_apps_2d_fade_out.xml
index cc47691..90520c7 100644
--- a/res/anim/all_apps_2d_fade_out.xml
+++ b/res/anim/all_apps_2d_fade_out.xml
@@ -20,4 +20,4 @@
android:fromAlpha="1.0"
android:toAlpha="0.0"
- android:duration="@integer/config_allAppsFadeOutTime" />
+ android:duration="@integer/config_appsCustomizeFadeOutTime" />
diff --git a/res/anim/fade_in_slow.xml b/res/anim/fade_in_slow.xml
index 0f1e4f4..9d2171a 100644
--- a/res/anim/fade_in_slow.xml
+++ b/res/anim/fade_in_slow.xml
@@ -20,4 +20,4 @@
android:fromAlpha="0.0"
android:toAlpha="1.0"
- android:duration="@integer/config_allAppsFadeInTime" />
+ android:duration="@integer/config_appsCustomizeFadeInTime" />
diff --git a/res/anim/fade_out_slow.xml b/res/anim/fade_out_slow.xml
index cc47691..90520c7 100644
--- a/res/anim/fade_out_slow.xml
+++ b/res/anim/fade_out_slow.xml
@@ -20,4 +20,4 @@
android:fromAlpha="1.0"
android:toAlpha="0.0"
- android:duration="@integer/config_allAppsFadeOutTime" />
+ android:duration="@integer/config_appsCustomizeFadeOutTime" />
diff --git a/res/drawable-hdpi/box_launcher_top_normal.9.png b/res/drawable-hdpi/box_launcher_top_normal.9.png
index 98997ad..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_normal.9.png
+++ b/res/drawable-hdpi/box_launcher_top_normal.9.png
Binary files differ
diff --git a/res/drawable-hdpi/box_launcher_top_pressed.9.png b/res/drawable-hdpi/box_launcher_top_pressed.9.png
index f52fd48..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_pressed.9.png
+++ b/res/drawable-hdpi/box_launcher_top_pressed.9.png
Binary files differ
diff --git a/res/drawable-hdpi/box_launcher_top_selected.9.png b/res/drawable-hdpi/box_launcher_top_selected.9.png
index 8cacf0e..af04b07 100644
--- a/res/drawable-hdpi/box_launcher_top_selected.9.png
+++ b/res/drawable-hdpi/box_launcher_top_selected.9.png
Binary files differ
diff --git a/res/drawable-hdpi/focused_bg.9.png b/res/drawable-hdpi/focused_bg.9.png
new file mode 100644
index 0000000..1b0d3fa
--- /dev/null
+++ b/res/drawable-hdpi/focused_bg.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/home_press.9.png b/res/drawable-hdpi/home_press.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/home_press.9.png
rename to res/drawable-hdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_delete_holo_dark.png b/res/drawable-hdpi/ic_home_delete_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_delete_holo_dark.png
rename to res/drawable-hdpi/ic_home_delete_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_delete_hover_holo_dark.png b/res/drawable-hdpi/ic_home_delete_hover_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_delete_hover_holo_dark.png
rename to res/drawable-hdpi/ic_home_delete_hover_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_info_holo_dark.png b/res/drawable-hdpi/ic_home_info_holo_dark.png
similarity index 100%
copy from res/drawable-xlarge-hdpi/ic_home_info_holo_dark.png
copy to res/drawable-hdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/portal_container_holo.9.png b/res/drawable-hdpi/portal_container_holo.9.png
new file mode 100644
index 0000000..af2fa98
--- /dev/null
+++ b/res/drawable-hdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/portal_ring_inner_holo.png b/res/drawable-hdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..8a9e85b
--- /dev/null
+++ b/res/drawable-hdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/portal_ring_outer_holo.png b/res/drawable-hdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..5b46419
--- /dev/null
+++ b/res/drawable-hdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-hdpi/wallpaper_divider.png b/res/drawable-hdpi/wallpaper_divider.png
new file mode 100644
index 0000000..2f92d60
--- /dev/null
+++ b/res/drawable-hdpi/wallpaper_divider.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_resize_frame_holo.9.png b/res/drawable-hdpi/widget_resize_frame_holo.9.png
new file mode 100644
index 0000000..8da665b
--- /dev/null
+++ b/res/drawable-hdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_resize_handle_bottom.png b/res/drawable-hdpi/widget_resize_handle_bottom.png
new file mode 100644
index 0000000..495476b
--- /dev/null
+++ b/res/drawable-hdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_resize_handle_left.png b/res/drawable-hdpi/widget_resize_handle_left.png
new file mode 100644
index 0000000..c73cf0e
--- /dev/null
+++ b/res/drawable-hdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_resize_handle_right.png b/res/drawable-hdpi/widget_resize_handle_right.png
new file mode 100644
index 0000000..9532302
--- /dev/null
+++ b/res/drawable-hdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-hdpi/widget_resize_handle_top.png b/res/drawable-hdpi/widget_resize_handle_top.png
new file mode 100644
index 0000000..a3d2f7c
--- /dev/null
+++ b/res/drawable-hdpi/widget_resize_handle_top.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/app_market_generic.png b/res/drawable-large-hdpi/app_market_generic.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/app_market_generic.png
rename to res/drawable-large-hdpi/app_market_generic.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/divider_launcher_holo.9.png b/res/drawable-large-hdpi/divider_launcher_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/divider_launcher_holo.9.png
rename to res/drawable-large-hdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_large_blue.9.png b/res/drawable-large-hdpi/homescreen_large_blue.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_large_blue.9.png
rename to res/drawable-large-hdpi/homescreen_large_blue.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_large_blue_strong.9.png b/res/drawable-large-hdpi/homescreen_large_blue_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_large_blue_strong.9.png
rename to res/drawable-large-hdpi/homescreen_large_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_large_green.9.png b/res/drawable-large-hdpi/homescreen_large_green.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_large_green.9.png
rename to res/drawable-large-hdpi/homescreen_large_green.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_large_green_strong.9.png b/res/drawable-large-hdpi/homescreen_large_green_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_large_green_strong.9.png
rename to res/drawable-large-hdpi/homescreen_large_green_strong.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_small_blue.9.png b/res/drawable-large-hdpi/homescreen_small_blue.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_small_blue.9.png
rename to res/drawable-large-hdpi/homescreen_small_blue.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_small_blue_strong.9.png b/res/drawable-large-hdpi/homescreen_small_blue_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_small_blue_strong.9.png
rename to res/drawable-large-hdpi/homescreen_small_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_small_green.9.png b/res/drawable-large-hdpi/homescreen_small_green.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_small_green.9.png
rename to res/drawable-large-hdpi/homescreen_small_green.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/homescreen_small_green_strong.9.png b/res/drawable-large-hdpi/homescreen_small_green_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/homescreen_small_green_strong.9.png
rename to res/drawable-large-hdpi/homescreen_small_green_strong.9.png
Binary files differ
diff --git a/res/drawable-large-hdpi/ic_generic_search.png b/res/drawable-large-hdpi/ic_generic_search.png
new file mode 100644
index 0000000..67bac5c
--- /dev/null
+++ b/res/drawable-large-hdpi/ic_generic_search.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_all_apps_holo_dark.png b/res/drawable-large-hdpi/ic_home_all_apps_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_all_apps_holo_dark.png
rename to res/drawable-large-hdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_home_info_holo_dark.png b/res/drawable-large-hdpi/ic_home_info_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_home_info_holo_dark.png
rename to res/drawable-large-hdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/ic_no_applications.png b/res/drawable-large-hdpi/ic_no_applications.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_no_applications.png
rename to res/drawable-large-hdpi/ic_no_applications.png
Binary files differ
diff --git a/res/drawable-large-hdpi/ic_voice_search.png b/res/drawable-large-hdpi/ic_voice_search.png
new file mode 100644
index 0000000..5d2f341
--- /dev/null
+++ b/res/drawable-large-hdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/tab_selected_focused_holo.9.png b/res/drawable-large-hdpi/tab_selected_focused_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/tab_selected_focused_holo.9.png
rename to res/drawable-large-hdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/tab_selected_holo.9.png b/res/drawable-large-hdpi/tab_selected_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/tab_selected_holo.9.png
rename to res/drawable-large-hdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-large-hdpi/tab_selected_pressed_focused_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/tab_selected_pressed_focused_holo.9.png
rename to res/drawable-large-hdpi/tab_selected_pressed_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/tab_selected_pressed_holo.9.png b/res/drawable-large-hdpi/tab_selected_pressed_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/tab_selected_pressed_holo.9.png
rename to res/drawable-large-hdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-large-hdpi/widget_resize_frame_holo.9.png b/res/drawable-large-hdpi/widget_resize_frame_holo.9.png
new file mode 100644
index 0000000..7d16d7d
--- /dev/null
+++ b/res/drawable-large-hdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-large-hdpi/widget_resize_handle_bottom.png b/res/drawable-large-hdpi/widget_resize_handle_bottom.png
new file mode 100644
index 0000000..045c15e
--- /dev/null
+++ b/res/drawable-large-hdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-large-hdpi/widget_resize_handle_left.png b/res/drawable-large-hdpi/widget_resize_handle_left.png
new file mode 100644
index 0000000..f0fc4d6
--- /dev/null
+++ b/res/drawable-large-hdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-large-hdpi/widget_resize_handle_right.png b/res/drawable-large-hdpi/widget_resize_handle_right.png
new file mode 100644
index 0000000..9c1f366
--- /dev/null
+++ b/res/drawable-large-hdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-large-hdpi/widget_resize_handle_top.png b/res/drawable-large-hdpi/widget_resize_handle_top.png
new file mode 100644
index 0000000..f7839ed
--- /dev/null
+++ b/res/drawable-large-hdpi/widget_resize_handle_top.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/app_market_generic.png b/res/drawable-large-mdpi/app_market_generic.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/app_market_generic.png
rename to res/drawable-large-mdpi/app_market_generic.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/divider_launcher_holo.9.png b/res/drawable-large-mdpi/divider_launcher_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/divider_launcher_holo.9.png
rename to res/drawable-large-mdpi/divider_launcher_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_large_blue.9.png b/res/drawable-large-mdpi/homescreen_large_blue.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_large_blue.9.png
rename to res/drawable-large-mdpi/homescreen_large_blue.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_large_green.9.png b/res/drawable-large-mdpi/homescreen_large_green.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_large_green.9.png
rename to res/drawable-large-mdpi/homescreen_large_green.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_large_green_strong.9.png b/res/drawable-large-mdpi/homescreen_large_green_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_large_green_strong.9.png
rename to res/drawable-large-mdpi/homescreen_large_green_strong.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_small_blue.9.png b/res/drawable-large-mdpi/homescreen_small_blue.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_small_blue.9.png
rename to res/drawable-large-mdpi/homescreen_small_blue.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_small_blue_strong.9.png b/res/drawable-large-mdpi/homescreen_small_blue_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_small_blue_strong.9.png
rename to res/drawable-large-mdpi/homescreen_small_blue_strong.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_small_green.9.png b/res/drawable-large-mdpi/homescreen_small_green.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_small_green.9.png
rename to res/drawable-large-mdpi/homescreen_small_green.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/homescreen_small_green_strong.9.png b/res/drawable-large-mdpi/homescreen_small_green_strong.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/homescreen_small_green_strong.9.png
rename to res/drawable-large-mdpi/homescreen_small_green_strong.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/ic_generic_search.png b/res/drawable-large-mdpi/ic_generic_search.png
new file mode 100644
index 0000000..e3fd5a2
--- /dev/null
+++ b/res/drawable-large-mdpi/ic_generic_search.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_add_holo_dark.png b/res/drawable-large-mdpi/ic_home_add_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_add_holo_dark.png
rename to res/drawable-large-mdpi/ic_home_add_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_all_apps_holo_dark.png b/res/drawable-large-mdpi/ic_home_all_apps_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_all_apps_holo_dark.png
rename to res/drawable-large-mdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_no_applications.png b/res/drawable-large-mdpi/ic_no_applications.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_no_applications.png
rename to res/drawable-large-mdpi/ic_no_applications.png
Binary files differ
diff --git a/res/drawable-large-mdpi/ic_voice_search.png b/res/drawable-large-mdpi/ic_voice_search.png
new file mode 100644
index 0000000..3c52e2a
--- /dev/null
+++ b/res/drawable-large-mdpi/ic_voice_search.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/tab_selected_focused_holo.9.png b/res/drawable-large-mdpi/tab_selected_focused_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/tab_selected_focused_holo.9.png
rename to res/drawable-large-mdpi/tab_selected_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/tab_selected_holo.9.png b/res/drawable-large-mdpi/tab_selected_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/tab_selected_holo.9.png
rename to res/drawable-large-mdpi/tab_selected_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-large-mdpi/tab_selected_pressed_focused_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/tab_selected_pressed_focused_holo.9.png
rename to res/drawable-large-mdpi/tab_selected_pressed_focused_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/tab_selected_pressed_holo.9.png b/res/drawable-large-mdpi/tab_selected_pressed_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/tab_selected_pressed_holo.9.png
rename to res/drawable-large-mdpi/tab_selected_pressed_holo.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/widget_resize_frame_holo.9.png b/res/drawable-large-mdpi/widget_resize_frame_holo.9.png
new file mode 100644
index 0000000..e2e1396
--- /dev/null
+++ b/res/drawable-large-mdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-large-mdpi/widget_resize_handle_bottom.png b/res/drawable-large-mdpi/widget_resize_handle_bottom.png
new file mode 100644
index 0000000..99ac1b2
--- /dev/null
+++ b/res/drawable-large-mdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-large-mdpi/widget_resize_handle_left.png b/res/drawable-large-mdpi/widget_resize_handle_left.png
new file mode 100644
index 0000000..d031ddd
--- /dev/null
+++ b/res/drawable-large-mdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-large-mdpi/widget_resize_handle_right.png b/res/drawable-large-mdpi/widget_resize_handle_right.png
new file mode 100644
index 0000000..f1b689c
--- /dev/null
+++ b/res/drawable-large-mdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-large-mdpi/widget_resize_handle_top.png b/res/drawable-large-mdpi/widget_resize_handle_top.png
new file mode 100644
index 0000000..40bef02
--- /dev/null
+++ b/res/drawable-large-mdpi/widget_resize_handle_top.png
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/all_apps_bg_gradient.9.png b/res/drawable-large-nodpi/all_apps_bg_gradient.9.png
similarity index 100%
rename from res/drawable-xlarge-nodpi/all_apps_bg_gradient.9.png
rename to res/drawable-large-nodpi/all_apps_bg_gradient.9.png
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bluecrystal.jpg b/res/drawable-large-nodpi/bluecrystal.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bluecrystal.jpg
rename to res/drawable-large-nodpi/bluecrystal.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bluecrystal_small.jpg b/res/drawable-large-nodpi/bluecrystal_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bluecrystal_small.jpg
rename to res/drawable-large-nodpi/bluecrystal_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bluelinebots.jpg b/res/drawable-large-nodpi/bluelinebots.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bluelinebots.jpg
rename to res/drawable-large-nodpi/bluelinebots.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bluelinebots_small.jpg b/res/drawable-large-nodpi/bluelinebots_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bluelinebots_small.jpg
rename to res/drawable-large-nodpi/bluelinebots_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bots.jpg b/res/drawable-large-nodpi/bots.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bots.jpg
rename to res/drawable-large-nodpi/bots.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bots_small.jpg b/res/drawable-large-nodpi/bots_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bots_small.jpg
rename to res/drawable-large-nodpi/bots_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bucky.jpg b/res/drawable-large-nodpi/bucky.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bucky.jpg
rename to res/drawable-large-nodpi/bucky.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/bucky_small.jpg b/res/drawable-large-nodpi/bucky_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/bucky_small.jpg
rename to res/drawable-large-nodpi/bucky_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/city.jpg b/res/drawable-large-nodpi/city.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/city.jpg
rename to res/drawable-large-nodpi/city.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/city_small.jpg b/res/drawable-large-nodpi/city_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/city_small.jpg
rename to res/drawable-large-nodpi/city_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/customize_bg_gradient.png b/res/drawable-large-nodpi/customize_bg_gradient.png
similarity index 100%
rename from res/drawable-xlarge-nodpi/customize_bg_gradient.png
rename to res/drawable-large-nodpi/customize_bg_gradient.png
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/flowerbot.jpg b/res/drawable-large-nodpi/flowerbot.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/flowerbot.jpg
rename to res/drawable-large-nodpi/flowerbot.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/flowerbot_small.jpg b/res/drawable-large-nodpi/flowerbot_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/flowerbot_small.jpg
rename to res/drawable-large-nodpi/flowerbot_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/glowy_hex.jpg b/res/drawable-large-nodpi/glowy_hex.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/glowy_hex.jpg
rename to res/drawable-large-nodpi/glowy_hex.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/glowy_hex_small.jpg b/res/drawable-large-nodpi/glowy_hex_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/glowy_hex_small.jpg
rename to res/drawable-large-nodpi/glowy_hex_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/lotus.jpg b/res/drawable-large-nodpi/lotus.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/lotus.jpg
rename to res/drawable-large-nodpi/lotus.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/lotus_small.jpg b/res/drawable-large-nodpi/lotus_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/lotus_small.jpg
rename to res/drawable-large-nodpi/lotus_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/village.jpg b/res/drawable-large-nodpi/village.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/village.jpg
rename to res/drawable-large-nodpi/village.jpg
Binary files differ
diff --git a/res/drawable-xlarge-nodpi/village_small.jpg b/res/drawable-large-nodpi/village_small.jpg
similarity index 100%
rename from res/drawable-xlarge-nodpi/village_small.jpg
rename to res/drawable-large-nodpi/village_small.jpg
Binary files differ
diff --git a/res/drawable-xlarge/delete_zone_selector.xml b/res/drawable-large/delete_zone_selector.xml
similarity index 100%
rename from res/drawable-xlarge/delete_zone_selector.xml
rename to res/drawable-large/delete_zone_selector.xml
diff --git a/res/drawable-mdpi/box_launcher_top_normal.9.png b/res/drawable-mdpi/box_launcher_top_normal.9.png
index 8adf2cf..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_normal.9.png
+++ b/res/drawable-mdpi/box_launcher_top_normal.9.png
Binary files differ
diff --git a/res/drawable-mdpi/box_launcher_top_pressed.9.png b/res/drawable-mdpi/box_launcher_top_pressed.9.png
index 7a20c54..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_pressed.9.png
+++ b/res/drawable-mdpi/box_launcher_top_pressed.9.png
Binary files differ
diff --git a/res/drawable-mdpi/box_launcher_top_selected.9.png b/res/drawable-mdpi/box_launcher_top_selected.9.png
index 9e636f0..af04b07 100644
--- a/res/drawable-mdpi/box_launcher_top_selected.9.png
+++ b/res/drawable-mdpi/box_launcher_top_selected.9.png
Binary files differ
diff --git a/res/drawable-mdpi/focused_bg.9.png b/res/drawable-mdpi/focused_bg.9.png
new file mode 100644
index 0000000..1b0d3fa
--- /dev/null
+++ b/res/drawable-mdpi/focused_bg.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/home_press.9.png b/res/drawable-mdpi/home_press.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/home_press.9.png
rename to res/drawable-mdpi/home_press.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_delete_holo_dark.png b/res/drawable-mdpi/ic_home_delete_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_delete_holo_dark.png
rename to res/drawable-mdpi/ic_home_delete_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_delete_hover_holo_dark.png b/res/drawable-mdpi/ic_home_delete_hover_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_delete_hover_holo_dark.png
rename to res/drawable-mdpi/ic_home_delete_hover_holo_dark.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_home_info_holo_dark.png b/res/drawable-mdpi/ic_home_info_holo_dark.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_home_info_holo_dark.png
rename to res/drawable-mdpi/ic_home_info_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_container_holo.9.png b/res/drawable-mdpi/portal_container_holo.9.png
new file mode 100644
index 0000000..42aca5f
--- /dev/null
+++ b/res/drawable-mdpi/portal_container_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_ring_inner_holo.png b/res/drawable-mdpi/portal_ring_inner_holo.png
new file mode 100644
index 0000000..4a64694
--- /dev/null
+++ b/res/drawable-mdpi/portal_ring_inner_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/portal_ring_outer_holo.png b/res/drawable-mdpi/portal_ring_outer_holo.png
new file mode 100644
index 0000000..90cf77f
--- /dev/null
+++ b/res/drawable-mdpi/portal_ring_outer_holo.png
Binary files differ
diff --git a/res/drawable-mdpi/wallpaper_divider.png b/res/drawable-mdpi/wallpaper_divider.png
new file mode 100644
index 0000000..1b453c5
--- /dev/null
+++ b/res/drawable-mdpi/wallpaper_divider.png
Binary files differ
diff --git a/res/drawable-mdpi/widget_resize_frame_holo.9.png b/res/drawable-mdpi/widget_resize_frame_holo.9.png
new file mode 100644
index 0000000..0572f89
--- /dev/null
+++ b/res/drawable-mdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-mdpi/widget_resize_handle_bottom.png b/res/drawable-mdpi/widget_resize_handle_bottom.png
new file mode 100644
index 0000000..6c93973
--- /dev/null
+++ b/res/drawable-mdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-mdpi/widget_resize_handle_left.png b/res/drawable-mdpi/widget_resize_handle_left.png
new file mode 100644
index 0000000..7139415
--- /dev/null
+++ b/res/drawable-mdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-mdpi/widget_resize_handle_right.png b/res/drawable-mdpi/widget_resize_handle_right.png
new file mode 100644
index 0000000..442224b
--- /dev/null
+++ b/res/drawable-mdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-mdpi/widget_resize_handle_top.png b/res/drawable-mdpi/widget_resize_handle_top.png
new file mode 100644
index 0000000..2435884
--- /dev/null
+++ b/res/drawable-mdpi/widget_resize_handle_top.png
Binary files differ
diff --git a/res/drawable-nodpi/apps_customize_bg_gradient.9.png b/res/drawable-nodpi/apps_customize_bg_gradient.9.png
new file mode 100644
index 0000000..e766bd6
--- /dev/null
+++ b/res/drawable-nodpi/apps_customize_bg_gradient.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_generic_search.png b/res/drawable-xlarge-mdpi/ic_generic_search.png
deleted file mode 100644
index d92071b..0000000
--- a/res/drawable-xlarge-mdpi/ic_generic_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/ic_voice_search.png b/res/drawable-xlarge-mdpi/ic_voice_search.png
deleted file mode 100644
index a2fe874..0000000
--- a/res/drawable-xlarge-mdpi/ic_voice_search.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xlarge/button_bg.xml b/res/drawable/button_bg.xml
similarity index 85%
rename from res/drawable-xlarge/button_bg.xml
rename to res/drawable/button_bg.xml
index 9e6e1ff..a830594 100644
--- a/res/drawable-xlarge/button_bg.xml
+++ b/res/drawable/button_bg.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -15,6 +15,7 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:drawable="@drawable/focused_bg" />
<item android:state_pressed="true" android:drawable="@drawable/home_press" />
<item android:drawable="@android:color/transparent" />
</selector>
diff --git a/res/drawable/delete_zone_selector.xml b/res/drawable/delete_zone_selector.xml
index 0c54b1d7..e2b37f4 100644
--- a/res/drawable/delete_zone_selector.xml
+++ b/res/drawable/delete_zone_selector.xml
@@ -19,6 +19,6 @@
-->
<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/trashcan" />
- <item android:drawable="@drawable/trashcan_hover" />
+ <item android:drawable="@drawable/ic_home_delete_holo_dark" />
+ <item android:drawable="@drawable/ic_home_delete_hover_holo_dark" />
</transition>
diff --git a/res/drawable-xlarge/button_bg.xml b/res/drawable/focusable_view_bg.xml
similarity index 77%
copy from res/drawable-xlarge/button_bg.xml
copy to res/drawable/focusable_view_bg.xml
index 9e6e1ff..66661e2 100644
--- a/res/drawable-xlarge/button_bg.xml
+++ b/res/drawable/focusable_view_bg.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -15,6 +15,5 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/home_press" />
- <item android:drawable="@android:color/transparent" />
+ <item android:state_focused="true" android:drawable="@drawable/focused_bg" />
</selector>
diff --git a/res/layout-land/all_apps_2d.xml b/res/layout-land/all_apps_2d.xml
deleted file mode 100644
index b7fcd45..0000000
--- a/res/layout-land/all_apps_2d.xml
+++ /dev/null
@@ -1,63 +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.
--->
-
-<!-- Sapphire gets 2D all apps view -->
-<com.android.launcher2.AllApps2D
- xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:id="@+id/all_apps_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="2dip"
- android:background="#FF000000">
-
- <GridView android:id="@+id/all_apps_2d_grid"
- android:tag="all_apps_2d_grid"
- android:scrollbars="none"
- android:drawSelectorOnTop="false"
- android:listSelector="@drawable/grid_selector"
- android:verticalSpacing="10dip"
- android:numColumns="6"
- android:fadingEdgeLength="48dip"
- android:cacheColorHint="#FF000000"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:layout_marginRight="@dimen/button_bar_height_portrait"
- android:nextFocusRight="@+id/all_apps_2d_home"
- android:nextFocusUp="@null"
- android:nextFocusLeft="@null"
- android:nextFocusDown="@null"
- />
-
- <view
- class="com.android.launcher2.AllApps2D$HomeButton"
- android:id="@+id/all_apps_2d_home"
- android:tag="all_apps_2d_home"
- android:src="@drawable/home_button"
- android:background="#FF000000"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/button_bar_height_portrait"
- android:paddingBottom="@dimen/status_bar_height"
- android:nextFocusLeft="@+id/all_apps_2d_grid"
- android:nextFocusDown="@null"
- android:nextFocusUp="@null"
- android:nextFocusRight="@null"
- />
-
-</com.android.launcher2.AllApps2D>
diff --git a/res/layout-land/application.xml b/res/layout-land/application.xml
index 6e8c31e..9ed1fa1 100644
--- a/res/layout-land/application.xml
+++ b/res/layout-land/application.xml
@@ -15,4 +15,6 @@
-->
<com.android.launcher2.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/WorkspaceIcon.Landscape" />
+ style="@style/WorkspaceIcon.Landscape"
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 6e797f8..b2b2c9f 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -22,8 +22,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/all_apps" />
-
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher2.Workspace
android:id="@+id/workspace"
@@ -43,6 +41,12 @@
</com.android.launcher2.Workspace>
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
<com.android.launcher2.ClippedImageView
android:id="@+id/previous_screen"
android:layout_width="93dip"
@@ -96,38 +100,26 @@
android:layout_height="fill_parent"
android:layout_width="@dimen/button_bar_height_portrait"
android:layout_gravity="right|center_vertical"
- android:layout_marginBottom="@dimen/half_status_bar_height"
- >
-
+ android:layout_marginBottom="@dimen/half_status_bar_height">
+ <ImageView
+ android:id="@+id/hotseat_left"
+ style="@style/HotseatButton.Left"
+ android:layout_below="@id/all_apps_button"
+ android:src="@drawable/hotseat_phone"
+ android:onClick="launchHotSeat" />
<com.android.launcher2.HandleView
style="@style/HotseatButton"
android:id="@+id/all_apps_button"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
-
android:src="@drawable/all_apps_button"
- launcher:direction="vertical"
- />
-
- <ImageView
- android:id="@+id/hotseat_left"
- style="@style/HotseatButton.Left"
- android:layout_below="@id/all_apps_button"
-
- android:src="@drawable/hotseat_phone"
-
- android:onClick="launchHotSeat"
- />
-
+ launcher:direction="vertical" />
<ImageView
android:id="@+id/hotseat_right"
style="@style/HotseatButton.Right"
android:layout_above="@id/all_apps_button"
-
android:src="@drawable/hotseat_browser"
-
- android:onClick="launchHotSeat"
- />
+ android:onClick="launchHotSeat" />
</RelativeLayout>
</com.android.launcher2.DragLayer>
diff --git a/res/layout-land/user_folder.xml b/res/layout-land/user_folder.xml
index 5da4aa5..87499e7 100644
--- a/res/layout-land/user_folder.xml
+++ b/res/layout-land/user_folder.xml
@@ -14,39 +14,27 @@
limitations under the License.
-->
-<com.android.launcher2.UserFolder xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/folder_close"
- android:background="@drawable/box_launcher_top"
- android:gravity="left|center_vertical"
- android:textSize="14sp"
- android:textColor="#404040"
- android:textStyle="bold"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+<com.android.launcher2.Folder
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:orientation="vertical"
+ android:background="@drawable/portal_container_holo">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:background="@drawable/box_launcher_bottom">
+ <com.android.launcher2.CellLayout
+ android:id="@id/folder_content"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
- <GridView
- android:id="@id/folder_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:cacheColorHint="#ff333333"
- android:cacheColorHint="#ff333333"
+ android:hapticFeedbackEnabled="false"
+ launcher:widthGap="@dimen/workspace_width_gap"
+ launcher:heightGap="@dimen/workspace_height_gap"
+ launcher:cellWidth="@dimen/workspace_cell_width"
+ launcher:cellHeight="@dimen/workspace_cell_height"
+ launcher:xAxisStartPadding="0dip"
+ launcher:xAxisEndPadding="0dip"
+ launcher:yAxisStartPadding="8dip"
+ launcher:yAxisEndPadding="8dip"/>
- android:scrollbarAlwaysDrawVerticalTrack="true"
- android:scrollbarStyle="insideInset"
- android:drawSelectorOnTop="false"
- android:listSelector="@drawable/grid_selector"
-
- android:verticalSpacing="10dip"
- android:numColumns="5" />
- </FrameLayout>
-
-</com.android.launcher2.UserFolder>
+</com.android.launcher2.Folder>
diff --git a/res/layout-xlarge-land/application.xml b/res/layout-large-land/application.xml
similarity index 85%
rename from res/layout-xlarge-land/application.xml
rename to res/layout-large-land/application.xml
index 2598e5a..9393f7e 100644
--- a/res/layout-xlarge-land/application.xml
+++ b/res/layout-large-land/application.xml
@@ -15,4 +15,6 @@
-->
<com.android.launcher2.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/WorkspaceIcon.Landscape" />
+ style="@style/WorkspaceIcon.Landscape"
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout-large-land/workspace.xml b/res/layout-large-land/workspace.xml
new file mode 100644
index 0000000..e8ea782
--- /dev/null
+++ b/res/layout-large-land/workspace.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- The workspace contains 5 screens of cells -->
+<com.android.launcher2.Workspace
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:paddingTop="?android:attr/actionBarSize"
+ android:paddingBottom="10dp"
+ launcher:defaultScreen="2"
+ launcher:pageSpacing="@dimen/workspace_page_spacing_land">
+ <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>
\ No newline at end of file
diff --git a/res/layout-xlarge-land/workspace_screen.xml b/res/layout-large-land/workspace_screen.xml
similarity index 72%
copy from res/layout-xlarge-land/workspace_screen.xml
copy to res/layout-large-land/workspace_screen.xml
index e983b79..25b05e9 100644
--- a/res/layout-xlarge-land/workspace_screen.xml
+++ b/res/layout-large-land/workspace_screen.xml
@@ -24,9 +24,10 @@
launcher:cellWidth="@dimen/workspace_cell_width"
launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:widthGap="@dimen/workspace_width_gap"
- launcher:heightGap="@dimen/workspace_height_gap"
- launcher:yAxisStartPadding="15dip"
- launcher:yAxisEndPadding="15dip"
- launcher:xAxisStartPadding="25dip"
- launcher:xAxisEndPadding="25dip" />
+ launcher:widthGap="@dimen/workspace_width_gap_land"
+ launcher:heightGap="@dimen/workspace_height_gap_land"
+
+ launcher:xAxisStartPadding="@dimen/workspace_x_axis_start_padding_land"
+ launcher:xAxisEndPadding="@dimen/workspace_x_axis_end_padding_land"
+ launcher:yAxisStartPadding="@dimen/workspace_y_axis_start_padding_land"
+ launcher:yAxisEndPadding="@dimen/workspace_y_axis_end_padding_land" />
diff --git a/res/layout-xlarge-port/application.xml b/res/layout-large-port/application.xml
similarity index 100%
rename from res/layout-xlarge-port/application.xml
rename to res/layout-large-port/application.xml
diff --git a/res/layout-large-port/workspace.xml b/res/layout-large-port/workspace.xml
new file mode 100644
index 0000000..ccd7d33
--- /dev/null
+++ b/res/layout-large-port/workspace.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- The workspace contains 5 screens of cells -->
+<com.android.launcher2.Workspace
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:paddingTop="?android:attr/actionBarSize"
+ android:paddingBottom="10dp"
+ launcher:defaultScreen="2"
+ launcher:pageSpacing="@dimen/workspace_page_spacing_port">
+ <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>
\ No newline at end of file
diff --git a/res/layout-xlarge-land/workspace_screen.xml b/res/layout-large-port/workspace_screen.xml
similarity index 72%
rename from res/layout-xlarge-land/workspace_screen.xml
rename to res/layout-large-port/workspace_screen.xml
index e983b79..e33c612 100644
--- a/res/layout-xlarge-land/workspace_screen.xml
+++ b/res/layout-large-port/workspace_screen.xml
@@ -24,9 +24,10 @@
launcher:cellWidth="@dimen/workspace_cell_width"
launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:widthGap="@dimen/workspace_width_gap"
- launcher:heightGap="@dimen/workspace_height_gap"
- launcher:yAxisStartPadding="15dip"
- launcher:yAxisEndPadding="15dip"
- launcher:xAxisStartPadding="25dip"
- launcher:xAxisEndPadding="25dip" />
+ launcher:widthGap="@dimen/workspace_width_gap_port"
+ launcher:heightGap="@dimen/workspace_height_gap_port"
+
+ launcher:xAxisStartPadding="@dimen/workspace_x_axis_start_padding_port"
+ launcher:xAxisEndPadding="@dimen/workspace_x_axis_end_padding_port"
+ launcher:yAxisStartPadding="@dimen/workspace_y_axis_start_padding_port"
+ launcher:yAxisEndPadding="@dimen/workspace_y_axis_end_padding_port" />
diff --git a/res/layout-xlarge/all_apps_no_items_placeholder.xml b/res/layout-large/all_apps_no_items_placeholder.xml
similarity index 94%
rename from res/layout-xlarge/all_apps_no_items_placeholder.xml
rename to res/layout-large/all_apps_no_items_placeholder.xml
index 247870c..b766df1 100644
--- a/res/layout-xlarge/all_apps_no_items_placeholder.xml
+++ b/res/layout-large/all_apps_no_items_placeholder.xml
@@ -32,4 +32,5 @@
android:drawablePadding="0dip"
android:maxLines="2"
- android:fadingEdge="horizontal" />
+ android:fadingEdge="horizontal"
+ android:focusable="false" />
diff --git a/res/layout-xlarge/all_apps_paged_view_application.xml b/res/layout-large/all_apps_paged_view_application.xml
similarity index 89%
rename from res/layout-xlarge/all_apps_paged_view_application.xml
rename to res/layout-large/all_apps_paged_view_application.xml
index e5f07bf..16e5d82 100644
--- a/res/layout-xlarge/all_apps_paged_view_application.xml
+++ b/res/layout-large/all_apps_paged_view_application.xml
@@ -21,9 +21,12 @@
launcher:blurColor="#FF6B8CF0"
launcher:outlineColor="#FF8CD2FF"
+ style="@style/WorkspaceIcon.AllApps"
+
android:id="@+id/application_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
- style="@style/WorkspaceIcon.AllApps" />
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout-xlarge-land/all_apps_tabbed.xml b/res/layout-large/all_apps_tabbed.xml
similarity index 63%
rename from res/layout-xlarge-land/all_apps_tabbed.xml
rename to res/layout-large/all_apps_tabbed.xml
index d03a571..b00b3c3 100644
--- a/res/layout-xlarge-land/all_apps_tabbed.xml
+++ b/res/layout-large/all_apps_tabbed.xml
@@ -16,16 +16,23 @@
<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"
android:layout_height="match_parent">
+ <!-- The layout_width of this RelativeLayout gets overwritten in
+ AllAppsTabbed.onFinishInflate -->
<RelativeLayout
- android:layout_width="952dp"
+ android:id="@+id/all_apps_tab_bar"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@drawable/tab_unselected_holo">
- <TabWidget
+ <com.android.launcher2.FocusOnlyTabWidget
android:id="@android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -43,17 +50,28 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:visibility="invisible"/>
- <ImageView
+ android:visibility="invisible"
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true" />
+ <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"
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true" />
</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,13 +82,16 @@
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"
android:shadowDx="0.0"
android:shadowDy="0.0"
- android:shadowRadius="2.0" />
+ android:shadowRadius="2.0"
+
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true" />
</RelativeLayout>
<FrameLayout
android:id="@android:id/tabcontent"
@@ -80,14 +101,14 @@
android:id="@+id/all_apps_paged_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- launcher:cellCountX="7"
- launcher:cellCountY="5"
- launcher:pageLayoutWidthGap="36dp"
- launcher:pageLayoutHeightGap="6dp"
- launcher:pageLayoutPaddingTop="20dp"
- launcher:pageLayoutPaddingBottom="15dp"
- launcher:pageLayoutPaddingLeft="40dp"
- launcher:pageLayoutPaddingRight="40dp">
+ launcher:cellCountX="@integer/all_apps_view_cellCountX"
+ launcher:cellCountY="@integer/all_apps_view_cellCountY"
+ launcher:pageLayoutWidthGap="@dimen/all_apps_view_pageLayoutWidthGap"
+ launcher:pageLayoutHeightGap="@dimen/all_apps_view_pageLayoutHeightGap"
+ launcher:pageLayoutPaddingTop="@dimen/all_apps_view_pageLayoutPaddingTop"
+ launcher:pageLayoutPaddingBottom="@dimen/all_apps_view_pageLayoutPaddingBottom"
+ launcher:pageLayoutPaddingLeft="@dimen/all_apps_view_pageLayoutPaddingLeft"
+ launcher:pageLayoutPaddingRight="@dimen/all_apps_view_pageLayoutPaddingRight">
</com.android.launcher2.AllAppsPagedView>
</FrameLayout>
</LinearLayout>
diff --git a/res/layout-large/button_bar.xml b/res/layout-large/button_bar.xml
new file mode 100644
index 0000000..62115f7
--- /dev/null
+++ b/res/layout-large/button_bar.xml
@@ -0,0 +1,159 @@
+<?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"
+ android:focusable="false">
+
+ <!-- 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"
+ android:contentDescription="@string/accessibility_search_button" />
+
+ <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"
+ android:contentDescription="@string/accessibility_voice_search_button" />
+
+ <!-- AllApps icon -->
+ <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/all_apps_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"
+ android:contentDescription="@string/accessibility_all_apps_button" />
+
+ <ImageView
+ android:id="@+id/all_apps_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" />
+
+ <!-- Customize icon -->
+ <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:contentDescription="@string/accessibility_customize_button" />
+
+ <!-- Delete icon -->
+ <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"
+
+ android:focusable="true"
+ android:contentDescription="@string/accessibility_delete_button" />
+</RelativeLayout>
diff --git a/res/layout-large/customization_drawer.xml b/res/layout-large/customization_drawer.xml
new file mode 100644
index 0000000..d8db066
--- /dev/null
+++ b/res/layout-large/customization_drawer.xml
@@ -0,0 +1,54 @@
+<?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.CustomizeTrayTabHost
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- The layout_width of this RelativeLayout gets overwritten in
+ CustomizeTrayTabHost.onFinishInflate -->
+ <com.android.launcher2.FocusOnlyTabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="wrap_content"
+ 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">
+ <com.android.launcher2.CustomizePagedView
+ android:id="@+id/customization_drawer_tab_contents"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ launcher:wallpaperCellSpanX="@integer/customization_drawer_contents_wallpaperCellSpanX"
+ launcher:wallpaperCellCountX="@integer/customization_drawer_contents_wallpaperCellCountX"
+ launcher:widgetCellCountX="@integer/customization_drawer_contents_widgetCellCountX"
+ launcher:cellCountX="@integer/customization_drawer_contents_cellCountX"
+ launcher:cellCountY="@integer/customization_drawer_contents_cellCountY"
+ launcher:pageLayoutWidthGap="@dimen/customization_drawer_contents_pageLayoutWidthGap"
+ launcher:pageLayoutHeightGap="12dp"
+ launcher:pageLayoutPaddingTop="40dp"
+ launcher:pageLayoutPaddingBottom="25dp"
+ launcher:pageLayoutPaddingLeft="20dp"
+ launcher:pageLayoutPaddingRight="20dp"
+ launcher:pageLayoutMaxHeight="@dimen/customization_drawer_content_height" />
+ </FrameLayout>
+ </LinearLayout>
+</com.android.launcher2.CustomizeTrayTabHost>
\ No newline at end of file
diff --git a/res/layout-xlarge/customize_paged_view_item.xml b/res/layout-large/customize_paged_view_item.xml
similarity index 88%
rename from res/layout-xlarge/customize_paged_view_item.xml
rename to res/layout-large/customize_paged_view_item.xml
index b2e5f08..80d678e 100644
--- a/res/layout-xlarge/customize_paged_view_item.xml
+++ b/res/layout-large/customize_paged_view_item.xml
@@ -25,4 +25,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
- style="@style/WorkspaceIcon.Landscape" />
+ style="@style/WorkspaceIcon.Landscape"
+
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true" />
diff --git a/res/layout-xlarge/customize_paged_view_wallpaper.xml b/res/layout-large/customize_paged_view_wallpaper.xml
similarity index 85%
rename from res/layout-xlarge/customize_paged_view_wallpaper.xml
rename to res/layout-large/customize_paged_view_wallpaper.xml
index e3be86d..d6284c2 100644
--- a/res/layout-xlarge/customize_paged_view_wallpaper.xml
+++ b/res/layout-large/customize_paged_view_wallpaper.xml
@@ -18,22 +18,25 @@
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">
+ launcher:outlineColor="#FF8CD2FF"
+
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true">
<!-- The preview image for the wallpaper. -->
<ImageView
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 +44,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 +54,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-large/customize_paged_view_widget.xml
similarity index 86%
rename from res/layout-xlarge/customize_paged_view_widget.xml
rename to res/layout-large/customize_paged_view_widget.xml
index 3b95ebc..35791f5 100644
--- a/res/layout-xlarge/customize_paged_view_widget.xml
+++ b/res/layout-large/customize_paged_view_widget.xml
@@ -18,23 +18,25 @@
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">
+ launcher:outlineColor="#FF8CD2FF"
+
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true">
<!-- The icon of the widget. -->
<ImageView
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 +44,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 +54,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 +73,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/external_widget_drop_list_item.xml b/res/layout-large/external_widget_drop_list_item.xml
similarity index 100%
rename from res/layout-xlarge/external_widget_drop_list_item.xml
rename to res/layout-large/external_widget_drop_list_item.xml
diff --git a/res/layout-large/launcher.xml b/res/layout-large/launcher.xml
new file mode 100644
index 0000000..6a16eb5
--- /dev/null
+++ b/res/layout-large/launcher.xml
@@ -0,0 +1,50 @@
+<?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"
+ android:focusable="false">
+
+ <include layout="@layout/workspace"
+ android:id="@+id/workspace"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <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/all_apps_tabbed"
+ android:id="@+id/all_apps_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="top"
+ android:visibility="invisible" />
+
+ <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"
+ android:visibility="invisible" />
+</com.android.launcher2.DragLayer>
diff --git a/res/layout-xlarge/tab_widget_indicator.xml b/res/layout-large/tab_widget_indicator.xml
similarity index 89%
rename from res/layout-xlarge/tab_widget_indicator.xml
rename to res/layout-large/tab_widget_indicator.xml
index 7794e29..c09c853 100644
--- a/res/layout-xlarge/tab_widget_indicator.xml
+++ b/res/layout-large/tab_widget_indicator.xml
@@ -14,6 +14,6 @@
limitations under the License.
-->
-<TextView
+<com.android.launcher2.AccessibleTabView
xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/TabIndicator" />
+ style="@style/TabIndicator.Wide" />
diff --git a/res/layout-xlarge/wallpaper_chooser.xml b/res/layout-large/wallpaper_chooser.xml
similarity index 100%
rename from res/layout-xlarge/wallpaper_chooser.xml
rename to res/layout-large/wallpaper_chooser.xml
diff --git a/res/layout-xlarge/wallpaper_chooser_base.xml b/res/layout-large/wallpaper_chooser_base.xml
similarity index 100%
rename from res/layout-xlarge/wallpaper_chooser_base.xml
rename to res/layout-large/wallpaper_chooser_base.xml
diff --git a/res/layout-xlarge/wallpaper_item.xml b/res/layout-large/wallpaper_item.xml
similarity index 100%
rename from res/layout-xlarge/wallpaper_item.xml
rename to res/layout-large/wallpaper_item.xml
diff --git a/res/layout-port/all_apps_2d.xml b/res/layout-port/all_apps_2d.xml
deleted file mode 100644
index 081cba2..0000000
--- a/res/layout-port/all_apps_2d.xml
+++ /dev/null
@@ -1,63 +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.
--->
-
-<!-- Sapphire gets 2D all apps view -->
-<com.android.launcher2.AllApps2D
- xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:id="@+id/all_apps_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:padding="2dip"
- android:background="#FF000000">
-
- <GridView android:id="@+id/all_apps_2d_grid"
- android:tag="all_apps_2d_grid"
- android:scrollbars="none"
- android:drawSelectorOnTop="false"
- android:listSelector="@drawable/grid_selector"
- android:verticalSpacing="10dip"
- android:numColumns="4"
- android:fadingEdgeLength="48dip"
- android:cacheColorHint="#FF000000"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentBottom="true"
- android:layout_marginBottom="@dimen/button_bar_height"
- android:layout_marginTop="8dip"
- android:nextFocusDown="@+id/all_apps_2d_home"
- android:nextFocusUp="@null"
- android:nextFocusLeft="@null"
- android:nextFocusRight="@null"
- />
-
- <view
- class="com.android.launcher2.AllApps2D$HomeButton"
- android:id="@+id/all_apps_2d_home"
- android:tag="all_apps_2d_home"
- android:src="@drawable/home_button"
- android:background="#FF000000"
- android:layout_centerHorizontal="true"
- android:layout_alignParentBottom="true"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/button_bar_height"
- android:nextFocusUp="@+id/all_apps_2d_grid"
- android:nextFocusDown="@null"
- android:nextFocusLeft="@null"
- android:nextFocusRight="@null"
- />
-
-</com.android.launcher2.AllApps2D>
diff --git a/res/layout-port/application.xml b/res/layout-port/application.xml
index 32c1510..ddc8354 100644
--- a/res/layout-port/application.xml
+++ b/res/layout-port/application.xml
@@ -15,4 +15,6 @@
-->
<com.android.launcher2.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/WorkspaceIcon.Portrait" />
+ style="@style/WorkspaceIcon.Portrait"
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index b7c61d8..c7bcbb0 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -22,8 +22,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <include layout="@layout/all_apps" />
-
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher2.Workspace
android:id="@+id/workspace"
@@ -41,6 +39,12 @@
</com.android.launcher2.Workspace>
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
<ImageView
android:id="@+id/previous_screen"
android:layout_width="93dip"
@@ -89,39 +93,26 @@
android:layout_width="fill_parent"
android:layout_height="@dimen/button_bar_height"
android:layout_gravity="bottom|center_horizontal"
- android:paddingTop="2dip"
- >
-
+ android:paddingTop="2dip">
+ <ImageView
+ android:id="@+id/hotseat_left"
+ style="@style/HotseatButton.Left"
+ android:layout_toLeftOf="@id/all_apps_button"
+ android:src="@drawable/hotseat_phone"
+ android:onClick="launchHotSeat" />
<com.android.launcher2.HandleView
style="@style/HotseatButton"
android:id="@+id/all_apps_button"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
-
android:src="@drawable/all_apps_button"
- launcher:direction="horizontal"
- />
-
- <ImageView
- android:id="@+id/hotseat_left"
- style="@style/HotseatButton.Left"
- android:layout_toLeftOf="@id/all_apps_button"
-
- android:src="@drawable/hotseat_phone"
-
- android:onClick="launchHotSeat"
- />
-
+ launcher:direction="horizontal" />
<ImageView
android:id="@+id/hotseat_right"
style="@style/HotseatButton.Right"
android:layout_toRightOf="@id/all_apps_button"
-
android:src="@drawable/hotseat_browser"
-
- android:onClick="launchHotSeat"
- />
-
+ android:onClick="launchHotSeat" />
</RelativeLayout>
</com.android.launcher2.DragLayer>
diff --git a/res/layout-port/user_folder.xml b/res/layout-port/user_folder.xml
index 0e6df66..0d383c1 100644
--- a/res/layout-port/user_folder.xml
+++ b/res/layout-port/user_folder.xml
@@ -14,38 +14,27 @@
limitations under the License.
-->
-<com.android.launcher2.UserFolder xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/folder_close"
- android:background="@drawable/box_launcher_top"
- android:gravity="left|center_vertical"
- android:textSize="14sp"
- android:textColor="#404040"
- android:textStyle="bold"
+<com.android.launcher2.Folder
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:orientation="vertical"
+ android:background="@drawable/portal_container_holo">
+
+ <com.android.launcher2.CellLayout
+ android:id="@id/folder_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="match_parent"
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:background="@drawable/box_launcher_bottom">
- <GridView
- android:id="@id/folder_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:cacheColorHint="#ff333333"
- android:cacheColorHint="#ff333333"
+ android:hapticFeedbackEnabled="false"
+ launcher:widthGap="@dimen/workspace_width_gap"
+ launcher:heightGap="@dimen/workspace_height_gap"
+ launcher:cellWidth="@dimen/workspace_cell_width"
+ launcher:cellHeight="@dimen/workspace_cell_height"
+ launcher:xAxisStartPadding="0dip"
+ launcher:xAxisEndPadding="0dip"
+ launcher:yAxisStartPadding="8dip"
+ launcher:yAxisEndPadding="8dip"/>
- android:scrollbarAlwaysDrawVerticalTrack="true"
- android:scrollbarStyle="insideInset"
- android:drawSelectorOnTop="false"
- android:listSelector="@drawable/grid_selector"
-
- android:verticalSpacing="10dip"
- android:numColumns="4" />
- </FrameLayout>
-
-</com.android.launcher2.UserFolder>
+</com.android.launcher2.Folder>
diff --git a/res/layout-xlarge-land/customization_drawer.xml b/res/layout-xlarge-land/customization_drawer.xml
deleted file mode 100644
index 50e7b66..0000000
--- a/res/layout-xlarge-land/customization_drawer.xml
+++ /dev/null
@@ -1,32 +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.CustomizePagedView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
-
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- launcher:wallpaperCellSpanX="3"
- launcher:wallpaperCellCountX="12"
- launcher:widgetCellCountX="14"
- launcher:cellCountX="8"
- launcher:cellCountY="3"
- launcher:pageLayoutWidthGap="32dp"
- launcher:pageLayoutHeightGap="12dp"
- launcher:pageLayoutPaddingTop="40dp"
- launcher:pageLayoutPaddingBottom="25dp"
- launcher:pageLayoutPaddingLeft="20dp"
- launcher:pageLayoutPaddingRight="20dp" />
\ No newline at end of file
diff --git a/res/layout-xlarge-land/launcher.xml b/res/layout-xlarge-land/launcher.xml
deleted file mode 100644
index 957327e..0000000
--- 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
deleted file mode 100644
index 269fa12..0000000
--- a/res/layout-xlarge-port/all_apps_tabbed.xml
+++ /dev/null
@@ -1,94 +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.AllAppsTabbed
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <RelativeLayout
- android:layout_width="700dp"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/tab_unselected_holo">
- <TabWidget
- android:id="@android:id/tabs"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:tabStripEnabled="false" />
- <FrameLayout
- android:id="@+id/market_info_frame"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true">
- <com.android.launcher2.ApplicationInfoDropTarget
- android:id="@+id/all_apps_info_target"
- android:drawableRight="@drawable/ic_home_info_holo_dark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:visibility="invisible"/>
- <ImageView
- android:id="@+id/market_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:onClick="onClickAppMarketButton"/>
- </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"
- android:layout_height="wrap_content"
- android:layout_toLeftOf="@id/market_info_frame"
- android:layout_centerVertical="true"
- android:visibility="invisible"
- android:paddingRight="22dp"
- launcher:direction="horizontal"
-
- 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" />
- </RelativeLayout>
- <FrameLayout
- android:id="@android:id/tabcontent"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <com.android.launcher2.AllAppsPagedView
- android:id="@+id/all_apps_paged_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- launcher:cellCountX="5"
- launcher:cellCountY="7"
- launcher:pageLayoutWidthGap="36dp"
- launcher:pageLayoutHeightGap="36dp"
- launcher:pageLayoutPaddingTop="25dp"
- launcher:pageLayoutPaddingBottom="10dp"
- launcher:pageLayoutPaddingLeft="20dp"
- launcher:pageLayoutPaddingRight="20dp">
- </com.android.launcher2.AllAppsPagedView>
- </FrameLayout>
- </LinearLayout>
-</com.android.launcher2.AllAppsTabbed>
diff --git a/res/layout-xlarge-port/customization_drawer.xml b/res/layout-xlarge-port/customization_drawer.xml
deleted file mode 100644
index a1bc7cc..0000000
--- a/res/layout-xlarge-port/customization_drawer.xml
+++ /dev/null
@@ -1,32 +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.CustomizePagedView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
-
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- launcher:wallpaperCellSpanX="3"
- launcher:wallpaperCellCountX="9"
- launcher:widgetCellCountX="10"
- launcher:cellCountX="5"
- launcher:cellCountY="3"
- launcher:pageLayoutWidthGap="36dp"
- launcher:pageLayoutHeightGap="12dp"
- launcher:pageLayoutPaddingTop="40dp"
- launcher:pageLayoutPaddingBottom="25dp"
- launcher:pageLayoutPaddingLeft="20dp"
- launcher:pageLayoutPaddingRight="20dp" />
diff --git a/res/layout-xlarge-port/launcher.xml b/res/layout-xlarge-port/launcher.xml
deleted file mode 100644
index a8087f4..0000000
--- 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-port/tab_widget_indicator.xml b/res/layout-xlarge-port/tab_widget_indicator.xml
deleted file mode 100644
index b113b7b..0000000
--- a/res/layout-xlarge-port/tab_widget_indicator.xml
+++ /dev/null
@@ -1,19 +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.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/TabIndicator.Portrait" />
diff --git a/res/layout-xlarge-port/workspace_screen.xml b/res/layout-xlarge-port/workspace_screen.xml
deleted file mode 100644
index 406441d..0000000
--- a/res/layout-xlarge-port/workspace_screen.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.launcher2.CellLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
-
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:hapticFeedbackEnabled="false"
-
- launcher:cellWidth="@dimen/workspace_cell_width"
- launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:widthGap="@dimen/workspace_width_gap"
- launcher:heightGap="@dimen/workspace_height_gap"
- launcher:yAxisStartPadding="25dip"
- launcher:yAxisEndPadding="25dip"
- launcher:xAxisStartPadding="15dip"
- launcher:xAxisEndPadding="15dip"/>
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
deleted file mode 100644
index fadf736..0000000
--- a/res/layout/all_apps.xml
+++ /dev/null
@@ -1,20 +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.
--->
-
-<!-- switch to all_apps_3d on devices that support RenderScript -->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <include layout="@layout/all_apps_2d" />
-</merge>
diff --git a/res/layout/all_apps_3d.xml b/res/layout/all_apps_3d.xml
deleted file mode 100644
index 7975df4..0000000
--- a/res/layout/all_apps_3d.xml
+++ /dev/null
@@ -1,33 +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.
--->
-
-<!-- Replace with AllAppsView to use 2D version -->
-<com.android.launcher2.AllApps3D
- xmlns:android="http://schemas.android.com/apk/res/android"
-
- android:id="@+id/all_apps_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
-
- android:scrollbarStyle="outsideInset"
- android:drawSelectorOnTop="false"
- android:listSelector="@drawable/grid_selector"
- android:verticalSpacing="10dip"
- android:numColumns="4"
- android:fadingEdgeLength="20dip"
- android:padding="2dip"
- android:cacheColorHint="#FF000000"
- />
diff --git a/res/layout/application_list.xml b/res/layout/application_list.xml
deleted file mode 100644
index b515c9e..0000000
--- a/res/layout/application_list.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
- * Copyright (c) 2008, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
-
- android:paddingLeft="10dip"
-
- android:orientation="horizontal">
-
- <ImageView android:id="@+id/icon"
- android:layout_width="@android:dimen/app_icon_size"
- android:layout_height="@android:dimen/app_icon_size"
- android:layout_gravity="center_vertical"
- android:scaleType="fitCenter" />
-
- <LinearLayout
- android:layout_width="0dip"
- android:layout_weight="1.0"
- android:layout_height="match_parent"
-
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
-
- android:orientation="vertical"
- android:gravity="center_vertical">
-
- <TextView android:id="@+id/name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
-
- android:singleLine="true"
- android:ellipsize="end"
-
- android:textAppearance="?android:attr/textAppearanceLarge" />
-
- <TextView android:id="@+id/description"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
-
- android:layout_below="@id/name"
- android:layout_alignLeft="@id/name"
-
- android:singleLine="true"
- android:ellipsize="end"
-
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorSecondary" />
-
- </LinearLayout>
-
-</LinearLayout>
diff --git a/res/layout-xlarge/all_apps_paged_view_application.xml b/res/layout/apps_customize_application.xml
similarity index 84%
copy from res/layout-xlarge/all_apps_paged_view_application.xml
copy to res/layout/apps_customize_application.xml
index e5f07bf..4f36326 100644
--- a/res/layout-xlarge/all_apps_paged_view_application.xml
+++ b/res/layout/apps_customize_application.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -18,12 +18,15 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
- launcher:blurColor="#FF6B8CF0"
- launcher:outlineColor="#FF8CD2FF"
+ style="@style/WorkspaceIcon.AllApps"
android:id="@+id/application_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
- style="@style/WorkspaceIcon.AllApps" />
+ launcher:blurColor="#FF6B8CF0"
+ launcher:outlineColor="#FF8CD2FF"
+
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
new file mode 100644
index 0000000..05884ef
--- /dev/null
+++ b/res/layout/apps_customize_pane.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.launcher2.AppsCustomizeTabHost
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/apps_customize_bg_gradient">
+ <!-- The layout_width of the tab bar gets overriden to align the content
+ with the text in the tabs in AppsCustomizeTabHost. -->
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/apps_customize_tab_bar_height"
+ android:layout_gravity="center_horizontal">
+ <com.android.launcher2.FocusOnlyTabWidget
+ android:id="@android:id/tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="left"
+ android:background="@drawable/tab_unselected_holo"
+ android:tabStripEnabled="false" />
+ <FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="right">
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:visibility="gone">
+ <com.android.launcher2.ApplicationInfoDropTarget
+ android:id="@+id/all_apps_info_target"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:drawableLeft="@drawable/ic_home_info_holo_dark"
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true"
+ android:visibility="gone" />
+ <com.android.launcher2.DeleteZone
+ style="@style/DeleteZone"
+ android:id="@+id/all_apps_delete_zone"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true"
+ android:visibility="gone"
+ launcher:direction="horizontal" />
+ </LinearLayout>
+ <TextView
+ style="@style/MarketButton"
+ android:id="@+id/market_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:gravity="center"
+ android:background="@drawable/tab_widget_indicator_selector"
+ android:focusable="true" />
+ </FrameLayout>
+ </FrameLayout>
+ <FrameLayout
+ android:id="@android:id/tabcontent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <com.android.launcher2.AppsCustomizePagedView
+ android:id="@+id/apps_customize_pane_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ launcher:cellCountX="@integer/all_apps_view_cellCountX"
+ launcher:cellCountY="@integer/all_apps_view_cellCountY"
+ launcher:pageLayoutWidthGap="@dimen/all_apps_view_pageLayoutWidthGap"
+ launcher:pageLayoutHeightGap="@dimen/all_apps_view_pageLayoutHeightGap"
+ launcher:pageLayoutPaddingTop="@dimen/all_apps_view_pageLayoutPaddingTop"
+ launcher:pageLayoutPaddingBottom="@dimen/all_apps_view_pageLayoutPaddingBottom"
+ launcher:pageLayoutPaddingLeft="@dimen/all_apps_view_pageLayoutPaddingLeft"
+ launcher:pageLayoutPaddingRight="@dimen/all_apps_view_pageLayoutPaddingRight"
+ launcher:widgetCellWidthGap="@dimen/apps_customize_widget_cell_width_gap"
+ launcher:widgetCellHeightGap="@dimen/apps_customize_widget_cell_height_gap"
+ launcher:widgetCountX="@integer/apps_customize_widget_cell_count_x"
+ launcher:widgetCountY="@integer/apps_customize_widget_cell_count_y"
+ launcher:wallpaperCountX="@integer/apps_customize_wallpaper_cell_count_x"
+ launcher:wallpaperCountY="@integer/apps_customize_wallpaper_cell_count_y" />
+ </FrameLayout>
+ </LinearLayout>
+</com.android.launcher2.AppsCustomizeTabHost>
diff --git a/res/layout-xlarge/customize_paged_view_wallpaper.xml b/res/layout/apps_customize_wallpaper.xml
similarity index 69%
copy from res/layout-xlarge/customize_paged_view_wallpaper.xml
copy to res/layout/apps_customize_wallpaper.xml
index e3be86d..d93825f 100644
--- a/res/layout-xlarge/customize_paged_view_wallpaper.xml
+++ b/res/layout/apps_customize_wallpaper.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -17,23 +17,25 @@
xmlns:android="http://schemas.android.com/apk/res/android"
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_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
android:orientation="vertical"
launcher:blurColor="#FF6B8CF0"
- launcher:outlineColor="#FF8CD2FF">
+ launcher:outlineColor="#FF8CD2FF"
- <!-- The preview image for the wallpaper. -->
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true">
+
+ <!-- The wallpaper preview. -->
<ImageView
- android:id="@+id/wallpaper_preview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
+ android:id="@+id/widget_preview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingBottom="10dp"
+ android:adjustViewBounds="true"
android:scaleType="fitStart" />
<!-- The divider image. -->
@@ -41,16 +43,18 @@
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" />
- <!-- The name of the wallpaper -->
+ <!-- The name of the wallpaper. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/wallpaper_name"
+ android:id="@+id/widget_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="left"
+ android:layout_weight="0"
+ android:gravity="left|bottom"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
diff --git a/res/layout-xlarge/customize_paged_view_widget.xml b/res/layout/apps_customize_widget.xml
similarity index 71%
copy from res/layout-xlarge/customize_paged_view_widget.xml
copy to res/layout/apps_customize_widget.xml
index 3b95ebc..9d0764c 100644
--- a/res/layout-xlarge/customize_paged_view_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -17,41 +17,34 @@
xmlns:android="http://schemas.android.com/apk/res/android"
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_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
android:orientation="vertical"
launcher:blurColor="#FF6B8CF0"
- launcher:outlineColor="#FF8CD2FF">
+ launcher:outlineColor="#FF8CD2FF"
+
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true">
<!-- The icon of the widget. -->
<ImageView
android:id="@+id/widget_preview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="1.0"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingBottom="5dp"
+ android:adjustViewBounds="true"
android:scaleType="fitStart" />
- <!-- The divider image. -->
- <ImageView
- android:id="@+id/divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingTop="10dp"
- android:paddingBottom="10dp"
- android:src="@drawable/widget_divider" />
-
<!-- The name of the widget. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="left"
+ android:layout_weight="0"
+ android:gravity="left|bottom"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
@@ -69,7 +62,8 @@
android:id="@+id/widget_dims"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="left"
+ android:layout_weight="0"
+ android:gravity="left|bottom"
android:textColor="#FF999999"
android:textSize="14sp"
diff --git a/res/layout-xlarge/tab_widget_indicator.xml b/res/layout/tab_widget_indicator.xml
similarity index 87%
copy from res/layout-xlarge/tab_widget_indicator.xml
copy to res/layout/tab_widget_indicator.xml
index 7794e29..b3694fe 100644
--- a/res/layout-xlarge/tab_widget_indicator.xml
+++ b/res/layout/tab_widget_indicator.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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.
@@ -14,6 +14,6 @@
limitations under the License.
-->
-<TextView
+<com.android.launcher2.AccessibleTabView
xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/TabIndicator" />
diff --git a/res/values-ar-xlarge/strings.xml b/res/values-ar-large/strings.xml
similarity index 100%
rename from res/values-ar-xlarge/strings.xml
rename to res/values-ar-large/strings.xml
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index f872444..cb4c1f3 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"المجلدات"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"المزيد"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"الخلفيات"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"اختصارات التطبيقات"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"اختصارات التطبيقات"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"ستكون هذه علامة تبويب الخلفيات"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"الكل"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"التطبيقات"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"الألعاب"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"منزّلة"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"تطبيقاتي"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"لم يتم العثور على ألعاب"</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"لم يُعثر على تطبيقات منزّلة"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"بحث"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"البحث الصوتي"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"التطبيقات"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"تخصيص"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"إزالة"</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-xlarge/strings.xml b/res/values-bg-large/strings.xml
similarity index 100%
rename from res/values-bg-xlarge/strings.xml
rename to res/values-bg-large/strings.xml
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 2686210..0f0f07d 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Папки"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Още"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Тапети"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Преки пътища на приложения"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Преки пътища на приложения"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Това ще бъде разделът с тапети"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Всички"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Приложения"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Игри"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Изтеглени"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Моите приложения"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Няма намерени игри."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Няма изтеглени приложения."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Търсене"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Гласово търсене"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Приложения"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Персонализиране"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Премахване"</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-xlarge/strings.xml b/res/values-ca-large/strings.xml
similarity index 100%
rename from res/values-ca-xlarge/strings.xml
rename to res/values-ca-large/strings.xml
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 8051418..85058ba 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Carpetes"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Més"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Empaperats"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Dreceres d\'aplicacions"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Dreceres d\'aplicacions"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Aquesta serà la pestanya dels empaperats"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Totes"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicacions"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Jocs"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Baixat"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"No s\'ha trobat cap aplicació baixada."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Cerca"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Cerca per veu"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicacions"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalitza"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Elimina"</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-xlarge/strings.xml b/res/values-cs-large/strings.xml
similarity index 100%
rename from res/values-cs-xlarge/strings.xml
rename to res/values-cs-large/strings.xml
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index b61068e..af04cb6 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Složky"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Další"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapety"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Zástupci aplikací"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Zástupci aplikací"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Toto bude karta Tapety"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Vše"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikace"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Hry"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Stažené"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikace"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Nenalezeny žádné hry."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Žádné stažené aplikace."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Hledat"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Hlasové vyhledávání"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplikace"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizovat"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Odebrat"</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-xlarge/strings.xml b/res/values-da-large/strings.xml
similarity index 100%
rename from res/values-da-xlarge/strings.xml
rename to res/values-da-large/strings.xml
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 66386a6..10bd77f 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mapper"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Flere"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapeter"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Programgenvej"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Programgenveje"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dette er fanen for tapeter"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Programmer"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Spil"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Downloadet"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Søg"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Stemmesøgning"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Programmer"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Tilpas"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Fjern"</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-xlarge/strings.xml b/res/values-de-large/strings.xml
similarity index 100%
rename from res/values-de-xlarge/strings.xml
rename to res/values-de-large/strings.xml
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index e035b27..87124a3 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -25,20 +25,21 @@
<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">"Die Anwendung ist nicht installiert."</string>
+ <string name="activity_not_found" msgid="5591731020063337696">"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>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mehr"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Hintergründe"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"App-Verknüpfungen"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"App-Verknüpfungen"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dies ist der Tab \"Hintergründe\""</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Spiele"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Heruntergeladen"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Meine Apps"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Keine Spiele gefunden."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Keine heruntergeladenen Apps 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>
@@ -46,7 +47,7 @@
<string name="rename_action" msgid="6016003384693240896">"OK"</string>
<string name="cancel_action" msgid="3811860427489435048">"Abbrechen"</string>
<string name="menu_item_add_item" msgid="6233177331075781114">"Zum Startbildschirm hinzufügen"</string>
- <string name="group_applications" msgid="4118484163419674240">"Anwendungen"</string>
+ <string name="group_applications" msgid="4118484163419674240">"Apps"</string>
<string name="group_shortcuts" msgid="9133529424900391877">"Verknüpfungen"</string>
<string name="group_folder" msgid="5143593791798929193">"Neuer Ordner"</string>
<string name="group_live_folders" msgid="2664945399140647217">"Ordner"</string>
@@ -62,10 +63,16 @@
<string name="title_select_shortcut" msgid="2858897527672831763">"Tastenkürzel auswählen"</string>
<string name="title_select_application" msgid="8031072293115454221">"Anwendung auswählen"</string>
<string name="title_select_live_folder" msgid="3753447798805166749">"Ordner auswählen"</string>
- <string name="all_apps_button_label" msgid="2578400570124163469">"Anwendungen"</string>
+ <string name="all_apps_button_label" msgid="2578400570124163469">"Apps"</string>
<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="accessibility_search_button" msgid="816822994629942611">"Suchen"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Sprachsuche"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Apps"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Anpassen"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Entfernen"</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-xlarge/strings.xml b/res/values-el-large/strings.xml
similarity index 100%
rename from res/values-el-xlarge/strings.xml
rename to res/values-el-large/strings.xml
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index e8b518fe..59ef926 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Φάκελοι"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Περισσότερα"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Ταπετσαρίες"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Συντομεύσεις Εφαρμογών"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Συντομεύσεις εφαρμογών"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Αυτή θα είναι η καρτέλα ταπετσαριών"</string>
- <string name="all_apps_tab_all" msgid="2942727589595027258">"Κάθε ηλικία"</string>
+ <string name="all_apps_tab_all" msgid="2942727589595027258">"Όλες"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Εφαρμογές"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Παιχνίδια"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Η λήψη ολοκληρώθηκε"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Αναζήτηση"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Φωνητική αναζήτηση"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Εφαρμογές"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Προσαρμογή"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Κατάργηση"</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-xlarge/strings.xml b/res/values-en-rGB-large/strings.xml
similarity index 75%
rename from res/values-en-rGB-xlarge/strings.xml
rename to res/values-en-rGB-large/strings.xml
index 60042b2..276ab94 100644
--- a/res/values-en-rGB-xlarge/strings.xml
+++ b/res/values-en-rGB-large/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="wallpaper_dialog_title" msgid="5764793286524787718">"Select wallpaper"</string>
- <string name="wallpaper_chooser_empty" msgid="7358237455389125747">"No wallpaper available"</string>
- <string name="wallpaper_cancel" msgid="6502936522490675611">"Cancel"</string>
+ <string name="wallpaper_dialog_title" msgid="8362944198120933329">"Select wallpaper"</string>
+ <string name="wallpaper_chooser_empty" msgid="6543937491391049913">"No wallpaper available"</string>
+ <string name="wallpaper_cancel" msgid="5942480248232268588">"Cancel"</string>
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index f15a01c..f07752c 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Folders"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"More"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Wallpaper"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"App Shortcuts"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"App shortcuts"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"This will be the wallpaper tab"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"All"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Games"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Downloaded"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Search"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Voice Search"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Applications"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Customise"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Remove"</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-xlarge/strings.xml b/res/values-es-large/strings.xml
similarity index 100%
rename from res/values-es-xlarge/strings.xml
rename to res/values-es-large/strings.xml
diff --git a/res/values-es-rUS-xlarge/strings.xml b/res/values-es-rUS-large/strings.xml
similarity index 100%
rename from res/values-es-rUS-xlarge/strings.xml
rename to res/values-es-rUS-large/strings.xml
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index ede2003..46781f1 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Carpetas"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Más"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Papeles tapiz"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Accesos directos a aplicaciones"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Accesos directos a aplicaciones"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ésta será la pestaña para los papeles tapiz"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Todos"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicaciones"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Juegos"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Descargado"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Buscar"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Búsqueda por voz"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicaciones"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizar"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Eliminar"</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>
@@ -82,7 +89,7 @@
<string name="permlab_install_shortcut" msgid="1201690825493376489">"instalar accesos directos"</string>
<string name="permdesc_install_shortcut" msgid="7429365847558984148">"Permite a una aplicación agregar accesos directos sin intervención del usuario."</string>
<string name="permlab_uninstall_shortcut" msgid="7696645932555926449">"desinstalar papel tapiz"</string>
- <string name="permdesc_uninstall_shortcut" msgid="959972195916090900">"Permite a una aplicación suprimir accesos directos sin intervención del usuario."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="959972195916090900">"Permite a una aplicación eliminar accesos directos sin intervención del usuario."</string>
<string name="permlab_read_settings" msgid="3452408290738106747">"leer configuración y accesos directos de la página principal"</string>
<string name="permdesc_read_settings" msgid="8377434937176025492">"Permite a una aplicación leer la configuración y los accesos directos de la página principal."</string>
<string name="permlab_write_settings" msgid="1360567537236705628">"escribir configuración y accesos directos de la página principal"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index bca032c..3d162b9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Carpetas"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Más"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Fondos de pantalla"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Accesos directos de aplicaciones"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Accesos directos de aplicaciones"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Será la carpeta de fondos de pantalla."</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Todas las aplicaciones"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicaciones"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Juegos"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Descargadas"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mis aplicaciones"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"No hay juegos."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Sin aplicaciones descargadas"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Buscar"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Búsqueda por voz"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicaciones"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizar"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Eliminar"</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-xlarge/strings.xml b/res/values-fa-large/strings.xml
similarity index 100%
rename from res/values-fa-xlarge/strings.xml
rename to res/values-fa-large/strings.xml
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 4e2b7d3..1170d79 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"پوشه ها"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"بیشتر"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"تصاویر زمینه"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"میانبرهای برنامه کاربردی"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"میانبرهای برنامه"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"این برگه تصاویر زمینه خواهد بود"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"همه"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"برنامه های کاربردی"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"بازی ها"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"دانلود شد"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"برنامه های من"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"هیچ بازی پیدا نشد."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"هیچ برنامه دانلود شده ای پیدا نشد."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"جستجو"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"جستجوی صوتی"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"برنامه های کاربردی"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"سفارشی کردن"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"حذف"</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-xlarge/strings.xml b/res/values-fi-large/strings.xml
similarity index 100%
rename from res/values-fi-xlarge/strings.xml
rename to res/values-fi-large/strings.xml
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 5ea5af6..4e40e56 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Kansiot"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Lisää"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Taustakuvat"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Sovelluspikakuvakkeet"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Sovelluspikakuvakkeet"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Tämä on taustakuvavälilehti"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Kaikki"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Sovellukset"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Pelit"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Ladatut"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Omat sovellukset"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Ei pelejä."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Ei ladattuja sovelluksia."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Haku"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Äänihaku"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Sovellukset"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Muokkaa"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"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-xlarge/strings.xml b/res/values-fr-large/strings.xml
similarity index 100%
rename from res/values-fr-xlarge/strings.xml
rename to res/values-fr-large/strings.xml
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 170dcfd..83d71d8 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Dossiers"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Plus"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Fonds d\'écran"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Raccourcis des applications"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Raccourcis applications"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Onglet des fonds d\'écran"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Toutes"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Applications"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Jeux"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Téléchargées"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Aucune application téléchargée trouvée"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Rechercher"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Recherche vocale"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Applications"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personnaliser"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Supprimer"</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-xlarge/strings.xml b/res/values-hr-large/strings.xml
similarity index 100%
rename from res/values-hr-xlarge/strings.xml
rename to res/values-hr-large/strings.xml
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c93d64b..34487a5 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mape"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Više"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Pozadinske slike"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Prečaci aplikacija"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Prečaci aplikacija"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ovo će biti kartica pozadinske slike"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Sve"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikacije"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Igre"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Preuzeto"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikacije"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Igre nisu pronađene."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nema preuzetih aplikacija"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Pretraži"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Glasovno pretraživanje"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplikacije"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Prilagodi"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Ukloni"</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-xlarge/strings.xml b/res/values-hu-large/strings.xml
similarity index 100%
rename from res/values-hu-xlarge/strings.xml
rename to res/values-hu-large/strings.xml
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index af42d2d..dfa267b 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mappák"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Egyebek"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Háttérképek"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Alkalmazás-parancsikonok"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Alkalmazás-parancsikonok"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ez lesz a háttérképek lapja"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Összes"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Alkalmazások"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Játékok"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Letöltött"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nincs letöltött alk."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Keresés"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Hangalapú keresés"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Alkalmazások"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Személyre szabás"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Törlé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-xlarge/strings.xml b/res/values-in-large/strings.xml
similarity index 100%
rename from res/values-in-xlarge/strings.xml
rename to res/values-in-large/strings.xml
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 22b5dde..d9a6d28 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Map"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Lainnya"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Wallpaper"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Pintasan App"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Pintasan apl"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ini akan menjadi tab wallpaper"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Semua"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Permainan"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Diunduh"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Apl saya"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Tidak ditemukan permainan."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Tidak ada aplikasi yang diunduh."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Telusuri"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Penelusuran Suara"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplikasi"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Ubahsuaikan"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Hapus"</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-xlarge/strings.xml b/res/values-it-large/strings.xml
similarity index 75%
rename from res/values-it-xlarge/strings.xml
rename to res/values-it-large/strings.xml
index e667b75..249f880 100644
--- a/res/values-it-xlarge/strings.xml
+++ b/res/values-it-large/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="wallpaper_dialog_title" msgid="5764793286524787718">"Seleziona sfondo"</string>
- <string name="wallpaper_chooser_empty" msgid="7358237455389125747">"Nessuno sfondo disponibile"</string>
- <string name="wallpaper_cancel" msgid="6502936522490675611">"Annulla"</string>
+ <string name="wallpaper_dialog_title" msgid="8362944198120933329">"Seleziona sfondo"</string>
+ <string name="wallpaper_chooser_empty" msgid="6543937491391049913">"Nessuno sfondo disponibile"</string>
+ <string name="wallpaper_cancel" msgid="5942480248232268588">"Annulla"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 62112b4..0a1f4fd 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Cartelle"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Altro"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Sfondi"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Scorciatoie applicazioni"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Scorciatoie applicazioni"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Questa sarà la scheda degli sfondi"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Tutte"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Applicazioni"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Giochi"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Scaricate"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Le mie applicazioni"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Nessun gioco trovato."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nessuna applicazione scaricata trovata."</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>
@@ -56,7 +57,7 @@
<string name="add_clock" msgid="2337943840175865746">"Orologio"</string>
<string name="add_photo_frame" msgid="3154058437359487954">"Cornice immagini"</string>
<string name="out_of_space" msgid="8365249326091984698">"Spazio nella schermata Home esaurito."</string>
- <string name="shortcut_installed" msgid="7071557296331322355">"Scoriciatoia \"<xliff:g id="NAME">%s</xliff:g>\" creata."</string>
+ <string name="shortcut_installed" msgid="7071557296331322355">"Scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" creata."</string>
<string name="shortcut_uninstalled" msgid="2129499669449749995">"La scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" è stata rimossa."</string>
<string name="shortcut_duplicate" msgid="4757756326465060694">"Scorciatoia \"<xliff:g id="NAME">%s</xliff:g>\" già presente."</string>
<string name="title_select_shortcut" msgid="2858897527672831763">"Seleziona scorciatoia"</string>
@@ -66,6 +67,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Cerca"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Ricerca vocale"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Applicazioni"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizza"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Rimuovi"</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-xlarge/strings.xml b/res/values-iw-large/strings.xml
similarity index 100%
rename from res/values-iw-xlarge/strings.xml
rename to res/values-iw-large/strings.xml
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index cb80a49..535cf73 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"תיקיות"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"עוד"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"טפטים"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"קיצורי דרך של יישומים"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"קיצורי דרך של יישומים"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"זו תהיה כרטיסיית הטפטים"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"הכל"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"יישומים"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"משחקים"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"מהורדות"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"חפש"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"חיפוש קולי"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"יישומים"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"התאם אישית"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"הסר"</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-xlarge/strings.xml b/res/values-ja-large/strings.xml
similarity index 100%
rename from res/values-ja-xlarge/strings.xml
rename to res/values-ja-large/strings.xml
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 9d45452..4b2d31d 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"フォルダ"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"その他"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"壁紙"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"アプリのショートカット"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"アプリのショートカット"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"ここが壁紙タブになります"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"すべて"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"アプリ"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"ゲーム"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"ダウンロード済み"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"マイアプリ"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"ゲームなし"</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"ダウンロードしたアプリケーションは見つかりません。"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"検索"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"音声検索"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"アプリケーション"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"カスタマイズ"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"削除"</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-xlarge/strings.xml b/res/values-ko-large/strings.xml
similarity index 100%
rename from res/values-ko-xlarge/strings.xml
rename to res/values-ko-large/strings.xml
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 5bd3246..9f6ee4a 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"폴더"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"더보기"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"배경화면"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"앱 바로가기"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"앱 바로가기"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"배경화면 탭이 됩니다."</string>
- <string name="all_apps_tab_all" msgid="2942727589595027258">"모두"</string>
+ <string name="all_apps_tab_all" msgid="2942727589595027258">"전체"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"애플리케이션"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"게임"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"다운로드됨"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"내 애플리케이션"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"게임이 없습니다."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"다운로드한 애플리케이션이 없습니다."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"검색"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"음성 검색"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"애플리케이션"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"맞춤설정"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"삭제"</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-land/dimens.xml b/res/values-land/dimens.xml
index 159cbb4..e1b0214 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -17,5 +17,23 @@
<resources>
<dimen name="workspace_cell_width">106dip</dimen>
<dimen name="workspace_cell_height">74dip</dimen>
+ <dimen name="folder_cell_width">100dip</dimen>
+ <dimen name="folder_cell_height">74dip</dimen>
<dimen name="button_bar_height">62dip</dimen>
+
+ <integer name="all_apps_view_cellCountX">6</integer>
+ <integer name="all_apps_view_cellCountY">3</integer>
+ <dimen name="all_apps_view_pageLayoutWidthGap">10dp</dimen>
+ <dimen name="all_apps_view_pageLayoutHeightGap">5dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingTop">10dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingBottom">10dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingLeft">2dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingRight">2dp</dimen>
+
+ <dimen name="apps_customize_widget_cell_width_gap">30dp</dimen>
+ <dimen name="apps_customize_widget_cell_height_gap">0dp</dimen>
+ <integer name="apps_customize_widget_cell_count_x">3</integer>
+ <integer name="apps_customize_widget_cell_count_y">1</integer>
+ <integer name="apps_customize_wallpaper_cell_count_x">3</integer>
+ <integer name="apps_customize_wallpaper_cell_count_y">1</integer>
</resources>
diff --git a/res/values-large-land/dimens.xml b/res/values-large-land/dimens.xml
new file mode 100644
index 0000000..196cdb0
--- /dev/null
+++ b/res/values-large-land/dimens.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<resources>
+ <!-- the area at the edge of the screen that makes the workspace go left
+ or right while you're dragging. -->
+ <dimen name="scroll_zone">100dip</dimen>
+
+ <dimen name="customization_drawer_height">480dp</dimen>
+ <dimen name="customization_drawer_content_height">420dp</dimen>
+
+ <integer name="all_apps_view_cellCountX">7</integer>
+ <integer name="all_apps_view_cellCountY">5</integer>
+ <dimen name="all_apps_view_pageLayoutWidthGap">36dp</dimen>
+ <dimen name="all_apps_view_pageLayoutHeightGap">6dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingTop">20dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingBottom">14dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingLeft">40dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingRight">40dp</dimen>
+
+ <integer name="customization_drawer_contents_wallpaperCellSpanX">3</integer>
+ <integer name="customization_drawer_contents_wallpaperCellCountX">12</integer>
+ <integer name="customization_drawer_contents_widgetCellCountX">14</integer>
+ <integer name="customization_drawer_contents_cellCountX">8</integer>
+ <integer name="customization_drawer_contents_cellCountY">3</integer>
+ <dimen name="customization_drawer_contents_pageLayoutWidthGap">32dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values-large-port/dimens.xml b/res/values-large-port/dimens.xml
new file mode 100644
index 0000000..47cac78
--- /dev/null
+++ b/res/values-large-port/dimens.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+
+<resources>
+ <!-- the area at the edge of the screen that makes the workspace go left
+ or right while you're dragging. -->
+ <dimen name="scroll_zone">40dp</dimen>
+
+ <dimen name="customization_drawer_height">800dp</dimen>
+ <dimen name="customization_drawer_content_height">420dp</dimen>
+
+ <integer name="all_apps_view_cellCountX">5</integer>
+ <integer name="all_apps_view_cellCountY">7</integer>
+ <dimen name="all_apps_view_pageLayoutWidthGap">36dp</dimen>
+ <dimen name="all_apps_view_pageLayoutHeightGap">36dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingTop">25dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingBottom">10dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingLeft">20dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingRight">20dp</dimen>
+
+ <integer name="customization_drawer_contents_wallpaperCellSpanX">3</integer>
+ <integer name="customization_drawer_contents_wallpaperCellCountX">9</integer>
+ <integer name="customization_drawer_contents_widgetCellCountX">9</integer>
+ <integer name="customization_drawer_contents_cellCountX">5</integer>
+ <integer name="customization_drawer_contents_cellCountY">3</integer>
+ <dimen name="customization_drawer_contents_pageLayoutWidthGap">36dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values-large/config.xml b/res/values-large/config.xml
new file mode 100644
index 0000000..99ee1ec
--- /dev/null
+++ b/res/values-large/config.xml
@@ -0,0 +1,32 @@
+<resources>
+<!-- AllApps/Customize/AppsCustomize -->
+ <!-- Fade/zoom in/out duration & scale in the Customize transition.
+ Note: This should be less than the workspaceShrinkTime as they happen together. -->
+ <integer name="config_customizeZoomInTime">800</integer>
+ <integer name="config_customizeZoomOutTime">600</integer>
+ <integer name="config_customizeZoomScaleFactor">7</integer>
+ <integer name="config_customizeFadeInTime">800</integer>
+
+ <!-- The slope, in percent, of the drag movement needed to drag an item out of
+ Customize (y / x * 100%) -->
+ <integer name="config_customizationDrawerDragSlopeThreshold">150</integer>
+
+ <!-- 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_customizeWorkspaceShrinkTime">800</integer>
+
+<!-- Workspace -->
+ <!-- When dragging items on the workspace, how much bigger (in pixels) the dragged view
+ should be, as compared to the original view. If 0, it will not be scaled at all.
+ Should be an even number, for pixel alignment. -->
+ <integer name="config_dragViewExtraPixels">0</integer>
+
+ <!-- When items are dropped on the mini screens in customize mode, we have a bounce animation
+ of the bright green hover outline, and then fade out the outline at the end. These are
+ the values used in that animation -->
+ <integer name="config_screenOnDropScalePercent">120</integer>
+ <integer name="config_screenOnDropScaleUpDuration">200</integer>
+ <integer name="config_screenOnDropScaleDownDuration">200</integer>
+ <integer name="config_screenOnDropAlphaFadeDelay">350</integer>
+ <integer name="config_screenOnDropAlphaFadeDuration">50</integer>
+</resources>
diff --git a/res/values-xlarge/dimens.xml b/res/values-large/dimens.xml
similarity index 61%
rename from res/values-xlarge/dimens.xml
rename to res/values-large/dimens.xml
index c4988e4..2416109 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -15,12 +15,28 @@
-->
<resources>
+ <dimen name="apps_customize_cell_width">96dp</dimen>
+ <dimen name="apps_customize_cell_height">96dp</dimen>
<dimen name="workspace_cell_width">96dip</dimen>
<dimen name="workspace_cell_height">96dip</dimen>
+ <dimen name="workspace_x_axis_start_padding_land">25dip</dimen>
+ <dimen name="workspace_x_axis_end_padding_land">25dip</dimen>
+ <dimen name="workspace_y_axis_start_padding_land">15dip</dimen>
+ <dimen name="workspace_y_axis_end_padding_land">15dip</dimen>
+ <dimen name="workspace_x_axis_start_padding_port">15dip</dimen>
+ <dimen name="workspace_x_axis_end_padding_port">15dip</dimen>
+ <dimen name="workspace_y_axis_start_padding_port">25dip</dimen>
+ <dimen name="workspace_y_axis_end_padding_port">25dip</dimen>
+
<!-- Width/height gap overrides for the workspace -->
- <dimen name="workspace_width_gap">0dp</dimen>
- <dimen name="workspace_height_gap">0dp</dimen>
+ <dimen name="workspace_width_gap_land">32dp</dimen>
+ <dimen name="workspace_height_gap_land">2dp</dimen>
+ <dimen name="workspace_width_gap_port">0dp</dimen>
+ <dimen name="workspace_height_gap_port">32dp</dimen>
+
+ <dimen name="workspace_page_spacing_land">50dp</dimen>
+ <dimen name="workspace_page_spacing_port">64dp</dimen>
<!-- The corner radius to draw the external drop icon rounded rect -->
<dimen name="external_drop_icon_rect_radius">10dp</dimen>
@@ -28,6 +44,9 @@
<!-- Size of icons in workspace -->
<dimen name="app_icon_size">72dp</dimen>
+ <!-- Size of content of icons in workspace, as specified by the android icon guidelines -->
+ <dimen name="app_icon_content_size">60dp</dimen>
+
<!-- extra horizontal spacing between mini screen thumbnails ie. in all
apps and in customization mode -->
<dimen name="smallScreenExtraSpacing">0dip</dimen>
@@ -37,15 +56,12 @@
<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>
+ <integer name="land_all_apps_view_cellCountX">7</integer>
+ <integer name="land_all_apps_view_cellCountY">5</integer>
+
<dimen name="toolbar_button_vertical_padding">12dip</dimen>
<dimen name="toolbar_button_horizontal_padding">16dip</dimen>
@@ -53,6 +69,9 @@
<dimen name="delete_zone_vertical_drag_padding">20dip</dimen>
<dimen name="delete_zone_horizontal_drag_padding">20dip</dimen>
+ <!-- roughly a status bar (for determining how many rows of icons are in home) -->
+ <dimen name="status_bar_height">48dip</dimen>
+
<!-- dimensions for the wallpaper picker wallpaper thumbnail width -->
<dimen name="wallpaper_chooser_grid_width">196dp</dimen>
<dimen name="wallpaper_chooser_grid_height">140dp</dimen>
@@ -64,4 +83,9 @@
<!-- How much the content view of an alert dialog should be inset (currently used
for the WallpaperChooser in XLarge mode) -->
<dimen name="alert_dialog_content_inset">0dp</dimen>
+
+ <!-- When dragging items on the workspace, the number of dps by which the position of
+ the drag view should be offset from the position of the original view. -->
+ <dimen name="dragViewOffsetX">0dp</dimen>
+ <dimen name="dragViewOffsetY">-12dp</dimen>
</resources>
diff --git a/res/values-xlarge/strings.xml b/res/values-large/strings.xml
similarity index 100%
rename from res/values-xlarge/strings.xml
rename to res/values-large/strings.xml
diff --git a/res/values-xlarge/styles.xml b/res/values-large/styles.xml
similarity index 78%
rename from res/values-xlarge/styles.xml
rename to res/values-large/styles.xml
index 7208d97..bcbe038 100644
--- a/res/values-xlarge/styles.xml
+++ b/res/values-large/styles.xml
@@ -41,4 +41,16 @@
<item name="android:paddingTop">0dip</item>
<item name="android:includeFontPadding">false</item>
</style>
+
+ <style name="TabIndicator.Wide">
+ <item name="android:paddingLeft">40dp</item>
+ <item name="android:paddingRight">40dp</item>
+ <item name="android:paddingTop">15dp</item>
+ <item name="android:paddingBottom">20dp</item>
+ <item name="android:textSize">20sp</item>
+ </style>
+
+ <style name="config_orientation">
+ <item name="@android:screenOrientation">unspecified</item>
+ </style>
</resources>
diff --git a/res/values-xlarge/wallpapers.xml b/res/values-large/wallpapers.xml
similarity index 100%
rename from res/values-xlarge/wallpapers.xml
rename to res/values-large/wallpapers.xml
diff --git a/res/values-lt-xlarge/strings.xml b/res/values-lt-large/strings.xml
similarity index 100%
rename from res/values-lt-xlarge/strings.xml
rename to res/values-lt-large/strings.xml
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index bb67115..e84360d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Aplankai"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Daugiau"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Darbalaukio fonai"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Spartieji programos klavišai"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Spartieji programos klavišai"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Tai bus darbalaukio fonų skirtukas"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Visos"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Žaidimai"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Atsisiųsta"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Ieškoti"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Balso paieška"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Programos"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Tinkinti"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"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-xlarge/strings.xml b/res/values-lv-large/strings.xml
similarity index 100%
rename from res/values-lv-xlarge/strings.xml
rename to res/values-lv-large/strings.xml
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 7a016a6..963c332 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mapes"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Vairāk"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Fona tapetes"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Lietotnes saīsnes"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Lietotņu saīsnes"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Šī būs fona tapetes cilne"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Visas"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Lietotnes"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Spēles"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Lejupielādētās"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Meklēt"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Balss meklēšana"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Lietojumprogrammas"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Pielāgot"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Noņemt"</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-xlarge/strings.xml b/res/values-nb-large/strings.xml
similarity index 100%
rename from res/values-nb-xlarge/strings.xml
rename to res/values-nb-large/strings.xml
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index bee708c..382bac4 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mapper"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mer"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Bakgrunner"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Programsnarveier"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"App-snarveier"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dette er nå bakgrunnsfanen"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Programmer"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Spill"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Nedlastet"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Søk"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Talesøk"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Applikasjoner"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Tilpass"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Fjern"</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-xlarge/strings.xml b/res/values-nl-large/strings.xml
similarity index 100%
rename from res/values-nl-xlarge/strings.xml
rename to res/values-nl-large/strings.xml
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 9d7ff2f..abcf29a 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -25,20 +25,21 @@
<string name="chooser_wallpaper" msgid="5988031014201479733">"Achtergrond selecteren in"</string>
<string name="wallpaper_instructions" msgid="4215640646180727542">"Achtergrond instellen"</string>
<string name="pick_wallpaper" msgid="5630222540525626723">"Achtergronden"</string>
- <string name="activity_not_found" msgid="5591731020063337696">"De toepassing is niet geïnstalleerd."</string>
+ <string name="activity_not_found" msgid="5591731020063337696">"De app is niet geïnstalleerd."</string>
<string name="configure_wallpaper" msgid="2820186271419674623">"Configureren..."</string>
<string name="widgets_tab_label" msgid="9145860100000983599">"Widgets"</string>
<string name="folders_tab_label" msgid="1145293785541489736">"Mappen"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Meer"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Achtergronden"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Toepassingssnelkoppelingen"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Toepassingssnelkoppelingen"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Dit wordt het tabblad \'Achtergronden\'"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Alle"</string>
- <string name="all_apps_tab_apps" msgid="5468972551904071712">"Toepassingen"</string>
+ <string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Games"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Gedownload"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mijn apps"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Geen games gevonden."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Geen gedownloade toepassingen 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>
@@ -46,7 +47,7 @@
<string name="rename_action" msgid="6016003384693240896">"OK"</string>
<string name="cancel_action" msgid="3811860427489435048">"Annuleren"</string>
<string name="menu_item_add_item" msgid="6233177331075781114">"Toevoegen aan startpagina"</string>
- <string name="group_applications" msgid="4118484163419674240">"Toepassingen"</string>
+ <string name="group_applications" msgid="4118484163419674240">"Apps"</string>
<string name="group_shortcuts" msgid="9133529424900391877">"Sneltoetsen"</string>
<string name="group_folder" msgid="5143593791798929193">"Nieuwe map"</string>
<string name="group_live_folders" msgid="2664945399140647217">"Mappen"</string>
@@ -60,33 +61,39 @@
<string name="shortcut_uninstalled" msgid="2129499669449749995">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' is verwijderd."</string>
<string name="shortcut_duplicate" msgid="4757756326465060694">"Snelkoppeling \'<xliff:g id="NAME">%s</xliff:g>\' bestaat al."</string>
<string name="title_select_shortcut" msgid="2858897527672831763">"Snelkoppeling selecteren"</string>
- <string name="title_select_application" msgid="8031072293115454221">"Toepassing selecteren"</string>
+ <string name="title_select_application" msgid="8031072293115454221">"App selecteren"</string>
<string name="title_select_live_folder" msgid="3753447798805166749">"Map selecteren"</string>
- <string name="all_apps_button_label" msgid="2578400570124163469">"Toepassingen"</string>
+ <string name="all_apps_button_label" msgid="2578400570124163469">"Apps"</string>
<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="accessibility_search_button" msgid="816822994629942611">"Zoeken"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Spraakgestuurd zoeken"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Apps"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Aanpassen"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"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">"Toepassingen beheren"</string>
+ <string name="menu_manage_apps" msgid="2308685199463588895">"Apps beheren"</string>
<string name="menu_wallpaper" msgid="5837429080911269832">"Achtergrond"</string>
<string name="menu_search" msgid="4826514464423239041">"Zoeken"</string>
<string name="menu_notifications" msgid="6424587053194766192">"Meldingen"</string>
<string name="menu_gestures" msgid="514678675575912237">"Gebaren"</string>
<string name="menu_settings" msgid="6233960148378443661">"Instellingen"</string>
- <string name="cab_menu_delete_app" msgid="1242619904941293871">"Toepassing verwijderen"</string>
+ <string name="cab_menu_delete_app" msgid="1242619904941293871">"App verwijderen"</string>
<string name="cab_menu_app_info" msgid="5180426909324882018">"Toepassingsdetails"</string>
- <string name="cab_app_selection_text" msgid="606113924828167756">"1 toepassing geselecteerd"</string>
+ <string name="cab_app_selection_text" msgid="606113924828167756">"1 app geselecteerd"</string>
<string name="cab_widget_selection_text" msgid="962527270506951955">"1 widget geselecteerd"</string>
<string name="cab_folder_selection_text" msgid="8916111874189565067">"1 map geselecteerd"</string>
<string name="cab_shortcut_selection_text" msgid="8115847384500412878">"1 snelkoppeling geselecteerd"</string>
<string name="permlab_install_shortcut" msgid="1201690825493376489">"snelkoppelingen installeren"</string>
- <string name="permdesc_install_shortcut" msgid="7429365847558984148">"Een toepassing toestaan om snelkoppelingen toe te voegen zonder tussenkomst van de gebruiker."</string>
+ <string name="permdesc_install_shortcut" msgid="7429365847558984148">"Een app toestaan snelkoppelingen toe te voegen zonder tussenkomst van de gebruiker."</string>
<string name="permlab_uninstall_shortcut" msgid="7696645932555926449">"snelkoppelingen verwijderen"</string>
- <string name="permdesc_uninstall_shortcut" msgid="959972195916090900">"Een toepassing toestaan om snelkoppelingen te verwijderen zonder tussenkomst van de gebruiker."</string>
+ <string name="permdesc_uninstall_shortcut" msgid="959972195916090900">"Een app toestaan snelkoppelingen te verwijderen zonder tussenkomst van de gebruiker."</string>
<string name="permlab_read_settings" msgid="3452408290738106747">"instellingen en snelkoppelingen voor de startpagina lezen"</string>
- <string name="permdesc_read_settings" msgid="8377434937176025492">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina lezen."</string>
+ <string name="permdesc_read_settings" msgid="8377434937176025492">"Hiermee kan een app de instellingen en snelkoppelingen op de startpagina lezen."</string>
<string name="permlab_write_settings" msgid="1360567537236705628">"instellingen en snelkoppelingen voor de startpagina schrijven"</string>
- <string name="permdesc_write_settings" msgid="1098648778383349818">"Hiermee kan een toepassing de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
+ <string name="permdesc_write_settings" msgid="1098648778383349818">"Hiermee kan een app de instellingen en snelkoppelingen op de startpagina wijzigen."</string>
<string name="gadget_error_text" msgid="8359351016167075858">"Probleem bij het laden van widget"</string>
<string name="uninstall_system_app_text" msgid="7488523163288397451">"Dit is een systeemtoepassing die niet kan worden verwijderd."</string>
</resources>
diff --git a/res/values-pl-xlarge/strings.xml b/res/values-pl-large/strings.xml
similarity index 100%
rename from res/values-pl-xlarge/strings.xml
rename to res/values-pl-large/strings.xml
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 50e955e..97b54af 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Foldery"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Więcej"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapety"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Skróty do aplikacji"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Skróty do aplikacji"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"To będzie karta tapet"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Wszystkie"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikacje"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Gry"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Pobrane"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moje aplikacje"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Nie znaleziono gier."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Brak pobranych aplikacji."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Szukaj"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Wyszukiwanie głosowe"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplikacje"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Dostosuj"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Usuń"</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-port/dimens.xml b/res/values-port/dimens.xml
index 65a3fd3..7d50c1a 100644
--- a/res/values-port/dimens.xml
+++ b/res/values-port/dimens.xml
@@ -17,4 +17,22 @@
<resources>
<dimen name="workspace_cell_width">80dip</dimen>
<dimen name="workspace_cell_height">100dip</dimen>
+ <dimen name="folder_cell_width">74dip</dimen>
+ <dimen name="folder_cell_height">86dip</dimen>
+
+ <integer name="all_apps_view_cellCountX">4</integer>
+ <integer name="all_apps_view_cellCountY">5</integer>
+ <dimen name="all_apps_view_pageLayoutWidthGap">3dp</dimen>
+ <dimen name="all_apps_view_pageLayoutHeightGap">12dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingTop">15dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingBottom">15dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingLeft">0dp</dimen>
+ <dimen name="all_apps_view_pageLayoutPaddingRight">0dp</dimen>
+
+ <dimen name="apps_customize_widget_cell_width_gap">20dp</dimen>
+ <dimen name="apps_customize_widget_cell_height_gap">40dp</dimen>
+ <integer name="apps_customize_widget_cell_count_x">2</integer>
+ <integer name="apps_customize_widget_cell_count_y">2</integer>
+ <integer name="apps_customize_wallpaper_cell_count_x">1</integer>
+ <integer name="apps_customize_wallpaper_cell_count_y">1</integer>
</resources>
diff --git a/res/values-pt-xlarge/strings.xml b/res/values-pt-large/strings.xml
similarity index 100%
rename from res/values-pt-xlarge/strings.xml
rename to res/values-pt-large/strings.xml
diff --git a/res/values-pt-rPT-xlarge/strings.xml b/res/values-pt-rPT-large/strings.xml
similarity index 100%
rename from res/values-pt-rPT-xlarge/strings.xml
rename to res/values-pt-rPT-large/strings.xml
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 69f202a..71f634d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Pastas"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mais"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Imagens de fundo"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Atalhos de aplicações"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Atalhos de aplicações"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Isto será o separador de imagens de fundo"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Todas"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicações"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Jogos"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Transferidas"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"As minhas aplicações"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Sem jogos."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Sem aplicações transferidas."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Pesquisar"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Pesquisa por Voz"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicações"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizar"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Remover"</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 9e6cdfd..2714fde 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Pastas"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mais"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Papéis de parede"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Atalhos de aplicativo"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Atalhos de aplicativo"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Esta será a guia de papéis de parede"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Todos"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicativos"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Jogos"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Download concluído"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Meus aplicativos"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Nenhum jogo encontrado."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nenhum aplic. 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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Pesquisar"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Pesquisa por voz"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicativos"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizar"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Remover"</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 6ac87d4..a8453ed 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,18 @@
<skip />
<!-- no translation found for delete_zone_label_all_apps (6664588234817475108) -->
<skip />
+ <!-- no translation found for accessibility_search_button (816822994629942611) -->
+ <skip />
+ <!-- no translation found for accessibility_voice_search_button (3938249215065842475) -->
+ <skip />
+ <!-- no translation found for accessibility_all_apps_button (1595097919145716305) -->
+ <skip />
+ <!-- no translation found for accessibility_customize_button (585539669413531163) -->
+ <skip />
+ <!-- no translation found for accessibility_delete_button (3628162007991023603) -->
+ <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-xlarge/strings.xml b/res/values-ro-large/strings.xml
similarity index 100%
rename from res/values-ro-xlarge/strings.xml
rename to res/values-ro-large/strings.xml
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index ff81c00..6bed5d0 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Dosare"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mai multe"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Imagini de fundal"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Comenzi rapide aplicaţii"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Comenzi rapide aplicaţii"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Aceasta va fi fila pentru imagini de fundal"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Toate"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplicaţii"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Jocuri"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Descărcate"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Nu s-au găsit aplicaţii descărcate."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Căutaţi"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Căutare vocală"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplicaţii"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Personalizaţi"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Eliminaţ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-xlarge/strings.xml b/res/values-ru-large/strings.xml
similarity index 100%
rename from res/values-ru-xlarge/strings.xml
rename to res/values-ru-large/strings.xml
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index abd09f9..0456e4c 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Папки"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Ещё"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Обои"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Ярлыки приложений"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Ярлыки приложений"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Это будет вкладка обоев"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Все"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Приложения"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Игры"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Загруженные"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Мои приложения"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Игр не найдено."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Нет загруженных приложений."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Поиск"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Голосовой поиск"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Приложения"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Настроить"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Удалить"</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-xlarge/strings.xml b/res/values-sk-large/strings.xml
similarity index 100%
rename from res/values-sk-xlarge/strings.xml
rename to res/values-sk-large/strings.xml
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 23a8476..064309d 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Priečinky"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Viac"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Tapety"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Odkazy aplikácií"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Odkazy aplikácií"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Toto bude karta Tapety"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Všetky"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Aplikácie"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Hry"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Prevzaté"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Neboli nájdené žiadne prevzaté aplikácie."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Hľadať"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Hlasové vyhľadávanie"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Aplikácie"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Prispôsobiť"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Odstrániť"</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-xlarge/strings.xml b/res/values-sl-large/strings.xml
similarity index 100%
rename from res/values-sl-xlarge/strings.xml
rename to res/values-sl-large/strings.xml
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index f12fd7b..78b5187 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mape"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Več"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Ozadja"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Bližnjice do programov"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Bližnjice do programov"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"To bo zavihek ozadij"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Vse"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Programi"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Igre"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Preneseno"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Moji programi"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Ni najdenih iger."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Ni najdenih prenesenih programov."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Išči"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Glasovno iskanje"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Programi"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Prilagodi"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"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-xlarge/strings.xml b/res/values-sr-large/strings.xml
similarity index 100%
rename from res/values-sr-xlarge/strings.xml
rename to res/values-sr-large/strings.xml
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 4a61abb..cbc4bf2 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Директоријуми"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Још"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Позадине"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Пречице за апликације"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Пречице за апликације"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ово ће бити картица позадине"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Све"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Игре"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Преузето"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Моје апликације"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Нису пронађене игре."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Нису пронађене преузете апликације"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Претражи"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Гласовна претрага"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Апликације"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Прилагоди"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Уклони"</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-xlarge/strings.xml b/res/values-sv-large/strings.xml
similarity index 100%
rename from res/values-sv-xlarge/strings.xml
rename to res/values-sv-large/strings.xml
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5f5a5d0..68859e3 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mappar"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Mer"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Bakgrundsbilder"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Genvägar för appar"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Genvägar för appar"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Det här kommer att vara fliken för bakgrundsbilder"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Alla"</string>
- <string name="all_apps_tab_apps" msgid="5468972551904071712">"Program"</string>
+ <string name="all_apps_tab_apps" msgid="5468972551904071712">"Appar"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Spel"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Hämtade"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Mina appar"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Inga spel hittades."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Inga hämtade appar."</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>
@@ -46,7 +47,7 @@
<string name="rename_action" msgid="6016003384693240896">"OK"</string>
<string name="cancel_action" msgid="3811860427489435048">"Avbryt"</string>
<string name="menu_item_add_item" msgid="6233177331075781114">"Lägg till på startsidan"</string>
- <string name="group_applications" msgid="4118484163419674240">"Program"</string>
+ <string name="group_applications" msgid="4118484163419674240">"Appar"</string>
<string name="group_shortcuts" msgid="9133529424900391877">"Genvägar"</string>
<string name="group_folder" msgid="5143593791798929193">"Ny mapp"</string>
<string name="group_live_folders" msgid="2664945399140647217">"Mappar"</string>
@@ -60,12 +61,18 @@
<string name="shortcut_uninstalled" msgid="2129499669449749995">"Genvägen \"<xliff:g id="NAME">%s</xliff:g>\" har tagits bort."</string>
<string name="shortcut_duplicate" msgid="4757756326465060694">"Genvägen \"<xliff:g id="NAME">%s</xliff:g>\" finns redan."</string>
<string name="title_select_shortcut" msgid="2858897527672831763">"Välj genväg"</string>
- <string name="title_select_application" msgid="8031072293115454221">"Välj program"</string>
+ <string name="title_select_application" msgid="8031072293115454221">"Välj app"</string>
<string name="title_select_live_folder" msgid="3753447798805166749">"Välj mapp"</string>
- <string name="all_apps_button_label" msgid="2578400570124163469">"Program"</string>
+ <string name="all_apps_button_label" msgid="2578400570124163469">"Appar"</string>
<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="accessibility_search_button" msgid="816822994629942611">"Sök"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Röstsökning"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Appar"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Anpassa"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Ta bort"</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>
@@ -73,9 +80,9 @@
<string name="menu_notifications" msgid="6424587053194766192">"Aviseringar"</string>
<string name="menu_gestures" msgid="514678675575912237">"Gester"</string>
<string name="menu_settings" msgid="6233960148378443661">"Inställningar"</string>
- <string name="cab_menu_delete_app" msgid="1242619904941293871">"Avinstallera program"</string>
+ <string name="cab_menu_delete_app" msgid="1242619904941293871">"Avinstallera app"</string>
<string name="cab_menu_app_info" msgid="5180426909324882018">"Programinformation"</string>
- <string name="cab_app_selection_text" msgid="606113924828167756">"1 program har valts"</string>
+ <string name="cab_app_selection_text" msgid="606113924828167756">"1 app har valts"</string>
<string name="cab_widget_selection_text" msgid="962527270506951955">"1 widget vald"</string>
<string name="cab_folder_selection_text" msgid="8916111874189565067">"1 mapp vald"</string>
<string name="cab_shortcut_selection_text" msgid="8115847384500412878">"1 genväg har valts"</string>
diff --git a/res/values-th-xlarge/strings.xml b/res/values-th-large/strings.xml
similarity index 100%
rename from res/values-th-xlarge/strings.xml
rename to res/values-th-large/strings.xml
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 39dc770..1562135 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"โฟลเดอร์"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"เพิ่มเติม"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"วอลเปเปอร์"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"ทางลัดของแอปพลิเคชัน"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"ทางลัดของแอปพลิเคชัน"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"นี่จะเป็นแท็บวอลเปเปอร์"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"ทั้งหมด"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"แอปพลิเคชัน"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"เกม"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"ดาวน์โหลดแล้ว"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"แอปพลิเคชันของฉัน"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"ไม่พบเกม"</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"ไม่พบแอปพลิเคชันที่ดาวน์โหลดไว้"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"ค้นหา"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Voice Search"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"แอปพลิเคชัน"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"กำหนดค่า"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"ลบ"</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-xlarge/strings.xml b/res/values-tl-large/strings.xml
similarity index 100%
rename from res/values-tl-xlarge/strings.xml
rename to res/values-tl-large/strings.xml
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index cbdac66..50ed317 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Mga Folder"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Higit pa"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Mga Wallpaper"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Mga Shortcut ng App"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Mga shortcut ng app"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Ito ang magiging tab ng mga wallpaper"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Lahat"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Apps"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Mga Laro"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Na-download"</string>
+ <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>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Walang na-download na app"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Maghanap"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Paghahanap gamit ang Boses"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Mga Application"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"I-customize"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Alisin"</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-xlarge/strings.xml b/res/values-tr-large/strings.xml
similarity index 100%
rename from res/values-tr-xlarge/strings.xml
rename to res/values-tr-large/strings.xml
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 3059ab4..2057828 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -31,21 +31,22 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Klasörler"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Diğer"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Duvar Kağıtları"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Uygulama Kısayolları"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Uygulama kısayolları"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Bu duvar kağıdı sekmesi olacaktır"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Tümü"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Uygulamalar"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Oyunlar"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"İndirilenler"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Uygulamalarım"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Oyun bulunamadı."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"İndirilmiş uygulama 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>
<string name="rename_folder_title" msgid="4544573104191526550">"Klasörü yeniden adlandır"</string>
<string name="rename_action" msgid="6016003384693240896">"Tamam"</string>
<string name="cancel_action" msgid="3811860427489435048">"İptal"</string>
- <string name="menu_item_add_item" msgid="6233177331075781114">"Ana ekrana ekle"</string>
+ <string name="menu_item_add_item" msgid="6233177331075781114">"Ana Sayfaya ekle"</string>
<string name="group_applications" msgid="4118484163419674240">"Uygulamalar"</string>
<string name="group_shortcuts" msgid="9133529424900391877">"Kısayollar"</string>
<string name="group_folder" msgid="5143593791798929193">"Yeni klasör"</string>
@@ -55,7 +56,7 @@
<string name="add_folder" msgid="3521088587367839879">"Klasör"</string>
<string name="add_clock" msgid="2337943840175865746">"Saat"</string>
<string name="add_photo_frame" msgid="3154058437359487954">"Resim çerçevesi"</string>
- <string name="out_of_space" msgid="8365249326091984698">"Bu Ana ekranda başka yer yok."</string>
+ <string name="out_of_space" msgid="8365249326091984698">"Bu Ana Sayfada yer yok."</string>
<string name="shortcut_installed" msgid="7071557296331322355">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu oluşturuldu."</string>
<string name="shortcut_uninstalled" msgid="2129499669449749995">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu kaldırıldı."</string>
<string name="shortcut_duplicate" msgid="4757756326465060694">"\"<xliff:g id="NAME">%s</xliff:g>\" kısayolu zaten var."</string>
@@ -66,6 +67,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Ara"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Sesli Arama"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Uygulamalar"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Özelleştir"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"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-xlarge/strings.xml b/res/values-uk-large/strings.xml
similarity index 100%
rename from res/values-uk-xlarge/strings.xml
rename to res/values-uk-large/strings.xml
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index caa04d8..b3f0846 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Папки"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Більше"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Фонові мал."</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Ярлики програм"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Ярлики програм"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"This will be the wallpapers tab"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Усі"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Програми"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Ігри"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Завантажені"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Мої програми"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"Ігор не знайдено."</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"Завантажених програм не знайдено."</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Пошук"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Голосовий пошук"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Програми"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Налаштувати"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Видалити"</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-xlarge/strings.xml b/res/values-vi-large/strings.xml
similarity index 74%
rename from res/values-vi-xlarge/strings.xml
rename to res/values-vi-large/strings.xml
index 9257327..c8ce028 100644
--- a/res/values-vi-xlarge/strings.xml
+++ b/res/values-vi-large/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="wallpaper_dialog_title" msgid="5764793286524787718">"Chọn hình nền"</string>
- <string name="wallpaper_chooser_empty" msgid="7358237455389125747">"Không có sẵn hình nền nào"</string>
- <string name="wallpaper_cancel" msgid="6502936522490675611">"Hủy"</string>
+ <string name="wallpaper_dialog_title" msgid="8362944198120933329">"Chọn hình nền"</string>
+ <string name="wallpaper_chooser_empty" msgid="6543937491391049913">"Không có sẵn hình nền nào"</string>
+ <string name="wallpaper_cancel" msgid="5942480248232268588">"Hủy"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 3277c07..9238c4a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"Thư mục"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"Khác"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"Hình nền"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"Lối tắt ứng dụng"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"Lối tắt ứng dụng"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"Đây sẽ là tab hình nền"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"Tất cả"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"Ứng dụng"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"Trò chơi"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"Đã tải xuống"</string>
+ <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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"Tìm kiếm"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"Tìm kiếm bằng giọng nói"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"Ứng dụng"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"Tùy chỉnh"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"Xóa"</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
deleted file mode 100644
index 51037f5..0000000
--- a/res/values-xlarge-land/dimens.xml
+++ /dev/null
@@ -1,25 +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.
--->
-
-<resources>
- <!-- the area at the edge of the screen that makes the workspace go left
- or right while you're dragging. -->
- <dimen name="scroll_zone">100dip</dimen>
-
- <!-- Width/height gap overrides for the workspace -->
- <dimen name="workspace_width_gap">32dp</dimen>
- <dimen name="workspace_height_gap">2dp</dimen>
-</resources>
\ No newline at end of file
diff --git a/res/values-xlarge-port/dimens.xml b/res/values-xlarge-port/dimens.xml
deleted file mode 100644
index baa31aa..0000000
--- a/res/values-xlarge-port/dimens.xml
+++ /dev/null
@@ -1,25 +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.
--->
-
-<resources>
- <!-- the area at the edge of the screen that makes the workspace go left
- or right while you're dragging. -->
- <dimen name="scroll_zone">40dp</dimen>
-
- <!-- Width/height gap overrides for the workspace -->
- <dimen name="workspace_width_gap">0dp</dimen>
- <dimen name="workspace_height_gap">32dp</dimen>
-</resources>
\ No newline at end of file
diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml
deleted file mode 100644
index dc9d096..0000000
--- a/res/values-xlarge/config.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<resources>
- <!-- NOTE: Many of the all apps values here are also used for the customization drawer -->
-
- <!-- Duration in milliseconds of the fade-in/out of the icons as they are being dragged
- from the AllApps or Customization trays -->
- <integer name="icon_allAppsCustomizeFadeInTime">150</integer>
- <integer name="icon_allAppsCustomizeFadeOutTime">200</integer>
- <integer name="icon_allAppsCustomizeFadeAlpha">102</integer>
-
- <!-- 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>
-
- <!-- Duration in milliseconds of the transition between tabs in the all apps/customize
- tray -->
- <integer name="config_tabTransitionTime">100</integer>
-
- <!-- Duration in milliseconds of the all apps zoom-out animation -->
- <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
- <integer name="config_allAppsZoomOutTime">1200</integer>
-
- <!-- Scaling factor used in the all apps zooming animations -->
- <integer name="config_allAppsZoomScaleFactor">20</integer>
-
- <!-- 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>
-
- <!-- Duration in milliseconds of the all apps zoom-out animation -->
- <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
- <integer name="config_customizeZoomOutTime">600</integer>
-
- <!-- Scaling factor used in the all apps zooming animations -->
- <integer name="config_customizeZoomScaleFactor">7</integer>
-
- <!-- 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_workspaceUnshrinkTime">650</integer>
-
- <!-- Duration in milliseconds toolbar fade in and fade out animations.
- NOTE: Fade in and fade out time should together be less the transition
- animations between all apps, customize, & the workspace. -->
- <integer name="config_toolbarButtonFadeInTime">350</integer>
- <integer name="config_toolbarButtonFadeOutTime">200</integer>
-
- <!-- When dragging items on the workspace, how much bigger (in pixels) the dragged view
- should be, as compared to the original view. If 0, it will not be scaled at all.
- Should be an even number, for pixel alignment. -->
- <integer name="config_dragViewExtraPixels">0</integer>
-
- <!-- When dragging items on the workspace, the number of pixels by which the position of
- the drag view should be offset from the position of the original view. -->
- <integer name="config_dragViewOffsetX">0</integer>
- <integer name="config_dragViewOffsetY">-12</integer>
-
- <!-- When items are dropped on the mini screens in customize mode, we have a bounce animation
- of the bright green hover outline, and then fade out the outline at the end. These are
- the values used in that animation -->
- <integer name="config_screenOnDropScalePercent">120</integer>
- <integer name="config_screenOnDropScaleUpDuration">200</integer>
- <integer name="config_screenOnDropScaleDownDuration">200</integer>
- <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>
- <integer name="config_allAppsDrawerDragSlopeThreshold">150</integer>
-
- <style name="config_orientation">
- <item name="@android:screenOrientation">unspecified</item>
- </style>
-</resources>
diff --git a/res/values-zh-rCN-xlarge/strings.xml b/res/values-zh-rCN-large/strings.xml
similarity index 100%
rename from res/values-zh-rCN-xlarge/strings.xml
rename to res/values-zh-rCN-large/strings.xml
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index b28d5a0..b2f228c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"文件夹"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"更多"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"壁纸"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"应用程序快捷方式"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"应用程序快捷方式"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"这将会成为壁纸标签"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"全部"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"应用程序"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"游戏"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"已下载"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"我的应用程序"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"未找到游戏。"</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"未找到已下载的应用程序。"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"搜索"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"语音搜索"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"应用程序"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"自定义"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"删除"</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-xlarge/strings.xml b/res/values-zh-rTW-large/strings.xml
similarity index 100%
rename from res/values-zh-rTW-xlarge/strings.xml
rename to res/values-zh-rTW-large/strings.xml
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 3b5b214..f172ef6 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -31,14 +31,15 @@
<string name="folders_tab_label" msgid="1145293785541489736">"資料夾"</string>
<string name="shortcuts_tab_label" msgid="8640731503933155644">"更多選項"</string>
<string name="wallpapers_tab_label" msgid="1617804870364119879">"桌布"</string>
- <!-- outdated translation 7756968120518062632 --> <string name="applications_tab_label" msgid="2991364240020736760">"應用程式捷徑"</string>
+ <string name="applications_tab_label" msgid="2991364240020736760">"應用程式捷徑"</string>
<string name="wallpapers_temp_tab_text" msgid="1660218201190495279">"桌布標籤保留位"</string>
<string name="all_apps_tab_all" msgid="2942727589595027258">"全部"</string>
<string name="all_apps_tab_apps" msgid="5468972551904071712">"應用程式"</string>
<string name="all_apps_tab_games" msgid="1855736784923494918">"遊戲"</string>
- <!-- outdated translation 7753043607780556423 --> <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"已下載"</string>
+ <string name="all_apps_tab_downloaded" msgid="1488049110598641387">"我的應用程式"</string>
<string name="all_apps_no_games" msgid="5293893733372793696">"找不到遊戲。"</string>
- <!-- outdated translation 6687010155766000796 --> <string name="all_apps_no_downloads" msgid="2284720393234453761">"找不到已下載的應用程式。"</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,12 @@
<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="accessibility_search_button" msgid="816822994629942611">"搜尋"</string>
+ <string name="accessibility_voice_search_button" msgid="3938249215065842475">"語音搜尋"</string>
+ <string name="accessibility_all_apps_button" msgid="1595097919145716305">"應用程式"</string>
+ <string name="accessibility_customize_button" msgid="585539669413531163">"自訂"</string>
+ <string name="accessibility_delete_button" msgid="3628162007991023603">"移除"</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 5e6a2ab..75b93bf 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">
@@ -94,10 +104,28 @@
<attr name="pageLayoutPaddingBottom" format="dimension" />
<attr name="pageLayoutPaddingLeft" format="dimension" />
<attr name="pageLayoutPaddingRight" format="dimension" />
+ <attr name="pageLayoutMaxHeight" format="dimension" />
<!-- The space between adjacent pages of the PagedView. -->
<attr name="pageSpacing" format="dimension" />
</declare-styleable>
+ <!-- AppsCustomizePagedView specific attributes. These attributes are used to
+ customize an AppsCustomizePagedView in xml files. -->
+ <declare-styleable name="AppsCustomizePagedView">
+ <!-- Horizontal spacing between widgets and wallpapers -->
+ <attr name="widgetCellWidthGap" format="dimension" />
+ <!-- Vertical spacing between widgets -->
+ <attr name="widgetCellHeightGap" format="dimension" />
+ <!-- Number of widgets horizontally -->
+ <attr name="widgetCountX" format="integer" />
+ <!-- Number of widgets vertically -->
+ <attr name="widgetCountY" format="integer" />
+ <!-- Number of wallpaper pickers horizontally -->
+ <attr name="wallpaperCountX" format="integer" />
+ <!-- Number of wallpaper pickers vertically -->
+ <attr name="wallpaperCountY" format="integer" />
+ </declare-styleable>
+
<!-- CustomizePagedView specific attributes. These attributes are used to customize
a CustomizePagedView view in XML files. -->
<declare-styleable name="CustomizePagedView">
diff --git a/res/values/config.xml b/res/values/config.xml
index 850c609..1cc019b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,10 +1,41 @@
<resources>
- <integer name="config_allAppsFadeInTime">700</integer>
- <integer name="config_allAppsFadeOutTime">700</integer>
- <integer name="config_allAppsBatchLoadDelay">0</integer>
- <integer name="config_allAppsBatchSize">0</integer>
+<!-- System -->
<bool name="config_hardwareAccelerated">false</bool>
+<!-- AllApps/Customize/AppsCustomize -->
+ <!-- Fade in/out duration of icons being dragged from the trays -->
+ <integer name="config_dragAppsCustomizeIconFadeInDuration">150</integer>
+ <integer name="config_dragAppsCustomizeIconFadeOutDuration">200</integer>
+ <integer name="config_dragAppsCustomizeIconFadeAlpha">100</integer>
+ <integer name="config_workspaceUnshrinkTime">650</integer>
+
+ <!-- Fade/zoom in/out duration & scale in the AllApps transition.
+ Note: This should be less than the workspaceShrinkTime as they happen together. -->
+ <integer name="config_appsCustomizeZoomInTime">1000</integer>
+ <integer name="config_appsCustomizeZoomOutTime">1200</integer>
+ <integer name="config_appsCustomizeZoomScaleFactor">20</integer>
+ <integer name="config_appsCustomizeFadeInTime">250</integer>
+ <integer name="config_appsCustomizeFadeOutTime">500</integer>
+ <integer name="config_appsCustomizeWorkspaceShrinkTime">1000</integer>
+
+ <!-- Tab transition animation duration -->
+ <integer name="config_tabTransitionDuration">100</integer>
+
+ <!-- The slope, in percent, of the drag movement needed to drag an item out of
+ AppsCustomize (y / x * 100%) -->
+ <integer name="config_appsCustomizeDragSlopeThreshold">150</integer>
+
+ <!-- Fade in/out duration of toolbar/button bar icons.
+ Note: In + Out duration together should be less the duration of the transition
+ between AllApps, Customize & the Workspace. -->
+ <integer name="config_toolbarButtonFadeInTime">350</integer>
+ <integer name="config_toolbarButtonFadeOutTime">200</integer>
+
+ <!-- Batch loading for loading in LauncherModel -->
+ <integer name="config_allAppsBatchLoadDelay">0</integer>
+ <integer name="config_allAppsBatchSize">0</integer>
+
+<!-- Workspace -->
<integer name="config_crosshairsFadeInTime">600</integer>
<!-- When dragging an item on the workspace, how much bigger (in pixels) the dragged view
@@ -12,12 +43,6 @@
Should be an even number, for pixel alignment. -->
<integer name="config_dragViewExtraPixels">40</integer>
- <!-- When dragging items on the workspace, the number of pixels by which the position of
- the drag view should be offset from the position of the original view.
- Setting to 1/2 of config_dragViewExtraPixels keeps it centered on its old position. -->
- <integer name="config_dragViewOffsetX">20</integer>
- <integer name="config_dragViewOffsetY">20</integer>
-
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->
<integer name="config_dragOutlineFadeTime">900</integer>
@@ -25,21 +50,20 @@
<!-- 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. -->
<integer name="config_dropAnimMaxDuration">400</integer>
+ <!-- The duration of the UserFolder opening and closing animation -->
+ <integer name="config_folderAnimDuration">100</integer>
+
<!-- The distance at which the animation should take the max duration -->
<integer name="config_dropAnimMaxDist">800</integer>
- <style name="config_orientation">
- <item name="@android:screenOrientation">nosensor</item>
- </style>
+ <!-- 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>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d6cd3ee..99b1240 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,8 +15,16 @@
-->
<resources>
+<!-- AllApps/Customize/AppsCustomize -->
+ <!-- Size of icons in Workspace/AppsCustomize -->
+ <dimen name="app_icon_size">50dp</dimen>
+ <dimen name="apps_customize_cell_width">68dp</dimen>
+ <dimen name="apps_customize_cell_height">68dp</dimen>
<dimen name="title_texture_width">120px</dimen>
+ <!-- height of the tab bar in AppsCustomize -->
+ <dimen name="apps_customize_tab_bar_height">56dp</dimen>
+
<!-- height of the bottom row of controls -->
<dimen name="button_bar_height">56dip</dimen>
@@ -24,6 +32,24 @@
button_bar_height changes -->
<dimen name="button_bar_height_portrait">56dip</dimen>
+ <!-- extra horizontal spacing between mini screen thumbnails ie. in all
+ apps and in customization mode -->
+ <dimen name="smallScreenExtraSpacing">0dip</dimen>
+
+ <!-- Vertical spacing between edge of screen and mini cell layouts when they
+ are minimized to the bottom in all apps -->
+ <dimen name="allAppsSmallScreenVerticalMarginLandscape">30dip</dimen>
+ <dimen name="allAppsSmallScreenVerticalMarginPortrait">60dip</dimen>
+
+ <!-- height & width of the drop rectangle for the trash icon -->
+ <dimen name="delete_zone_size">70dip</dimen>
+
+ <!-- delete_zone_size_full - button_bar_height_portrait -->
+ <dimen name="delete_zone_padding">14dip</dimen>
+
+ <!-- padding between the delete zone drawable and text -->
+ <dimen name="delete_zone_drawable_padding">8dip</dimen>
+
<!-- roughly a status bar (for vertically centering the all apps
home icon in landscape) -->
<dimen name="status_bar_height">25dip</dimen>
@@ -32,16 +58,17 @@
button cluster in landscape) -->
<dimen name="half_status_bar_height">12dip</dimen>
- <!-- Size of icons in workspace -->
- <dimen name="app_icon_size">50dp</dimen>
-
- <!-- height & width of the drop rectangle for the trash icon -->
- <dimen name="delete_zone_size">70dip</dimen>
-
- <!-- delete_zone_size_full - button_bar_height_portrait -->
- <dimen name="delete_zone_padding">14dip</dimen>
-
+<!-- Dragging -->
<!-- the area at the edge of the screen that makes the workspace go left
or right while you're dragging. -->
<dimen name="scroll_zone">20dp</dimen>
+
+ <!-- When dragging items on the workspace, the number of dps by which the position of
+ the drag view should be offset from the position of the original view. -->
+ <dimen name="dragViewOffsetX">0dp</dimen>
+ <dimen name="dragViewOffsetY">-8dp</dimen>
+
+ <!-- Width/height gap overrides for the workspace -->
+ <dimen name="workspace_width_gap">-1dp</dimen>
+ <dimen name="workspace_height_gap">-1dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6dcaa57..9ad3e24 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,21 @@
device. [CHAR_LIMIT=30]-->
<string name="delete_zone_label_all_apps">Uninstall</string>
+ <!-- Accessibility: Search button -->
+ <string name="accessibility_search_button">Search</string>
+ <!-- Accessibility: Voice Search button -->
+ <string name="accessibility_voice_search_button">Voice Search</string>
+ <!-- Accessibility: AllApps button -->
+ <string name="accessibility_all_apps_button">Applications</string>
+ <!-- Accessibility: Customize button -->
+ <string name="accessibility_customize_button">Customize</string>
+ <!-- Accessibility: Delete button -->
+ <string name="accessibility_delete_button">Remove</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/res/values/styles.xml b/res/values/styles.xml
index 0c74a6a..abe6ac4 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -35,17 +35,17 @@
</style>
<style name="WorkspaceIcon">
- <item name="android:textSize">13dip</item>
- <item name="android:singleLine">true</item>
- <item name="android:ellipsize">marquee</item>
- <item name="android:shadowColor">#B0000000</item>
- <item name="android:shadowRadius">2.0</item>
- <item name="android:textColor">#FFF</item>
- <item name="android:gravity">center_horizontal</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:paddingLeft">5dip</item>
<item name="android:paddingRight">5dip</item>
+ <item name="android:gravity">center_horizontal</item>
+ <item name="android:singleLine">true</item>
+ <item name="android:ellipsize">marquee</item>
+ <item name="android:textSize">13dip</item>
+ <item name="android:textColor">#FFF</item>
+ <item name="android:shadowRadius">2.0</item>
+ <item name="android:shadowColor">#B0000000</item>
</style>
<style name="WorkspaceIcon.AllApps">
@@ -54,7 +54,7 @@
<style name="WorkspaceIcon.Portrait">
<item name="android:drawablePadding">5dip</item>
- <item name="android:paddingTop">4dip</item>
+ <item name="android:paddingTop">0dip</item>
<item name="android:layout_marginLeft">3dip</item>
<item name="android:layout_marginRight">3dip</item>
<item name="android:layout_marginTop">13dip</item>
@@ -72,24 +72,19 @@
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">match_parent</item>
<item name="android:gravity">center</item>
- <item name="android:paddingLeft">40dp</item>
- <item name="android:paddingRight">40dp</item>
- <item name="android:paddingTop">15dp</item>
- <item name="android:paddingBottom">20dp</item>
- <item name="android:textColor">@color/tab_widget_indicator_color</item>
+ <item name="android:paddingLeft">15dp</item>
+ <item name="android:paddingRight">15dp</item>
+ <item name="android:paddingTop">10dp</item>
+ <item name="android:paddingBottom">15dp</item>
<item name="android:background">@drawable/tab_widget_indicator_selector</item>
- <item name="android:textSize">20sp</item>
+ <item name="android:textColor">@color/tab_widget_indicator_color</item>
+ <item name="android:textSize">16sp</item>
<item name="android:shadowColor">#393939</item>
<item name="android:shadowDx">0.0</item>
<item name="android:shadowDy">1.0</item>
<item name="android:shadowRadius">1.0</item>
</style>
- <style name="TabIndicator.Portrait">
- <item name="android:paddingLeft">20dp</item>
- <item name="android:paddingRight">20dp</item>
- </style>
-
<style name="SearchButton" parent="@android:style/Widget.Button.Small">
<item name="android:paddingTop">7dip</item>
<item name="android:paddingBottom">9dip</item>
@@ -97,6 +92,29 @@
<item name="android:paddingRight">10dip</item>
</style>
+ <style name="MarketButton">
+ <item name="android:paddingRight">20dp</item>
+ <item name="android:text">@string/market</item>
+ <item name="android:textColor">@color/workspace_all_apps_and_delete_zone_text_color</item>
+ <item name="android:textSize">18sp</item>
+ <item name="android:shadowColor">@color/workspace_all_apps_and_delete_zone_text_shadow_color</item>
+ <item name="android:shadowDx">0.0</item>
+ <item name="android:shadowDy">0.0</item>
+ <item name="android:shadowRadius">2.0</item>
+ </style>
+
+ <style name="DeleteZone">
+ <item name="android:drawableLeft">@drawable/delete_zone_selector</item>
+ <item name="android:drawablePadding">@dimen/delete_zone_drawable_padding</item>
+ <item name="android:paddingRight">20dp</item>
+ <item name="android:textColor">@color/workspace_all_apps_and_delete_zone_text_color</item>
+ <item name="android:textSize">18sp</item>
+ <item name="android:shadowColor">@color/workspace_all_apps_and_delete_zone_text_shadow_color</item>
+ <item name="android:shadowDx">0.0</item>
+ <item name="android:shadowDy">0.0</item>
+ <item name="android:shadowRadius">2.0</item>
+ </style>
+
<style name="HotseatButton">
<item name="android:paddingLeft">12dip</item>
<item name="android:paddingRight">12dip</item>
@@ -116,4 +134,7 @@
<item name="android:background">@drawable/hotseat_bg_right</item>
</style>
+ <style name="config_orientation">
+ <item name="@android:screenOrientation">nosensor</item>
+ </style>
</resources>
diff --git a/src/com/android/launcher2/AccessibleTabView.java b/src/com/android/launcher2/AccessibleTabView.java
new file mode 100644
index 0000000..101f139
--- /dev/null
+++ b/src/com/android/launcher2/AccessibleTabView.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.TextView;
+
+/**
+ * We use a custom tab view to process our own focus traversals.
+ */
+public class AccessibleTabView extends TextView {
+ public AccessibleTabView(Context context) {
+ super(context);
+ }
+
+ public AccessibleTabView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AccessibleTabView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return FocusHelper.handleTabKeyEvent(this, keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return FocusHelper.handleTabKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ }
+}
diff --git a/src/com/android/launcher2/AddAdapter.java b/src/com/android/launcher2/AddAdapter.java
index 24c31ff..6f97d72 100644
--- a/src/com/android/launcher2/AddAdapter.java
+++ b/src/com/android/launcher2/AddAdapter.java
@@ -40,7 +40,6 @@
public static final int ITEM_SHORTCUT = 0;
public static final int ITEM_APPWIDGET = 1;
- public static final int ITEM_LIVE_FOLDER = 2;
public static final int ITEM_WALLPAPER = 3;
/**
@@ -76,9 +75,6 @@
mItems.add(new ListItem(res, R.string.group_widgets,
R.drawable.ic_launcher_appwidget, ITEM_APPWIDGET));
- mItems.add(new ListItem(res, R.string.group_live_folders,
- R.drawable.ic_launcher_folder, ITEM_LIVE_FOLDER));
-
mItems.add(new ListItem(res, R.string.group_wallpapers,
R.drawable.ic_launcher_wallpaper, ITEM_WALLPAPER));
diff --git a/src/com/android/launcher2/AllApps2D.java b/src/com/android/launcher2/AllApps2D.java
index 66d9395..44af7b7 100644
--- a/src/com/android/launcher2/AllApps2D.java
+++ b/src/com/android/launcher2/AllApps2D.java
@@ -143,7 +143,7 @@
homeButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
}
});
}
@@ -158,8 +158,10 @@
this(context, attrs);
}
- public void setLauncher(Launcher launcher) {
+ @Override
+ public void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
+ mDragController = dragController;
}
public boolean onKey(View v, int keyCode, KeyEvent event) {
@@ -167,7 +169,7 @@
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
break;
default:
return false;
@@ -190,7 +192,7 @@
app = new ApplicationInfo(app);
mDragController.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
return true;
}
@@ -202,16 +204,11 @@
}
@Override
- public void setDragController(DragController dragger) {
- mDragController = dragger;
- }
-
- @Override
public void onDragViewVisible() {
}
@Override
- public void onDropCompleted(View target, boolean success) {
+ public void onDropCompleted(View target, Object dragInfo, boolean success) {
}
/**
@@ -313,19 +310,9 @@
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);
}
}
@@ -351,6 +338,10 @@
public void surrender() {
}
+
+ public void reset() {
+ // Do nothing
+ }
}
diff --git a/src/com/android/launcher2/AllApps3D.java b/src/com/android/launcher2/AllApps3D.java
index 2ecf761..0e512c6 100644
--- a/src/com/android/launcher2/AllApps3D.java
+++ b/src/com/android/launcher2/AllApps3D.java
@@ -155,13 +155,6 @@
setRenderScriptGL(sRS);
}
- final DisplayMetrics metrics = getResources().getDisplayMetrics();
- final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
- mColumnsPerPage = isPortrait ? Defines.COLUMNS_PER_PAGE_PORTRAIT :
- Defines.COLUMNS_PER_PAGE_LANDSCAPE;
- mRowsPerPage = isPortrait ? Defines.ROWS_PER_PAGE_PORTRAIT :
- Defines.ROWS_PER_PAGE_LANDSCAPE;
-
if (sRollo != null) {
sRollo.mAllApps = this;
sRollo.mRes = getResources();
@@ -208,8 +201,10 @@
setSoundEffectsEnabled(old);
}
- public void setLauncher(Launcher launcher) {
+ @Override
+ public void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
+ mDragController = dragController;
}
@Override
@@ -231,6 +226,12 @@
super.surfaceChanged(holder, format, w, h);
+ final boolean isPortrait = w < h;
+ mColumnsPerPage = isPortrait ? Defines.COLUMNS_PER_PAGE_PORTRAIT :
+ Defines.COLUMNS_PER_PAGE_LANDSCAPE;
+ mRowsPerPage = isPortrait ? Defines.ROWS_PER_PAGE_PORTRAIT :
+ Defines.ROWS_PER_PAGE_LANDSCAPE;
+
if (mSurrendered) return;
mHaveSurface = true;
@@ -350,7 +351,7 @@
if (mArrowNavigation) {
if (mLastSelection == SELECTION_HOME) {
reallyPlaySoundEffect(SoundEffectConstants.CLICK);
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
} else {
int whichApp = sRollo.mScript.get_gSelectedIconIndex();
if (whichApp >= 0) {
@@ -637,7 +638,7 @@
if ((isPortrait && y > mTouchYBorders[mTouchYBorders.length-1]) ||
(!isPortrait && x > mTouchXBorders[mTouchXBorders.length-1])) {
reallyPlaySoundEffect(SoundEffectConstants.CLICK);
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
}
sRollo.setHomeSelected(SELECTED_NONE);
}
@@ -685,18 +686,18 @@
&& 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);
+ mLauncher.lockScreenOrientation();
+ mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, bmp);
+ mDragController.startDrag(
+ bmp, screenX, screenY, this, app, DragController.DRAG_ACTION_COPY);
- mLauncher.closeAllApps(true);
+ mLauncher.showWorkspace(true);
}
return true;
}
@@ -739,16 +740,13 @@
}
@Override
- public void setDragController(DragController dragger) {
- mDragController = dragger;
- }
-
- @Override
public void onDragViewVisible() {
}
@Override
- public void onDropCompleted(View target, boolean success) {
+ public void onDropCompleted(View target, Object dragInfo, boolean success) {
+ mLauncher.getWorkspace().onDragStopped(success);
+ mLauncher.unlockScreenOrientation();
}
/**
@@ -1047,13 +1045,16 @@
i.ScaleOffset.x = (2.f / 480.f);
i.ScaleOffset.y = 0;
i.ScaleOffset.z = -((float)w / 2) - 0.25f;
- i.ScaleOffset.w = -380.25f;
- i.BendPos.x = 120.f;
- i.BendPos.y = 680.f;
- if (w > h) {
- i.ScaleOffset.z = 40.f;
- i.ScaleOffset.w = h - 40.f;
- i.BendPos.y = 1.f;
+ if (w < h) {
+ // portrait
+ i.ScaleOffset.w = -380.25f;
+ i.BendPos.x = 120.f; // bottom of screen
+ i.BendPos.y = h - 82.f; // top of screen
+ } else {
+ // landscape
+ i.ScaleOffset.w = -206.25f;
+ i.BendPos.x = 50.f;
+ i.BendPos.y = h - 30.f;
}
mUniformAlloc.set(i, 0, true);
}
@@ -1093,7 +1094,7 @@
" float aDy = cos(bendAngle);\n" +
" float aDz = sin(bendAngle);\n" +
- " float scale = (2.0 / 480.0);\n" +
+ " float scale = (2.0 / " + mWidth + ".0);\n" +
" float x = UNI_Position.x + UNI_ImgSize.x * (1.0 - ani) * (ATTRIB_position.x - 0.5);\n" +
" float ys= UNI_Position.y + UNI_ImgSize.y * (1.0 - ani) * ATTRIB_position.y;\n" +
" float y = 0.0;\n" +
@@ -1468,4 +1469,8 @@
sRS.contextDump();
}
}
+
+ public void reset() {
+ // Do nothing
+ }
}
diff --git a/src/com/android/launcher2/AllAppsBackground.java b/src/com/android/launcher2/AllAppsBackground.java
new file mode 100644
index 0000000..5292d0a
--- /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 daa5d64..59ba57b 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -24,6 +24,7 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -63,7 +64,12 @@
private int mAppFilter = ALL_APPS_FLAG;
private final LayoutInflater mInflater;
+ private boolean mAllowHardwareLayerCreation;
+ private boolean mFirstMeasure = true;
+
+ private int mPageContentWidth;
+ private boolean mHasMadeSuccessfulDrop;
public AllAppsPagedView(Context context) {
this(context, null);
@@ -79,12 +85,14 @@
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);
Resources r = context.getResources();
setDragSlopeThreshold(
- r.getInteger(R.integer.config_allAppsDrawerDragSlopeThreshold) / 100.0f);
+ r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold) / 100.0f);
}
@Override
@@ -94,14 +102,51 @@
}
@Override
- public void setLauncher(Launcher launcher) {
- mLauncher = launcher;
- mLauncher.setAllAppsPagedView(this);
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+ if (mFirstMeasure) {
+ mFirstMeasure = false;
+
+ // TODO: actually calculate mCellCountX/mCellCountY as some function of
+ // widthSize and heightSize
+ //mCellCountX = ?;
+ //mCellCountY = ?;
+
+ // Since mCellCountX/mCellCountY changed, we need to update the pages
+ invalidatePageData();
+
+ // Create a dummy page and set it up to find out the content width (used by our parent)
+ PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
+ setupPage(layout);
+ mPageContentWidth = layout.getContentWidth();
+ }
+ }
+
+ 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 setDragController(DragController dragger) {
- mDragController = dragger;
+ public void setup(Launcher launcher, DragController dragController) {
+ mLauncher = launcher;
+ mLauncher.setAllAppsPagedView(this);
+ mDragController = dragController;
}
public void setAppFilter(int filterType) {
@@ -113,14 +158,16 @@
}
}
+ void resetSuccessfulDropFlag() {
+ mHasMadeSuccessfulDrop = false;
+ }
+
@Override
public void zoom(float zoom, boolean animate) {
mZoom = zoom;
cancelLongPress();
if (isVisible()) {
- getParent().bringChildToFront(this);
- setVisibility(View.VISIBLE);
if (animate) {
startAnimation(AnimationUtils.loadAnimation(getContext(),
R.anim.all_apps_2d_fade_in));
@@ -139,7 +186,6 @@
protected void onAnimationEnd() {
if (!isVisible()) {
- setVisibility(View.GONE);
mZoom = 0.0f;
endChoiceMode();
@@ -201,11 +247,21 @@
}
}
- 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 +294,12 @@
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];
@@ -253,6 +309,16 @@
c.translate((v.getWidth() - icon.getIntrinsicWidth()) / 2, v.getPaddingTop());
icon.draw(c);
+ Rect dragRect = null;
+ if (v instanceof TextView) {
+ int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+ int top = v.getPaddingTop();
+ int left = (b.getWidth() - iconSize) / 2;
+ int right = left + iconSize;
+ int bottom = top + iconSize;
+ dragRect = new Rect(left, top, right, bottom);
+ }
+
// We toggle the checked state _after_ we create the view for the drag in case toggling the
// checked state changes the view's look
if (v instanceof Checkable) {
@@ -272,7 +338,7 @@
// Start the drag
mLauncher.lockScreenOrientation();
mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
- mDragController.startDrag(v, b, this, app, DragController.DRAG_ACTION_COPY, null);
+ mDragController.startDrag(v, b, this, app, DragController.DRAG_ACTION_COPY, dragRect);
b.recycle();
return true;
}
@@ -282,7 +348,7 @@
}
@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();
@@ -290,6 +356,16 @@
tearDownDragMode();
mLauncher.getWorkspace().onDragStopped(success);
mLauncher.unlockScreenOrientation();
+
+ if (!success && !mHasMadeSuccessfulDrop) {
+ mLauncher.getWorkspace().shrink(Workspace.ShrinkState.BOTTOM_HIDDEN);
+ } else {
+ mHasMadeSuccessfulDrop |= success;
+ }
+ }
+
+ int getPageContentWidth() {
+ return mPageContentWidth;
}
@Override
@@ -376,6 +452,7 @@
}
mFilteredApps = rebuildFilteredApps(mApps);
}
+
@Override
public void removeApps(ArrayList<ApplicationInfo> list) {
removeAppsWithoutInvalidate(list);
@@ -390,12 +467,14 @@
}
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;
@@ -411,8 +490,25 @@
// do nothing?
}
+ public void reset() {
+ setCurrentPage(0);
+ invalidatePageData();
+ }
+
+ private void setupPage(PagedViewCellLayout layout) {
+ layout.setCellCount(mCellCountX, mCellCountY);
+ layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, mPageLayoutPaddingRight,
+ mPageLayoutPaddingBottom);
+ layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap);
+ }
+
@Override
public void syncPages() {
+ if (mFirstMeasure) {
+ // We don't know our size yet, which means we haven't calculated cell count x/y;
+ // onMeasure will call us once we figure out our size
+ return;
+ }
// ensure that we have the right number of pages (min of 1, since we have placeholders)
int numPages = Math.max(1,
(int) Math.ceil((float) mFilteredApps.size() / (mCellCountX * mCellCountY)));
@@ -425,11 +521,10 @@
// add any necessary pages
for (int i = curNumPages; i < numPages; ++i) {
PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
- layout.enableHardwareLayers();
- layout.setCellCount(mCellCountX, mCellCountY);
- layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
- mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
- layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap);
+ if (mAllowHardwareLayerCreation) {
+ layout.allowHardwareLayerCreation();
+ }
+ setupPage(layout);
addView(layout);
}
@@ -440,6 +535,7 @@
@Override
public void syncPageItems(int page) {
// Ensure that we have the right number of items on the pages
+ final int numPages = getPageCount();
final int cellsPerPage = mCellCountX * mCellCountY;
final int startIndex = page * cellsPerPage;
final int endIndex = Math.min(startIndex + cellsPerPage, mFilteredApps.size());
@@ -448,6 +544,7 @@
if (!mFilteredApps.isEmpty()) {
int curNumPageItems = layout.getPageChildCount();
int numPageItems = endIndex - startIndex;
+ boolean createHolographicOutlines = (numPages > 1);
// If we were previously an empty page, then restart anew
boolean wasEmptyPage = false;
@@ -483,12 +580,12 @@
}
// Actually reapply to the existing text views
- final int numPages = getPageCount();
for (int i = startIndex; i < endIndex; ++i) {
final int index = i - startIndex;
final ApplicationInfo info = mFilteredApps.get(i);
PagedViewIcon icon = (PagedViewIcon) layout.getChildOnPageAt(index);
- icon.applyFromApplicationInfo(info, mPageViewIconCache, true, (numPages > 1));
+ icon.applyFromApplicationInfo(
+ info, mPageViewIconCache, true, createHolographicOutlines);
PagedViewCellLayout.LayoutParams params =
(PagedViewCellLayout.LayoutParams) icon.getLayoutParams();
@@ -496,6 +593,9 @@
params.cellY = index / mCellCountX;
}
+ // We should try and sync all the holographic icons after adding/removing new items
+ layout.reloadHolographicIcons(createHolographicOutlines);
+
// Default to left-aligned icons
layout.enableCenteredContent(false);
} else {
@@ -510,11 +610,13 @@
}
// Center-align the message
+ final boolean createHolographicOutlines = (numPages > 1);
layout.enableCenteredContent(true);
layout.removeAllViewsOnPage();
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 47a5bf7..a2f10f5 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -29,6 +29,7 @@
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;
@@ -38,7 +39,7 @@
/**
* 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 +47,8 @@
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 +67,8 @@
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");
}
@@ -75,6 +80,8 @@
}
};
+ // Create the tabs and wire them up properly
+ AllAppsTabKeyEventListener keyListener = new AllAppsTabKeyEventListener();
TextView tabView;
TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
@@ -85,11 +92,17 @@
tabView.setText(mContext.getString(R.string.all_apps_tab_downloaded));
addTab(newTabSpec(TAG_DOWNLOADED).setIndicator(tabView).setContent(contentFactory));
+ // Setup the key listener to jump between the last tab view and the market icon
+ View lastTab = tabWidget.getChildTabViewAt(tabWidget.getTabCount() - 1);
+ lastTab.setOnKeyListener(keyListener);
+ View shopButton = findViewById(R.id.market_button);
+ shopButton.setOnKeyListener(keyListener);
+
setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
// animate the changing of the tab content by fading pages in and out
final Resources res = getResources();
- final int duration = res.getInteger(R.integer.config_tabTransitionTime);
+ final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
final float alpha = mAllApps.getAlpha();
ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mAllApps, "alpha", alpha, 0.0f).
setDuration(duration);
@@ -112,19 +125,16 @@
}
});
+
// It needs to be INVISIBLE so that it will be measured in the layout.
// Otherwise the animations is messed up when we show it for the first time.
setVisibility(INVISIBLE);
}
@Override
- public void setLauncher(Launcher launcher) {
- mAllApps.setLauncher(launcher);
- }
-
- @Override
- public void setDragController(DragController dragger) {
- mAllApps.setDragController(dragger);
+ public void setup(Launcher launcher, DragController dragController) {
+ mLauncher = launcher;
+ mAllApps.setup(launcher, dragController);
}
@Override
@@ -154,7 +164,20 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
- mFirstLayout = false;
+ if (mFirstLayout) {
+ mFirstLayout = false;
+ // Set the width of the tab bar properly
+ int pageWidth = mAllApps.getPageContentWidth();
+ TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+ View allAppsTabBar = (View) findViewById(R.id.all_apps_tab_bar);
+ if (allAppsTabBar == null) throw new Resources.NotFoundException();
+ int tabWidgetPadding = 0;
+ final int childCount = tabWidget.getChildCount();
+ if (childCount > 0) {
+ tabWidgetPadding += tabWidget.getChildAt(0).getPaddingLeft() * 2;
+ }
+ allAppsTabBar.getLayoutParams().width = pageWidth + tabWidgetPadding;
+ }
super.onLayout(changed, l, t, r, b);
}
@@ -164,6 +187,44 @@
}
@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);
}
@@ -193,6 +254,10 @@
mAllApps.surrender();
}
+ public void reset() {
+ mAllApps.reset();
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getY() > mAllApps.getBottom()) {
@@ -200,4 +265,12 @@
}
return true;
}
+
+ @Override
+ public int getDescendantFocusability() {
+ if (getVisibility() != View.VISIBLE) {
+ return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
+ return super.getDescendantFocusability();
+ }
}
diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java
index 007ecf8..e8ca61f 100644
--- a/src/com/android/launcher2/AllAppsView.java
+++ b/src/com/android/launcher2/AllAppsView.java
@@ -23,9 +23,7 @@
public void zoomed(float zoom);
}
- public void setLauncher(Launcher launcher);
-
- public void setDragController(DragController dragger);
+ public void setup(Launcher launcher, DragController dragController);
public void zoom(float zoom, boolean animate);
@@ -41,6 +39,9 @@
public void updateApps(ArrayList<ApplicationInfo> list);
+ // Resets the AllApps page to the front
+ public void reset();
+
public void dumpState();
public void surrender();
diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java
new file mode 100644
index 0000000..4390c59
--- /dev/null
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -0,0 +1,350 @@
+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 DragLayer mDragLayer;
+ private Workspace mWorkspace;
+ 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, DragLayer dragLayer) {
+
+ super(context);
+ mContext = context;
+ mItemInfo = itemInfo;
+ mCellLayout = cellLayout;
+ mWidgetView = widgetView;
+ mResizeMode = widgetView.getAppWidgetInfo().resizeMode;
+ mDragLayer = dragLayer;
+ mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
+
+ 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(mDragLayer.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(mDragLayer.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);
+ DragLayer.LayoutParams lp = (DragLayer.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);
+ mWidgetView.requestLayout();
+ }
+
+ /**
+ * 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 DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
+ int xOffset = mCellLayout.getLeft() + mCellLayout.getLeftPadding() - mWorkspace.getScrollX();
+ int yOffset = mCellLayout.getTop() + mCellLayout.getTopPadding() - mWorkspace.getScrollY();
+
+ int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding;
+ int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding;
+ int newX = mWidgetView.getLeft() - mBackgroundPadding + xOffset;
+ int newY = mWidgetView.getTop() - mBackgroundPadding + yOffset;
+
+ // We need to make sure the frame stays within the bounds of the CellLayout
+ if (newY < 0) {
+ newHeight -= -newY;
+ newY = 0;
+ }
+ if (newY + newHeight > mDragLayer.getHeight()) {
+ newHeight -= newY + newHeight - mDragLayer.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 3adea37..1d948b7 100644
--- a/src/com/android/launcher2/ApplicationInfo.java
+++ b/src/com/android/launcher2/ApplicationInfo.java
@@ -59,9 +59,9 @@
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 @@
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;
+
+ if ((appFlags & android.content.pm.ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+ flags |= UPDATED_SYSTEM_APP_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;
- }
} catch (NameNotFoundException e) {
Log.d(TAG, "PackageManager.getApplicationInfo failed for " + packageName);
}
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index 78a9d2d..f42aaf5 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -50,7 +50,7 @@
int colour = getContext().getResources().getColor(R.color.app_info_filter);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(colour, PorterDuff.Mode.SRC_ATOP));
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
// For the application info drop target, we just ignore the left padding since we don't want
// to overlap with the delete zone padding
int tb = getResources().getDimensionPixelSize(
@@ -162,10 +162,13 @@
// Fade in the overlapping views
if (mOverlappingViews != null) {
for (View view : mOverlappingViews) {
- ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 1.0f);
- oa.setDuration(sFadeInAnimationDuration);
- mFadeAnimator.play(oa);
- view.setVisibility(VISIBLE);
+ // Check whether the views are enabled first, before trying to fade them in
+ if (view.isEnabled()) {
+ ObjectAnimator oa = ObjectAnimator.ofFloat(view, "alpha", 1.0f);
+ oa.setDuration(sFadeInAnimationDuration);
+ mFadeAnimator.play(oa);
+ view.setVisibility(VISIBLE);
+ }
}
}
mFadeAnimator.start();
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
new file mode 100644
index 0000000..87be63e
--- /dev/null
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -0,0 +1,1084 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.app.WallpaperManager;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.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.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.LruCache;
+import android.util.Slog;
+import android.util.TypedValue;
+import android.util.Xml;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+
+public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
+ AllAppsView, View.OnClickListener, DragSource {
+ static final String LOG_TAG = "AppsCustomizePagedView";
+
+ /**
+ * The different content types that this paged view can show.
+ */
+ public enum ContentType {
+ Applications,
+ Widgets,
+ Wallpapers
+ }
+
+ // Refs
+ private Launcher mLauncher;
+ private DragController mDragController;
+ private final LayoutInflater mLayoutInflater;
+ private final PackageManager mPackageManager;
+
+ // Content
+ private ContentType mContentType;
+ private ArrayList<ApplicationInfo> mApps;
+ private List<Object> mWidgets;
+ private List<ResolveInfo> mWallpapers;
+
+ // Caching
+ private Drawable mDefaultWidgetBackground;
+ private final int sWidgetPreviewCacheSize = 1 * 1024 * 1024; // 1 MiB
+ private LruCache<Object, Bitmap> mWidgetPreviewCache;
+ private IconCache mIconCache;
+
+ // Dimens
+ private int mContentWidth;
+ private int mMaxWidgetSpan, mMinWidgetSpan;
+ private int mCellWidthGap, mCellHeightGap;
+ private int mWidgetCountX, mWidgetCountY;
+ private int mWallpaperCountX, mWallpaperCountY;
+ private final int mWidgetPreviewIconPaddedDimension;
+ private final float sWidgetPreviewIconPaddingPercentage = 0.25f;
+ private PagedViewCellLayout mWidgetSpacingLayout;
+
+ // Animations
+ private final float ANIMATION_SCALE = 0.5f;
+ private final int TRANSLATE_ANIM_DURATION = 400;
+ private final int DROP_ANIM_DURATION = 200;
+
+ public AppsCustomizePagedView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mLayoutInflater = LayoutInflater.from(context);
+ mPackageManager = context.getPackageManager();
+ mContentType = ContentType.Applications;
+ mApps = new ArrayList<ApplicationInfo>();
+ mWidgets = new ArrayList<Object>();
+ mWallpapers = new ArrayList<ResolveInfo>();
+ mIconCache = ((LauncherApplication) context.getApplicationContext()).getIconCache();
+ mWidgetPreviewCache = new LruCache<Object, Bitmap>(sWidgetPreviewCacheSize) {
+ protected int sizeOf(Object key, Bitmap value) {
+ return value.getByteCount();
+ }
+ };
+
+ // Save the default widget preview background
+ Resources resources = context.getResources();
+ mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
+ mCellCountX = a.getInt(R.styleable.PagedView_cellCountX, 6);
+ mCellCountY = a.getInt(R.styleable.PagedView_cellCountY, 4);
+ a.recycle();
+ a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0);
+ mCellWidthGap =
+ a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 10);
+ mCellHeightGap =
+ a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 10);
+ mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2);
+ mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2);
+ mWallpaperCountX = a.getInt(R.styleable.AppsCustomizePagedView_wallpaperCountX, 2);
+ mWallpaperCountY = a.getInt(R.styleable.AppsCustomizePagedView_wallpaperCountY, 2);
+ a.recycle();
+
+ // Create a dummy page that we can use to approximate the cell dimensions of widgets and
+ // the content width (to be used by our parent)
+ mWidgetSpacingLayout = new PagedViewCellLayout(context);
+ setupPage(mWidgetSpacingLayout);
+ mContentWidth = mWidgetSpacingLayout.getContentWidth();
+
+ // The max widget span is the length N, such that NxN is the largest bounds that the widget
+ // preview can be before applying the widget scaling
+ mMinWidgetSpan = 1;
+ mMaxWidgetSpan = 3;
+
+ // The padding on the non-matched dimension for the default widget preview icons
+ // (top + bottom)
+ int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+ mWidgetPreviewIconPaddedDimension =
+ (int) (iconSize * (1 + (2 * sWidgetPreviewIconPaddingPercentage)));
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ mCenterPagesVertically = false;
+
+ Context context = getContext();
+ Resources r = context.getResources();
+ setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
+ }
+
+ public void onPackagesUpdated() {
+ // Get the list of widgets and shortcuts
+ mWidgets.clear();
+ mWidgets.addAll(AppWidgetManager.getInstance(mLauncher).getInstalledProviders());
+ Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+ mWidgets.addAll(mPackageManager.queryIntentActivities(shortcutsIntent, 0));
+ Collections.sort(mWidgets,
+ new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
+
+ // Get the list of wallpapers
+ Intent wallpapersIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
+ mWallpapers = mPackageManager.queryIntentActivities(wallpapersIntent,
+ PackageManager.GET_META_DATA);
+ Collections.sort(mWallpapers,
+ new LauncherModel.ShortcutNameComparator(mPackageManager));
+ }
+
+ /**
+ * 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) {
+ // On the phone, we only want to fade the widget preview out
+ float[] position = new float[2];
+ position[0] = layout.getWidth() / 2;
+ position[1] = layout.getHeight() / 2;
+
+ mLauncher.getWorkspace().mapPointFromChildToSelf(layout, position);
+
+ int dragViewWidth = dragView.getMeasuredWidth();
+ int dragViewHeight = dragView.getMeasuredHeight();
+ float heightOffset = 0;
+ float widthOffset = 0;
+
+ if (dragView instanceof ImageView) {
+ Drawable d = ((ImageView) dragView).getDrawable();
+ int width = d.getIntrinsicWidth();
+ int height = d.getIntrinsicHeight();
+
+ if ((1.0 * width / height) >= (1.0f * dragViewWidth) / dragViewHeight) {
+ float f = (dragViewWidth / (width * 1.0f));
+ heightOffset = ANIMATION_SCALE * (dragViewHeight - f * height) / 2;
+ } else {
+ float f = (dragViewHeight / (height * 1.0f));
+ widthOffset = ANIMATION_SCALE * (dragViewWidth - f * width) / 2;
+ }
+ }
+ final float toX = position[0] - dragView.getMeasuredWidth() / 2 + widthOffset;
+ final float toY = position[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);
+
+ // Translate the item to the center of the appropriate home screen
+ animateIntoPosition(dragCopy, toX, toY, null);
+
+ // 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);
+ }
+
+ /**
+ * 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));
+ 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();
+ }
+
+ /**
+ * 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(new DecelerateInterpolator(2.5f));
+ anim.setDuration(TRANSLATE_ANIM_DURATION);
+ if (endRunnable != null) {
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ endRunnable.run();
+ }
+ });
+ }
+ anim.start();
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v instanceof PagedViewIcon) {
+ // Animate some feedback to the click
+ final ApplicationInfo appInfo = (ApplicationInfo) v.getTag();
+ animateClickFeedback(v, new Runnable() {
+ @Override
+ public void run() {
+ mLauncher.startActivitySafely(appInfo.intent, appInfo);
+ }
+ });
+ } else if (v instanceof PagedViewWidget) {
+ final ResolveInfo info = (ResolveInfo) v.getTag();
+ if (mWallpapers.contains(info)) {
+ // Start the wallpaper picker
+ animateClickFeedback(v, new Runnable() {
+ @Override
+ public void run() {
+ // add the shortcut
+ Intent createWallpapersIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
+ ComponentName name = new ComponentName(info.activityInfo.packageName,
+ info.activityInfo.name);
+ createWallpapersIntent.setComponent(name);
+ mLauncher.processWallpaper(createWallpapersIntent);
+ }
+ });
+ } else {
+ // Add the widget to the current workspace screen
+ Workspace w = mLauncher.getWorkspace();
+ int currentWorkspaceScreen = mLauncher.getCurrentWorkspaceScreen();
+ final CellLayout cl = (CellLayout) w.getChildAt(currentWorkspaceScreen);
+ final View dragView = v.findViewById(R.id.widget_preview);
+ final ItemInfo itemInfo = (ItemInfo) v.getTag();
+ animateClickFeedback(v, new Runnable() {
+ @Override
+ public void run() {
+ cl.calculateSpans(itemInfo);
+ if (cl.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY)) {
+ if (LauncherApplication.isScreenLarge()) {
+ animateItemOntoScreen(dragView, cl, itemInfo);
+ } else {
+ mLauncher.addExternalItemToScreen(itemInfo, cl);
+ itemInfo.dropPos = null;
+ }
+
+ // Hide the pane so we can see the workspace we dropped on
+ mLauncher.showWorkspace(true);
+ } else {
+ mLauncher.showOutOfSpaceMessage();
+ }
+ }
+ });
+ }
+ }
+ }
+
+ /*
+ * PagedViewWithDraggableItems implementation
+ */
+ @Override
+ protected void determineDraggingStart(android.view.MotionEvent ev) {
+ // Disable dragging by pulling an app down for now.
+ }
+ private void beginDraggingApplication(View v) {
+ // Make a copy of the ApplicationInfo
+ ApplicationInfo appInfo = new ApplicationInfo((ApplicationInfo) v.getTag());
+
+ // Show the uninstall button if the app is uninstallable.
+ if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) {
+ DeleteZone allAppsDeleteZone = (DeleteZone)
+ mLauncher.findViewById(R.id.all_apps_delete_zone);
+ allAppsDeleteZone.setDragAndDropEnabled(true);
+
+ if ((appInfo.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);
+ }
+ }
+
+ // Show the info button
+ ApplicationInfoDropTarget allAppsInfoButton =
+ (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
+ allAppsInfoButton.setDragAndDropEnabled(true);
+
+ // Compose the drag image (top compound drawable, index is 1)
+ final TextView tv = (TextView) v;
+ final Drawable icon = tv.getCompoundDrawables()[1];
+ Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ c.translate((v.getWidth() - icon.getIntrinsicWidth()) / 2, v.getPaddingTop());
+ icon.draw(c);
+
+ // Compose the visible rect of the drag image
+ Rect dragRect = null;
+ if (v instanceof TextView) {
+ int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+ int top = v.getPaddingTop();
+ int left = (b.getWidth() - iconSize) / 2;
+ int right = left + iconSize;
+ int bottom = top + iconSize;
+ dragRect = new Rect(left, top, right, bottom);
+ }
+
+ // Start the drag
+ mLauncher.lockScreenOrientation();
+ mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
+ mDragController.startDrag(v, b, this, appInfo, DragController.DRAG_ACTION_COPY, dragRect);
+ b.recycle();
+ }
+ private void beginDraggingWidget(View v) {
+ // Get the widget preview as the drag representation
+ ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
+ PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
+
+ // Compose the drag image
+ Bitmap b;
+ Drawable preview = image.getDrawable();
+ int w = preview.getIntrinsicWidth();
+ int h = preview.getIntrinsicHeight();
+ if (createItemInfo instanceof PendingAddWidgetInfo) {
+ PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) createItemInfo;
+ int[] spanXY = CellLayout.rectToCell(getResources(),
+ createWidgetInfo.minWidth, createWidgetInfo.minHeight, null);
+ createItemInfo.spanX = spanXY[0];
+ createItemInfo.spanY = spanXY[1];
+
+ b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+ renderDrawableToBitmap(preview, b, 0, 0, w, h, 1, 1);
+ } else {
+ // Workaround for the fact that we don't keep the original ResolveInfo associated with
+ // the shortcut around. To get the icon, we just render the preview image (which has
+ // the shortcut icon) to a new drag bitmap that clips the non-icon space.
+ b = Bitmap.createBitmap(mWidgetPreviewIconPaddedDimension,
+ mWidgetPreviewIconPaddedDimension, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ preview.draw(c);
+ createItemInfo.spanX = createItemInfo.spanY = 1;
+ }
+
+ // Start the drag
+ mLauncher.lockScreenOrientation();
+ mLauncher.getWorkspace().onDragStartedWithItemSpans(createItemInfo.spanX,
+ createItemInfo.spanY, b);
+ mDragController.startDrag(image, b, this, createItemInfo,
+ DragController.DRAG_ACTION_COPY, null);
+ b.recycle();
+ }
+ @Override
+ protected boolean beginDragging(View v) {
+ if (!super.beginDragging(v)) return false;
+
+ // Hide the pane so that the user can drop onto the workspace, we must do this first,
+ // due to how the drop target layout is computed when we start dragging to the workspace.
+ mLauncher.showWorkspace(true);
+
+ if (v instanceof PagedViewIcon) {
+ beginDraggingApplication(v);
+ } else if (v instanceof PagedViewWidget) {
+ beginDraggingWidget(v);
+ }
+
+ return true;
+ }
+ private void endDragging(boolean success) {
+ post(new Runnable() {
+ // Once the drag operation has fully completed, hence the post, we want to disable the
+ // deleteZone and the appInfoButton in all apps, and re-enable the instance which
+ // live in the workspace
+ public void run() {
+ // if onDestroy was called on Launcher, we might have already deleted the
+ // all apps delete zone / info button, so check if they are null
+ DeleteZone allAppsDeleteZone =
+ (DeleteZone) mLauncher.findViewById(R.id.all_apps_delete_zone);
+ ApplicationInfoDropTarget allAppsInfoButton =
+ (ApplicationInfoDropTarget) mLauncher.findViewById(R.id.all_apps_info_target);
+
+ if (allAppsDeleteZone != null) allAppsDeleteZone.setDragAndDropEnabled(false);
+ if (allAppsInfoButton != null) allAppsInfoButton.setDragAndDropEnabled(false);
+ }
+ });
+ mLauncher.getWorkspace().onDragStopped(success);
+ mLauncher.unlockScreenOrientation();
+ }
+
+ /*
+ * DragSource implementation
+ */
+ @Override
+ public void onDragViewVisible() {}
+ @Override
+ public void onDropCompleted(View target, Object dragInfo, boolean success) {
+ endDragging(success);
+
+ // Display an error message if the drag failed due to there not being enough space on the
+ // target layout we were dropping on.
+ if (!success) {
+ boolean showOutOfSpaceMessage = false;
+ if (target instanceof Workspace) {
+ int currentScreen = mLauncher.getCurrentWorkspaceScreen();
+ Workspace workspace = (Workspace) target;
+ CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
+ ItemInfo itemInfo = (ItemInfo) dragInfo;
+ if (layout != null) {
+ layout.calculateSpans(itemInfo);
+ showOutOfSpaceMessage =
+ !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
+ }
+ }
+ // TODO-APPS_CUSTOMIZE: We need to handle this for folders as well later.
+ if (showOutOfSpaceMessage) {
+ mLauncher.showOutOfSpaceMessage();
+ }
+ }
+ }
+
+ public void setContentType(ContentType type) {
+ mContentType = type;
+ setCurrentPage(0);
+ invalidatePageData();
+ }
+
+ /*
+ * Apps PagedView implementation
+ */
+ private void setVisibilityOnChildren(ViewGroup layout, int visibility) {
+ int childCount = layout.getChildCount();
+ for (int i = 0; i < childCount; ++i) {
+ layout.getChildAt(i).setVisibility(visibility);
+ }
+ }
+ private void setupPage(PagedViewCellLayout layout) {
+ layout.setCellCount(mCellCountX, mCellCountY);
+ layout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap);
+ layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+ mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+
+ // Note: We force a measure here to get around the fact that when we do layout calculations
+ // immediately after syncing, we don't have a proper width. That said, we already know the
+ // expected page width, so we can actually optimize by hiding all the TextView-based
+ // children that are expensive to measure, and let that happen naturally later.
+ setVisibilityOnChildren(layout, View.GONE);
+ int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
+ int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
+ layout.setMinimumWidth(getPageContentWidth());
+ layout.measure(widthSpec, heightSpec);
+ setVisibilityOnChildren(layout, View.VISIBLE);
+ }
+ public void syncAppsPages() {
+ // Ensure that we have the right number of pages
+ Context context = getContext();
+ int numPages = (int) Math.ceil((float) mApps.size() / (mCellCountX * mCellCountY));
+ for (int i = 0; i < numPages; ++i) {
+ PagedViewCellLayout layout = new PagedViewCellLayout(context);
+ setupPage(layout);
+ addView(layout);
+ }
+ }
+ public void syncAppsPageItems(int page) {
+ // ensure that we have the right number of items on the pages
+ int numPages = getPageCount();
+ int numCells = mCellCountX * mCellCountY;
+ int startIndex = page * numCells;
+ int endIndex = Math.min(startIndex + numCells, mApps.size());
+ PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
+ layout.removeAllViewsOnPage();
+ for (int i = startIndex; i < endIndex; ++i) {
+ ApplicationInfo info = mApps.get(i);
+ PagedViewIcon icon = (PagedViewIcon) mLayoutInflater.inflate(
+ R.layout.apps_customize_application, layout, false);
+ icon.applyFromApplicationInfo(
+ info, mPageViewIconCache, true, isHardwareAccelerated() && (numPages > 1));
+ icon.setOnClickListener(this);
+ icon.setOnLongClickListener(this);
+ icon.setOnTouchListener(this);
+
+ int index = i - startIndex;
+ int x = index % mCellCountX;
+ int y = index / mCellCountX;
+ layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+ }
+ }
+ /*
+ * Widgets PagedView implementation
+ */
+ private void setupPage(PagedViewGridLayout layout) {
+ layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+ mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+
+ // Note: We force a measure here to get around the fact that when we do layout calculations
+ // immediately after syncing, we don't have a proper width. That said, we already know the
+ // expected page width, so we can actually optimize by hiding all the TextView-based
+ // children that are expensive to measure, and let that happen naturally later.
+ setVisibilityOnChildren(layout, View.GONE);
+ int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.AT_MOST);
+ int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
+ layout.setMinimumWidth(getPageContentWidth());
+ layout.measure(widthSpec, heightSpec);
+ setVisibilityOnChildren(layout, View.VISIBLE);
+ }
+ private void renderDrawableToBitmap(Drawable d, Bitmap bitmap, int x, int y, int w, int h,
+ float scaleX, float scaleY) {
+ Canvas c = new Canvas();
+ if (bitmap != null) c.setBitmap(bitmap);
+ c.save();
+ c.scale(scaleX, scaleY);
+ Rect oldBounds = d.copyBounds();
+ d.setBounds(x, y, x + w, y + h);
+ d.draw(c);
+ d.setBounds(oldBounds); // Restore the bounds
+ c.restore();
+ }
+ private FastBitmapDrawable getShortcutPreview(ResolveInfo info, int cellWidth, int cellHeight) {
+ // Return the cached version if necessary
+ Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
+ if (cachedBitmap != null) {
+ return new FastBitmapDrawable(cachedBitmap);
+ }
+
+ Resources resources = mLauncher.getResources();
+ int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+ // We only need to make it wide enough so as not allow the preview to be scaled
+ int expectedWidth = cellWidth;
+ int expectedHeight = mWidgetPreviewIconPaddedDimension;
+ int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
+
+ // Render the icon
+ Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
+ Drawable icon = mIconCache.getFullResIcon(info, mPackageManager);
+ renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0,
+ mWidgetPreviewIconPaddedDimension, mWidgetPreviewIconPaddedDimension, 1f, 1f);
+ renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f);
+ FastBitmapDrawable iconDrawable = new FastBitmapDrawable(preview);
+ iconDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
+ mWidgetPreviewCache.put(info, preview);
+ return iconDrawable;
+ }
+ private FastBitmapDrawable getWidgetPreview(AppWidgetProviderInfo info, int cellHSpan,
+ int cellVSpan, int cellWidth, int cellHeight) {
+ // Return the cached version if necessary
+ Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
+ if (cachedBitmap != null) {
+ return new FastBitmapDrawable(cachedBitmap);
+ }
+
+ // Calculate the size of the drawable
+ cellHSpan = Math.max(mMinWidgetSpan, Math.min(mMaxWidgetSpan, cellHSpan));
+ cellVSpan = Math.max(mMinWidgetSpan, Math.min(mMaxWidgetSpan, cellVSpan));
+ int expectedWidth = mWidgetSpacingLayout.estimateCellWidth(cellHSpan);
+ int expectedHeight = mWidgetSpacingLayout.estimateCellHeight(cellVSpan);
+
+ // Scale down the bitmap to fit the space
+ float widgetPreviewScale = (float) cellWidth / expectedWidth;
+ expectedWidth = (int) (widgetPreviewScale * expectedWidth);
+ expectedHeight = (int) (widgetPreviewScale * expectedHeight);
+
+ // Load the preview image if possible
+ String packageName = info.provider.getPackageName();
+ Drawable drawable = null;
+ FastBitmapDrawable newDrawable = null;
+ if (info.previewImage != 0) {
+ drawable = mPackageManager.getDrawable(packageName, info.previewImage, null);
+ if (drawable == null) {
+ Log.w(LOG_TAG, "Can't load icon drawable 0x" + Integer.toHexString(info.icon)
+ + " for provider: " + info.provider);
+ } else {
+ // Scale down the preview to the dimensions we want
+ int imageWidth = drawable.getIntrinsicWidth();
+ int imageHeight = drawable.getIntrinsicHeight();
+ float aspect = (float) imageWidth / imageHeight;
+ int newWidth = imageWidth;
+ int newHeight = imageHeight;
+ if (aspect > 1f) {
+ newWidth = expectedWidth;
+ newHeight = (int) (imageHeight * ((float) expectedWidth / imageWidth));
+ } else {
+ newHeight = expectedHeight;
+ newWidth = (int) (imageWidth * ((float) expectedHeight / imageHeight));
+ }
+
+ Bitmap preview = Bitmap.createBitmap(newWidth, newHeight, Config.ARGB_8888);
+ renderDrawableToBitmap(drawable, preview, 0, 0, newWidth, newHeight, 1f, 1f);
+ newDrawable = new FastBitmapDrawable(preview);
+ newDrawable.setBounds(0, 0, newWidth, newHeight);
+ mWidgetPreviewCache.put(info, preview);
+ }
+ }
+
+ // Generate a preview image if we couldn't load one
+ if (drawable == null) {
+ Resources resources = mLauncher.getResources();
+ int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+
+ // Specify the dimensions of the bitmap
+ if (info.minWidth >= info.minHeight) {
+ expectedWidth = cellWidth;
+ expectedHeight = mWidgetPreviewIconPaddedDimension;
+ } else {
+ // Note that in vertical widgets, we might not have enough space due to the text
+ // label, so be conservative and use the width as a height bound
+ expectedWidth = mWidgetPreviewIconPaddedDimension;
+ expectedHeight = cellWidth;
+ }
+
+ Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
+ renderDrawableToBitmap(mDefaultWidgetBackground, preview, 0, 0, expectedWidth,
+ expectedHeight, 1f,1f);
+
+ // Draw the icon in the top left corner
+ try {
+ Drawable icon = null;
+ if (info.icon > 0) icon = mPackageManager.getDrawable(packageName, info.icon, null);
+ if (icon == null) icon = resources.getDrawable(R.drawable.ic_launcher_application);
+
+ int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
+ renderDrawableToBitmap(icon, preview, offset, offset, iconSize, iconSize, 1f, 1f);
+ } catch (Resources.NotFoundException e) {}
+
+ newDrawable = new FastBitmapDrawable(preview);
+ newDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
+ mWidgetPreviewCache.put(info, preview);
+ }
+ return newDrawable;
+ }
+ public void syncWidgetPages() {
+ // Ensure that we have the right number of pages
+ Context context = getContext();
+ int numWidgetsPerPage = mWidgetCountX * mWidgetCountY;
+ int numPages = (int) Math.ceil(mWidgets.size() / (float) numWidgetsPerPage);
+ for (int i = 0; i < numPages; ++i) {
+ PagedViewGridLayout layout = new PagedViewGridLayout(context, mWidgetCountX,
+ mWidgetCountY);
+ setupPage(layout);
+ addView(layout);
+ }
+ }
+ public void syncWidgetPageItems(int page) {
+ PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(page);
+ layout.removeAllViews();
+
+ // Calculate the dimensions of each cell we are giving to each widget
+ int numWidgetsPerPage = mWidgetCountX * mWidgetCountY;
+ int offset = page * numWidgetsPerPage;
+ int cellWidth = ((mWidgetSpacingLayout.getContentWidth() - mPageLayoutWidthGap
+ - ((mWidgetCountX - 1) * mCellWidthGap)) / mWidgetCountX);
+ int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap
+ - ((mWidgetCountY - 1) * mCellHeightGap)) / mWidgetCountY);
+ for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) {
+ Object rawInfo = mWidgets.get(offset + i);
+ PendingAddItemInfo createItemInfo = null;
+ PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
+ R.layout.apps_customize_widget, layout, false);
+ if (rawInfo instanceof AppWidgetProviderInfo) {
+ // Fill in the widget information
+ AppWidgetProviderInfo info = (AppWidgetProviderInfo) rawInfo;
+ createItemInfo = new PendingAddWidgetInfo(info, null, null);
+ final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
+ info.minHeight, null);
+ FastBitmapDrawable preview = getWidgetPreview(info, cellSpans[0], cellSpans[1],
+ cellWidth, cellHeight);
+ widget.applyFromAppWidgetProviderInfo(info, preview, -1, cellSpans, null, false);
+ widget.setTag(createItemInfo);
+ } else if (rawInfo instanceof ResolveInfo) {
+ // Fill in the shortcuts information
+ ResolveInfo info = (ResolveInfo) rawInfo;
+ createItemInfo = new PendingAddItemInfo();
+ createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+ createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
+ info.activityInfo.name);
+ FastBitmapDrawable preview = getShortcutPreview(info, cellWidth, cellHeight);
+ widget.applyFromResolveInfo(mPackageManager, info, preview, null, false);
+ widget.setTag(createItemInfo);
+ }
+ widget.setOnClickListener(this);
+ widget.setOnLongClickListener(this);
+ widget.setOnTouchListener(this);
+
+ // Layout each widget
+ int ix = i % mWidgetCountX;
+ int iy = i / mWidgetCountX;
+ PagedViewGridLayout.LayoutParams lp = new PagedViewGridLayout.LayoutParams(cellWidth,
+ cellHeight);
+ lp.leftMargin = (ix * cellWidth) + (ix * mCellWidthGap);
+ lp.topMargin = (iy * cellHeight) + (iy * mCellHeightGap);
+ layout.addView(widget, lp);
+ }
+ }
+
+ /*
+ * This method fetches an xml file specified in the manifest identified by
+ * WallpaperManager.WALLPAPER_PREVIEW_META_DATA). The xml file specifies
+ * an image which will be used as the wallpaper preview for an activity
+ * which responds to ACTION_SET_WALLPAPER. This image is returned and used
+ * in the customize drawer.
+ */
+ private Drawable parseWallpaperPreviewXml(ResolveInfo ri) {
+ ActivityInfo activityInfo = ri.activityInfo;
+ XmlResourceParser parser = null;
+ ComponentName component = new ComponentName(ri.activityInfo.packageName,
+ ri.activityInfo.name);
+ try {
+ parser = activityInfo.loadXmlMetaData(mPackageManager,
+ WallpaperManager.WALLPAPER_PREVIEW_META_DATA);
+ if (parser == null) {
+ Slog.w(LOG_TAG, "No " + WallpaperManager.WALLPAPER_PREVIEW_META_DATA
+ + " meta-data for " + "wallpaper provider '" + component + '\'');
+ return null;
+ }
+
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+
+ int type;
+ while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ && type != XmlPullParser.START_TAG) {
+ // drain whitespace, comments, etc.
+ }
+
+ String nodeName = parser.getName();
+ if (!"wallpaper-preview".equals(nodeName)) {
+ Slog.w(LOG_TAG, "Meta-data does not start with wallpaper-preview tag for "
+ + "wallpaper provider '" + component + '\'');
+ return null;
+ }
+
+ // If metaData was null, we would have returned earlier when getting
+ // the parser No need to do the check here
+ Resources res = mPackageManager.getResourcesForApplication(
+ activityInfo.applicationInfo);
+
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.WallpaperPreviewInfo);
+
+ TypedValue value = sa.peekValue(
+ com.android.internal.R.styleable.WallpaperPreviewInfo_staticWallpaperPreview);
+ if (value == null) return null;
+
+ return res.getDrawable(value.resourceId);
+ } catch (Exception e) {
+ Slog.w(LOG_TAG, "XML parsing failed for wallpaper provider '" + component + '\'', e);
+ return null;
+ } finally {
+ if (parser != null) parser.close();
+ }
+ }
+ private FastBitmapDrawable getWallpaperPreview(ResolveInfo info, int cellWidth, int cellHeight){
+ // Return the cached version if necessary
+ Bitmap cachedBitmap = mWidgetPreviewCache.get(info);
+ if (cachedBitmap != null) {
+ return new FastBitmapDrawable(cachedBitmap);
+ }
+
+ // Get the preview
+ Resources resources = getContext().getResources();
+ Drawable wallpaperPreview = parseWallpaperPreviewXml(info);
+ Drawable wallpaperIcon = null;
+ int expectedWidth;
+ int expectedHeight;
+ if (wallpaperPreview != null) {
+ expectedWidth = wallpaperPreview.getIntrinsicWidth();
+ expectedHeight = wallpaperPreview.getIntrinsicHeight();
+ } else {
+ wallpaperPreview = mDefaultWidgetBackground;
+ expectedWidth = expectedHeight = Math.min(cellWidth, cellHeight);
+
+ // Draw the icon in the top left corner
+ String packageName = info.activityInfo.packageName;
+ try {
+ if (info.icon > 0) {
+ wallpaperIcon = mPackageManager.getDrawable(packageName, info.icon, null);
+ }
+ if (wallpaperIcon == null) {
+ wallpaperIcon = resources.getDrawable(R.drawable.ic_launcher_application);
+ }
+ } catch (Resources.NotFoundException e) {}
+ }
+
+ // Create the bitmap
+ Bitmap preview = Bitmap.createBitmap(expectedWidth, expectedHeight, Config.ARGB_8888);
+ renderDrawableToBitmap(wallpaperPreview, preview, 0, 0, expectedWidth, expectedHeight,
+ 1f, 1f);
+ if (wallpaperIcon != null) {
+ int iconSize = resources.getDimensionPixelSize(R.dimen.app_icon_size);
+ int offset = (int) (iconSize * sWidgetPreviewIconPaddingPercentage);
+ renderDrawableToBitmap(wallpaperIcon, preview, offset, offset, iconSize, iconSize,
+ 1f, 1f);
+ }
+
+ FastBitmapDrawable previewDrawable = new FastBitmapDrawable(preview);
+ previewDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
+ mWidgetPreviewCache.put(info, preview);
+ return previewDrawable;
+ }
+ /*
+ * Wallpapers PagedView implementation
+ */
+ public void syncWallpaperPages() {
+ // Ensure that we have the right number of pages
+ Context context = getContext();
+ int numWidgetsPerPage = mWallpaperCountX * mWallpaperCountY;
+ int numPages = (int) Math.ceil(mWallpapers.size() / (float) numWidgetsPerPage);
+ for (int i = 0; i < numPages; ++i) {
+ PagedViewGridLayout layout = new PagedViewGridLayout(context, mWallpaperCountX,
+ mWallpaperCountY);
+ setupPage(layout);
+ addView(layout);
+ }
+ }
+ public void syncWallpaperPageItems(int page) {
+ PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(page);
+ layout.removeAllViews();
+
+ // Calculate the dimensions of each cell we are giving to each widget
+ int numWidgetsPerPage = mWallpaperCountX * mWallpaperCountY;
+ int offset = page * numWidgetsPerPage;
+ int cellWidth = ((mWidgetSpacingLayout.getContentWidth() - mPageLayoutWidthGap
+ - ((mWallpaperCountX - 1) * mCellWidthGap)) / mWallpaperCountX);
+ int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap
+ - ((mWallpaperCountY - 1) * mCellHeightGap)) / mWallpaperCountY);
+ for (int i = 0; i < Math.min(numWidgetsPerPage, mWallpapers.size() - offset); ++i) {
+ ResolveInfo info = mWallpapers.get(offset + i);
+ PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
+ R.layout.apps_customize_wallpaper, layout, false);
+
+ // Fill in the shortcuts information
+ FastBitmapDrawable preview = getWallpaperPreview(info, cellWidth, cellHeight);
+ widget.applyFromResolveInfo(mPackageManager, info, preview, null, false);
+ widget.setTag(info);
+ widget.setOnClickListener(this);
+ widget.setOnLongClickListener(this);
+ widget.setOnTouchListener(this);
+
+ // Layout each widget
+ int ix = i % mWallpaperCountX;
+ int iy = i / mWallpaperCountX;
+ PagedViewGridLayout.LayoutParams lp = new PagedViewGridLayout.LayoutParams(cellWidth,
+ cellHeight);
+ lp.leftMargin = (ix * cellWidth) + (ix * mCellWidthGap);
+ lp.topMargin = (iy * cellHeight) + (iy * mCellHeightGap);
+ layout.addView(widget, lp);
+ }
+ }
+
+ @Override
+ public void syncPages() {
+ removeAllViews();
+ switch (mContentType) {
+ case Applications:
+ syncAppsPages();
+ break;
+ case Widgets:
+ syncWidgetPages();
+ break;
+ case Wallpapers:
+ syncWallpaperPages();
+ break;
+ }
+ }
+ @Override
+ public void syncPageItems(int page) {
+ switch (mContentType) {
+ case Applications:
+ syncAppsPageItems(page);
+ break;
+ case Widgets:
+ syncWidgetPageItems(page);
+ break;
+ case Wallpapers:
+ syncWallpaperPageItems(page);
+ break;
+ }
+ }
+
+ /**
+ * Used by the parent to get the content width to set the tab bar to
+ * @return
+ */
+ public int getPageContentWidth() {
+ return mContentWidth;
+ }
+
+ /*
+ * AllAppsView implementation
+ */
+ @Override
+ public void setup(Launcher launcher, DragController dragController) {
+ mLauncher = launcher;
+ mDragController = dragController;
+ }
+ @Override
+ public void zoom(float zoom, boolean animate) {
+ // TODO-APPS_CUSTOMIZE: Call back to mLauncher.zoomed()
+ }
+ @Override
+ public boolean isVisible() {
+ return (getVisibility() == VISIBLE);
+ }
+ @Override
+ public boolean isAnimating() {
+ return false;
+ }
+ @Override
+ public void setApps(ArrayList<ApplicationInfo> list) {
+ mApps = list;
+ Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
+ invalidatePageData();
+ }
+ private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+ // We add it in place, in alphabetical order
+ int count = list.size();
+ for (int i = 0; i < count; ++i) {
+ ApplicationInfo info = list.get(i);
+ int index = Collections.binarySearch(mApps, info, LauncherModel.APP_NAME_COMPARATOR);
+ if (index < 0) {
+ mApps.add(-(index + 1), info);
+ }
+ }
+ }
+ @Override
+ public void addApps(ArrayList<ApplicationInfo> list) {
+ addAppsWithoutInvalidate(list);
+ invalidatePageData();
+ }
+ private int findAppByComponent(List<ApplicationInfo> list, ApplicationInfo item) {
+ ComponentName removeComponent = item.intent.getComponent();
+ 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;
+ }
+ private void removeAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
+ // loop through all the apps and remove apps that have the same component
+ int length = list.size();
+ for (int i = 0; i < length; ++i) {
+ ApplicationInfo info = list.get(i);
+ int removeIndex = findAppByComponent(mApps, info);
+ if (removeIndex > -1) {
+ mApps.remove(removeIndex);
+ mPageViewIconCache.removeOutline(new PagedViewIconCache.Key(info));
+ }
+ }
+ }
+ @Override
+ public void removeApps(ArrayList<ApplicationInfo> list) {
+ removeAppsWithoutInvalidate(list);
+ invalidatePageData();
+ }
+ @Override
+ public void updateApps(ArrayList<ApplicationInfo> list) {
+ // We remove and re-add the updated applications list because it's properties may have
+ // changed (ie. the title), and this will ensure that the items will be in their proper
+ // place in the list.
+ removeAppsWithoutInvalidate(list);
+ addAppsWithoutInvalidate(list);
+ invalidatePageData();
+ }
+ @Override
+ public void reset() {
+ if (mContentType != ContentType.Applications) {
+ // Reset to the first page of the Apps pane
+ AppsCustomizeTabHost tabs = (AppsCustomizeTabHost)
+ mLauncher.findViewById(R.id.apps_customize_pane);
+ tabs.setCurrentTabByTag(tabs.getTabTagForContentType(ContentType.Applications));
+ } else {
+ setCurrentPage(0);
+ invalidatePageData();
+ }
+ }
+ @Override
+ public void dumpState() {
+ // TODO: Dump information related to current list of Applications, Widgets, etc.
+ ApplicationInfo.dumpApplicationInfoList(LOG_TAG, "mApps", mApps);
+ dumpAppWidgetProviderInfoList(LOG_TAG, "mWidgets", mWidgets);
+ }
+ private void dumpAppWidgetProviderInfoList(String tag, String label,
+ List<Object> list) {
+ Log.d(tag, label + " size=" + list.size());
+ for (Object i: list) {
+ if (i instanceof AppWidgetProviderInfo) {
+ AppWidgetProviderInfo info = (AppWidgetProviderInfo) i;
+ Log.d(tag, " label=\"" + info.label + "\" previewImage=" + info.previewImage
+ + " resizeMode=" + info.resizeMode + " configure=" + info.configure
+ + " initialLayout=" + info.initialLayout
+ + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
+ } else if (i instanceof ResolveInfo) {
+ ResolveInfo info = (ResolveInfo) i;
+ Log.d(tag, " label=\"" + info.loadLabel(mPackageManager) + "\" icon="
+ + info.icon);
+ }
+ }
+ }
+ @Override
+ public void surrender() {
+ // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
+ // should stop this now.
+ }
+}
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
new file mode 100644
index 0000000..e2d21b6
--- /dev/null
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -0,0 +1,138 @@
+/*
+ * 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.Resources;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TabHost;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+
+public class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable,
+ TabHost.OnTabChangeListener {
+ static final String LOG_TAG = "AppsCustomizeTabHost";
+
+ private static final String APPS_TAB_TAG = "APPS";
+ private static final String WIDGETS_TAB_TAG = "WIDGETS";
+ private static final String WALLPAPERS_TAB_TAG = "WALLPAPERS";
+
+ private final LayoutInflater mLayoutInflater;
+
+ public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mLayoutInflater = LayoutInflater.from(context);
+ }
+
+ /**
+ * Setup the tab host and create all necessary tabs.
+ */
+ @Override
+ protected void onFinishInflate() {
+ // Setup the tab host
+ setup();
+
+ final ViewGroup tabs = (ViewGroup) findViewById(com.android.internal.R.id.tabs);
+ final AppsCustomizePagedView content = (AppsCustomizePagedView)
+ findViewById(R.id.apps_customize_pane_content);
+ if (tabs == null || content == null) throw new Resources.NotFoundException();
+
+ // Configure the tabs content factory to return the same paged view (that we change the
+ // content filter on)
+ TabContentFactory contentFactory = new TabContentFactory() {
+ public View createTabContent(String tag) {
+ return content;
+ }
+ };
+
+ // Create the tabs
+ TextView tabView;
+ tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
+ tabView.setText(mContext.getString(R.string.all_apps_button_label));
+ addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
+ tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
+ tabView.setText(mContext.getString(R.string.widgets_tab_label));
+ addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
+ tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
+ tabView.setText(mContext.getString(R.string.wallpapers_tab_label));
+ addTab(newTabSpec(WALLPAPERS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
+ setOnTabChangedListener(this);
+
+ // Set the width of the tab bar to match the content (for now)
+ tabs.getLayoutParams().width = content.getPageContentWidth();
+ }
+
+ @Override
+ public void onTabChanged(String tabId) {
+ final AppsCustomizePagedView content = (AppsCustomizePagedView)
+ findViewById(R.id.apps_customize_pane_content);
+ content.setContentType(getContentTypeForTabTag(tabId));
+ }
+
+ /**
+ * Returns the content type for the specified tab tag.
+ */
+ public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
+ if (tag.equals(APPS_TAB_TAG)) {
+ return AppsCustomizePagedView.ContentType.Applications;
+ } else if (tag.equals(WIDGETS_TAB_TAG)) {
+ return AppsCustomizePagedView.ContentType.Widgets;
+ } else if (tag.equals(WALLPAPERS_TAB_TAG)) {
+ return AppsCustomizePagedView.ContentType.Wallpapers;
+ }
+ return AppsCustomizePagedView.ContentType.Applications;
+ }
+
+ /**
+ * Returns the tab tag for a given content type.
+ */
+ public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
+ if (type == AppsCustomizePagedView.ContentType.Applications) {
+ return APPS_TAB_TAG;
+ } else if (type == AppsCustomizePagedView.ContentType.Widgets) {
+ return WIDGETS_TAB_TAG;
+ } else if (type == AppsCustomizePagedView.ContentType.Wallpapers) {
+ return WALLPAPERS_TAB_TAG;
+ }
+ return APPS_TAB_TAG;
+ }
+
+ /**
+ * Disable focus on anything under this view in the hierarchy if we are not visible.
+ */
+ @Override
+ public int getDescendantFocusability() {
+ if (getVisibility() != View.VISIBLE) {
+ return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
+ return super.getDescendantFocusability();
+ }
+
+ /* LauncherTransitionable overrides */
+ @Override
+ public void onLauncherTransitionStart(android.animation.Animator animation) {
+ // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionStart();
+ }
+ @Override
+ public void onLauncherTransitionEnd(android.animation.Animator animation) {
+ // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionEnd();
+ }
+}
diff --git a/src/com/android/launcher2/BubbleTextView.java b/src/com/android/launcher2/BubbleTextView.java
index ad01fac..703b3a8 100644
--- a/src/com/android/launcher2/BubbleTextView.java
+++ b/src/com/android/launcher2/BubbleTextView.java
@@ -29,6 +29,7 @@
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
@@ -66,6 +67,8 @@
private boolean mBackgroundSizeChanged;
private Drawable mBackground;
+ private boolean mStayPressed;
+
private VisibilityChangedListener mOnVisibilityChangedListener;
public BubbleTextView(Context context) {
@@ -85,8 +88,6 @@
private void init() {
mBackground = getBackground();
- setFocusable(true);
- setBackgroundDrawable(null);
final Resources res = getContext().getResources();
int bubbleColor = res.getColor(R.color.bubble_dark_background);
@@ -130,21 +131,30 @@
// 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 +166,8 @@
}
/**
- * 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 +253,32 @@
super.onVisibilityChanged(changedView, visibility);
}
+ 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) {
- 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();
- }
-
final Drawable background = mBackground;
if (background != null) {
final int scrollX = mScrollX;
@@ -310,4 +329,16 @@
}
return true;
}
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return FocusHelper.handleBubbleTextViewKeyEvent(this, keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return FocusHelper.handleBubbleTextViewKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ }
}
diff --git a/src/com/android/launcher2/CachedTextView.java b/src/com/android/launcher2/CachedTextView.java
index 403d856..d0f6dd8 100644
--- a/src/com/android/launcher2/CachedTextView.java
+++ b/src/com/android/launcher2/CachedTextView.java
@@ -18,10 +18,11 @@
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Paint;
-import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
+import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.util.AttributeSet;
import android.widget.TextView;
@@ -163,6 +164,16 @@
if (mPrevAlpha != alpha) {
mPrevAlpha = alpha;
mCachePaint.setAlpha(alpha);
+
+ // We manually update the drawables alpha since the default TextView implementation may
+ // not do this if there is a background set (which we may due to the focus bg)
+ final Drawable[] dr = getCompoundDrawables();
+ for (int i = 0; i < dr.length; ++i) {
+ if (dr[i] != null) {
+ dr[i].mutate().setAlpha(alpha);
+ }
+ }
+
super.onSetAlpha(alpha);
}
return true;
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 6691e64..5f848a8 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -16,7 +16,7 @@
package com.android.launcher2;
-import com.android.launcher.R;
+import java.util.Arrays;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -39,7 +39,6 @@
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.ContextMenu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
@@ -48,7 +47,7 @@
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LayoutAnimationController;
-import java.util.Arrays;
+import com.android.launcher.R;
public class CellLayout extends ViewGroup {
static final String TAG = "CellLayout";
@@ -95,7 +94,7 @@
private float mGlowBackgroundScale;
private float mGlowBackgroundAlpha;
- private boolean mAcceptsDrops = false;
+ private boolean mAcceptsDrops = true;
// If we're actively dragging something over this screen, mIsDragOverlapping is true
private boolean mIsDragOverlapping = false;
private boolean mIsDragOccuring = false;
@@ -104,7 +103,7 @@
// These arrays are used to implement the drag visualization on x-large screens.
// They are used as circular arrays, indexed by mDragOutlineCurrent.
- private Point[] mDragOutlines = new Point[8];
+ private Point[] mDragOutlines = new Point[4];
private float[] mDragOutlineAlphas = new float[mDragOutlines.length];
private InterruptibleInOutAnimator[] mDragOutlineAnims =
new InterruptibleInOutAnimator[mDragOutlines.length];
@@ -113,6 +112,8 @@
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;
@@ -166,7 +167,7 @@
final Resources res = getResources();
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
mNormalBackground = res.getDrawable(R.drawable.homescreen_large_blue);
mActiveBackground = res.getDrawable(R.drawable.homescreen_large_green);
mActiveGlowBackground = res.getDrawable(R.drawable.homescreen_large_green_strong);
@@ -262,11 +263,95 @@
setHoverAlpha(1.0f);
mChildren = new CellLayoutChildren(context);
- mChildren.setCellDimensions(
- mCellWidth, mCellHeight, mLeftPadding, mTopPadding, mWidthGap, mHeightGap);
+ mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
addView(mChildren);
}
+ static int widthInPortrait(Resources r, int numCells) {
+ // We use this method from Workspace to figure out how many rows/columns Launcher should
+ // have. We ignore the left/right padding on CellLayout because it turns out in our design
+ // the padding extends outside the visible screen size, but it looked fine anyway.
+ // However, we make sure there's at least enough space for the crosshairs at either
+ // edge to be rendered (half the crosshair is sticking out on either side)
+ int cellWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);
+ int widthGap = r.getDimensionPixelSize(R.dimen.workspace_width_gap_port);
+ int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicWidth();
+
+ return widthGap * (numCells - 1) + cellWidth * numCells + crosshairsSize;
+ }
+
+ static int widthInLandscape(Resources r, int numCells) {
+ // We use this method from Workspace to figure out how many rows/columns Launcher should
+ // have. We ignore the left/right padding on CellLayout because it turns out in our design
+ // the padding extends outside the visible screen size, but it looked fine anyway.
+ // However, we make sure there's at least enough space for the crosshairs at either
+ // edge to be rendered (half the crosshair is sticking out on either side)
+ int cellWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);
+ int widthGap = r.getDimensionPixelSize(R.dimen.workspace_width_gap_land);
+ int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicWidth();
+
+ return widthGap * (numCells - 1) + cellWidth * numCells + crosshairsSize;
+ }
+
+ static int heightInPortrait(Resources r, int numCells) {
+ // We use this method from Workspace to figure out how many rows/columns Launcher should
+ // have. We ignore the left/right padding on CellLayout because it turns out in our design
+ // the padding extends outside the visible screen size, but it looked fine anyway.
+ // However, we make sure there's at least enough space for the crosshairs at the bottom
+ // to be rendered (half the crosshair is sticking out); we don't worry about the top
+ // crosshair since it can bleed into the action bar space
+ int cellHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height);
+ int heightGap = r.getDimensionPixelSize(R.dimen.workspace_height_gap_port);
+ int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicHeight();
+
+ return heightGap * (numCells - 1) + cellHeight * numCells + (crosshairsSize + 1) / 2;
+ }
+
+ static int heightInLandscape(Resources r, int numCells) {
+ // We use this method from Workspace to figure out how many rows/columns Launcher should
+ // have. We ignore the left/right padding on CellLayout because it turns out in our design
+ // the padding extends outside the visible screen size, but it looked fine anyway.
+ // However, we make sure there's at least enough space for the crosshairs at the bottom
+ // to be rendered (half the crosshair is sticking out); we don't worry about the top
+ // crosshair since it can bleed into the action bar space
+ int cellHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height);
+ int heightGap = r.getDimensionPixelSize(R.dimen.workspace_height_gap_land);
+ int crosshairsSize = r.getDrawable(R.drawable.gardening_crosshairs).getIntrinsicHeight();
+
+ return heightGap * (numCells - 1) + cellHeight * numCells + (crosshairsSize + 1) / 2;
+ }
+
+ public void enableHardwareLayers() {
+ mChildren.enableHardwareLayers();
+ }
+
+ public void setGridSize(int x, int y) {
+ mCountX = x;
+ mCountY = y;
+ mOccupied = new boolean[mCountX][mCountY];
+ }
+
+ private void invalidateBubbleTextView(BubbleTextView icon) {
+ final int padding = icon.getPressedOrFocusedBackgroundPadding();
+ invalidate(icon.getLeft() + getLeftPadding() - padding,
+ icon.getTop() + getTopPadding() - padding,
+ icon.getRight() + getLeftPadding() + padding,
+ icon.getBottom() + getTopPadding() + 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);
@@ -332,7 +417,7 @@
}
void animateDrop() {
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
Resources res = getResources();
float onDropScale = res.getInteger(R.integer.config_screenOnDropScalePercent) / 100.0f;
ObjectAnimator scaleUp = ObjectAnimator.ofFloat(this, "hoverScale", onDropScale);
@@ -370,7 +455,7 @@
// When we're small, we are either drawn normally or in the "accepts drops" state (during
// a drag). However, we also drag the mini hover background *over* one of those two
// backgrounds
- if (LauncherApplication.isScreenXLarge() && mBackgroundAlpha > 0.0f) {
+ if (LauncherApplication.isScreenLarge() && mBackgroundAlpha > 0.0f) {
Drawable bg;
boolean mini = getScaleX() < 0.5f;
@@ -457,6 +542,19 @@
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() + getLeftPadding() - padding,
+ mPressedOrFocusedIcon.getTop() + getTopPadding() - padding,
+ null);
+ }
+ }
}
@Override
@@ -571,6 +669,10 @@
mChildren.draw(canvas);
}
+ void buildChildrenLayer() {
+ mChildren.buildLayer();
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -587,11 +689,12 @@
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;
@@ -695,6 +798,22 @@
result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap);
}
+ /**
+ * Given a cell coordinate, return the point that represents the upper left corner of that cell
+ *
+ * @param cellX X coordinate of the cell
+ * @param cellY Y coordinate of the cell
+ *
+ * @param result Array of 2 ints to hold the x and y coordinate of the point
+ */
+ void cellToCenterPoint(int cellX, int cellY, int[] result) {
+ final int hStartPadding = getLeftPadding();
+ final int vStartPadding = getTopPadding();
+
+ result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap) + mCellWidth / 2;
+ result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap) + mCellHeight / 2;
+ }
+
int getCellWidth() {
return mCellWidth;
}
@@ -703,6 +822,14 @@
return mCellHeight;
}
+ int getWidthGap() {
+ return mWidthGap;
+ }
+
+ int getHeightGap() {
+ return mHeightGap;
+ }
+
int getLeftPadding() {
return mLeftPadding;
}
@@ -719,6 +846,18 @@
return mBottomPadding;
}
+ Rect getContentRect(Rect r) {
+ if (r == null) {
+ r = new Rect();
+ }
+ int left = getPaddingLeft();
+ int top = getPaddingTop();
+ int right = left + getWidth() - mLeftPadding - mRightPadding;
+ int bottom = top + getHeight() - mTopPadding - mBottomPadding;
+ r.set(left, top, right, bottom);
+ return r;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO: currently ignoring padding
@@ -741,10 +880,10 @@
if (mWidthGap < 0 || mHeightGap < 0) {
int vSpaceLeft = heightSpecSize - mTopPadding - mBottomPadding - (cellHeight * mCountY);
- mHeightGap = vSpaceLeft / numHeightGaps;
+ mHeightGap = numHeightGaps > 0 ? vSpaceLeft / numHeightGaps : 0;
int hSpaceLeft = widthSpecSize - mLeftPadding - mRightPadding - (cellWidth * mCountX);
- mWidthGap = hSpaceLeft / numWidthGaps;
+ mWidthGap = numWidthGaps > 0 ? hSpaceLeft / numWidthGaps : 0;
// center it around the min gaps
int minGap = Math.min(mWidthGap, mHeightGap);
@@ -765,9 +904,10 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
- int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
- int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight,
- MeasureSpec.EXACTLY);
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth - mLeftPadding -
+ mRightPadding, MeasureSpec.EXACTLY);
+ int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(newHeight - mTopPadding -
+ mBottomPadding, MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
}
setMeasuredDimension(newWidth, newHeight);
@@ -778,7 +918,7 @@
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
- child.layout(0, 0, r - l, b - t);
+ child.layout(mLeftPadding, mTopPadding, r - l - mRightPadding , b - t - mBottomPadding);
}
}
@@ -898,6 +1038,13 @@
mDragCenter.set(originX, originY);
}
+ if (dragOutline == null && v == null) {
+ if (mCrosshairsDrawable != null) {
+ invalidate();
+ }
+ return;
+ }
+
if (nearest != null && (nearest[0] != oldDragCellX || nearest[1] != oldDragCellY)) {
// Find the top left corner of the rect the object will occupy
final int[] topLeft = mTmpPoint;
@@ -907,15 +1054,23 @@
int top = topLeft[1];
if (v != null) {
- if (v.getParent() instanceof CellLayout) {
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- left += lp.leftMargin;
- top += lp.topMargin;
- }
+ // When drawing the drag outline, it did not account for margin offsets
+ // added by the view's parent.
+ MarginLayoutParams lp = (MarginLayoutParams) v.getLayoutParams();
+ left += lp.leftMargin;
+ top += lp.topMargin;
- // Offsets due to the size difference between the View and the dragOutline
+ // Offsets due to the size difference between the View and the dragOutline.
+ // There is a size difference to account for the outer blur, which may lie
+ // outside the bounds of the view.
left += (v.getWidth() - dragOutline.getWidth()) / 2;
top += (v.getHeight() - dragOutline.getHeight()) / 2;
+ } else {
+ // Center the drag outline in the cell
+ left += ((mCellWidth * spanX) + ((spanX - 1) * mWidthGap)
+ - dragOutline.getWidth()) / 2;
+ top += ((mCellHeight * spanY) + ((spanY - 1) * mHeightGap)
+ - dragOutline.getHeight()) / 2;
}
final int oldIndex = mDragOutlineCurrent;
@@ -933,6 +1088,13 @@
}
}
+ public void clearDragOutlines() {
+ final int oldIndex = mDragOutlineCurrent;
+ mDragOutlineAnims[oldIndex].animateOut();
+ mDragCell[0] = -1;
+ mDragCell[1] = -1;
+ }
+
/**
* Find a vacant area that will fit the given bounds nearest the requested
* cell location. Uses Euclidean distance to score multiple vacant areas.
@@ -959,16 +1121,23 @@
* @param pixelY The Y location at which you want to search for a vacant area.
* @param spanX Horizontal span of the object.
* @param spanY Vertical span of the object.
- * @param ignoreView Considers space occupied by this view as unoccupied
- * @param result Previously returned value to possibly recycle.
+ * @param ignoreOccupied If true, the result can be an occupied cell
+ * @param result Array in which to place the result, or null (in which case a new array will
+ * be allocated)
* @return The X, Y cell of a vacant area that can contain this object,
* nearest the requested location.
*/
- int[] findNearestVacantArea(
- int pixelX, int pixelY, int spanX, int spanY, View ignoreView, int[] result) {
+ int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, View ignoreView,
+ boolean ignoreOccupied, int[] result) {
// mark space take by ignoreView as available (method checks if ignoreView is null)
markCellsAsUnoccupiedForView(ignoreView);
+ // For items with a spanX / spanY > 1, the passed in point (pixelX, pixelY) corresponds
+ // to the center of the item, but we are searching based on the top-left cell, so
+ // we translate the point over to correspond to the top-left.
+ pixelX -= (mCellWidth + mWidthGap) * (spanX - 1) / 2f;
+ pixelY -= (mCellHeight + mHeightGap) * (spanY - 1) / 2f;
+
// Keep track of best-scoring drop area
final int[] bestXY = result != null ? result : new int[2];
double bestDistance = Double.MAX_VALUE;
@@ -980,18 +1149,20 @@
for (int y = 0; y < countY - (spanY - 1); y++) {
inner:
for (int x = 0; x < countX - (spanX - 1); x++) {
- for (int i = 0; i < spanX; i++) {
- for (int j = 0; j < spanY; j++) {
- if (occupied[x + i][y + j]) {
- // small optimization: we can skip to after the column we just found
- // an occupied cell
- x += i;
- continue inner;
+ if (ignoreOccupied) {
+ for (int i = 0; i < spanX; i++) {
+ for (int j = 0; j < spanY; j++) {
+ if (occupied[x + i][y + j]) {
+ // small optimization: we can skip to after the column we
+ // just found an occupied cell
+ x += i;
+ continue inner;
+ }
}
}
}
final int[] cellXY = mTmpCellXY;
- cellToPoint(x, y, cellXY);
+ cellToCenterPoint(x, y, cellXY);
double distance = Math.sqrt(Math.pow(cellXY[0] - pixelX, 2)
+ Math.pow(cellXY[1] - pixelY, 2));
@@ -1013,6 +1184,42 @@
}
}
+ /**
+ * Find a vacant area that will fit the given bounds nearest the requested
+ * cell location. Uses Euclidean distance to score multiple vacant areas.
+ *
+ * @param pixelX The X location at which you want to search for a vacant area.
+ * @param pixelY The Y location at which you want to search for a vacant area.
+ * @param spanX Horizontal span of the object.
+ * @param spanY Vertical span of the object.
+ * @param ignoreView Considers space occupied by this view as unoccupied
+ * @param result Previously returned value to possibly recycle.
+ * @return The X, Y cell of a vacant area that can contain this object,
+ * nearest the requested location.
+ */
+ int[] findNearestVacantArea(
+ int pixelX, int pixelY, int spanX, int spanY, View ignoreView, int[] result) {
+ return findNearestArea(pixelX, pixelY, spanX, spanY, ignoreView, true, result);
+ }
+
+ /**
+ * Find a starting cell position that will fit the given bounds nearest the requested
+ * cell location. Uses Euclidean distance to score multiple vacant areas.
+ *
+ * @param pixelX The X location at which you want to search for a vacant area.
+ * @param pixelY The Y location at which you want to search for a vacant area.
+ * @param spanX Horizontal span of the object.
+ * @param spanY Vertical span of the object.
+ * @param ignoreView Considers space occupied by this view as unoccupied
+ * @param result Previously returned value to possibly recycle.
+ * @return The X, Y cell of a vacant area that can contain this object,
+ * nearest the requested location.
+ */
+ int[] findNearestArea(
+ int pixelX, int pixelY, int spanX, int spanY, int[] result) {
+ return findNearestArea(pixelX, pixelY, spanX, spanY, null, false, result);
+ }
+
boolean existsEmptyCell() {
return findCellForSpan(null, 1, 1);
}
@@ -1303,8 +1510,8 @@
static boolean findVacantCell(int[] vacant, int spanX, int spanY,
int xCount, int yCount, boolean[][] occupied) {
- for (int x = 0; x < xCount; x++) {
- for (int y = 0; y < yCount; y++) {
+ for (int y = 0; y < yCount; y++) {
+ for (int x = 0; x < xCount; x++) {
boolean available = !occupied[x][y];
out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
for (int j = y; j < y + spanY - 1 && y < yCount; j++) {
@@ -1332,19 +1539,69 @@
}
}
+ /**
+ * 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);
@@ -1358,6 +1615,24 @@
}
}
+ public int getDesiredWidth() {
+ return mLeftPadding + mRightPadding + (mCountX * mCellWidth) +
+ (Math.max((mCountX - 1), 0) * mWidthGap);
+ }
+
+ public int getDesiredHeight() {
+ return mTopPadding + mBottomPadding + (mCountY * mCellHeight) +
+ (Math.max((mCountY - 1), 0) * mHeightGap);
+ }
+
+ public boolean isOccupied(int x, int y) {
+ if (x < mCountX && y < mCountY) {
+ return mOccupied[x][y];
+ } else {
+ throw new RuntimeException("Position exceeds the bound of this CellLayout");
+ }
+ }
+
@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new CellLayout.LayoutParams(getContext(), attrs);
@@ -1410,6 +1685,12 @@
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;
@@ -1465,26 +1746,57 @@
this.cellVSpan = cellVSpan;
}
- public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
- int hStartPadding, int vStartPadding) {
+ public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap) {
+ if (isLockedToGrid) {
+ final int myCellHSpan = cellHSpan;
+ final int myCellVSpan = cellVSpan;
+ final int myCellX = cellX;
+ final int myCellY = cellY;
- 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;
+ width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
+ leftMargin - rightMargin;
+ height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
+ topMargin - bottomMargin;
+ x = myCellX * (cellWidth + widthGap) + leftMargin;
+ y = myCellY * (cellHeight + heightGap) + topMargin;
+ }
}
public String toString() {
return "(" + this.cellX + ", " + this.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;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public int getY() {
+ return y;
+ }
}
// This class stores info for two purposes:
@@ -1493,7 +1805,7 @@
// 2. When long clicking on an empty cell in a CellLayout, we save information about the
// cellX and cellY coordinates and which page was clicked. We then set this as a tag on
// the CellLayout that was long clicked
- static final class CellInfo implements ContextMenu.ContextMenuInfo {
+ static final class CellInfo {
View cell;
int cellX = -1;
int cellY = -1;
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java
index 0d0a339..59db9c9 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -21,7 +21,6 @@
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
-import android.view.View.MeasureSpec;
public class CellLayoutChildren extends ViewGroup {
static final String TAG = "CellLayoutChildren";
@@ -35,27 +34,21 @@
private int mCellWidth;
private int mCellHeight;
- private int mLeftPadding;
- private int mTopPadding;
-
private int mWidthGap;
private int mHeightGap;
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,
- int leftPadding, int topPadding, int widthGap, int heightGap ) {
+ public void enableHardwareLayers() {
+ setLayerType(LAYER_TYPE_HARDWARE, null);
+ }
+
+ public void setCellDimensions(int cellWidth, int cellHeight, int widthGap, int heightGap ) {
mCellWidth = cellWidth;
mCellHeight = cellHeight;
- mLeftPadding = leftPadding;
- mTopPadding = topPadding;
mWidthGap = widthGap;
mHeightGap = heightGap;
}
@@ -67,7 +60,7 @@
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
- (lp.cellY <= y) && (y < lp.cellY + lp.cellHSpan)) {
+ (lp.cellY <= y) && (y < lp.cellY + lp.cellVSpan)) {
return child;
}
}
@@ -76,27 +69,29 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int cellWidth = mCellWidth;
- final int cellHeight = mCellHeight;
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
- CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-
- lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
- mLeftPadding, mTopPadding);
-
- int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
- int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
- MeasureSpec.EXACTLY);
-
- child.measure(childWidthMeasureSpec, childheightMeasureSpec);
+ measureChild(child);
}
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(widthSpecSize, heightSpecSize);
}
+ public void measureChild(View child) {
+ final int cellWidth = mCellWidth;
+ final int cellHeight = mCellHeight;
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+
+ lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap);
+ int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
+ int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
+ MeasureSpec.EXACTLY);
+
+ child.measure(childWidthMeasureSpec, childheightMeasureSpec);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
@@ -171,4 +166,4 @@
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
super.setChildrenDrawnWithCacheEnabled(enabled);
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index d08bf54..68ec535 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -38,8 +38,10 @@
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;
@@ -52,8 +54,9 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.MeasureSpec;
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 +92,10 @@
// 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;
@@ -118,11 +125,25 @@
private final Canvas mCanvas = new Canvas();
private final LayoutInflater mInflater;
+ private boolean mFirstMeasure = true;
+
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];
+
+ private int mPageContentWidth;
public CustomizePagedView(Context context) {
this(context, null, 0);
@@ -166,6 +187,32 @@
mCenterPagesVertically = false;
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+ if (mFirstMeasure) {
+ mFirstMeasure = false;
+
+ // TODO: actually calculate mCellCountX/mCellCountY as some function of
+ // widthSize and heightSize
+ //mCellCountX = ?
+ //mCellCountY = ?
+
+ // Since mCellCountX/mCellCountY changed, we need to update the pages
+ invalidatePageData();
+
+ // Create a dummy page and set it up to find out the content width (used by our parent)
+ PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
+ setupPage(layout);
+ mPageContentWidth = layout.getContentWidth();
+ mMinPageWidth = layout.getWidthBeforeFirstLayout();
+ }
+ }
+
public void setLauncher(Launcher launcher) {
Context context = getContext();
mLauncher = launcher;
@@ -277,13 +324,8 @@
}
});
- Comparator<ResolveInfo> resolveInfoComparator = new Comparator<ResolveInfo>() {
- @Override
- public int compare(ResolveInfo object1, ResolveInfo object2) {
- return object1.loadLabel(mPackageManager).toString().compareTo(
- object2.loadLabel(mPackageManager).toString());
- }
- };
+ LauncherModel.ShortcutNameComparator resolveInfoComparator =
+ new LauncherModel.ShortcutNameComparator(mPackageManager);
// get the list of shortcuts
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
@@ -324,38 +366,60 @@
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,43 +438,74 @@
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
public void onClick(final View v) {
- // Return early if this is not initiated from a touch
- if (!v.isInTouchMode()) return;
// Return early if we are still animating the pages
if (mNextPage != INVALID_PAGE) return;
@@ -479,12 +574,12 @@
}
}
- 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 +596,7 @@
if (isChoiceMode(CHOICE_MODE_SINGLE)) {
endChoiceMode();
}
+ final Workspace workspace = mLauncher.getWorkspace();
boolean result = false;
mLauncher.lockScreenOrientation();
switch (mCustomizationType) {
@@ -509,50 +605,50 @@
// 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();
+ workspace.onDragStartedWithItemSpans(spanXY[0], spanXY[1], mDragBitmap);
+ mDragController.startDrag(i, mDragBitmap, this, createWidgetInfo,
+ DragController.DRAG_ACTION_COPY, null);
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();
- 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);
- mLauncher.getWorkspace().onDragStartedWithItemSpans(1, 1, b);
- mDragController.startDrag(v, b, this, app, DragController.DRAG_ACTION_COPY, null);
- b.recycle();
+ 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);
+
+ // 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 +715,15 @@
/**
* 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 +806,7 @@
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 +818,7 @@
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 +858,7 @@
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 +872,7 @@
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 +898,7 @@
}
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);
}
@@ -852,11 +952,13 @@
final int[] cellSpans = CellLayout.rectToCell(getResources(), info.minWidth,
info.minHeight, null);
final FastBitmapDrawable icon = getWidgetPreview(info);
+ final boolean createHolographicOutlines = (numPages > 1);
PagedViewWidget l = (PagedViewWidget) mInflater.inflate(
R.layout.customize_paged_view_widget, layout, false);
+
l.applyFromAppWidgetProviderInfo(info, icon, mMaxWidgetWidth, cellSpans,
- mPageViewIconCache, (numPages > 1));
+ mPageViewIconCache, createHolographicOutlines);
l.setTag(createItemInfo);
l.setOnClickListener(this);
l.setOnTouchListener(this);
@@ -897,11 +999,12 @@
for (int i = startIndex; i < endIndex; ++i) {
final ResolveInfo info = mWallpaperList.get(i);
final FastBitmapDrawable icon = getWallpaperPreview(info);
+ final boolean createHolographicOutlines = (numPages > 1);
PagedViewWidget l = (PagedViewWidget) mInflater.inflate(
R.layout.customize_paged_view_wallpaper, layout, false);
l.applyFromWallpaperInfo(info, mPackageManager, icon, mMaxWidgetWidth,
- mPageViewIconCache, (numPages > 1));
+ mPageViewIconCache, createHolographicOutlines);
l.setTag(info);
l.setOnClickListener(this);
@@ -934,12 +1037,13 @@
for (int i = startIndex; i < endIndex; ++i) {
ResolveInfo info = list.get(i);
PendingAddItemInfo createItemInfo = new PendingAddItemInfo();
+ final boolean createHolographicOutlines = (numPages > 1);
PagedViewIcon icon = (PagedViewIcon) mInflater.inflate(
R.layout.customize_paged_view_item, layout, false);
icon.applyFromResolveInfo(info, mPackageManager, mPageViewIconCache,
((LauncherApplication) mLauncher.getApplication()).getIconCache(),
- (numPages > 1));
+ createHolographicOutlines);
switch (mCustomizationType) {
case WallpaperCustomization:
icon.setOnClickListener(this);
@@ -993,9 +1097,11 @@
layout.removeAllViewsOnPage();
for (int i = startIndex; i < endIndex; ++i) {
final ApplicationInfo info = mApps.get(i);
+ final boolean createHolographicOutlines = (numPages > 1);
PagedViewIcon icon = (PagedViewIcon) mInflater.inflate(
R.layout.all_apps_paged_view_application, layout, false);
- icon.applyFromApplicationInfo(info, mPageViewIconCache, true, (numPages > 1));
+ icon.applyFromApplicationInfo(
+ info, mPageViewIconCache, true, createHolographicOutlines);
icon.setOnClickListener(this);
icon.setOnTouchListener(this);
icon.setOnLongClickListener(this);
@@ -1010,10 +1116,17 @@
@Override
public void syncPages() {
+ if (mFirstMeasure) {
+ // We don't know our size yet, which means we haven't calculated cell count x/y;
+ // onMeasure will call us once we figure out our size
+ return;
+ }
+ boolean enforceMinimumPagedWidths = false;
boolean centerPagedViewCellLayouts = false;
switch (mCustomizationType) {
case WidgetCustomization:
syncWidgetPages();
+ enforceMinimumPagedWidths = true;
break;
case ShortcutCustomization:
syncListPages(mShortcutList);
@@ -1021,6 +1134,7 @@
break;
case WallpaperCustomization:
syncWallpaperPages();
+ enforceMinimumPagedWidths = true;
break;
case ApplicationCustomization:
syncAppPages();
@@ -1046,8 +1160,22 @@
}
}
- // 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 && childCount > 1) {
+ setMinimumWidthOverride(mMinPageWidth);
+ } else {
+ resetMinimumWidthOverride();
+ }
+
+ // Bound the current page index
+ requestLayout();
+ post(new Runnable() {
+ @Override
+ public void run() {
+ setCurrentPage(Math.max(0, Math.min(childCount - 1, getCurrentPage())));
+ forceUpdateAdjacentPagesAlpha();
+ }
+ });
}
@Override
@@ -1068,6 +1196,10 @@
}
}
+ int getPageContentWidth() {
+ return mPageContentWidth;
+ }
+
@Override
protected int getAssociatedLowerPageBound(int page) {
return 0;
diff --git a/src/com/android/launcher2/CustomizeTrayTabHost.java b/src/com/android/launcher2/CustomizeTrayTabHost.java
new file mode 100644
index 0000000..ab50cf1
--- /dev/null
+++ b/src/com/android/launcher2/CustomizeTrayTabHost.java
@@ -0,0 +1,182 @@
+/*
+ * 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 java.util.Random;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+import android.widget.TextView;
+
+import com.android.launcher.R;
+import com.android.launcher2.CustomizePagedView.CustomizationType;
+
+public class CustomizeTrayTabHost extends TabHost implements LauncherTransitionable {
+ // tags for the customization tabs
+ private static final String WIDGETS_TAG = "widgets";
+ private static final String APPLICATIONS_TAG = "applications";
+ private static final String SHORTCUTS_TAG = "shortcuts";
+ private static final String WALLPAPERS_TAG = "wallpapers";
+
+ private boolean mFirstLayout = true;
+
+ private final LayoutInflater mInflater;
+ private Context mContext;
+
+ public CustomizeTrayTabHost(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ setup();
+
+ final CustomizePagedView customizePagedView =
+ (CustomizePagedView) findViewById(R.id.customization_drawer_tab_contents);
+
+ // Configure tabs
+ TabContentFactory contentFactory = new TabContentFactory() {
+ public View createTabContent(String tag) {
+ return customizePagedView;
+ }
+ };
+
+ TextView tabView;
+ TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+
+ tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView.setText(mContext.getString(R.string.widgets_tab_label));
+ addTab(newTabSpec(WIDGETS_TAG)
+ .setIndicator(tabView).setContent(contentFactory));
+ tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView.setText(mContext.getString(R.string.applications_tab_label));
+ addTab(newTabSpec(APPLICATIONS_TAG)
+ .setIndicator(tabView).setContent(contentFactory));
+ tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView.setText(mContext.getString(R.string.wallpapers_tab_label));
+ addTab(newTabSpec(WALLPAPERS_TAG)
+ .setIndicator(tabView).setContent(contentFactory));
+ tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
+ tabView.setText(mContext.getString(R.string.shortcuts_tab_label));
+ addTab(newTabSpec(SHORTCUTS_TAG)
+ .setIndicator(tabView).setContent(contentFactory));
+
+ setOnTabChangedListener(new OnTabChangeListener() {
+ public void onTabChanged(String tabId) {
+ final CustomizePagedView.CustomizationType newType =
+ getCustomizeFilterForTabTag(tabId);
+ if (newType != customizePagedView.getCustomizationFilter()) {
+ // animate the changing of the tab content by fading pages in and out
+ final Resources res = getResources();
+ final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
+ final float alpha = customizePagedView.getAlpha();
+ ValueAnimator alphaAnim = ObjectAnimator.ofFloat(customizePagedView,
+ "alpha", alpha, 0.0f);
+ alphaAnim.setDuration(duration);
+ alphaAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ customizePagedView.setCustomizationFilter(newType);
+
+ final float alpha = customizePagedView.getAlpha();
+ ValueAnimator alphaAnim = ObjectAnimator.ofFloat(
+ customizePagedView, "alpha", alpha, 1.0f);
+ alphaAnim.setDuration(duration);
+ alphaAnim.start();
+ }
+ });
+ alphaAnim.start();
+ }
+ }
+ });
+ }
+
+ @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) {
+ if (mFirstLayout) {
+ mFirstLayout = false;
+
+ final CustomizePagedView customizePagedView =
+ (CustomizePagedView) findViewById(R.id.customization_drawer_tab_contents);
+ TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+ // Set the width of the tab bar properly
+ int pageWidth = customizePagedView.getPageContentWidth();
+ TabWidget customizeTabBar = (TabWidget) findViewById(com.android.internal.R.id.tabs);
+ if (customizeTabBar == null) throw new Resources.NotFoundException();
+ int tabWidgetPadding = 0;
+ final int childCount = tabWidget.getChildCount();
+ if (childCount > 0) {
+ tabWidgetPadding += tabWidget.getChildAt(0).getPaddingLeft() * 2;
+ }
+ customizeTabBar.getLayoutParams().width = pageWidth + tabWidgetPadding;
+ }
+ super.onLayout(changed, l, t, r, b);
+ }
+
+ @Override
+ public int getDescendantFocusability() {
+ if (getVisibility() != View.VISIBLE) {
+ return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
+ return super.getDescendantFocusability();
+ }
+
+ CustomizationType getCustomizeFilterForTabTag(String tag) {
+ if (tag.equals(WIDGETS_TAG)) {
+ return CustomizationType.WidgetCustomization;
+ } else if (tag.equals(APPLICATIONS_TAG)) {
+ return CustomizationType.ApplicationCustomization;
+ } else if (tag.equals(WALLPAPERS_TAG)) {
+ return CustomizePagedView.CustomizationType.WallpaperCustomization;
+ } else if (tag.equals(SHORTCUTS_TAG)) {
+ return CustomizePagedView.CustomizationType.ShortcutCustomization;
+ }
+ return CustomizationType.WidgetCustomization;
+ }
+}
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index 98d2b83..5d9b5db 100644
--- a/src/com/android/launcher2/DeleteZone.java
+++ b/src/com/android/launcher2/DeleteZone.java
@@ -16,8 +16,10 @@
package com.android.launcher2;
-import com.android.launcher.R;
-
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -29,10 +31,8 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
-import android.view.animation.TranslateAnimation;
+
+import com.android.launcher.R;
public class DeleteZone extends IconDropTarget {
private static final int ORIENTATION_HORIZONTAL = 1;
@@ -42,10 +42,8 @@
private static final int XLARGE_ANIMATION_DURATION = 200;
private static final int LEFT_DRAWABLE = 0;
- private AnimationSet mInAnimation;
- private AnimationSet mOutAnimation;
- private Animation mHandleInAnimation;
- private Animation mHandleOutAnimation;
+ private AnimatorSet mInAnimation;
+ private AnimatorSet mOutAnimation;
private int mOrientation;
private DragController mDragController;
@@ -70,7 +68,7 @@
mOrientation = a.getInt(R.styleable.DeleteZone_direction, ORIENTATION_HORIZONTAL);
a.recycle();
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
int tb = getResources().getDimensionPixelSize(
R.dimen.delete_zone_vertical_drag_padding);
int lr = getResources().getDimensionPixelSize(
@@ -83,7 +81,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mTransition = (TransitionDrawable) getCompoundDrawables()[LEFT_DRAWABLE];
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
mTransition.setCrossFadeEnabled(false);
}
@@ -104,7 +102,7 @@
final ItemInfo item = (ItemInfo) dragInfo;
// On x-large screens, you can uninstall an app by dragging from all apps
- if (item instanceof ApplicationInfo && LauncherApplication.isScreenXLarge()) {
+ if (item instanceof ApplicationInfo && LauncherApplication.isScreenLarge()) {
mLauncher.startApplicationUninstallActivity((ApplicationInfo) item);
}
@@ -114,18 +112,12 @@
if (item instanceof LauncherAppWidgetInfo) {
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
}
- } else if (source instanceof UserFolder) {
- final UserFolder userFolder = (UserFolder) source;
- final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
- // Item must be a ShortcutInfo otherwise it couldn't have been in the folder
- // in the first place.
- userFolderInfo.remove((ShortcutInfo)item);
}
- if (item instanceof UserFolderInfo) {
- final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
- LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
- mLauncher.removeFolder(userFolderInfo);
+ if (item instanceof FolderInfo) {
+ final FolderInfo folderInfo = (FolderInfo)item;
+ LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
+ mLauncher.removeFolder(folderInfo);
} else if (item instanceof LauncherAppWidgetInfo) {
final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
@@ -168,7 +160,7 @@
getHitRect(mRegion);
mRegionF.set(mRegion);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
// This region will be a "dead zone" for scrolling; make it extend to the edge of
// the screen so users don't accidentally trigger a scroll while deleting items
mRegionF.top = mLauncher.getWorkspace().getTop();
@@ -181,10 +173,10 @@
mTransition.resetTransition();
createAnimations();
- startAnimation(mInAnimation);
+ mInAnimation.start();
if (mOverlappingViews != null) {
for (View view : mOverlappingViews) {
- view.startAnimation(mHandleOutAnimation);
+ createOutAlphaAnim(view).start();
}
}
setVisibility(VISIBLE);
@@ -196,68 +188,72 @@
mActive = false;
mDragController.setDeleteRegion(null);
- if (mOutAnimation != null) startAnimation(mOutAnimation);
- if (mHandleInAnimation != null && mOverlappingViews != null) {
+ mOutAnimation.start();
+ if (mOverlappingViews != null) {
for (View view : mOverlappingViews) {
- view.startAnimation(mHandleInAnimation);
+ createInAlphaAnim(view).start();
}
}
- setVisibility(GONE);
}
}
+ private Animator createAlphaAnim(View v, float start, float end) {
+ Animator anim = ObjectAnimator.ofFloat(v, "alpha", start, end);
+ anim.setDuration(getAnimationDuration());
+ return anim;
+ }
+ private Animator createInAlphaAnim(View v) {
+ return createAlphaAnim(v, 0f, 1f);
+ }
+ private Animator createOutAlphaAnim(View v) {
+ return createAlphaAnim(v, 1f, 0f);
+ }
+
private void createAnimations() {
int duration = getAnimationDuration();
- if (mHandleInAnimation == null) {
- mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
- mHandleInAnimation.setDuration(duration);
- }
+ Animator inAlphaAnim = createInAlphaAnim(this);
if (mInAnimation == null) {
- mInAnimation = new FastAnimationSet();
- if (!LauncherApplication.isScreenXLarge()) {
- final AnimationSet animationSet = mInAnimation;
- animationSet.setInterpolator(new AccelerateInterpolator());
- animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
+ mInAnimation = new AnimatorSet();
+ mInAnimation.setInterpolator(new AccelerateInterpolator());
+ mInAnimation.setDuration(duration);
+ if (!LauncherApplication.isScreenLarge()) {
+ Animator translateAnim;
if (mOrientation == ORIENTATION_HORIZONTAL) {
- animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
- Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
- Animation.RELATIVE_TO_SELF, 0.0f));
+ translateAnim = ObjectAnimator.ofFloat(this, "translationY",
+ getMeasuredWidth(), 0f);
} else {
- animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
- 1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
- Animation.ABSOLUTE, 0.0f));
+ translateAnim = ObjectAnimator.ofFloat(this, "translationX",
+ getMeasuredHeight(), 0f);
}
- animationSet.setDuration(duration);
+ mInAnimation.playTogether(translateAnim, inAlphaAnim);
} else {
- mInAnimation.addAnimation(mHandleInAnimation);
+ mInAnimation.play(inAlphaAnim);
}
}
- if (mHandleOutAnimation == null) {
- mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
- mHandleOutAnimation.setFillAfter(true);
- mHandleOutAnimation.setDuration(duration);
- }
-
+ Animator outAlphaAnim = createOutAlphaAnim(this);
if (mOutAnimation == null) {
- mOutAnimation = new FastAnimationSet();
- if (!LauncherApplication.isScreenXLarge()) {
- final AnimationSet animationSet = mOutAnimation;
- animationSet.setInterpolator(new AccelerateInterpolator());
- animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
+ mOutAnimation = new AnimatorSet();
+ mOutAnimation.setInterpolator(new AccelerateInterpolator());
+ mOutAnimation.setDuration(duration);
+ if (!LauncherApplication.isScreenLarge()) {
+ Animator translateAnim;
if (mOrientation == ORIENTATION_HORIZONTAL) {
- animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
- Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
- Animation.RELATIVE_TO_SELF, 1.0f));
+ translateAnim = ObjectAnimator.ofFloat(this, "translationY", 0f,
+ getMeasuredWidth());
} else {
- animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
- 0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
- Animation.ABSOLUTE, 0.0f));
+ translateAnim = ObjectAnimator.ofFloat(this, "translationX", 0f,
+ getMeasuredHeight());
}
- animationSet.setDuration(duration);
+ mOutAnimation.playTogether(translateAnim, outAlphaAnim);
} else {
- mOutAnimation.addAnimation(mHandleOutAnimation);
+ mOutAnimation.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ setVisibility(GONE);
+ }
+ });
+ mOutAnimation.play(outAlphaAnim);
}
}
}
@@ -267,46 +263,12 @@
}
private int getTransitionAnimationDuration() {
- return LauncherApplication.isScreenXLarge() ?
+ return LauncherApplication.isScreenLarge() ?
XLARGE_TRANSITION_DURATION : TRANSITION_DURATION;
}
private int getAnimationDuration() {
- return LauncherApplication.isScreenXLarge() ?
+ return LauncherApplication.isScreenLarge() ?
XLARGE_ANIMATION_DURATION : ANIMATION_DURATION;
}
-
- private static class FastTranslateAnimation extends TranslateAnimation {
- public FastTranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
- int fromYType, float fromYValue, int toYType, float toYValue) {
- super(fromXType, fromXValue, toXType, toXValue,
- fromYType, fromYValue, toYType, toYValue);
- }
-
- @Override
- public boolean willChangeTransformationMatrix() {
- return true;
- }
-
- @Override
- public boolean willChangeBounds() {
- return false;
- }
- }
-
- private static class FastAnimationSet extends AnimationSet {
- FastAnimationSet() {
- super(false);
- }
-
- @Override
- public boolean willChangeTransformationMatrix() {
- return true;
- }
-
- @Override
- public boolean willChangeBounds() {
- return false;
- }
- }
}
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 45b359d..5ca1e1c 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -73,10 +73,10 @@
private boolean mDragging;
/** X coordinate of the down event. */
- private float mMotionDownX;
+ private int mMotionDownX;
/** Y coordinate of the down event. */
- private float mMotionDownY;
+ private int mMotionDownY;
/** Info about the screen for clamping. */
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -85,10 +85,10 @@
private View mOriginator;
/** X offset from the upper-left corner of the cell to where we touched. */
- private float mTouchOffsetX;
+ private int mTouchOffsetX;
/** Y offset from the upper-left corner of the cell to where we touched. */
- private float mTouchOffsetY;
+ private int mTouchOffsetY;
/** the area at the edge of the screen that makes the workspace go left
* or right while you're dragging.
@@ -205,9 +205,7 @@
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 @@
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 @@
* 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 @@
* 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 @@
* 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");
@@ -303,13 +289,14 @@
listener.onDragStart(source, dragInfo, dragAction);
}
- int registrationX = ((int)mMotionDownX) - screenX;
- int registrationY = ((int)mMotionDownY) - screenY;
+ final int registrationX = ((int)mMotionDownX) - screenX;
+ final int registrationY = ((int)mMotionDownY) - screenY;
final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
- mTouchOffsetX = mMotionDownX - screenX - dragRegionLeft;
- mTouchOffsetY = mMotionDownY - screenY - dragRegionTop;
+
+ mTouchOffsetX = mMotionDownX - (screenX + dragRegionLeft);
+ mTouchOffsetY = mMotionDownY - (screenY + dragRegionTop);
mDragging = true;
mDragSource = source;
@@ -318,7 +305,7 @@
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() {
@@ -328,8 +315,7 @@
});
if (dragRegion != null) {
- dragView.setDragRegion(dragRegionLeft, dragRegion.top,
- dragRegion.right - dragRegionLeft, dragRegion.bottom - dragRegionTop);
+ dragView.setDragRegion(new Rect(dragRegion));
}
dragView.show(mWindowToken, (int)mMotionDownX, (int)mMotionDownY);
@@ -400,7 +386,7 @@
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 @@
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 @@
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 @@
(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 @@
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 a9dd7e3..7503dda 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -16,8 +16,11 @@
package com.android.launcher2;
+import java.util.ArrayList;
+
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -25,6 +28,8 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.launcher.R;
+
/**
* A ViewGroup that coordinates dragging across its descendants
*/
@@ -32,6 +37,14 @@
private DragController mDragController;
private int[] mTmpXY = new int[2];
+ // Variables relating to resizing widgets
+ private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
+ new ArrayList<AppWidgetResizeFrame>();
+ private AppWidgetResizeFrame mCurrentResizeFrame;
+ private int mXDown, mYDown;
+ private Folder mCurrentFolder = null;
+ private Launcher mLauncher;
+
/**
* Used to create a new DragLayer from XML.
*
@@ -54,13 +67,78 @@
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
+ 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;
+ }
+ }
+ }
+ if (mCurrentFolder != null) {
+ mCurrentFolder.getHitRect(hitRect);
+ int[] screenPos = new int[2];
+ View parent = (View) mCurrentFolder.getParent();
+ if (parent != null) {
+ parent.getLocationOnScreen(screenPos);
+ hitRect.offset(screenPos[0], screenPos[1]);
+ if (!hitRect.contains(x, y)) {
+ mLauncher.closeFolder();
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ if (handleTouchDown(ev)) {
+ return true;
+ }
+ }
+ clearAllResizeFrames();
return mDragController.onInterceptTouchEvent(ev);
}
@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;
+ }
+ }
+ if (handled) return true;
return mDragController.onTouchEvent(ev);
}
@@ -83,4 +161,102 @@
v.getLocationOnScreen(mTmpXY);
return createDragView(mDragController.getViewBitmap(v), mTmpXY[0], mTmpXY[1]);
}
+
+ public static class LayoutParams extends FrameLayout.LayoutParams {
+ public int x, y;
+ public boolean customPosition = false;
+
+ /**
+ * {@inheritDoc}
+ */
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+
+ 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;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public int getY() {
+ return y;
+ }
+ }
+
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
+ if (flp instanceof LayoutParams) {
+ final LayoutParams lp = (LayoutParams) flp;
+ if (lp.customPosition) {
+ child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
+ }
+ }
+ }
+ }
+
+ public void clearAllResizeFrames() {
+ if (mResizeFrames.size() > 0) {
+ for (AppWidgetResizeFrame frame: mResizeFrames) {
+ removeView(frame);
+ }
+ mResizeFrames.clear();
+ }
+ }
+
+ public boolean hasResizeFrames() {
+ return mResizeFrames.size() > 0;
+ }
+
+ public boolean isWidgetBeingResized() {
+ return mCurrentResizeFrame != null;
+ }
+
+ public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
+ CellLayout cellLayout) {
+ AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
+ itemInfo, widget, cellLayout, this);
+
+ LayoutParams lp = new LayoutParams(-1, -1);
+ lp.customPosition = true;
+
+ addView(resizeFrame, lp);
+ mResizeFrames.add(resizeFrame);
+
+ resizeFrame.snapToWidget(false);
+ }
+
+ public void setLauncher(Launcher l) {
+ mLauncher = l;
+ }
+
+ public void setCurrentFolder(Folder f) {
+ mCurrentFolder = f;
+ }
}
diff --git a/src/com/android/launcher2/DragScroller.java b/src/com/android/launcher2/DragScroller.java
index 6af9c30..6ef4bd8 100644
--- a/src/com/android/launcher2/DragScroller.java
+++ b/src/com/android/launcher2/DragScroller.java
@@ -26,6 +26,7 @@
/**
* 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 @@
/**
* 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 11cdcc9..649120d 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -23,13 +23,11 @@
*
*/
public interface DragSource {
- void setDragController(DragController dragger);
-
/**
* Callback from the DragController when it begins drawing the drag view.
* This allows the DragSource to dim or hide the original view.
*/
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 c0776a9..b02e22b 100644
--- a/src/com/android/launcher2/DragView.java
+++ b/src/com/android/launcher2/DragView.java
@@ -26,6 +26,7 @@
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.os.IBinder;
import android.view.Gravity;
import android.view.View;
@@ -42,10 +43,7 @@
private int mRegistrationX;
private int mRegistrationY;
- private int mDragRegionLeft = 0;
- private int mDragRegionTop = 0;
- private int mDragRegionWidth;
- private int mDragRegionHeight;
+ private Rect mDragRegion = null;
ValueAnimator mAnim;
private float mOffsetX = 0.0f;
@@ -87,8 +85,8 @@
scale.setScale(scaleFactor, scaleFactor);
}
- final int offsetX = res.getInteger(R.integer.config_dragViewOffsetX);
- final int offsetY = res.getInteger(R.integer.config_dragViewOffsetY);
+ final int offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
+ final int offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY);
// Animate the view into the correct position
mAnim = ValueAnimator.ofFloat(0.0f, 1.0f);
@@ -117,7 +115,7 @@
});
mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height, scale, true);
- setDragRegion(0, 0, width, height);
+ setDragRegion(new Rect(0, 0, width, height));
// The point in our scaled bitmap that the touch events are located
mRegistrationX = registrationX;
@@ -132,31 +130,32 @@
return mOffsetY;
}
- public void setDragRegion(int left, int top, int width, int height) {
- mDragRegionLeft = left;
- mDragRegionTop = top;
- mDragRegionWidth = width;
- mDragRegionHeight = height;
- }
-
public void setOnDrawRunnable(Runnable r) {
mOnDrawRunnable = r;
}
public int getDragRegionLeft() {
- return mDragRegionLeft;
+ return mDragRegion.left;
}
public int getDragRegionTop() {
- return mDragRegionTop;
+ return mDragRegion.top;
}
public int getDragRegionWidth() {
- return mDragRegionWidth;
+ return mDragRegion.width();
}
public int getDragRegionHeight() {
- return mDragRegionHeight;
+ return mDragRegion.height();
+ }
+
+ public void setDragRegion(Rect r) {
+ mDragRegion = r;
+ }
+
+ public Rect getDragRegion() {
+ return mDragRegion;
}
@Override
@@ -245,5 +244,13 @@
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/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
new file mode 100644
index 0000000..861a70b
--- /dev/null
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -0,0 +1,1056 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import android.content.res.Configuration;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.TabHost;
+import android.widget.TabWidget;
+
+import com.android.launcher.R;
+
+/**
+ * A keyboard listener we set on all the button bar buttons.
+ */
+class ButtonBarKeyEventListener implements View.OnKeyListener {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ return FocusHelper.handleButtonBarButtonKeyEvent(v, keyCode, event);
+ }
+}
+
+/**
+ * A keyboard listener we set on the indicator buttons.
+ */
+class IndicatorKeyEventListener implements View.OnKeyListener {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ return FocusHelper.handleIndicatorButtonKeyEvent(v, keyCode, event);
+ }
+}
+
+/**
+ * A keyboard listener we set on all the dock buttons.
+ */
+class DockKeyEventListener implements View.OnKeyListener {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ final Configuration configuration = v.getResources().getConfiguration();
+ return FocusHelper.handleDockButtonKeyEvent(v, keyCode, event, configuration.orientation);
+ }
+}
+
+/**
+ * A keyboard listener we set on the last tab button in AllApps to jump to then
+ * market icon and vice versa.
+ */
+class AllAppsTabKeyEventListener implements View.OnKeyListener {
+ @Override
+ public boolean onKey(View v, int keyCode, KeyEvent event) {
+ return FocusHelper.handleAllAppsTabKeyEvent(v, keyCode, event);
+ }
+}
+
+public class FocusHelper {
+ /**
+ * Private helper to get the parent TabHost in the view hiearchy.
+ */
+ private static TabHost findTabHostParent(View v) {
+ ViewParent p = v.getParent();
+ while (p != null && !(p instanceof TabHost)) {
+ p = p.getParent();
+ }
+ return (TabHost) p;
+ }
+
+ /**
+ * Handles key events in a AllApps tab between the last tab view and the shop button.
+ */
+ static boolean handleAllAppsTabKeyEvent(View v, int keyCode, KeyEvent e) {
+ final TabHost tabHost = findTabHostParent(v);
+ final ViewGroup contents = (ViewGroup)
+ tabHost.findViewById(com.android.internal.R.id.tabcontent);
+ final View shop = tabHost.findViewById(R.id.market_button);
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the shop button if we aren't on it
+ if (v != shop) {
+ shop.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the content view (down is handled by the tab key handler otherwise)
+ if (v == shop) {
+ contents.requestFocus();
+ wasHandled = true;
+ }
+ }
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Private helper to determine whether a view is visible.
+ */
+ private static boolean isVisible(View v) {
+ return v.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * Handles key events in a PageViewExtendedLayout containing PagedViewWidgets.
+ * To be deprecated.
+ */
+ static boolean handlePagedViewWidgetKeyEvent(PagedViewWidget w, int keyCode, KeyEvent e) {
+ if (!LauncherApplication.isScreenLarge()) return false;
+
+ final PagedViewExtendedLayout parent = (PagedViewExtendedLayout) w.getParent();
+ final ViewGroup container = (ViewGroup) parent.getParent();
+ final TabHost tabHost = findTabHostParent(container);
+ final TabWidget tabs = (TabWidget) tabHost.findViewById(com.android.internal.R.id.tabs);
+ final int widgetIndex = parent.indexOfChild(w);
+ final int widgetCount = parent.getChildCount();
+ final int pageIndex = container.indexOfChild(parent);
+ final int pageCount = container.getChildCount();
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ PagedViewExtendedLayout newParent = null;
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous widget or the last widget on the previous page
+ if (widgetIndex > 0) {
+ parent.getChildAt(widgetIndex - 1).requestFocus();
+ } else {
+ if (pageIndex > 0) {
+ newParent = (PagedViewExtendedLayout)
+ container.getChildAt(pageIndex - 1);
+ newParent.getChildAt(newParent.getChildCount() - 1).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next widget or the first widget on the next page
+ if (widgetIndex < (widgetCount - 1)) {
+ parent.getChildAt(widgetIndex + 1).requestFocus();
+ } else {
+ if (pageIndex < (pageCount - 1)) {
+ newParent = (PagedViewExtendedLayout)
+ container.getChildAt(pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select widgets tab on the tab bar
+ tabs.requestFocus();
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // TODO: Should focus the global search bar
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ if (handleKeyEvent) {
+ // Simulate a click on the widget
+ View.OnClickListener clickListener = (View.OnClickListener) container;
+ clickListener.onClick(w);
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_UP:
+ if (handleKeyEvent) {
+ // Select the first item on the previous page, or the first item on this page
+ // if there is no previous page
+ if (pageIndex > 0) {
+ newParent = (PagedViewExtendedLayout) container.getChildAt(pageIndex - 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(0).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_DOWN:
+ if (handleKeyEvent) {
+ // Select the first item on the next page, or the last item on this page
+ // if there is no next page
+ if (pageIndex < (pageCount - 1)) {
+ newParent = (PagedViewExtendedLayout) container.getChildAt(pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_HOME:
+ if (handleKeyEvent) {
+ // Select the first item on this page
+ parent.getChildAt(0).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_END:
+ if (handleKeyEvent) {
+ // Select the last item on this page
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Handles key events in a PageViewExtendedLayout containing PagedViewWidgets.
+ */
+ static boolean handlePagedViewGridLayoutWidgetKeyEvent(PagedViewWidget w, int keyCode,
+ KeyEvent e) {
+
+ final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
+ final ViewGroup container = (ViewGroup) parent.getParent();
+ final TabHost tabHost = findTabHostParent(container);
+ final TabWidget tabs = (TabWidget) tabHost.findViewById(com.android.internal.R.id.tabs);
+ final int widgetIndex = parent.indexOfChild(w);
+ final int widgetCount = parent.getChildCount();
+ final int pageIndex = container.indexOfChild(parent);
+ final int pageCount = container.getChildCount();
+ final int cellCountX = parent.getCellCountX();
+ final int cellCountY = parent.getCellCountY();
+ final int x = widgetIndex % cellCountX;
+ final int y = widgetIndex / cellCountX;
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ PagedViewGridLayout newParent = null;
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous widget or the last widget on the previous page
+ if (widgetIndex > 0) {
+ parent.getChildAt(widgetIndex - 1).requestFocus();
+ } else {
+ if (pageIndex > 0) {
+ newParent = (PagedViewGridLayout)
+ container.getChildAt(pageIndex - 1);
+ newParent.getChildAt(newParent.getChildCount() - 1).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next widget or the first widget on the next page
+ if (widgetIndex < (widgetCount - 1)) {
+ parent.getChildAt(widgetIndex + 1).requestFocus();
+ } else {
+ if (pageIndex < (pageCount - 1)) {
+ newParent = (PagedViewGridLayout)
+ container.getChildAt(pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select the closest icon in the previous row, otherwise select the tab bar
+ if (y > 0) {
+ int newWidgetIndex = ((y - 1) * cellCountX) + x;
+ parent.getChildAt(newWidgetIndex).requestFocus();
+ } else {
+ tabs.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the closest icon in the previous row, otherwise do nothing
+ if (y < (cellCountY - 1)) {
+ int newWidgetIndex = Math.min(widgetCount - 1, ((y + 1) * cellCountX) + x);
+ parent.getChildAt(newWidgetIndex).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ if (handleKeyEvent) {
+ // Simulate a click on the widget
+ View.OnClickListener clickListener = (View.OnClickListener) container;
+ clickListener.onClick(w);
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_UP:
+ if (handleKeyEvent) {
+ // Select the first item on the previous page, or the first item on this page
+ // if there is no previous page
+ if (pageIndex > 0) {
+ newParent = (PagedViewGridLayout) container.getChildAt(pageIndex - 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(0).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_DOWN:
+ if (handleKeyEvent) {
+ // Select the first item on the next page, or the last item on this page
+ // if there is no next page
+ if (pageIndex < (pageCount - 1)) {
+ newParent = (PagedViewGridLayout) container.getChildAt(pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_HOME:
+ if (handleKeyEvent) {
+ // Select the first item on this page
+ parent.getChildAt(0).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_END:
+ if (handleKeyEvent) {
+ // Select the last item on this page
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Private helper method to get the PagedViewCellLayoutChildren given a PagedViewCellLayout
+ * index.
+ */
+ private static PagedViewCellLayoutChildren getPagedViewCellLayoutChildrenForIndex(
+ ViewGroup container, int i) {
+ ViewGroup parent = (ViewGroup) container.getChildAt(i);
+ return (PagedViewCellLayoutChildren) parent.getChildAt(0);
+ }
+
+ /**
+ * Handles key events in a PageViewCellLayout containing PagedViewIcons.
+ */
+ static boolean handlePagedViewIconKeyEvent(PagedViewIcon v, int keyCode, KeyEvent e) {
+ final PagedViewCellLayoutChildren parent = (PagedViewCellLayoutChildren) v.getParent();
+ final PagedViewCellLayout parentLayout = (PagedViewCellLayout) parent.getParent();
+ // Note we have an extra parent because of the
+ // PagedViewCellLayout/PagedViewCellLayoutChildren relationship
+ final ViewGroup container = (ViewGroup) parentLayout.getParent();
+ final TabHost tabHost = findTabHostParent(container);
+ final TabWidget tabs = (TabWidget) tabHost.findViewById(com.android.internal.R.id.tabs);
+ final int widgetIndex = parent.indexOfChild(v);
+ final int widgetCount = parent.getChildCount();
+ final int pageIndex = container.indexOfChild(parentLayout);
+ final int pageCount = container.getChildCount();
+ final int cellCountX = parentLayout.getCellCountX();
+ final int cellCountY = parentLayout.getCellCountY();
+ final int x = widgetIndex % cellCountX;
+ final int y = widgetIndex / cellCountX;
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ PagedViewCellLayoutChildren newParent = null;
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous icon or the last icon on the previous page
+ if (widgetIndex > 0) {
+ parent.getChildAt(widgetIndex - 1).requestFocus();
+ } else {
+ if (pageIndex > 0) {
+ newParent = getPagedViewCellLayoutChildrenForIndex(container,
+ pageIndex - 1);
+ newParent.getChildAt(newParent.getChildCount() - 1).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next icon or the first icon on the next page
+ if (widgetIndex < (widgetCount - 1)) {
+ parent.getChildAt(widgetIndex + 1).requestFocus();
+ } else {
+ if (pageIndex < (pageCount - 1)) {
+ newParent = getPagedViewCellLayoutChildrenForIndex(container,
+ pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select the closest icon in the previous row, otherwise select the tab bar
+ if (y > 0) {
+ int newWidgetIndex = ((y - 1) * cellCountX) + x;
+ parent.getChildAt(newWidgetIndex).requestFocus();
+ } else {
+ tabs.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the closest icon in the previous row, otherwise do nothing
+ if (y < (cellCountY - 1)) {
+ int newWidgetIndex = Math.min(widgetCount - 1, ((y + 1) * cellCountX) + x);
+ parent.getChildAt(newWidgetIndex).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ if (handleKeyEvent) {
+ // Simulate a click on the icon
+ View.OnClickListener clickListener = (View.OnClickListener) container;
+ clickListener.onClick(v);
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_UP:
+ if (handleKeyEvent) {
+ // Select the first icon on the previous page, or the first icon on this page
+ // if there is no previous page
+ if (pageIndex > 0) {
+ newParent = getPagedViewCellLayoutChildrenForIndex(container,
+ pageIndex - 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(0).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_DOWN:
+ if (handleKeyEvent) {
+ // Select the first icon on the next page, or the last icon on this page
+ // if there is no next page
+ if (pageIndex < (pageCount - 1)) {
+ newParent = getPagedViewCellLayoutChildrenForIndex(container,
+ pageIndex + 1);
+ newParent.getChildAt(0).requestFocus();
+ } else {
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_HOME:
+ if (handleKeyEvent) {
+ // Select the first icon on this page
+ parent.getChildAt(0).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_END:
+ if (handleKeyEvent) {
+ // Select the last icon on this page
+ parent.getChildAt(widgetCount - 1).requestFocus();
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Handles key events in the tab widget.
+ */
+ static boolean handleTabKeyEvent(AccessibleTabView v, int keyCode, KeyEvent e) {
+ if (!LauncherApplication.isScreenLarge()) return false;
+
+ final FocusOnlyTabWidget parent = (FocusOnlyTabWidget) v.getParent();
+ final TabHost tabHost = findTabHostParent(parent);
+ final ViewGroup contents = (ViewGroup)
+ tabHost.findViewById(com.android.internal.R.id.tabcontent);
+ final int tabCount = parent.getTabCount();
+ final int tabIndex = parent.getChildTabIndex(v);
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous tab
+ if (tabIndex > 0) {
+ parent.getChildTabViewAt(tabIndex - 1).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next tab, or if the last tab has a focus right id, select that
+ if (tabIndex < (tabCount - 1)) {
+ parent.getChildTabViewAt(tabIndex + 1).requestFocus();
+ } else {
+ if (v.getNextFocusRightId() != View.NO_ID) {
+ tabHost.findViewById(v.getNextFocusRightId()).requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ // Do nothing
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the content view
+ contents.requestFocus();
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Handles key events in the workspace button bar.
+ */
+ static boolean handleButtonBarButtonKeyEvent(View v, int keyCode, KeyEvent e) {
+ if (!LauncherApplication.isScreenLarge()) return false;
+
+ final ViewGroup parent = (ViewGroup) v.getParent();
+ final ViewGroup launcher = (ViewGroup) parent.getParent();
+ final Workspace workspace = (Workspace) launcher.findViewById(R.id.workspace);
+ final int buttonIndex = parent.indexOfChild(v);
+ final int buttonCount = parent.getChildCount();
+ final int pageIndex = workspace.getCurrentPage();
+ final int pageCount = workspace.getChildCount();
+ final int firstButtonIndex = parent.indexOfChild(parent.findViewById(R.id.search_button));
+ final int lastButtonIndex = parent.indexOfChild(parent.findViewById(R.id.configure_button));
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous button, otherwise do nothing (since the button bar is
+ // static)
+ if (buttonIndex > firstButtonIndex) {
+ int newButtonIndex = buttonIndex - 1;
+ while (newButtonIndex >= firstButtonIndex) {
+ View prev = parent.getChildAt(newButtonIndex);
+ if (isVisible(prev) && prev.isFocusable()) {
+ prev.requestFocus();
+ break;
+ }
+ --newButtonIndex;
+ }
+ } else {
+ if (pageIndex > 0) {
+ // Snap to previous page and clear focus
+ workspace.snapToPage(pageIndex - 1);
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next button, otherwise do nothing (since the button bar is
+ // static)
+ if (buttonIndex < lastButtonIndex) {
+ int newButtonIndex = buttonIndex + 1;
+ while (newButtonIndex <= lastButtonIndex) {
+ View next = parent.getChildAt(newButtonIndex);
+ if (isVisible(next) && next.isFocusable()) {
+ next.requestFocus();
+ break;
+ }
+ ++newButtonIndex;
+ }
+ } else {
+ if (pageIndex < (pageCount - 1)) {
+ // Snap to next page and clear focus
+ workspace.snapToPage(pageIndex + 1);
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ // Do nothing
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the first bubble text view in the current page of the workspace
+ final CellLayout layout = (CellLayout) workspace.getChildAt(pageIndex);
+ final CellLayoutChildren children = layout.getChildrenLayout();
+ final View newIcon = getBubbleTextViewInDirection(layout, children, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ workspace.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Handles key events in the prev/next indicators.
+ */
+ static boolean handleIndicatorButtonKeyEvent(View v, int keyCode, KeyEvent e) {
+ final ViewGroup launcher = (ViewGroup) v.getParent();
+ final Workspace workspace = (Workspace) launcher.findViewById(R.id.workspace);
+ final ViewGroup hotseat = (ViewGroup) launcher.findViewById(R.id.all_apps_button_cluster);
+ final View previousIndicator = launcher.findViewById(R.id.previous_screen);
+ final View nextIndicator = launcher.findViewById(R.id.next_screen);
+ final int pageIndex = workspace.getCurrentPage();
+ final int pageCount = workspace.getChildCount();
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ if (v == previousIndicator) {
+ if (pageIndex > 0) {
+ // Snap to previous page and clear focus
+ workspace.snapToPage(pageIndex - 1);
+ }
+ } else if (v == nextIndicator) {
+ // Select the last button in the hot seat
+ hotseat.getChildAt(hotseat.getChildCount() - 1).requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ if (v == previousIndicator) {
+ // Select the first button in the hot seat
+ hotseat.getChildAt(0).requestFocus();
+ } else if (v == nextIndicator) {
+ if (pageIndex < (pageCount - 1)) {
+ // Snap to next page and clear focus
+ workspace.snapToPage(pageIndex + 1);
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select the first bubble text view in the current page of the workspace
+ final CellLayout layout = (CellLayout) workspace.getChildAt(pageIndex);
+ final CellLayoutChildren children = layout.getChildrenLayout();
+ final View newIcon = getBubbleTextViewInDirection(layout, children, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ workspace.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ // Do nothing
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Handles key events in the workspace dock (bottom of the screen).
+ */
+ static boolean handleDockButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) {
+ final ViewGroup parent = (ViewGroup) v.getParent();
+ final ViewGroup launcher = (ViewGroup) parent.getParent();
+ final Workspace workspace = (Workspace) launcher.findViewById(R.id.workspace);
+ final int buttonIndex = parent.indexOfChild(v);
+ final int buttonCount = parent.getChildCount();
+ final int pageIndex = workspace.getCurrentPage();
+ final int pageCount = workspace.getChildCount();
+ final View previousIndicator = launcher.findViewById(R.id.previous_screen);
+ final View nextIndicator = launcher.findViewById(R.id.next_screen);
+
+ // NOTE: currently we don't special case for the phone UI in different
+ // orientations, even though the dock is on the side in landscape mode. This
+ // is to ensure that accessibility consistency is maintained across rotations.
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+
+ // Select the previous button, otherwise select the previous page indicator
+ if (buttonIndex > 0) {
+ parent.getChildAt(buttonIndex - 1).requestFocus();
+ } else {
+ previousIndicator.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next button, otherwise select the next page indicator
+ if (buttonIndex < (buttonCount - 1)) {
+ parent.getChildAt(buttonIndex + 1).requestFocus();
+ } else {
+ nextIndicator.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select the first bubble text view in the current page of the workspace
+ final CellLayout layout = (CellLayout) workspace.getChildAt(pageIndex);
+ final CellLayoutChildren children = layout.getChildrenLayout();
+ final View newIcon = getBubbleTextViewInDirection(layout, children, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ workspace.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ // Do nothing
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+
+ /**
+ * Private helper method to get the CellLayoutChildren given a CellLayout index.
+ */
+ private static CellLayoutChildren getCellLayoutChildrenForIndex(ViewGroup container, int i) {
+ ViewGroup parent = (ViewGroup) container.getChildAt(i);
+ return (CellLayoutChildren) parent.getChildAt(0);
+ }
+
+ /**
+ * Private helper method to sort all the CellLayout children in order of their (x,y) spatially
+ * from top left to bottom right.
+ */
+ private static ArrayList<View> getCellLayoutChildrenSortedSpatially(CellLayout layout,
+ ViewGroup parent) {
+ // First we order each the CellLayout children by their x,y coordinates
+ final int cellCountX = layout.getCountX();
+ final int count = parent.getChildCount();
+ ArrayList<View> views = new ArrayList<View>();
+ for (int j = 0; j < count; ++j) {
+ views.add(parent.getChildAt(j));
+ }
+ Collections.sort(views, new Comparator<View>() {
+ @Override
+ public int compare(View lhs, View rhs) {
+ CellLayout.LayoutParams llp = (CellLayout.LayoutParams) lhs.getLayoutParams();
+ CellLayout.LayoutParams rlp = (CellLayout.LayoutParams) rhs.getLayoutParams();
+ int lvIndex = (llp.cellY * cellCountX) + llp.cellX;
+ int rvIndex = (rlp.cellY * cellCountX) + rlp.cellX;
+ return lvIndex - rvIndex;
+ }
+ });
+ return views;
+ }
+ /**
+ * Private helper method to find the index of the next BubbleTextView in the delta direction.
+ * @param delta either -1 or 1 depending on the direction we want to search
+ */
+ private static View findIndexOfBubbleTextView(ArrayList<View> views, int i, int delta) {
+ // Then we find the next BubbleTextView offset by delta from i
+ final int count = views.size();
+ int newI = i + delta;
+ while (0 <= newI && newI < count) {
+ View newV = views.get(newI);
+ if (newV instanceof BubbleTextView) {
+ return newV;
+ }
+ newI += delta;
+ }
+ return null;
+ }
+ private static View getBubbleTextViewInDirection(CellLayout layout, ViewGroup parent, int i,
+ int delta) {
+ final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
+ return findIndexOfBubbleTextView(views, i, delta);
+ }
+ private static View getBubbleTextViewInDirection(CellLayout layout, ViewGroup parent, View v,
+ int delta) {
+ final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
+ return findIndexOfBubbleTextView(views, views.indexOf(v), delta);
+ }
+ /**
+ * Private helper method to find the next closest BubbleTextView in the delta direction on the
+ * next line.
+ * @param delta either -1 or 1 depending on the line and direction we want to search
+ */
+ private static View getClosestBubbleTextViewOnLine(CellLayout layout, ViewGroup parent, View v,
+ int lineDelta) {
+ final ArrayList<View> views = getCellLayoutChildrenSortedSpatially(layout, parent);
+ final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
+ final int cellCountX = layout.getCountX();
+ final int cellCountY = layout.getCountY();
+ final int row = lp.cellY;
+ final int newRow = row + lineDelta;
+ if (0 <= newRow && newRow < cellCountY) {
+ float closestDistance = Float.MAX_VALUE;
+ int closestIndex = -1;
+ int index = views.indexOf(v);
+ int endIndex = (lineDelta < 0) ? -1 : views.size();
+ while (index != endIndex) {
+ View newV = views.get(index);
+ CellLayout.LayoutParams tmpLp = (CellLayout.LayoutParams) newV.getLayoutParams();
+ boolean satisfiesRow = (lineDelta < 0) ? (tmpLp.cellY < row) : (tmpLp.cellY > row);
+ if (satisfiesRow && newV instanceof BubbleTextView) {
+ float tmpDistance = (float) Math.sqrt(Math.pow(tmpLp.cellX - lp.cellX, 2) +
+ Math.pow(tmpLp.cellY - lp.cellY, 2));
+ if (tmpDistance < closestDistance) {
+ closestIndex = index;
+ closestDistance = tmpDistance;
+ }
+ }
+ if (index <= endIndex) {
+ ++index;
+ } else {
+ --index;
+ }
+ }
+ if (closestIndex > -1) {
+ return views.get(closestIndex);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Handles key events in a Workspace containing BubbleTextView.
+ */
+ static boolean handleBubbleTextViewKeyEvent(BubbleTextView v, int keyCode, KeyEvent e) {
+ CellLayoutChildren parent = (CellLayoutChildren) v.getParent();
+ final CellLayout layout = (CellLayout) parent.getParent();
+ final Workspace workspace = (Workspace) layout.getParent();
+ final ViewGroup launcher = (ViewGroup) workspace.getParent();
+ final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.all_apps_button_cluster);
+ int iconIndex = parent.indexOfChild(v);
+ int iconCount = parent.getChildCount();
+ int pageIndex = workspace.indexOfChild(layout);
+ int pageCount = workspace.getChildCount();
+
+ final int action = e.getAction();
+ final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
+ boolean wasHandled = false;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (handleKeyEvent) {
+ // Select the previous icon or the last icon on the previous page if possible
+ View newIcon = getBubbleTextViewInDirection(layout, parent, v, -1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ if (pageIndex > 0) {
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+ newIcon = getBubbleTextViewInDirection(layout, parent,
+ parent.getChildCount(), -1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ // Snap to the previous page
+ workspace.snapToPage(pageIndex - 1);
+ }
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (handleKeyEvent) {
+ // Select the next icon or the first icon on the next page if possible
+ View newIcon = getBubbleTextViewInDirection(layout, parent, v, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ if (pageIndex < (pageCount - 1)) {
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
+ newIcon = getBubbleTextViewInDirection(layout, parent, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ // Snap to the next page
+ workspace.snapToPage(pageIndex + 1);
+ }
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (handleKeyEvent) {
+ // Select the closest icon in the previous line, otherwise select the tab bar
+ View newIcon = getClosestBubbleTextViewOnLine(layout, parent, v, -1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ wasHandled = true;
+ } else {
+ tabs.requestFocus();
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (handleKeyEvent) {
+ // Select the closest icon in the next line, otherwise select the tab bar
+ View newIcon = getClosestBubbleTextViewOnLine(layout, parent, v, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ wasHandled = true;
+ }
+ }
+ break;
+ case KeyEvent.KEYCODE_PAGE_UP:
+ if (handleKeyEvent) {
+ // Select the first icon on the previous page or the first icon on this page
+ // if there is no previous page
+ if (pageIndex > 0) {
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex - 1);
+ View newIcon = getBubbleTextViewInDirection(layout, parent, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ // Snap to the previous page
+ workspace.snapToPage(pageIndex - 1);
+ }
+ } else {
+ View newIcon = getBubbleTextViewInDirection(layout, parent, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_PAGE_DOWN:
+ if (handleKeyEvent) {
+ // Select the first icon on the next page or the last icon on this page
+ // if there is no previous page
+ if (pageIndex < (pageCount - 1)) {
+ parent = getCellLayoutChildrenForIndex(workspace, pageIndex + 1);
+ View newIcon = getBubbleTextViewInDirection(layout, parent, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ } else {
+ // Snap to the next page
+ workspace.snapToPage(pageIndex + 1);
+ }
+ } else {
+ View newIcon = getBubbleTextViewInDirection(layout, parent,
+ parent.getChildCount(), -1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ }
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_HOME:
+ if (handleKeyEvent) {
+ // Select the first icon on this page
+ View newIcon = getBubbleTextViewInDirection(layout, parent, -1, 1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ case KeyEvent.KEYCODE_MOVE_END:
+ if (handleKeyEvent) {
+ // Select the last icon on this page
+ View newIcon = getBubbleTextViewInDirection(layout, parent,
+ parent.getChildCount(), -1);
+ if (newIcon != null) {
+ newIcon.requestFocus();
+ }
+ }
+ wasHandled = true;
+ break;
+ default: break;
+ }
+ return wasHandled;
+ }
+}
diff --git a/src/com/android/launcher2/FocusOnlyTabWidget.java b/src/com/android/launcher2/FocusOnlyTabWidget.java
new file mode 100644
index 0000000..8e9f58c
--- /dev/null
+++ b/src/com/android/launcher2/FocusOnlyTabWidget.java
@@ -0,0 +1,86 @@
+/*
+ * 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.util.AttributeSet;
+import android.view.View;
+import android.widget.TabWidget;
+
+public class FocusOnlyTabWidget extends TabWidget {
+ public FocusOnlyTabWidget(Context context) {
+ super(context);
+ }
+
+ public FocusOnlyTabWidget(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public FocusOnlyTabWidget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public View getSelectedTab() {
+ final int count = getTabCount();
+ for (int i = 0; i < count; ++i) {
+ View v = getChildTabViewAt(i);
+ if (v.isSelected()) {
+ return v;
+ }
+ }
+ return null;
+ }
+
+ public int getChildTabIndex(View v) {
+ final int tabCount = getTabCount();
+ for (int i = 0; i < tabCount; ++i) {
+ if (getChildTabViewAt(i) == v) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public void setCurrentTabToFocusedTab() {
+ View tab = null;
+ int index = -1;
+ final int count = getTabCount();
+ for (int i = 0; i < count; ++i) {
+ View v = getChildTabViewAt(i);
+ if (v.hasFocus()) {
+ tab = v;
+ index = i;
+ break;
+ }
+ }
+ if (index > -1) {
+ super.setCurrentTab(index);
+ super.onFocusChange(tab, true);
+ }
+ }
+ public void superOnFocusChange(View v, boolean hasFocus) {
+ super.onFocusChange(v, hasFocus);
+ }
+
+ @Override
+ public void onFocusChange(android.view.View v, boolean hasFocus) {
+ if (v == this && hasFocus && getTabCount() > 0) {
+ getSelectedTab().requestFocus();
+ return;
+ }
+ }
+}
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index cb450b9..0470e41 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -16,34 +16,42 @@
package com.android.launcher2;
+import java.util.ArrayList;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.AbsListView;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.Button;
import android.widget.LinearLayout;
+import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import com.android.launcher.R;
+import com.android.launcher2.FolderInfo.FolderListener;
/**
* Represents a set of icons chosen by the user or generated by the system.
*/
public class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
- OnItemClickListener, OnClickListener, View.OnLongClickListener {
+ OnItemClickListener, OnClickListener, View.OnLongClickListener, DropTarget, FolderListener {
- protected AbsListView mContent;
protected DragController mDragController;
-
+
protected Launcher mLauncher;
- protected Button mCloseButton;
-
protected FolderInfo mInfo;
/**
@@ -51,6 +59,30 @@
*/
protected ShortcutInfo mDragItem;
+ private static final String TAG = "Launcher.Folder";
+
+ static final int STATE_NONE = -1;
+ static final int STATE_SMALL = 0;
+ static final int STATE_ANIMATING = 1;
+ static final int STATE_OPEN = 2;
+
+ private int mExpandDuration;
+ protected CellLayout mContent;
+ private final LayoutInflater mInflater;
+ private final IconCache mIconCache;
+ private int mState = STATE_NONE;
+ private int[] mDragItemPosition = new int[2];
+ private static final int FULL_GROW = 0;
+ private static final int PARTIAL_GROW = 1;
+ private int mMode = PARTIAL_GROW;
+ private boolean mRearrangeOnClose = false;
+ private FolderIcon mFolderIcon;
+ private int mMaxCountX;
+ private int mMaxCountY;
+ private Rect mNewSize = new Rect();
+ private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
+ boolean mItemsInvalidated = false;
+
/**
* Used to inflate the Workspace from XML.
*
@@ -60,21 +92,22 @@
public Folder(Context context, AttributeSet attrs) {
super(context, attrs);
setAlwaysDrawnWithCacheEnabled(false);
+ mInflater = LayoutInflater.from(context);
+ mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache();
+ mExpandDuration = getResources().getInteger(R.integer.config_folderAnimDuration);
+
+ mMaxCountX = LauncherModel.getCellCountX() - 1;
+ mMaxCountY = LauncherModel.getCellCountY() - 1;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
-
- mContent = (AbsListView) findViewById(R.id.folder_content);
- mContent.setOnItemClickListener(this);
- mContent.setOnItemLongClickListener(this);
-
- mCloseButton = (Button) findViewById(R.id.folder_close);
- mCloseButton.setOnClickListener(this);
- mCloseButton.setOnLongClickListener(this);
+ mContent = (CellLayout) findViewById(R.id.folder_content);
+ mContent.setGridSize(0, 0);
+ mContent.enableHardwareLayers();
}
-
+
public void onItemClick(AdapterView parent, View v, int position, long id) {
ShortcutInfo app = (ShortcutInfo) parent.getItemAtPosition(position);
int[] pos = new int[2];
@@ -85,12 +118,47 @@
}
public void onClick(View v) {
- mLauncher.closeFolder(this);
+ Object tag = v.getTag();
+ if (tag instanceof ShortcutInfo) {
+ // refactor this code from Folder
+ ShortcutInfo item = (ShortcutInfo) tag;
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ item.intent.setSourceBounds(new Rect(pos[0], pos[1],
+ pos[0] + v.getWidth(), pos[1] + v.getHeight()));
+ mLauncher.startActivitySafely(item.intent, item);
+ }
}
public boolean onLongClick(View v) {
- mLauncher.closeFolder(this);
- mLauncher.showRenameDialog(mInfo);
+ Object tag = v.getTag();
+ if (tag instanceof ShortcutInfo) {
+ mLauncher.closeFolder(this);
+
+ ShortcutInfo item = (ShortcutInfo) tag;
+ if (!v.isInTouchMode()) {
+ return false;
+ }
+
+ mLauncher.getWorkspace().onDragStartedWithItem(v);
+ mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY);
+ mDragItemPosition[0] = item.cellX;
+ mDragItemPosition[1] = item.cellY;
+ mInfo.remove(item);
+
+ mDragItem = item;
+ } else {
+ mLauncher.closeFolder(this);
+ mLauncher.showRenameDialog(mInfo);
+ }
+ return true;
+ }
+
+ /**
+ * We need to handle touch events to prevent them from falling through to the workspace below.
+ */
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
return true;
}
@@ -108,37 +176,21 @@
return true;
}
- @Override
public void setDragController(DragController dragController) {
mDragController = dragController;
}
- @Override
- public void onDropCompleted(View target, boolean success) {
- }
-
- @Override
public void onDragViewVisible() {
}
- /**
- * Sets the adapter used to populate the content area. The adapter must only
- * contains ShortcutInfo items.
- *
- * @param adapter The list of applications to display in the folder.
- */
- void setContentAdapter(BaseAdapter adapter) {
- mContent.setAdapter(adapter);
- }
-
- void notifyDataSetChanged() {
- ((BaseAdapter) mContent.getAdapter()).notifyDataSetChanged();
- }
-
void setLauncher(Launcher launcher) {
mLauncher = launcher;
}
-
+
+ void setFolderIcon(FolderIcon icon) {
+ mFolderIcon = icon;
+ }
+
/**
* @return the FolderInfo object associated with this folder
*/
@@ -146,10 +198,12 @@
return mInfo;
}
- // When the folder opens, we need to refresh the GridView's selection by
- // forcing a layout
void onOpen() {
+ // When the folder opens, we need to refresh the GridView's selection by
+ // forcing a layout
+ // TODO: find out if this is still necessary
mContent.requestLayout();
+ requestFocus();
}
void onClose() {
@@ -159,6 +213,413 @@
void bind(FolderInfo info) {
mInfo = info;
- mCloseButton.setText(info.title);
+ ArrayList<ShortcutInfo> children = info.contents;
+ setupContentForNumItems(children.size());
+ for (int i = 0; i < children.size(); i++) {
+ ShortcutInfo child = (ShortcutInfo) children.get(i);
+ createAndAddShortcut(child);
+ }
+ mItemsInvalidated = true;
+ mInfo.addListener(this);
+ }
+
+ /**
+ * Creates a new UserFolder, inflated from R.layout.user_folder.
+ *
+ * @param context The application's context.
+ *
+ * @return A new UserFolder.
+ */
+ static Folder fromXml(Context context) {
+ return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
+ }
+
+ /**
+ * This method is intended to make the UserFolder to be visually identical in size and position
+ * to its associated FolderIcon. This allows for a seamless transition into the expanded state.
+ */
+ private void positionAndSizeAsIcon() {
+ if (!(getParent() instanceof CellLayoutChildren)) return;
+
+ CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ if (mMode == PARTIAL_GROW) {
+ setScaleX(0.8f);
+ setScaleY(0.8f);
+ setAlpha(0f);
+ } else {
+ lp.width = iconLp.width;
+ lp.height = iconLp.height;
+ lp.x = iconLp.x;
+ lp.y = iconLp.y;
+ mContent.setAlpha(0);
+ }
+ mState = STATE_SMALL;
+ }
+
+ public void animateOpen() {
+ if (mState != STATE_SMALL) {
+ positionAndSizeAsIcon();
+ }
+ if (!(getParent() instanceof CellLayoutChildren)) return;
+
+ ObjectAnimator oa;
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ centerAboutIcon();
+ if (mMode == PARTIAL_GROW) {
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1);
+ PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
+ PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
+ oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
+ } else {
+ PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mNewSize.width());
+ PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mNewSize.height());
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mNewSize.left);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mNewSize.top);
+ oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
+ oa.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ requestLayout();
+ }
+ });
+
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
+ ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
+ alphaOa.setDuration(mExpandDuration);
+ alphaOa.setInterpolator(new AccelerateInterpolator(2.0f));
+ alphaOa.start();
+ }
+
+ oa.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = STATE_ANIMATING;
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mState = STATE_OPEN;
+ }
+ });
+ oa.setDuration(mExpandDuration);
+ oa.start();
+ }
+
+ public void animateClosed() {
+ if (!(getParent() instanceof CellLayoutChildren)) return;
+
+ CellLayoutChildren clc = (CellLayoutChildren) getParent();
+ final CellLayout cellLayout = (CellLayout) clc.getParent();
+ ObjectAnimator oa;
+
+ if (mMode == PARTIAL_GROW) {
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
+ PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f);
+ PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f);
+ oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
+ } else {
+ CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width);
+ PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height);
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y);
+ oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
+ oa.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ requestLayout();
+ }
+ });
+
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
+ ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
+ alphaOa.setDuration(mExpandDuration);
+ alphaOa.setInterpolator(new DecelerateInterpolator(2.0f));
+ alphaOa.start();
+ }
+
+ oa.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ onCloseComplete();
+ cellLayout.removeViewWithoutMarkingCells(Folder.this);
+ mState = STATE_SMALL;
+ }
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = STATE_ANIMATING;
+ }
+ });
+ oa.setDuration(mExpandDuration);
+ oa.start();
+ }
+
+ void notifyDataSetChanged() {
+ // recreate all the children if the data set changes under us. We may want to do this more
+ // intelligently (ie just removing the views that should no longer exist)
+ mContent.removeAllViewsInLayout();
+ bind(mInfo);
+ }
+
+ public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ final ItemInfo item = (ItemInfo) dragInfo;
+ final int itemType = item.itemType;
+ return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
+ !isFull());
+ }
+
+ public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ ShortcutInfo item;
+ if (dragInfo instanceof ApplicationInfo) {
+ // Came from all apps -- make a copy
+ item = ((ApplicationInfo)dragInfo).makeShortcut();
+ item.spanX = 1;
+ item.spanY = 1;
+ } else {
+ item = (ShortcutInfo)dragInfo;
+ }
+ mInfo.add(item);
+ LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
+ }
+
+ protected boolean findAndSetEmptyCells(ShortcutInfo item) {
+ int[] emptyCell = new int[2];
+ if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
+ item.cellX = emptyCell[0];
+ item.cellY = emptyCell[1];
+ LauncherModel.addOrMoveItemInDatabase(
+ mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected void createAndAddShortcut(ShortcutInfo item) {
+ final TextView textView =
+ (TextView) mInflater.inflate(R.layout.application_boxed, this, false);
+ textView.setCompoundDrawablesWithIntrinsicBounds(null,
+ new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
+ textView.setText(item.title);
+ textView.setTag(item);
+
+ textView.setOnClickListener(this);
+ textView.setOnLongClickListener(this);
+
+ CellLayout.LayoutParams lp =
+ new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
+ boolean insert = false;
+ mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
+ }
+
+ public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ mContent.onDragEnter();
+ }
+
+ public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ float[] r = mapPointFromScreenToContent(x, y, null);
+ mContent.visualizeDropLocation(null, null, (int) r[0], (int) r[1], 1, 1);
+ }
+
+ public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ mContent.onDragExit();
+ }
+
+ public float[] mapPointFromScreenToContent(int x, int y, float[] r) {
+ if (r == null) {
+ r = new float[2];
+ }
+
+ int[] screenLocation = new int[2];
+ mContent.getLocationOnScreen(screenLocation);
+
+ r[0] = x - screenLocation[0];
+ r[1] = y - screenLocation[1];
+ return r;
+ }
+
+ public void onDropCompleted(View target, Object dragInfo, boolean success) {
+ }
+
+ public boolean isDropEnabled() {
+ return true;
+ }
+
+ public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ return null;
+ }
+
+ private void setupContentDimension(int count) {
+ ArrayList<View> list = getItemsInReadingOrder();
+
+ int countX = mContent.getCountX();
+ int countY = mContent.getCountY();
+ boolean done = false;
+
+ while (!done) {
+ int oldCountX = countX;
+ int oldCountY = countY;
+ if (countX * countY < count) {
+ // Current grid is too small, expand it
+ if (countX <= countY && countX < mMaxCountX) {
+ countX++;
+ } else if (countY < mMaxCountY) {
+ countY++;
+ }
+ if (countY == 0) countY++;
+ } else if ((countY - 1) * countX >= count && countY >= countX) {
+ countY = Math.max(0, countY - 1);
+ } else if ((countX - 1) * countY >= count) {
+ countX = Math.max(0, countX - 1);
+ }
+ done = countX == oldCountX && countY == oldCountY;
+ }
+ mContent.setGridSize(countX, countY);
+ arrangeChildren(list);
+ }
+
+ public boolean isFull() {
+ return getItemCount() >= mMaxCountX * mMaxCountY;
+ }
+
+ private void centerAboutIcon() {
+ CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
+ int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight();
+
+ int centerX = iconLp.x + iconLp.width / 2;
+ int centerY = iconLp.y + iconLp.height / 2;
+ int centeredLeft = centerX - width / 2;
+ int centeredTop = centerY - height / 2;
+
+ CellLayoutChildren clc = (CellLayoutChildren) getParent();
+ int parentWidth = 0;
+ int parentHeight = 0;
+ if (clc != null) {
+ parentWidth = clc.getMeasuredWidth();
+ parentHeight = clc.getMeasuredHeight();
+ }
+
+ int left = Math.min(Math.max(0, centeredLeft), parentWidth - width);
+ int top = Math.min(Math.max(0, centeredTop), parentHeight - height);
+
+ int folderPivotX = width / 2 + (centeredLeft - left);
+ int folderPivotY = height / 2 + (centeredTop - top);
+ setPivotX(folderPivotX);
+ setPivotY(folderPivotY);
+ int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
+ (1.0f * folderPivotX / width));
+ int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
+ (1.0f * folderPivotY / height));
+ mFolderIcon.setPivotX(folderIconPivotX);
+ mFolderIcon.setPivotY(folderIconPivotY);
+
+ if (mMode == PARTIAL_GROW) {
+ lp.width = width;
+ lp.height = height;
+ lp.x = left;
+ lp.y = top;
+ } else {
+ mNewSize.set(left, top, left + width, top + height);
+ }
+ }
+
+ private void setupContentForNumItems(int count) {
+ setupContentDimension(count);
+
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+ if (lp == null) {
+ lp = new CellLayout.LayoutParams(0, 0, -1, -1);
+ lp.isLockedToGrid = false;
+ setLayoutParams(lp);
+ }
+ centerAboutIcon();
+ }
+
+ private void arrangeChildren(ArrayList<View> list) {
+ int[] vacant = new int[2];
+ if (list == null) {
+ list = getItemsInReadingOrder();
+ }
+ mContent.removeAllViews();
+
+ for (int i = 0; i < list.size(); i++) {
+ View v = list.get(i);
+ mContent.getVacantCell(vacant, 1, 1);
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
+ lp.cellX = vacant[0];
+ lp.cellY = vacant[1];
+ ItemInfo info = (ItemInfo) v.getTag();
+ info.cellX = vacant[0];
+ info.cellY = vacant[1];
+ boolean insert = false;
+ mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true);
+ LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
+ info.cellX, info.cellY);
+ }
+ mItemsInvalidated = true;
+ }
+
+ public void onAdd(ShortcutInfo item) {
+ mItemsInvalidated = true;
+ if (!findAndSetEmptyCells(item)) {
+ // The current layout is full, can we expand it?
+ setupContentForNumItems(getItemCount() + 1);
+ findAndSetEmptyCells(item);
+ }
+ createAndAddShortcut(item);
+ }
+
+ public int getItemCount() {
+ return mContent.getChildrenLayout().getChildCount();
+ }
+
+ public View getItemAt(int index) {
+ return mContent.getChildrenLayout().getChildAt(index);
+ }
+
+ private void onCloseComplete() {
+ if (mRearrangeOnClose) {
+ setupContentForNumItems(getItemCount());
+ mRearrangeOnClose = false;
+ }
+ }
+
+ public void onRemove(ShortcutInfo item) {
+ mItemsInvalidated = true;
+ View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
+ mContent.removeView(v);
+ if (mState == STATE_ANIMATING) {
+ mRearrangeOnClose = true;
+ } else {
+ setupContentForNumItems(getItemCount());
+ }
+ }
+
+ public ArrayList<View> getItemsInReadingOrder() {
+ if (mItemsInvalidated) {
+ mItemsInReadingOrder.clear();
+ for (int j = 0; j < mContent.getCountY(); j++) {
+ for (int i = 0; i < mContent.getCountX(); i++) {
+ View v = mContent.getChildAt(i, j);
+ if (v != null) {
+ mItemsInReadingOrder.add(v);
+ }
+ }
+ }
+ mItemsInvalidated = false;
+ }
+ return mItemsInReadingOrder;
}
}
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index dd83c78..2a5a5a0 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -16,23 +16,55 @@
package com.android.launcher2;
+import java.util.ArrayList;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.TextView;
import com.android.launcher.R;
+import com.android.launcher2.FolderInfo.FolderListener;
/**
* An icon that can appear on in the workspace representing an {@link UserFolder}.
*/
-public class FolderIcon extends BubbleTextView implements DropTarget {
- private UserFolderInfo mInfo;
+public class FolderIcon extends FrameLayout implements DropTarget, FolderListener {
private Launcher mLauncher;
- private Drawable mCloseIcon;
- private Drawable mOpenIcon;
+ Folder mFolder;
+ FolderInfo mInfo;
+
+ private static final int NUM_ITEMS_IN_PREVIEW = 4;
+ private static final float ICON_ANGLE = 15f;
+ private static final int CONSUMPTION_ANIMATION_DURATION = 100;
+ private static final float INNER_RING_GROWTH_FACTOR = 0.1f;
+ private static final float OUTER_RING_BASELINE_SCALE = 0.7f;
+ private static final float OUTER_RING_GROWTH_FACTOR = 0.3f;
+ private static final float INNER_RING_BASELINE_SCALE = 1.0f;
+
+ public static Drawable sFolderOuterRingDrawable = null;
+ public static Drawable sFolderInnerRingDrawable = null;
+
+ private int mOriginalWidth = -1;
+ private int mOriginalHeight = -1;
+ private int mOriginalX = -1;
+ private int mOriginalY = -1;
+
+ private int mFolderLocX;
+ private int mFolderLocY;
+ private float mOuterRingScale;
+ private float mInnerRingScale;
public FolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -43,35 +75,61 @@
}
public boolean isDropEnabled() {
- return !((Workspace)getParent().getParent()).isSmall();
+ final ViewGroup cellLayoutChildren = (ViewGroup) getParent();
+ final ViewGroup cellLayout = (ViewGroup) cellLayoutChildren.getParent();
+ final Workspace workspace = (Workspace) cellLayout.getParent();
+ return !workspace.isSmall();
}
static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
- UserFolderInfo folderInfo, IconCache iconCache) {
+ FolderInfo folderInfo, IconCache iconCache) {
FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
final Resources resources = launcher.getResources();
- Drawable d = iconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder);
- icon.mCloseIcon = d;
- icon.mOpenIcon = iconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder_open);
- icon.setCompoundDrawablesWithIntrinsicBounds(null, d, null, null);
- icon.setText(folderInfo.title);
+ Drawable d = iconCache.getFullResIcon(resources, R.drawable.portal_ring_inner_holo);
+ icon.setBackgroundDrawable(d);
icon.setTag(folderInfo);
icon.setOnClickListener(launcher);
icon.mInfo = folderInfo;
icon.mLauncher = launcher;
-
+
+ Folder folder = Folder.fromXml(launcher);
+ folder.setDragController(launcher.getDragController());
+ folder.setLauncher(launcher);
+ folder.setFolderIcon(icon);
+ folder.bind(folderInfo);
+ icon.mFolder = folder;
+
+ folderInfo.addListener(icon);
+ if (sFolderOuterRingDrawable == null) {
+ sFolderOuterRingDrawable =
+ launcher.getResources().getDrawable(R.drawable.portal_ring_outer_holo);
+ }
+
+ if (sFolderInnerRingDrawable == null) {
+ sFolderInnerRingDrawable =
+ launcher.getResources().getDrawable(R.drawable.portal_ring_inner_holo);
+ }
return icon;
}
+ private boolean willAcceptItem(ItemInfo item) {
+ final int itemType = item.itemType;
+ return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
+ !mFolder.isFull() && item != mInfo);
+ }
+
public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
final ItemInfo item = (ItemInfo) dragInfo;
- final int itemType = item.itemType;
- return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
- itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
- && item.container != mInfo.id;
+ return willAcceptItem(item);
+ }
+
+ public void addItem(ShortcutInfo item) {
+ mInfo.add(item);
+ LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
}
public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
@@ -83,15 +141,84 @@
} else {
item = (ShortcutInfo)dragInfo;
}
- mInfo.add(item);
- LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
+ item.cellX = -1;
+ item.cellY = -1;
+ addItem(item);
+ }
+
+ void saveState(CellLayout.LayoutParams lp) {
+ mOriginalWidth = lp.width;
+ mOriginalHeight = lp.height;
+ mOriginalX = lp.x;
+ mOriginalY = lp.y;
+ }
+
+ private void animateToAcceptState() {
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
+ va.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ va.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float percent = (Float) animation.getAnimatedValue();
+ mOuterRingScale = OUTER_RING_BASELINE_SCALE + percent * OUTER_RING_GROWTH_FACTOR;
+ mInnerRingScale = INNER_RING_BASELINE_SCALE + percent * INNER_RING_GROWTH_FACTOR;
+ mLauncher.getWorkspace().invalidate();
+ invalidate();
+ }
+ });
+ va.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Instead of setting the background drawable to null, we set the color to
+ // transparent. Setting the background drawable to null results in onDraw
+ // not getting called.
+ setBackgroundColor(Color.TRANSPARENT);
+ requestLayout();
+ }
+ });
+ va.start();
+ }
+
+ private void animateToNaturalState() {
+ ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
+ va.setDuration(CONSUMPTION_ANIMATION_DURATION);
+ va.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float percent = (Float) animation.getAnimatedValue();
+ mOuterRingScale = OUTER_RING_BASELINE_SCALE + OUTER_RING_GROWTH_FACTOR
+ - percent * OUTER_RING_GROWTH_FACTOR;
+ mInnerRingScale = INNER_RING_BASELINE_SCALE + INNER_RING_GROWTH_FACTOR
+ - percent * INNER_RING_GROWTH_FACTOR;
+ mLauncher.getWorkspace().invalidate();
+ invalidate();
+ }
+ });
+ va.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setBackgroundDrawable(sFolderInnerRingDrawable);
+ mLauncher.getWorkspace().hideFolderAccept(FolderIcon.this);
+ }
+ });
+ va.start();
+ }
+
+ private void determineFolderLocationInWorkspace() {
+ int tvLocation[] = new int[2];
+ int wsLocation[] = new int[2];
+ getLocationOnScreen(tvLocation);
+ mLauncher.getWorkspace().getLocationOnScreen(wsLocation);
+ mFolderLocX = tvLocation[0] - wsLocation[0] + getMeasuredWidth() / 2;
+ mFolderLocY = tvLocation[1] - wsLocation[1] + getMeasuredHeight() / 2;
}
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
- if (acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) {
- setCompoundDrawablesWithIntrinsicBounds(null, mOpenIcon, null, null);
- }
+ if (!willAcceptItem((ItemInfo) dragInfo)) return;
+ determineFolderLocationInWorkspace();
+ mLauncher.getWorkspace().showFolderAccept(this);
+ animateToAcceptState();
}
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
@@ -100,7 +227,8 @@
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
- setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
+ if (!willAcceptItem((ItemInfo) dragInfo)) return;
+ animateToNaturalState();
}
@Override
@@ -108,4 +236,64 @@
DragView dragView, Object dragInfo) {
return null;
}
+
+ public void getFolderLocation(int[] loc) {
+ loc[0] = mFolderLocX;
+ loc[1] = mFolderLocY;
+ }
+
+ public float getOuterRingScale() {
+ return mOuterRingScale;
+ }
+
+ public float getInnerRingScale() {
+ return mInnerRingScale;
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mFolder == null) return;
+ if (mFolder.getItemCount() == 0) return;
+
+ canvas.save();
+ TextView v = (TextView) mFolder.getItemAt(0);
+ Drawable d = v.getCompoundDrawables()[1];
+
+ if (mOriginalWidth < 0 || mOriginalHeight < 0) {
+ mOriginalWidth = getMeasuredWidth();
+ mOriginalHeight = getMeasuredHeight();
+ }
+
+ int xShift = (mOriginalWidth - d.getIntrinsicWidth()) / 2;
+ int yShift = (mOriginalHeight - d.getIntrinsicHeight()) / 2;
+ canvas.translate(xShift, yShift);
+
+ ArrayList<View> items = mFolder.getItemsInReadingOrder();
+ int firstItemIndex = Math.max(0, items.size() - NUM_ITEMS_IN_PREVIEW);
+ for (int i = firstItemIndex; i < items.size(); i++) {
+ v = (TextView) items.get(i);
+ d = v.getCompoundDrawables()[1];
+
+ canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
+ canvas.rotate(i == firstItemIndex ? ICON_ANGLE : -ICON_ANGLE);
+ canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
+
+ if (d != null) {
+ d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
+ d.draw(canvas);
+ }
+ }
+
+ canvas.restore();
+ }
+
+ public void onAdd(ShortcutInfo item) {
+ invalidate();
+ requestLayout();
+ }
+
+ public void onRemove(ShortcutInfo item) {
+ invalidate();
+ requestLayout();
+ }
}
diff --git a/src/com/android/launcher2/FolderInfo.java b/src/com/android/launcher2/FolderInfo.java
index 8732690..12ed27c 100644
--- a/src/com/android/launcher2/FolderInfo.java
+++ b/src/com/android/launcher2/FolderInfo.java
@@ -16,12 +16,15 @@
package com.android.launcher2;
+import java.util.ArrayList;
+
+import android.content.ContentValues;
/**
* Represents a folder containing shortcuts or apps.
*/
class FolderInfo extends ItemInfo {
-
+
/**
* Whether this folder has been opened
*/
@@ -31,4 +34,60 @@
* The folder name.
*/
CharSequence title;
+
+ /**
+ * The apps and shortcuts
+ */
+ ArrayList<ShortcutInfo> contents = new ArrayList<ShortcutInfo>();
+
+ ArrayList<FolderListener> listeners = new ArrayList<FolderListener>();
+
+ FolderInfo() {
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
+ }
+
+ /**
+ * Add an app or shortcut
+ *
+ * @param item
+ */
+ public void add(ShortcutInfo item) {
+ contents.add(item);
+ for (int i = 0; i < listeners.size(); i++) {
+ listeners.get(i).onAdd(item);
+ }
+ }
+
+ /**
+ * Remove an app or shortcut. Does not change the DB.
+ *
+ * @param item
+ */
+ public void remove(ShortcutInfo item) {
+ contents.remove(item);
+ for (int i = 0; i < listeners.size(); i++) {
+ listeners.get(i).onRemove(item);
+ }
+ }
+
+ @Override
+ void onAddToDatabase(ContentValues values) {
+ super.onAddToDatabase(values);
+ values.put(LauncherSettings.Favorites.TITLE, title.toString());
+ }
+
+ void addListener(FolderListener listener) {
+ listeners.add(listener);
+ }
+
+ void removeListener(FolderListener listener) {
+ if (listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
+ }
+
+ interface FolderListener {
+ public void onAdd(ShortcutInfo item);
+ public void onRemove(ShortcutInfo item);
+ }
}
diff --git a/src/com/android/launcher2/HolographicOutlineHelper.java b/src/com/android/launcher2/HolographicOutlineHelper.java
index 1efc123..80548fb 100644
--- a/src/com/android/launcher2/HolographicOutlineHelper.java
+++ b/src/com/android/launcher2/HolographicOutlineHelper.java
@@ -32,6 +32,7 @@
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 @@
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/HolographicPagedViewIcon.java b/src/com/android/launcher2/HolographicPagedViewIcon.java
index 5e18169..7123e2a 100644
--- a/src/com/android/launcher2/HolographicPagedViewIcon.java
+++ b/src/com/android/launcher2/HolographicPagedViewIcon.java
@@ -41,7 +41,6 @@
@Override
protected void onDraw(Canvas canvas) {
Bitmap overlay = mOriginalIcon.getHolographicOutline();
-
if (overlay != null) {
final int offset = getScrollX();
final int compoundPaddingLeft = getCompoundPaddingLeft();
diff --git a/src/com/android/launcher2/IconCache.java b/src/com/android/launcher2/IconCache.java
index 2e47adc..7e37afe 100644
--- a/src/com/android/launcher2/IconCache.java
+++ b/src/com/android/launcher2/IconCache.java
@@ -54,7 +54,7 @@
mContext = context;
mPackageManager = context.getPackageManager();
mBubble = new Utilities.BubbleText(context);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
mIconDpi = DisplayMetrics.DENSITY_HIGH;
} else {
mIconDpi = context.getResources().getDisplayMetrics().densityDpi;
@@ -68,11 +68,13 @@
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 @@
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/IconDropTarget.java b/src/com/android/launcher2/IconDropTarget.java
index fb5d0f0..4d018e6 100644
--- a/src/com/android/launcher2/IconDropTarget.java
+++ b/src/com/android/launcher2/IconDropTarget.java
@@ -126,7 +126,7 @@
@Override
public void getHitRect(Rect outRect) {
super.getHitRect(outRect);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
outRect.top -= mDragPadding[0];
outRect.right += mDragPadding[1];
outRect.bottom += mDragPadding[2];
diff --git a/src/com/android/launcher2/ItemInfo.java b/src/com/android/launcher2/ItemInfo.java
index dc45750..3bb3b07 100644
--- a/src/com/android/launcher2/ItemInfo.java
+++ b/src/com/android/launcher2/ItemInfo.java
@@ -38,7 +38,7 @@
/**
* One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
* {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
- * {@link LauncherSettings.Favorites#ITEM_TYPE_USER_FOLDER}, or
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or
* {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}.
*/
int itemType;
@@ -81,6 +81,11 @@
*/
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 df6ff36..9dfed69 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -17,10 +17,13 @@
package com.android.launcher2;
-import com.android.common.Search;
-import com.android.launcher.R;
-import com.android.launcher2.CustomizePagedView.CustomizationType;
-import com.android.launcher2.Workspace.ShrinkState;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -66,10 +69,8 @@
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
-import android.os.Parcelable;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.provider.LiveFolders;
import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.text.Selection;
@@ -88,6 +89,7 @@
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;
@@ -98,20 +100,12 @@
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TabHost;
-import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TabHost.TabContentFactory;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
+import com.android.common.Search;
+import com.android.launcher.R;
+import com.android.launcher2.Workspace.ShrinkState;
/**
* Default launcher application.
@@ -137,11 +131,9 @@
private static final int MENU_SETTINGS = MENU_NOTIFICATIONS + 1;
private static final int REQUEST_CREATE_SHORTCUT = 1;
- private static final int REQUEST_CREATE_LIVE_FOLDER = 4;
private static final int REQUEST_CREATE_APPWIDGET = 5;
private static final int REQUEST_PICK_APPLICATION = 6;
private static final int REQUEST_PICK_SHORTCUT = 7;
- private static final int REQUEST_PICK_LIVE_FOLDER = 8;
private static final int REQUEST_PICK_APPWIDGET = 9;
private static final int REQUEST_PICK_WALLPAPER = 10;
@@ -160,7 +152,7 @@
// Type: int
private static final String RUNTIME_STATE = "launcher.state";
// Type: long
- private static final String RUNTIME_STATE_USER_FOLDERS = "launcher.user_folder";
+ private static final String RUNTIME_STATE_FOLDERS = "launcher.folder";
// Type: int
private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen";
// Type: int
@@ -172,16 +164,10 @@
// Type: long
private static final String RUNTIME_STATE_PENDING_FOLDER_RENAME_ID = "launcher.rename_folder_id";
- // tags for the customization tabs
- private static final String WIDGETS_TAG = "widgets";
- private static final String APPLICATIONS_TAG = "applications";
- private static final String SHORTCUTS_TAG = "shortcuts";
- private static final String WALLPAPERS_TAG = "wallpapers";
-
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, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE,
CUSTOMIZE_SPRING_LOADED, ALL_APPS_SPRING_LOADED };
private State mState = State.WORKSPACE;
private AnimatorSet mStateAnimation;
@@ -214,9 +200,16 @@
private DeleteZone mDeleteZone;
private HandleView mHandleView;
private AllAppsView mAllAppsGrid;
- private TabHost mHomeCustomizationDrawer;
+ private AppsCustomizeTabHost mAppsCustomizeTabHost;
+ private AppsCustomizePagedView mAppsCustomizeContent;
+ private CustomizeTrayTabHost mHomeCustomizationDrawer;
private boolean mAutoAdvanceRunning = false;
+ private ViewGroup mButtonCluster;
+ private View mAllAppsButton;
+ private View mDivider;
+ private View mConfigureButton;
+
private AllAppsPagedView mAllAppsPagedView = null;
private CustomizePagedView mCustomizePagedView = null;
@@ -245,6 +238,7 @@
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,17 +268,19 @@
private static Drawable.ConstantState sVoiceSearchIcon;
private static Drawable.ConstantState sAppMarketIcon;
- private CustomizationType getCustomizeFilterForTabTag(String tag) {
- if (tag.equals(WIDGETS_TAG)) {
- return CustomizationType.WidgetCustomization;
- } else if (tag.equals(APPLICATIONS_TAG)) {
- return CustomizationType.ApplicationCustomization;
- } else if (tag.equals(WALLPAPERS_TAG)) {
- return CustomizePagedView.CustomizationType.WallpaperCustomization;
- } else if (tag.equals(SHORTCUTS_TAG)) {
- return CustomizePagedView.CustomizationType.ShortcutCustomization;
- }
- return CustomizationType.WidgetCustomization;
+ private DragLayer mDragLayer;
+
+ 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;
}
@Override
@@ -315,68 +311,11 @@
loadHotseats();
checkForLocaleChange();
setContentView(R.layout.launcher);
- mHomeCustomizationDrawer = (TabHost) findViewById(R.id.customization_drawer);
+ mHomeCustomizationDrawer = (CustomizeTrayTabHost) findViewById(R.id.customization_drawer);
if (mHomeCustomizationDrawer != null) {
- mHomeCustomizationDrawer.setup();
-
// share the same customization workspace across all the tabs
- mCustomizePagedView = (CustomizePagedView) mInflater.inflate(
- R.layout.customization_drawer, mHomeCustomizationDrawer, false);
- TabContentFactory contentFactory = new TabContentFactory() {
- public View createTabContent(String tag) {
- return mCustomizePagedView;
- }
- };
-
-
- TextView tabView;
- TabWidget tabWidget = (TabWidget)
- mHomeCustomizationDrawer.findViewById(com.android.internal.R.id.tabs);
-
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
- tabView.setText(getString(R.string.widgets_tab_label));
- mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(WIDGETS_TAG)
- .setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
- tabView.setText(getString(R.string.applications_tab_label));
- mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(APPLICATIONS_TAG)
- .setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
- tabView.setText(getString(R.string.wallpapers_tab_label));
- mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(WALLPAPERS_TAG)
- .setIndicator(tabView).setContent(contentFactory));
- tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
- tabView.setText(getString(R.string.shortcuts_tab_label));
- mHomeCustomizationDrawer.addTab(mHomeCustomizationDrawer.newTabSpec(SHORTCUTS_TAG)
- .setIndicator(tabView).setContent(contentFactory));
- mHomeCustomizationDrawer.setOnTabChangedListener(new OnTabChangeListener() {
- public void onTabChanged(String tabId) {
- final CustomizePagedView.CustomizationType newType =
- getCustomizeFilterForTabTag(tabId);
- if (newType != mCustomizePagedView.getCustomizationFilter()) {
- // animate the changing of the tab content by fading pages in and out
- final Resources res = getResources();
- final int duration = res.getInteger(R.integer.config_tabTransitionTime);
- final float alpha = mCustomizePagedView.getAlpha();
- ValueAnimator alphaAnim = ObjectAnimator.ofFloat(mCustomizePagedView,
- "alpha", alpha, 0.0f);
- alphaAnim.setDuration(duration);
- alphaAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mCustomizePagedView.setCustomizationFilter(newType);
-
- final float alpha = mCustomizePagedView.getAlpha();
- ValueAnimator alphaAnim = ObjectAnimator.ofFloat(
- mCustomizePagedView, "alpha", alpha, 1.0f);
- alphaAnim.setDuration(duration);
- alphaAnim.start();
- }
- });
- alphaAnim.start();
- }
- }
- });
+ mCustomizePagedView = (CustomizePagedView) findViewById(
+ R.id.customization_drawer_tab_contents);
}
setupViews();
@@ -391,6 +330,9 @@
if (mCustomizePagedView != null) {
mCustomizePagedView.update();
}
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.onPackagesUpdated();
+ }
if (PROFILE_STARTUP) {
android.os.Debug.stopMethodTracing();
@@ -408,9 +350,12 @@
registerReceiver(mCloseSystemDialogsReceiver, filter);
// If we have a saved version of these external icons, we load them up immediately
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
+ if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) {
+ updateIconsAffectedByPackageManagerChanges();
+ }
if (sGlobalSearchIcon != null) {
- updateGlobalSearchIcon(sGlobalSearchIcon);
+ updateGlobalSearchIcon(sGlobalSearchIcon);
}
if (sVoiceSearchIcon != null) {
updateVoiceSearchIcon(sVoiceSearchIcon);
@@ -421,21 +366,6 @@
}
}
- @Override
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
- super.dispatchPopulateAccessibilityEvent(event);
-
- // we want to take over text population so it is context dependent
- event.getText().clear();
- if (mState == State.ALL_APPS) {
- event.getText().add(getString(R.string.all_apps_button_label));
- } else if (mState == State.WORKSPACE) {
- event.getText().add(getString(R.string.all_apps_home_button_label));
- }
-
- return true;
- }
-
private void checkForLocaleChange() {
if (sLocaleConfiguration == null) {
new AsyncTask<Void, Void, LocaleConfiguration>() {
@@ -695,8 +625,32 @@
}
}
+ 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_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 +660,18 @@
// 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 +694,9 @@
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();
@@ -778,7 +720,12 @@
public Object onRetainNonConfigurationInstance() {
// Flag the loader to stop early before switching
mModel.stopLoader();
- mAllAppsGrid.surrender();
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.surrender();
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.surrender();
+ }
return Boolean.TRUE;
}
@@ -811,8 +758,10 @@
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- boolean handled = super.onKeyDown(keyCode, event);
- if (!handled && acceptFilter() && keyCode != KeyEvent.KEYCODE_ENTER) {
+ final int uniChar = event.getUnicodeChar();
+ final boolean handled = super.onKeyDown(keyCode, event);
+ final boolean isKeyNotWhitespace = uniChar > 0 && !Character.isWhitespace(uniChar);
+ if (!handled && acceptFilter() && isKeyNotWhitespace) {
boolean gotKey = TextKeyListener.getInstance().onKeyDown(mWorkspace, mDefaultKeySsb,
keyCode, event);
if (gotKey && mDefaultKeySsb != null && mDefaultKeySsb.length() > 0) {
@@ -872,7 +821,7 @@
State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));
- if (state == State.ALL_APPS) {
+ if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) {
showAllApps(false);
} else if (state == State.CUSTOMIZE) {
showCustomizationDrawer(false);
@@ -917,13 +866,28 @@
String curTab = savedState.getString("customize_currentTab");
if (curTab != null) {
// We set this directly so that there is no delay before the tab is set
- mCustomizePagedView.setCustomizationFilter(getCustomizeFilterForTabTag(curTab));
+ mCustomizePagedView.setCustomizationFilter(
+ mHomeCustomizationDrawer.getCustomizeFilterForTabTag(curTab));
mHomeCustomizationDrawer.setCurrentTabByTag(curTab);
}
// Note: currently we do not restore the page for the customization tray because unlike
// AllApps, the page content can change drastically
}
+
+ // Restore the AppsCustomize tab
+ if (mAppsCustomizeTabHost != null) {
+ String curTab = savedState.getString("apps_customize_currentTab");
+ if (curTab != null) {
+ // We set this directly so that there is no delay before the tab is set
+ mAppsCustomizeContent.setContentType(
+ mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));
+ mAppsCustomizeTabHost.setCurrentTabByTag(curTab);
+ }
+
+ // Note: currently we do not restore the page for the AppsCustomize pane because the
+ // change in layout can drastically affect the saved page index
+ }
}
/**
@@ -934,19 +898,20 @@
DragLayer dragLayer = (DragLayer) findViewById(R.id.drag_layer);
dragLayer.setDragController(dragController);
+ dragLayer.setLauncher(this);
+ mDragLayer = dragLayer;
- mAllAppsGrid = (AllAppsView)dragLayer.findViewById(R.id.all_apps_view);
- mAllAppsGrid.setLauncher(this);
- mAllAppsGrid.setDragController(dragController);
- ((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
- // Manage focusability manually since this thing is always visible (in non-xlarge)
- ((View) mAllAppsGrid).setFocusable(false);
-
- if (LauncherApplication.isScreenXLarge()) {
- // They need to be INVISIBLE initially so that they will be measured in the layout.
- // Otherwise the animations are messed up when we show them for the first time.
- ((View) mAllAppsGrid).setVisibility(View.INVISIBLE);
- mHomeCustomizationDrawer.setVisibility(View.INVISIBLE);
+ if (LauncherApplication.isScreenLarge()) {
+ mAllAppsGrid = (AllAppsView) dragLayer.findViewById(R.id.all_apps_view);
+ mAllAppsGrid.setup(this, dragController);
+ // We don't want a hole punched in our window.
+ ((View) mAllAppsGrid).setWillNotDraw(false);
+ } else {
+ mAppsCustomizeTabHost = (AppsCustomizeTabHost)
+ findViewById(R.id.apps_customize_pane);
+ mAppsCustomizeContent = (AppsCustomizePagedView)
+ mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
+ mAppsCustomizeContent.setup(this, dragController);
}
mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
@@ -962,7 +927,6 @@
// we don't use handle view in xlarge mode
mHandleView = (HandleView)handleView;
mHandleView.setLauncher(this);
- mHandleView.setOnClickListener(this);
mHandleView.setOnLongClickListener(this);
}
@@ -977,8 +941,11 @@
hotseatRight.setContentDescription(mHotseatLabels[1]);
hotseatRight.setImageDrawable(mHotseatIcons[1]);
+ View.OnKeyListener listener = new IndicatorKeyEventListener();
mPreviousView = (ImageView) dragLayer.findViewById(R.id.previous_screen);
+ mPreviousView.setOnKeyListener(listener);
mNextView = (ImageView) dragLayer.findViewById(R.id.next_screen);
+ mNextView.setOnKeyListener(listener);
Drawable previous = mPreviousView.getDrawable();
Drawable next = mNextView.getDrawable();
@@ -999,10 +966,10 @@
deleteZone.setDragController(dragController);
final View allAppsButton = findViewById(R.id.all_apps_button);
- final View divider = findViewById(R.id.divider);
+ final View divider = findViewById(R.id.all_apps_divider);
final View configureButton = findViewById(R.id.configure_button);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
deleteZone.setOverlappingViews(new View[] { allAppsButton, divider, configureButton });
} else {
deleteZone.setOverlappingView(findViewById(R.id.all_apps_button_cluster));
@@ -1024,10 +991,17 @@
allAppsInfoTarget.setLauncher(this);
dragController.addDragListener(allAppsInfoTarget);
allAppsInfoTarget.setDragAndDropEnabled(false);
- View marketButton = findViewById(R.id.market_button);
- if (marketButton != null) {
+ }
+ View marketButton = findViewById(R.id.market_button);
+ if (marketButton != null) {
+ if (allAppsInfoTarget != null) {
allAppsInfoTarget.setOverlappingView(marketButton);
}
+ marketButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ onClickAppMarketButton(v);
+ }
+ });
}
dragController.setDragScoller(workspace);
@@ -1043,18 +1017,60 @@
if (allAppsDeleteZone != null) {
dragController.addDropTarget(allAppsDeleteZone);
}
+ mButtonCluster = (ViewGroup) findViewById(R.id.all_apps_button_cluster);
+ View.OnKeyListener listener = null;
+ if (LauncherApplication.isScreenLarge()) {
+ // For tablets, AllApps lives in the button bar at the top
+ listener = new ButtonBarKeyEventListener();
+ } else {
+ // For phones, AppsCustomize lives in the "dock" at the bottom
+ listener = new DockKeyEventListener();
+ }
+ int buttonCount = mButtonCluster.getChildCount();
+ for (int i = 0; i < buttonCount; ++i) {
+ mButtonCluster.getChildAt(i).setOnKeyListener(listener);
+ }
+
+ mAllAppsButton = findViewById(R.id.all_apps_button);
+ mDivider = findViewById(R.id.all_apps_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"})
public void previousScreen(View v) {
- if (mState != State.ALL_APPS) {
+ if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
mWorkspace.scrollLeft();
}
}
@SuppressWarnings({"UnusedDeclaration"})
public void nextScreen(View v) {
- if (mState != State.ALL_APPS) {
+ if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
mWorkspace.scrollRight();
}
}
@@ -1114,7 +1130,7 @@
* @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 +1140,7 @@
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 +1197,7 @@
* @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 +1227,16 @@
}
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;
}
@@ -1249,6 +1273,14 @@
if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mUserPresent = false;
updateRunning();
+
+ // Reset AllApps to it's initial state
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.reset();
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.reset();
+ }
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
mUserPresent = true;
updateRunning();
@@ -1402,16 +1434,11 @@
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
- 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();
+ // In all these cases, only animate if we're already on home
+ mWorkspace.unshrink(alreadyOnHome);
+ mWorkspace.exitWidgetResizeMode();
+ if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive()) {
+ mWorkspace.moveToDefaultScreen(true);
}
showWorkspace(alreadyOnHome);
@@ -1421,6 +1448,14 @@
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
+
+ // Reset AllApps to it's initial state
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.reset();
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.reset();
+ }
}
}
@@ -1442,7 +1477,7 @@
final FolderInfo info = folders.get(i).getInfo();
ids[i] = info.id;
}
- outState.putLongArray(RUNTIME_STATE_USER_FOLDERS, ids);
+ outState.putLongArray(RUNTIME_STATE_FOLDERS, ids);
} else {
super.onSaveInstanceState(outState);
}
@@ -1469,7 +1504,6 @@
outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage());
}
}
-
// Save the current customization drawer tab
if (mHomeCustomizationDrawer != null) {
String currentTabTag = mHomeCustomizationDrawer.getCurrentTabTag();
@@ -1477,6 +1511,13 @@
outState.putString("customize_currentTab", currentTabTag);
}
}
+ // Save the current AppsCustomize tab
+ if (mAppsCustomizeTabHost != null) {
+ String currentTabTag = mAppsCustomizeTabHost.getCurrentTabTag();
+ if (currentTabTag != null) {
+ outState.putString("apps_customize_currentTab", currentTabTag);
+ }
+ }
}
@Override
@@ -1518,6 +1559,10 @@
ValueAnimator.clearAllAnimations();
}
+ public DragController getDragController() {
+ return mDragController;
+ }
+
@Override
public void startActivityForResult(Intent intent, int requestCode) {
if (requestCode >= 0) mWaitingForResult = true;
@@ -1585,22 +1630,28 @@
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- // If all apps is animating, don't show the menu, because we don't know
- // which one to show.
- if (mAllAppsGrid.isAnimating()) {
- return false;
+ if (mAllAppsGrid != null) {
+ // If all apps is animating, don't show the menu, because we don't know
+ // which one to show.
+ if (mAllAppsGrid.isAnimating()) {
+ return false;
+ }
+
+ // Only show the add and wallpaper options when we're not in all apps.
+ boolean visible = !mAllAppsGrid.isVisible();
+ menu.setGroupVisible(MENU_GROUP_ADD, visible);
+ menu.setGroupVisible(MENU_GROUP_WALLPAPER, visible);
+
+ // Disable add if the workspace is full.
+ if (visible) {
+ CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
+ menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell());
+ }
}
- // Only show the add and wallpaper options when we're not in all apps.
- boolean visible = !mAllAppsGrid.isVisible();
- menu.setGroupVisible(MENU_GROUP_ADD, visible);
- menu.setGroupVisible(MENU_GROUP_WALLPAPER, visible);
-
- // Disable add if the workspace is full.
- if (visible) {
- CellLayout layout = (CellLayout) mWorkspace.getChildAt(mWorkspace.getCurrentPage());
- menu.setGroupEnabled(MENU_GROUP_ADD, layout.existsEmptyCell());
- }
+ // TODO-APPS_CUSTOMIZE: Remove this for the phone UI at some point, along with all the menu
+ // related code?
+ if (mAppsCustomizeContent != null && mAppsCustomizeContent.isAnimating()) return false;
return true;
}
@@ -1643,8 +1694,14 @@
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()) {
+ if (LauncherApplication.isScreenLarge()) {
// Animate the widget chooser up from the bottom of the screen
if (mState != State.CUSTOMIZE) {
showCustomizationDrawer(true);
@@ -1761,38 +1818,15 @@
startActivityForResult(intent, REQUEST_PICK_WALLPAPER);
}
- void addLiveFolderFromDrop(ComponentName componentName, int screen, int[] position) {
- resetAddInfo();
- mAddScreen = screen;
- mAddDropPosition = position;
-
- Intent createFolderIntent = new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER);
- createFolderIntent.setComponent(componentName);
-
- addLiveFolder(createFolderIntent);
- }
-
- void addLiveFolder(Intent intent) { // YYY add screen intersect etc. parameters here
- // Handle case where user selected "Folder"
- String folderName = getResources().getString(R.string.group_folder);
- String shortcutName = intent.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
-
- if (folderName != null && folderName.equals(shortcutName)) {
- addFolder(mAddScreen, mAddIntersectCellX, mAddIntersectCellY);
- } else {
- startActivityForResultSafely(intent, REQUEST_CREATE_LIVE_FOLDER);
- }
- }
-
- void addFolder(int screen, int intersectCellX, int intersectCellY) {
- UserFolderInfo folderInfo = new UserFolderInfo();
+ FolderIcon addFolder(int screen, int intersectCellX, int intersectCellY) {
+ FolderInfo folderInfo = new FolderInfo();
folderInfo.title = getText(R.string.folder_name);
final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
final int[] cellXY = mTmpAddItemCellCoordinates;
if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
showOutOfSpaceMessage();
- return;
+ return null;
}
// Update the model
@@ -1806,73 +1840,13 @@
(ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()),
folderInfo, mIconCache);
mWorkspace.addInScreen(newFolder, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
+ return newFolder;
}
void removeFolder(FolderInfo folder) {
sFolders.remove(folder.id);
}
- private void completeAddLiveFolder(
- Intent data, int screen, int intersectCellX, int intersectCellY) {
- final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen);
- final int[] cellXY = mTmpAddItemCellCoordinates;
- if (!layout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectCellX, intersectCellY)) {
- showOutOfSpaceMessage();
- return;
- }
-
- final LiveFolderInfo info = addLiveFolder(this, data, screen, cellXY[0], cellXY[1], false);
-
- if (!mRestoring) {
- final View view = LiveFolderIcon.fromXml(R.layout.live_folder_icon, this,
- (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
- mWorkspace.addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked());
- }
- }
-
- static LiveFolderInfo addLiveFolder(Context context, Intent data,
- int screen, int cellX, int cellY, boolean notify) {
-
- Intent baseIntent = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT);
- String name = data.getStringExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME);
-
- Drawable icon = null;
- Intent.ShortcutIconResource iconResource = null;
-
- Parcelable extra = data.getParcelableExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON);
- if (extra != null && extra instanceof Intent.ShortcutIconResource) {
- try {
- iconResource = (Intent.ShortcutIconResource) extra;
- final PackageManager packageManager = context.getPackageManager();
- Resources resources = packageManager.getResourcesForApplication(
- iconResource.packageName);
- final int id = resources.getIdentifier(iconResource.resourceName, null, null);
- icon = resources.getDrawable(id);
- } catch (Exception e) {
- Log.w(TAG, "Could not load live folder icon: " + extra);
- }
- }
-
- if (icon == null) {
- icon = context.getResources().getDrawable(R.drawable.ic_launcher_folder);
- }
-
- final LiveFolderInfo info = new LiveFolderInfo();
- info.icon = Utilities.createIconBitmap(icon, context);
- info.title = name;
- info.iconResource = iconResource;
- info.uri = data.getData();
- info.baseIntent = baseIntent;
- info.displayMode = data.getIntExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
- LiveFolders.DISPLAY_MODE_GRID);
-
- LauncherModel.addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screen, cellX, cellY, notify);
- sFolders.put(info.id, info);
-
- return info;
- }
-
private void showNotifications() {
final StatusBarManager statusBar = (StatusBarManager) getSystemService(STATUS_BAR_SERVICE);
if (statusBar != null) {
@@ -1934,36 +1908,41 @@
@Override
public void onBackPressed() {
- if (mState == State.ALL_APPS || mState == State.CUSTOMIZE) {
+ if (mState == State.ALL_APPS || mState == State.CUSTOMIZE || mState == State.APPS_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();
}
}
- private void closeFolder() {
+ public void closeFolder() {
Folder folder = mWorkspace.getOpenFolder();
if (folder != null) {
closeFolder(folder);
+ mDragLayer.setCurrentFolder(null);
}
}
void closeFolder(Folder folder) {
folder.getInfo().opened = false;
+
ViewGroup parent = (ViewGroup) folder.getParent().getParent();
if (parent != null) {
CellLayout cl = (CellLayout) parent;
- cl.removeViewWithoutMarkingCells(folder);
- if (folder instanceof DropTarget) {
- // Live folders aren't DropTargets.
- mDragController.removeDropTarget((DropTarget)folder);
- }
+ FolderIcon fi = (FolderIcon) cl.getChildAt(folder.mInfo.cellX, folder.mInfo.cellY);
+ shrinkAndFadeInFolderIcon(fi);
+ mDragController.removeDropTarget((DropTarget)folder);
}
+
+ folder.animateClosed();
folder.onClose();
}
@@ -1971,7 +1950,9 @@
* Re-listen when widgets are reset.
*/
private void onAppWidgetReset() {
- mAppWidgetHost.startListening();
+ if (mAppWidgetHost != null) {
+ mAppWidgetHost.startListening();
+ }
}
/**
@@ -1999,9 +1980,17 @@
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);
+ if (v instanceof FolderIcon) {
+ FolderIcon fi = (FolderIcon) v;
+ handleFolderClick(fi);
+ }
} else if (v == mHandleView) {
if (mState == State.ALL_APPS) {
showWorkspace(true);
@@ -2092,10 +2081,11 @@
}
}
- 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 +2096,7 @@
"or use the exported attribute for this activity. "
+ "tag="+ tag + " intent=" + intent, e);
}
+ return false;
}
void startActivityForResultSafely(Intent intent, int requestCode) {
@@ -2121,15 +2112,16 @@
}
}
- private void handleFolderClick(FolderInfo folderInfo) {
- if (!folderInfo.opened) {
+ private void handleFolderClick(FolderIcon folderIcon) {
+ final FolderInfo info = folderIcon.mInfo;
+ if (!info.opened) {
// Close any open folder
closeFolder();
// Open the requested folder
- openFolder(folderInfo);
+ openFolder(folderIcon);
} else {
// Find the open folder...
- Folder openFolder = mWorkspace.getFolderForTag(folderInfo);
+ Folder openFolder = mWorkspace.getFolderForTag(info);
int folderScreen;
if (openFolder != null) {
folderScreen = mWorkspace.getPageForView(openFolder);
@@ -2139,12 +2131,32 @@
// Close any folder open on the current screen
closeFolder();
// Pull the folder onto this screen
- openFolder(folderInfo);
+ openFolder(folderIcon);
}
}
}
}
+ private void growAndFadeOutFolderIcon(FolderIcon fi) {
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
+ PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.5f);
+ PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.5f);
+
+ ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY);
+ oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));
+ oa.start();
+ }
+
+ private void shrinkAndFadeInFolderIcon(FolderIcon fi) {
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
+ PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
+ PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
+
+ ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY);
+ oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));
+ oa.start();
+ }
+
/**
* Opens the user folder described by the specified tag. The opening of the folder
* is animated relative to the specified View. If the View is null, no animation
@@ -2152,46 +2164,41 @@
*
* @param folderInfo The FolderInfo describing the folder to open.
*/
- public void openFolder(FolderInfo folderInfo) {
- Folder openFolder;
+ public void openFolder(FolderIcon folderIcon) {
+ Folder folder = folderIcon.mFolder;
+ FolderInfo info = folder.mInfo;
- if (folderInfo instanceof UserFolderInfo) {
- openFolder = UserFolder.fromXml(this);
- } else if (folderInfo instanceof LiveFolderInfo) {
- openFolder = com.android.launcher2.LiveFolder.fromXml(this, folderInfo);
- } else {
- return;
- }
+ growAndFadeOutFolderIcon(folderIcon);
+ info.opened = true;
- openFolder.setDragController(mDragController);
- openFolder.setLauncher(this);
-
- openFolder.bind(folderInfo);
- folderInfo.opened = true;
-
- mWorkspace.addInFullScreen(openFolder, folderInfo.screen);
-
- openFolder.onOpen();
+ mWorkspace.addInFullScreen(folder, info.screen);
+ mDragLayer.setCurrentFolder(folder);
+ folder.animateOpen();
+ folder.onOpen();
}
public boolean onLongClick(View v) {
+ if (mState != State.WORKSPACE) {
+ return false;
+ }
+
switch (v.getId()) {
case R.id.previous_screen:
- if (mState != State.ALL_APPS) {
+ if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
}
return true;
case R.id.next_screen:
- if (mState != State.ALL_APPS) {
+ if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
}
return true;
case R.id.all_apps_button:
- if (mState != State.ALL_APPS) {
+ if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
@@ -2207,7 +2214,6 @@
v = (View) v.getParent().getParent();
}
-
resetAddInfo();
CellLayout.CellInfo longClickCellInfo = (CellLayout.CellInfo) v.getTag();
// This happens when long clicking an item with the dpad/trackball
@@ -2223,10 +2229,10 @@
mWorkspace.setAllowLongPress(false);
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
addItems();
} else {
- showAddDialog(longClickCellInfo.cellX, longClickCellInfo.cellY);
+ startWallpaper();
}
} else {
if (!(itemUnderLongClick instanceof Folder)) {
@@ -2253,11 +2259,12 @@
for (int i = 0; i < count; i++) {
((ImageView) group.getChildAt(i)).setImageDrawable(null);
}
- ArrayList<Bitmap> bitmaps = (ArrayList<Bitmap>) v.getTag(R.id.icon);
+ ArrayList<Bitmap> bitmaps =
+ (ArrayList<Bitmap>) v.getTag(R.id.all_apps_button_cluster);
for (Bitmap bitmap : bitmaps) bitmap.recycle();
v.setTag(R.id.workspace, null);
- v.setTag(R.id.icon, null);
+ v.setTag(R.id.all_apps_button_cluster, null);
window.setOnDismissListener(null);
}
});
@@ -2349,7 +2356,7 @@
anchor.setTag(p);
anchor.setTag(R.id.workspace, preview);
- anchor.setTag(R.id.icon, bitmaps);
+ anchor.setTag(R.id.all_apps_button_cluster, bitmaps);
}
class PreviewTouchHandler implements View.OnClickListener, Runnable, View.OnFocusChangeListener {
@@ -2379,6 +2386,10 @@
return mWorkspace;
}
+ TabHost getCustomizationDrawer() {
+ return mHomeCustomizationDrawer;
+ }
+
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
@@ -2504,7 +2515,9 @@
final FolderIcon folderIcon = (FolderIcon)
mWorkspace.getViewForTag(mFolderInfo);
if (folderIcon != null) {
- folderIcon.setText(name);
+ // TODO: At some point we'll probably want some version of setting
+ // the text for a folder icon.
+ //folderIcon.setText(name);
getWorkspace().requestLayout();
} else {
lockAllApps();
@@ -2525,29 +2538,25 @@
// Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
public boolean isAllAppsVisible() {
- return mState == State.ALL_APPS;
+ return (mState == State.ALL_APPS) || (mState == State.APPS_CUSTOMIZE);
}
// AllAppsView.Watcher
public void zoomed(float zoom) {
// In XLarge view, we zoom down the workspace below all apps so it's still visible
- if (zoom == 1.0f && !LauncherApplication.isScreenXLarge()) {
+ if (zoom == 1.0f && !LauncherApplication.isScreenLarge()) {
mWorkspace.setVisibility(View.GONE);
}
}
- private void showToolbarButton(View button) {
+ private void showAndEnableToolbarButton(View button) {
button.setVisibility(View.VISIBLE);
- button.setFocusable(true);
- button.setClickable(true);
}
private void hideToolbarButton(View button) {
- button.setAlpha(0.0f);
// We can't set it to GONE, otherwise the RelativeLayout gets screwed up
button.setVisibility(View.INVISIBLE);
- button.setFocusable(false);
- button.setClickable(false);
+ button.setAlpha(0.0f);
}
/**
@@ -2567,12 +2576,17 @@
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);
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -2582,7 +2596,7 @@
seq.play(anim);
} else {
if (showing) {
- showToolbarButton(view);
+ showAndEnableToolbarButton(view);
view.setAlpha(1f);
} else {
hideToolbarButton(view);
@@ -2599,26 +2613,24 @@
* @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.setDragAndDropEnabled(true);
- mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_workspace));
+ if (LauncherApplication.isScreenLarge()) {
+ mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_workspace));
+ }
break;
case ALL_APPS:
- hideOrShowToolbarButton(false, buttonCluster, hideSeq);
+ case APPS_CUSTOMIZE:
+ hideOrShowToolbarButton(false, mButtonCluster, hideSeq);
mDeleteZone.setDragAndDropEnabled(false);
- mDeleteZone.setText(getResources().getString(R.string.delete_zone_label_all_apps));
+ if (LauncherApplication.isScreenLarge()) {
+ 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;
}
@@ -2637,7 +2649,7 @@
// Set pivotY so that at the starting zoom factor, the view is partially
// visible. Modifying initialHeightFactor changes how much of the view is
// initially showing, and hence the perceived angle from which the view enters.
- if (state == State.ALL_APPS) {
+ if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) {
final float initialHeightFactor = 0.175f;
view.setPivotY((1 - initialHeightFactor) * height);
} else {
@@ -2652,35 +2664,54 @@
* of the screen.
* @param toState The state to zoom out to. Must be ALL_APPS or CUSTOMIZE.
*/
- private void cameraZoomOut(State toState, boolean animated) {
+ private void cameraZoomOut(State toState, boolean animated, boolean springLoaded) {
final Resources res = getResources();
- final boolean toAllApps = (toState == State.ALL_APPS);
+ final boolean toAllApps = (toState == State.ALL_APPS)
+ || (toState == State.APPS_CUSTOMIZE);
- final int duration = toAllApps ?
- res.getInteger(R.integer.config_allAppsZoomInTime) :
- res.getInteger(R.integer.config_customizeZoomInTime);
+ final int duration = (toAllApps ?
+ res.getInteger(R.integer.config_appsCustomizeZoomInTime) :
+ res.getInteger(R.integer.config_customizeZoomInTime));
+ final int fadeDuration = (toAllApps ?
+ res.getInteger(R.integer.config_appsCustomizeFadeInTime) :
+ res.getInteger(R.integer.config_customizeFadeInTime));
final float scale = toAllApps ?
- (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor) :
+ (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) :
(float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
- final View toView = toAllApps ? (View) mAllAppsGrid : mHomeCustomizationDrawer;
+ View tmpView;
+ if (toAllApps) {
+ tmpView = (LauncherApplication.isScreenLarge())
+ ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
+ } else {
+ tmpView = mHomeCustomizationDrawer;
+ }
+ final View toView = tmpView;
setPivotsForZoom(toView, toState, scale);
if (toAllApps) {
- mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
+ if (!springLoaded) {
+ mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
+
+ if (LauncherApplication.isScreenLarge()) {
+ // Everytime we launch into AllApps, we reset the successful drop flag which
+ // controls when it should hide/show the mini workspaces
+ mAllAppsPagedView.resetSuccessfulDropFlag();
+ }
+ } else {
+ mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
+ }
} else {
mWorkspace.shrink(ShrinkState.TOP, animated);
}
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) {
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ scaleAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
((View) toView.getParent()).fastInvalidate();
toView.setFastScaleX(a * scale + b * 1f);
toView.setFastScaleY(a * scale + b * 1f);
@@ -2688,13 +2719,12 @@
});
if (toAllApps) {
- toView.setAlpha(0f);
- ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
+ toView.setVisibility(View.VISIBLE);
+ 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) {
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ alphaAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
// don't need to invalidate because we do so above
toView.setFastAlpha(a * 0f + b * 1f);
}
@@ -2702,9 +2732,8 @@
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
@@ -2713,8 +2742,9 @@
toView.setTranslationX(0.0f);
toView.setTranslationY(0.0f);
toView.setVisibility(View.VISIBLE);
+ toView.bringToFront();
if (!toAllApps) {
- toView.setAlpha(1.0f);
+ toView.setFastAlpha(1.0f);
}
}
@Override
@@ -2722,9 +2752,11 @@
// 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 +2782,11 @@
toView.setScaleX(1.0f);
toView.setScaleY(1.0f);
toView.setVisibility(View.VISIBLE);
+ toView.bringToFront();
+ if (toView instanceof LauncherTransitionable) {
+ ((LauncherTransitionable) toView).onLauncherTransitionStart(null);
+ ((LauncherTransitionable) toView).onLauncherTransitionEnd(null);
+ }
hideAndShowToolbarButtons(toState, null, null);
}
}
@@ -2760,33 +2797,38 @@
* @param fromState The current state (must be ALL_APPS or CUSTOMIZE).
* @param animated If true, the transition will be animated.
*/
- private void cameraZoomIn(State fromState, boolean animated) {
- cameraZoomIn(fromState, animated, false);
- }
-
private void cameraZoomIn(State fromState, boolean animated, boolean springLoaded) {
Resources res = getResources();
- final boolean fromAllApps = (fromState == State.ALL_APPS);
+ final boolean fromAllApps = (fromState == State.ALL_APPS)
+ || (fromState == State.APPS_CUSTOMIZE);
int duration = fromAllApps ?
- res.getInteger(R.integer.config_allAppsZoomOutTime) :
+ res.getInteger(R.integer.config_appsCustomizeZoomOutTime) :
res.getInteger(R.integer.config_customizeZoomOutTime);
final float scaleFactor = fromAllApps ?
- (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor) :
+ (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) :
(float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
- final View fromView = fromAllApps ? (View) mAllAppsGrid : mHomeCustomizationDrawer;
+ View tmpView;
+ if (fromAllApps) {
+ tmpView = (LauncherApplication.isScreenLarge())
+ ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
+ } else {
+ tmpView = mHomeCustomizationDrawer;
+ }
+ final View fromView = tmpView;
- mCustomizePagedView.endChoiceMode();
- mAllAppsPagedView.endChoiceMode();
+ if (LauncherApplication.isScreenLarge()) {
+ mCustomizePagedView.endChoiceMode();
+ mAllAppsPagedView.endChoiceMode();
+ }
setPivotsForZoom(fromView, fromState, scaleFactor);
if (!springLoaded) {
mWorkspace.unshrink(animated);
}
-
if (animated) {
if (mStateAnimation != null) mStateAnimation.cancel();
mStateAnimation = new AnimatorSet();
@@ -2796,33 +2838,32 @@
ValueAnimator scaleAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
scaleAnim.setInterpolator(new Workspace.ZoomInInterpolator());
- scaleAnim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ scaleAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
((View)fromView.getParent()).fastInvalidate();
fromView.setFastScaleX(a * oldScaleX + b * scaleFactor);
fromView.setFastScaleY(a * oldScaleY + b * scaleFactor);
}
});
- ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f);
- alphaAnim.setDuration(res.getInteger(R.integer.config_allAppsFadeOutTime));
+ final ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f);
+ alphaAnim.setDuration(res.getInteger(R.integer.config_appsCustomizeFadeOutTime));
alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f));
- alphaAnim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ alphaAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
// don't need to invalidate because we do so above
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,121 +2882,16 @@
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) {
- return;
- }
-
- if (LauncherApplication.isScreenXLarge()) {
- if (mState == State.CUSTOMIZE) {
- cameraPan(State.CUSTOMIZE, State.ALL_APPS, animated);
- } else {
- cameraZoomOut(State.ALL_APPS, animated);
- }
- } else {
- mAllAppsGrid.zoom(1.0f, animated);
- }
-
- ((View) mAllAppsGrid).setFocusable(true);
- ((View) mAllAppsGrid).requestFocus();
-
- // TODO: fade these two too
- mDeleteZone.setVisibility(View.GONE);
-
- // Change the state *after* we've called all the transition code
- mState = State.ALL_APPS;
-
- // Pause the auto-advance of widgets until we are out of AllApps
- mUserPresent = false;
- updateRunning();
-
- // send an accessibility event to announce the context change
- getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- }
-
void showWorkspace(boolean animated) {
showWorkspace(animated, null);
}
@@ -2968,7 +2904,7 @@
} else {
mWorkspace.unshrink(animated);
}
- if (mState == State.ALL_APPS) {
+ if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
closeAllApps(animated);
} else if (mState == State.CUSTOMIZE) {
hideCustomizationDrawer(animated);
@@ -2987,12 +2923,16 @@
void enterSpringLoadedDragMode(CellLayout layout) {
mWorkspace.enterSpringLoadedDragMode(layout);
- if (mState == State.ALL_APPS) {
- cameraZoomIn(State.ALL_APPS, true, true);
+ if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
mState = State.ALL_APPS_SPRING_LOADED;
+ if (LauncherApplication.isScreenLarge()) {
+ cameraZoomIn(State.ALL_APPS, true, true);
+ } else {
+ cameraZoomIn(State.APPS_CUSTOMIZE, true, true);
+ }
} else if (mState == State.CUSTOMIZE) {
- cameraZoomIn(State.CUSTOMIZE, true, true);
mState = State.CUSTOMIZE_SPRING_LOADED;
+ cameraZoomIn(State.CUSTOMIZE, true, true);
}/* else {
// we're already in spring loaded mode; don't do anything
}*/
@@ -3001,17 +2941,50 @@
void exitSpringLoadedDragMode() {
if (mState == State.ALL_APPS_SPRING_LOADED) {
mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_VISIBLE);
- cameraZoomOut(State.ALL_APPS, true);
- mState = State.ALL_APPS;
+ if (LauncherApplication.isScreenLarge()) {
+ cameraZoomOut(State.ALL_APPS, true, true);
+ mState = State.ALL_APPS;
+ } else {
+ cameraZoomOut(State.APPS_CUSTOMIZE, true, true);
+ mState = State.APPS_CUSTOMIZE;
+ }
} else if (mState == State.CUSTOMIZE_SPRING_LOADED) {
mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.TOP);
- cameraZoomOut(State.CUSTOMIZE, true);
+ cameraZoomOut(State.CUSTOMIZE, true, true);
mState = State.CUSTOMIZE;
}/* else {
// we're not in spring loaded mode; don't do anything
}*/
}
+ void showAllApps(boolean animated) {
+ if (mState != State.WORKSPACE) return;
+ if (LauncherApplication.isScreenLarge()) {
+ cameraZoomOut(State.ALL_APPS, animated, false);
+ ((View) mAllAppsGrid).requestFocus();
+
+ // TODO: fade these two too
+ mDeleteZone.setVisibility(View.GONE);
+
+ // Change the state *after* we've called all the transition code
+ mState = State.ALL_APPS;
+ } else {
+ View appsCustomizePane = findViewById(R.id.apps_customize_pane);
+ cameraZoomOut(State.APPS_CUSTOMIZE, animated, false);
+ appsCustomizePane.requestFocus();
+
+ // Change the state *after* we've called all the transition code
+ mState = State.APPS_CUSTOMIZE;
+ }
+
+ // Pause the auto-advance of widgets until we are out of AllApps
+ mUserPresent = false;
+ updateRunning();
+
+ // Send an accessibility event to announce the context change
+ getWindow().getDecorView().sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ }
+
/**
* Things to test when changing this code.
* - Home from workspace
@@ -3052,15 +3025,22 @@
* - From another workspace
*/
void closeAllApps(boolean animated) {
- if (mState == State.ALL_APPS || mState == State.ALL_APPS_SPRING_LOADED) {
- mWorkspace.setVisibility(View.VISIBLE);
- if (LauncherApplication.isScreenXLarge()) {
- cameraZoomIn(State.ALL_APPS, animated);
- } else {
- mAllAppsGrid.zoom(0.0f, animated);
+ if (LauncherApplication.isScreenLarge()) {
+ if (mState == State.ALL_APPS || mState == State.ALL_APPS_SPRING_LOADED) {
+ mWorkspace.setVisibility(View.VISIBLE);
+ cameraZoomIn(State.ALL_APPS, animated, false);
+
+ // Set focus to the AllApps button
+ findViewById(R.id.all_apps_button).requestFocus();
}
- ((View)mAllAppsGrid).setFocusable(false);
- mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
+ } else {
+ if (mState == State.APPS_CUSTOMIZE || mState == State.ALL_APPS_SPRING_LOADED) {
+ mWorkspace.setVisibility(View.VISIBLE);
+ cameraZoomIn(State.APPS_CUSTOMIZE, animated, false);
+
+ // Set focus to the AllApps button
+ findViewById(R.id.all_apps_button).requestFocus();
+ }
}
}
@@ -3074,11 +3054,12 @@
// 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, false);
+
// Change the state *after* we've called all the transition code
mState = State.CUSTOMIZE;
@@ -3090,13 +3071,22 @@
// Hide the customization drawer (only exists in x-large configuration)
void hideCustomizationDrawer(boolean animated) {
if (mState == State.CUSTOMIZE || mState == State.CUSTOMIZE_SPRING_LOADED) {
- cameraZoomIn(State.CUSTOMIZE, animated);
+ cameraZoomIn(State.CUSTOMIZE, animated, false);
+
+ // Set focus to the customize button
+ findViewById(R.id.configure_button).requestFocus();
}
}
- 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 +3094,7 @@
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 +3104,37 @@
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,21 +3145,32 @@
}
}
+ 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()));
}
private void updateGlobalSearchIcon() {
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
+ final View searchButton = findViewById(R.id.search_button);
+ final View searchDivider = findViewById(R.id.search_divider);
+
final SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
ComponentName activityName = searchManager.getGlobalSearchActivity();
if (activityName != null) {
sGlobalSearchIcon = updateButtonWithIconFromExternalActivity(
R.id.search_button, activityName, R.drawable.ic_generic_search);
+ searchButton.setVisibility(View.VISIBLE);
+ searchDivider.setVisibility(View.VISIBLE);
} else {
- findViewById(R.id.search_button).setVisibility(View.GONE);
+ searchButton.setVisibility(View.GONE);
+ searchDivider.setVisibility(View.GONE);
}
}
}
@@ -3158,14 +3180,20 @@
}
private void updateVoiceSearchIcon() {
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
+ final View searchDivider = findViewById(R.id.search_divider);
+ final View voiceButton = findViewById(R.id.voice_button);
+
Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
ComponentName activityName = intent.resolveActivity(getPackageManager());
if (activityName != null) {
sVoiceSearchIcon = updateButtonWithIconFromExternalActivity(
R.id.voice_button, activityName, R.drawable.ic_voice_search);
+ searchDivider.setVisibility(View.VISIBLE);
+ voiceButton.setVisibility(View.VISIBLE);
} else {
- findViewById(R.id.voice_button).setVisibility(View.GONE);
+ searchDivider.setVisibility(View.GONE);
+ voiceButton.setVisibility(View.GONE);
}
}
}
@@ -3178,21 +3206,26 @@
* Sets the app market icon (shown when all apps is visible on x-large screens)
*/
private void updateAppMarketIcon() {
- if (LauncherApplication.isScreenXLarge()) {
- Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
- // Find the app market activity by resolving an intent.
- // (If multiple app markets are installed, it will return the ResolverActivity.)
- ComponentName activityName = intent.resolveActivity(getPackageManager());
- if (activityName != null) {
- mAppMarketIntent = intent;
- sAppMarketIcon = updateButtonWithIconFromExternalActivity(
- R.id.market_button, activityName, R.drawable.app_market_generic);
- }
+ final View marketButton = findViewById(R.id.market_button);
+ Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET);
+ // Find the app market activity by resolving an intent.
+ // (If multiple app markets are installed, it will return the ResolverActivity.)
+ ComponentName activityName = intent.resolveActivity(getPackageManager());
+ if (activityName != null) {
+ mAppMarketIntent = intent;
+ sAppMarketIcon = updateTextButtonWithIconFromExternalActivity(
+ R.id.market_button, activityName, R.drawable.app_market_generic);
+ marketButton.setVisibility(View.VISIBLE);
+ } else {
+ // We should hide and disable the view so that we don't try and restore the visibility
+ // of it when we swap between drag & normal states from IconDropTarget subclasses.
+ marketButton.setVisibility(View.GONE);
+ marketButton.setEnabled(false);
}
}
private void updateAppMarketIcon(Drawable.ConstantState d) {
- updateButtonWithDrawable(R.id.market_button, d);
+ updateTextButtonWithDrawable(R.id.market_button, d);
}
/**
@@ -3261,31 +3294,6 @@
break;
}
- case AddAdapter.ITEM_LIVE_FOLDER: {
- // Insert extra item to handle inserting folder
- Bundle bundle = new Bundle();
-
- ArrayList<String> shortcutNames = new ArrayList<String>();
- shortcutNames.add(res.getString(R.string.group_folder));
- bundle.putStringArrayList(Intent.EXTRA_SHORTCUT_NAME, shortcutNames);
-
- ArrayList<ShortcutIconResource> shortcutIcons =
- new ArrayList<ShortcutIconResource>();
- shortcutIcons.add(ShortcutIconResource.fromContext(Launcher.this,
- R.drawable.ic_launcher_folder));
- bundle.putParcelableArrayList(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, shortcutIcons);
-
- Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
- pickIntent.putExtra(Intent.EXTRA_INTENT,
- new Intent(LiveFolders.ACTION_CREATE_LIVE_FOLDER));
- pickIntent.putExtra(Intent.EXTRA_TITLE,
- getText(R.string.title_select_live_folder));
- pickIntent.putExtras(bundle);
-
- startActivityForResult(pickIntent, REQUEST_PICK_LIVE_FOLDER);
- break;
- }
-
case AddAdapter.ITEM_WALLPAPER: {
startWallpaper();
break;
@@ -3376,6 +3384,8 @@
*/
public void startBinding() {
final Workspace workspace = mWorkspace;
+
+ mWorkspace.clearDropTargets();
int count = workspace.getChildCount();
for (int i = 0; i < count; i++) {
// Use removeAllViewsInLayout() to avoid an extra requestLayout() and invalidate().
@@ -3421,21 +3431,13 @@
workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1,
false);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+ case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this,
(ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
- (UserFolderInfo) item, mIconCache);
+ (FolderInfo) item, mIconCache);
workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1,
false);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
- final FolderIcon newLiveFolder = LiveFolderIcon.fromXml(
- R.layout.live_folder_icon, this,
- (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()),
- (LiveFolderInfo) item);
- workspace.addInScreen(newLiveFolder, item.screen, item.cellX, item.cellY, 1, 1,
- false);
- break;
}
}
@@ -3504,12 +3506,14 @@
mWorkspace.getChildAt(mWorkspace.getCurrentPage()).requestFocus();
}
- final long[] userFolders = mSavedState.getLongArray(RUNTIME_STATE_USER_FOLDERS);
- if (userFolders != null) {
- for (long folderId : userFolders) {
+ final long[] folders = mSavedState.getLongArray(RUNTIME_STATE_FOLDERS);
+ if (folders != null) {
+ for (long folderId : folders) {
final FolderInfo info = sFolders.get(folderId);
- if (info != null) {
- openFolder(info);
+ final FolderIcon folderIcon = (FolderIcon)
+ mWorkspace.getViewForTag(info);
+ if (folderIcon != null) {
+ openFolder(folderIcon);
}
}
final Folder openFolder = mWorkspace.getOpenFolder();
@@ -3528,7 +3532,7 @@
// Workaround a bug that occurs when rotating the device while the customization mode is
// open, we trigger a new layout on all the CellLayout children.
- if (LauncherApplication.isScreenXLarge() && (mState == State.CUSTOMIZE)) {
+ if (LauncherApplication.isScreenLarge() && (mState == State.CUSTOMIZE)) {
final int childCount = mWorkspace.getChildCount();
for (int i = 0; i < childCount; ++i) {
mWorkspace.getChildAt(i).requestLayout();
@@ -3536,6 +3540,13 @@
}
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();
}
/**
@@ -3554,7 +3565,12 @@
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
- mAllAppsGrid.setApps(apps);
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.setApps(apps);
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.setApps(apps);
+ }
if (mCustomizePagedView != null) {
mCustomizePagedView.setApps(apps);
}
@@ -3569,7 +3585,12 @@
public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
setLoadOnResume();
removeDialog(DIALOG_CREATE_SHORTCUT);
- mAllAppsGrid.addApps(apps);
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.addApps(apps);
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.addApps(apps);
+ }
if (mCustomizePagedView != null) {
mCustomizePagedView.addApps(apps);
}
@@ -3584,8 +3605,15 @@
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 (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.updateApps(apps);
+ }
if (mCustomizePagedView != null) {
mCustomizePagedView.updateApps(apps);
}
@@ -3602,7 +3630,12 @@
if (permanent) {
mWorkspace.removeItems(apps);
}
- mAllAppsGrid.removeApps(apps);
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.removeApps(apps);
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.removeApps(apps);
+ }
if (mCustomizePagedView != null) {
mCustomizePagedView.removeApps(apps);
}
@@ -3617,6 +3650,9 @@
if (mCustomizePagedView != null) {
mCustomizePagedView.update();
}
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.onPackagesUpdated();
+ }
}
private int mapConfigurationOriActivityInfoOri(int configOri) {
@@ -3675,7 +3711,17 @@
Log.d(TAG, "mDesktopItems.size=" + mDesktopItems.size());
Log.d(TAG, "sFolders.size=" + sFolders.size());
mModel.dumpState();
- mAllAppsGrid.dumpState();
+ if (mAllAppsGrid != null) {
+ mAllAppsGrid.dumpState();
+ }
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.dumpState();
+ }
Log.d(TAG, "END launcher2 dump state");
}
}
+
+interface LauncherTransitionable {
+ void onLauncherTransitionStart(Animator animation);
+ void onLauncherTransitionEnd(Animator animation);
+}
diff --git a/src/com/android/launcher2/LauncherAnimatorUpdateListener.java b/src/com/android/launcher2/LauncherAnimatorUpdateListener.java
new file mode 100644
index 0000000..dd82113
--- /dev/null
+++ b/src/com/android/launcher2/LauncherAnimatorUpdateListener.java
@@ -0,0 +1,30 @@
+/*
+ * 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.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+
+abstract class LauncherAnimatorUpdateListener implements AnimatorUpdateListener {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float b = (Float) animation.getAnimatedValue();
+ final float a = 1f - b;
+ onAnimationUpdate(a, b);
+ }
+
+ abstract void onAnimationUpdate(float a, float b);
+}
\ No newline at end of file
diff --git a/src/com/android/launcher2/LauncherAppWidgetHostView.java b/src/com/android/launcher2/LauncherAppWidgetHostView.java
index 85a80f9..0dd1d83 100644
--- a/src/com/android/launcher2/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher2/LauncherAppWidgetHostView.java
@@ -22,6 +22,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewGroup;
import com.android.launcher.R;
@@ -72,7 +73,7 @@
// Otherwise continue letting touch events fall through to children
return false;
}
-
+
class CheckForLongPress implements Runnable {
private int mOriginalWindowAttachCount;
@@ -122,4 +123,9 @@
}
super.onVisibilityChanged(changedView, visibility);
}
+
+ @Override
+ public int getDescendantFocusability() {
+ return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
}
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index ed007dd..67573e0 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -23,23 +23,22 @@
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.os.Handler;
-import dalvik.system.VMRuntime;
public class LauncherApplication extends Application {
public LauncherModel mModel;
public IconCache mIconCache;
- private static boolean sIsScreenXLarge;
+ private static boolean sIsScreenLarge;
private static float sScreenDensity;
private static final boolean ENABLE_ROTATION = false;
@Override
public void onCreate() {
- VMRuntime.getRuntime().setMinimumHeapSize(4 * 1024 * 1024);
-
super.onCreate();
// set sIsScreenXLarge and sScreenDensity *before* creating icon cache
- sIsScreenXLarge = (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
+ final int screenSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
+ sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||
+ screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;
sScreenDensity = getResources().getDisplayMetrics().density;
mIconCache = new IconCache(this);
@@ -100,11 +99,11 @@
}
public static boolean isInPlaceRotationEnabled() {
- return sIsScreenXLarge && ENABLE_ROTATION;
+ return sIsScreenLarge && ENABLE_ROTATION;
}
- public static boolean isScreenXLarge() {
- return sIsScreenXLarge;
+ public static boolean isScreenLarge() {
+ return sIsScreenLarge;
}
public static float getScreenDensity() {
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 0052737..d5505c5 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -37,13 +37,13 @@
import android.content.Intent.ShortcutIconResource;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
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 +65,7 @@
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
@@ -89,9 +90,6 @@
private AllAppsList mAllAppsList; // only access in worker thread
private IconCache mIconCache;
- final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();
- final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>();
- final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>();
private Bitmap mDefaultIcon;
@@ -115,6 +113,7 @@
}
LauncherModel(LauncherApplication app, IconCache iconCache) {
+ mAppsCanBeOnExternalStorage = !Environment.isExternalStorageEmulated();
mApp = app;
mAllAppsList = new AllAppsList(iconCache);
mIconCache = iconCache;
@@ -174,6 +173,33 @@
}
/**
+ * 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.
*/
@@ -241,8 +267,7 @@
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, null,
"_id=? and (itemType=? or itemType=?)",
new String[] { String.valueOf(id),
- String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER),
- String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER) }, null);
+ String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_FOLDER)}, null);
try {
if (c.moveToFirst()) {
@@ -255,11 +280,8 @@
FolderInfo folderInfo = null;
switch (c.getInt(itemTypeIndex)) {
- case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
- folderInfo = findOrMakeUserFolder(folderList, id);
- break;
- case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
- folderInfo = findOrMakeLiveFolder(folderList, id);
+ case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
+ folderInfo = findOrMakeFolder(folderList, id);
break;
}
@@ -361,7 +383,7 @@
/**
* Remove the contents of the specified folder from the database
*/
- static void deleteUserFolderContentsFromDatabase(Context context, UserFolderInfo info) {
+ static void deleteFolderContentsFromDatabase(Context context, FolderInfo info) {
final ContentResolver cr = context.getContentResolver();
cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null);
@@ -492,9 +514,6 @@
mLoaderTask.stopLocked();
}
}
- mItems.clear();
- mAppWidgets.clear();
- mFolders.clear();
}
/**
@@ -510,6 +529,10 @@
private boolean mStopped;
private boolean mLoadAndBindStepFinished;
+ final ArrayList<ItemInfo> mItems = new ArrayList<ItemInfo>();
+ final ArrayList<LauncherAppWidgetInfo> mAppWidgets = new ArrayList<LauncherAppWidgetInfo>();
+ final HashMap<Long, FolderInfo> mFolders = new HashMap<Long, FolderInfo>();
+
LoaderTask(Context context, boolean isLaunching) {
mContext = context;
mIsLaunching = isLaunching;
@@ -629,22 +652,6 @@
mLoaderTask = null;
}
}
-
- // Trigger a gc to try to clean up after the stuff is done, since the
- // renderscript allocations aren't charged to the java heap.
- if (mStopped) {
- mHandler.post(new Runnable() {
- public void run() {
- System.gc();
- }
- });
- } else {
- mHandler.postIdle(new Runnable() {
- public void run() {
- System.gc();
- }
- });
- }
}
public void stopLocked() {
@@ -794,8 +801,6 @@
}
if (info != null) {
- updateSavedIcon(context, info, c, iconIndex);
-
info.intent = intent;
info.id = c.getLong(idIndex);
container = c.getInt(containerIndex);
@@ -815,11 +820,15 @@
break;
default:
// Item is in a user folder
- UserFolderInfo folderInfo =
- findOrMakeUserFolder(mFolders, container);
+ FolderInfo folderInfo =
+ findOrMakeFolder(mFolders, container);
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
@@ -832,9 +841,9 @@
}
break;
- case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+ case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
id = c.getLong(idIndex);
- UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id);
+ FolderInfo folderInfo = findOrMakeFolder(mFolders, id);
folderInfo.title = c.getString(titleIndex);
folderInfo.id = id;
@@ -857,57 +866,6 @@
mFolders.put(folderInfo.id, folderInfo);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
- id = c.getLong(idIndex);
- Uri uri = Uri.parse(c.getString(uriIndex));
-
- // Make sure the live folder exists
- final ProviderInfo providerInfo =
- context.getPackageManager().resolveContentProvider(
- uri.getAuthority(), 0);
-
- if (providerInfo == null && !isSafeMode) {
- itemsToRemove.add(id);
- } else {
- LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
- intentDescription = c.getString(intentIndex);
- intent = null;
- if (intentDescription != null) {
- try {
- intent = Intent.parseUri(intentDescription, 0);
- } catch (URISyntaxException e) {
- // Ignore, a live folder might not have a base intent
- }
- }
-
- liveFolderInfo.title = c.getString(titleIndex);
- liveFolderInfo.id = id;
- liveFolderInfo.uri = uri;
- container = c.getInt(containerIndex);
- liveFolderInfo.container = container;
- liveFolderInfo.screen = c.getInt(screenIndex);
- liveFolderInfo.cellX = c.getInt(cellXIndex);
- liveFolderInfo.cellY = c.getInt(cellYIndex);
- liveFolderInfo.baseIntent = intent;
- liveFolderInfo.displayMode = c.getInt(displayModeIndex);
-
- // check & update map of what's occupied
- if (!checkItemPlacement(occupied, liveFolderInfo)) {
- break;
- }
-
- loadLiveFolderIcon(context, c, iconTypeIndex, iconPackageIndex,
- iconResourceIndex, liveFolderInfo);
-
- switch (container) {
- case LauncherSettings.Favorites.CONTAINER_DESKTOP:
- mItems.add(liveFolderInfo);
- break;
- }
- mFolders.put(liveFolderInfo.id, liveFolderInfo);
- }
- break;
-
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
// Read all Launcher-specific widget details
int appWidgetId = c.getInt(appWidgetIdIndex);
@@ -1262,6 +1220,7 @@
Log.d(TAG, "mLoaderTask.mIsLaunching=" + mIsLaunching);
Log.d(TAG, "mLoaderTask.mStopped=" + mStopped);
Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished);
+ Log.d(TAG, "mItems size=" + mItems.size());
}
}
@@ -1591,13 +1550,11 @@
Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
Bitmap icon = null;
- boolean filtered = false;
boolean customIcon = false;
ShortcutIconResource iconResource = null;
if (bitmap != null && bitmap instanceof Bitmap) {
icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context);
- filtered = true;
customIcon = true;
} else {
Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
@@ -1636,39 +1593,11 @@
return info;
}
- private void loadLiveFolderIcon(Context context, Cursor c, int iconTypeIndex,
- int iconPackageIndex, int iconResourceIndex, LiveFolderInfo liveFolderInfo) {
-
- int iconType = c.getInt(iconTypeIndex);
- switch (iconType) {
- case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
- String packageName = c.getString(iconPackageIndex);
- String resourceName = c.getString(iconResourceIndex);
- PackageManager packageManager = context.getPackageManager();
- try {
- Resources appResources = packageManager.getResourcesForApplication(packageName);
- final int id = appResources.getIdentifier(resourceName, null, null);
- liveFolderInfo.icon = Utilities.createIconBitmap(
- mIconCache.getFullResIcon(appResources, id), context);
- } catch (Exception e) {
- Resources resources = context.getResources();
- liveFolderInfo.icon = Utilities.createIconBitmap(
- mIconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder),
- context);
- }
- liveFolderInfo.iconResource = new Intent.ShortcutIconResource();
- liveFolderInfo.iconResource.packageName = packageName;
- liveFolderInfo.iconResource.resourceName = resourceName;
- break;
- default:
- Resources resources = context.getResources();
- liveFolderInfo.icon = Utilities.createIconBitmap(
- mIconCache.getFullResIcon(resources, R.drawable.ic_launcher_folder),
- context);
- }
- }
-
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,53 +1620,26 @@
}
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);
}
}
}
/**
- * Return an existing UserFolderInfo object if we have encountered this ID previously,
+ * Return an existing FolderInfo object if we have encountered this ID previously,
* or make a new one.
*/
- private static UserFolderInfo findOrMakeUserFolder(HashMap<Long, FolderInfo> folders, long id) {
+ private static FolderInfo findOrMakeFolder(HashMap<Long, FolderInfo> folders, long id) {
// See if a placeholder was created for us already
FolderInfo folderInfo = folders.get(id);
- if (folderInfo == null || !(folderInfo instanceof UserFolderInfo)) {
+ if (folderInfo == null) {
// No placeholder -- create a new instance
- folderInfo = new UserFolderInfo();
+ folderInfo = new FolderInfo();
folders.put(id, folderInfo);
}
- return (UserFolderInfo) folderInfo;
- }
-
- /**
- * Return an existing UserFolderInfo object if we have encountered this ID previously, or make a
- * new one.
- */
- private static LiveFolderInfo findOrMakeLiveFolder(HashMap<Long, FolderInfo> folders, long id) {
- // See if a placeholder was created for us already
- FolderInfo folderInfo = folders.get(id);
- if (folderInfo == null || !(folderInfo instanceof LiveFolderInfo)) {
- // No placeholder -- create a new instance
- folderInfo = new LiveFolderInfo();
- folders.put(id, folderInfo);
- }
- return (LiveFolderInfo) folderInfo;
- }
-
- private static String getLabel(PackageManager manager, ActivityInfo activityInfo) {
- String label = activityInfo.loadLabel(manager).toString();
- if (label == null) {
- label = manager.getApplicationLabel(activityInfo.applicationInfo).toString();
- if (label == null) {
- label = activityInfo.name;
- }
- }
- return label;
+ return folderInfo;
}
private static final Collator sCollator = Collator.getInstance();
@@ -1755,6 +1657,48 @@
return 0;
}
};
+ public static final Comparator<AppWidgetProviderInfo> WIDGET_NAME_COMPARATOR
+ = new Comparator<AppWidgetProviderInfo>() {
+ public final int compare(AppWidgetProviderInfo a, AppWidgetProviderInfo b) {
+ return sCollator.compare(a.label.toString(), b.label.toString());
+ }
+ };
+ public static class ShortcutNameComparator implements Comparator<ResolveInfo> {
+ private PackageManager mPackageManager;
+ private HashMap<Object, String> mLabelCache;
+ ShortcutNameComparator(PackageManager pm) {
+ mPackageManager = pm;
+ mLabelCache = new HashMap<Object, String>();
+ }
+ public final int compare(ResolveInfo a, ResolveInfo b) {
+ String labelA, labelB;
+ if (mLabelCache.containsKey(a)) labelA = mLabelCache.get(a);
+ else labelA = a.loadLabel(mPackageManager).toString();
+ if (mLabelCache.containsKey(b)) labelB = mLabelCache.get(b);
+ else labelB = b.loadLabel(mPackageManager).toString();
+ return sCollator.compare(labelA, labelB);
+ }
+ };
+ public static class WidgetAndShortcutNameComparator implements Comparator<Object> {
+ private PackageManager mPackageManager;
+ private HashMap<Object, String> mLabelCache;
+ WidgetAndShortcutNameComparator(PackageManager pm) {
+ mPackageManager = pm;
+ mLabelCache = new HashMap<Object, String>();
+ }
+ public final int compare(Object a, Object b) {
+ String labelA, labelB;
+ if (mLabelCache.containsKey(a)) labelA = mLabelCache.get(a);
+ else labelA = (a instanceof AppWidgetProviderInfo) ?
+ ((AppWidgetProviderInfo) a).label :
+ ((ResolveInfo) a).loadLabel(mPackageManager).toString();
+ if (mLabelCache.containsKey(b)) labelB = mLabelCache.get(b);
+ else labelB = (b instanceof AppWidgetProviderInfo) ?
+ ((AppWidgetProviderInfo) b).label :
+ ((ResolveInfo) b).loadLabel(mPackageManager).toString();
+ return sCollator.compare(labelA, labelB);
+ }
+ };
public void dumpState() {
Log.d(TAG, "mCallbacks=" + mCallbacks);
@@ -1762,7 +1706,6 @@
ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.added", mAllAppsList.added);
ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.removed", mAllAppsList.removed);
ApplicationInfo.dumpApplicationInfoList(TAG, "mAllAppsList.modified", mAllAppsList.modified);
- Log.d(TAG, "mItems size=" + mItems.size());
if (mLoaderTask != null) {
mLoaderTask.dumpState();
} else {
diff --git a/src/com/android/launcher2/LauncherSettings.java b/src/com/android/launcher2/LauncherSettings.java
index 9c685ce..c378405 100644
--- a/src/com/android/launcher2/LauncherSettings.java
+++ b/src/com/android/launcher2/LauncherSettings.java
@@ -16,8 +16,8 @@
package com.android.launcher2;
-import android.provider.BaseColumns;
import android.net.Uri;
+import android.provider.BaseColumns;
/**
* Settings related utilities.
@@ -169,11 +169,15 @@
/**
* The favorite is a user created folder
*/
- static final int ITEM_TYPE_USER_FOLDER = 2;
+ static final int ITEM_TYPE_FOLDER = 2;
/**
- * The favorite is a live folder
- */
+ * The favorite is a live folder
+ *
+ * Note: live folders can no longer be added to Launcher, and any live folders which
+ * exist within the launcher database will be ignored when loading. That said, these
+ * entries in the database may still exist, and are not automatically stripped.
+ */
static final int ITEM_TYPE_LIVE_FOLDER = 3;
/**
diff --git a/src/com/android/launcher2/LiveFolder.java b/src/com/android/launcher2/LiveFolder.java
deleted file mode 100644
index 07a295f..0000000
--- a/src/com/android/launcher2/LiveFolder.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.Context;
-import android.content.Intent;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.AdapterView;
-import android.net.Uri;
-import android.provider.LiveFolders;
-import android.os.AsyncTask;
-import android.database.Cursor;
-
-import java.lang.ref.WeakReference;
-
-import com.android.launcher.R;
-
-public class LiveFolder extends Folder {
- private AsyncTask<LiveFolderInfo,Void,Cursor> mLoadingTask;
-
- public LiveFolder(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- static LiveFolder fromXml(Context context, FolderInfo folderInfo) {
- final int layout = isDisplayModeList(folderInfo) ?
- R.layout.live_folder_list : R.layout.live_folder_grid;
- return (LiveFolder) LayoutInflater.from(context).inflate(layout, null);
- }
-
- private static boolean isDisplayModeList(FolderInfo folderInfo) {
- return ((LiveFolderInfo) folderInfo).displayMode ==
- LiveFolders.DISPLAY_MODE_LIST;
- }
-
- @Override
- public void onItemClick(AdapterView parent, View v, int position, long id) {
- LiveFolderAdapter.ViewHolder holder = (LiveFolderAdapter.ViewHolder) v.getTag();
-
- if (holder.useBaseIntent) {
- final Intent baseIntent = ((LiveFolderInfo) mInfo).baseIntent;
- if (baseIntent != null) {
- final Intent intent = new Intent(baseIntent);
- Uri uri = baseIntent.getData();
- uri = uri.buildUpon().appendPath(Long.toString(holder.id)).build();
- intent.setData(uri);
- mLauncher.startActivitySafely(intent, "(position=" + position + ", id=" + id + ")");
- }
- } else if (holder.intent != null) {
- mLauncher.startActivitySafely(holder.intent,
- "(position=" + position + ", id=" + id + ")");
- }
- }
-
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- return false;
- }
-
- void bind(FolderInfo info) {
- super.bind(info);
- if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
- mLoadingTask.cancel(true);
- }
- mLoadingTask = new FolderLoadingTask(this).execute((LiveFolderInfo) info);
- }
-
- @Override
- void onOpen() {
- super.onOpen();
- requestFocus();
- }
-
- @Override
- void onClose() {
- super.onClose();
- if (mLoadingTask != null && mLoadingTask.getStatus() == AsyncTask.Status.RUNNING) {
- mLoadingTask.cancel(true);
- }
-
- // The adapter can be null if onClose() is called before FolderLoadingTask
- // is done querying the provider
- final LiveFolderAdapter adapter = (LiveFolderAdapter) mContent.getAdapter();
- if (adapter != null) {
- adapter.cleanup();
- }
- }
-
- static class FolderLoadingTask extends AsyncTask<LiveFolderInfo, Void, Cursor> {
- private final WeakReference<LiveFolder> mFolder;
- private LiveFolderInfo mInfo;
-
- FolderLoadingTask(LiveFolder folder) {
- mFolder = new WeakReference<LiveFolder>(folder);
- }
-
- protected Cursor doInBackground(LiveFolderInfo... params) {
- final LiveFolder folder = mFolder.get();
- if (folder != null) {
- mInfo = params[0];
- return LiveFolderAdapter.query(folder.mLauncher, mInfo);
- }
- return null;
- }
-
- @Override
- protected void onPostExecute(Cursor cursor) {
- if (!isCancelled()) {
- if (cursor != null) {
- final LiveFolder folder = mFolder.get();
- if (folder != null) {
- final Launcher launcher = folder.mLauncher;
- folder.setContentAdapter(new LiveFolderAdapter(launcher, mInfo, cursor));
- }
- }
- } else if (cursor != null) {
- cursor.close();
- }
- }
- }
-}
diff --git a/src/com/android/launcher2/LiveFolderAdapter.java b/src/com/android/launcher2/LiveFolderAdapter.java
deleted file mode 100644
index fb9c6a3..0000000
--- a/src/com/android/launcher2/LiveFolderAdapter.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.widget.CursorAdapter;
-import android.widget.TextView;
-import android.widget.ImageView;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.content.pm.PackageManager;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.LayoutInflater;
-import android.database.Cursor;
-import android.provider.LiveFolders;
-import android.graphics.drawable.Drawable;
-import android.graphics.BitmapFactory;
-import android.graphics.Bitmap;
-
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.lang.ref.SoftReference;
-
-import com.android.launcher.R;
-
-class LiveFolderAdapter extends CursorAdapter {
- private boolean mIsList;
- private LayoutInflater mInflater;
-
- private final HashMap<String, Drawable> mIcons = new HashMap<String, Drawable>();
- private final HashMap<Long, SoftReference<Drawable>> mCustomIcons =
- new HashMap<Long, SoftReference<Drawable>>();
- private final Launcher mLauncher;
-
- LiveFolderAdapter(Launcher launcher, LiveFolderInfo info, Cursor cursor) {
- super(launcher, cursor, true);
- mIsList = info.displayMode == LiveFolders.DISPLAY_MODE_LIST;
- mInflater = LayoutInflater.from(launcher);
- mLauncher = launcher;
-
- mLauncher.startManagingCursor(getCursor());
- }
-
- static Cursor query(Context context, LiveFolderInfo info) {
- return context.getContentResolver().query(info.uri, null, null,
- null, LiveFolders.NAME + " ASC");
- }
-
- public View newView(Context context, Cursor cursor, ViewGroup parent) {
- View view;
- final ViewHolder holder = new ViewHolder();
-
- if (!mIsList) {
- view = mInflater.inflate(R.layout.application_boxed, parent, false);
- } else {
- view = mInflater.inflate(R.layout.application_list, parent, false);
- holder.description = (TextView) view.findViewById(R.id.description);
- holder.icon = (ImageView) view.findViewById(R.id.icon);
- }
-
- holder.name = (TextView) view.findViewById(R.id.name);
-
- holder.idIndex = cursor.getColumnIndexOrThrow(LiveFolders._ID);
- holder.nameIndex = cursor.getColumnIndexOrThrow(LiveFolders.NAME);
- holder.descriptionIndex = cursor.getColumnIndex(LiveFolders.DESCRIPTION);
- holder.intentIndex = cursor.getColumnIndex(LiveFolders.INTENT);
- holder.iconBitmapIndex = cursor.getColumnIndex(LiveFolders.ICON_BITMAP);
- holder.iconResourceIndex = cursor.getColumnIndex(LiveFolders.ICON_RESOURCE);
- holder.iconPackageIndex = cursor.getColumnIndex(LiveFolders.ICON_PACKAGE);
-
- view.setTag(holder);
-
- return view;
- }
-
- public void bindView(View view, Context context, Cursor cursor) {
- final ViewHolder holder = (ViewHolder) view.getTag();
-
- holder.id = cursor.getLong(holder.idIndex);
- final Drawable icon = loadIcon(context, cursor, holder);
-
- holder.name.setText(cursor.getString(holder.nameIndex));
-
- if (!mIsList) {
- holder.name.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
- } else {
- final boolean hasIcon = icon != null;
- holder.icon.setVisibility(hasIcon ? View.VISIBLE : View.GONE);
- if (hasIcon) holder.icon.setImageDrawable(icon);
-
- if (holder.descriptionIndex != -1) {
- final String description = cursor.getString(holder.descriptionIndex);
- if (description != null) {
- holder.description.setText(description);
- holder.description.setVisibility(View.VISIBLE);
- } else {
- holder.description.setVisibility(View.GONE);
- }
- } else {
- holder.description.setVisibility(View.GONE);
- }
- }
-
- if (holder.intentIndex != -1) {
- try {
- holder.intent = Intent.parseUri(cursor.getString(holder.intentIndex), 0);
- } catch (URISyntaxException e) {
- // Ignore
- }
- } else {
- holder.useBaseIntent = true;
- }
- }
-
- private Drawable loadIcon(Context context, Cursor cursor, ViewHolder holder) {
- Drawable icon = null;
- byte[] data = null;
-
- if (holder.iconBitmapIndex != -1) {
- data = cursor.getBlob(holder.iconBitmapIndex);
- }
-
- if (data != null) {
- final SoftReference<Drawable> reference = mCustomIcons.get(holder.id);
- if (reference != null) {
- icon = reference.get();
- }
-
- if (icon == null) {
- final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
- final Bitmap resampled = Utilities.resampleIconBitmap(bitmap, mContext);
- if (bitmap != resampled) {
- // If we got back a different object, we don't need the old one any more.
- bitmap.recycle();
- }
- icon = new FastBitmapDrawable(resampled);
- mCustomIcons.put(holder.id, new SoftReference<Drawable>(icon));
- }
- } else if (holder.iconResourceIndex != -1 && holder.iconPackageIndex != -1) {
- final String resource = cursor.getString(holder.iconResourceIndex);
- icon = mIcons.get(resource);
- if (icon == null) {
- try {
- final PackageManager packageManager = context.getPackageManager();
- Resources resources = packageManager.getResourcesForApplication(
- cursor.getString(holder.iconPackageIndex));
- final int id = resources.getIdentifier(resource,
- null, null);
- icon = new FastBitmapDrawable(
- Utilities.createIconBitmap(resources.getDrawable(id), mContext));
- mIcons.put(resource, icon);
- } catch (Exception e) {
- // Ignore
- }
- }
- }
-
- return icon;
- }
-
- void cleanup() {
- for (Drawable icon : mIcons.values()) {
- icon.setCallback(null);
- }
- mIcons.clear();
-
- for (SoftReference<Drawable> icon : mCustomIcons.values()) {
- final Drawable drawable = icon.get();
- if (drawable != null) {
- drawable.setCallback(null);
- }
- }
- mCustomIcons.clear();
-
- final Cursor cursor = getCursor();
- if (cursor != null) {
- try {
- cursor.close();
- } finally {
- mLauncher.stopManagingCursor(cursor);
- }
- }
- }
-
- static class ViewHolder {
- TextView name;
- TextView description;
- ImageView icon;
-
- Intent intent;
- long id;
- boolean useBaseIntent;
-
- int idIndex;
- int nameIndex;
- int descriptionIndex = -1;
- int intentIndex = -1;
- int iconBitmapIndex = -1;
- int iconResourceIndex = -1;
- int iconPackageIndex = -1;
- }
-}
diff --git a/src/com/android/launcher2/LiveFolderIcon.java b/src/com/android/launcher2/LiveFolderIcon.java
deleted file mode 100644
index 5b73a59..0000000
--- a/src/com/android/launcher2/LiveFolderIcon.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.AttributeSet;
-import android.view.ViewGroup;
-import android.view.LayoutInflater;
-import android.graphics.Bitmap;
-
-import com.android.launcher.R;
-
-public class LiveFolderIcon extends FolderIcon {
- public LiveFolderIcon(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public LiveFolderIcon(Context context) {
- super(context);
- }
-
- static LiveFolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
- LiveFolderInfo folderInfo) {
-
- LiveFolderIcon icon = (LiveFolderIcon)
- LayoutInflater.from(launcher).inflate(resId, group, false);
-
- final Resources resources = launcher.getResources();
- Bitmap b = folderInfo.icon;
- if (b == null) {
- b = Utilities.createIconBitmap(resources.getDrawable(R.drawable.ic_launcher_folder),
- launcher);
- }
- icon.setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(b), null, null);
- icon.setText(folderInfo.title);
- icon.setTag(folderInfo);
- icon.setOnClickListener(launcher);
-
- return icon;
- }
-
- @Override
- public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- return false;
- }
-
- @Override
- public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- @Override
- public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- @Override
- public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- @Override
- public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-}
diff --git a/src/com/android/launcher2/LiveFolderInfo.java b/src/com/android/launcher2/LiveFolderInfo.java
deleted file mode 100644
index 74b0217..0000000
--- a/src/com/android/launcher2/LiveFolderInfo.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.ContentValues;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.net.Uri;
-
-class LiveFolderInfo extends FolderInfo {
-
- /**
- * The base intent, if it exists.
- */
- Intent baseIntent;
-
- /**
- * The live folder's content uri.
- */
- Uri uri;
-
- /**
- * The live folder's display type.
- */
- int displayMode;
-
- /**
- * The live folder icon.
- */
- Bitmap icon;
-
- /**
- * Reference to the live folder icon as an application's resource.
- */
- Intent.ShortcutIconResource iconResource;
-
- LiveFolderInfo() {
- itemType = LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER;
- }
-
- @Override
- void onAddToDatabase(ContentValues values) {
- super.onAddToDatabase(values);
- values.put(LauncherSettings.Favorites.TITLE, title.toString());
- values.put(LauncherSettings.Favorites.URI, uri.toString());
- if (baseIntent != null) {
- values.put(LauncherSettings.Favorites.INTENT, baseIntent.toUri(0));
- }
- values.put(LauncherSettings.Favorites.ICON_TYPE, LauncherSettings.Favorites.ICON_TYPE_RESOURCE);
- values.put(LauncherSettings.Favorites.DISPLAY_MODE, displayMode);
- if (iconResource != null) {
- values.put(LauncherSettings.Favorites.ICON_PACKAGE, iconResource.packageName);
- values.put(LauncherSettings.Favorites.ICON_RESOURCE, iconResource.resourceName);
- }
- }
-}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index e4cdd59..1180106 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -29,7 +29,10 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.ActionMode;
+import android.view.InputDevice;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -48,6 +51,7 @@
*/
public abstract class PagedView extends ViewGroup {
private static final String TAG = "PagedView";
+ private static final boolean DEBUG = false;
protected static final int INVALID_PAGE = -1;
// the min drag distance for a fling to register, to prevent random page shifts
@@ -61,6 +65,7 @@
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 +86,7 @@
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 +104,7 @@
protected int mTouchSlop;
private int mPagingTouchSlop;
private int mMaximumVelocity;
+ private int mMinimumWidth;
protected int mPageSpacing;
protected int mPageLayoutPaddingTop;
protected int mPageLayoutPaddingBottom;
@@ -105,6 +112,7 @@
protected int mPageLayoutPaddingRight;
protected int mPageLayoutWidthGap;
protected int mPageLayoutHeightGap;
+ protected int mPageLayoutMaxHeight;
protected int mCellCountX;
protected int mCellCountY;
protected boolean mCenterPagesVertically;
@@ -173,17 +181,19 @@
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(
R.styleable.PagedView_pageLayoutHeightGap, -1);
+ mPageLayoutMaxHeight = a.getDimensionPixelSize(
+ R.styleable.PagedView_pageLayoutMaxHeight, -1);
a.recycle();
setHapticFeedbackEnabled(false);
@@ -284,6 +294,10 @@
mIsPageMoving = false;
}
+ protected boolean isPageMoving() {
+ return mIsPageMoving;
+ }
+
// a method that subclasses can override to add behavior
protected void onPageBeginMoving() {
}
@@ -379,8 +393,13 @@
final int verticalPadding = mPaddingTop + mPaddingBottom;
+ if (mPageLayoutMaxHeight != -1) {
+ heightSize = Math.min(mPageLayoutMaxHeight, heightSize);
+ }
+
// The children are given the same width and height as the workspace
// unless they were set to WRAP_CONTENT
+ if (DEBUG) Log.d(TAG, "PagedView.onMeasure(): " + widthSize + ", " + heightSize);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
// disallowing padding in paged view (just pass 0)
@@ -408,6 +427,8 @@
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+ if (DEBUG) Log.d(TAG, "\tmeasure-child" + i + ": " + child.getMeasuredWidth() + ", "
+ + child.getMeasuredHeight());
}
if (heightMode == MeasureSpec.AT_MOST) {
@@ -462,6 +483,7 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
setHorizontalScrollBarEnabled(false);
int newX = getChildOffset(mCurrentPage) - getRelativeChildOffset(mCurrentPage);
@@ -475,6 +497,8 @@
final int childCount = getChildCount();
int childLeft = 0;
if (childCount > 0) {
+ if (DEBUG) Log.d(TAG, "getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+ + getChildWidth(0));
childLeft = getRelativeChildOffset(0);
}
@@ -488,6 +512,7 @@
childTop += ((getMeasuredHeight() - verticalPadding) - childHeight) / 2;
}
+ if (DEBUG) Log.d(TAG, "\tlayout-child" + i + ": " + childLeft + ", " + childTop);
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(), childTop + childHeight);
childLeft += childWidth + mPageSpacing;
@@ -498,10 +523,16 @@
}
}
+ protected void forceUpdateAdjacentPagesAlpha() {
+ mDirtyPageAlpha = true;
+ updateAdjacentPagesAlpha();
+ }
+
protected void updateAdjacentPagesAlpha() {
if (mFadeInAdjacentScreens) {
if (mDirtyPageAlpha || (mTouchState == TOUCH_STATE_SCROLLING) || !mScroller.isFinished()) {
- int halfScreenSize = getMeasuredWidth() / 2;
+ int screenWidth = getMeasuredWidth();
+ int halfScreenSize = screenWidth / 2;
int screenCenter = mScrollX + halfScreenSize;
final int childCount = getChildCount();
for (int i = 0; i < childCount; ++i) {
@@ -514,7 +545,7 @@
// we should just assume full page width (and calculate the offset according to
// that).
if (childWidth <= 0) {
- childWidth = getMeasuredWidth();
+ childWidth = screenWidth;
childCenter = (i * childWidth) + (childWidth / 2);
}
@@ -544,6 +575,11 @@
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 +632,7 @@
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 +759,7 @@
* 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 +800,7 @@
mLastMotionX = x;
mLastMotionY = y;
mLastMotionXRemainder = 0;
+ mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
mAllowLongPress = true;
@@ -814,10 +838,12 @@
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
mActivePointerId = INVALID_POINTER;
+ releaseVelocityTracker();
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
+ releaseVelocityTracker();
break;
}
@@ -869,6 +895,7 @@
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 +979,7 @@
// 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 +993,8 @@
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).
@@ -973,6 +1003,7 @@
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
if (!mDeferScrollUpdate) {
scrollBy((int) deltaX, 0);
+ if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
} else {
invalidate();
}
@@ -995,17 +1026,37 @@
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 +1105,35 @@
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();
@@ -1097,7 +1177,7 @@
public void requestChildFocus(View child, View focused) {
super.requestChildFocus(child, focused);
int page = indexOfChild(child);
- if (page >= 0 && !isInTouchMode()) {
+ if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
snapToPage(page);
}
}
@@ -1116,8 +1196,23 @@
return -1;
}
+ protected void setMinimumWidthOverride(int minimumWidth) {
+ mMinimumWidth = minimumWidth;
+ }
+ protected void resetMinimumWidthOverride() {
+ mMinimumWidth = 0;
+ }
+
+ protected int getChildWidth(int index) {
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredWidth = getChildAt(index).getMeasuredWidth();
+ final int minWidth = mMinimumWidth;
+ return (minWidth > measuredWidth) ? minWidth : measuredWidth;
+ }
+
protected int getRelativeChildOffset(int index) {
- return (getMeasuredWidth() - getChildAt(index).getMeasuredWidth()) / 2;
+ return (getMeasuredWidth() - getChildWidth(index)) / 2;
}
protected int getChildOffset(int index) {
@@ -1132,7 +1227,12 @@
}
protected int getScaledMeasuredWidth(View child) {
- return (int) (child.getMeasuredWidth() * mLayoutScale + 0.5f);
+ // This functions are called enough times that it actually makes a difference in the
+ // profiler -- so just inline the max() here
+ final int measuredWidth = child.getMeasuredWidth();
+ final int minWidth = mMinimumWidth;
+ final int maxWidth = (minWidth > measuredWidth) ? minWidth : measuredWidth;
+ return (int) (maxWidth * mLayoutScale + 0.5f);
}
int getPageNearestToCenterOfScreen() {
@@ -1182,6 +1282,9 @@
whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
int halfScreenSize = getMeasuredWidth() / 2;
+ if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+ if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+ + getMeasuredWidth() + ", " + getChildWidth(whichPage));
final int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
int delta = newX - mUnboundedScrollX;
int duration = 0;
@@ -1219,6 +1322,9 @@
protected void snapToPage(int whichPage, int duration) {
whichPage = Math.max(0, Math.min(whichPage, getPageCount() - 1));
+ if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
+ if (DEBUG) Log.d(TAG, "snapToPage.getRelativeChildOffset(): " + getMeasuredWidth() + ", "
+ + getChildWidth(whichPage));
int newX = getChildOffset(whichPage) - getRelativeChildOffset(whichPage);
final int sX = mUnboundedScrollX;
final int delta = newX - sX;
@@ -1330,6 +1436,8 @@
if (page < count) {
int lowerPageBound = getAssociatedLowerPageBound(page);
int upperPageBound = getAssociatedUpperPageBound(page);
+ if (DEBUG) Log.d(TAG, "loadAssociatedPages: " + lowerPageBound + "/"
+ + upperPageBound);
for (int i = 0; i < count; ++i) {
Page layout = (Page) getChildAt(i);
final int childCount = layout.getPageChildCount();
@@ -1398,7 +1506,7 @@
* 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 +1522,6 @@
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 d64f3c9..9022cac 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -17,12 +17,15 @@
package com.android.launcher2;
import android.content.Context;
+import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import com.android.launcher.R;
+
/**
* An abstraction of the original CellLayout which supports laying out items
* which span multiple cells into a grid-like layout. Also supports dimming
@@ -37,10 +40,10 @@
private int mCellHeight;
private int mWidthGap;
private int mHeightGap;
- 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);
@@ -56,7 +59,9 @@
setAlwaysDrawnWithCacheEnabled(false);
// setup default cell parameters
- mCellWidth = mCellHeight = sDefaultCellDimensions;
+ Resources resources = context.getResources();
+ mCellWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width);
+ mCellHeight = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height);
mCellCountX = LauncherModel.getCellCountX();
mCellCountY = LauncherModel.getCellCountY();
mWidthGap = mHeightGap = -1;
@@ -74,8 +79,17 @@
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 +99,18 @@
}
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();
}
@@ -109,6 +128,15 @@
}
}
+ /** Syncs the holographic icon views to the child icon views */
+ public void reloadHolographicIcons(boolean createHolographicOutlines) {
+ if (createHolographicOutlines) {
+ mChildren.loadHolographicOutlines();
+ } else {
+ mChildren.clearHolographicOutlines();
+ }
+ }
+
public boolean addViewToCellLayout(View child, int index, int childId,
PagedViewCellLayout.LayoutParams params) {
final PagedViewCellLayout.LayoutParams lp = params;
@@ -127,10 +155,11 @@
if (child instanceof PagedViewIcon) {
PagedViewIcon pagedViewIcon = (PagedViewIcon) child;
- if (mUseHardwareLayers) {
+ if (mAllowHardwareLayerCreation) {
pagedViewIcon.disableCache();
}
- mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(), index, lp);
+ mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(),
+ index, lp);
}
return true;
}
@@ -141,6 +170,7 @@
public void removeAllViewsOnPage() {
mChildren.removeAllViews();
mHolographicChildren.removeAllViews();
+ destroyHardwareLayers();
}
@Override
@@ -164,6 +194,14 @@
return mChildren.indexOfChild(v);
}
+ public int getCellCountX() {
+ return mCellCountX;
+ }
+
+ public int getCellCountY() {
+ return mCellCountY;
+ }
+
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO: currently ignoring padding
@@ -227,12 +265,37 @@
setMeasuredDimension(newWidth, newHeight);
}
+ int getContentWidth() {
+ if (LauncherApplication.isScreenLarge()) {
+ // Return the distance from the left edge of the content of the leftmost icon to
+ // the right edge of the content of the rightmost icon
+
+ // icons are centered within cells, find out how much padding that accounts for
+ return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize());
+ } else {
+ return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
+ }
+ }
+
+ int getContentHeight() {
+ return mCellCountY * mCellHeight + (mCellCountY - 1) * Math.max(0, mHeightGap);
+ }
+
+ int getWidthBeforeFirstLayout() {
+ return mCellCountX * mCellWidth + (mCellCountX - 1) * Math.max(0, mWidthGap);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
- child.layout(0, 0, r - l, b - t);
+ if (LauncherApplication.isScreenLarge()) {
+ child.layout(0, 0, r - l, b - t);
+ } else {
+ child.layout(mPaddingLeft, mPaddingTop, getMeasuredWidth() - mPaddingRight,
+ getMeasuredHeight() - mPaddingBottom);
+ }
}
}
@@ -265,17 +328,6 @@
mHolographicChildren.setGap(widthGap, heightGap);
}
- public void setCellDimensions(int width, int height) {
- mCellWidth = width;
- mCellHeight = height;
- mChildren.setCellDimensions(width, height);
- mHolographicChildren.setCellDimensions(width, height);
- }
-
- public int getDefaultCellDimensions() {
- return sDefaultCellDimensions;
- }
-
public int[] getCellCountForDimensions(int width, int height) {
// Always assume we're working with the smallest span to make sure we
// reserve enough space in both orientations
@@ -432,8 +484,13 @@
height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
topMargin - bottomMargin;
- x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
- y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+ if (LauncherApplication.isScreenLarge()) {
+ x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
+ y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+ } else {
+ x = myCellX * (cellWidth + widthGap) + leftMargin;
+ y = myCellY * (cellHeight + heightGap) + topMargin;
+ }
}
public Object getTag() {
diff --git a/src/com/android/launcher2/PagedViewCellLayoutChildren.java b/src/com/android/launcher2/PagedViewCellLayoutChildren.java
index 27da02a..6333f7f 100644
--- a/src/com/android/launcher2/PagedViewCellLayoutChildren.java
+++ b/src/com/android/launcher2/PagedViewCellLayoutChildren.java
@@ -139,12 +139,12 @@
}
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);
}
}
@@ -165,4 +165,26 @@
}
}
}
+
+ public void loadHolographicOutlines() {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View view = getChildAt(i);
+ if (view instanceof PagedViewIcon) {
+ PagedViewIcon icon = (PagedViewIcon) view;
+ icon.loadHolographicIcon();
+ }
+ }
+ }
+
+ public void clearHolographicOutlines() {
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View view = getChildAt(i);
+ if (view instanceof PagedViewIcon) {
+ PagedViewIcon icon = (PagedViewIcon) view;
+ icon.clearHolographicIcon();
+ }
+ }
+ }
}
diff --git a/src/com/android/launcher2/PagedViewExtendedLayout.java b/src/com/android/launcher2/PagedViewExtendedLayout.java
index e54d261..94890d8 100644
--- a/src/com/android/launcher2/PagedViewExtendedLayout.java
+++ b/src/com/android/launcher2/PagedViewExtendedLayout.java
@@ -23,10 +23,11 @@
import android.widget.LinearLayout;
/**
- * The linear layout used strictly for the widget/wallpaper tab of the customization tray
+ * The linear layout used strictly for the widget/wallpaper tab of the customization tray.
+ * To be deprecated.
*/
public class PagedViewExtendedLayout extends LinearLayout implements Page {
- static final String TAG = "PagedViewWidgetLayout";
+ static final String TAG = "PagedViewExtendedLayout";
public PagedViewExtendedLayout(Context context) {
this(context, null);
@@ -40,6 +41,22 @@
super(context, attrs, defStyle);
}
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (LauncherApplication.isScreenLarge()) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ } else {
+ // PagedView currently has issues with different-sized pages since it calculates the
+ // offset of each page to scroll to before it updates the actual size of each page
+ // (which canchange depending on the content if the contains aren't a fixed size).
+ // We work around this by having a minimum size on each widget page).
+ int widthSpecSize = Math.max(getSuggestedMinimumWidth(),
+ MeasureSpec.getSize(widthMeasureSpec));
+ int widthSpecMode = MeasureSpec.AT_MOST;
+ super.onMeasure(MeasureSpec.makeMeasureSpec(widthSpecSize, widthSpecMode),
+ heightMeasureSpec);
+ }
+ }
+
@Override
public boolean onTouchEvent(MotionEvent event) {
// We eat up the touch events here, since the PagedView (which uses the same swiping
@@ -94,4 +111,11 @@
public int indexOfChildOnPage(View v) {
return indexOfChild(v);
}
+
+ public static class LayoutParams extends LinearLayout.LayoutParams {
+ public LayoutParams() {
+ super(LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.MATCH_PARENT);
+ }
+ }
}
diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java
new file mode 100644
index 0000000..cedf71c
--- /dev/null
+++ b/src/com/android/launcher2/PagedViewGridLayout.java
@@ -0,0 +1,120 @@
+/*
+ * 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.view.MotionEvent;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+/**
+ * The grid based layout used strictly for the widget/wallpaper tab of the AppsCustomize pane
+ */
+public class PagedViewGridLayout extends FrameLayout implements Page {
+ static final String TAG = "PagedViewGridLayout";
+
+ private int mCellCountX;
+ private int mCellCountY;
+
+ public PagedViewGridLayout(Context context, int cellCountX, int cellCountY) {
+ super(context, null, 0);
+ mCellCountX = cellCountX;
+ mCellCountY = cellCountY;
+ }
+
+ int getCellCountX() {
+ return mCellCountX;
+ }
+ int getCellCountY() {
+ return mCellCountY;
+ }
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ // PagedView currently has issues with different-sized pages since it calculates the
+ // offset of each page to scroll to before it updates the actual size of each page
+ // (which can change depending on the content if the contents aren't a fixed size).
+ // We work around this by having a minimum size on each widget page).
+ int widthSpecSize = Math.max(getSuggestedMinimumWidth(),
+ MeasureSpec.getSize(widthMeasureSpec));
+ int widthSpecMode = MeasureSpec.AT_MOST;
+ super.onMeasure(MeasureSpec.makeMeasureSpec(widthSpecSize, widthSpecMode),
+ heightMeasureSpec);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // We eat up the touch events here, since the PagedView (which uses the same swiping
+ // touch code as Workspace previously) uses onInterceptTouchEvent() to determine when
+ // the user is scrolling between pages. This means that if the pages themselves don't
+ // handle touch events, it gets forwarded up to PagedView itself, and it's own
+ // onTouchEvent() handling will prevent further intercept touch events from being called
+ // (it's the same view in that case). This is not ideal, but to prevent more changes,
+ // we just always mark the touch event as handled.
+ return super.onTouchEvent(event) || true;
+ }
+
+ @Override
+ protected boolean onSetAlpha(int alpha) {
+ return true;
+ }
+
+ @Override
+ public void setAlpha(float alpha) {
+ setChildrenAlpha(alpha);
+ super.setAlpha(alpha);
+ }
+
+ private void setChildrenAlpha(float alpha) {
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ getChildAt(i).setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public void removeAllViewsOnPage() {
+ removeAllViews();
+ }
+
+ @Override
+ public void removeViewOnPageAt(int index) {
+ removeViewAt(index);
+ }
+
+ @Override
+ public int getPageChildCount() {
+ return getChildCount();
+ }
+
+ @Override
+ public View getChildOnPageAt(int i) {
+ return getChildAt(i);
+ }
+
+ @Override
+ public int indexOfChildOnPage(View v) {
+ return indexOfChild(v);
+ }
+
+ public static class LayoutParams extends FrameLayout.LayoutParams {
+ public LayoutParams(int width, int height) {
+ super(width, height);
+ }
+ }
+}
diff --git a/src/com/android/launcher2/PagedViewIcon.java b/src/com/android/launcher2/PagedViewIcon.java
index 1366619..306ff9e 100644
--- a/src/com/android/launcher2/PagedViewIcon.java
+++ b/src/com/android/launcher2/PagedViewIcon.java
@@ -16,9 +16,8 @@
package com.android.launcher2;
-import com.android.launcher.R;
-
import android.animation.ObjectAnimator;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -31,9 +30,11 @@
import android.os.HandlerThread;
import android.os.Message;
import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
import android.widget.Checkable;
-import android.widget.TextView;
+import com.android.launcher.R;
/**
@@ -121,15 +122,15 @@
// Set up fade in/out constants
final Resources r = context.getResources();
- final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
+ final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha);
if (alpha > 0) {
- mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
- mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
- mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
+ mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f;
+ mCheckedFadeInDuration =
+ r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration);
+ mCheckedFadeOutDuration =
+ r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration);
}
- setFocusable(true);
- setBackgroundDrawable(null);
mHolographicOutlineView = new HolographicPagedViewIcon(context, this);
}
@@ -141,34 +142,51 @@
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 loadHolographicIcon() {
+ if (mHolographicOutline == null) {
+ mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
+ if (!queueHolographicOutlineCreation()) {
+ getHolographicOutlineView().invalidate();
+ }
+ }
+ }
+ public void clearHolographicIcon() {
+ mHolographicOutline = null;
+ getHolographicOutlineView().invalidate();
}
public void applyFromApplicationInfo(ApplicationInfo info, PagedViewIconCache cache,
boolean scaleUp, boolean createHolographicOutlines) {
+ mIconCache = cache;
+ mIconCacheKey = new PagedViewIconCache.Key(info);
mIcon = info.iconBitmap;
setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
setText(info.title);
setTag(info);
if (createHolographicOutlines) {
- mIconCache = cache;
- mIconCacheKey = new PagedViewIconCache.Key(info);
mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
- queueHolographicOutlineCreation();
+ if (!queueHolographicOutlineCreation()) {
+ getHolographicOutlineView().invalidate();
+ }
}
}
public void applyFromResolveInfo(ResolveInfo info, PackageManager packageManager,
PagedViewIconCache cache, IconCache modelIconCache, boolean createHolographicOutlines) {
- mIcon = Utilities.createIconBitmap(
- modelIconCache.getFullResIcon(info, packageManager), mContext);
+ ComponentName cn = new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
+ mIcon = modelIconCache.getIcon(cn, info);
setCompoundDrawablesWithIntrinsicBounds(null, new FastBitmapDrawable(mIcon), null, null);
setText(info.loadLabel(packageManager));
setTag(info);
@@ -177,7 +195,9 @@
mIconCache = cache;
mIconCacheKey = new PagedViewIconCache.Key(info);
mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
- queueHolographicOutlineCreation();
+ if (!queueHolographicOutlineCreation()) {
+ getHolographicOutlineView().invalidate();
+ }
}
}
@@ -210,12 +230,7 @@
Bitmap overlay = null;
// draw any blended overlays
- if (mCheckedOutline == null) {
- if (mHolographicOutline != null && mHolographicAlpha > 0) {
- mPaint.setAlpha(mHolographicAlpha);
- overlay = mHolographicOutline;
- }
- } else {
+ if (mCheckedOutline != null) {
mPaint.setAlpha(255);
overlay = mCheckedOutline;
}
@@ -239,12 +254,23 @@
}
@Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return FocusHelper.handlePagedViewIconKeyEvent(this, keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return FocusHelper.handlePagedViewIconKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ }
+
+ @Override
public boolean isChecked() {
return mIsChecked;
}
- @Override
- public void setChecked(boolean checked) {
+ void setChecked(boolean checked, boolean animate) {
if (mIsChecked != checked) {
mIsChecked = checked;
@@ -262,15 +288,24 @@
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 9b83f48..2ffa398 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -27,11 +27,16 @@
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;
import android.util.AttributeSet;
+import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Checkable;
@@ -52,9 +57,14 @@
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;
+ private String mDimensionsFormatString;
private int mAlpha = 255;
private int mHolographicAlpha;
@@ -81,8 +91,11 @@
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 +107,12 @@
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 +142,11 @@
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) {
@@ -131,14 +155,16 @@
// Set up fade in/out constants
final Resources r = context.getResources();
- final int alpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha);
+ final int alpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha);
if (alpha > 0) {
- mCheckedAlpha = r.getInteger(R.integer.icon_allAppsCustomizeFadeAlpha) / 256.0f;
- mCheckedFadeInDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeInTime);
- mCheckedFadeOutDuration = r.getInteger(R.integer.icon_allAppsCustomizeFadeOutTime);
+ mCheckedAlpha = r.getInteger(R.integer.config_dragAppsCustomizeIconFadeAlpha) / 256.0f;
+ mCheckedFadeInDuration =
+ r.getInteger(R.integer.config_dragAppsCustomizeIconFadeInDuration);
+ mCheckedFadeOutDuration =
+ r.getInteger(R.integer.config_dragAppsCustomizeIconFadeOutDuration);
}
+ mDimensionsFormatString = r.getString(R.string.widget_dims_format);
- setFocusable(true);
setWillNotDraw(false);
setClipToPadding(false);
}
@@ -156,13 +182,16 @@
FastBitmapDrawable preview, int maxWidth, int[] cellSpan,
PagedViewIconCache cache, boolean createHolographicOutline) {
final ImageView image = (ImageView) findViewById(R.id.widget_preview);
- image.setMaxWidth(maxWidth);
+ if (maxWidth > -1) {
+ 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);
final TextView dims = (TextView) findViewById(R.id.widget_dims);
- dims.setText(mContext.getString(R.string.widget_dims_format, cellSpan[0], cellSpan[1]));
+ dims.setText(String.format(mDimensionsFormatString, cellSpan[0], cellSpan[1]));
dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
if (createHolographicOutline) {
@@ -173,12 +202,35 @@
}
}
+ public void applyFromResolveInfo(PackageManager pm, ResolveInfo info,
+ FastBitmapDrawable preview, PagedViewIconCache cache, boolean createHolographicOutline){
+ final ImageView image = (ImageView) findViewById(R.id.widget_preview);
+ image.setImageDrawable(preview);
+ mPreviewImageView = image;
+ final TextView name = (TextView) findViewById(R.id.widget_name);
+ name.setText(info.loadLabel(pm));
+ name.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ final TextView dims = (TextView) findViewById(R.id.widget_dims);
+ if (dims != null) {
+ dims.setText(String.format(mDimensionsFormatString, 1, 1));
+ dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ }
+
+ if (createHolographicOutline) {
+ mIconCache = cache;
+ mIconCacheKey = new PagedViewIconCache.Key(info);
+ mHolographicOutline = mIconCache.getOutline(mIconCacheKey);
+ mPreview = preview;
+ }
+ }
+
public void applyFromWallpaperInfo(ResolveInfo info, PackageManager packageManager,
FastBitmapDrawable preview, int maxWidth, PagedViewIconCache cache,
boolean createHolographicOutline) {
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);
@@ -204,6 +256,28 @@
}
@Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (LauncherApplication.isScreenLarge()) {
+ return FocusHelper.handlePagedViewWidgetKeyEvent(this, keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ } else {
+ return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event)
+ || super.onKeyDown(keyCode, event);
+ }
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ if (LauncherApplication.isScreenLarge()) {
+ return FocusHelper.handlePagedViewWidgetKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ } else {
+ return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
+ }
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
if (mAlpha > 0) {
super.onDraw(canvas);
@@ -211,8 +285,15 @@
// 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 +338,7 @@
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 +356,24 @@
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/ShortcutInfo.java b/src/com/android/launcher2/ShortcutInfo.java
index 72f2d51..c0f80ae 100644
--- a/src/com/android/launcher2/ShortcutInfo.java
+++ b/src/com/android/launcher2/ShortcutInfo.java
@@ -148,12 +148,6 @@
return "ShortcutInfo(title=" + title.toString() + ")";
}
- @Override
- void unbind() {
- super.unbind();
- }
-
-
public static void dumpShortcutInfoList(String tag, String label,
ArrayList<ShortcutInfo> list) {
Log.d(tag, label + " size=" + list.size());
diff --git a/src/com/android/launcher2/ShortcutsAdapter.java b/src/com/android/launcher2/ShortcutsAdapter.java
index 93c500a..de73c3e 100644
--- a/src/com/android/launcher2/ShortcutsAdapter.java
+++ b/src/com/android/launcher2/ShortcutsAdapter.java
@@ -30,7 +30,7 @@
/**
* GridView adapter to show the list of applications and shortcuts
*/
-public class ShortcutsAdapter extends ArrayAdapter<ShortcutInfo> {
+public class ShortcutsAdapter extends ArrayAdapter<ShortcutInfo> {
private final LayoutInflater mInflater;
private final IconCache mIconCache;
diff --git a/src/com/android/launcher2/StrokedTextView.java b/src/com/android/launcher2/StrokedTextView.java
new file mode 100644
index 0000000..20f9f48
--- /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
deleted file mode 100644
index b362fbd..0000000
--- a/src/com/android/launcher2/UserFolder.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package com.android.launcher2;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-
-import com.android.launcher.R;
-
-/**
- * Folder which contains applications or shortcuts chosen by the user.
- *
- */
-public class UserFolder extends Folder implements DropTarget {
- private static final String TAG = "Launcher.UserFolder";
-
- public UserFolder(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * Creates a new UserFolder, inflated from R.layout.user_folder.
- *
- * @param context The application's context.
- *
- * @return A new UserFolder.
- */
- static UserFolder fromXml(Context context) {
- return (UserFolder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
- }
-
- public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- final ItemInfo item = (ItemInfo) dragInfo;
- final int itemType = item.itemType;
- return (itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
- itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT)
- && item.container != mInfo.id;
- }
-
- public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- ShortcutInfo item;
- if (dragInfo instanceof ApplicationInfo) {
- // Came from all apps -- make a copy
- item = ((ApplicationInfo)dragInfo).makeShortcut();
- } else {
- item = (ShortcutInfo)dragInfo;
- }
- ((ShortcutsAdapter)mContent.getAdapter()).add(item);
- LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
- }
-
- public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- }
-
- @Override
- public void onDropCompleted(View target, boolean success) {
- if (success) {
- ShortcutsAdapter adapter = (ShortcutsAdapter)mContent.getAdapter();
- adapter.remove(mDragItem);
- }
- }
-
- public boolean isDropEnabled() {
- return true;
- }
-
- void bind(FolderInfo info) {
- super.bind(info);
- setContentAdapter(new ShortcutsAdapter(mContext, ((UserFolderInfo) info).contents));
- }
-
- // When the folder opens, we need to refresh the GridView's selection by
- // forcing a layout
- @Override
- void onOpen() {
- super.onOpen();
- requestFocus();
- }
-
- @Override
- public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
- DragView dragView, Object dragInfo) {
- return null;
- }
-}
diff --git a/src/com/android/launcher2/UserFolderInfo.java b/src/com/android/launcher2/UserFolderInfo.java
deleted file mode 100644
index 0b8841c..0000000
--- a/src/com/android/launcher2/UserFolderInfo.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher2;
-
-import android.content.ContentValues;
-
-import java.util.ArrayList;
-
-/**
- * Represents a folder containing shortcuts or apps.
- */
-class UserFolderInfo extends FolderInfo {
- /**
- * The apps and shortcuts
- */
- ArrayList<ShortcutInfo> contents = new ArrayList<ShortcutInfo>();
-
- UserFolderInfo() {
- itemType = LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER;
- }
-
- /**
- * Add an app or shortcut
- *
- * @param item
- */
- public void add(ShortcutInfo item) {
- contents.add(item);
- }
-
- /**
- * Remove an app or shortcut. Does not change the DB.
- *
- * @param item
- */
- public void remove(ShortcutInfo item) {
- contents.remove(item);
- }
-
- @Override
- void onAddToDatabase(ContentValues values) {
- super.onAddToDatabase(values);
- values.put(LauncherSettings.Favorites.TITLE, title.toString());
- }
-}
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index 60f71f5..ba25893 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -16,6 +16,8 @@
package com.android.launcher2;
+import java.util.Random;
+
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -51,6 +53,7 @@
private static int sIconWidth = -1;
private static int sIconHeight = -1;
+ private static int sIconContentSize = -1;
private static int sIconTextureWidth = -1;
private static int sIconTextureHeight = -1;
@@ -90,6 +93,10 @@
static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
static int sColorIndex = 0;
+ static int getIconContentSize() {
+ return sIconContentSize;
+ }
+
/**
* Returns a bitmap suitable for the all apps view. The bitmap will be a power
* of two sized ARGB_8888 bitmap that can be used as a gl texture.
@@ -236,6 +243,9 @@
final float density = metrics.density;
sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
+ if (LauncherApplication.isScreenLarge()) {
+ sIconContentSize = (int) resources.getDimension(R.dimen.app_icon_content_size);
+ }
sIconTextureWidth = sIconTextureHeight = sIconWidth + 2;
sBlurPaint.setMaskFilter(new BlurMaskFilter(5 * density, BlurMaskFilter.Blur.NORMAL));
@@ -381,4 +391,8 @@
}
return n;
}
+
+ static int generateRandomId() {
+ return new Random(System.currentTimeMillis()).nextInt(1 << 24);
+ }
}
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 0daed37..bc15b32 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,14 +16,14 @@
package com.android.launcher2;
-import com.android.launcher.R;
-import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
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;
@@ -38,7 +38,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -50,10 +49,10 @@
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
-import android.net.Uri;
import android.os.IBinder;
import android.os.Parcelable;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.Display;
@@ -62,12 +61,13 @@
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;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
+import com.android.launcher.R;
+import com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData;
/**
* The workspace is a wide area with a wallpaper and a finite number of pages.
@@ -75,7 +75,8 @@
* 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 +109,11 @@
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,10 +125,12 @@
private float[] mCustomizationDrawerTransformedPos = new float[2];
private final WallpaperManager mWallpaperManager;
+ private IBinder mWindowToken;
private int mDefaultPage;
private boolean mIsDragInProcess = false;
+ private boolean mIsDraggingOverIcon = false;
/**
* CellInfo for the cell that is currently being dragged
@@ -151,12 +155,13 @@
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
private int[] mTempCell = new int[2];
private int[] mTempEstimate = new int[2];
- private float[] mTempOriginXY = new float[2];
+ private float[] mDragViewVisualCenter = new float[2];
private float[] mTempDragCoordinates = new float[2];
private float[] mTempTouchCoordinates = new float[2];
private float[] mTempCellLayoutCenterCoordinates = new float[2];
private float[] mTempDragBottomRightCoordinates = new float[2];
private Matrix mTempInverseMatrix = new Matrix();
+ private int[] mTempLocation = new int[2];
private SpringLoadedDragController mSpringLoadedDragController;
@@ -209,6 +214,7 @@
WallpaperOffsetInterpolator mWallpaperOffset;
boolean mUpdateWallpaperOffsetImmediately = false;
boolean mSyncWallpaperOffsetWithScroll = true;
+ private Runnable mDelayedResizeRunnable;
// info about the last drag
private DragView mLastDragView;
@@ -217,6 +223,8 @@
private int mLastDragXOffset;
private int mLastDragYOffset;
+ private ArrayList<FolderIcon> mFolderOuterRings = new ArrayList<FolderIcon>();
+
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
private float mYDown;
@@ -224,9 +232,6 @@
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.
*
@@ -248,16 +253,60 @@
super(context, attrs, defStyle);
mContentIsRefreshable = false;
- if (!LauncherApplication.isScreenXLarge()) {
+ if (!LauncherApplication.isScreenLarge()) {
mFadeInAdjacentScreens = false;
}
mWallpaperManager = WallpaperManager.getInstance(context);
+ int cellCountX = DEFAULT_CELL_COUNT_X;
+ int cellCountY = DEFAULT_CELL_COUNT_Y;
+
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.Workspace, defStyle, 0);
- int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X);
- int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y);
+
+ if (LauncherApplication.isScreenLarge()) {
+ final Resources res = context.getResources();
+ final DisplayMetrics dm = res.getDisplayMetrics();
+ float widthDp = dm.widthPixels / dm.density;
+ float heightDp = dm.heightPixels / dm.density;
+
+ final float statusBarHeight = res.getDimension(R.dimen.status_bar_height);
+ TypedArray actionBarSizeTypedArray =
+ context.obtainStyledAttributes(new int[] { android.R.attr.actionBarSize });
+ float actionBarHeight = actionBarSizeTypedArray.getDimension(0, 0f);
+
+ if (heightDp > widthDp) {
+ float temp = widthDp;
+ widthDp = heightDp;
+ heightDp = temp;
+ }
+ int cellCountXLand = 1;
+ int cellCountXPort = 1;
+ while (2*mPageSpacing + CellLayout.widthInLandscape(res, cellCountXLand + 1) <= widthDp) {
+ cellCountXLand++;
+ }
+ while (CellLayout.widthInPortrait(res, cellCountXPort + 1) <= heightDp) {
+ cellCountXPort++;
+ }
+ cellCountX = Math.min(cellCountXLand, cellCountXPort);
+
+ int cellCountYLand = 1;
+ int cellCountYPort = 1;
+ while (statusBarHeight + actionBarHeight +
+ CellLayout.heightInLandscape(res, cellCountYLand + 1) <= heightDp) {
+ cellCountYLand++;
+ }
+ while (statusBarHeight + actionBarHeight +
+ CellLayout.heightInPortrait(res, cellCountYPort + 1) <= widthDp) {
+ cellCountYPort++;
+ }
+ cellCountY = Math.min(cellCountYLand, cellCountYPort);
+ }
+
+ // if the value is manually specified, use that instead
+ cellCountX = a.getInt(R.styleable.Workspace_cellCountX, cellCountX);
+ cellCountY = a.getInt(R.styleable.Workspace_cellCountY, cellCountY);
mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
a.recycle();
@@ -265,6 +314,9 @@
setHapticFeedbackEnabled(false);
initWorkspace();
+
+ // Disable multitouch across the workspace/all apps/customize tray
+ setMotionEventSplittingEnabled(true);
}
/**
@@ -329,55 +381,51 @@
@Override
protected int getScrollMode() {
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
return SmoothPagedView.X_LARGE_MODE;
} else {
return SmoothPagedView.DEFAULT_MODE;
}
}
- @Override
- public void addView(View child, int index, LayoutParams params) {
+ private void onAddView(View child) {
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
- ((CellLayout) child).setOnInterceptTouchListener(this);
+ CellLayout cl = ((CellLayout) child);
+ cl.setOnInterceptTouchListener(this);
+ cl.setOnClickListener(this);
+ cl.setClickable(true);
+ cl.enableHardwareLayers();
+ }
+
+ @Override
+ public void addView(View child, int index, LayoutParams params) {
+ onAddView(child);
super.addView(child, index, params);
}
@Override
public void addView(View child) {
- if (!(child instanceof CellLayout)) {
- throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
- }
- ((CellLayout) child).setOnInterceptTouchListener(this);
+ onAddView(child);
super.addView(child);
}
@Override
public void addView(View child, int index) {
- if (!(child instanceof CellLayout)) {
- throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
- }
- ((CellLayout) child).setOnInterceptTouchListener(this);
+ onAddView(child);
super.addView(child, index);
}
@Override
public void addView(View child, int width, int height) {
- if (!(child instanceof CellLayout)) {
- throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
- }
- ((CellLayout) child).setOnInterceptTouchListener(this);
+ onAddView(child);
super.addView(child, width, height);
}
@Override
public void addView(View child, LayoutParams params) {
- if (!(child instanceof CellLayout)) {
- throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
- }
- ((CellLayout) child).setOnInterceptTouchListener(this);
+ onAddView(child);
super.addView(child, params);
}
@@ -418,8 +466,8 @@
return folders;
}
- boolean isDefaultPageShowing() {
- return mCurrentPage == mDefaultPage;
+ boolean isTouchActive() {
+ return mTouchState != TOUCH_STATE_REST;
}
/**
@@ -471,6 +519,10 @@
lp.cellVSpan = spanY;
}
+ if (spanX < 0 && spanY < 0) {
+ lp.isLockedToGrid = false;
+ }
+
// Get the canonical child id to uniquely represent this view in this screen
int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY);
boolean markCellsAsOccupied = !(child instanceof Folder);
@@ -520,16 +572,25 @@
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 +614,7 @@
}
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)
@@ -623,6 +683,11 @@
}
mOverScrollMaxBackgroundAlpha = 0.0f;
mOverScrollPageIndex = -1;
+
+ if (mDelayedResizeRunnable != null) {
+ mDelayedResizeRunnable.run();
+ mDelayedResizeRunnable = null;
+ }
}
@Override
@@ -689,7 +754,11 @@
// 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 +776,15 @@
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 +798,6 @@
// 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,12 +807,13 @@
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;
}
private void syncWallpaperOffsetWithScroll() {
- if (LauncherApplication.isScreenXLarge()) {
+ final boolean enableWallpaperEffects = isHardwareAccelerated();
+ if (enableWallpaperEffects) {
mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
}
}
@@ -761,14 +834,13 @@
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 +963,7 @@
}
}
- public void showOutlines() {
+ void showOutlines() {
if (!mIsSmall && !mIsInUnshrinkAnimation) {
if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel();
if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel();
@@ -901,7 +973,7 @@
}
}
- public void hideOutlines() {
+ void hideOutlines() {
if (!mIsSmall && !mIsInUnshrinkAnimation) {
if (mChildrenOutlineFadeInAnimation != null) mChildrenOutlineFadeInAnimation.cancel();
if (mChildrenOutlineFadeOutAnimation != null) mChildrenOutlineFadeOutAnimation.cancel();
@@ -912,6 +984,12 @@
}
}
+ public void showOutlinesTemporarily() {
+ if (!mIsPageMoving && !isTouchActive()) {
+ snapToPage(mCurrentPage);
+ }
+ }
+
public void setChildrenOutlineAlpha(float alpha) {
mChildrenOutlineAlpha = alpha;
for (int i = 0; i < getChildCount(); i++) {
@@ -924,6 +1002,13 @@
return mChildrenOutlineAlpha;
}
+ void disableBackground() {
+ mDrawBackground = false;
+ }
+ void enableBackground() {
+ mDrawBackground = true;
+ }
+
private void showBackgroundGradientForAllApps() {
showBackgroundGradient();
mDrawCustomizeTrayBackground = false;
@@ -938,7 +1023,12 @@
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 +1038,22 @@
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() {
@@ -1014,6 +1111,11 @@
@Override
protected void screenScrolled(int screenCenter) {
+ // If the screen is not xlarge, then don't rotate the CellLayouts
+ // NOTE: If we don't update the side pages alpha, then we should not hide the side pages.
+ // see unshrink().
+ if (!LauncherApplication.isScreenLarge()) return;
+
final int halfScreenSize = getMeasuredWidth() / 2;
for (int i = 0; i < getChildCount(); i++) {
@@ -1050,8 +1152,13 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mWindowToken = getWindowToken();
computeScroll();
- mDragController.setWindowToken(getWindowToken());
+ mDragController.setWindowToken(mWindowToken);
+ }
+
+ protected void onDetachedFromWindow() {
+ mWindowToken = null;
}
@Override
@@ -1081,12 +1188,22 @@
}
}
+ public void showFolderAccept(FolderIcon fi) {
+ mFolderOuterRings.add(fi);
+ }
+
+ public void hideFolderAccept(FolderIcon fi) {
+ if (mFolderOuterRings.contains(fi)) {
+ mFolderOuterRings.remove(fi);
+ }
+ }
+
@Override
protected void onDraw(Canvas canvas) {
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
@@ -1116,6 +1233,30 @@
mBackground.draw(canvas);
}
}
+
+ // The folder outer / inner ring image(s)
+ for (int i = 0; i < mFolderOuterRings.size(); i++) {
+
+ // Draw outer ring
+ FolderIcon fi = mFolderOuterRings.get(i);
+ Drawable d = FolderIcon.sFolderOuterRingDrawable;
+ int width = (int) (d.getIntrinsicWidth() * fi.getOuterRingScale());
+ int height = (int) (d.getIntrinsicHeight() * fi.getOuterRingScale());
+ fi.getFolderLocation(mTempLocation);
+ int x = mTempLocation[0] + mScrollX - width / 2;
+ int y = mTempLocation[1] + mScrollY - height / 2;
+ d.setBounds(x, y, x + width, y + height);
+ d.draw(canvas);
+
+ // Draw inner ring
+ d = FolderIcon.sFolderInnerRingDrawable;
+ width = (int) (fi.getMeasuredWidth() * fi.getInnerRingScale());
+ height = (int) (fi.getMeasuredHeight() * fi.getInnerRingScale());
+ x = mTempLocation[0] + mScrollX - width / 2;
+ y = mTempLocation[1] + mScrollY - height / 2;
+ d.setBounds(x, y, x + width, y + height);
+ d.draw(canvas);
+ }
super.onDraw(canvas);
}
@@ -1126,9 +1267,11 @@
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);
@@ -1184,6 +1327,14 @@
}
@Override
+ public int getDescendantFocusability() {
+ if (mIsSmall) {
+ return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ }
+ return super.getDescendantFocusability();
+ }
+
+ @Override
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
if (!mLauncher.isAllAppsVisible()) {
final Folder openFolder = getOpenFolder();
@@ -1195,19 +1346,6 @@
}
}
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps
- // ie when you click on a mini-screen, it zooms back to that screen)
- if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) {
- return false;
- }
- }
-
- return super.dispatchTouchEvent(ev);
- }
-
void enableChildrenCache(int fromPage, int toPage) {
if (fromPage > toPage) {
final int temp = fromPage;
@@ -1237,27 +1375,32 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- AllAppsPagedView allApps = (AllAppsPagedView)
- mLauncher.findViewById(R.id.all_apps_paged_view);
-
- if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN
- && allApps != null) {
- if (ev.getAction() == MotionEvent.ACTION_UP &&
- allApps.getTouchState() == TOUCH_STATE_REST) {
-
- // Cancel any scrolling that is in progress.
- if (!mScroller.isFinished()) {
- mScroller.abortAnimation();
- }
- setCurrentPage(mCurrentPage);
-
- if (mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
- mLauncher.showWorkspace(true);
- }
- allApps.onTouchEvent(ev);
- return true;
+ if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
+ PagedView appsPane;
+ if (LauncherApplication.isScreenLarge()) {
+ appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view);
} else {
- return allApps.onTouchEvent(ev);
+ appsPane = (PagedView) mLauncher.findViewById(R.id.apps_customize_pane_content);
+ }
+
+ if (appsPane != null) {
+ if (ev.getAction() == MotionEvent.ACTION_UP &&
+ appsPane.getTouchState() == TOUCH_STATE_REST) {
+
+ // Cancel any scrolling that is in progress.
+ if (!mScroller.isFinished()) {
+ mScroller.abortAnimation();
+ }
+ setCurrentPage(mCurrentPage);
+
+ if (mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
+ mLauncher.showWorkspace(true);
+ }
+ appsPane.onTouchEvent(ev);
+ return true;
+ } else {
+ return appsPane.onTouchEvent(ev);
+ }
}
}
return super.onTouchEvent(ev);
@@ -1317,16 +1460,21 @@
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
- // visible in the bottom of the screen, and then want to fade to being invisible.
- // After spring loaded mode ends, this method was getting called twice, the first time
- // with BOTTOM_VISIBLE (what we want) and a second time with BOTTOM_INVISIBLE (not
- // what we want). As a temporary solution, we just change the second call to BOTTOM_VISIBLE
- if (mIsSmall && mShrinkState == ShrinkState.BOTTOM_VISIBLE) {
- shrinkState = ShrinkState.BOTTOM_VISIBLE;
- }
if (mFirstLayout) {
// (mFirstLayout == "first layout has not happened yet")
// if we get a call to shrink() as part of our initialization (for example, if
@@ -1393,14 +1541,12 @@
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;
if (shrinkState == ShrinkState.BOTTOM_HIDDEN || shrinkState == ShrinkState.BOTTOM_VISIBLE) {
- duration = res.getInteger(R.integer.config_allAppsWorkspaceShrinkTime);
+ duration = res.getInteger(R.integer.config_appsCustomizeWorkspaceShrinkTime);
} else {
duration = res.getInteger(R.integer.config_customizeWorkspaceShrinkTime);
}
@@ -1446,6 +1592,11 @@
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();
@@ -1480,30 +1631,35 @@
float offsetFromCenter = (wallpaperTravelHeight / (float) mWallpaperHeight) / 2f;
boolean isLandscape = display.getWidth() > display.getHeight();
- switch (shrinkState) {
- // animating in
- case TOP:
- // customize
- wallpaperOffset = 0.5f + offsetFromCenter;
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.46f : 0.44f);
- break;
- case MIDDLE:
- case SPRING_LOADED:
- wallpaperOffset = 0.5f;
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.34f : 0.32f);
- break;
- case BOTTOM_HIDDEN:
- case BOTTOM_VISIBLE:
- // allapps
- wallpaperOffset = 0.5f - offsetFromCenter;
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.34f : 0.32f);
- break;
+ final boolean enableWallpaperEffects = isHardwareAccelerated();
+ if (enableWallpaperEffects) {
+ switch (shrinkState) {
+ // animating in
+ case TOP:
+ // customize
+ wallpaperOffset = 0.5f + offsetFromCenter;
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.46f : 0.44f);
+ break;
+ case MIDDLE:
+ case SPRING_LOADED:
+ wallpaperOffset = 0.5f;
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.34f : 0.32f);
+ break;
+ case BOTTOM_HIDDEN:
+ case BOTTOM_VISIBLE:
+ // allapps
+ wallpaperOffset = 0.5f - offsetFromCenter;
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.34f : 0.32f);
+ break;
+ }
}
setLayoutScale(1.0f);
if (animated) {
- mWallpaperOffset.setHorizontalCatchupConstant(0.46f);
- mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
+ if (enableWallpaperEffects) {
+ mWallpaperOffset.setHorizontalCatchupConstant(0.46f);
+ mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
+ }
mSyncWallpaperOffsetWithScroll = false;
@@ -1515,15 +1671,19 @@
final float oldVerticalWallpaperOffset = getVerticalWallpaperOffset();
final float newHorizontalWallpaperOffset = 0.5f;
final float newVerticalWallpaperOffset = wallpaperOffset;
- animWithInterpolator.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
+ animWithInterpolator.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
+ if (b == 0f) {
+ // an optimization, and required for correct behavior.
+ return;
+ }
fastInvalidate();
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
- setHorizontalWallpaperOffset(
+ if (enableWallpaperEffects) {
+ setHorizontalWallpaperOffset(
a * oldHorizontalWallpaperOffset + b * newHorizontalWallpaperOffset);
- setVerticalWallpaperOffset(
+ setVerticalWallpaperOffset(
a * oldVerticalWallpaperOffset + b * newVerticalWallpaperOffset);
+ }
for (int i = 0; i < screenCount; i++) {
final CellLayout cl = (CellLayout) getChildAt(i);
cl.fastInvalidate();
@@ -1541,7 +1701,7 @@
mAnimator.playTogether(animWithInterpolator);
mAnimator.addListener(mShrinkAnimationListener);
mAnimator.start();
- } else {
+ } else if (enableWallpaperEffects) {
setVerticalWallpaperOffset(wallpaperOffset);
setHorizontalWallpaperOffset(0.5f);
updateWallpaperOffsetImmediately();
@@ -1628,39 +1788,57 @@
for (int i = 0; i < screenCount; i++) {
CellLayout cl = (CellLayout) getChildAt(i);
cl.setIsDragOccuring(isDragHappening);
- switch (state) {
- case TOP:
- cl.setIsDefaultDropTarget(i == mCurrentPage);
- case BOTTOM_HIDDEN:
- case BOTTOM_VISIBLE:
- case SPRING_LOADED:
- if (state != ShrinkState.TOP) {
- cl.setIsDefaultDropTarget(false);
- }
- if (!isDragHappening) {
- // even if a drag isn't happening, we don't want to show a screen as
- // accepting drops if it doesn't have at least one free cell
- spanX = 1;
- spanY = 1;
- }
- // the page accepts drops if we can find at least one empty spot
- cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY));
- break;
- default:
- throw new RuntimeException("Unhandled ShrinkState " + state);
+ if (state == null) {
+ // If we are not in a shrunken state, mark all cell layouts as droppable (if they
+ // have the space)
+ cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY));
+ } else {
+ switch (state) {
+ case TOP:
+ cl.setIsDefaultDropTarget(i == mCurrentPage);
+ case BOTTOM_HIDDEN:
+ case BOTTOM_VISIBLE:
+ case SPRING_LOADED:
+ if (state != ShrinkState.TOP) {
+ cl.setIsDefaultDropTarget(false);
+ }
+ if (!isDragHappening) {
+ // even if a drag isn't happening, we don't want to show a screen as
+ // accepting drops if it doesn't have at least one free cell
+ spanX = 1;
+ spanY = 1;
+ }
+ // the page accepts drops if we can find at least one empty spot
+ cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY));
+ break;
+ default:
+ throw new RuntimeException("Unhandled ShrinkState " + state);
+ }
}
}
}
/*
- *
- * We call these methods (onDragStartedWithItemSpans/onDragStartedWithItemMinSize) whenever we
- * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace
- *
- * These methods mark the appropriate pages as accepting drops (which alters their visual
- * appearance).
- *
- */
+ *
+ * We call these methods (onDragStartedWithItemSpans/onDragStartedWithSize) whenever we
+ * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace
+ *
+ * These methods mark the appropriate pages as accepting drops (which alters their visual
+ * appearance).
+ *
+ */
+ public void onDragStartedWithItem(View v) {
+ mIsDragInProcess = true;
+
+ final Canvas canvas = new Canvas();
+
+ // We need to add extra padding to the bitmap to make room for the glow effect
+ final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS;
+
+ // The outline is used to visualize where the item will land if dropped
+ mDragOutline = createDragOutline(v, canvas, bitmapPadding);
+ }
+
public void onDragStartedWithItemSpans(int spanX, int spanY, Bitmap b) {
mIsDragInProcess = true;
@@ -1670,9 +1848,11 @@
final int bitmapPadding = HolographicOutlineHelper.MAX_OUTER_BLUR_RADIUS;
CellLayout cl = (CellLayout) getChildAt(0);
- int[] desiredSize = cl.cellSpansToSize(spanX, spanY);
+
+ int[] size = cl.cellSpansToSize(spanX, spanY);
+
// The outline is used to visualize where the item will land if dropped
- mDragOutline = createDragOutline(b, canvas, bitmapPadding, desiredSize[0], desiredSize[1]);
+ mDragOutline = createDragOutline(b, canvas, bitmapPadding, size[0], size[1]);
updateWhichPagesAcceptDropsDuringDrag(mShrinkState, spanX, spanY);
}
@@ -1719,6 +1899,11 @@
}
}
+ public void exitWidgetResizeMode() {
+ DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+ dragLayer.clearAllResizeFrames();
+ }
+
void unshrink(boolean animated) {
unshrink(animated, false);
}
@@ -1762,20 +1947,34 @@
for (int i = 0; i < screenCount; i++) {
final CellLayout cl = (CellLayout)getChildAt(i);
- float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
+ float finalAlphaValue = 0f;
+ float rotation = 0f;
+ if (LauncherApplication.isScreenLarge()) {
+ finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
+
+ if (i < mCurrentPage) {
+ rotation = WORKSPACE_ROTATION;
+ } else if (i > mCurrentPage) {
+ rotation = -WORKSPACE_ROTATION;
+ }
+ } else {
+ // Don't hide the side panes on the phone if we don't also update the side pages
+ // alpha. See screenScrolled().
+ finalAlphaValue = 1f;
+ }
float finalAlphaMultiplierValue =
((i == mCurrentPage) && (mShrinkState != ShrinkState.SPRING_LOADED)) ?
0.0f : 1.0f;
- float rotation = 0.0f;
- if (i < mCurrentPage) {
- rotation = WORKSPACE_ROTATION;
- } else if (i > mCurrentPage) {
- rotation = -WORKSPACE_ROTATION;
+ float translation = 0f;
+
+ // If the screen is not xlarge, then don't rotate the CellLayouts
+ // NOTE: If we don't update the side pages alpha, then we should not hide the side
+ // pages. see unshrink().
+ if (LauncherApplication.isScreenLarge()) {
+ translation = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
}
- float translation = getOffsetXForRotation(rotation, cl.getWidth(), cl.getHeight());
-
oldAlphas[i] = cl.getAlpha();
newAlphas[i] = finalAlphaValue;
if (animated) {
@@ -1808,52 +2007,62 @@
}
Display display = mLauncher.getWindowManager().getDefaultDisplay();
boolean isLandscape = display.getWidth() > display.getHeight();
- switch (mShrinkState) {
- // animating out
- case TOP:
- // customize
- if (animated) {
- mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.65f : 0.62f);
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.65f : 0.62f);
- mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
- }
- break;
- case MIDDLE:
- case SPRING_LOADED:
- if (animated) {
- mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.49f : 0.46f);
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.49f : 0.46f);
- mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
- }
- break;
- case BOTTOM_HIDDEN:
- case BOTTOM_VISIBLE:
- // all apps
- if (animated) {
- mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.65f : 0.65f);
- mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.65f : 0.65f);
- mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
- }
- break;
+ final boolean enableWallpaperEffects = isHardwareAccelerated();
+ if (enableWallpaperEffects) {
+ switch (mShrinkState) {
+ // animating out
+ case TOP:
+ // customize
+ if (animated) {
+ mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.65f : 0.62f);
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.65f : 0.62f);
+ mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
+ }
+ break;
+ case MIDDLE:
+ case SPRING_LOADED:
+ if (animated) {
+ mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.49f : 0.46f);
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.49f : 0.46f);
+ mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
+ }
+ break;
+ case BOTTOM_HIDDEN:
+ case BOTTOM_VISIBLE:
+ // all apps
+ if (animated) {
+ mWallpaperOffset.setHorizontalCatchupConstant(isLandscape ? 0.65f : 0.65f);
+ mWallpaperOffset.setVerticalCatchupConstant(isLandscape ? 0.65f : 0.65f);
+ mWallpaperOffset.setOverrideHorizontalCatchupConstant(true);
+ }
+ break;
+ }
}
if (animated) {
ValueAnimator animWithInterpolator =
ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
animWithInterpolator.setInterpolator(mZoomInInterpolator);
- final float oldHorizontalWallpaperOffset = getHorizontalWallpaperOffset();
- final float oldVerticalWallpaperOffset = getVerticalWallpaperOffset();
- final float newHorizontalWallpaperOffset = wallpaperOffsetForCurrentScroll();
- final float newVerticalWallpaperOffset = 0.5f;
- animWithInterpolator.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
+ final float oldHorizontalWallpaperOffset = enableWallpaperEffects ?
+ getHorizontalWallpaperOffset() : 0;
+ final float oldVerticalWallpaperOffset = enableWallpaperEffects ?
+ getVerticalWallpaperOffset() : 0;
+ final float newHorizontalWallpaperOffset = enableWallpaperEffects ?
+ wallpaperOffsetForCurrentScroll() : 0;
+ final float newVerticalWallpaperOffset = enableWallpaperEffects ? 0.5f : 0;
+ animWithInterpolator.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
+ if (b == 0f) {
+ // an optimization, but not required
+ return;
+ }
fastInvalidate();
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
- setHorizontalWallpaperOffset(
- a * oldHorizontalWallpaperOffset + b * newHorizontalWallpaperOffset);
- setVerticalWallpaperOffset(
- a * oldVerticalWallpaperOffset + b * newVerticalWallpaperOffset);
+ if (enableWallpaperEffects) {
+ setHorizontalWallpaperOffset(a * oldHorizontalWallpaperOffset
+ + b * newHorizontalWallpaperOffset);
+ setVerticalWallpaperOffset(a * oldVerticalWallpaperOffset
+ + b * newVerticalWallpaperOffset);
+ }
for (int i = 0; i < screenCount; i++) {
final CellLayout cl = (CellLayout) getChildAt(i);
cl.fastInvalidate();
@@ -1875,11 +2084,13 @@
ValueAnimator rotationAnim =
ValueAnimator.ofFloat(0f, 1f).setDuration(duration);
rotationAnim.setInterpolator(new DecelerateInterpolator(2.0f));
- rotationAnim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
+ rotationAnim.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
// 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]);
@@ -1893,9 +2104,11 @@
mAnimator.addListener(mUnshrinkAnimationListener);
mAnimator.start();
} else {
- setHorizontalWallpaperOffset(wallpaperOffsetForCurrentScroll());
- setVerticalWallpaperOffset(0.5f);
- updateWallpaperOffsetImmediately();
+ if (enableWallpaperEffects) {
+ setHorizontalWallpaperOffset(wallpaperOffsetForCurrentScroll());
+ setVerticalWallpaperOffset(0.5f);
+ updateWallpaperOffsetImmediately();
+ }
}
}
@@ -1916,7 +2129,8 @@
v.getDrawingRect(clipRect);
// For a TextView, adjust the clip rect so that we don't include the text label
- if (v instanceof BubbleTextView) {
+ if (v instanceof FolderIcon) {
+ } else if (v instanceof BubbleTextView) {
final BubbleTextView tv = (BubbleTextView) v;
clipRect.bottom = tv.getExtendedPaddingTop() - (int) BubbleTextView.PADDING_V +
tv.getLayout().getLineTop(0);
@@ -2047,12 +2261,24 @@
final int bmpWidth = b.getWidth();
final int bmpHeight = b.getHeight();
+
child.getLocationOnScreen(mTempXY);
final int screenX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2;
final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2;
+
+ Rect dragRect = null;
+ if ((child instanceof BubbleTextView) && !(child instanceof FolderIcon)) {
+ int iconSize = getResources().getDimensionPixelSize(R.dimen.app_icon_size);
+ int top = child.getPaddingTop();
+ int left = (bmpWidth - iconSize) / 2;
+ int right = left + iconSize;
+ int bottom = top + iconSize;
+ dragRect = new Rect(left, top, right, bottom);
+ }
+
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, dragRect);
b.recycle();
}
@@ -2074,15 +2300,15 @@
final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
// Based on the position of the drag view, find the top left of the original view
- int viewX = dragViewX + (dragView.getWidth() - child.getWidth()) / 2;
- int viewY = dragViewY + (dragView.getHeight() - child.getHeight()) / 2;
- viewX += getResources().getInteger(R.integer.config_dragViewOffsetX);
- viewY += getResources().getInteger(R.integer.config_dragViewOffsetY);
+ int viewX = dragViewX + (dragView.getWidth() - child.getMeasuredWidth()) / 2;
+ int viewY = dragViewY + (dragView.getHeight() - child.getMeasuredHeight()) / 2;
+
+ CellLayout layout = (CellLayout) parent;
// Set its old pos (in the new parent's coordinates); it will be animated
// in animateViewIntoPosition after the next layout pass
- lp.oldX = viewX - (parent.getLeft() - mScrollX);
- lp.oldY = viewY - (parent.getTop() - mScrollY);
+ lp.oldX = viewX - (layout.getLeft() + layout.getLeftPadding() - mScrollX);
+ lp.oldY = viewY - (layout.getTop() + layout.getTopPadding() - mScrollY);
}
/*
@@ -2094,8 +2320,8 @@
final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
// Convert the animation params to be relative to the Workspace, not the CellLayout
- final int fromX = lp.oldX + parent.getLeft();
- final int fromY = lp.oldY + parent.getTop();
+ final int fromX = lp.oldX + parent.getLeft() + parent.getLeftPadding();
+ final int fromY = lp.oldY + parent.getTop() + parent.getTopPadding();
final int dx = lp.x - lp.oldX;
final int dy = lp.y - lp.oldY;
@@ -2178,19 +2404,80 @@
return true;
}
+ boolean willCreateUserFolder(ItemInfo info, CellLayout target, int originX, int originY) {
+ mTargetCell = findNearestArea(originX, originY,
+ 1, 1, target,
+ mTargetCell);
+
+ View v = target.getChildAt(mTargetCell[0], mTargetCell[1]);
+ boolean hasntMoved = mDragInfo != null && (mDragInfo.cellX == mTargetCell[0] &&
+ mDragInfo.cellY == mTargetCell[1]);
+
+ if (v == null || hasntMoved) return false;
+
+ boolean aboveShortcut = (v.getTag() instanceof ShortcutInfo);
+ boolean willBecomeShortcut =
+ (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
+ info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT);
+
+ return (aboveShortcut && willBecomeShortcut);
+ }
+
+ boolean createUserFolderIfNecessary(View newView, CellLayout target, int originX,
+ int originY, boolean external) {
+ int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
+ int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
+
+ // First we find the cell nearest to point at which the item is dropped, without
+ // any consideration to whether there is an item there.
+ mTargetCell = findNearestArea(originX, originY,
+ spanX, spanY, target,
+ mTargetCell);
+
+ View v = target.getChildAt(mTargetCell[0], mTargetCell[1]);
+ boolean hasntMoved = mDragInfo != null && (mDragInfo.cellX == mTargetCell[0] &&
+ mDragInfo.cellY == mTargetCell[1]);
+
+ if (v == null || hasntMoved) return false;
+
+ final int screen = (mTargetCell == null) ?
+ mDragInfo.screen : indexOfChild(target);
+
+ boolean aboveShortcut = (v.getTag() instanceof ShortcutInfo);
+ boolean willBecomeShortcut = (newView.getTag() instanceof ShortcutInfo);
+
+ if (aboveShortcut && willBecomeShortcut) {
+ ShortcutInfo sourceInfo = (ShortcutInfo) newView.getTag();
+ ShortcutInfo destInfo = (ShortcutInfo) v.getTag();
+ // if the drag started here, we need to remove it from the workspace
+ if (!external) {
+ int fromScreen = mDragInfo.screen;
+ CellLayout sourceLayout = (CellLayout) getChildAt(fromScreen);
+ sourceLayout.removeView(newView);
+ }
+
+ target.removeView(v);
+ FolderIcon fi = mLauncher.addFolder(screen, mTargetCell[0], mTargetCell[1]);
+ destInfo.cellX = -1;
+ destInfo.cellY = -1;
+ sourceInfo.cellX = -1;
+ sourceInfo.cellY = -1;
+ fi.addItem(destInfo);
+ fi.addItem(sourceInfo);
+ return true;
+ }
+ return false;
+ }
+
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;
+ mDragViewVisualCenter = getDragViewVisualCenter(x, y, xOffset, yOffset, dragView,
+ mDragViewVisualCenter);
- if (mIsSmall || mIsInUnshrinkAnimation) {
- // get originX and originY in the local coordinate system of the screen
- mTempOriginXY[0] = originX;
- mTempOriginXY[1] = originY;
- mapPointFromSelfToChild(mDragTargetLayout, mTempOriginXY);
- originX = (int)mTempOriginXY[0];
- originY = (int)mTempOriginXY[1];
+ // We want the point to be mapped to the dragTarget.
+ if (mDragTargetLayout != null) {
+ mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null);
}
// When you are in customization mode and drag to a particular screen, make that the
@@ -2203,20 +2490,25 @@
}
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[] { (int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1] };
+ if (LauncherApplication.isScreenLarge() && (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, dragView);
} else if (mDragInfo != null) {
final View cell = mDragInfo.cell;
CellLayout dropTargetLayout = mDragTargetLayout;
+ boolean dropInscrollArea = false;
// Handle the case where the user drops when in the scroll area.
// This is treated as a drop on the adjacent page.
if (dropTargetLayout == null && mInScrollArea) {
+ dropInscrollArea = true;
if (mPendingScrollDirection == DragController.SCROLL_LEFT) {
dropTargetLayout = (CellLayout) getChildAt(mCurrentPage - 1);
} else if (mPendingScrollDirection == DragController.SCROLL_RIGHT) {
@@ -2226,13 +2518,22 @@
if (dropTargetLayout != null) {
// Move internally
- mTargetCell = findNearestVacantArea(originX, originY,
- mDragInfo.spanX, mDragInfo.spanY, cell, dropTargetLayout,
- mTargetCell);
-
final int screen = (mTargetCell == null) ?
mDragInfo.screen : indexOfChild(dropTargetLayout);
+ // If the item being dropped is a shortcut and the nearest drop cell also contains
+ // a shortcut, then create a folder with the two shortcuts.
+ if (!dropInscrollArea && createUserFolderIfNecessary(cell, dropTargetLayout,
+ (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], false)) {
+ return;
+ }
+
+ // Aside from the special case where we're dropping a shortcut onto a shortcut,
+ // we need to find the nearest cell location that is vacant
+ mTargetCell = findNearestVacantArea((int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1], mDragInfo.spanX, mDragInfo.spanY, cell,
+ dropTargetLayout, mTargetCell);
+
if (screen != mCurrentPage) {
snapToPage(screen);
}
@@ -2254,6 +2555,34 @@
cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen,
mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
+ if (cell instanceof LauncherAppWidgetHostView) {
+ 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) {
+ final Runnable resizeRunnable = new Runnable() {
+ public void run() {
+ DragLayer dragLayer = (DragLayer)
+ mLauncher.findViewById(R.id.drag_layer);
+ dragLayer.addResizeFrame(info, hostView,
+ cellLayout);
+ }
+ };
+ post(new Runnable() {
+ public void run() {
+ if (!isPageMoving()) {
+ resizeRunnable.run();
+ } else {
+ mDelayedResizeRunnable = resizeRunnable;
+ }
+ }
+ });
+ }
+ }
+
LauncherModel.moveItemInDatabase(mLauncher, info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
lp.cellX, lp.cellY);
@@ -2262,14 +2591,30 @@
final CellLayout parent = (CellLayout) cell.getParent().getParent();
+ int loc[] = new int[2];
+ getViewLocationRelativeToSelf(dragView, loc);
+
// Prepare it to be animated into its new position
// This must be called after the view has been re-parented
- setPositionForDropAnimation(dragView, originX, originY, parent, cell);
+ setPositionForDropAnimation(dragView, loc[0], loc[1], parent, cell);
boolean animateDrop = !mWasSpringLoadedOnDragExit;
parent.onDropChild(cell, animateDrop);
}
}
+ private void getViewLocationRelativeToSelf(View v, int[] location) {
+ getLocationOnScreen(location);
+ int x = location[0];
+ int y = location[1];
+
+ v.getLocationOnScreen(location);
+ int vX = location[0];
+ int vY = location[1];
+
+ location[0] = vX - x;
+ location[1] = vY - y;
+ }
+
public void onDragEnter(DragSource source, int x, int y, int xOffset,
int yOffset, DragView dragView, Object dragInfo) {
mDragTargetLayout = null; // Reset the drag state
@@ -2292,7 +2637,7 @@
// 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 +2763,7 @@
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
@@ -2498,11 +2843,11 @@
xy[1] -= (mScrollY - v.getTop());
}
- static private float squaredDistance(float[] point1, float[] point2) {
+ static private float squaredDistance(float[] point1, float[] point2) {
float distanceX = point1[0] - point2[0];
float distanceY = point2[1] - point2[1];
return distanceX * distanceX + distanceY * distanceY;
- }
+ }
/*
*
@@ -2600,32 +2945,79 @@
return bestMatchingScreen;
}
+ // This is used to compute the visual center of the dragView. This point is then
+ // used to visualize drop locations and determine where to drop an item. The idea is that
+ // the visual center represents the user's interpretation of where the item is, and hence
+ // is the appropriate point to use when determining drop location.
+ private float[] getDragViewVisualCenter(int x, int y, int xOffset, int yOffset,
+ DragView dragView, float[] recycle) {
+ float res[];
+ if (recycle == null) {
+ res = new float[2];
+ } else {
+ res = recycle;
+ }
+
+ // First off, the drag view has been shifted in a way that is not represented in the
+ // x and y values or the x/yOffsets. Here we account for that shift.
+ x += getResources().getDimensionPixelSize(R.dimen.dragViewOffsetX);
+ y += getResources().getDimensionPixelSize(R.dimen.dragViewOffsetY);
+
+ // These represent the visual top and left of drag view if a dragRect was provided.
+ // If a dragRect was not provided, then they correspond to the actual view left and
+ // top, as the dragRect is in that case taken to be the entire dragView.
+ // R.dimen.dragViewOffsetY.
+ int left = x - xOffset;
+ int top = y - yOffset;
+
+ // In order to find the visual center, we shift by half the dragRect
+ res[0] = left + dragView.getDragRegion().width() / 2;
+ res[1] = top + dragView.getDragRegion().height() / 2;
+
+ return res;
+ }
+
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
// When touch is inside the scroll area, skip dragOver actions for the current screen
if (!mInScrollArea) {
CellLayout layout;
- int originX = x - xOffset;
- int originY = y - yOffset;
+ int left = x - xOffset;
+ int top = y - yOffset;
+
+ mDragViewVisualCenter = getDragViewVisualCenter(x, y, xOffset, yOffset, dragView,
+ mDragViewVisualCenter);
+
boolean shrunken = mIsSmall || mIsInUnshrinkAnimation;
if (shrunken) {
mLastDragView = dragView;
- mLastDragOriginX = originX;
- mLastDragOriginY = originY;
+ mLastDragOriginX = left;
+ mLastDragOriginY = top;
mLastDragXOffset = xOffset;
mLastDragYOffset = yOffset;
- layout = findMatchingPageForDragOver(dragView, originX, originY, xOffset, yOffset);
+ layout = findMatchingPageForDragOver(dragView, left, top, xOffset, yOffset);
- if (layout != mDragTargetLayout) {
+ if (layout != null && layout != mDragTargetLayout) {
if (mDragTargetLayout != null) {
mDragTargetLayout.setIsDragOverlapping(false);
mSpringLoadedDragController.onDragExit();
}
mDragTargetLayout = layout;
- if (mDragTargetLayout != null && mDragTargetLayout.getAcceptsDrops()) {
- mDragTargetLayout.setIsDragOverlapping(true);
- mSpringLoadedDragController.onDragEnter(
- mDragTargetLayout, mShrinkState == ShrinkState.SPRING_LOADED);
+
+ // Workaround the fact that we don't actually want spring-loaded mode in phone
+ // UI yet.
+ if (LauncherApplication.isScreenLarge()) {
+ // 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);
+ }
}
}
} else {
@@ -2654,37 +3046,23 @@
}
}
- if (source instanceof AllAppsPagedView) {
- // This is a hack to fix the point used to determine which cell an icon from
- // the all apps screen is over
- if (item != null && item.spanX == 1 && layout != null) {
- int dragRegionLeft = (dragView.getWidth() - layout.getCellWidth()) / 2;
-
- originX += dragRegionLeft - dragView.getDragRegionLeft();
- if (dragView.getDragRegionWidth() != layout.getCellWidth()) {
- dragView.setDragRegion(dragView.getDragRegionLeft(),
- dragView.getDragRegionTop(),
- layout.getCellWidth(),
- dragView.getDragRegionHeight());
- }
- }
- } else if (source == this) {
- // When dragging from the workspace, the drag view is slightly bigger than
- // the original view, and offset vertically. Adjust to account for this.
- final View origView = mDragInfo.cell;
- originX += (dragView.getMeasuredWidth() - origView.getWidth()) / 2;
- originY += (dragView.getMeasuredHeight() - origView.getHeight()) / 2
- + dragView.getOffsetY();
- }
-
if (mDragTargetLayout != null) {
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);
+ // We want the point to be mapped to the dragTarget.
+ mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null);
+ ItemInfo info = (ItemInfo) dragInfo;
+
+ if (!willCreateUserFolder(info, mDragTargetLayout,
+ (int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1])) {
+ mIsDraggingOverIcon = false;
+ mDragTargetLayout.visualizeDropLocation(child, mDragOutline,
+ (int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1],
+ item.spanX, item.spanY);
+ } else if (!mIsDraggingOverIcon) {
+ mIsDraggingOverIcon = true;
+ mDragTargetLayout.clearDragOutlines();
+ }
}
}
}
@@ -2723,13 +3101,18 @@
*/
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();
return false;
}
+ private void onDropExternal(int[] touchXY, Object dragInfo,
+ CellLayout cellLayout, boolean insertAtFirst) {
+ onDropExternal(touchXY, dragInfo, cellLayout, insertAtFirst, null);
+ }
+
/**
* Drop an item that didn't originate on one of the workspace screens.
* It may have come from Launcher (e.g. from all apps or customize), or it may have
@@ -2738,24 +3121,17 @@
* 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,
- CellLayout cellLayout, boolean insertAtFirst) {
+ private void onDropExternal(int[] touchXY, Object dragInfo,
+ CellLayout cellLayout, boolean insertAtFirst, DragView dragView) {
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);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
- mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY);
- break;
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY);
break;
@@ -2778,23 +3154,26 @@
view = mLauncher.createShortcut(R.layout.application, cellLayout,
(ShortcutInfo) info);
break;
- case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
+ case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
- cellLayout, (UserFolderInfo) info, mIconCache);
+ cellLayout, (FolderInfo) info, mIconCache);
break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
- mTargetCell = new int[2];
- if (x != -1 && y != -1) {
- // when dragging and dropping, just find the closest free spot
+ // If the item being dropped is a shortcut and the nearest drop cell also contains
+ // a shortcut, then create a folder with the two shortcuts.
+ if (touchXY != null && createUserFolderIfNecessary(view, cellLayout, touchXY[0],
+ touchXY[1], true)) {
+ return;
+ }
- // 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);
+ mTargetCell = new int[2];
+ if (touchXY != null) {
+ // when dragging and dropping, just find the closest free spot
+ mTargetCell = findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, null, cellLayout,
+ mTargetCell);
} else {
cellLayout.findCellForSpan(mTargetCell, 1, 1);
}
@@ -2804,6 +3183,15 @@
cellLayout.onDropChild(view, animateDrop);
cellLayout.animateDrop();
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
+ cellLayout.getChildrenLayout().measureChild(view);
+
+ if (dragView != null) {
+ // we have the visual center of the drag view, we need to find the actual
+ // left and top of the dragView.
+ int loc[] = new int[2];
+ getViewLocationRelativeToSelf(dragView, loc);
+ setPositionForDropAnimation(dragView, loc[0], loc[1], cellLayout, view);
+ }
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
@@ -2815,11 +3203,8 @@
* 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);
}
/**
@@ -2834,16 +3219,24 @@
/**
* Calculate the nearest cell where the given object would be dropped.
+ *
+ * pixelX and pixelY should be in the coordinate system of layout
*/
private int[] findNearestVacantArea(int pixelX, int pixelY,
int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) {
-
- int localPixelX = pixelX - (layout.getLeft() - mScrollX);
- int localPixelY = pixelY - (layout.getTop() - mScrollY);
-
- // Find the best target drop location
return layout.findNearestVacantArea(
- localPixelX, localPixelY, spanX, spanY, ignoreView, recycle);
+ pixelX, pixelY, spanX, spanY, ignoreView, recycle);
+ }
+
+ /**
+ * Calculate the nearest cell where the given object would be dropped.
+ *
+ * pixelX and pixelY should be in the coordinate system of layout
+ */
+ private int[] findNearestArea(int pixelX, int pixelY,
+ int spanX, int spanY, CellLayout layout, int[] recycle) {
+ return layout.findNearestArea(
+ pixelX, pixelY, spanX, spanY, recycle);
}
void setLauncher(Launcher launcher) {
@@ -2864,7 +3257,7 @@
/**
* 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 +3324,10 @@
mDragTargetLayout.onDragExit();
mDragTargetLayout = null;
}
+ // In portrait, need to redraw the edge glow when entering the scroll area
+ if (getHeight() > getWidth()) {
+ invalidate();
+ }
}
}
}
@@ -2941,6 +3338,12 @@
((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
@@ -2986,6 +3389,21 @@
return null;
}
+ void clearDropTargets() {
+ final int screenCount = getChildCount();
+
+ for (int i = 0; i < screenCount; i++) {
+ final CellLayout layoutParent = (CellLayout) getChildAt(i);
+ final ViewGroup layout = layoutParent.getChildrenLayout();
+ int childCount = layout.getChildCount();
+ for (int j = 0; j < childCount; j++) {
+ View v = layout.getChildAt(j);
+ if (v instanceof DropTarget) {
+ mDragController.removeDropTarget((DropTarget) v);
+ }
+ }
+ }
+ }
void removeItems(final ArrayList<ApplicationInfo> apps) {
final int screenCount = getChildCount();
@@ -3026,8 +3444,8 @@
}
}
}
- } else if (tag instanceof UserFolderInfo) {
- final UserFolderInfo info = (UserFolderInfo) tag;
+ } else if (tag instanceof FolderInfo) {
+ final FolderInfo info = (FolderInfo) tag;
final ArrayList<ShortcutInfo> contents = info.contents;
final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1);
final int contentsCount = contents.size();
@@ -3055,20 +3473,6 @@
if (folder != null)
folder.notifyDataSetChanged();
}
- } else if (tag instanceof LiveFolderInfo) {
- final LiveFolderInfo info = (LiveFolderInfo) tag;
- final Uri uri = info.uri;
- final ProviderInfo providerInfo = manager.resolveContentProvider(
- uri.getAuthority(), 0);
-
- if (providerInfo != null) {
- for (String packageName: packageNames) {
- if (packageName.equals(providerInfo.packageName)) {
- LauncherModel.deleteItemFromDatabase(mLauncher, info);
- childrenToRemove.add(view);
- }
- }
- }
} else if (tag instanceof LauncherAppWidgetInfo) {
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
final AppWidgetProviderInfo provider =
diff --git a/src/com/android/launcher2/allapps.rs b/src/com/android/launcher2/allapps.rs
index bebc04d..4ea1aee 100644
--- a/src/com/android/launcher2/allapps.rs
+++ b/src/com/android/launcher2/allapps.rs
@@ -298,7 +298,7 @@
vpConstants->ImgSize.y = rsAllocationGetDimY(gSelectedIconTexture);
vpConstants->Position.y = y - (rsAllocationGetDimY(gSelectedIconTexture)
- rsAllocationGetDimY(gIcons[iconNum])) * 0.5f;
- rsAllocationMarkDirty(g_VPConstAlloc);
+ rsgAllocationSyncAll(g_VPConstAlloc);
rsgDrawMesh(gSMCell);
}
@@ -306,7 +306,7 @@
vpConstants->ImgSize.x = rsAllocationGetDimX(gIcons[iconNum]);
vpConstants->ImgSize.y = rsAllocationGetDimY(gIcons[iconNum]);
vpConstants->Position.y = y - 0.2f;
- rsAllocationMarkDirty(g_VPConstAlloc);
+ rsgAllocationSyncAll(g_VPConstAlloc);
rsgBindTexture(gPFTexMip, 0, gIcons[iconNum]);
rsgDrawMesh(gSMCell);
@@ -314,7 +314,7 @@
vpConstants->ImgSize.x = rsAllocationGetDimX(gLabels[iconNum]);
vpConstants->ImgSize.y = rsAllocationGetDimY(gLabels[iconNum]);
vpConstants->Position.y = y - 64.f - 0.2f;
- rsAllocationMarkDirty(g_VPConstAlloc);
+ rsgAllocationSyncAll(g_VPConstAlloc);
rsgBindTexture(gPFTexMipAlpha, 0, gLabels[iconNum]);
rsgDrawMesh(gSMCell);
}