am 1f9fb1d1: (-s ours) am 2b06c5b5: am 12ac0d60: Setting tab bar widths automatically
* commit '1f9fb1d1d98b2837bbaf21a8cb50014e60369f45':
Setting tab bar widths automatically
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 19c8fd5..c2b2c65 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -20,6 +20,17 @@
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();
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-hdpi/folder_bg.9.png b/res/drawable-hdpi/folder_bg.9.png
new file mode 100644
index 0000000..6f1bbe5
--- /dev/null
+++ b/res/drawable-hdpi/folder_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/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-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-xlarge-hdpi/ic_generic_search.png b/res/drawable-large-hdpi/ic_generic_search.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_generic_search.png
rename to 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-xlarge-hdpi/ic_voice_search.png b/res/drawable-large-hdpi/ic_voice_search.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/ic_voice_search.png
rename to 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-xlarge-hdpi/widget_resize_frame_holo.9.png b/res/drawable-large-hdpi/widget_resize_frame_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/widget_resize_frame_holo.9.png
rename to res/drawable-large-hdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_bottom.png b/res/drawable-large-hdpi/widget_resize_handle_bottom.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/widget_resize_handle_bottom.png
rename to res/drawable-large-hdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_left.png b/res/drawable-large-hdpi/widget_resize_handle_left.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/widget_resize_handle_left.png
rename to res/drawable-large-hdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_right.png b/res/drawable-large-hdpi/widget_resize_handle_right.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/widget_resize_handle_right.png
rename to res/drawable-large-hdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-xlarge-hdpi/widget_resize_handle_top.png b/res/drawable-large-hdpi/widget_resize_handle_top.png
similarity index 100%
rename from res/drawable-xlarge-hdpi/widget_resize_handle_top.png
rename to 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-xlarge-mdpi/ic_generic_search.png b/res/drawable-large-mdpi/ic_generic_search.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_generic_search.png
rename to 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-xlarge-mdpi/ic_voice_search.png b/res/drawable-large-mdpi/ic_voice_search.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/ic_voice_search.png
rename to 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-xlarge-mdpi/widget_resize_frame_holo.9.png b/res/drawable-large-mdpi/widget_resize_frame_holo.9.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/widget_resize_frame_holo.9.png
rename to res/drawable-large-mdpi/widget_resize_frame_holo.9.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_bottom.png b/res/drawable-large-mdpi/widget_resize_handle_bottom.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/widget_resize_handle_bottom.png
rename to res/drawable-large-mdpi/widget_resize_handle_bottom.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_left.png b/res/drawable-large-mdpi/widget_resize_handle_left.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/widget_resize_handle_left.png
rename to res/drawable-large-mdpi/widget_resize_handle_left.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_right.png b/res/drawable-large-mdpi/widget_resize_handle_right.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/widget_resize_handle_right.png
rename to res/drawable-large-mdpi/widget_resize_handle_right.png
Binary files differ
diff --git a/res/drawable-xlarge-mdpi/widget_resize_handle_top.png b/res/drawable-large-mdpi/widget_resize_handle_top.png
similarity index 100%
rename from res/drawable-xlarge-mdpi/widget_resize_handle_top.png
rename to 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-mdpi/folder_bg.9.png b/res/drawable-mdpi/folder_bg.9.png
new file mode 100644
index 0000000..6f1bbe5
--- /dev/null
+++ b/res/drawable-mdpi/folder_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/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-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/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..b814462 100644
--- a/res/layout-land/user_folder.xml
+++ b/res/layout-land/user_folder.xml
@@ -14,8 +14,11 @@
limitations under the License.
-->
-<com.android.launcher2.UserFolder xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical">
+<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/folder_bg">
<Button
android:id="@+id/folder_close"
@@ -29,17 +32,23 @@
<FrameLayout
android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:background="@drawable/box_launcher_bottom">
+ android:layout_height="0dip"
+ android:layout_weight="1">
- <GridView
+ <com.android.launcher2.CellLayout
android:id="@id/folder_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="#ff333333"
+ launcher:cellWidth="@dimen/folder_cell_width"
+ launcher:cellHeight="@dimen/folder_cell_height"
+ launcher:xAxisStartPadding="0dip"
+ launcher:xAxisEndPadding="0dip"
+ launcher:yAxisStartPadding="0dip"
+ launcher:yAxisEndPadding="0dip"
+
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="insideInset"
android:drawSelectorOnTop="false"
@@ -49,4 +58,4 @@
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-xlarge-land/workspace_screen.xml b/res/layout-large-land/workspace_screen.xml
similarity index 100%
rename from res/layout-xlarge-land/workspace_screen.xml
rename to res/layout-large-land/workspace_screen.xml
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-xlarge-port/workspace_screen.xml b/res/layout-large-port/workspace_screen.xml
similarity index 100%
rename from res/layout-xlarge-port/workspace_screen.xml
rename to res/layout-large-port/workspace_screen.xml
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/all_apps_tabbed.xml b/res/layout-large/all_apps_tabbed.xml
similarity index 90%
rename from res/layout-xlarge/all_apps_tabbed.xml
rename to res/layout-large/all_apps_tabbed.xml
index 9937338..b00b3c3 100644
--- a/res/layout-xlarge/all_apps_tabbed.xml
+++ b/res/layout-large/all_apps_tabbed.xml
@@ -32,7 +32,7 @@
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"
@@ -50,7 +50,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:visibility="invisible"/>
+ android:visibility="invisible"
+ android:background="@drawable/focusable_view_bg"
+ android:focusable="true" />
<TextView
android:id="@+id/market_button"
android:layout_width="wrap_content"
@@ -64,7 +66,9 @@
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" />
</FrameLayout>
<com.android.launcher2.DeleteZone
android:id="@+id/all_apps_delete_zone"
@@ -84,7 +88,10 @@
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"
diff --git a/res/layout-xlarge/button_bar.xml b/res/layout-large/button_bar.xml
similarity index 78%
rename from res/layout-xlarge/button_bar.xml
rename to res/layout-large/button_bar.xml
index 5c96c5c..62115f7 100644
--- a/res/layout-xlarge/button_bar.xml
+++ b/res/layout-large/button_bar.xml
@@ -15,31 +15,34 @@
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
+ 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: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:layout_toRightOf="@+id/search_button"
android:paddingTop="@dimen/toolbar_button_vertical_padding"
android:paddingBottom="@dimen/toolbar_button_vertical_padding"
@@ -52,7 +55,7 @@
android:id="@+id/voice_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_toRightOf="@id/search_divider"
+ 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"
@@ -60,35 +63,12 @@
android:src="@drawable/ic_voice_search"
android:background="@drawable/button_bg"
android:onClick="onClickVoiceButton"
- android:focusable="true"
- android:clickable="true"/>
-
- <ImageView
- android:id="@+id/configure_button"
- android:src="@drawable/ic_home_add_holo_dark"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
- android:paddingRight="@dimen/toolbar_button_horizontal_padding"
- android:paddingTop="@dimen/toolbar_button_vertical_padding"
- android:paddingBottom="@dimen/toolbar_button_vertical_padding"
- android:background="@drawable/button_bg"
android:focusable="true"
- android:clickable="true" />
- <ImageView
- android:id="@+id/divider"
- android:src="@drawable/divider_launcher_holo"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_toLeftOf="@id/configure_button"
- android:paddingTop="@dimen/toolbar_button_vertical_padding"
- android:paddingBottom="@dimen/toolbar_button_vertical_padding"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_voice_search_button" />
- android:focusable="false"
- android:clickable="true" />
+ <!-- AllApps icon -->
<com.android.launcher2.StrokedTextView
android:id="@+id/all_apps_button"
android:text="@string/all_apps_button_label"
@@ -96,7 +76,7 @@
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: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"
@@ -117,16 +97,38 @@
android:shadowRadius="2.5"
android:focusable="true"
- android:clickable="true" />
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_all_apps_button" />
+
<ImageView
- android:id="@+id/divider_during_drag"
+ 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:layout_toLeftOf="@+id/configure_button"
android:paddingTop="@dimen/toolbar_button_vertical_padding"
android:paddingBottom="@dimen/toolbar_button_vertical_padding"
- android:visibility="gone" />
+
+ 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"
@@ -134,12 +136,12 @@
android:drawableLeft="@drawable/delete_zone_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignRight="@id/configure_button"
+ 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:background="@drawable/button_bg"
android:gravity="center_horizontal|center_vertical"
android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
@@ -150,5 +152,8 @@
android:shadowRadius="2.0"
android:visibility="gone"
- launcher:direction="horizontal" />
-</RelativeLayout>
\ No newline at end of file
+ launcher:direction="horizontal"
+
+ android:focusable="true"
+ android:contentDescription="@string/accessibility_delete_button" />
+</RelativeLayout>
diff --git a/res/layout-xlarge/customization_drawer.xml b/res/layout-large/customization_drawer.xml
similarity index 91%
rename from res/layout-xlarge/customization_drawer.xml
rename to res/layout-large/customization_drawer.xml
index 98fc9d9..d8db066 100644
--- a/res/layout-xlarge/customization_drawer.xml
+++ b/res/layout-large/customization_drawer.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent">
<!-- The layout_width of this RelativeLayout gets overwritten in
CustomizeTrayTabHost.onFinishInflate -->
- <TabWidget
+ <com.android.launcher2.FocusOnlyTabWidget
android:id="@android:id/tabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -32,7 +32,7 @@
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
- android:layout_height="@dimen/customization_drawer_content_height">
+ android:layout_height="match_parent">
<com.android.launcher2.CustomizePagedView
android:id="@+id/customization_drawer_tab_contents"
android:layout_width="match_parent"
@@ -47,7 +47,8 @@
launcher:pageLayoutPaddingTop="40dp"
launcher:pageLayoutPaddingBottom="25dp"
launcher:pageLayoutPaddingLeft="20dp"
- launcher:pageLayoutPaddingRight="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 94%
rename from res/layout-xlarge/customize_paged_view_wallpaper.xml
rename to res/layout-large/customize_paged_view_wallpaper.xml
index 8c5abc8..d6284c2 100644
--- a/res/layout-xlarge/customize_paged_view_wallpaper.xml
+++ b/res/layout-large/customize_paged_view_wallpaper.xml
@@ -25,7 +25,10 @@
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
diff --git a/res/layout-xlarge/customize_paged_view_widget.xml b/res/layout-large/customize_paged_view_widget.xml
similarity index 95%
rename from res/layout-xlarge/customize_paged_view_widget.xml
rename to res/layout-large/customize_paged_view_widget.xml
index c0b4552..35791f5 100644
--- a/res/layout-xlarge/customize_paged_view_widget.xml
+++ b/res/layout-large/customize_paged_view_widget.xml
@@ -25,7 +25,10 @@
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
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-xlarge/launcher.xml b/res/layout-large/launcher.xml
similarity index 91%
rename from res/layout-xlarge/launcher.xml
rename to res/layout-large/launcher.xml
index acf62f9..6c6fecf 100644
--- a/res/layout-xlarge/launcher.xml
+++ b/res/layout-large/launcher.xml
@@ -20,7 +20,8 @@
android:id="@+id/drag_layer"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:focusable="false">
<!-- The workspace contains 5 screens of cells -->
<com.android.launcher2.Workspace
@@ -41,22 +42,24 @@
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
</com.android.launcher2.Workspace>
- <include
- layout="@layout/all_apps_tabbed"
- android:id="@+id/all_apps_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="top" />
-
<include layout="@layout/button_bar"
android:id="@+id/all_apps_button_cluster"
android:layout_width="fill_parent"
android:layout_height="?android:attr/actionBarSize"
android:layout_gravity="top" />
+ <include
+ layout="@layout/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: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..4901eb2 100644
--- a/res/layout-port/user_folder.xml
+++ b/res/layout-port/user_folder.xml
@@ -14,12 +14,15 @@
limitations under the License.
-->
-<com.android.launcher2.UserFolder xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical">
-
+<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/folder_bg">
+
<Button
android:id="@+id/folder_close"
- android:background="@drawable/box_launcher_top"
+ android:background="@drawable/box_launcher_top"
android:gravity="left|center_vertical"
android:textSize="14sp"
android:textColor="#404040"
@@ -29,23 +32,30 @@
<FrameLayout
android:layout_width="match_parent"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:background="@drawable/box_launcher_bottom">
- <GridView
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <com.android.launcher2.CellLayout
android:id="@id/folder_content"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="match_parent"
android:cacheColorHint="#ff333333"
+ launcher:cellWidth="@dimen/folder_cell_width"
+ launcher:cellHeight="@dimen/folder_cell_height"
+ launcher:xAxisStartPadding="0dip"
+ launcher:xAxisEndPadding="0dip"
+ launcher:yAxisStartPadding="0dip"
+ launcher:yAxisEndPadding="0dip"
+
android:scrollbarAlwaysDrawVerticalTrack="true"
android:scrollbarStyle="insideInset"
android:drawSelectorOnTop="false"
android:listSelector="@drawable/grid_selector"
android:verticalSpacing="10dip"
- android:numColumns="4" />
+ android:numColumns="5" />
</FrameLayout>
-</com.android.launcher2.UserFolder>
+</com.android.launcher2.Folder>
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/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 77%
copy from res/layout-xlarge/customize_paged_view_wallpaper.xml
copy to res/layout/apps_customize_wallpaper.xml
index 8c5abc8..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,22 +17,24 @@
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_width="match_parent"
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"
- <!-- 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: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" />
@@ -46,13 +48,13 @@
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:layout_weight="0"
- android:gravity="left"
+ 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 76%
copy from res/layout-xlarge/customize_paged_view_widget.xml
copy to res/layout/apps_customize_widget.xml
index c0b4552..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,42 +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_width="match_parent"
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_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:layout_weight="0"
- 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:layout_weight="0"
- android:gravity="left"
+ android:gravity="left|bottom"
android:textColor="#FFFFFFFF"
android:textSize="14sp"
@@ -71,7 +63,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
- android:gravity="left"
+ 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 df0a210..cb4c1f3 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -67,6 +67,11 @@
<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>
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 5be82f1..0f0f07d 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -67,6 +67,11 @@
<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>
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 56ada67..85058ba 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -67,6 +67,11 @@
<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>
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 47fb726..af04cb6 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -67,6 +67,11 @@
<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>
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 f481234..10bd77f 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -67,6 +67,11 @@
<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>
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 fdb2a41..87124a3 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -67,6 +67,11 @@
<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>
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 5e9b644..59ef926 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-en-rGB-xlarge/strings.xml b/res/values-en-rGB-large/strings.xml
similarity index 100%
rename from res/values-en-rGB-xlarge/strings.xml
rename to res/values-en-rGB-large/strings.xml
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 7334133..f07752c 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -67,6 +67,11 @@
<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>
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 eadcbae..46781f1 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 90b4e1d..3d162b9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -67,6 +67,11 @@
<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>
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 0d53ea5..1170d79 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -67,6 +67,11 @@
<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>
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 7b02c8d..4e40e56 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -67,6 +67,11 @@
<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>
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 7ff39d7..83d71d8 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -67,6 +67,11 @@
<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>
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 ea09db0..34487a5 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -67,6 +67,11 @@
<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>
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 77d9dda..dfa267b 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -67,6 +67,11 @@
<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>
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 a7ed856..d9a6d28 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-it-xlarge/strings.xml b/res/values-it-large/strings.xml
similarity index 100%
rename from res/values-it-xlarge/strings.xml
rename to res/values-it-large/strings.xml
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 003db6f..0a1f4fd 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -67,6 +67,11 @@
<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>
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 75df245..535cf73 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -67,6 +67,11 @@
<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>
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 ee6ab83..4b2d31d 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -67,6 +67,11 @@
<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>
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 f2b8b0c..9f6ee4a 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -67,6 +67,11 @@
<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>
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-xlarge-land/dimens.xml b/res/values-large-land/dimens.xml
similarity index 93%
rename from res/values-xlarge-land/dimens.xml
rename to res/values-large-land/dimens.xml
index b44a94a..8d25555 100644
--- a/res/values-xlarge-land/dimens.xml
+++ b/res/values-large-land/dimens.xml
@@ -27,8 +27,6 @@
<dimen name="customization_drawer_height">480dp</dimen>
<dimen name="customization_drawer_content_height">420dp</dimen>
- <dimen name="customization_drawer_content_min_width">952dp</dimen>
- <dimen name="customization_drawer_tab_widget_width">952dp</dimen>
<integer name="all_apps_view_cellCountX">7</integer>
<integer name="all_apps_view_cellCountY">5</integer>
diff --git a/res/values-xlarge-port/dimens.xml b/res/values-large-port/dimens.xml
similarity index 93%
rename from res/values-xlarge-port/dimens.xml
rename to res/values-large-port/dimens.xml
index bb410b1..e696e34 100644
--- a/res/values-xlarge-port/dimens.xml
+++ b/res/values-large-port/dimens.xml
@@ -27,8 +27,6 @@
<dimen name="customization_drawer_height">800dp</dimen>
<dimen name="customization_drawer_content_height">420dp</dimen>
- <dimen name="customization_drawer_content_min_width">640dp</dimen>
- <dimen name="customization_drawer_tab_widget_width">700dp</dimen>
<integer name="all_apps_view_cellCountX">5</integer>
<integer name="all_apps_view_cellCountY">7</integer>
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 88%
rename from res/values-xlarge/dimens.xml
rename to res/values-large/dimens.xml
index 2b97697..11f85ab 100644
--- a/res/values-xlarge/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -15,6 +15,8 @@
-->
<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>
@@ -40,7 +42,6 @@
<dimen name="allAppsSmallScreenVerticalMarginLandscape">30dip</dimen>
<dimen name="allAppsSmallScreenVerticalMarginPortrait">60dip</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>
@@ -62,4 +63,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 acf0e27..e84360d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -67,6 +67,11 @@
<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>
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 9c1b389..963c332 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -67,6 +67,11 @@
<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>
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 ccdab7e..382bac4 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -67,6 +67,11 @@
<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>
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 3d7c7ac..abcf29a 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -67,6 +67,11 @@
<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">"Apps beheren"</string>
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 f116165..97b54af 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -67,6 +67,11 @@
<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>
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 a3a5a8d..71f634d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 55deb94..2714fde 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-rm/strings.xml b/res/values-rm/strings.xml
index 1b5729b..a8453ed 100644
--- a/res/values-rm/strings.xml
+++ b/res/values-rm/strings.xml
@@ -85,6 +85,16 @@
<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>
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 3a72c51..6bed5d0 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -67,6 +67,11 @@
<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>
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 912c3f4..0456e4c 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -67,6 +67,11 @@
<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>
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 3cadf3b..064309d 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -67,6 +67,11 @@
<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>
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 daf0899..78b5187 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -67,6 +67,11 @@
<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>
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 1d92080..cbc4bf2 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -67,6 +67,11 @@
<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>
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 8094f05..68859e3 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -67,6 +67,11 @@
<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>
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 26c33c9..1562135 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -67,6 +67,11 @@
<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>
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 f21dc3c..50ed317 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -67,6 +67,11 @@
<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>
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 bf80bf5..2057828 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -67,6 +67,11 @@
<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>
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 267ca88..b3f0846 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-vi-xlarge/strings.xml b/res/values-vi-large/strings.xml
similarity index 100%
rename from res/values-vi-xlarge/strings.xml
rename to res/values-vi-large/strings.xml
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index d3f549f..9238c4a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml
deleted file mode 100644
index 56c7bc6..0000000
--- a/res/values-xlarge/config.xml
+++ /dev/null
@@ -1,78 +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">1000</integer>
- <integer name="config_allAppsFadeInTime">250</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>
- <integer name="config_customizeFadeInTime">800</integer>
-
- <!-- Duration in milliseconds of the all apps zoom-out animation -->
- <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
- <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_allAppsFadeOutTime">500</integer>
- <integer name="config_customizeWorkspaceShrinkTime">800</integer>
- <integer name="config_allAppsWorkspaceShrinkTime">1000</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>
-
- <!-- 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 a3dc212..b2f228c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -67,6 +67,11 @@
<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>
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 2274274..f172ef6 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -67,6 +67,11 @@
<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>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 2be5999..75b93bf 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -104,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 c56a8ce..0aa1ee4 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>
@@ -30,6 +55,9 @@
<integer name="config_dropAnimMaxDuration">400</integer>
+ <!-- The duration of the UserFolder opening and closing animation -->
+ <integer name="config_folderAnimDuration">150</integer>
+
<!-- The distance at which the animation should take the max duration -->
<integer name="config_dropAnimMaxDist">800</integer>
@@ -38,8 +66,4 @@
than the view itself (workspaceScreenBitmapCacheScale) -->
<integer name="config_workspaceScreenBitmapCacheScale">20</integer>
<integer name="config_maxScaleForUsingWorkspaceScreenBitmapCache">50</integer>
-
- <style name="config_orientation">
- <item name="@android:screenOrientation">nosensor</item>
- </style>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index d6cd3ee..62e55d2 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,13 @@
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>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index eedbd6a..9ad3e24 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -151,6 +151,17 @@
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>
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 1cbb999..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,11 +204,6 @@
}
@Override
- public void setDragController(DragController dragger) {
- mDragController = dragger;
- }
-
- @Override
public void onDragViewVisible() {
}
@@ -341,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 29f49af..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);
}
@@ -691,10 +692,12 @@
int screenX = mMotionDownRawX - (bmp.getWidth() / 2);
int screenY = mMotionDownRawY - bmp.getHeight();
+ 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;
}
@@ -737,16 +740,13 @@
}
@Override
- public void setDragController(DragController dragger) {
- mDragController = dragger;
- }
-
- @Override
public void onDragViewVisible() {
}
@Override
public void onDropCompleted(View target, Object dragInfo, boolean success) {
+ mLauncher.getWorkspace().onDragStopped(success);
+ mLauncher.unlockScreenOrientation();
}
/**
@@ -1045,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);
}
@@ -1091,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" +
@@ -1466,4 +1469,8 @@
sRS.contextDump();
}
}
+
+ public void reset() {
+ // Do nothing
+ }
}
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index 87d255e..d9a503f 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;
@@ -66,6 +67,7 @@
private boolean mAllowHardwareLayerCreation;
private int mPageContentWidth;
+ private boolean mHasMadeSuccessfulDrop;
public AllAppsPagedView(Context context) {
this(context, null);
@@ -88,7 +90,7 @@
Resources r = context.getResources();
setDragSlopeThreshold(
- r.getInteger(R.integer.config_allAppsDrawerDragSlopeThreshold) / 100.0f);
+ r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold) / 100.0f);
// Create a dummy page and set it up to find out the content width (used by our parent)
PagedViewCellLayout layout = new PagedViewCellLayout(getContext());
@@ -119,14 +121,10 @@
}
@Override
- public void setLauncher(Launcher launcher) {
+ public void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
mLauncher.setAllAppsPagedView(this);
- }
-
- @Override
- public void setDragController(DragController dragger) {
- mDragController = dragger;
+ mDragController = dragController;
}
public void setAppFilter(int filterType) {
@@ -138,6 +136,10 @@
}
}
+ void resetSuccessfulDropFlag() {
+ mHasMadeSuccessfulDrop = false;
+ }
+
@Override
public void zoom(float zoom, boolean animate) {
mZoom = zoom;
@@ -285,6 +287,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) {
@@ -304,7 +316,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;
}
@@ -322,6 +334,12 @@
tearDownDragMode();
mLauncher.getWorkspace().onDragStopped(success);
mLauncher.unlockScreenOrientation();
+
+ if (!success && !mHasMadeSuccessfulDrop) {
+ mLauncher.getWorkspace().shrink(Workspace.ShrinkState.BOTTOM_HIDDEN);
+ } else {
+ mHasMadeSuccessfulDrop |= success;
+ }
}
int getPageContentWidth() {
@@ -450,6 +468,11 @@
// do nothing?
}
+ public void reset() {
+ setCurrentPage(0);
+ invalidatePageData();
+ }
+
private void setupPage(PagedViewCellLayout layout) {
layout.setCellCount(mCellCountX, mCellCountY);
layout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop, mPageLayoutPaddingRight,
@@ -485,6 +508,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());
@@ -517,6 +541,7 @@
// Add any necessary items
for (int i = curNumPageItems; i < numPageItems; ++i) {
+ final boolean createHolographicOutlines = (numPages > 1);
TextView text = (TextView) mInflater.inflate(
R.layout.all_apps_paged_view_application, layout, false);
text.setOnClickListener(this);
@@ -524,16 +549,17 @@
text.setOnTouchListener(this);
layout.addViewToCellLayout(text, -1, i,
- new PagedViewCellLayout.LayoutParams(0, 0, 1, 1));
+ new PagedViewCellLayout.LayoutParams(0, 0, 1, 1), createHolographicOutlines);
}
// 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);
+ final boolean createHolographicOutlines = (numPages > 1);
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();
@@ -555,10 +581,11 @@
}
// 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));
+ new PagedViewCellLayout.LayoutParams(0, 0, 4, 1), createHolographicOutlines);
}
layout.createHardwareLayers();
}
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index ee7bfc0..96de5a7 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -29,11 +29,13 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabWidget;
import android.widget.TextView;
import java.util.ArrayList;
+import java.util.Random;
/**
* Implements a tabbed version of AllApps2D.
@@ -80,6 +82,7 @@
};
// 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);
@@ -90,11 +93,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);
@@ -134,14 +143,9 @@
}
@Override
- public void setLauncher(Launcher launcher) {
- mAllApps.setLauncher(launcher);
+ public void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
- }
-
- @Override
- public void setDragController(DragController dragger) {
- mAllApps.setDragController(dragger);
+ mAllApps.setup(launcher, dragController);
}
@Override
@@ -248,6 +252,10 @@
mAllApps.surrender();
}
+ public void reset() {
+ mAllApps.reset();
+ }
+
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getY() > mAllApps.getBottom()) {
@@ -255,4 +263,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
index 2b2662f..4390c59 100644
--- a/src/com/android/launcher2/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -18,6 +18,8 @@
private ItemInfo mItemInfo;
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
+ private DragLayer mDragLayer;
+ private Workspace mWorkspace;
private ImageView mLeftHandle;
private ImageView mRightHandle;
private ImageView mTopHandle;
@@ -57,7 +59,7 @@
public static final int BOTTOM = 3;
public AppWidgetResizeFrame(Context context, ItemInfo itemInfo,
- LauncherAppWidgetHostView widgetView, CellLayout cellLayout) {
+ LauncherAppWidgetHostView widgetView, CellLayout cellLayout, DragLayer dragLayer) {
super(context);
mContext = context;
@@ -65,6 +67,8 @@
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);
@@ -150,7 +154,7 @@
mDeltaX = Math.max(-mBaselineX, deltaX);
mDeltaX = Math.min(mBaselineWidth - 2 * mTouchTargetWidth, mDeltaX);
} else if (mRightBorderActive) {
- mDeltaX = Math.min(mCellLayout.getWidth() - (mBaselineX + mBaselineWidth), deltaX);
+ mDeltaX = Math.min(mDragLayer.getWidth() - (mBaselineX + mBaselineWidth), deltaX);
mDeltaX = Math.max(-mBaselineWidth + 2 * mTouchTargetWidth, mDeltaX);
}
@@ -158,7 +162,7 @@
mDeltaY = Math.max(-mBaselineY, deltaY);
mDeltaY = Math.min(mBaselineHeight - 2 * mTouchTargetWidth, mDeltaY);
} else if (mBottomBorderActive) {
- mDeltaY = Math.min(mCellLayout.getHeight() - (mBaselineY + mBaselineHeight), deltaY);
+ mDeltaY = Math.min(mDragLayer.getHeight() - (mBaselineY + mBaselineHeight), deltaY);
mDeltaY = Math.max(-mBaselineHeight + 2 * mTouchTargetWidth, mDeltaY);
}
}
@@ -168,7 +172,8 @@
*/
public void visualizeResizeForDelta(int deltaX, int deltaY) {
updateDeltas(deltaX, deltaY);
- CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+ DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
+
if (mLeftBorderActive) {
lp.x = mBaselineX + mDeltaX;
lp.width = mBaselineWidth - mDeltaX;
@@ -261,6 +266,7 @@
// Update the cells occupied by this widget
mCellLayout.markCellsAsOccupiedForView(mWidgetView);
+ mWidgetView.requestLayout();
}
/**
@@ -284,20 +290,22 @@
}
public void snapToWidget(boolean animate) {
- final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+ 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;
- int newY = mWidgetView.getTop() - 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 > mCellLayout.getHeight()) {
- newHeight -= newY + newHeight - mCellLayout.getHeight();
+ if (newY + newHeight > mDragLayer.getHeight()) {
+ newHeight -= newY + newHeight - mDragLayer.getHeight();
}
if (!animate) {
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..14e051c
--- /dev/null
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -0,0 +1,1085 @@
+/*
+ * 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),
+ isHardwareAccelerated() && (numPages > 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 1464854..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;
@@ -87,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);
@@ -330,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 1111c53..8efb6ce 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];
@@ -168,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);
@@ -264,17 +263,16 @@
setHoverAlpha(1.0f);
mChildren = new CellLayoutChildren(context);
- mChildren.setCellDimensions(
- mCellWidth, mCellHeight, mLeftPadding, mTopPadding, mWidthGap, mHeightGap);
+ mChildren.setCellDimensions(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
addView(mChildren);
}
private void invalidateBubbleTextView(BubbleTextView icon) {
final int padding = icon.getPressedOrFocusedBackgroundPadding();
- invalidate(icon.getLeft() - padding,
- icon.getTop() - padding,
- icon.getRight() + padding,
- icon.getBottom() + padding);
+ invalidate(icon.getLeft() + getLeftPadding() - padding,
+ icon.getTop() + getTopPadding() - padding,
+ icon.getRight() + getLeftPadding() + padding,
+ icon.getBottom() + getTopPadding() + padding);
}
void setPressedOrFocusedIcon(BubbleTextView icon) {
@@ -355,7 +353,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);
@@ -393,7 +391,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;
@@ -488,8 +486,8 @@
final Bitmap b = mPressedOrFocusedIcon.getPressedOrFocusedBackground();
if (b != null) {
canvas.drawBitmap(b,
- mPressedOrFocusedIcon.getLeft() - padding,
- mPressedOrFocusedIcon.getTop() - padding,
+ mPressedOrFocusedIcon.getLeft() + getLeftPadding() - padding,
+ mPressedOrFocusedIcon.getTop() + getTopPadding() - padding,
null);
}
}
@@ -736,6 +734,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;
}
@@ -768,6 +782,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
@@ -827,7 +853,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);
}
}
@@ -956,15 +982,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;
@@ -982,6 +1016,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.
@@ -1008,16 +1049,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;
@@ -1029,18 +1077,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));
@@ -1062,6 +1112,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);
}
@@ -1457,6 +1543,14 @@
}
}
+ 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);
@@ -1570,8 +1664,7 @@
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;
@@ -1582,11 +1675,15 @@
leftMargin - rightMargin;
height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
topMargin - bottomMargin;
- x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
- y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
+ 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;
}
@@ -1618,10 +1715,6 @@
public int getY() {
return y;
}
-
- public String toString() {
- return "(" + this.cellX + ", " + this.cellY + ")";
- }
}
// This class stores info for two purposes:
@@ -1630,7 +1723,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 04996f3..f9adce0 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -16,12 +16,9 @@
package com.android.launcher2;
-import java.util.ArrayList;
-
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Rect;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -34,33 +31,21 @@
private final WallpaperManager mWallpaperManager;
- private int mLeftPadding;
- private int mTopPadding;
-
private int mCellWidth;
private int mCellHeight;
private int mWidthGap;
private int mHeightGap;
- // Variables relating to resizing widgets
- private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
- new ArrayList<AppWidgetResizeFrame>();
- private AppWidgetResizeFrame mCurrentResizeFrame;
- private int mXDown, mYDown;
-
public CellLayoutChildren(Context context) {
super(context);
mWallpaperManager = WallpaperManager.getInstance(context);
setLayerType(LAYER_TYPE_HARDWARE, null);
}
- public void setCellDimensions(int cellWidth, int cellHeight,
- int leftPadding, int topPadding, int widthGap, int heightGap ) {
+ public void setCellDimensions(int cellWidth, int cellHeight, int widthGap, int heightGap ) {
mCellWidth = cellWidth;
mCellHeight = cellHeight;
- mLeftPadding = leftPadding;
- mTopPadding = topPadding;
mWidthGap = widthGap;
mHeightGap = heightGap;
}
@@ -72,7 +57,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;
}
}
@@ -81,27 +66,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();
@@ -176,95 +163,4 @@
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
super.setChildrenDrawnWithCacheEnabled(enabled);
}
-
- public void clearAllResizeFrames() {
- for (AppWidgetResizeFrame frame: mResizeFrames) {
- removeView(frame);
- }
- mResizeFrames.clear();
- }
-
- public boolean hasResizeFrames() {
- return mResizeFrames.size() > 0;
- }
-
- public boolean isWidgetBeingResized() {
- return mCurrentResizeFrame != null;
- }
-
- private boolean handleTouchDown(MotionEvent ev) {
- Rect hitRect = new Rect();
-
- int x = (int) ev.getX();
- int y = (int) ev.getY();
-
- for (AppWidgetResizeFrame child: mResizeFrames) {
- child.getHitRect(hitRect);
- if (hitRect.contains(x, y)) {
- if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
- mCurrentResizeFrame = child;
- mXDown = x;
- mYDown = y;
- requestDisallowInterceptTouchEvent(true);
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (handleTouchDown(ev)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- boolean handled = false;
- int action = ev.getAction();
-
- int x = (int) ev.getX();
- int y = (int) ev.getY();
-
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (handleTouchDown(ev)) {
- return true;
- }
- }
- }
-
- if (mCurrentResizeFrame != null) {
- handled = true;
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
- break;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
- mCurrentResizeFrame = null;
- }
- }
- return handled;
- }
-
- public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
- CellLayout cellLayout) {
- AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
- itemInfo, widget, cellLayout);
-
- CellLayout.LayoutParams lp = new CellLayout.LayoutParams(-1, -1, -1, -1);
- lp.isLockedToGrid = false;
-
- addView(resizeFrame, lp);
- mResizeFrames.add(resizeFrame);
-
- resizeFrame.snapToWidget(false);
- }
}
diff --git a/src/com/android/launcher2/CustomizePagedView.java b/src/com/android/launcher2/CustomizePagedView.java
index 36a638b..e5bc8b8 100644
--- a/src/com/android/launcher2/CustomizePagedView.java
+++ b/src/com/android/launcher2/CustomizePagedView.java
@@ -172,12 +172,12 @@
final Resources r = context.getResources();
setDragSlopeThreshold(
r.getInteger(R.integer.config_customizationDrawerDragSlopeThreshold) / 100.0f);
- mMinPageWidth = r.getDimensionPixelSize(R.dimen.customization_drawer_content_min_width);
// 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();
setVisibility(View.GONE);
setSoundEffectsEnabled(false);
@@ -301,13 +301,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);
@@ -488,8 +483,6 @@
@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;
@@ -936,12 +929,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);
@@ -982,11 +976,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);
@@ -1019,12 +1014,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);
@@ -1046,7 +1042,8 @@
final int x = index % mCellCountX;
final int y = index / mCellCountX;
setupPage(layout);
- layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+ layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1),
+ createHolographicOutlines);
}
}
@@ -1078,9 +1075,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);
@@ -1089,7 +1088,8 @@
final int x = index % mCellCountX;
final int y = index / mCellCountX;
setupPage(layout);
- layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
+ layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1),
+ createHolographicOutlines);
}
}
@@ -1135,8 +1135,10 @@
}
// Set a min page width for PagedView layout if we have more than a single page
- if (enforceMinimumPagedWidths) {
- setMinimumWidthOverride((childCount > 1) ? mMinPageWidth : 0);
+ if (enforceMinimumPagedWidths && childCount > 1) {
+ setMinimumWidthOverride(mMinPageWidth);
+ } else {
+ resetMinimumWidthOverride();
}
// Bound the current page index
diff --git a/src/com/android/launcher2/CustomizeTrayTabHost.java b/src/com/android/launcher2/CustomizeTrayTabHost.java
index 3e04025..2c47895 100644
--- a/src/com/android/launcher2/CustomizeTrayTabHost.java
+++ b/src/com/android/launcher2/CustomizeTrayTabHost.java
@@ -16,8 +16,7 @@
package com.android.launcher2;
-import com.android.launcher.R;
-import com.android.launcher2.CustomizePagedView.CustomizationType;
+import java.util.Random;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -28,10 +27,14 @@
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";
@@ -69,7 +72,8 @@
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));
+ 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)
@@ -82,6 +86,7 @@
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 =
@@ -89,7 +94,7 @@
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_tabTransitionTime);
+ final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
final float alpha = customizePagedView.getAlpha();
ValueAnimator alphaAnim = ObjectAnimator.ofFloat(customizePagedView,
"alpha", alpha, 0.0f);
@@ -149,6 +154,14 @@
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;
diff --git a/src/com/android/launcher2/DeleteZone.java b/src/com/android/launcher2/DeleteZone.java
index 98d2b83..fdd4125 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,18 @@
if (item instanceof LauncherAppWidgetInfo) {
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
}
- } else if (source instanceof UserFolder) {
- final UserFolder userFolder = (UserFolder) source;
- final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
+ } else if (source instanceof Folder) {
+ final Folder folder = (Folder) source;
+ final FolderInfo folderInfo = (FolderInfo) folder.getInfo();
// Item must be a ShortcutInfo otherwise it couldn't have been in the folder
// in the first place.
- userFolderInfo.remove((ShortcutInfo)item);
+ folderInfo.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 +166,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 +179,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 +194,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 +269,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 cb4509b..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.
@@ -289,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;
@@ -314,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);
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index eb53945..c2b710e 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -16,10 +16,11 @@
package com.android.launcher2;
-import com.android.launcher.R;
+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;
@@ -27,6 +28,8 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import com.android.launcher.R;
+
/**
* A ViewGroup that coordinates dragging across its descendants
*/
@@ -34,6 +37,12 @@
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;
+
/**
* Used to create a new DragLayer from XML.
*
@@ -56,31 +65,66 @@
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // If the current CellLayoutChildren has a resize frame, we need to detect if any touch
- // event has occurred which doesn't result in resizing a widget. In this case, we
- // dismiss any visible resize frames.
- final Workspace w = (Workspace) findViewById(R.id.workspace);
- if (w != null) {
- final CellLayout currentPage = (CellLayout) w.getChildAt(w.getCurrentPage());
- final CellLayoutChildren childrenLayout = currentPage.getChildrenLayout();
+ private boolean handleTouchDown(MotionEvent ev) {
+ Rect hitRect = new Rect();
+ int x = (int) ev.getX();
+ int y = (int) ev.getY();
- if (childrenLayout.hasResizeFrames() && !childrenLayout.isWidgetBeingResized()) {
- post(new Runnable() {
- public void run() {
- if (!childrenLayout.isWidgetBeingResized()) {
- childrenLayout.clearAllResizeFrames();
- }
- }
- });
+ for (AppWidgetResizeFrame child: mResizeFrames) {
+ child.getHitRect(hitRect);
+ if (hitRect.contains(x, y)) {
+ if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
+ mCurrentResizeFrame = child;
+ mXDown = x;
+ mYDown = y;
+ requestDisallowInterceptTouchEvent(true);
+ return true;
+ }
}
}
+ return false;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ if (handleTouchDown(ev)) {
+ return true;
+ }
+ }
+ 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);
}
@@ -103,4 +147,94 @@
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);
+ }
}
diff --git a/src/com/android/launcher2/DragSource.java b/src/com/android/launcher2/DragSource.java
index 4dbdaf7..649120d 100644
--- a/src/com/android/launcher2/DragSource.java
+++ b/src/com/android/launcher2/DragSource.java
@@ -23,8 +23,6 @@
*
*/
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.
diff --git a/src/com/android/launcher2/DragView.java b/src/com/android/launcher2/DragView.java
index 45620b9..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
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 059e73d..3a8a68d 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -16,34 +16,45 @@
package com.android.launcher2;
+import java.util.ArrayList;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.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.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;
+import com.android.launcher2.Workspace.ShrinkState;
/**
* 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 +62,20 @@
*/
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];
+
/**
* Used to inflate the Workspace from XML.
*
@@ -60,19 +85,19 @@
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);
}
@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);
}
public void onItemClick(AdapterView parent, View v, int position, long id) {
@@ -85,12 +110,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);
+ } else {
+ mLauncher.closeFolder(this);
+ }
}
public boolean onLongClick(View v) {
- mLauncher.closeFolder(this);
- mLauncher.showRenameDialog(mInfo);
+ Object tag = v.getTag();
+ if (tag instanceof ShortcutInfo) {
+ // refactor this code from Folder
+ 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;
+ mLauncher.closeFolder(this);
+ 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,33 +168,13 @@
return true;
}
- @Override
public void setDragController(DragController dragController) {
mDragController = dragController;
}
- @Override
- public void onDropCompleted(View target, Object dragInfo, 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;
}
@@ -146,10 +186,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() {
@@ -160,5 +202,245 @@
void bind(FolderInfo info) {
mInfo = info;
mCloseButton.setText(info.title);
+ ArrayList<ShortcutInfo> children = info.contents;
+ for (int i = 0; i < children.size(); i++) {
+ ShortcutInfo child = (ShortcutInfo) children.get(i);
+ if ((child.cellX == -1 && child.cellY == -1) ||
+ mContent.isOccupied(child.cellX, child.cellY)) {
+ findAndSetEmptyCells(child);
+ }
+ createAndAddShortcut((ShortcutInfo) children.get(i));
+ }
+ 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;
+
+ CellLayoutChildren clc = (CellLayoutChildren) getParent();
+ CellLayout cellLayout = (CellLayout) clc.getParent();
+
+ FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
+ CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.getLayoutParams();
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ lp.width = iconLp.width;
+ lp.height = iconLp.height;
+ lp.x = iconLp.x;
+ lp.y = iconLp.y;
+
+ mContent.setAlpha(0f);
+ mState = STATE_SMALL;
+ }
+
+ public void animateOpen() {
+ if (mState != STATE_SMALL) {
+ positionAndSizeAsIcon();
+ }
+ if (!(getParent() instanceof CellLayoutChildren)) return;
+
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
+
+ CellLayoutChildren clc = (CellLayoutChildren) getParent();
+ CellLayout cellLayout = (CellLayout) clc.getParent();
+ Rect r = cellLayout.getContentRect(null);
+
+ PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", r.width());
+ PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", r.height());
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", 0);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", 0);
+
+ ObjectAnimator 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 oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
+
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(oa, oaContentAlpha);
+ set.setDuration(mExpandDuration);
+ set.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = STATE_ANIMATING;
+ }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mState = STATE_SMALL;
+ }
+ });
+ set.start();
+ }
+
+ public void animateClosed() {
+ if (!(getParent() instanceof CellLayoutChildren)) return;
+
+ CellLayoutChildren clc = (CellLayoutChildren) getParent();
+ final CellLayout cellLayout = (CellLayout) clc.getParent();
+
+ FolderIcon fi = (FolderIcon) cellLayout.getChildAt(mInfo.cellX, mInfo.cellY);
+ CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) fi.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);
+
+ ObjectAnimator 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 oaContentAlpha = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
+
+ AnimatorSet set = new AnimatorSet();
+ set.playTogether(oa, oaContentAlpha);
+ set.setDuration(mExpandDuration);
+
+ set.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ cellLayout.removeViewWithoutMarkingCells(Folder.this);
+ mState = STATE_OPEN;
+ }
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mState = STATE_ANIMATING;
+ }
+ });
+ set.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)
+ && 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();
+ item.spanX = 1;
+ item.spanY = 1;
+ } else {
+ item = (ShortcutInfo)dragInfo;
+ }
+ findAndSetEmptyCells(item);
+ 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) {
+ }
+
+ 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) {
+ }
+
+ public void onDropCompleted(View target, Object dragInfo, boolean success) {
+ if (success) {
+ mInfo.remove(mDragItem);
+ }
+ }
+
+ public boolean isDropEnabled() {
+ return true;
+ }
+
+ public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
+ DragView dragView, Object dragInfo) {
+ return null;
+ }
+
+ public void onAdd(ShortcutInfo item) {
+ if ((item.cellX == -1 && item.cellY == -1) ||
+ mContent.isOccupied(item.cellX, item.cellY)) {
+ findAndSetEmptyCells(item);
+ }
+ createAndAddShortcut(item);
+ }
+
+ public int getItemCount() {
+ return mContent.getChildrenLayout().getChildCount();
+ }
+
+ public View getItemAt(int index) {
+ return mContent.getChildrenLayout().getChildAt(index);
+ }
+
+ public void onRemove(ShortcutInfo item) {
+ View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
+ mContent.removeView(v);
}
}
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index dd83c78..b770cd6 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -18,21 +18,27 @@
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
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;
public FolderIcon(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -43,25 +49,33 @@
}
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.folder_bg);
+ 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.bind(folderInfo);
+ icon.mFolder = folder;
+
+ folderInfo.addListener(icon);
+
return icon;
}
@@ -74,6 +88,11 @@
&& item.container != mInfo.id;
}
+ 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,
DragView dragView, Object dragInfo) {
ShortcutInfo item;
@@ -83,15 +102,13 @@
} else {
item = (ShortcutInfo)dragInfo;
}
- mInfo.add(item);
- LauncherModel.addOrMoveItemInDatabase(mLauncher, item, mInfo.id, 0, 0, 0);
+ item.cellX = -1;
+ item.cellY = -1;
+ addItem(item);
}
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);
- }
}
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
@@ -100,7 +117,6 @@
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
DragView dragView, Object dragInfo) {
- setCompoundDrawablesWithIntrinsicBounds(null, mCloseIcon, null, null);
}
@Override
@@ -108,4 +124,49 @@
DragView dragView, Object dragInfo) {
return null;
}
+
+ @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];
+
+ canvas.translate( (getMeasuredWidth() - d.getIntrinsicWidth()) / 2,
+ (getMeasuredHeight() - d.getIntrinsicHeight()) / 2);
+
+ canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
+ canvas.rotate(ICON_ANGLE);
+
+ canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
+
+ for (int i = Math.max(0, mFolder.getItemCount() - NUM_ITEMS_IN_PREVIEW);
+ i < mFolder.getItemCount(); i++) {
+ v = (TextView) mFolder.getItemAt(i);
+ d = v.getCompoundDrawables()[1];
+
+ if (d != null) {
+ d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
+ d.draw(canvas);
+ }
+
+ canvas.translate(d.getIntrinsicWidth() / 2, d.getIntrinsicHeight() / 2);
+ canvas.rotate(-ICON_ANGLE);
+ canvas.translate(-d.getIntrinsicWidth() / 2, -d.getIntrinsicHeight() / 2);
+ }
+
+ 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/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 0c26bf0..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;
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 b361214..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;
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index b7f04f7..2fe1c7d 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -17,9 +17,13 @@
package com.android.launcher2;
-import com.android.common.Search;
-import com.android.launcher.R;
-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;
@@ -63,10 +67,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;
@@ -99,14 +101,9 @@
import android.widget.TextView;
import android.widget.Toast;
-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.
@@ -132,11 +129,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;
@@ -155,7 +150,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
@@ -170,7 +165,7 @@
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,
+ private enum State { WORKSPACE, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE,
CUSTOMIZE_SPRING_LOADED, ALL_APPS_SPRING_LOADED };
private State mState = State.WORKSPACE;
private AnimatorSet mStateAnimation;
@@ -203,10 +198,12 @@
private DeleteZone mDeleteZone;
private HandleView mHandleView;
private AllAppsView mAllAppsGrid;
+ private AppsCustomizeTabHost mAppsCustomizeTabHost;
+ private AppsCustomizePagedView mAppsCustomizeContent;
private CustomizeTrayTabHost mHomeCustomizationDrawer;
private boolean mAutoAdvanceRunning = false;
- private View mButtonCluster;
+ private ViewGroup mButtonCluster;
private View mAllAppsButton;
private View mDivider;
private View mConfigureButton;
@@ -315,7 +312,6 @@
// share the same customization workspace across all the tabs
mCustomizePagedView = (CustomizePagedView) findViewById(
R.id.customization_drawer_tab_contents);
-
}
setupViews();
@@ -330,6 +326,9 @@
if (mCustomizePagedView != null) {
mCustomizePagedView.update();
}
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.onPackagesUpdated();
+ }
if (PROFILE_STARTUP) {
android.os.Debug.stopMethodTracing();
@@ -347,7 +346,7 @@
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();
}
@@ -363,21 +362,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>() {
@@ -648,12 +632,6 @@
case REQUEST_CREATE_SHORTCUT:
completeAddShortcut(args.intent, args.screen, args.cellX, args.cellY);
break;
- case REQUEST_PICK_LIVE_FOLDER:
- addLiveFolder(args.intent);
- break;
- case REQUEST_CREATE_LIVE_FOLDER:
- completeAddLiveFolder(args.intent, args.screen, args.cellX, args.cellY);
- break;
case REQUEST_PICK_APPWIDGET:
addAppWidgetFromPick(args.intent);
break;
@@ -738,7 +716,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;
}
@@ -771,8 +754,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) {
@@ -832,7 +817,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);
@@ -885,6 +870,20 @@
// 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
+ }
}
/**
@@ -896,18 +895,17 @@
DragLayer dragLayer = (DragLayer) findViewById(R.id.drag_layer);
dragLayer.setDragController(dragController);
- 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);
@@ -923,7 +921,6 @@
// we don't use handle view in xlarge mode
mHandleView = (HandleView)handleView;
mHandleView.setLauncher(this);
- mHandleView.setOnClickListener(this);
mHandleView.setOnLongClickListener(this);
}
@@ -938,8 +935,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();
@@ -960,10 +960,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));
@@ -985,15 +985,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);
- }
- });
}
+ marketButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ onClickAppMarketButton(v);
+ }
+ });
}
dragController.setDragScoller(workspace);
@@ -1009,10 +1011,22 @@
if (allAppsDeleteZone != null) {
dragController.addDropTarget(allAppsDeleteZone);
}
- mButtonCluster = findViewById(R.id.all_apps_button_cluster);
+ 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.divider);
+ 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
@@ -1043,14 +1057,14 @@
@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();
}
}
@@ -1253,6 +1267,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();
@@ -1407,11 +1429,7 @@
!= Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
// In all these cases, only animate if we're already on home
-
- if (LauncherApplication.isScreenXLarge()) {
- mWorkspace.unshrink(alreadyOnHome);
- }
-
+ mWorkspace.unshrink(alreadyOnHome);
mWorkspace.exitWidgetResizeMode();
if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive()) {
mWorkspace.moveToDefaultScreen(true);
@@ -1424,6 +1442,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();
+ }
}
}
@@ -1445,7 +1471,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);
}
@@ -1472,7 +1498,6 @@
outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage());
}
}
-
// Save the current customization drawer tab
if (mHomeCustomizationDrawer != null) {
String currentTabTag = mHomeCustomizationDrawer.getCurrentTabTag();
@@ -1480,6 +1505,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
@@ -1521,6 +1553,10 @@
ValueAnimator.clearAllAnimations();
}
+ public DragController getDragController() {
+ return mDragController;
+ }
+
@Override
public void startActivityForResult(Intent intent, int requestCode) {
if (requestCode >= 0) mWaitingForResult = true;
@@ -1588,22 +1624,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;
}
@@ -1653,7 +1695,7 @@
}
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);
@@ -1770,38 +1812,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
@@ -1815,73 +1834,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) {
@@ -1943,7 +1902,7 @@
@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 if (mWorkspace.getOpenFolder() != null) {
closeFolder();
@@ -1967,15 +1926,14 @@
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);
- }
+ mDragController.removeDropTarget((DropTarget)folder);
}
+
+ folder.animateClosed();
folder.onClose();
}
@@ -2020,7 +1978,10 @@
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);
@@ -2142,15 +2103,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);
@@ -2160,7 +2122,7 @@
// Close any folder open on the current screen
closeFolder();
// Pull the folder onto this screen
- openFolder(folderInfo);
+ openFolder(folderIcon);
}
}
}
@@ -2173,26 +2135,15 @@
*
* @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;
- }
+ 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);
+ folder.animateOpen();
+ folder.onOpen();
}
public boolean onLongClick(View v) {
@@ -2202,21 +2153,21 @@
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);
@@ -2247,10 +2198,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)) {
@@ -2277,11 +2228,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);
}
});
@@ -2373,7 +2325,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 {
@@ -2532,7 +2484,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();
@@ -2553,32 +2507,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 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);
- }
-
- private void disableToolbarButton(View button) {
- button.setFocusable(false);
- button.setClickable(false);
+ button.setAlpha(0.0f);
}
/**
@@ -2609,7 +2556,6 @@
@Override
public void onAnimationStart(Animator animation) {
if (showing) showAndEnableToolbarButton(view);
- if (hiding) disableToolbarButton(view);
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -2622,7 +2568,6 @@
showAndEnableToolbarButton(view);
view.setAlpha(1f);
} else {
- disableToolbarButton(view);
hideToolbarButton(view);
}
}
@@ -2640,15 +2585,18 @@
switch (newState) {
case WORKSPACE:
hideOrShowToolbarButton(true, mButtonCluster, showSeq);
- mDeleteZone.setOverlappingViews(
- new View[] { mAllAppsButton, mDivider, mConfigureButton });
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:
+ 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, mButtonCluster, hideSeq);
@@ -2670,7 +2618,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 {
@@ -2685,27 +2633,45 @@
* 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 fadeDuration = toAllApps ?
- res.getInteger(R.integer.config_allAppsFadeInTime) :
- res.getInteger(R.integer.config_customizeFadeInTime);
+ 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);
}
@@ -2713,10 +2679,8 @@
if (animated) {
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);
@@ -2724,13 +2688,12 @@
});
if (toAllApps) {
+ 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);
}
@@ -2748,6 +2711,7 @@
toView.setTranslationX(0.0f);
toView.setTranslationY(0.0f);
toView.setVisibility(View.VISIBLE);
+ toView.bringToFront();
if (!toAllApps) {
toView.setFastAlpha(1.0f);
}
@@ -2787,6 +2751,7 @@
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);
@@ -2801,33 +2766,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();
@@ -2837,22 +2807,18 @@
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);
}
});
final ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f);
- alphaAnim.setDuration(res.getInteger(R.integer.config_allAppsFadeOutTime));
+ 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);
}
@@ -2895,34 +2861,6 @@
}
}
- void showAllApps(boolean animated) {
- if (mState != State.WORKSPACE) {
- return;
- }
-
- if (LauncherApplication.isScreenXLarge()) {
- 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);
}
@@ -2935,7 +2873,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);
@@ -2954,12 +2892,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
}*/
@@ -2968,17 +2910,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
@@ -3019,15 +2994,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();
+ }
}
}
@@ -3045,7 +3027,7 @@
return;
}
- cameraZoomOut(State.CUSTOMIZE, animated);
+ cameraZoomOut(State.CUSTOMIZE, animated, false);
// Change the state *after* we've called all the transition code
mState = State.CUSTOMIZE;
@@ -3058,7 +3040,10 @@
// 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();
}
}
@@ -3140,15 +3125,21 @@
}
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 +3149,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,16 +3175,21 @@
* 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 = updateTextButtonWithIconFromExternalActivity(
- 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);
}
}
@@ -3261,31 +3263,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 +3353,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 +3400,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 +3475,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 +3501,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();
@@ -3561,7 +3534,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);
}
@@ -3576,7 +3554,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);
}
@@ -3597,6 +3580,9 @@
if (mAllAppsGrid != null) {
mAllAppsGrid.updateApps(apps);
}
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.updateApps(apps);
+ }
if (mCustomizePagedView != null) {
mCustomizePagedView.updateApps(apps);
}
@@ -3613,7 +3599,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);
}
@@ -3628,6 +3619,9 @@
if (mCustomizePagedView != null) {
mCustomizePagedView.update();
}
+ if (mAppsCustomizeContent != null) {
+ mAppsCustomizeContent.onPackagesUpdated();
+ }
}
private int mapConfigurationOriActivityInfoOri(int configOri) {
@@ -3686,7 +3680,12 @@
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");
}
}
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 7f60cac..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;
@@ -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 c098749..d5505c5 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -37,7 +37,6 @@
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;
@@ -91,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;
@@ -271,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()) {
@@ -285,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;
}
@@ -391,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);
@@ -522,9 +514,6 @@
mLoaderTask.stopLocked();
}
}
- mItems.clear();
- mAppWidgets.clear();
- mFolders.clear();
}
/**
@@ -540,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;
@@ -659,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() {
@@ -843,8 +820,8 @@
break;
default:
// Item is in a user folder
- UserFolderInfo folderInfo =
- findOrMakeUserFolder(mFolders, container);
+ FolderInfo folderInfo =
+ findOrMakeFolder(mFolders, container);
folderInfo.add(info);
break;
}
@@ -864,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;
@@ -889,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);
@@ -1294,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());
}
}
@@ -1623,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);
@@ -1668,38 +1593,6 @@
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) {
@@ -1735,44 +1628,18 @@
}
/**
- * 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();
@@ -1790,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);
@@ -1797,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 e7ecb99..1180106 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -29,6 +29,7 @@
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;
@@ -50,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
@@ -110,6 +112,7 @@
protected int mPageLayoutPaddingRight;
protected int mPageLayoutWidthGap;
protected int mPageLayoutHeightGap;
+ protected int mPageLayoutMaxHeight;
protected int mCellCountX;
protected int mCellCountY;
protected boolean mCenterPagesVertically;
@@ -189,6 +192,8 @@
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);
@@ -289,6 +294,10 @@
mIsPageMoving = false;
}
+ protected boolean isPageMoving() {
+ return mIsPageMoving;
+ }
+
// a method that subclasses can override to add behavior
protected void onPageBeginMoving() {
}
@@ -384,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)
@@ -413,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) {
@@ -467,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);
@@ -480,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);
}
@@ -493,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;
@@ -511,7 +531,8 @@
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) {
@@ -524,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);
}
@@ -982,6 +1003,7 @@
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
if (!mDeferScrollUpdate) {
scrollBy((int) deltaX, 0);
+ if (DEBUG) Log.d(TAG, "onTouchEvent().Scrolling: " + deltaX);
} else {
invalidate();
}
@@ -1155,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);
}
}
@@ -1177,9 +1199,16 @@
protected void setMinimumWidthOverride(int minimumWidth) {
mMinimumWidth = minimumWidth;
}
+ protected void resetMinimumWidthOverride() {
+ mMinimumWidth = 0;
+ }
protected int getChildWidth(int index) {
- return Math.max(mMinimumWidth, getChildAt(index).getMeasuredWidth());
+ // 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) {
@@ -1198,7 +1227,12 @@
}
protected int getScaledMeasuredWidth(View child) {
- return (int) (Math.max(mMinimumWidth, 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() {
@@ -1248,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;
@@ -1285,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;
@@ -1396,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();
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 53657e5..54bdec4 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,7 +40,6 @@
private int mCellHeight;
private int mWidthGap;
private int mHeightGap;
- private static int sDefaultCellDimensions = 96;
protected PagedViewCellLayoutChildren mChildren;
private PagedViewCellLayoutChildren mHolographicChildren;
private boolean mAllowHardwareLayerCreation = false;
@@ -57,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;
@@ -125,7 +129,7 @@
}
public boolean addViewToCellLayout(View child, int index, int childId,
- PagedViewCellLayout.LayoutParams params) {
+ PagedViewCellLayout.LayoutParams params, boolean createHolographicOutlines) {
final PagedViewCellLayout.LayoutParams lp = params;
// Generate an id for each view, this assumes we have at most 256x256 cells
@@ -145,7 +149,10 @@
if (mAllowHardwareLayerCreation) {
pagedViewIcon.disableCache();
}
- mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(), index, lp);
+ if (createHolographicOutlines) {
+ mHolographicChildren.addView(pagedViewIcon.getHolographicOutlineView(),
+ index, lp);
+ }
}
return true;
}
@@ -180,6 +187,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
@@ -244,12 +259,23 @@
}
int getContentWidth() {
- // 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
+ 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 offset that accounts for
- int iconHorizontalOffset = (mCellWidth - Utilities.getIconContentSize());
- return mCellCountX * mCellWidth + (mCellCountX - 1) * mWidthGap - iconHorizontalOffset;
+ // 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
@@ -257,7 +283,12 @@
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);
+ }
}
}
@@ -446,8 +477,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/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 bde6559..e23f1c6 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);
}
@@ -171,8 +172,8 @@
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);
@@ -217,7 +218,8 @@
// draw any blended overlays
if (mCheckedOutline == null) {
- if (mHolographicOutline != null && mHolographicAlpha > 0) {
+ if (canvas.isHardwareAccelerated() && mHolographicOutline != null
+ && mHolographicAlpha > 0) {
mPaint.setAlpha(mHolographicAlpha);
overlay = mHolographicOutline;
}
@@ -245,6 +247,18 @@
}
@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;
}
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 72f928b..2ffa398 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -36,6 +36,7 @@
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;
@@ -63,6 +64,7 @@
private PagedViewIconCache.Key mIconCacheKey;
private PagedViewIconCache mIconCache;
+ private String mDimensionsFormatString;
private int mAlpha = 255;
private int mHolographicAlpha;
@@ -153,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);
}
@@ -178,14 +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) {
@@ -196,6 +202,28 @@
}
}
+ 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) {
@@ -228,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);
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/UserFolder.java b/src/com/android/launcher2/UserFolder.java
deleted file mode 100644
index 251b3f9..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, Object dragInfo, 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 8ab22eb..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;
@@ -241,7 +243,7 @@
final float density = metrics.density;
sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
- if (LauncherApplication.isScreenXLarge()) {
+ if (LauncherApplication.isScreenLarge()) {
sIconContentSize = (int) resources.getDimension(R.dimen.app_icon_content_size);
}
sIconTextureWidth = sIconTextureHeight = sIconWidth + 2;
@@ -389,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 e7865d2..1373996 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,8 +16,9 @@
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;
@@ -37,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;
@@ -49,7 +49,6 @@
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;
@@ -66,9 +65,8 @@
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.
@@ -131,6 +129,7 @@
private int mDefaultPage;
private boolean mIsDragInProcess = false;
+ private boolean mIsDraggingOverIcon = false;
/**
* CellInfo for the cell that is currently being dragged
@@ -155,7 +154,7 @@
// 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];
@@ -213,6 +212,7 @@
WallpaperOffsetInterpolator mWallpaperOffset;
boolean mUpdateWallpaperOffsetImmediately = false;
boolean mSyncWallpaperOffsetWithScroll = true;
+ private Runnable mDelayedResizeRunnable;
// info about the last drag
private DragView mLastDragView;
@@ -249,7 +249,7 @@
super(context, attrs, defStyle);
mContentIsRefreshable = false;
- if (!LauncherApplication.isScreenXLarge()) {
+ if (!LauncherApplication.isScreenLarge()) {
mFadeInAdjacentScreens = false;
}
@@ -333,65 +333,48 @@
@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);
child.setOnClickListener(this);
child.setClickable(true);
+ }
+ @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);
- child.setOnClickListener(this);
- child.setClickable(true);
+ 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);
- child.setOnClickListener(this);
- child.setClickable(true);
+ 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);
- child.setOnClickListener(this);
- child.setClickable(true);
+ 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);
- child.setOnClickListener(this);
- child.setClickable(true);
+ onAddView(child);
super.addView(child, params);
}
@@ -485,6 +468,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);
@@ -645,6 +632,11 @@
}
mOverScrollMaxBackgroundAlpha = 0.0f;
mOverScrollPageIndex = -1;
+
+ if (mDelayedResizeRunnable != null) {
+ mDelayedResizeRunnable.run();
+ mDelayedResizeRunnable = null;
+ }
}
@Override
@@ -769,7 +761,8 @@
return offset;
}
private void syncWallpaperOffsetWithScroll() {
- if (LauncherApplication.isScreenXLarge()) {
+ final boolean enableWallpaperEffects = isHardwareAccelerated();
+ if (enableWallpaperEffects) {
mWallpaperOffset.setFinalX(wallpaperOffsetForCurrentScroll());
}
}
@@ -1067,6 +1060,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++) {
@@ -1244,6 +1242,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();
@@ -1255,19 +1261,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;
@@ -1297,27 +1290,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);
@@ -1392,14 +1390,6 @@
// 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
@@ -1471,7 +1461,7 @@
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);
}
@@ -1556,30 +1546,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;
@@ -1591,19 +1586,19 @@
final float oldVerticalWallpaperOffset = getVerticalWallpaperOffset();
final float newHorizontalWallpaperOffset = 0.5f;
final float newVerticalWallpaperOffset = wallpaperOffset;
- animWithInterpolator.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- final float b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ animWithInterpolator.addUpdateListener(new LauncherAnimatorUpdateListener() {
+ public void onAnimationUpdate(float a, float b) {
if (b == 0f) {
// an optimization, and required for correct behavior.
return;
}
fastInvalidate();
- 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();
@@ -1621,7 +1616,7 @@
mAnimator.playTogether(animWithInterpolator);
mAnimator.addListener(mShrinkAnimationListener);
mAnimator.start();
- } else {
+ } else if (enableWallpaperEffects) {
setVerticalWallpaperOffset(wallpaperOffset);
setHorizontalWallpaperOffset(0.5f);
updateWallpaperOffsetImmediately();
@@ -1708,39 +1703,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;
@@ -1750,9 +1763,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);
}
@@ -1800,8 +1815,8 @@
}
public void exitWidgetResizeMode() {
- final CellLayout currentLayout = (CellLayout) getChildAt(getCurrentPage());
- currentLayout.getChildrenLayout().clearAllResizeFrames();
+ DragLayer dragLayer = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
+ dragLayer.clearAllResizeFrames();
}
void unshrink(boolean animated) {
@@ -1847,20 +1862,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) {
@@ -1893,56 +1922,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 b = (Float) animation.getAnimatedValue();
- final float a = 1f - b;
+ 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();
- 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();
@@ -1964,11 +1999,9 @@
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;
@@ -1986,9 +2019,11 @@
mAnimator.addListener(mUnshrinkAnimationListener);
mAnimator.start();
} else {
- setHorizontalWallpaperOffset(wallpaperOffsetForCurrentScroll());
- setVerticalWallpaperOffset(0.5f);
- updateWallpaperOffsetImmediately();
+ if (enableWallpaperEffects) {
+ setHorizontalWallpaperOffset(wallpaperOffsetForCurrentScroll());
+ setVerticalWallpaperOffset(0.5f);
+ updateWallpaperOffsetImmediately();
+ }
}
}
@@ -2009,7 +2044,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);
@@ -2140,12 +2176,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, this, child.getTag(), DragController.DRAG_ACTION_MOVE);
+ mDragController.startDrag(b, screenX, screenY, this, child.getTag(),
+ DragController.DRAG_ACTION_MOVE, dragRect);
b.recycle();
}
@@ -2167,15 +2215,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);
}
/*
@@ -2187,8 +2235,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;
@@ -2271,23 +2319,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) {
- boolean largeOrSpringLoaded = !mIsSmall || mWasSpringLoadedOnDragExit;
- int originX = largeOrSpringLoaded ? x - xOffset : x - xOffset + dragView.getWidth() / 2;
- int originY = largeOrSpringLoaded ? y - yOffset : y - yOffset + dragView.getHeight() / 2;
- if (mIsSmall || mIsInUnshrinkAnimation) {
- // get originX and originY in the local coordinate system of the screen
- mTempOriginXY[0] = originX;
- mTempOriginXY[1] = originY;
- mapPointFromSelfToChild(mDragTargetLayout, mTempOriginXY);
- originX = (int)mTempOriginXY[0];
- originY = (int)mTempOriginXY[1];
- if (!largeOrSpringLoaded) {
- originX -= mDragTargetLayout.getCellWidth() / 2;
- originY -= mDragTargetLayout.getCellHeight() / 2;
- }
+ mDragViewVisualCenter = getDragViewVisualCenter(x, y, xOffset, yOffset, dragView,
+ mDragViewVisualCenter);
+
+ // 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
@@ -2300,21 +2405,25 @@
}
if (source != this) {
- final int[] touchXY = new int[] { originX, originY };
- if ((mIsSmall || mIsInUnshrinkAnimation) && !mLauncher.isAllAppsVisible()) {
+ 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);
+ 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) {
@@ -2324,13 +2433,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);
}
@@ -2353,7 +2471,6 @@
mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
if (cell instanceof LauncherAppWidgetHostView) {
- final CellLayoutChildren children = dropTargetLayout.getChildrenLayout();
final CellLayout cellLayout = dropTargetLayout;
// We post this call so that the widget has a chance to be placed
// in its final location
@@ -2361,10 +2478,21 @@
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() {
- children.addResizeFrame(info, hostView,
- cellLayout);
+ if (!isPageMoving()) {
+ resizeRunnable.run();
+ } else {
+ mDelayedResizeRunnable = resizeRunnable;
+ }
}
});
}
@@ -2378,14 +2506,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
@@ -2614,11 +2758,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;
- }
+ }
/*
*
@@ -2716,38 +2860,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;
- // 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);
+
+ // 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 {
@@ -2776,35 +2961,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);
- 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();
+ }
}
}
}
@@ -2850,6 +3023,11 @@
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
@@ -2859,7 +3037,7 @@
* to add an item to one of the workspace screens.
*/
private void onDropExternal(int[] touchXY, Object dragInfo,
- CellLayout cellLayout, boolean insertAtFirst) {
+ CellLayout cellLayout, boolean insertAtFirst, DragView dragView) {
int screen = indexOfChild(cellLayout);
if (dragInfo instanceof PendingAddItemInfo) {
PendingAddItemInfo info = (PendingAddItemInfo) dragInfo;
@@ -2869,9 +3047,6 @@
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;
@@ -2894,18 +3069,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);
}
+ // 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;
+ }
+
mTargetCell = new int[2];
if (touchXY != null) {
// when dragging and dropping, just find the closest free spot
- cellLayout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, mTargetCell);
+ mTargetCell = findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, null, cellLayout,
+ mTargetCell);
} else {
cellLayout.findCellForSpan(mTargetCell, 1, 1);
}
@@ -2915,6 +3098,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,
@@ -2942,16 +3134,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) {
@@ -3104,6 +3304,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();
@@ -3144,8 +3359,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();
@@ -3173,20 +3388,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 =