merge in ics-release history after reset to master
diff --git a/res/drawable-large-nodpi/all_apps_bg_gradient.9.png b/res/drawable-hdpi/all_apps_bg_gradient.9.png
similarity index 100%
copy from res/drawable-large-nodpi/all_apps_bg_gradient.9.png
copy to res/drawable-hdpi/all_apps_bg_gradient.9.png
Binary files differ
diff --git a/res/drawable-hdpi/all_apps_bg_gradient.png b/res/drawable-hdpi/all_apps_bg_gradient.png
deleted file mode 100644
index c420ca5..0000000
--- a/res/drawable-hdpi/all_apps_bg_gradient.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-hdpi/ic_home_all_apps_holo_dark.png b/res/drawable-hdpi/ic_home_all_apps_holo_dark.png
similarity index 100%
rename from res/drawable-large-hdpi/ic_home_all_apps_holo_dark.png
rename to res/drawable-hdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-large/delete_zone_selector.xml b/res/drawable-large/delete_zone_selector.xml
deleted file mode 100644
index e2b37f4..0000000
--- a/res/drawable-large/delete_zone_selector.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-**
-** Copyright 2007, 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.
-*/
--->
-
-<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <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-large-nodpi/all_apps_bg_gradient.9.png b/res/drawable-mdpi/all_apps_bg_gradient.9.png
similarity index 100%
copy from res/drawable-large-nodpi/all_apps_bg_gradient.9.png
copy to res/drawable-mdpi/all_apps_bg_gradient.9.png
Binary files differ
diff --git a/res/drawable-mdpi/all_apps_bg_gradient.png b/res/drawable-mdpi/all_apps_bg_gradient.png
deleted file mode 100644
index c420ca5..0000000
--- a/res/drawable-mdpi/all_apps_bg_gradient.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-large-mdpi/ic_home_all_apps_holo_dark.png b/res/drawable-mdpi/ic_home_all_apps_holo_dark.png
similarity index 100%
rename from res/drawable-large-mdpi/ic_home_all_apps_holo_dark.png
rename to res/drawable-mdpi/ic_home_all_apps_holo_dark.png
Binary files differ
diff --git a/res/drawable-large-nodpi/all_apps_bg_gradient.9.png b/res/drawable-nodpi/all_apps_bg_gradient.9.png
similarity index 100%
rename from res/drawable-large-nodpi/all_apps_bg_gradient.9.png
rename to res/drawable-nodpi/all_apps_bg_gradient.9.png
Binary files differ
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 7073661..b076f52 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -38,7 +38,6 @@
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
-
</com.android.launcher2.Workspace>
<include layout="@layout/qsb_bar"
diff --git a/res/layout-land/user_folder.xml b/res/layout-land/user_folder.xml
deleted file mode 100644
index 87499e7..0000000
--- a/res/layout-land/user_folder.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.launcher2.Folder
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
- android:orientation="vertical"
- android:background="@drawable/portal_container_holo">
-
- <com.android.launcher2.CellLayout
- android:id="@id/folder_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
-
- android:cacheColorHint="#ff333333"
-
- android:hapticFeedbackEnabled="false"
- launcher:widthGap="@dimen/workspace_width_gap"
- launcher:heightGap="@dimen/workspace_height_gap"
- launcher:cellWidth="@dimen/workspace_cell_width"
- launcher:cellHeight="@dimen/workspace_cell_height"
- launcher:xAxisStartPadding="0dip"
- launcher:xAxisEndPadding="0dip"
- launcher:yAxisStartPadding="8dip"
- launcher:yAxisEndPadding="8dip"/>
-
-</com.android.launcher2.Folder>
diff --git a/res/layout-large/launcher.xml b/res/layout-large/launcher.xml
index 2d14137..cb84b5a 100644
--- a/res/layout-large/launcher.xml
+++ b/res/layout-large/launcher.xml
@@ -28,23 +28,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <include layout="@layout/button_bar"
- android:id="@+id/all_apps_button_cluster"
- android:layout_width="fill_parent"
- android:layout_height="?android:attr/actionBarSize"
+ <include layout="@layout/qsb_bar"
+ android:id="@+id/qsb_bar"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/qsb_bar_height"
android:layout_gravity="top" />
- <include layout="@layout/all_apps_tabbed"
- android:id="@+id/all_apps_view"
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
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="wrap_content"
- android:layout_gravity="bottom"
android:visibility="invisible" />
</com.android.launcher2.DragLayer>
diff --git a/res/layout-large/qsb_bar.xml b/res/layout-large/qsb_bar.xml
new file mode 100644
index 0000000..421ace2
--- /dev/null
+++ b/res/layout-large/qsb_bar.xml
@@ -0,0 +1,131 @@
+<?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.SearchDropTargetBar
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
+ android:focusable="false">
+
+ <!-- Search buttons container -->
+ <RelativeLayout
+ style="@style/SearchDropTargetBar"
+ android:id="@+id/qsb_search_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <!-- Global search icon -->
+ <ImageView
+ style="@style/SearchButton"
+ android:id="@+id/search_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ 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
+ style="@style/SearchButtonDivider"
+ android:id="@+id/search_divider"
+ android:layout_toRightOf="@+id/search_button"
+ android:src="@drawable/divider_launcher_holo"
+ android:onClick="onClickSearchButton"
+ android:focusable="false"
+ android:clickable="true" />
+
+ <!-- Voice search icon -->
+ <ImageView
+ style="@style/SearchButton"
+ android:id="@+id/voice_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@+id/search_divider"
+ android:src="@drawable/ic_voice_search"
+ android:background="@drawable/button_bg"
+ android:onClick="onClickVoiceButton"
+ android:focusable="true"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_voice_search_button" />
+
+ <!-- AppsCustomize icon -->
+ <com.android.launcher2.StrokedTextView
+ android:id="@+id/all_apps_button"
+ android:onClick="onClickAllAppsButton"
+ android:drawableLeft="@drawable/ic_home_all_apps_holo_dark"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@+id/all_apps_divider"
+ android:paddingLeft="@dimen/toolbar_button_horizontal_padding"
+ android:paddingRight="@dimen/toolbar_button_horizontal_padding"
+ android:paddingTop="@dimen/all_apps_button_vertical_padding"
+ android:paddingBottom="@dimen/all_apps_button_vertical_padding"
+ android:background="@drawable/button_bg"
+
+ android:gravity="center"
+ android:textColor="#CCFFFFFF"
+ android:textSize="18sp"
+
+ launcher:strokeColor="#991e3157"
+ launcher:strokeTextColor="#DDFFFFFF"
+ launcher:strokeWidth="2.5"
+
+ android:shadowColor="#DA000000"
+ android:shadowDx="0.0"
+ android:shadowDy="0.0"
+ android:shadowRadius="2.5"
+
+ android:focusable="true"
+ android:clickable="true"
+ android:contentDescription="@string/accessibility_all_apps_button" />
+ </RelativeLayout>
+
+ <!-- Drag specific targets container -->
+ <LinearLayout
+ style="@style/SearchDropTargetBar"
+ android:id="@+id/drag_target_bar"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:alpha="0">
+
+ <com.android.launcher2.DeleteDropTarget
+ style="@style/DropTargetButtonContainer"
+ android:id="@+id/delete_target"
+ android:layout_weight="1">
+ <!-- Delete target -->
+ <TextView
+ style="@style/DropTargetButton"
+ android:id="@+id/delete_target_text"
+ android:text="@string/delete_zone_label_workspace"
+ android:drawableLeft="@drawable/delete_zone_selector" />
+ </com.android.launcher2.DeleteDropTarget>
+
+ <com.android.launcher2.InfoDropTarget
+ style="@style/DropTargetButtonContainer"
+ android:id="@+id/info_target"
+ android:layout_weight="1">
+ <!-- Info target -->
+ <TextView
+ style="@style/DropTargetButton"
+ android:id="@+id/info_target_text"
+ android:text="@string/info_target_label"
+ android:drawableLeft="@drawable/ic_home_info_holo_dark" />
+ </com.android.launcher2.InfoDropTarget>
+ </LinearLayout>
+</com.android.launcher2.SearchDropTargetBar>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 2d5a34f..5ee2833 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -40,7 +40,7 @@
<include layout="@layout/qsb_bar"
android:id="@+id/qsb_bar"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="@dimen/qsb_bar_height"
android:layout_gravity="top" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index f3ecb48..55cba99 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -16,10 +16,6 @@
<com.android.launcher2.AppsCustomizeTabHost
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher">
- <com.android.launcher2.AllAppsBackground
- android:id="@+id/all_apps_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
@@ -28,57 +24,33 @@
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_height="@dimen/qsb_bar_height"
android:layout_gravity="center_horizontal">
<com.android.launcher2.FocusOnlyTabWidget
android:id="@android:id/tabs"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="@drawable/tab_unselected_holo"
android:tabStripEnabled="false" />
- <FrameLayout
+ <TextView
+ style="@style/MarketButton"
+ android:id="@+id/market_button"
+ android:onClick="onClickAppMarketButton"
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:onClick="onClickAppMarketButton"
- 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"
- android:clickable="true" />
- </FrameLayout>
+ android:layout_gravity="right"
+ android:gravity="center"
+ android:text="@string/market"
+ android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
+ android:textSize="18sp"
+ android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
+ android:shadowDx="0.0"
+ android:shadowDy="0.0"
+ android:shadowRadius="2.0"
+ android:background="@drawable/tab_widget_indicator_selector"
+ android:focusable="true"
+ android:clickable="true" />
</FrameLayout>
<FrameLayout
android:id="@android:id/tabcontent"
@@ -87,7 +59,7 @@
<com.android.launcher2.AppsCustomizePagedView
android:id="@+id/apps_customize_pane_content"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
launcher:cellCountX="@integer/all_apps_view_cellCountX"
launcher:cellCountY="@integer/all_apps_view_cellCountY"
launcher:pageLayoutWidthGap="@dimen/all_apps_view_pageLayoutWidthGap"
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index 9d0764c..53643b4 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -38,6 +38,17 @@
android:adjustViewBounds="true"
android:scaleType="fitStart" />
+ <!-- The divider image. -->
+ <ImageView
+ style="WidgetDivider"
+ 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"
diff --git a/res/layout/qsb_bar.xml b/res/layout/qsb_bar.xml
index 820fae6..68ee8b6 100644
--- a/res/layout/qsb_bar.xml
+++ b/res/layout/qsb_bar.xml
@@ -67,26 +67,28 @@
android:layout_height="match_parent"
android:alpha="0">
- <FrameLayout
+ <com.android.launcher2.DeleteDropTarget
style="@style/DropTargetButtonContainer"
+ android:id="@+id/delete_target"
android:layout_weight="1">
<!-- Delete target -->
- <com.android.launcher2.DeleteDropTarget
+ <TextView
style="@style/DropTargetButton"
- android:id="@+id/delete_target"
+ android:id="@+id/delete_target_text"
android:text="@string/delete_zone_label_workspace"
android:drawableLeft="@drawable/delete_zone_selector" />
- </FrameLayout>
+ </com.android.launcher2.DeleteDropTarget>
- <FrameLayout
+ <com.android.launcher2.InfoDropTarget
style="@style/DropTargetButtonContainer"
+ android:id="@+id/info_target"
android:layout_weight="1">
<!-- Info target -->
- <com.android.launcher2.InfoDropTarget
+ <TextView
style="@style/DropTargetButton"
- android:id="@+id/info_target"
+ android:id="@+id/info_target_text"
android:text="@string/info_target_label"
android:drawableLeft="@drawable/ic_home_info_holo_dark" />
- </FrameLayout>
+ </com.android.launcher2.InfoDropTarget>
</LinearLayout>
</com.android.launcher2.SearchDropTargetBar>
diff --git a/res/layout-port/user_folder.xml b/res/layout/user_folder.xml
similarity index 99%
rename from res/layout-port/user_folder.xml
rename to res/layout/user_folder.xml
index 0d383c1..5ef959d 100644
--- a/res/layout-port/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -4,9 +4,9 @@
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.
@@ -36,5 +36,4 @@
launcher:xAxisEndPadding="0dip"
launcher:yAxisStartPadding="8dip"
launcher:yAxisEndPadding="8dip"/>
-
</com.android.launcher2.Folder>
diff --git a/res/values-large-port/dimens.xml b/res/values-large-port/dimens.xml
index 89f8605..86bd03d 100644
--- a/res/values-large-port/dimens.xml
+++ b/res/values-large-port/dimens.xml
@@ -15,11 +15,18 @@
-->
<resources>
+ <dimen name="apps_customize_cell_width">96dp</dimen>
+ <dimen name="apps_customize_cell_height">96dp</dimen>
+ <!-- The amount of space to account for the next/prev pages when
+ calculating the number of columns to fit a page.
+ In portrait/large we use apps_customize_cell_width / 8. -->
+ <dimen name="apps_customize_peek_width">12dp</dimen>
+
<!-- the area at the edge of the screen that makes the workspace go left
or right while you're dragging. -->
<dimen name="scroll_zone">40dp</dimen>
- <dimen name="all_apps_view_pageLayoutWidthGap">36dp</dimen>
+ <dimen name="all_apps_view_pageLayoutWidthGap">24dp</dimen>
<dimen name="all_apps_view_pageLayoutHeightGap">36dp</dimen>
<dimen name="all_apps_view_pageLayoutPaddingTop">25dp</dimen>
<dimen name="all_apps_view_pageLayoutPaddingBottom">10dp</dimen>
diff --git a/res/values-large/config.xml b/res/values-large/config.xml
index dca8282..2a52664 100644
--- a/res/values-large/config.xml
+++ b/res/values-large/config.xml
@@ -7,7 +7,7 @@
<integer name="config_customizeZoomScaleFactor">7</integer>
<integer name="config_customizeFadeInTime">800</integer>
<!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
- <integer name="config_workspaceSpringLoadShrinkPercentage">70</integer>
+ <integer name="config_workspaceSpringLoadShrinkPercentage">90</integer>
<!-- The slope, in percent, of the drag movement needed to drag an item out of
Customize (y / x * 100%) -->
diff --git a/res/values-large/dimens.xml b/res/values-large/dimens.xml
index 970a200..924832a 100644
--- a/res/values-large/dimens.xml
+++ b/res/values-large/dimens.xml
@@ -15,8 +15,18 @@
-->
<resources>
+<!-- Workspace -->
+ <dimen name="qsb_bar_height">56dp</dimen>
+
<dimen name="apps_customize_cell_width">96dp</dimen>
<dimen name="apps_customize_cell_height">96dp</dimen>
+ <!-- The amount of space to account for the next/prev pages when
+ calculating the number of columns to fit a page.
+ In landscape/large we use apps_customize_cell_width / 4. -->
+ <dimen name="apps_customize_peek_width">48dp</dimen>
+ <dimen name="apps_customize_widget_cell_width_gap">36dp</dimen>
+ <dimen name="apps_customize_widget_cell_height_gap">36dp</dimen>
+
<dimen name="workspace_cell_width">96dip</dimen>
<dimen name="workspace_cell_height">96dip</dimen>
diff --git a/res/values-large/strings.xml b/res/values-large/strings.xml
index 75a22a2..97024fa 100644
--- a/res/values-large/strings.xml
+++ b/res/values-large/strings.xml
@@ -26,4 +26,14 @@
<!-- Negative button text for the wallpaper selection dialog [CHAR_LIMIT=40]-->
<string name="wallpaper_cancel">Cancel</string>
+
+ <!-- Label for delete drop target. [CHAR_LIMIT=30] -->
+ <string name="delete_target_label">Remove</string>
+ <!-- Label for uninstall drop target. [CHAR_LIMIT=30]-->
+ <string name="delete_target_uninstall_label">Uninstall</string>
+ <!-- Label for the info icon. [CHAR_LIMIT=30] -->
+ <string name="info_target_label">Manage</string>
+
+ <!-- Market button text [CHAR LIMIT=32] -->
+ <string name="market">Shop</string>
</resources>
\ No newline at end of file
diff --git a/res/values-large/styles.xml b/res/values-large/styles.xml
index 054d967..9c1532a 100644
--- a/res/values-large/styles.xml
+++ b/res/values-large/styles.xml
@@ -42,10 +42,14 @@
<item name="android:includeFontPadding">false</item>
</style>
+ <style name="WidgetDivider">
+ <item name="android:visibility">visible</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:paddingTop">10dp</item>
<item name="android:paddingBottom">20dp</item>
<item name="android:textSize">20sp</item>
</style>
@@ -53,6 +57,37 @@
<style name="CustomizeTabIndicator.Wide" parent="TabIndicator.Wide">
</style>
+
+ <!-- QSB Search / Drop Target bar -->
+ <style name="SearchDropTargetBar">
+ <item name="android:orientation">horizontal</item>
+ </style>
+ <style name="SearchButton">
+ <item name="android:layout_gravity">center_vertical</item>
+ <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
+ <item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
+ </style>
+ <style name="SearchButtonDivider">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_gravity">center_vertical</item>
+ </style>
+ <style name="DropTargetButtonContainer">
+ <item name="android:layout_width">0dp</item>
+ <item name="android:layout_height">match_parent</item>
+ </style>
+ <style name="DropTargetButton">
+ <item name="android:layout_width">wrap_content</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_gravity">center</item>
+ <item name="android:gravity">center_vertical</item>
+ <item name="android:drawablePadding">7.5dp</item>
+ <item name="android:textColor">#FFFFFFFF</item>
+ <item name="android:textSize">16sp</item>
+ </style>
+
<style name="config_orientation">
<item name="@android:screenOrientation">unspecified</item>
</style>
diff --git a/res/values-xlarge-port/dimens.xml b/res/values-xlarge-port/dimens.xml
new file mode 100644
index 0000000..31db0b3
--- /dev/null
+++ b/res/values-xlarge-port/dimens.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- The amount of space to account for the next/prev pages when
+ calculating the number of columns to fit a page.
+ In portrait/xlarge we use apps_customize_cell_width / 4. -->
+ <dimen name="apps_customize_peek_width">48dp</dimen>
+
+ <!-- We can also afford to have a slightly wider portrait layout in
+ xlarge -->
+ <dimen name="all_apps_view_pageLayoutWidthGap">36dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index ae1b7f7..ee48aa7 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -104,7 +104,6 @@
<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>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index e14fbfe..fd7b21c 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,8 +20,8 @@
<resources>
<!-- The color tints to apply to the text and drag view when hovering
over the delete target or the info target -->
- <color name="delete_target_hover_tint">#A5FF0000</color>
- <color name="info_target_hover_tint">#A50000FE</color>
+ <color name="delete_target_hover_tint">#D4FF3600</color>
+ <color name="info_target_hover_tint">#D40078FF</color>
<color name="window_background">#FF191919</color>
<color name="grid_dark_background">#EB191919</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index 394ff8a..06e8fda 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -43,6 +43,9 @@
<integer name="config_allAppsBatchSize">0</integer>
<!-- Workspace -->
+ <!-- The transition duration for the background of the drop targets -->
+ <integer name="config_dropTargetBgTransitionDuration">100</integer>
+
<integer name="config_crosshairsFadeInTime">600</integer>
<!-- When dragging an item on the workspace, how much bigger (in pixels) the dragged view
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f51f8b1..15dbc3a 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -27,6 +27,10 @@
<dimen name="app_icon_size">50dp</dimen>
<dimen name="apps_customize_cell_width">68dp</dimen>
<dimen name="apps_customize_cell_height">68dp</dimen>
+ <!-- In portrat/normal, we peek only 1/8th the app cell width -->
+ <dimen name="apps_customize_peek_width">9dp</dimen>
+ <dimen name="apps_customize_widget_cell_width_gap">10dp</dimen>
+ <dimen name="apps_customize_widget_cell_height_gap">10dp</dimen>
<dimen name="title_texture_width">120px</dimen>
<!-- height of the tab bar in AppsCustomize -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5ecfdd6..b3c6000 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -83,8 +83,8 @@
<string name="all_apps_no_games">No games found.</string>
<!-- Message to show when there are no downloaded apps [CHAR_LIMIT=50] -->
<string name="all_apps_no_downloads">You have no downloaded applications.</string>
- <!-- Market button text [CHAR LIMIT=32] -->
- <string name="market">Shop</string>
+ <!-- Market button text. The market button has no text in the Phone UI. [CHAR LIMIT=32] -->
+ <string name="market"></string>
<!-- Customization Drawer -->
<!-- The format string for the dimensions of a widget in the drawer -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index f2c07f7..5c458b4 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -68,6 +68,10 @@
<item name="android:layout_marginRight">10dip</item>
</style>
+ <style name="WidgetDivider">
+ <item name="android:visibility">gone</item>
+ </style>
+
<style name="SearchDropTargetBar">
<item name="android:orientation">horizontal</item>
</style>
@@ -89,12 +93,12 @@
</style>
<style name="DropTargetButton">
<item name="android:layout_width">wrap_content</item>
- <item name="android:layout_height">match_parent</item>
- <item name="android:layout_gravity">center_horizontal</item>
+ <item name="android:layout_height">wrap_content</item>
+ <item name="android:layout_gravity">center</item>
<item name="android:gravity">center_vertical</item>
<item name="android:drawablePadding">7.5dp</item>
- <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
- <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
+ <item name="android:textColor">#FFFFFFFF</item>
+ <item name="android:textSize">16sp</item>
</style>
<style name="TabIndicator">
diff --git a/src/com/android/launcher2/AllAppsPagedView.java b/src/com/android/launcher2/AllAppsPagedView.java
index ae8b970..5c8812d 100644
--- a/src/com/android/launcher2/AllAppsPagedView.java
+++ b/src/com/android/launcher2/AllAppsPagedView.java
@@ -208,7 +208,6 @@
@Override
public void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
- mLauncher.setAllAppsPagedView(this);
mDragController = dragController;
}
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index 94488a1..b765e17 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -81,7 +81,7 @@
};
// Create the tabs and wire them up properly
- AllAppsTabKeyEventListener keyListener = new AllAppsTabKeyEventListener();
+ AppsCustomizeTabKeyEventListener keyListener = new AppsCustomizeTabKeyEventListener();
TextView tabView;
TabWidget tabWidget = (TabWidget) findViewById(com.android.internal.R.id.tabs);
tabView = (TextView) mInflater.inflate(R.layout.tab_widget_indicator, tabWidget, false);
diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java
index 4390c59..eca5ad7 100644
--- a/src/com/android/launcher2/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -7,6 +7,7 @@
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
+import android.content.res.Resources;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -30,6 +31,11 @@
private boolean mTopBorderActive;
private boolean mBottomBorderActive;
+ private int mWidgetPaddingLeft;
+ private int mWidgetPaddingRight;
+ private int mWidgetPaddingTop;
+ private int mWidgetPaddingBottom;
+
private int mBaselineWidth;
private int mBaselineHeight;
private int mBaselineX;
@@ -103,6 +109,12 @@
Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
addView(mBottomHandle, lp);
+ Resources r = context.getResources();
+ mWidgetPaddingLeft = r.getDimensionPixelSize(R.dimen.app_widget_padding_left);
+ mWidgetPaddingTop = r.getDimensionPixelSize(R.dimen.app_widget_padding_top);
+ mWidgetPaddingRight = r.getDimensionPixelSize(R.dimen.app_widget_padding_right);
+ mWidgetPaddingBottom = r.getDimensionPixelSize(R.dimen.app_widget_padding_bottom);
+
if (mResizeMode == AppWidgetProviderInfo.RESIZE_HORIZONTAL) {
mTopHandle.setVisibility(GONE);
mBottomHandle.setVisibility(GONE);
@@ -294,10 +306,13 @@
int xOffset = mCellLayout.getLeft() + mCellLayout.getLeftPadding() - mWorkspace.getScrollX();
int yOffset = mCellLayout.getTop() + mCellLayout.getTopPadding() - mWorkspace.getScrollY();
- int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding;
- int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding;
- int newX = mWidgetView.getLeft() - mBackgroundPadding + xOffset;
- int newY = mWidgetView.getTop() - mBackgroundPadding + yOffset;
+ int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding - mWidgetPaddingLeft -
+ mWidgetPaddingRight;
+ int newHeight = mWidgetView.getHeight() + 2 * mBackgroundPadding - mWidgetPaddingTop -
+ mWidgetPaddingBottom;
+
+ int newX = mWidgetView.getLeft() - mBackgroundPadding + xOffset + mWidgetPaddingLeft;
+ int newY = mWidgetView.getTop() - mBackgroundPadding + yOffset + mWidgetPaddingTop;
// We need to make sure the frame stays within the bounds of the CellLayout
if (newY < 0) {
diff --git a/src/com/android/launcher2/ApplicationInfoDropTarget.java b/src/com/android/launcher2/ApplicationInfoDropTarget.java
index fa4663a..4a9727d 100644
--- a/src/com/android/launcher2/ApplicationInfoDropTarget.java
+++ b/src/com/android/launcher2/ApplicationInfoDropTarget.java
@@ -50,15 +50,13 @@
int colour = getContext().getResources().getColor(R.color.info_target_hover_tint);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(colour, PorterDuff.Mode.SRC_ATOP));
- 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(
- R.dimen.delete_zone_vertical_drag_padding);
- int lr = getResources().getDimensionPixelSize(
- R.dimen.delete_zone_horizontal_drag_padding);
- setDragPadding(tb, lr, tb, 0);
- }
+ // 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(
+ R.dimen.delete_zone_vertical_drag_padding);
+ int lr = getResources().getDimensionPixelSize(
+ R.dimen.delete_zone_horizontal_drag_padding);
+ setDragPadding(tb, lr, tb, 0);
}
public boolean acceptDrop(DragObject d) {
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 464bb44..dfdbce9 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -16,11 +16,8 @@
package com.android.launcher2;
-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.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
@@ -30,12 +27,13 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;
-import android.graphics.Bitmap.Config;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
@@ -44,8 +42,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -88,9 +84,10 @@
private IconCache mIconCache;
// Dimens
+ private Runnable mOnSizeChangedCallback;
private int mContentWidth;
private int mMaxWidgetSpan, mMinWidgetSpan;
- private int mCellWidthGap, mCellHeightGap;
+ private int mWidgetWidthGap, mWidgetHeightGap;
private int mWidgetCountX, mWidgetCountY;
private final int mWidgetPreviewIconPaddedDimension;
private final float sWidgetPreviewIconPaddingPercentage = 0.25f;
@@ -120,23 +117,19 @@
mDefaultWidgetBackground = resources.getDrawable(R.drawable.default_widget_preview);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PagedView, 0, 0);
+ // TODO-APPS_CUSTOMIZE: remove these unnecessary attrs after
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);
+ mWidgetWidthGap =
+ a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellWidthGap, 0);
+ mWidgetHeightGap =
+ a.getDimensionPixelSize(R.styleable.AppsCustomizePagedView_widgetCellHeightGap, 0);
mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2);
mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 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();
+ mWidgetSpacingLayout = new PagedViewCellLayout(getContext());
// 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
@@ -160,6 +153,70 @@
setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
}
+ @Override
+ protected void onWallpaperTap(android.view.MotionEvent ev) {
+ mLauncher.showWorkspace(true);
+ }
+
+ /**
+ * This differs from isDataReady as this is the test done if isDataReady is not set.
+ */
+ private boolean testDataReady() {
+ return !mApps.isEmpty() && !mWidgets.isEmpty();
+ }
+
+ protected void onDataReady(int width, int height) {
+ // Note that we transpose the counts in portrait so that we get a similar layout
+ boolean isLandscape = getResources().getConfiguration().orientation ==
+ Configuration.ORIENTATION_LANDSCAPE;
+ int maxCellCountX = Integer.MAX_VALUE;
+ int maxCellCountY = Integer.MAX_VALUE;
+ if (LauncherApplication.isScreenLarge()) {
+ maxCellCountX = (isLandscape ? LauncherModel.getCellCountX() :
+ LauncherModel.getCellCountY());
+ maxCellCountY = (isLandscape ? LauncherModel.getCellCountY() :
+ LauncherModel.getCellCountX());
+ }
+
+ // Now that the data is ready, we can calculate the content width, the number of cells to
+ // use for each page
+ mWidgetSpacingLayout.setGap(mPageLayoutWidthGap, mPageLayoutHeightGap);
+ mWidgetSpacingLayout.setPadding(mPageLayoutPaddingLeft, mPageLayoutPaddingTop,
+ mPageLayoutPaddingRight, mPageLayoutPaddingBottom);
+ mWidgetSpacingLayout.calculateCellCount(width, height, maxCellCountX, maxCellCountY);
+ mCellCountX = mWidgetSpacingLayout.getCellCountX();
+ mCellCountY = mWidgetSpacingLayout.getCellCountY();
+ mWidgetCountX = Math.max(1, (int) Math.round(mCellCountX / 2f));
+ mWidgetCountY = Math.max(1, (int) Math.round(mCellCountY / 3f));
+ mContentWidth = mWidgetSpacingLayout.getContentWidth();
+
+ // Notify our parent so that we can synchronize the tab bar width to this page width
+ if (mOnSizeChangedCallback != null) {
+ mOnSizeChangedCallback.run();
+ }
+
+ invalidatePageData();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ int height = MeasureSpec.getSize(heightMeasureSpec);
+ if (!isDataReady()) {
+ if (testDataReady()) {
+ setDataIsReady();
+ setMeasuredDimension(width, height);
+ onDataReady(width, height);
+ }
+ }
+
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+ public void setOnSizeChangedCallback(Runnable r) {
+ mOnSizeChangedCallback = r;
+ }
+
/** Removes and returns the ResolveInfo with the specified ComponentName */
private ResolveInfo removeResolveInfoWithComponentName(List<ResolveInfo> list,
ComponentName cn) {
@@ -179,108 +236,20 @@
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,
+ List<AppWidgetProviderInfo> widgets =
+ AppWidgetManager.getInstance(mLauncher).getInstalledProviders();
+ Collections.sort(widgets,
new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
- }
+ Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
+ List<ResolveInfo> shortcuts = mPackageManager.queryIntentActivities(shortcutsIntent, 0);
+ Collections.sort(shortcuts,
+ new LauncherModel.WidgetAndShortcutNameComparator(mPackageManager));
+ mWidgets.addAll(widgets);
+ mWidgets.addAll(shortcuts);
- /**
- * 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();
+ // The next layout pass will trigger data-ready if both widgets and apps are set, so request
+ // a layout to do this test and invalidate the page data when ready.
+ if (testDataReady()) requestLayout();
}
@Override
@@ -324,24 +293,6 @@
// 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];
@@ -542,6 +493,10 @@
int y = index / mCellCountX;
layout.addViewToCellLayout(icon, -1, i, new PagedViewCellLayout.LayoutParams(x,y, 1,1));
}
+
+ // Create the hardware layers
+ layout.allowHardwareLayerCreation();
+ layout.createHardwareLayers();
}
/*
* Widgets PagedView implementation
@@ -585,14 +540,11 @@
// 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);
+ renderDrawableToBitmap(icon, preview, 0, 0, iconSize, iconSize, 1f, 1f);
FastBitmapDrawable iconDrawable = new FastBitmapDrawable(preview);
iconDrawable.setBounds(0, 0, expectedWidth, expectedHeight);
mWidgetPreviewCache.put(info, preview);
@@ -706,9 +658,9 @@
int numPages = (int) Math.ceil(mWidgets.size() / (float) numWidgetsPerPage);
int offset = page * numWidgetsPerPage;
int cellWidth = ((mWidgetSpacingLayout.getContentWidth() - mPageLayoutWidthGap
- - ((mWidgetCountX - 1) * mCellWidthGap)) / mWidgetCountX);
+ - ((mWidgetCountX - 1) * mWidgetWidthGap)) / mWidgetCountX);
int cellHeight = ((mWidgetSpacingLayout.getContentHeight() - mPageLayoutHeightGap
- - ((mWidgetCountY - 1) * mCellHeightGap)) / mWidgetCountY);
+ - ((mWidgetCountY - 1) * mWidgetHeightGap)) / mWidgetCountY);
for (int i = 0; i < Math.min(numWidgetsPerPage, mWidgets.size() - offset); ++i) {
Object rawInfo = mWidgets.get(offset + i);
PendingAddItemInfo createItemInfo = null;
@@ -746,8 +698,8 @@
int iy = i / mWidgetCountX;
PagedViewGridLayout.LayoutParams lp = new PagedViewGridLayout.LayoutParams(cellWidth,
cellHeight);
- lp.leftMargin = (ix * cellWidth) + (ix * mCellWidthGap);
- lp.topMargin = (iy * cellHeight) + (iy * mCellHeightGap);
+ lp.leftMargin = (ix * cellWidth) + (ix * mWidgetWidthGap);
+ lp.topMargin = (iy * cellHeight) + (iy * mWidgetHeightGap);
layout.addView(widget, lp);
}
}
@@ -836,7 +788,10 @@
public void setApps(ArrayList<ApplicationInfo> list) {
mApps = list;
Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
- invalidatePageData();
+
+ // The next layout pass will trigger data-ready if both widgets and apps are set, so request
+ // a layout to do this test and invalidate the page data when ready.
+ if (testDataReady()) requestLayout();
}
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {
// We add it in place, in alphabetical order
diff --git a/src/com/android/launcher2/AppsCustomizeTabHost.java b/src/com/android/launcher2/AppsCustomizeTabHost.java
index e40524d..51db66c 100644
--- a/src/com/android/launcher2/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher2/AppsCustomizeTabHost.java
@@ -16,6 +16,7 @@
package com.android.launcher2;
+import android.animation.Animator;
import android.content.Context;
import android.content.res.Resources;
import android.util.AttributeSet;
@@ -24,6 +25,7 @@
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;
@@ -36,6 +38,7 @@
private static final String WIDGETS_TAB_TAG = "WIDGETS";
private final LayoutInflater mLayoutInflater;
+ private ViewGroup mTabs;
private AppsCustomizePagedView mAppsCustomizePane;
public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
@@ -43,6 +46,9 @@
mLayoutInflater = LayoutInflater.from(context);
}
+ /**
+ * Convenience methods to select specific tabs
+ */
void selectAppsTab() {
setCurrentTabByTag(APPS_TAB_TAG);
}
@@ -58,9 +64,10 @@
// Setup the tab host
setup();
- final ViewGroup tabs = (ViewGroup) findViewById(com.android.internal.R.id.tabs);
+ final TabWidget tabs = (TabWidget) findViewById(com.android.internal.R.id.tabs);
final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView)
findViewById(R.id.apps_customize_pane_content);
+ mTabs = tabs;
mAppsCustomizePane = appsCustomizePane;
if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException();
@@ -82,8 +89,24 @@
addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
setOnTabChangedListener(this);
- // Set the width of the tab bar to match the content (for now)
- tabs.getLayoutParams().width = mAppsCustomizePane.getPageContentWidth();
+ // Setup the key listener to jump between the last tab view and the market icon
+ AppsCustomizeTabKeyEventListener keyListener = new AppsCustomizeTabKeyEventListener();
+ View lastTab = tabs.getChildTabViewAt(tabs.getTabCount() - 1);
+ lastTab.setOnKeyListener(keyListener);
+ View shopButton = findViewById(R.id.market_button);
+ shopButton.setOnKeyListener(keyListener);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ boolean remeasureTabWidth = (mTabs.getLayoutParams().width <= 0);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ // Set the width of the tab list to the content width
+ if (remeasureTabWidth) {
+ mTabs.getLayoutParams().width = mAppsCustomizePane.getPageContentWidth();
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
}
@Override
@@ -138,11 +161,21 @@
/* LauncherTransitionable overrides */
@Override
- public void onLauncherTransitionStart(android.animation.Animator animation) {
- // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionStart();
+ public void onLauncherTransitionStart(Animator animation) {
+ if (animation != null) {
+ // Turn on hardware layers for performance
+ setLayerType(LAYER_TYPE_HARDWARE, null);
+
+ // force building the layer at the beginning of the animation, so you don't get a
+ // blip early in the animation
+ buildLayer();
+ }
}
+
@Override
- public void onLauncherTransitionEnd(android.animation.Animator animation) {
- // TODO-APPS_CUSTOMIZE: see AllAppsTabbed.onLauncherTransitionEnd();
+ public void onLauncherTransitionEnd(Animator animation) {
+ if (animation != null) {
+ setLayerType(LAYER_TYPE_NONE, null);
+ }
}
}
diff --git a/src/com/android/launcher2/ButtonDropTarget.java b/src/com/android/launcher2/ButtonDropTarget.java
new file mode 100644
index 0000000..e3da860
--- /dev/null
+++ b/src/com/android/launcher2/ButtonDropTarget.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher2;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.android.launcher.R;
+
+
+/**
+ * Implements a DropTarget.
+ */
+public class ButtonDropTarget extends FrameLayout implements DropTarget, DragController.DragListener {
+
+ protected final int mTransitionDuration;
+
+ protected Launcher mLauncher;
+
+ /** Whether this drop target is active for the current drag */
+ protected boolean mActive;
+
+ /** The paint applied to the drag view on hover */
+ protected final Paint mHoverPaint = new Paint();
+
+ public ButtonDropTarget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ButtonDropTarget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mTransitionDuration =
+ context.getResources().getInteger(R.integer.config_dropTargetBgTransitionDuration);
+ }
+
+ void setLauncher(Launcher launcher) {
+ mLauncher = launcher;
+ }
+
+ public boolean acceptDrop(DragObject d) {
+ return false;
+ }
+
+ public void onDrop(DragObject d) {
+ // Do nothing
+ }
+
+ public void onDragEnter(DragObject d) {
+ d.dragView.setPaint(mHoverPaint);
+ }
+
+ public void onDragOver(DragObject d) {
+ // Do nothing
+ }
+
+ public void onDragExit(DragObject d) {
+ d.dragView.setPaint(null);
+ }
+
+ public void onDragStart(DragSource source, Object info, int dragAction) {
+ // Do nothing
+ }
+
+ public boolean isDropEnabled() {
+ return mActive;
+ }
+
+ public void onDragEnd() {
+ // Do nothing
+ }
+
+ @Override
+ public DropTarget getDropTargetDelegate(DragObject d) {
+ return null;
+ }
+}
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index e5aa7a9..a9ba88d 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -20,6 +20,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
@@ -48,6 +49,7 @@
import com.android.launcher.R;
import java.util.Arrays;
+import java.util.HashMap;
public class CellLayout extends ViewGroup {
static final String TAG = "CellLayout";
@@ -118,6 +120,9 @@
private InterruptibleInOutAnimator mCrosshairsAnimator = null;
private float mCrosshairsVisibility = 0.0f;
+ private HashMap<CellLayout.LayoutParams, ObjectAnimator> mReorderAnimators = new
+ HashMap<CellLayout.LayoutParams, ObjectAnimator>();
+
// When a drag operation is in progress, holds the nearest cell to the touch point
private final int[] mDragCell = new int[2];
@@ -966,6 +971,64 @@
return mChildren.getChildAt(x, y);
}
+ public boolean animateChildToPosition(final View child, int cellX, int cellY, int duration) {
+ CellLayoutChildren clc = getChildrenLayout();
+ if (clc.indexOfChild(child) != -1 && !mOccupied[cellX][cellY]) {
+ final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final ItemInfo info = (ItemInfo) child.getTag();
+
+ // We cancel any existing animations
+ if (mReorderAnimators.containsKey(lp)) {
+ mReorderAnimators.get(lp).cancel();
+ mReorderAnimators.remove(lp);
+ }
+
+ int oldX = lp.x;
+ int oldY = lp.y;
+ mOccupied[lp.cellX][lp.cellY] = false;
+ mOccupied[cellX][cellY] = true;
+
+ lp.isLockedToGrid = true;
+ lp.cellX = info.cellX = cellX;
+ lp.cellY = info.cellY = cellY;
+ clc.setupLp(lp);
+ lp.isLockedToGrid = false;
+ int newX = lp.x;
+ int newY = lp.y;
+
+ PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", oldX, newX);
+ PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", oldY, newY);
+ ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, x, y);
+ oa.setDuration(duration);
+ mReorderAnimators.put(lp, oa);
+ oa.addUpdateListener(new AnimatorUpdateListener() {
+ public void onAnimationUpdate(ValueAnimator animation) {
+ child.requestLayout();
+ }
+ });
+ oa.addListener(new AnimatorListenerAdapter() {
+ boolean cancelled = false;
+ public void onAnimationEnd(Animator animation) {
+ // If the animation was cancelled, it means that another animation
+ // has interrupted this one, and we don't want to lock the item into
+ // place just yet.
+ if (!cancelled) {
+ lp.isLockedToGrid = true;
+ }
+ if (mReorderAnimators.containsKey(lp)) {
+ mReorderAnimators.remove(lp);
+ }
+ }
+ public void onAnimationCancel(Animator animation) {
+ cancelled = true;
+ }
+ });
+ oa.start();
+ return true;
+ }
+ return false;
+ }
+
/**
* Estimate where the top left cell of the dragged item will land if it is dropped.
*
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java
index 59db9c9..6e78885 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -79,6 +79,10 @@
setMeasuredDimension(widthSpecSize, heightSpecSize);
}
+ public void setupLp(CellLayout.LayoutParams lp) {
+ lp.setup(mCellWidth, mCellHeight, mWidthGap, mHeightGap);
+ }
+
public void measureChild(View child) {
final int cellWidth = mCellWidth;
final int cellHeight = mCellHeight;
diff --git a/src/com/android/launcher2/DeleteDropTarget.java b/src/com/android/launcher2/DeleteDropTarget.java
index 4986a31..5b3fd1e 100644
--- a/src/com/android/launcher2/DeleteDropTarget.java
+++ b/src/com/android/launcher2/DeleteDropTarget.java
@@ -16,23 +16,22 @@
package com.android.launcher2;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.TransitionDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.TextView;
import com.android.launcher.R;
-public class DeleteDropTarget extends IconDropTarget {
+public class DeleteDropTarget extends ButtonDropTarget {
- private static final int sTransitionDuration = 0;
-
- private TransitionDrawable mIcon;
- private int mDefaultTextColor;
+ private TextView mText;
private int mHoverColor = 0xFFFF0000;
public DeleteDropTarget(Context context, AttributeSet attrs) {
@@ -48,14 +47,15 @@
super.onFinishInflate();
// Get the drawable
- mIcon = (TransitionDrawable) getCompoundDrawables()[0];
+ mText = (TextView) findViewById(R.id.delete_target_text);
// Get the hover color
Resources r = getResources();
- mDefaultTextColor = getTextColors().getDefaultColor();
mHoverColor = r.getColor(R.color.delete_target_hover_tint);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(
mHoverColor, PorterDuff.Mode.SRC_ATOP));
+ setBackgroundColor(mHoverColor);
+ getBackground().setAlpha(0);
}
private boolean isAllAppsApplication(DragSource source, Object info) {
@@ -82,11 +82,10 @@
@Override
public void onDragStart(DragSource source, Object info, int dragAction) {
- ItemInfo item = (ItemInfo) info;
boolean isVisible = true;
boolean isUninstall = false;
- // If we are dragging a widget from AppsCustomize , hide the delete target
+ // If we are dragging a widget from AppsCustomize, hide the delete target
if (isAllAppsWidget(source, info)) {
isVisible = false;
}
@@ -103,9 +102,9 @@
}
mActive = isVisible;
- ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
- if (getText().length() > 0) {
- setText(isUninstall ? R.string.delete_target_uninstall_label
+ setVisibility(isVisible ? View.VISIBLE : View.GONE);
+ if (mText.getText().length() > 0) {
+ mText.setText(isUninstall ? R.string.delete_target_uninstall_label
: R.string.delete_target_label);
}
}
@@ -119,15 +118,18 @@
public void onDragEnter(DragObject d) {
super.onDragEnter(d);
- mIcon.startTransition(sTransitionDuration);
- setTextColor(mHoverColor);
+ ObjectAnimator anim = ObjectAnimator.ofInt(getBackground(), "alpha",
+ Color.alpha(mHoverColor));
+ anim.setDuration(mTransitionDuration);
+ anim.start();
}
public void onDragExit(DragObject d) {
super.onDragExit(d);
- mIcon.resetTransition();
- setTextColor(mDefaultTextColor);
+ ObjectAnimator anim = ObjectAnimator.ofInt(getBackground(), "alpha", 0);
+ anim.setDuration(mTransitionDuration);
+ anim.start();
}
public void onDrop(DragObject d) {
diff --git a/src/com/android/launcher2/DragController.java b/src/com/android/launcher2/DragController.java
index 8ad5c7c..5b1b20a 100644
--- a/src/com/android/launcher2/DragController.java
+++ b/src/com/android/launcher2/DragController.java
@@ -284,6 +284,7 @@
mDragging = true;
+ mDragObject.dragComplete = false;
mDragObject.xOffset = mMotionDownX - (screenX + dragRegionLeft);
mDragObject.yOffset = mMotionDownY - (screenY + dragRegionTop);
mDragObject.dragSource = source;
@@ -373,6 +374,7 @@
public void cancelDrag() {
if (mDragging) {
// Should we also be calling onDragExit() here?
+ mDragObject.dragComplete = true;
mDragObject.dragSource.onDropCompleted(null, mDragObject, false);
}
endDrag();
@@ -565,6 +567,7 @@
mDragObject.y = coordinates[1];
boolean accepted = false;
if (dropTarget != null) {
+ mDragObject.dragComplete = true;
dropTarget.onDragExit(mDragObject);
if (dropTarget.acceptDrop(mDragObject)) {
dropTarget.onDrop(mDragObject);
diff --git a/src/com/android/launcher2/DropTarget.java b/src/com/android/launcher2/DropTarget.java
index 9c0faf3..6e18479 100644
--- a/src/com/android/launcher2/DropTarget.java
+++ b/src/com/android/launcher2/DropTarget.java
@@ -34,6 +34,12 @@
/** Y offset from the upper-left corner of the cell to where we touched. */
public int yOffset = -1;
+ /** This indicates whether a drag is in final stages, either drop or cancel. It
+ * differentiates onDragExit, since this is called when the drag is ending, above
+ * the current drag target, or when the drag moves off the current drag object.
+ */
+ public boolean dragComplete = false;
+
/** The view that moves around while you drag. */
public DragView dragView = null;
diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java
index 861a70b..25d941b 100644
--- a/src/com/android/launcher2/FocusHelper.java
+++ b/src/com/android/launcher2/FocusHelper.java
@@ -16,10 +16,6 @@
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;
@@ -30,6 +26,10 @@
import com.android.launcher.R;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
/**
* A keyboard listener we set on all the button bar buttons.
*/
@@ -62,13 +62,13 @@
}
/**
- * A keyboard listener we set on the last tab button in AllApps to jump to then
+ * A keyboard listener we set on the last tab button in AppsCustomize to jump to then
* market icon and vice versa.
*/
-class AllAppsTabKeyEventListener implements View.OnKeyListener {
+class AppsCustomizeTabKeyEventListener implements View.OnKeyListener {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
- return FocusHelper.handleAllAppsTabKeyEvent(v, keyCode, event);
+ return FocusHelper.handleAppsCustomizeTabKeyEvent(v, keyCode, event);
}
}
@@ -85,9 +85,9 @@
}
/**
- * Handles key events in a AllApps tab between the last tab view and the shop button.
+ * Handles key events in a AppsCustomize tab between the last tab view and the shop button.
*/
- static boolean handleAllAppsTabKeyEvent(View v, int keyCode, KeyEvent e) {
+ static boolean handleAppsCustomizeTabKeyEvent(View v, int keyCode, KeyEvent e) {
final TabHost tabHost = findTabHostParent(v);
final ViewGroup contents = (ViewGroup)
tabHost.findViewById(com.android.internal.R.id.tabcontent);
@@ -129,124 +129,6 @@
/**
* 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) {
@@ -908,7 +790,7 @@
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);
+ final ViewGroup tabs = (ViewGroup) launcher.findViewById(R.id.qsb_bar);
int iconIndex = parent.indexOfChild(v);
int iconCount = parent.getChildCount();
int pageIndex = workspace.indexOfChild(layout);
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index d6be307..d81183c 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -23,6 +23,7 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
+import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
@@ -54,11 +55,6 @@
protected Launcher mLauncher;
protected FolderInfo mInfo;
-
- /**
- * Which item is being dragged
- */
- protected ShortcutInfo mDragItem;
private static final String TAG = "Launcher.Folder";
@@ -75,6 +71,8 @@
private int[] mDragItemPosition = new int[2];
private static final int FULL_GROW = 0;
private static final int PARTIAL_GROW = 1;
+ private static final int REORDER_ANIMATION_DURATION = 230;
+ private static final int ON_EXIT_CLOSE_DELAY = 800;
private int mMode = PARTIAL_GROW;
private boolean mRearrangeOnClose = false;
private FolderIcon mFolderIcon;
@@ -84,7 +82,14 @@
private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
private Drawable mIconDrawable;
boolean mItemsInvalidated = false;
- ShortcutInfo mCurrentDragInfo;
+ private ShortcutInfo mCurrentDragInfo;
+ private View mCurrentDragView;
+ boolean mSuppressOnAdd = false;
+ private int[] mTargetCell = new int[2];
+ private int[] mPreviousTargetCell = new int[2];
+ private int[] mEmptyCell = new int[2];
+ private Alarm mReorderAlarm = new Alarm();
+ private Alarm mOnExitAlarm = new Alarm();
/**
* Used to inflate the Workspace from XML.
@@ -136,8 +141,6 @@
public boolean onLongClick(View v) {
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
- mLauncher.closeFolder(this);
-
ShortcutInfo item = (ShortcutInfo) tag;
if (!v.isInTouchMode()) {
return false;
@@ -150,10 +153,11 @@
mIconDrawable = ((TextView) v).getCompoundDrawables()[1];
mCurrentDragInfo = item;
- mItemsInvalidated = true;
- mInfo.itemsChanged();
-
- mDragItem = item;
+ mEmptyCell[0] = item.cellX;
+ mEmptyCell[1] = item.cellY;
+ mCurrentDragView = v;
+ mContent.removeView(mCurrentDragView);
+ mInfo.remove(item);
} else {
mLauncher.closeFolder(this);
mLauncher.showRenameDialog(mInfo);
@@ -182,8 +186,6 @@
mDragController.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
mLauncher.closeFolder(this);
- mDragItem = app;
-
return true;
}
@@ -382,25 +384,6 @@
!isFull());
}
- public void onDrop(DragObject d) {
- ShortcutInfo item;
- if (d.dragInfo instanceof ApplicationInfo) {
- // Came from all apps -- make a copy
- item = ((ApplicationInfo) d.dragInfo).makeShortcut();
- item.spanX = 1;
- item.spanY = 1;
- } else {
- item = (ShortcutInfo) d.dragInfo;
- }
-
- // Dragged from self onto self
- if (item == mCurrentDragInfo) {
- mInfo.remove(item);
- }
-
- mInfo.add(item);
- }
-
protected boolean findAndSetEmptyCells(ShortcutInfo item) {
int[] emptyCell = new int[2];
if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
@@ -430,46 +413,135 @@
}
public void onDragEnter(DragObject d) {
+ mPreviousTargetCell[0] = -1;
+ mPreviousTargetCell[1] = -1;
mContent.onDragEnter();
+ mOnExitAlarm.cancelAlarm();
+ }
+
+ OnAlarmListener mReorderAlarmListener = new OnAlarmListener() {
+ public void onAlarm(Alarm alarm) {
+ realTimeReorder(mEmptyCell, mTargetCell);
+ }
+ };
+
+ boolean readingOrderGreaterThan(int[] v1, int[] v2) {
+ if (v1[1] > v2[1] || (v1[1] == v2[1] && v1[0] > v2[0])) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void realTimeReorder(int[] empty, int[] target) {
+ boolean wrap;
+ int startX;
+ int endX;
+ int startY;
+ if (readingOrderGreaterThan(target, empty)) {
+ wrap = empty[0] >= mContent.getCountX() - 1;
+ startY = wrap ? empty[1] + 1 : empty[1];
+ for (int y = startY; y <= target[1]; y++) {
+ startX = y == empty[1] ? empty[0] + 1 : 0;
+ endX = y < target[1] ? mContent.getCountX() - 1 : target[0];
+ for (int x = startX; x <= endX; x++) {
+ View v = mContent.getChildAt(x,y);
+ if (mContent.animateChildToPosition(v, empty[0], empty[1],
+ REORDER_ANIMATION_DURATION)) {
+ empty[0] = x;
+ empty[1] = y;
+ }
+ }
+ }
+ } else {
+ wrap = empty[0] == 0;
+ startY = wrap ? empty[1] - 1 : empty[1];
+ for (int y = startY; y >= target[1]; y--) {
+ startX = y == empty[1] ? empty[0] - 1 : mContent.getCountX() - 1;
+ endX = y > target[1] ? 0 : target[0];
+ for (int x = startX; x >= endX; x--) {
+ View v = mContent.getChildAt(x,y);
+ if (mContent.animateChildToPosition(v, empty[0], empty[1],
+ REORDER_ANIMATION_DURATION)) {
+ empty[0] = x;
+ empty[1] = y;
+ }
+ }
+ }
+ }
}
public void onDragOver(DragObject d) {
- float[] r = mapPointFromScreenToContent(d.x, d.y, null);
- mContent.visualizeDropLocation(null, null, (int) r[0], (int) r[1], 1, 1);
+ float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView, null);
+ mTargetCell = mContent.findNearestArea((int) r[0], (int) r[1], 1, 1, mTargetCell);
+
+ if (mTargetCell[0] != mPreviousTargetCell[0] || mTargetCell[1] != mPreviousTargetCell[1]) {
+ mReorderAlarm.cancelAlarm();
+ mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
+ mReorderAlarm.setAlarm(150);
+ mPreviousTargetCell[0] = mTargetCell[0];
+ mPreviousTargetCell[1] = mTargetCell[1];
+ }
}
+ // This is used to compute the visual center of the dragView. 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;
+ }
+
+ // 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;
+ }
+
+ OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() {
+ public void onAlarm(Alarm alarm) {
+ mLauncher.closeFolder(Folder.this);
+ mCurrentDragInfo = null;
+ mCurrentDragView = null;
+ mSuppressOnAdd = false;
+ mRearrangeOnClose = true;
+ }
+ };
+
public void onDragExit(DragObject d) {
+ // We only close the folder if this is a true drag exit, ie. not because a drop
+ // has occurred above the folder.
+ if (!d.dragComplete) {
+ mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener);
+ mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY);
+ }
+ mReorderAlarm.cancelAlarm();
mContent.onDragExit();
}
- public float[] mapPointFromScreenToContent(int x, int y, float[] r) {
- if (r == null) {
- r = new float[2];
- }
-
- int[] screenLocation = new int[2];
- mContent.getLocationOnScreen(screenLocation);
-
- r[0] = x - screenLocation[0];
- r[1] = y - screenLocation[1];
- return r;
- }
-
public void onDropCompleted(View target, DragObject d, boolean success) {
+ mCurrentDragInfo = null;
+ mCurrentDragView = null;
+ mSuppressOnAdd = false;
if (!success) {
if (d.dragView != null) {
if (target instanceof CellLayout) {
// TODO: we should animate the item back to the folder in this case
}
}
- mCurrentDragInfo = null;
- mItemsInvalidated = true;
- mInfo.itemsChanged();
- } else {
- if (target != this) {
- mInfo.remove(mCurrentDragInfo);
- mCurrentDragInfo = null;
- }
+ // TODO: if the drag fails, we need to re-add the item
}
}
@@ -594,18 +666,6 @@
mItemsInvalidated = true;
}
- public void onAdd(ShortcutInfo item) {
- mItemsInvalidated = true;
- if (!findAndSetEmptyCells(item)) {
- // The current layout is full, can we expand it?
- setupContentForNumItems(getItemCount() + 1);
- findAndSetEmptyCells(item);
- }
- createAndAddShortcut(item);
- LauncherModel.addOrMoveItemInDatabase(
- mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
- }
-
public int getItemCount() {
return mContent.getChildrenLayout().getChildCount();
}
@@ -621,8 +681,46 @@
}
}
+ public void onDrop(DragObject d) {
+ ShortcutInfo item;
+ if (d.dragInfo instanceof ApplicationInfo) {
+ // Came from all apps -- make a copy
+ item = ((ApplicationInfo) d.dragInfo).makeShortcut();
+ item.spanX = 1;
+ item.spanY = 1;
+ } else {
+ item = (ShortcutInfo) d.dragInfo;
+ }
+ // Dragged from self onto self
+ if (item == mCurrentDragInfo) {
+ ShortcutInfo si = (ShortcutInfo) mCurrentDragView.getTag();
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mCurrentDragView.getLayoutParams();
+ si.cellX = lp.cellX = mEmptyCell[0];
+ si.cellX = lp.cellY = mEmptyCell[1];
+ mContent.addViewToCellLayout(mCurrentDragView, -1, (int)item.id, lp, true);
+ mSuppressOnAdd = true;
+ mItemsInvalidated = true;
+ setupContentDimension(getItemCount());
+ }
+ mInfo.add(item);
+ }
+
+ public void onAdd(ShortcutInfo item) {
+ mItemsInvalidated = true;
+ if (mSuppressOnAdd) return;
+ if (!findAndSetEmptyCells(item)) {
+ // The current layout is full, can we expand it?
+ setupContentForNumItems(getItemCount() + 1);
+ findAndSetEmptyCells(item);
+ }
+ createAndAddShortcut(item);
+ LauncherModel.addOrMoveItemInDatabase(
+ mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
+ }
+
public void onRemove(ShortcutInfo item) {
mItemsInvalidated = true;
+ if (item == mCurrentDragInfo) return;
View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
mContent.removeView(v);
if (mState == STATE_ANIMATING) {
diff --git a/src/com/android/launcher2/IconDropTarget.java b/src/com/android/launcher2/IconDropTarget.java
index a091f6c..202b38d 100644
--- a/src/com/android/launcher2/IconDropTarget.java
+++ b/src/com/android/launcher2/IconDropTarget.java
@@ -28,7 +28,7 @@
* Implements a DropTarget which allows applications to be dropped on it,
* in order to launch the application info for that app.
*/
-public class IconDropTarget extends TextView implements DropTarget, DragController.DragListener {
+public class IconDropTarget extends StrokedTextView implements DropTarget, DragController.DragListener {
protected Launcher mLauncher;
/**
diff --git a/src/com/android/launcher2/InfoDropTarget.java b/src/com/android/launcher2/InfoDropTarget.java
index bbde2b8..7e6b700 100644
--- a/src/com/android/launcher2/InfoDropTarget.java
+++ b/src/com/android/launcher2/InfoDropTarget.java
@@ -16,20 +16,20 @@
package com.android.launcher2;
+import android.animation.ObjectAnimator;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import android.view.View;
-import android.view.ViewGroup;
import com.android.launcher.R;
-public class InfoDropTarget extends IconDropTarget {
+public class InfoDropTarget extends ButtonDropTarget {
- private int mDefaultTextColor;
private int mHoverColor = 0xFF0000FF;
public InfoDropTarget(Context context, AttributeSet attrs) {
@@ -46,10 +46,11 @@
// Get the hover color
Resources r = getResources();
- mDefaultTextColor = getTextColors().getDefaultColor();
mHoverColor = r.getColor(R.color.info_target_hover_tint);
mHoverPaint.setColorFilter(new PorterDuffColorFilter(
mHoverColor, PorterDuff.Mode.SRC_ATOP));
+ setBackgroundColor(mHoverColor);
+ getBackground().setAlpha(0);
}
private boolean isApplication(Object info) {
@@ -85,7 +86,7 @@
}
mActive = isVisible;
- ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
+ setVisibility(isVisible ? View.VISIBLE : View.GONE);
}
@Override
@@ -97,12 +98,17 @@
public void onDragEnter(DragObject d) {
super.onDragEnter(d);
- setTextColor(mHoverColor);
+ ObjectAnimator anim = ObjectAnimator.ofInt(getBackground(), "alpha",
+ Color.alpha(mHoverColor));
+ anim.setDuration(mTransitionDuration);
+ anim.start();
}
public void onDragExit(DragObject d) {
super.onDragExit(d);
- setTextColor(mDefaultTextColor);
+ ObjectAnimator anim = ObjectAnimator.ofInt(getBackground(), "alpha", 0);
+ anim.setDuration(mTransitionDuration);
+ anim.start();
}
}
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 6279b78..7d2c741 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -23,7 +23,6 @@
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -40,12 +39,12 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.Intent.ShortcutIconResource;
+import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -79,10 +78,9 @@
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
@@ -91,7 +89,6 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
-import android.widget.TabHost;
import android.widget.TextView;
import android.widget.Toast;
@@ -167,8 +164,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, APPS_CUSTOMIZE, ALL_APPS, CUSTOMIZE,
- APPS_CUSTOMIZE_SPRING_LOADED };
+ private enum State { WORKSPACE, APPS_CUSTOMIZE, APPS_CUSTOMIZE_SPRING_LOADED };
private State mState = State.WORKSPACE;
private AnimatorSet mStateAnimation;
@@ -198,21 +194,12 @@
private FolderInfo mFolderInfo;
private DeleteZone mDeleteZone;
- private HandleView mHandleView;
- private SearchDropTargetBar mSearchDeleteBar;
- private AllAppsView mAllAppsGrid;
- private AppsCustomizeTabHost mAppsCustomizeTabHost;
- private AppsCustomizePagedView mAppsCustomizeContent;
- private CustomizeTrayTabHost mHomeCustomizationDrawer;
- private boolean mAutoAdvanceRunning = false;
-
private ViewGroup mButtonCluster;
private View mAllAppsButton;
- private View mDivider;
- private View mConfigureButton;
-
- private AllAppsPagedView mAllAppsPagedView = null;
- private CustomizePagedView mCustomizePagedView = null;
+ private SearchDropTargetBar mSearchDeleteBar;
+ private AppsCustomizeTabHost mAppsCustomizeTabHost;
+ private AppsCustomizePagedView mAppsCustomizeContent;
+ private boolean mAutoAdvanceRunning = false;
private Bundle mSavedState;
@@ -287,13 +274,6 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- if (LauncherApplication.isInPlaceRotationEnabled()) {
- // hide the status bar (temporary until we get the status bar design figured out)
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
- this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
- }
-
LauncherApplication app = ((LauncherApplication)getApplication());
mModel = app.setLauncher(this);
mIconCache = app.getIconCache();
@@ -312,12 +292,6 @@
loadHotseats();
checkForLocaleChange();
setContentView(R.layout.launcher);
- mHomeCustomizationDrawer = (CustomizeTrayTabHost) findViewById(R.id.customization_drawer);
- if (mHomeCustomizationDrawer != null) {
- // share the same customization workspace across all the tabs
- mCustomizePagedView = (CustomizePagedView) findViewById(
- R.id.customization_drawer_tab_contents);
- }
setupViews();
registerContentObservers();
@@ -328,9 +302,6 @@
restoreState(mSavedState);
// Update customization drawer _after_ restoring the states
- if (mCustomizePagedView != null) {
- mCustomizePagedView.update();
- }
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.onPackagesUpdated();
}
@@ -351,19 +322,17 @@
registerReceiver(mCloseSystemDialogsReceiver, filter);
// If we have a saved version of these external icons, we load them up immediately
- if (LauncherApplication.isScreenLarge()) {
- if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) {
- updateIconsAffectedByPackageManagerChanges();
- }
- if (sGlobalSearchIcon != null) {
- updateGlobalSearchIcon(sGlobalSearchIcon);
- }
- if (sVoiceSearchIcon != null) {
- updateVoiceSearchIcon(sVoiceSearchIcon);
- }
- if (sAppMarketIcon != null) {
- updateAppMarketIcon(sAppMarketIcon);
- }
+ if (sGlobalSearchIcon == null || sVoiceSearchIcon == null || sAppMarketIcon == null) {
+ updateIconsAffectedByPackageManagerChanges();
+ }
+ if (sGlobalSearchIcon != null) {
+ updateGlobalSearchIcon(sGlobalSearchIcon);
+ }
+ if (sVoiceSearchIcon != null) {
+ updateVoiceSearchIcon(sVoiceSearchIcon);
+ }
+ if (sAppMarketIcon != null) {
+ updateAppMarketIcon(sAppMarketIcon);
}
}
@@ -721,9 +690,6 @@
public Object onRetainNonConfigurationInstance() {
// Flag the loader to stop early before switching
mModel.stopLoader();
- if (mAllAppsGrid != null) {
- mAllAppsGrid.surrender();
- }
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.surrender();
}
@@ -822,10 +788,8 @@
State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));
- if (state == State.ALL_APPS || state == State.APPS_CUSTOMIZE) {
+ if (state == State.APPS_CUSTOMIZE) {
showAllApps(false);
- } else if (state == State.CUSTOMIZE) {
- showCustomizationDrawer(false);
}
final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
@@ -849,38 +813,12 @@
mRestoring = true;
}
- // Restore the current AllApps drawer tab
- if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) {
- String curTab = savedState.getString("allapps_currentTab");
- if (curTab != null) {
- AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid;
- tabhost.setCurrentTabByTag(curTab);
- }
- int curPage = savedState.getInt("allapps_currentPage", -1);
- if (curPage > -1) {
- mAllAppsPagedView.setRestorePage(curPage);
- }
- }
-
- // Restore the current customization drawer tab
- if (mHomeCustomizationDrawer != null) {
- String curTab = savedState.getString("customize_currentTab");
- if (curTab != null) {
- // We set this directly so that there is no delay before the tab is set
- mCustomizePagedView.setCustomizationFilter(
- mHomeCustomizationDrawer.getCustomizeFilterForTabTag(curTab));
- mHomeCustomizationDrawer.setCurrentTabByTag(curTab);
- }
-
- // Note: currently we do not restore the page for the customization tray because unlike
- // AllApps, the page content can change drastically
- }
// Restore the AppsCustomize tab
if (mAppsCustomizeTabHost != null) {
String curTab = savedState.getString("apps_customize_currentTab");
if (curTab != null) {
- // We set this directly so that there is no delay before the tab is set
+ // We set this directly so that there is no delay before the tab is set
mAppsCustomizeContent.setContentType(
mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));
mAppsCustomizeTabHost.setCurrentTabByTag(curTab);
@@ -909,67 +847,29 @@
mWorkspace.setup(this, dragController);
mWorkspace.setWallpaperDimension();
- // Setup the different configurations
- DeleteZone allAppsDeleteZone = null;
- ApplicationInfoDropTarget allAppsInfoTarget = null;
- if (LauncherApplication.isScreenLarge()) {
- // Setup AllApps
- mAllAppsGrid = (AllAppsView) mDragLayer.findViewById(R.id.all_apps_view);
- mAllAppsGrid.setup(this, dragController);
- // We don't want a hole punched in our window.
- ((View) mAllAppsGrid).setWillNotDraw(false);
+ // Get the search/delete bar
+ mSearchDeleteBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar);
- // Setup Customize
- mCustomizePagedView.setLauncher(this);
- mCustomizePagedView.setDragController(dragController);
- mCustomizePagedView.setAllAppsPagedView(mAllAppsPagedView);
+ // Setup AppsCustomize
+ mAppsCustomizeTabHost = (AppsCustomizeTabHost)
+ findViewById(R.id.apps_customize_pane);
+ mAppsCustomizeContent = (AppsCustomizePagedView)
+ mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
+ mAppsCustomizeContent.setup(this, dragController);
- // Setup DeleteZone
- mDeleteZone = (DeleteZone) mDragLayer.findViewById(R.id.delete_zone);
- mDeleteZone.setLauncher(this);
- mDeleteZone.setDragController(dragController);
+ // Setup AppsCustomize button
+ mAllAppsButton = mDragLayer.findViewById(R.id.all_apps_button);
+ mAllAppsButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ onClickAllAppsButton(v);
+ }
+ });
- // Setup the top-right Apps/Customize buttons
- mAllAppsButton = findViewById(R.id.all_apps_button);
- mDivider = findViewById(R.id.all_apps_divider);
- mConfigureButton = findViewById(R.id.configure_button);
- mDeleteZone.setOverlappingViews(new View[] { mAllAppsButton, mDivider,
- mConfigureButton });
-
- // Setup the AllApps Delete toolbar button
- allAppsDeleteZone = (DeleteZone) findViewById(R.id.all_apps_delete_zone);
- allAppsDeleteZone.setLauncher(this);
- allAppsDeleteZone.setDragController(dragController);
- allAppsDeleteZone.setDragAndDropEnabled(false);
-
- // Setup the AllApps Info toolbar button
- allAppsInfoTarget = (ApplicationInfoDropTarget) findViewById(R.id.all_apps_info_target);
- allAppsInfoTarget.setLauncher(this);
- allAppsInfoTarget.setDragAndDropEnabled(false);
-
- // Setup the AllApps Market toolbar button
- View marketButton = findViewById(R.id.market_button);
- allAppsInfoTarget.setOverlappingView(marketButton);
- } else {
- // Get the search/delete bar
- mSearchDeleteBar = (SearchDropTargetBar) mDragLayer.findViewById(R.id.qsb_bar);
-
- // Setup AppsCustomize
- mAppsCustomizeTabHost = (AppsCustomizeTabHost)
- findViewById(R.id.apps_customize_pane);
- mAppsCustomizeContent = (AppsCustomizePagedView)
- mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
- mAppsCustomizeContent.setup(this, dragController);
-
- // Setup AppsCustomize button
- mHandleView = (HandleView) mDragLayer.findViewById(R.id.all_apps_button);
- mHandleView.setLauncher(this);
- mHandleView.setOnLongClickListener(this);
- mHandleView.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- onClickAllAppsButton(v);
- }
- });
+ if (!LauncherApplication.isScreenLarge()) {
+ // Setup AppsCustomize button on the phone
+ HandleView handleView = (HandleView) mAllAppsButton;
+ handleView.setLauncher(this);
+ handleView.setOnLongClickListener(this);
// Setup Hotseat
ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left);
@@ -995,19 +895,21 @@
mNextView.setOnLongClickListener(this);
}
- // Setup keylistener for 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);
+ if (!LauncherApplication.isScreenLarge()) {
+ // Setup keylistener for 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);
+ }
}
// Setup the drag controller (the drop targets have to be added in reverse order)
@@ -1015,40 +917,28 @@
dragController.setScrollView(mDragLayer);
dragController.setMoveTarget(mWorkspace);
dragController.addDropTarget(mWorkspace);
- if (mDeleteZone != null) {
- dragController.addDragListener(mDeleteZone);
- dragController.addDropTarget(mDeleteZone);
- }
if (mSearchDeleteBar != null) {
mSearchDeleteBar.setup(this, dragController);
}
- if (allAppsDeleteZone != null) {
- dragController.addDragListener(allAppsDeleteZone);
- dragController.addDropTarget(allAppsDeleteZone);
- }
- if (allAppsInfoTarget != null) {
- dragController.addDragListener(allAppsInfoTarget);
- dragController.addDropTarget(allAppsInfoTarget);
- }
}
@SuppressWarnings({"UnusedDeclaration"})
public void previousScreen(View v) {
- if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
+ if (mState != State.APPS_CUSTOMIZE) {
mWorkspace.scrollLeft();
}
}
@SuppressWarnings({"UnusedDeclaration"})
public void nextScreen(View v) {
- if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
+ if (mState != State.APPS_CUSTOMIZE) {
mWorkspace.scrollRight();
}
}
@SuppressWarnings({"UnusedDeclaration"})
public void launchHotSeat(View v) {
- if (mState == State.ALL_APPS) return;
+ if (mState == State.APPS_CUSTOMIZE) return;
int index = -1;
if (v.getId() == R.id.hotseat_left) {
@@ -1246,9 +1136,6 @@
updateRunning();
// Reset AllApps to it's initial state
- if (mAllAppsGrid != null) {
- mAllAppsGrid.reset();
- }
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.reset();
}
@@ -1421,9 +1308,6 @@
}
// Reset AllApps to it's initial state
- if (mAllAppsGrid != null) {
- mAllAppsGrid.reset();
- }
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.reset();
}
@@ -1466,22 +1350,6 @@
outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);
}
- // Save the current AllApps drawer tab
- if (mAllAppsGrid != null && mAllAppsGrid instanceof AllAppsTabbed) {
- AllAppsTabbed tabhost = (AllAppsTabbed) mAllAppsGrid;
- String currentTabTag = tabhost.getCurrentTabTag();
- if (currentTabTag != null) {
- outState.putString("allapps_currentTab", currentTabTag);
- outState.putInt("allapps_currentPage", mAllAppsPagedView.getCurrentPage());
- }
- }
- // Save the current customization drawer tab
- if (mHomeCustomizationDrawer != null) {
- String currentTabTag = mHomeCustomizationDrawer.getCurrentTabTag();
- if (currentTabTag != null) {
- outState.putString("customize_currentTab", currentTabTag);
- }
- }
// Save the current AppsCustomize tab
if (mAppsCustomizeTabHost != null) {
String currentTabTag = mAppsCustomizeTabHost.getCurrentTabTag();
@@ -1605,25 +1473,6 @@
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
- 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());
- }
- }
-
// 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;
@@ -1676,15 +1525,8 @@
}
private void addItems() {
- if (LauncherApplication.isScreenLarge()) {
- // Animate the widget chooser up from the bottom of the screen
- if (mState != State.CUSTOMIZE) {
- showCustomizationDrawer(true);
- }
- } else {
- showWorkspace(true);
- showAddDialog(-1, -1);
- }
+ showWorkspace(true);
+ showAddDialog(-1, -1);
}
private void resetAddInfo() {
@@ -1883,7 +1725,7 @@
@Override
public void onBackPressed() {
- if (mState == State.ALL_APPS || mState == State.CUSTOMIZE || mState == State.APPS_CUSTOMIZE) {
+ if (mState == State.APPS_CUSTOMIZE) {
showWorkspace(true);
} else if (mWorkspace.getOpenFolder() != null) {
closeFolder();
@@ -1966,8 +1808,8 @@
FolderIcon fi = (FolderIcon) v;
handleFolderClick(fi);
}
- } else if (v == mHandleView) {
- if (mState == State.ALL_APPS) {
+ } else if (v == mAllAppsButton) {
+ if (mState == State.APPS_CUSTOMIZE) {
showWorkspace(true);
} else {
showAllApps(true);
@@ -2159,21 +2001,21 @@
switch (v.getId()) {
case R.id.previous_screen:
- if (mState != State.ALL_APPS && mState != State.APPS_CUSTOMIZE) {
+ if (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 && mState != State.APPS_CUSTOMIZE) {
+ if (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 && mState != State.APPS_CUSTOMIZE) {
+ if (mState != State.APPS_CUSTOMIZE) {
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
showPreviews(v);
@@ -2357,10 +2199,6 @@
return mWorkspace;
}
- TabHost getCustomizationDrawer() {
- return mHomeCustomizationDrawer;
- }
-
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
@@ -2509,116 +2347,20 @@
// Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
public boolean isAllAppsVisible() {
- return (mState == State.ALL_APPS) || (mState == State.APPS_CUSTOMIZE);
+ return (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.isScreenLarge()) {
+ if (zoom == 1.0f) {
mWorkspace.setVisibility(View.GONE);
}
}
-
- private void showAndEnableToolbarButton(View button) {
- button.setVisibility(View.VISIBLE);
- }
-
- private void hideToolbarButton(View button) {
- // We can't set it to GONE, otherwise the RelativeLayout gets screwed up
- button.setVisibility(View.INVISIBLE);
- button.setAlpha(0.0f);
- }
-
- /**
- * Helper function for showing or hiding a toolbar button, possibly animated.
- *
- * @param show If true, create an animation to the show the item. Otherwise, hide it.
- * @param view The toolbar button to be animated
- * @param seq A AnimatorSet that will be used to animate the transition. If null, the
- * transition will not be animated.
- */
- private void hideOrShowToolbarButton(boolean show, final View view, AnimatorSet seq) {
- final boolean showing = show;
- final boolean hiding = !show;
-
- final int duration = show ?
- getResources().getInteger(R.integer.config_toolbarButtonFadeInTime) :
- getResources().getInteger(R.integer.config_toolbarButtonFadeOutTime);
-
- if (seq != null) {
- ValueAnimator anim = ValueAnimator.ofFloat(view.getAlpha(), show ? 1.0f : 0.0f);
- anim.setDuration(duration);
- anim.addUpdateListener(new AnimatorUpdateListener() {
- public void onAnimationUpdate(ValueAnimator animation) {
- view.setAlpha((Float) animation.getAnimatedValue());
- }
- });
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- if (showing) showAndEnableToolbarButton(view);
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- if (hiding) hideToolbarButton(view);
- }
- });
- seq.play(anim);
- } else {
- if (showing) {
- showAndEnableToolbarButton(view);
- view.setAlpha(1f);
- } else {
- hideToolbarButton(view);
- }
- }
- }
-
- /**
- * Show/hide the appropriate toolbar buttons for newState.
- * If showSeq or hideSeq is null, the transition will be done immediately (not animated).
- *
- * @param newState The state that is being switched to
- * @param showSeq AnimatorSet in which to put "show" animations, or null.
- * @param hideSeq AnimatorSet in which to put "hide" animations, or null.
- */
- private void hideAndShowToolbarButtons(State newState, AnimatorSet showSeq, AnimatorSet hideSeq) {
- switch (newState) {
- case WORKSPACE:
- hideOrShowToolbarButton(true, mButtonCluster, showSeq);
- if (mDeleteZone != null) {
- mDeleteZone.setDragAndDropEnabled(true);
- if (LauncherApplication.isScreenLarge()) {
- mDeleteZone.setText(
- getResources().getString(R.string.delete_zone_label_workspace));
- }
- }
- break;
- case ALL_APPS:
- case APPS_CUSTOMIZE:
- hideOrShowToolbarButton(false, mButtonCluster, hideSeq);
- if (mDeleteZone != null) {
- mDeleteZone.setDragAndDropEnabled(false);
- if (LauncherApplication.isScreenLarge()) {
- mDeleteZone.setText(
- getResources().getString(R.string.delete_zone_label_all_apps));
- }
- }
- break;
- case CUSTOMIZE:
- hideOrShowToolbarButton(false, mButtonCluster, hideSeq);
- if (mDeleteZone != null) {
- mDeleteZone.setDragAndDropEnabled(false);
- }
- break;
- }
- }
/**
* Helper method for the cameraZoomIn/cameraZoomOut animations
* @param view The view being animated
- * @param state The state that we are moving in or out of -- either ALL_APPS or CUSTOMIZE
+ * @param state The state that we are moving in or out of (eg. APPS_CUSTOMIZE)
* @param scaleFactor The scale factor used for the zoom
*/
private void setPivotsForZoom(View view, State state, float scaleFactor) {
@@ -2628,7 +2370,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 || state == State.APPS_CUSTOMIZE) {
+ if (state == State.APPS_CUSTOMIZE) {
final float initialHeightFactor = 0.175f;
view.setPivotY((1 - initialHeightFactor) * height);
} else {
@@ -2641,57 +2383,30 @@
* Zoom the camera out from the workspace to reveal 'toView'.
* Assumes that the view to show is anchored at either the very top or very bottom
* of the screen.
- * @param toState The state to zoom out to. Must be ALL_APPS or CUSTOMIZE.
+ * @param toState The state to zoom out to. Must be APPS_CUSTOMIZE.
*/
private void cameraZoomOut(State toState, boolean animated, boolean springLoaded) {
final Resources res = getResources();
- final boolean toAllApps = (toState == State.ALL_APPS)
- || (toState == State.APPS_CUSTOMIZE);
- 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_appsCustomizeZoomScaleFactor) :
- (float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
-
- View tmpView;
- if (toAllApps) {
- tmpView = (LauncherApplication.isScreenLarge())
- ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
- } else {
- tmpView = mHomeCustomizationDrawer;
- }
- final View toView = tmpView;
+ final int duration = res.getInteger(R.integer.config_appsCustomizeZoomInTime);
+ final int fadeDuration = res.getInteger(R.integer.config_appsCustomizeFadeInTime);
+ final float scale = (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);
+ final View toView = mAppsCustomizeTabHost;
setPivotsForZoom(toView, toState, scale);
- if (toAllApps) {
- if (springLoaded) {
- if (toState == State.APPS_CUSTOMIZE) {
- // Shrink workspaces away if going back to AppsCustomize from spring loaded mode
- mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
- } else {
- // Shrink workspaces to bottom if going back to AllApps from spring loaded mode
- mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
- }
- } else {
- // Shrink workspaces away if going to AllApps/AppsCustomize from workspace
- 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();
- }
+ if (springLoaded) {
+ if (toState == State.APPS_CUSTOMIZE) {
+ // Shrink workspaces away if going back to AppsCustomize from spring loaded mode
+ mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
+ } else {
+ // Shrink workspaces to bottom if going back to AllApps from spring loaded mode
+ mWorkspace.shrink(ShrinkState.BOTTOM_VISIBLE, animated);
}
} else {
- // In Customize mode, shrink the workspaces to the top
- mWorkspace.shrink(ShrinkState.TOP, animated);
+ // Shrink workspaces away if going to AllApps/AppsCustomize from workspace
+ mWorkspace.shrink(ShrinkState.BOTTOM_HIDDEN, animated);
}
if (animated) {
@@ -2705,19 +2420,17 @@
}
});
- 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 LauncherAnimatorUpdateListener() {
- public void onAnimationUpdate(float a, float b) {
- // don't need to invalidate because we do so above
- toView.setFastAlpha(a * 0f + b * 1f);
- }
- });
- alphaAnim.start();
- }
+ toView.setVisibility(View.VISIBLE);
+ toView.setFastAlpha(0f);
+ ValueAnimator alphaAnim = ValueAnimator.ofFloat(0f, 1f).setDuration(fadeDuration);
+ alphaAnim.setInterpolator(new DecelerateInterpolator(1.5f));
+ 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);
+ }
+ });
+ alphaAnim.start();
if (toView instanceof LauncherTransitionable) {
((LauncherTransitionable) toView).onLauncherTransitionStart(scaleAnim);
@@ -2730,9 +2443,6 @@
toView.setTranslationY(0.0f);
toView.setVisibility(View.VISIBLE);
toView.bringToFront();
- if (!toAllApps) {
- toView.setFastAlpha(1.0f);
- }
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -2747,21 +2457,12 @@
}
});
- AnimatorSet toolbarHideAnim = new AnimatorSet();
- AnimatorSet toolbarShowAnim = new AnimatorSet();
- hideAndShowToolbarButtons(toState, toolbarShowAnim, toolbarHideAnim);
-
// toView should appear right at the end of the workspace shrink animation
final int startDelay = 0;
if (mStateAnimation != null) mStateAnimation.cancel();
mStateAnimation = new AnimatorSet();
- mStateAnimation.playTogether(scaleAnim, toolbarHideAnim);
mStateAnimation.play(scaleAnim).after(startDelay);
-
- // Show the new toolbar buttons just as the main animation is ending
- final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime);
- mStateAnimation.play(toolbarShowAnim).after(duration + startDelay - fadeInTime);
mStateAnimation.start();
} else {
toView.setTranslationX(0.0f);
@@ -2774,42 +2475,22 @@
((LauncherTransitionable) toView).onLauncherTransitionStart(null);
((LauncherTransitionable) toView).onLauncherTransitionEnd(null);
}
- hideAndShowToolbarButtons(toState, null, null);
}
}
/**
* Zoom the camera back into the workspace, hiding 'fromView'.
* This is the opposite of cameraZoomOut.
- * @param fromState The current state (must be ALL_APPS or CUSTOMIZE).
+ * @param fromState The current state (must be APPS_CUSTOMIZE).
* @param animated If true, the transition will be animated.
*/
private void cameraZoomIn(State fromState, boolean animated, boolean springLoaded) {
Resources res = getResources();
- final boolean fromAllApps = (fromState == State.ALL_APPS)
- || (fromState == State.APPS_CUSTOMIZE);
- int duration = fromAllApps ?
- res.getInteger(R.integer.config_appsCustomizeZoomOutTime) :
- res.getInteger(R.integer.config_customizeZoomOutTime);
-
- final float scaleFactor = fromAllApps ?
- (float) res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor) :
- (float) res.getInteger(R.integer.config_customizeZoomScaleFactor);
-
- View tmpView;
- if (fromAllApps) {
- tmpView = (LauncherApplication.isScreenLarge())
- ? (View) mAllAppsGrid : mAppsCustomizeTabHost;
- } else {
- tmpView = mHomeCustomizationDrawer;
- }
- final View fromView = tmpView;
-
- if (LauncherApplication.isScreenLarge()) {
- mCustomizePagedView.endChoiceMode();
- mAllAppsPagedView.endChoiceMode();
- }
+ final int duration = res.getInteger(R.integer.config_appsCustomizeZoomOutTime);
+ final float scaleFactor = (float)
+ res.getInteger(R.integer.config_appsCustomizeZoomScaleFactor);
+ final View fromView = mAppsCustomizeTabHost;
setPivotsForZoom(fromView, fromState, scaleFactor);
@@ -2854,18 +2535,7 @@
}
});
- AnimatorSet toolbarHideAnim = new AnimatorSet();
- AnimatorSet toolbarShowAnim = new AnimatorSet();
- if (!springLoaded) {
- hideAndShowToolbarButtons(State.WORKSPACE, toolbarShowAnim, toolbarHideAnim);
- }
-
- mStateAnimation.playTogether(scaleAnim, toolbarHideAnim, alphaAnim);
-
- // Show the new toolbar buttons at the very end of the whole animation
- final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime);
- final int unshrinkTime = res.getInteger(R.integer.config_workspaceUnshrinkTime);
- mStateAnimation.play(toolbarShowAnim).after(unshrinkTime - fadeInTime);
+ mStateAnimation.playTogether(scaleAnim, alphaAnim);
mStateAnimation.start();
} else {
fromView.setVisibility(View.GONE);
@@ -2873,9 +2543,6 @@
((LauncherTransitionable) fromView).onLauncherTransitionStart(null);
((LauncherTransitionable) fromView).onLauncherTransitionEnd(null);
}
- if (!springLoaded) {
- hideAndShowToolbarButtons(State.WORKSPACE, null, null);
- }
}
}
@@ -2891,10 +2558,8 @@
} else {
mWorkspace.unshrink(animated);
}
- if (mState == State.ALL_APPS || mState == State.APPS_CUSTOMIZE) {
+ if (mState == State.APPS_CUSTOMIZE) {
closeAllApps(animated);
- } else if (mState == State.CUSTOMIZE) {
- hideCustomizationDrawer(animated);
}
// Change the state *after* we've called all the transition code
@@ -2915,40 +2580,67 @@
if (mState == State.APPS_CUSTOMIZE) {
mState = State.APPS_CUSTOMIZE_SPRING_LOADED;
cameraZoomIn(State.APPS_CUSTOMIZE, true, true);
- } else {
- // Do nothing
}
+ // Otherwise, we are not in spring loaded mode, so don't do anything.
}
void exitSpringLoadedDragMode() {
if (mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {
- mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_HIDDEN);
+ mWorkspace.exitSpringLoadedDragMode(Workspace.ShrinkState.BOTTOM_VISIBLE);
cameraZoomOut(State.APPS_CUSTOMIZE, true, true);
mState = State.APPS_CUSTOMIZE;
- } else {
- // Do nothing
+ }
+ // Otherwise, we are not in spring loaded mode, so don't do anything.
+ }
+
+ /**
+ * Shows the dock/hotseat area.
+ */
+ void showDock(boolean animated) {
+ if (!LauncherApplication.isScreenLarge()) {
+ if (animated) {
+ int duration = mSearchDeleteBar.getTransitionInDuration();
+ mButtonCluster.animate().alpha(1f).setDuration(duration);
+ mPreviousView.animate().alpha(1f).setDuration(duration);
+ mNextView.animate().alpha(1f).setDuration(duration);
+ } else {
+ mButtonCluster.setAlpha(1f);
+ mPreviousView.setAlpha(1f);
+ mNextView.setAlpha(1f);
+ }
+ }
+ }
+
+ /**
+ * Hides the dock/hotseat area.
+ */
+ void hideDock(boolean animated) {
+ if (!LauncherApplication.isScreenLarge()) {
+ if (animated) {
+ int duration = mSearchDeleteBar.getTransitionOutDuration();
+ mButtonCluster.animate().alpha(0f).setDuration(duration);
+ mPreviousView.animate().alpha(0f).setDuration(duration);
+ mNextView.animate().alpha(0f).setDuration(duration);
+ } else {
+ mButtonCluster.setAlpha(0f);
+ mPreviousView.setAlpha(0f);
+ mNextView.setAlpha(0f);
+ }
}
}
void showAllApps(boolean animated) {
if (mState != State.WORKSPACE) return;
- if (LauncherApplication.isScreenLarge()) {
- cameraZoomOut(State.ALL_APPS, animated, false);
- ((View) mAllAppsGrid).requestFocus();
- if (mDeleteZone != null) {
- mDeleteZone.setVisibility(View.GONE);
- }
+ cameraZoomOut(State.APPS_CUSTOMIZE, animated, false);
+ mAppsCustomizeTabHost.requestFocus();
- // Change the state *after* we've called all the transition code
- mState = State.ALL_APPS;
- } else {
- cameraZoomOut(State.APPS_CUSTOMIZE, animated, false);
- mAppsCustomizeTabHost.requestFocus();
+ // Hide the search bar and dock
+ mSearchDeleteBar.hideSearchBar(animated);
+ hideDock(animated);
- // Change the state *after* we've called all the transition code
- mState = State.APPS_CUSTOMIZE;
- }
+ // 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;
@@ -2998,22 +2690,16 @@
* - From another workspace
*/
void closeAllApps(boolean animated) {
- if (LauncherApplication.isScreenLarge()) {
- if (mState == State.ALL_APPS) {
- mWorkspace.setVisibility(View.VISIBLE);
- cameraZoomIn(State.ALL_APPS, animated, false);
+ if (mState == State.APPS_CUSTOMIZE || mState == State.APPS_CUSTOMIZE_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();
- }
- } else {
- if (mState == State.APPS_CUSTOMIZE || mState == State.APPS_CUSTOMIZE_SPRING_LOADED) {
- mWorkspace.setVisibility(View.VISIBLE);
- cameraZoomIn(State.APPS_CUSTOMIZE, animated, false);
+ // Show the search bar and dock
+ mSearchDeleteBar.showSearchBar(animated);
+ showDock(animated);
- // Set focus to the AllApps button
- findViewById(R.id.all_apps_button).requestFocus();
- }
+ // Set focus to the AppsCustomize button
+ findViewById(R.id.all_apps_button).requestFocus();
}
}
@@ -3025,32 +2711,6 @@
// TODO
}
- // Show the customization drawer (only exists in x-large configuration)
- private void showCustomizationDrawer(boolean animated) {
- if (mState != State.WORKSPACE) {
- return;
- }
-
- cameraZoomOut(State.CUSTOMIZE, animated, false);
-
- // Change the state *after* we've called all the transition code
- mState = State.CUSTOMIZE;
-
- // Pause the auto-advance of widgets until we are out of Customization drawer
- mUserPresent = false;
- updateRunning();
- }
-
- // Hide the customization drawer (only exists in x-large configuration)
- void hideCustomizationDrawer(boolean animated) {
- if (mState == State.CUSTOMIZE) {
- cameraZoomIn(State.CUSTOMIZE, animated, false);
-
- // Set focus to the customize button
- findViewById(R.id.configure_button).requestFocus();
- }
- }
-
/**
* Add an item from all apps or customize onto the given workspace screen.
* If layout is null, add to the current screen.
@@ -3361,9 +3021,6 @@
}
}
- void setAllAppsPagedView(AllAppsPagedView view) {
- mAllAppsPagedView = view;
- }
/**
* Refreshes the shortcuts shown on the workspace.
@@ -3518,15 +3175,6 @@
mSavedInstanceState = null;
}
- // 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.isScreenLarge() && (mState == State.CUSTOMIZE)) {
- final int childCount = mWorkspace.getChildCount();
- for (int i = 0; i < childCount; ++i) {
- mWorkspace.getChildAt(i).requestLayout();
- }
- }
-
mWorkspaceLoading = false;
// If we received the result of any pending adds while the loader was running (e.g. the
@@ -3553,15 +3201,9 @@
* Implementation of the method from LauncherModel.Callbacks.
*/
public void bindAllApplications(ArrayList<ApplicationInfo> apps) {
- if (mAllAppsGrid != null) {
- mAllAppsGrid.setApps(apps);
- }
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.setApps(apps);
}
- if (mCustomizePagedView != null) {
- mCustomizePagedView.setApps(apps);
- }
updateIconsAffectedByPackageManagerChanges();
}
@@ -3573,15 +3215,10 @@
public void bindAppsAdded(ArrayList<ApplicationInfo> apps) {
setLoadOnResume();
removeDialog(DIALOG_CREATE_SHORTCUT);
- if (mAllAppsGrid != null) {
- mAllAppsGrid.addApps(apps);
- }
+
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.addApps(apps);
}
- if (mCustomizePagedView != null) {
- mCustomizePagedView.addApps(apps);
- }
updateIconsAffectedByPackageManagerChanges();
}
@@ -3596,15 +3233,10 @@
if (mWorkspace != null) {
mWorkspace.updateShortcuts(apps);
}
- if (mAllAppsGrid != null) {
- mAllAppsGrid.updateApps(apps);
- }
+
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.updateApps(apps);
}
- if (mCustomizePagedView != null) {
- mCustomizePagedView.updateApps(apps);
- }
updateIconsAffectedByPackageManagerChanges();
}
@@ -3618,15 +3250,10 @@
if (permanent) {
mWorkspace.removeItems(apps);
}
- if (mAllAppsGrid != null) {
- mAllAppsGrid.removeApps(apps);
- }
+
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.removeApps(apps);
}
- if (mCustomizePagedView != null) {
- mCustomizePagedView.removeApps(apps);
- }
updateIconsAffectedByPackageManagerChanges();
}
@@ -3634,10 +3261,7 @@
* A number of packages were updated.
*/
public void bindPackagesUpdated() {
- // update the customization drawer contents
- if (mCustomizePagedView != null) {
- mCustomizePagedView.update();
- }
+
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.onPackagesUpdated();
}
@@ -3699,9 +3323,7 @@
Log.d(TAG, "mDesktopItems.size=" + mDesktopItems.size());
Log.d(TAG, "sFolders.size=" + sFolders.size());
mModel.dumpState();
- if (mAllAppsGrid != null) {
- mAllAppsGrid.dumpState();
- }
+
if (mAppsCustomizeContent != null) {
mAppsCustomizeContent.dumpState();
}
diff --git a/src/com/android/launcher2/LauncherApplication.java b/src/com/android/launcher2/LauncherApplication.java
index 67573e0..68b1644 100644
--- a/src/com/android/launcher2/LauncherApplication.java
+++ b/src/com/android/launcher2/LauncherApplication.java
@@ -29,7 +29,6 @@
public IconCache mIconCache;
private static boolean sIsScreenLarge;
private static float sScreenDensity;
- private static final boolean ENABLE_ROTATION = false;
@Override
public void onCreate() {
@@ -98,10 +97,6 @@
return mModel;
}
- public static boolean isInPlaceRotationEnabled() {
- return sIsScreenLarge && ENABLE_ROTATION;
- }
-
public static boolean isScreenLarge() {
return sIsScreenLarge;
}
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 605f4b6..d83db74 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -77,7 +77,6 @@
protected int mCurrentPage;
protected int mNextPage = INVALID_PAGE;
- protected int mRestorePage = -1;
protected int mMaxScrollX;
protected Scroller mScroller;
private VelocityTracker mVelocityTracker;
@@ -112,7 +111,6 @@
protected int mPageLayoutPaddingRight;
protected int mPageLayoutWidthGap;
protected int mPageLayoutHeightGap;
- protected int mPageLayoutMaxHeight;
protected int mCellCountX = 0;
protected int mCellCountY = 0;
protected boolean mCenterPagesVertically;
@@ -161,6 +159,9 @@
protected boolean mIsPageMoving = false;
+ // All syncs and layout passes are deferred until data is ready.
+ protected boolean mIsDataReady = false;
+
public interface PageSwitchListener {
void onPageSwitch(View newPage, int newPageIndex);
}
@@ -192,8 +193,6 @@
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);
@@ -224,6 +223,17 @@
}
/**
+ * Called by subclasses to mark that data is ready, and that we can begin loading and laying
+ * out pages.
+ */
+ protected void setDataIsReady() {
+ mIsDataReady = true;
+ }
+ protected boolean isDataReady() {
+ return mIsDataReady;
+ }
+
+ /**
* Returns the index of the currently displayed page.
*
* @return The index of the currently displayed page.
@@ -244,10 +254,6 @@
return getWidth();
}
- public int getTouchState() {
- return mTouchState;
- }
-
/**
* Updates the scroll of the current page immediately to its final scroll position. We use this
* in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
@@ -376,6 +382,11 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (!mIsDataReady) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ return;
+ }
+
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
@@ -393,9 +404,6 @@
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
@@ -489,6 +497,10 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ if (!mIsDataReady) {
+ return;
+ }
+
if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
if (mFirstLayout && mCurrentPage >= 0 && mCurrentPage < getChildCount()) {
setHorizontalScrollBarEnabled(false);
@@ -560,10 +572,14 @@
if (distanceFromScreenCenter > 0) {
if (i > 0) {
d += getScaledMeasuredWidth(getChildAt(i - 1)) / 2;
+ } else {
+ continue;
}
} else {
if (i < childCount - 1) {
d += getScaledMeasuredWidth(getChildAt(i + 1)) / 2;
+ } else {
+ continue;
}
}
d += mPageSpacing;
@@ -839,7 +855,6 @@
}
case MotionEvent.ACTION_UP:
- onWallpaperTap(ev);
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
@@ -1176,8 +1191,7 @@
}
}
- protected void onWallpaperTap(MotionEvent ev) {
- }
+ protected void onWallpaperTap(MotionEvent ev) {}
@Override
public void requestChildFocus(View child, View focused) {
@@ -1537,10 +1551,6 @@
}
}
- public void setRestorePage(int restorePage) {
- mRestorePage = restorePage;
- }
-
/**
* This method is called ONLY to synchronize the number of pages that the paged view has.
* To actually fill the pages with information, implement syncPageItems() below. It is
@@ -1568,6 +1578,10 @@
}
protected void invalidatePageData() {
+ if (!mIsDataReady) {
+ return;
+ }
+
if (mContentIsRefreshable) {
// Update all the pages
syncPages();
@@ -1579,12 +1593,6 @@
mDirtyPageContent.add(true);
}
- // Use the restore page if necessary
- if (mRestorePage > -1) {
- mCurrentPage = mRestorePage;
- mRestorePage = -1;
- }
-
// Load any pages that are necessary for the current window of views
loadAssociatedPages(mCurrentPage);
mDirtyPageAlpha = true;
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 901ac26..d7f8784 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -40,6 +40,7 @@
private int mCellHeight;
private int mWidthGap;
private int mHeightGap;
+ private float mPeekWidth;
protected PagedViewCellLayoutChildren mChildren;
private PagedViewCellLayoutChildren mHolographicChildren;
private boolean mAllowHardwareLayerCreation = false;
@@ -62,6 +63,7 @@
Resources resources = context.getResources();
mCellWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_width);
mCellHeight = resources.getDimensionPixelSize(R.dimen.apps_customize_cell_height);
+ mPeekWidth = resources.getDimensionPixelSize(R.dimen.apps_customize_peek_width);
mCellCountX = LauncherModel.getCellCountX();
mCellCountY = LauncherModel.getCellCountY();
mWidthGap = mHeightGap = -1;
@@ -229,11 +231,11 @@
int vSpaceLeft = heightSpecSize - mPaddingTop
- mPaddingBottom - (cellHeight * mCellCountY);
- int heightGap = vSpaceLeft / numHeightGaps;
+ int heightGap = (numHeightGaps <= 0) ? 0 : (vSpaceLeft / numHeightGaps);
int hSpaceLeft = widthSpecSize - mPaddingLeft
- mPaddingRight - (cellWidth * mCellCountX);
- int widthGap = hSpaceLeft / numWidthGaps;
+ int widthGap = (numWidthGaps <= 0) ? 0 : (hSpaceLeft / numWidthGaps);
// center it around the min gaps
int minGap = Math.min(widthGap, heightGap);
@@ -271,15 +273,7 @@
}
int getContentWidth() {
- if (LauncherApplication.isScreenLarge()) {
- // Return the distance from the left edge of the content of the leftmost icon to
- // the right edge of the content of the rightmost icon
-
- // icons are centered within cells, find out how much padding that accounts for
- return getWidthBeforeFirstLayout() - (mCellWidth - Utilities.getIconContentSize());
- } else {
- return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
- }
+ return getWidthBeforeFirstLayout() + mPaddingLeft + mPaddingRight;
}
int getContentHeight() {
@@ -308,7 +302,20 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
- return super.onTouchEvent(event) || true;
+ boolean result = super.onTouchEvent(event);
+ int count = getPageChildCount();
+ if (count > 0) {
+ // We only intercept the touch if we are tapping in empty space after the final row
+ View child = getChildOnPageAt(count - 1);
+ int bottom = child.getBottom();
+ int numRows = (int) Math.ceil((float) getPageChildCount() / getCellCountX());
+ if (numRows < getCellCountY()) {
+ // Add a little bit of buffer if there is room for another row
+ bottom += mCellHeight / 2;
+ }
+ result = result || (event.getY() < bottom);
+ }
+ return result;
}
public void enableCenteredContent(boolean enabled) {
@@ -361,16 +368,37 @@
* Estimates the number of cells that the specified width would take up.
*/
public int estimateCellHSpan(int width) {
- // TODO: we need to take widthGap into effect
- return (width + mCellWidth) / mCellWidth;
+ // The space for a page assuming that we want to show half of a column of the previous and
+ // next pages is the width - left padding (current & next page) - right padding (previous &
+ // current page) - half cell width (for previous and next pages)
+ int availWidth = (int) (width - (2 * mPaddingLeft + 2 * mPaddingRight) - (2 * mPeekWidth));
+
+ // We know that we have to fit N cells with N-1 width gaps, so we just juggle to solve for N
+ int n = Math.max(1, (availWidth + mWidthGap) / (mCellWidth + mWidthGap));
+
+ // We don't do anything fancy to determine if we squeeze another row in.
+ return n;
}
/**
* Estimates the number of cells that the specified height would take up.
*/
public int estimateCellVSpan(int height) {
- // TODO: we need to take heightGap into effect
- return (height + mCellHeight) / mCellHeight;
+ // The space for a page is the height - top padding (current page) - bottom padding (current
+ // page)
+ int availHeight = height - (mPaddingTop + mPaddingBottom);
+
+ // We know that we have to fit N cells with N-1 height gaps, so we juggle to solve for N
+ int n = Math.max(1, (availHeight + mHeightGap) / (mCellHeight + mHeightGap));
+
+ // We don't do anything fancy to determine if we squeeze another row in.
+ return n;
+ }
+
+ public void calculateCellCount(int width, int height, int maxCellCountX, int maxCellCountY) {
+ mCellCountX = Math.min(maxCellCountX, estimateCellHSpan(width));
+ mCellCountY = Math.min(maxCellCountY, estimateCellVSpan(height));
+ requestLayout();
}
/**
diff --git a/src/com/android/launcher2/PagedViewGridLayout.java b/src/com/android/launcher2/PagedViewGridLayout.java
index cedf71c..c6d39fd 100644
--- a/src/com/android/launcher2/PagedViewGridLayout.java
+++ b/src/com/android/launcher2/PagedViewGridLayout.java
@@ -59,14 +59,15 @@
@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;
+ boolean result = super.onTouchEvent(event);
+ int count = getPageChildCount();
+ if (count > 0) {
+ // We only intercept the touch if we are tapping in empty space after the final row
+ View child = getChildOnPageAt(count - 1);
+ int bottom = child.getBottom();
+ result = result || (event.getY() < bottom);
+ }
+ return result;
}
@Override
diff --git a/src/com/android/launcher2/PagedViewIconCache.java b/src/com/android/launcher2/PagedViewIconCache.java
index de05ff1..d65f68b 100644
--- a/src/com/android/launcher2/PagedViewIconCache.java
+++ b/src/com/android/launcher2/PagedViewIconCache.java
@@ -48,11 +48,11 @@
final ComponentInfo ci = info.activityInfo != null ? info.activityInfo :
info.serviceInfo;
mComponentName = new ComponentName(ci.packageName, ci.name);
- mType = Type.AppWidgetProviderInfoKey;
+ mType = Type.ResolveInfoKey;
}
public Key(AppWidgetProviderInfo info) {
mComponentName = info.provider;
- mType = Type.ResolveInfoKey;
+ mType = Type.AppWidgetProviderInfoKey;
}
private ComponentName getComponentName() {
diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java
index 2ffa398..6ddecf1 100644
--- a/src/com/android/launcher2/PagedViewWidget.java
+++ b/src/com/android/launcher2/PagedViewWidget.java
@@ -257,24 +257,14 @@
@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);
- }
+ 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);
- }
+ return FocusHelper.handlePagedViewGridLayoutWidgetKeyEvent(this, keyCode, event)
+ || super.onKeyUp(keyCode, event);
}
@Override
diff --git a/src/com/android/launcher2/SearchDropTargetBar.java b/src/com/android/launcher2/SearchDropTargetBar.java
index 7a208b7..d00e210 100644
--- a/src/com/android/launcher2/SearchDropTargetBar.java
+++ b/src/com/android/launcher2/SearchDropTargetBar.java
@@ -17,9 +17,6 @@
package com.android.launcher2;
import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
@@ -33,12 +30,13 @@
public class SearchDropTargetBar extends FrameLayout implements DragController.DragListener {
private static final int sTransitionInDuration = 275;
- private static final int sTransitionOutDuration = 200;
+ private static final int sTransitionOutDuration = 100;
+ private boolean mIsSearchBarHidden;
private View mQSBSearchBar;
private View mDropTargetBar;
- private IconDropTarget mInfoDropTarget;
- private IconDropTarget mDeleteDropTarget;
+ private ButtonDropTarget mInfoDropTarget;
+ private ButtonDropTarget mDeleteDropTarget;
public SearchDropTargetBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -56,6 +54,7 @@
dragController.addDropTarget(mDeleteDropTarget);
mInfoDropTarget.setLauncher(launcher);
mDeleteDropTarget.setLauncher(launcher);
+ mDropTargetBar.setBackgroundColor(0x33000000);
}
@Override
@@ -65,8 +64,38 @@
// Get the individual components
mQSBSearchBar = findViewById(R.id.qsb_search_bar);
mDropTargetBar = findViewById(R.id.drag_target_bar);
- mInfoDropTarget = (IconDropTarget) mDropTargetBar.findViewById(R.id.info_target);
- mDeleteDropTarget = (IconDropTarget) mDropTargetBar.findViewById(R.id.delete_target);
+ mInfoDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.info_target);
+ mDeleteDropTarget = (ButtonDropTarget) mDropTargetBar.findViewById(R.id.delete_target);
+ }
+
+ /*
+ * Shows and hides the search bar.
+ */
+ public void showSearchBar(boolean animated) {
+ if (animated) {
+ mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration);
+ } else {
+ mQSBSearchBar.setAlpha(1f);
+ }
+ mIsSearchBarHidden = false;
+ }
+ public void hideSearchBar(boolean animated) {
+ if (animated) {
+ mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration);
+ } else {
+ mQSBSearchBar.setAlpha(0f);
+ }
+ mIsSearchBarHidden = true;
+ }
+
+ /*
+ * Gets various transition durations.
+ */
+ public int getTransitionInDuration() {
+ return sTransitionInDuration;
+ }
+ public int getTransitionOutDuration() {
+ return sTransitionOutDuration;
}
/*
@@ -75,14 +104,18 @@
@Override
public void onDragStart(DragSource source, Object info, int dragAction) {
// Animate out the QSB search bar, and animate in the drop target bar
- mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration);
mDropTargetBar.animate().alpha(1f).setDuration(sTransitionInDuration);
+ if (!mIsSearchBarHidden) {
+ mQSBSearchBar.animate().alpha(0f).setDuration(sTransitionOutDuration);
+ }
}
@Override
public void onDragEnd() {
// Restore the QSB search bar, and animate out the drop target bar
mDropTargetBar.animate().alpha(0f).setDuration(sTransitionOutDuration);
- mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration);
+ if (!mIsSearchBarHidden) {
+ mQSBSearchBar.animate().alpha(1f).setDuration(sTransitionInDuration);
+ }
}
}
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 216c74e..1e01254 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -45,6 +45,7 @@
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region.Op;
@@ -61,8 +62,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
-import android.widget.TabHost;
-import android.widget.TabWidget;
import android.widget.TextView;
import android.widget.Toast;
@@ -106,17 +105,12 @@
private ValueAnimator mBackgroundFadeInAnimation;
private ValueAnimator mBackgroundFadeOutAnimation;
private Drawable mBackground;
- private Drawable mCustomizeTrayBackground;
boolean mDrawBackground = true;
- private boolean mDrawCustomizeTrayBackground;
private float mBackgroundAlpha = 0;
private float mOverScrollMaxBackgroundAlpha = 0.0f;
private int mOverScrollPageIndex = -1;
- private View mCustomizationDrawer;
- private View mCustomizationDrawerContent;
- private int[] mCustomizationDrawerPos = new int[2];
- private float[] mCustomizationDrawerTransformedPos = new float[2];
+
private final WallpaperManager mWallpaperManager;
private IBinder mWindowToken;
@@ -173,7 +167,7 @@
private boolean mIsInUnshrinkAnimation = false;
private AnimatorListener mShrinkAnimationListener;
private AnimatorListener mUnshrinkAnimationListener;
- enum ShrinkState { TOP, SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE };
+ enum ShrinkState { SPRING_LOADED, MIDDLE, BOTTOM_HIDDEN, BOTTOM_VISIBLE };
private ShrinkState mShrinkState;
private boolean mWaitingToShrink = false;
private ShrinkState mWaitingToShrinkState;
@@ -257,6 +251,9 @@
super(context, attrs, defStyle);
mContentIsRefreshable = false;
+ // With workspace, data is available straight from the get-go
+ setDataIsReady();
+
if (!LauncherApplication.isScreenLarge()) {
mFadeInAdjacentScreens = false;
}
@@ -330,7 +327,6 @@
try {
final Resources res = getResources();
mBackground = res.getDrawable(R.drawable.all_apps_bg_gradient);
- mCustomizeTrayBackground = res.getDrawable(R.drawable.customize_bg_gradient);
} catch (Resources.NotFoundException e) {
// In this case, we will skip drawing background protection
}
@@ -345,8 +341,12 @@
public void onAnimationEnd(Animator animation) {
mIsInUnshrinkAnimation = false;
mSyncWallpaperOffsetWithScroll = true;
- if (mShrinkState != ShrinkState.SPRING_LOADED) {
- mDrawCustomizeTrayBackground = false;
+ if (mShrinkState == ShrinkState.SPRING_LOADED) {
+ View layout = null;
+ if (mLastDragView != null) {
+ layout = findMatchingPageForDragOver(mLastDragView, mLastDragOriginX,
+ mLastDragOriginY, mLastDragXOffset, mLastDragYOffset);
+ }
}
mWallpaperOffset.setOverrideHorizontalCatchupConstant(false);
mAnimator = null;
@@ -598,24 +598,6 @@
mYDown = ev.getY();
}
- if (mIsSmall || mIsInUnshrinkAnimation) {
- if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
- // Intercept this event so we can show the workspace in full view
- // when it is clicked on and it is small
- PagedView appsPane = null;
- if (LauncherApplication.isScreenLarge()) {
- appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view);
- } else {
- appsPane = (PagedView) mLauncher.findViewById(R.id.apps_customize_pane_content);
- }
-
- if (appsPane != null) {
- appsPane.onInterceptTouchEvent(ev);
- }
- return true;
- }
- return false;
- }
return super.onInterceptTouchEvent(ev);
}
@@ -737,8 +719,13 @@
protected void setWallpaperDimension() {
Display display = mLauncher.getWindowManager().getDefaultDisplay();
- final int maxDim = Math.max(display.getWidth(), display.getHeight());
- final int minDim = Math.min(display.getWidth(), display.getHeight());
+ Point displaySize = new Point();
+ display.getSize(displaySize);
+ if (LauncherApplication.isScreenLarge()) {
+ displaySize.y += (int) getResources().getDimension(R.dimen.status_bar_height);
+ }
+ final int maxDim = Math.max(displaySize.x, displaySize.y);
+ final int minDim = Math.min(displaySize.x, displaySize.y);
// We need to ensure that there is enough extra space in the wallpaper for the intended
// parallax effects
@@ -1000,12 +987,6 @@
private void showBackgroundGradientForAllApps() {
showBackgroundGradient();
- mDrawCustomizeTrayBackground = false;
- }
-
- private void showBackgroundGradientForCustomizeTray() {
- showBackgroundGradient();
- mDrawCustomizeTrayBackground = true;
}
private void showBackgroundGradient() {
@@ -1169,12 +1150,6 @@
}
});
}
-
- if (LauncherApplication.isInPlaceRotationEnabled()) {
- // When the device is rotated, the scroll position of the current screen
- // needs to be refreshed
- setCurrentPage(getCurrentPage());
- }
}
public void showFolderAccept(FolderRingAnimator fra) {
@@ -1195,33 +1170,10 @@
// Draw the background gradient if necessary
if (mBackground != null && mBackgroundAlpha > 0.0f && mDrawBackground) {
int alpha = (int) (mBackgroundAlpha * 255);
- if (mDrawCustomizeTrayBackground) {
- // Find out where to offset the gradient for the customization tray content
- mCustomizationDrawer.getLocationOnScreen(mCustomizationDrawerPos);
- final Matrix m = mCustomizationDrawer.getMatrix();
- mCustomizationDrawerTransformedPos[0] = 0.0f;
- mCustomizationDrawerTransformedPos[1] = mCustomizationDrawerContent.getTop();
- m.mapPoints(mCustomizationDrawerTransformedPos);
-
- // Draw the bg glow behind the gradient
- mCustomizeTrayBackground.setAlpha(alpha);
- mCustomizeTrayBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(),
- getMeasuredHeight());
- mCustomizeTrayBackground.draw(canvas);
-
- // Draw the bg gradient
- final int offset = (int) (mCustomizationDrawerPos[1] +
- mCustomizationDrawerTransformedPos[1]);
- mBackground.setAlpha(alpha);
- mBackground.setBounds(mScrollX, offset, mScrollX + getMeasuredWidth(),
- offset + getMeasuredHeight());
- mBackground.draw(canvas);
- } else {
- mBackground.setAlpha(alpha);
- mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(),
- getMeasuredHeight());
- mBackground.draw(canvas);
- }
+ mBackground.setAlpha(alpha);
+ mBackground.setBounds(mScrollX, 0, mScrollX + getMeasuredWidth(),
+ getMeasuredHeight());
+ mBackground.draw(canvas);
}
// The folder outer / inner ring image(s)
@@ -1401,39 +1353,6 @@
}
}
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mLauncher.isAllAppsVisible() && mShrinkState == ShrinkState.BOTTOM_HIDDEN) {
- PagedView appsPane;
- if (LauncherApplication.isScreenLarge()) {
- appsPane = (PagedView) mLauncher.findViewById(R.id.all_apps_paged_view);
- } else {
- 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);
- }
-
protected void enableChildrenLayers(boolean enable) {
for (int i = 0; i < getPageCount(); i++) {
((ViewGroup)getChildAt(i)).setChildrenLayersEnabled(enable);
@@ -1488,18 +1407,6 @@
shrink(shrinkState, true);
}
- private int getCustomizeDrawerHeight() {
- TabHost customizationDrawer = mLauncher.getCustomizationDrawer();
- int height = customizationDrawer.getHeight();
- TabWidget tabWidget = (TabWidget)
- customizationDrawer.findViewById(com.android.internal.R.id.tabs);
- if (tabWidget.getTabCount() > 0) {
- TextView tabText = (TextView) tabWidget.getChildTabViewAt(0);
- // subtract the empty space above the tab text
- height -= ((tabWidget.getHeight() - tabText.getLineHeight())) / 2;
- }
- return height;
- }
// we use this to shrink the workspace for the all apps view and the customize view
public void shrink(ShrinkState shrinkState, boolean animated) {
@@ -1571,8 +1478,6 @@
} else if (shrinkState == ShrinkState.MIDDLE) {
y = screenHeight / 2 - scaledPageHeight / 2;
finalAlpha = 1.0f;
- } else if (shrinkState == ShrinkState.TOP) {
- y = (screenHeight - getCustomizeDrawerHeight() - scaledPageHeight) / 2;
}
int duration;
@@ -1667,11 +1572,6 @@
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;
@@ -1740,11 +1640,7 @@
}
setChildrenDrawnWithCacheEnabled(true);
- if (shrinkState == ShrinkState.TOP) {
- showBackgroundGradientForCustomizeTray();
- } else {
- showBackgroundGradientForAllApps();
- }
+ showBackgroundGradientForAllApps();
}
/*
@@ -1826,14 +1722,10 @@
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);
- }
+ 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
@@ -2045,14 +1937,6 @@
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) {
@@ -2541,13 +2425,6 @@
if (d.dragSource != this) {
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) d.dragInfo).dropPos = touchXY;
- return;
- }
onDropExternal(touchXY, d.dragInfo, dropTargetLayout, false, d.dragView);
} else if (mDragInfo != null) {
final View cell = mDragInfo.cell;
@@ -2678,42 +2555,6 @@
}
public DropTarget getDropTargetDelegate(DragObject d) {
-
- if (mIsSmall || mIsInUnshrinkAnimation) {
- // If we're shrunken, don't let anyone drag on folders/etc that are on the mini-screens
- return null;
- }
- // We may need to delegate the drag to a child view. If a 1x1 item
- // would land in a cell occupied by a DragTarget (e.g. a Folder),
- // then drag events should be handled by that child.
-
- ItemInfo item = (ItemInfo) d.dragInfo;
- CellLayout currentLayout = getCurrentDropLayout();
-
- int dragPointX, dragPointY;
- if (item.spanX == 1 && item.spanY == 1) {
- // For a 1x1, calculate the drop cell exactly as in onDragOver
- dragPointX = d.x - d.xOffset;
- dragPointY = d.y - d.yOffset;
- } else {
- // Otherwise, use the exact drag coordinates
- dragPointX = d.x;
- dragPointY = d.y;
- }
- dragPointX += mScrollX - currentLayout.getLeft();
- dragPointY += mScrollY - currentLayout.getTop();
-
- // If we are dragging over a cell that contains a DropTarget that will
- // accept the drop, delegate to that DropTarget.
- final int[] cellXY = mTempCell;
- currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY);
- View child = currentLayout.getChildAt(cellXY[0], cellXY[1]);
- if (child instanceof DropTarget) {
- DropTarget target = (DropTarget)child;
- if (target.acceptDrop(d)) {
- return target;
- }
- }
return null;
}
@@ -3367,12 +3208,6 @@
void setup(Launcher launcher, DragController dragController) {
mLauncher = launcher;
mSpringLoadedDragController = new SpringLoadedDragController(mLauncher);
-
- mCustomizationDrawer = mLauncher.findViewById(R.id.customization_drawer);
- if (mCustomizationDrawer != null) {
- mCustomizationDrawerContent =
- mCustomizationDrawer.findViewById(com.android.internal.R.id.tabcontent);
- }
mDragController = dragController;
}
@@ -3688,5 +3523,4 @@
@Override
public void syncPageItems(int page) {
}
-
}