summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2013-02-15 14:45:54 -0800
committerSteve Kondik <shade@chemlab.org>2013-02-15 14:45:54 -0800
commited1816e3a828046439da5cb31a65af4641be9076 (patch)
tree994e4ed51b3e1630e338b3ec255a8f4dce429953
parentc43d6eebe95dcabcb4ded1c4da8c6cc21d2514f5 (diff)
parent002c25eede2a33a5378c16c5bb9165179783e729 (diff)
downloadandroid_packages_apps_Trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.tar.gz
android_packages_apps_Trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.tar.bz2
android_packages_apps_Trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.zip
Merge tag 'android-4.2.2_r1' of https://android.googlesource.com/platform/packages/apps/Launcher2 into treb
Android 4.2.2 release 1 Conflicts: res/layout-land/launcher.xml res/layout-port/launcher.xml res/layout-sw720dp/launcher.xml src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java src/com/cyanogenmod/trebuchet/CellLayout.java src/com/cyanogenmod/trebuchet/Launcher.java src/com/cyanogenmod/trebuchet/PagedView.java Change-Id: I415138430337bcd21070b815a80de9c0cdd52239
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/drawable-hdpi/ic_launcher_wallpaper.pngbin4034 -> 0 bytes
-rw-r--r--res/drawable-mdpi/ic_launcher_wallpaper.pngbin2850 -> 0 bytes
-rw-r--r--res/drawable-xhdpi/ic_launcher_wallpaper.pngbin7201 -> 0 bytes
-rw-r--r--res/layout-land/launcher.xml152
-rw-r--r--res/layout-port/launcher.xml176
-rw-r--r--res/layout-sw720dp/launcher.xml177
-rwxr-xr-xres/mipmap-hdpi/ic_launcher_home.png (renamed from res/drawable-hdpi/ic_launcher_home.png)bin23597 -> 23597 bytes
-rw-r--r--res/mipmap-hdpi/ic_launcher_wallpaper.pngbin0 -> 4418 bytes
-rwxr-xr-xres/mipmap-mdpi/ic_launcher_home.png (renamed from res/drawable-mdpi/ic_launcher_home.png)bin12053 -> 12053 bytes
-rw-r--r--res/mipmap-mdpi/ic_launcher_wallpaper.pngbin0 -> 2871 bytes
-rwxr-xr-xres/mipmap-xhdpi/ic_launcher_home.png (renamed from res/drawable-xhdpi/ic_launcher_home.png)bin39749 -> 39749 bytes
-rw-r--r--res/mipmap-xhdpi/ic_launcher_wallpaper.pngbin0 -> 6061 bytes
-rw-r--r--res/mipmap-xxhdpi/ic_launcher_wallpaper.pngbin0 -> 7596 bytes
-rw-r--r--src/com/cyanogenmod/trebuchet/AddAdapter.java2
-rw-r--r--src/com/cyanogenmod/trebuchet/AppWidgetResizeFrame.java6
-rw-r--r--src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java3
-rw-r--r--src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java159
-rw-r--r--src/com/cyanogenmod/trebuchet/CellLayout.java521
-rw-r--r--src/com/cyanogenmod/trebuchet/Launcher.java66
-rw-r--r--src/com/cyanogenmod/trebuchet/LauncherAppWidgetInfo.java1
-rw-r--r--src/com/cyanogenmod/trebuchet/PagedView.java16
22 files changed, 783 insertions, 500 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index f9271e4e7..78e4db744 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -65,7 +65,7 @@
<application
android:name="com.cyanogenmod.trebuchet.LauncherApplication"
android:label="@string/application_name"
- android:icon="@drawable/ic_launcher_home"
+ android:icon="@mipmap/ic_launcher_home"
android:hardwareAccelerated="true"
android:largeHeap="@bool/config_largeHeap"
android:supportsRtl="true">
@@ -88,7 +88,7 @@
android:name="com.cyanogenmod.trebuchet.WallpaperChooser"
android:theme="@style/Theme.WallpaperPicker"
android:label="@string/pick_wallpaper"
- android:icon="@drawable/ic_launcher_wallpaper"
+ android:icon="@mipmap/ic_launcher_wallpaper"
android:finishOnCloseSystemDialogs="true"
android:process=":wallpaper_chooser">
<intent-filter>
diff --git a/res/drawable-hdpi/ic_launcher_wallpaper.png b/res/drawable-hdpi/ic_launcher_wallpaper.png
deleted file mode 100644
index 5c8ee24bb..000000000
--- a/res/drawable-hdpi/ic_launcher_wallpaper.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_wallpaper.png b/res/drawable-mdpi/ic_launcher_wallpaper.png
deleted file mode 100644
index d2803b1ca..000000000
--- a/res/drawable-mdpi/ic_launcher_wallpaper.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_wallpaper.png b/res/drawable-xhdpi/ic_launcher_wallpaper.png
deleted file mode 100644
index 9b0b7b2bc..000000000
--- a/res/drawable-xhdpi/ic_launcher_wallpaper.png
+++ /dev/null
Binary files differ
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index f6ac21d59..c6156c163 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -14,85 +14,97 @@
limitations under the License.
-->
-<com.cyanogenmod.trebuchet.DragLayer
+<!-- Full screen view projects under the status bar and contains the background -->
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.cyanogenmod.trebuchet"
-
- android:id="@+id/drag_layer"
+ android:id="@+id/launcher"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@drawable/workspace_bg">
- <!-- The workspace contains 5 screens of cells -->
- <com.cyanogenmod.trebuchet.Workspace
- android:id="@+id/workspace"
+ <com.cyanogenmod.trebuchet.DragLayer
+ android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingLeft="@dimen/workspace_left_padding"
- android:paddingRight="@dimen/workspace_right_padding"
- android:paddingTop="@dimen/workspace_top_padding"
- android:paddingBottom="@dimen/workspace_bottom_padding"
- launcher:cellCountX="@integer/target_cell_count_x"
- launcher:cellCountY="@integer/target_cell_count_y"
- launcher:pageSpacing="@dimen/workspace_page_spacing"
- launcher:scrollIndicatorPaddingLeft="@dimen/qsb_bar_height"
- launcher:scrollIndicatorPaddingRight="@dimen/button_bar_height" />
+ android:fitsSystemWindows="true">
- <include
- android:id="@+id/qsb_divider"
- layout="@layout/workspace_divider"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginLeft="@dimen/qsb_bar_height"
- android:layout_gravity="left" />
- <include
- android:id="@+id/dock_divider"
- layout="@layout/workspace_divider"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_marginRight="@dimen/button_bar_height"
- android:layout_gravity="right" />
- <include
- android:id="@+id/paged_view_indicator_horizontal"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
+ <!-- The workspace contains 5 screens of cells -->
+ <com.cyanogenmod.trebuchet.Workspace
+ android:id="@+id/workspace"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/workspace_left_padding"
+ android:paddingRight="@dimen/workspace_right_padding"
+ android:paddingTop="@dimen/workspace_top_padding"
+ android:paddingBottom="@dimen/workspace_bottom_padding"
+ launcher:cellCountX="@integer/target_cell_count_x"
+ launcher:cellCountY="@integer/target_cell_count_y"
+ launcher:pageSpacing="@dimen/workspace_page_spacing"
+ launcher:scrollIndicatorPaddingLeft="@dimen/qsb_bar_height"
+ launcher:scrollIndicatorPaddingRight="@dimen/button_bar_height" />
+
+ <include
+ android:id="@+id/qsb_divider"
+ layout="@layout/workspace_divider"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="@dimen/qsb_bar_height"
+ android:layout_gravity="left" />
+ <include
+ android:id="@+id/dock_divider"
+ layout="@layout/workspace_divider"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginRight="@dimen/button_bar_height"
+ android:layout_gravity="right" />
+ <include
+ android:id="@+id/paged_view_indicator_horizontal"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom" />
- <include layout="@layout/hotseat"
- android:id="@+id/hotseat"
- android:layout_width="@dimen/button_bar_height_plus_padding"
- android:layout_height="match_parent"
- android:layout_gravity="right" />
- <include
- android:id="@+id/qsb_bar"
- layout="@layout/qsb_bar" />
+ <include layout="@layout/hotseat"
+ android:id="@+id/hotseat"
+ android:layout_width="@dimen/button_bar_height_plus_padding"
+ android:layout_height="match_parent"
+ android:layout_gravity="right" />
+ <include
+ android:id="@+id/qsb_bar"
+ layout="@layout/qsb_bar" />
- <com.cyanogenmod.trebuchet.DrawableStateProxyView
- android:id="@+id/voice_button_proxy"
- android:layout_width="@dimen/qsb_bar_height"
- android:layout_height="@dimen/app_icon_size"
- android:layout_gravity="top|left"
- android:layout_marginTop="64dp"
- android:clickable="true"
- android:onClick="onClickVoiceButton"
- android:importantForAccessibility="no"
- launcher:sourceViewId="@+id/voice_button" />
+ <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
+ that it is still visible during the transition to AllApps and doesn't overlay on
+ top of that view. -->
+ <include layout="@layout/workspace_cling"
+ android:id="@+id/workspace_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible" />
+ <include layout="@layout/folder_cling"
+ android:id="@+id/folder_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
- <include layout="@layout/workspace_cling"
- android:id="@+id/workspace_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
+ <com.cyanogenmod.trebuchet.DrawableStateProxyView
+ android:id="@+id/voice_button_proxy"
+ android:layout_width="@dimen/qsb_bar_height"
+ android:layout_height="@dimen/app_icon_size"
+ android:layout_gravity="top|left"
+ android:layout_marginTop="64dp"
+ android:clickable="true"
+ android:onClick="onClickVoiceButton"
+ android:importantForAccessibility="no"
+ launcher:sourceViewId="@+id/voice_button" />
- <include layout="@layout/folder_cling"
- android:id="@+id/folder_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
-</com.cyanogenmod.trebuchet.DragLayer>
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
+ </com.cyanogenmod.trebuchet.DragLayer>
+</FrameLayout>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index f05aac7b8..dbfcfcef9 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -14,93 +14,105 @@
limitations under the License.
-->
-<com.cyanogenmod.trebuchet.DragLayer
+<!-- Full screen view projects under the status bar and contains the background -->
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.cyanogenmod.trebuchet"
-
- android:id="@+id/drag_layer"
+ android:id="@+id/launcher"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@drawable/workspace_bg">
- <!-- The workspace contains 5 screens of cells -->
- <com.cyanogenmod.trebuchet.Workspace
- android:id="@+id/workspace"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingLeft="@dimen/workspace_left_padding"
- android:paddingRight="@dimen/workspace_right_padding"
- android:paddingTop="@dimen/workspace_top_padding"
- android:paddingBottom="@dimen/workspace_bottom_padding"
- launcher:cellCountX="@integer/target_cell_count_x"
- launcher:cellCountY="@integer/target_cell_count_y"
- launcher:pageSpacing="@dimen/workspace_page_spacing"
- launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
- launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right" />
-
- <include
- android:id="@+id/dock_divider"
- layout="@layout/workspace_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/button_bar_height"
- android:layout_gravity="bottom" />
- <include
- android:id="@+id/paged_view_indicator_dock"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginBottom="@dimen/button_bar_height" />
-
- <include
- android:id="@+id/paged_view_indicator_top"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top" />
-
- <include
- android:id="@+id/paged_view_indicator_bottom"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <include layout="@layout/hotseat"
- android:id="@+id/hotseat"
- android:layout_width="match_parent"
- android:layout_height="@dimen/button_bar_height_plus_padding"
- android:layout_gravity="bottom" />
-
- <include
- android:id="@+id/qsb_bar"
- layout="@layout/qsb_bar" />
-
- <com.cyanogenmod.trebuchet.DrawableStateProxyView
- android:id="@+id/voice_button_proxy"
- android:layout_width="80dp"
- android:layout_height="@dimen/qsb_bar_height"
- android:layout_gravity="top|right"
- android:clickable="true"
- android:onClick="onClickVoiceButton"
- android:importantForAccessibility="no"
- launcher:sourceViewId="@+id/voice_button" />
-
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
+ <com.cyanogenmod.trebuchet.DragLayer
+ android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="invisible" />
+ android:fitsSystemWindows="true">
- <include layout="@layout/workspace_cling"
- android:id="@+id/workspace_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
+ <!-- The workspace contains 5 screens of cells -->
+ <com.cyanogenmod.trebuchet.Workspace
+ android:id="@+id/workspace"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/workspace_left_padding"
+ android:paddingRight="@dimen/workspace_right_padding"
+ android:paddingTop="@dimen/workspace_top_padding"
+ android:paddingBottom="@dimen/workspace_bottom_padding"
+ launcher:cellCountX="@integer/target_cell_count_x"
+ launcher:cellCountY="@integer/target_cell_count_y"
+ launcher:pageSpacing="@dimen/workspace_page_spacing"
+ launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
+ launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right" />
- <include layout="@layout/folder_cling"
- android:id="@+id/folder_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
-</com.cyanogenmod.trebuchet.DragLayer>
+ <include
+ android:id="@+id/dock_divider"
+ layout="@layout/workspace_divider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/button_bar_height"
+ android:layout_gravity="bottom" />
+ <include
+ android:id="@+id/paged_view_indicator_dock"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="@dimen/button_bar_height" />
+
+ <include
+ android:id="@+id/paged_view_indicator_top"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top" />
+
+ <include
+ android:id="@+id/paged_view_indicator_bottom"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom" />
+
+ <include layout="@layout/hotseat"
+ android:id="@+id/hotseat"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/button_bar_height_plus_padding"
+ android:layout_gravity="bottom" />
+
+ <include
+ android:id="@+id/qsb_bar"
+ layout="@layout/qsb_bar" />
+
+ <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
+ that it is still visible during the transition to AllApps and doesn't overlay on
+ top of that view. -->
+ <include layout="@layout/workspace_cling"
+ android:id="@+id/workspace_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <include layout="@layout/folder_cling"
+ android:id="@+id/folder_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <com.cyanogenmod.trebuchet.DrawableStateProxyView
+ android:id="@+id/voice_button_proxy"
+ android:layout_width="80dp"
+ android:layout_height="@dimen/qsb_bar_height"
+ android:layout_gravity="top|right"
+ android:clickable="true"
+ android:onClick="onClickVoiceButton"
+ android:importantForAccessibility="no"
+ launcher:sourceViewId="@+id/voice_button" />
+
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
+ </com.cyanogenmod.trebuchet.DragLayer>
+</FrameLayout>
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index be3404589..443db2e4c 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -14,95 +14,106 @@
limitations under the License.
-->
-<com.cyanogenmod.trebuchet.DragLayer
+<!-- Full screen view projects under the status bar and contains the background -->
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res/com.cyanogenmod.trebuchet"
- android:id="@+id/drag_layer"
- android:background="@drawable/workspace_bg"
+ android:id="@+id/launcher"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="@drawable/workspace_bg">
- <!-- The workspace contains 5 screens of cells -->
- <com.cyanogenmod.trebuchet.Workspace
- android:id="@+id/workspace"
+ <com.cyanogenmod.trebuchet.DragLayer
+ android:id="@+id/drag_layer"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingLeft="@dimen/workspace_left_padding"
- android:paddingRight="@dimen/workspace_right_padding"
- android:paddingTop="@dimen/workspace_top_padding"
- android:paddingBottom="@dimen/workspace_bottom_padding"
- launcher:cellCountX="@integer/target_cell_count_x"
- launcher:cellCountY="@integer/target_cell_count_y"
- launcher:pageSpacing="@dimen/workspace_page_spacing"
- launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
- launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right" />
-
- <include
- android:id="@+id/dock_divider"
- layout="@layout/workspace_divider"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/button_bar_height_plus_padding"
- android:layout_gravity="bottom|center_horizontal" />
- <include
- android:id="@+id/paged_view_indicator_dock"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
-
- <include
- android:id="@+id/paged_view_indicator_top"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top" />
-
- <include
- android:id="@+id/paged_view_indicator_bottom"
- layout="@layout/scroll_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom" />
-
- <include layout="@layout/hotseat"
- android:id="@+id/hotseat"
- android:layout_width="match_parent"
- android:layout_height="@dimen/button_bar_height_plus_padding"
- android:layout_gravity="bottom" />
-
- <include
- android:id="@+id/qsb_bar"
- layout="@layout/qsb_bar" />
-
- <com.cyanogenmod.trebuchet.DrawableStateProxyView
- android:id="@+id/voice_button_proxy"
- android:layout_width="80dp"
- android:layout_height="@dimen/qsb_bar_height"
- android:layout_marginRight="@dimen/qsb_voice_proxy_padding_right"
- android:layout_gravity="top|right"
- android:clickable="true"
- android:onClick="onClickVoiceButton"
- android:importantForAccessibility="no"
- launcher:sourceViewId="@+id/voice_button" />
-
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible" />
+ android:fitsSystemWindows="true">
- <include layout="@layout/workspace_cling"
- android:id="@+id/workspace_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
+ <!-- The workspace contains 5 screens of cells -->
+ <com.cyanogenmod.trebuchet.Workspace
+ android:id="@+id/workspace"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingLeft="@dimen/workspace_left_padding"
+ android:paddingRight="@dimen/workspace_right_padding"
+ android:paddingTop="@dimen/workspace_top_padding"
+ android:paddingBottom="@dimen/workspace_bottom_padding"
+ launcher:cellCountX="@integer/target_cell_count_x"
+ launcher:cellCountY="@integer/target_cell_count_y"
+ launcher:pageSpacing="@dimen/workspace_page_spacing"
+ launcher:scrollIndicatorPaddingLeft="@dimen/workspace_divider_padding_left"
+ launcher:scrollIndicatorPaddingRight="@dimen/workspace_divider_padding_right" />
- <include layout="@layout/folder_cling"
- android:id="@+id/folder_cling"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
-</com.cyanogenmod.trebuchet.DragLayer>
+ <include
+ android:id="@+id/dock_divider"
+ layout="@layout/workspace_divider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/button_bar_height_plus_padding"
+ android:layout_gravity="bottom|center_horizontal" />
+ <include
+ android:id="@+id/paged_view_indicator_dock"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:layout_marginBottom="@dimen/button_bar_height_plus_padding" />
+
+ <include
+ android:id="@+id/paged_view_indicator_top"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top" />
+
+ <include
+ android:id="@+id/paged_view_indicator_bottom"
+ layout="@layout/scroll_indicator"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom" />
+
+ <include layout="@layout/hotseat"
+ android:id="@+id/hotseat"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/button_bar_height_plus_padding"
+ android:layout_gravity="bottom" />
+
+ <include
+ android:id="@+id/qsb_bar"
+ layout="@layout/qsb_bar" />
+
+ <!-- The Workspace cling must appear under the AppsCustomizePagedView below to ensure
+ that it is still visible during the transition to AllApps and doesn't overlay on
+ top of that view. -->
+ <include layout="@layout/workspace_cling"
+ android:id="@+id/workspace_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <include layout="@layout/folder_cling"
+ android:id="@+id/folder_cling"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone" />
+
+ <com.cyanogenmod.trebuchet.DrawableStateProxyView
+ android:id="@+id/voice_button_proxy"
+ android:layout_width="80dp"
+ android:layout_height="@dimen/qsb_bar_height"
+ android:layout_marginRight="@dimen/qsb_voice_proxy_padding_right"
+ android:layout_gravity="top|right"
+ android:clickable="true"
+ android:onClick="onClickVoiceButton"
+ android:importantForAccessibility="no"
+ launcher:sourceViewId="@+id/voice_button" />
+
+ <include layout="@layout/apps_customize_pane"
+ android:id="@+id/apps_customize_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+ </com.cyanogenmod.trebuchet.DragLayer>
+</FrameLayout>
diff --git a/res/drawable-hdpi/ic_launcher_home.png b/res/mipmap-hdpi/ic_launcher_home.png
index 33d36b0dc..33d36b0dc 100755
--- a/res/drawable-hdpi/ic_launcher_home.png
+++ b/res/mipmap-hdpi/ic_launcher_home.png
Binary files differ
diff --git a/res/mipmap-hdpi/ic_launcher_wallpaper.png b/res/mipmap-hdpi/ic_launcher_wallpaper.png
new file mode 100644
index 000000000..affee851d
--- /dev/null
+++ b/res/mipmap-hdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_home.png b/res/mipmap-mdpi/ic_launcher_home.png
index 5ab889c9a..5ab889c9a 100755
--- a/res/drawable-mdpi/ic_launcher_home.png
+++ b/res/mipmap-mdpi/ic_launcher_home.png
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_wallpaper.png b/res/mipmap-mdpi/ic_launcher_wallpaper.png
new file mode 100644
index 000000000..cb4443bdb
--- /dev/null
+++ b/res/mipmap-mdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_home.png b/res/mipmap-xhdpi/ic_launcher_home.png
index 70ec47580..70ec47580 100755
--- a/res/drawable-xhdpi/ic_launcher_home.png
+++ b/res/mipmap-xhdpi/ic_launcher_home.png
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_wallpaper.png b/res/mipmap-xhdpi/ic_launcher_wallpaper.png
new file mode 100644
index 000000000..60f8dceec
--- /dev/null
+++ b/res/mipmap-xhdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_wallpaper.png b/res/mipmap-xxhdpi/ic_launcher_wallpaper.png
new file mode 100644
index 000000000..023fb5886
--- /dev/null
+++ b/res/mipmap-xxhdpi/ic_launcher_wallpaper.png
Binary files differ
diff --git a/src/com/cyanogenmod/trebuchet/AddAdapter.java b/src/com/cyanogenmod/trebuchet/AddAdapter.java
index 5a3d43d05..8f4e8fcfd 100644
--- a/src/com/cyanogenmod/trebuchet/AddAdapter.java
+++ b/src/com/cyanogenmod/trebuchet/AddAdapter.java
@@ -71,7 +71,7 @@ public class AddAdapter extends BaseAdapter {
Resources res = launcher.getResources();
mItems.add(new ListItem(res, R.string.group_wallpapers,
- R.drawable.ic_launcher_wallpaper, ITEM_WALLPAPER));
+ R.mipmap.ic_launcher_wallpaper, ITEM_WALLPAPER));
}
public View getView(int position, View convertView, ViewGroup parent) {
diff --git a/src/com/cyanogenmod/trebuchet/AppWidgetResizeFrame.java b/src/com/cyanogenmod/trebuchet/AppWidgetResizeFrame.java
index 5b868c179..48d41160d 100644
--- a/src/com/cyanogenmod/trebuchet/AppWidgetResizeFrame.java
+++ b/src/com/cyanogenmod/trebuchet/AppWidgetResizeFrame.java
@@ -389,8 +389,10 @@ public class AppWidgetResizeFrame extends FrameLayout {
public void snapToWidget(boolean animate) {
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
- int xOffset = mCellLayout.getLeft() + mCellLayout.getPaddingLeft() - mWorkspace.getScrollX();
- int yOffset = mCellLayout.getTop() + mCellLayout.getPaddingTop() - mWorkspace.getScrollY();
+ int xOffset = mCellLayout.getLeft() + mCellLayout.getPaddingLeft()
+ + mDragLayer.getPaddingLeft() - mWorkspace.getScrollX();
+ int yOffset = mCellLayout.getTop() + mCellLayout.getPaddingTop()
+ + mDragLayer.getPaddingTop() - mWorkspace.getScrollY();
int newWidth = mWidgetView.getWidth() + 2 * mBackgroundPadding - mWidgetPaddingLeft -
mWidgetPaddingRight;
diff --git a/src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java b/src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java
index 8d4e4d791..9f7595d96 100644
--- a/src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java
+++ b/src/com/cyanogenmod/trebuchet/AppsCustomizePagedView.java
@@ -600,9 +600,10 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int[] pos = mWidgetSpacingLayout.estimateCellPosition(mClingFocusedX, mClingFocusedY);
mLauncher.getDragLayer().getLocationInDragLayer(this, offset);
// PagedViews are centered horizontally but top aligned
+ // Note we have to shift the items up now that Launcher sits under the status bar
pos[0] += (getMeasuredWidth() - mWidgetSpacingLayout.getMeasuredWidth()) / 2 +
offset[0];
- pos[1] += offset[1];
+ pos[1] += offset[1] - mLauncher.getDragLayer().getPaddingTop();
mLauncher.showFirstRunAllAppsCling(pos);
} else if (!mHasShownAllAppsSortCling && isDataReady() &&
allAppsCling != null && allAppsCling.isDismissed()) {
diff --git a/src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java b/src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java
index 08d959753..067b98ff2 100644
--- a/src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java
+++ b/src/com/cyanogenmod/trebuchet/AppsCustomizeTabHost.java
@@ -232,81 +232,87 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona
post(new Runnable() {
@Override
public void run() {
- if (mAppsCustomizePane.getMeasuredWidth() <= 0 ||
- mAppsCustomizePane.getMeasuredHeight() <= 0) {
- reloadCurrentPage();
- return;
- }
- // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
- // and then cross fade to the new pages
- int[] visiblePageRange = new int[2];
- mAppsCustomizePane.getVisiblePages(visiblePageRange);
- if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) {
- // If we can't get the visible page ranges, then just skip the animation
- reloadCurrentPage();
- return;
- }
- ArrayList<View> visiblePages = new ArrayList<View>();
- for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
- visiblePages.add(mAppsCustomizePane.getPageAt(i));
- }
- // We want the pages to be rendered in exactly the same way as they were when
- // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
- // to be exactly the same as mAppsCustomizePane, and below, set the left/top
- // parameters to be correct for each of the pages
- mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
-
- // mAppsCustomizePane renders its children in reverse order, so
- // add the pages to mAnimationBuffer in reverse order to match that behavior
- for (int i = visiblePages.size() - 1; i >= 0; i--) {
- View child = visiblePages.get(i);
- if (child instanceof PagedViewCellLayout) {
- ((PagedViewCellLayout) child).resetChildrenOnKeyListeners();
- } else if (child instanceof PagedViewGridLayout) {
- ((PagedViewGridLayout) child).resetChildrenOnKeyListeners();
+ if (mAppsCustomizePane.getMeasuredWidth() <= 0 ||
+ mAppsCustomizePane.getMeasuredHeight() <= 0) {
+ reloadCurrentPage();
+ return;
}
- PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
- mAppsCustomizePane.removeView(child);
- PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
- mAnimationBuffer.setAlpha(1f);
- mAnimationBuffer.setVisibility(View.VISIBLE);
- LayoutParams p = new FrameLayout.LayoutParams(child.getMeasuredWidth(),
- child.getMeasuredHeight());
- p.setMargins(child.getLeft(), child.getTop(), 0, 0);
- mAnimationBuffer.addView(child, p);
-
- // Toggle the new content
- onTabChangedStart();
- onTabChangedEnd(type);
-
- // Animate the transition
- ObjectAnimator outAnim = LauncherAnimUtils.ofFloat(mAnimationBuffer, "alpha", 0f);
- outAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimationBuffer.setVisibility(View.GONE);
- mAnimationBuffer.removeAllViews();
+ // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
+ // and then cross fade to the new pages
+ int[] visiblePageRange = new int[2];
+ mAppsCustomizePane.getVisiblePages(visiblePageRange);
+ if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) {
+ // If we can't get the visible page ranges, then just skip the animation
+ reloadCurrentPage();
+ return;
}
- @Override
- public void onAnimationCancel(Animator animation) {
- mAnimationBuffer.setVisibility(View.GONE);
- mAnimationBuffer.removeAllViews();
+ ArrayList<View> visiblePages = new ArrayList<View>();
+ for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
+ visiblePages.add(mAppsCustomizePane.getPageAt(i));
}
- });
- ObjectAnimator inAnim = LauncherAnimUtils.ofFloat(mAppsCustomizePane, "alpha", 1f);
- inAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- reloadCurrentPage();
+ // We want the pages to be rendered in exactly the same way as they were when
+ // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
+ // to be exactly the same as mAppsCustomizePane, and below, set the left/top
+ // parameters to be correct for each of the pages
+ mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
+
+ // mAppsCustomizePane renders its children in reverse order, so
+ // add the pages to mAnimationBuffer in reverse order to match that behavior
+ for (int i = visiblePages.size() - 1; i >= 0; i--) {
+ View child = visiblePages.get(i);
+ if (child instanceof PagedViewCellLayout) {
+ ((PagedViewCellLayout) child).resetChildrenOnKeyListeners();
+ } else if (child instanceof PagedViewGridLayout) {
+ ((PagedViewGridLayout) child).resetChildrenOnKeyListeners();
+ }
+ PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
+ mAppsCustomizePane.removeView(child);
+ PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
+ mAnimationBuffer.setAlpha(1f);
+ mAnimationBuffer.setVisibility(View.VISIBLE);
+ LayoutParams p = new FrameLayout.LayoutParams(child.getMeasuredWidth(),
+ child.getMeasuredHeight());
+ p.setMargins(child.getLeft(), child.getTop(), 0, 0);
+ mAnimationBuffer.addView(child, p);
}
- });
- AnimatorSet animSet = LauncherAnimUtils.createAnimatorSet();
- animSet.playTogether(outAnim, inAnim);
- animSet.setDuration(duration);
- animSet.start();
- }}
- });
- }
+
+ // Toggle the new content
+ onTabChangedStart();
+ onTabChangedEnd(type);
+
+ // Animate the transition
+ ObjectAnimator outAnim = LauncherAnimUtils.ofFloat(mAnimationBuffer, "alpha", 0f);
+ outAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimationBuffer.setVisibility(View.GONE);
+ mAnimationBuffer.removeAllViews();
+ }
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mAnimationBuffer.setVisibility(View.GONE);
+ mAnimationBuffer.removeAllViews();
+ }
+ });
+ ObjectAnimator inAnim = LauncherAnimUtils.ofFloat(mAppsCustomizePane, "alpha", 1f);
+ inAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ reloadCurrentPage();
+ }
+ });
+
+ final AnimatorSet animSet = LauncherAnimUtils.createAnimatorSet();
+ animSet.playTogether(outAnim, inAnim);
+ animSet.setDuration(duration);
+ post(new Runnable() {
+ public void run() {
+ animSet.start();
+ }
+ });
+ }
+ });
+ }
}
public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) {
@@ -432,11 +438,9 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona
}
if (!toWorkspace) {
- // Going from Workspace -> All Apps
- setVisibilityOfSiblingsWithLowerZOrder(INVISIBLE);
-
- // Dismiss the workspace cling and show the all apps cling (if not already shown)
+ // Dismiss the workspace cling
l.dismissWorkspaceCling(null);
+ // Show the all apps cling (if not already shown)
mAppsCustomizePane.showAllAppsCling();
// Make sure adjacent pages are loaded (we wait until after the transition to
// prevent slowing down the animation)
@@ -445,6 +449,11 @@ public class AppsCustomizeTabHost extends TabHost implements LauncherTransitiona
if (!LauncherApplication.isScreenLarge() && mFadeScrollingIndicator) {
mAppsCustomizePane.hideScrollingIndicator(false);
}
+
+ // Going from Workspace -> All Apps
+ // NOTE: We should do this at the end since we check visibility state in some of the
+ // cling initialization/dismiss code above.
+ setVisibilityOfSiblingsWithLowerZOrder(INVISIBLE);
}
}
diff --git a/src/com/cyanogenmod/trebuchet/CellLayout.java b/src/com/cyanogenmod/trebuchet/CellLayout.java
index 1fd5a5fa8..a59a96e0d 100644
--- a/src/com/cyanogenmod/trebuchet/CellLayout.java
+++ b/src/com/cyanogenmod/trebuchet/CellLayout.java
@@ -52,6 +52,8 @@ import com.cyanogenmod.trebuchet.FolderIcon.FolderRingAnimator;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Stack;
@@ -1561,48 +1563,6 @@ public class CellLayout extends ViewGroup {
return bestXY;
}
- private int[] findNearestAreaInDirection(int cellX, int cellY, int spanX, int spanY,
- int[] direction,boolean[][] occupied,
- boolean blockOccupied[][], int[] result) {
- // Keep track of best-scoring drop area
- final int[] bestXY = result != null ? result : new int[2];
- bestXY[0] = -1;
- bestXY[1] = -1;
- float bestDistance = Float.MAX_VALUE;
-
- // We use this to march in a single direction
- if ((direction[0] != 0 && direction[1] != 0) ||
- (direction[0] == 0 && direction[1] == 0)) {
- return bestXY;
- }
-
- // This will only incrememnet one of x or y based on the assertion above
- int x = cellX + direction[0];
- int y = cellY + direction[1];
- while (x >= 0 && x + spanX <= mCountX && y >= 0 && y + spanY <= mCountY) {
- boolean fail = false;
- for (int i = 0; i < spanX; i++) {
- for (int j = 0; j < spanY; j++) {
- if (occupied[x + i][y + j] && (blockOccupied == null || blockOccupied[i][j])) {
- fail = true;
- }
- }
- }
- if (!fail) {
- float distance = (float)
- Math.sqrt((x - cellX) * (x - cellX) + (y - cellY) * (y - cellY));
- if (Float.compare(distance, bestDistance) < 0) {
- bestDistance = distance;
- bestXY[0] = x;
- bestXY[1] = y;
- }
- }
- x += direction[0];
- y += direction[1];
- }
- return bestXY;
- }
-
private boolean addViewToTempLocation(View v, Rect rectOccupiedByPotentialDrop,
int[] direction, ItemConfiguration currentState) {
CellAndSpan c = currentState.map.get(v);
@@ -1616,118 +1576,343 @@ public class CellLayout extends ViewGroup {
c.x = mTempLocation[0];
c.y = mTempLocation[1];
success = true;
-
}
markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
return success;
}
- // This method looks in the specified direction to see if there are additional views adjacent
- // to the current set of views. If there are, then these views are added to the current
- // set of views. This is performed iteratively, giving a cascading push behaviour.
- private boolean addViewInDirection(ArrayList<View> views, Rect boundingRect, int[] direction,
- boolean[][] occupied, View dragView, ItemConfiguration currentState) {
- boolean found = false;
+ /**
+ * This helper class defines a cluster of views. It helps with defining complex edges
+ * of the cluster and determining how those edges interact with other views. The edges
+ * essentially define a fine-grained boundary around the cluster of views -- like a more
+ * precise version of a bounding box.
+ */
+ private class ViewCluster {
+ final static int LEFT = 0;
+ final static int TOP = 1;
+ final static int RIGHT = 2;
+ final static int BOTTOM = 3;
+
+ ArrayList<View> views;
+ ItemConfiguration config;
+ Rect boundingRect = new Rect();
+
+ int[] leftEdge = new int[mCountY];
+ int[] rightEdge = new int[mCountY];
+ int[] topEdge = new int[mCountX];
+ int[] bottomEdge = new int[mCountX];
+ boolean leftEdgeDirty, rightEdgeDirty, topEdgeDirty, bottomEdgeDirty, boundingRectDirty;
- int childCount = mShortcutsAndWidgets.getChildCount();
- Rect r0 = new Rect(boundingRect);
- Rect r1 = new Rect();
+ @SuppressWarnings("unchecked")
+ public ViewCluster(ArrayList<View> views, ItemConfiguration config) {
+ this.views = (ArrayList<View>) views.clone();
+ this.config = config;
+ resetEdges();
+ }
- // First, we consider the rect of the views that we are trying to translate
- int deltaX = 0;
- int deltaY = 0;
- if (direction[1] < 0) {
- r0.set(r0.left, r0.top - 1, r0.right, r0.bottom - 1);
- deltaY = -1;
- } else if (direction[1] > 0) {
- r0.set(r0.left, r0.top + 1, r0.right, r0.bottom + 1);
- deltaY = 1;
- } else if (direction[0] < 0) {
- r0.set(r0.left - 1, r0.top, r0.right - 1, r0.bottom);
- deltaX = -1;
- } else if (direction[0] > 0) {
- r0.set(r0.left + 1, r0.top, r0.right + 1, r0.bottom);
- deltaX = 1;
+ void resetEdges() {
+ for (int i = 0; i < mCountX; i++) {
+ topEdge[i] = -1;
+ bottomEdge[i] = -1;
+ }
+ for (int i = 0; i < mCountY; i++) {
+ leftEdge[i] = -1;
+ rightEdge[i] = -1;
+ }
+ leftEdgeDirty = true;
+ rightEdgeDirty = true;
+ bottomEdgeDirty = true;
+ topEdgeDirty = true;
+ boundingRectDirty = true;
+ }
+
+ void computeEdge(int which, int[] edge) {
+ int count = views.size();
+ for (int i = 0; i < count; i++) {
+ CellAndSpan cs = config.map.get(views.get(i));
+ switch (which) {
+ case LEFT:
+ int left = cs.x;
+ for (int j = cs.y; j < cs.y + cs.spanY; j++) {
+ if (left < edge[j] || edge[j] < 0) {
+ edge[j] = left;
+ }
+ }
+ break;
+ case RIGHT:
+ int right = cs.x + cs.spanX;
+ for (int j = cs.y; j < cs.y + cs.spanY; j++) {
+ if (right > edge[j]) {
+ edge[j] = right;
+ }
+ }
+ break;
+ case TOP:
+ int top = cs.y;
+ for (int j = cs.x; j < cs.x + cs.spanX; j++) {
+ if (top < edge[j] || edge[j] < 0) {
+ edge[j] = top;
+ }
+ }
+ break;
+ case BOTTOM:
+ int bottom = cs.y + cs.spanY;
+ for (int j = cs.x; j < cs.x + cs.spanX; j++) {
+ if (bottom > edge[j]) {
+ edge[j] = bottom;
+ }
+ }
+ break;
+ }
+ }
}
- // Now we see which views, if any, are being overlapped by shifting the current group
- // of views in the desired direction.
- for (int i = 0; i < childCount; i++) {
- // We don't need to worry about views already in our group, or the current drag view.
- View child = mShortcutsAndWidgets.getChildAt(i);
- if (views.contains(child) || child == dragView) continue;
- CellAndSpan c = currentState.map.get(child);
+ boolean isViewTouchingEdge(View v, int whichEdge) {
+ CellAndSpan cs = config.map.get(v);
- LayoutParams lp = (LayoutParams) child.getLayoutParams();
- r1.set(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
- if (Rect.intersects(r0, r1)) {
- if (!lp.canReorder) {
- return false;
- }
- // First we verify that the view in question is at the border of the extents
- // of the block of items we are pushing
- if ((direction[0] < 0 && c.x == r0.left) ||
- (direction[0] > 0 && c.x == r0.right - 1) ||
- (direction[1] < 0 && c.y == r0.top) ||
- (direction[1] > 0 && c.y == r0.bottom - 1)) {
- boolean pushed = false;
- // Since the bounding rect is a coarse description of the region (there can
- // be holes at the edge of the block), we need to check to verify that a solid
- // piece is intersecting. This ensures that interlocking is possible.
- for (int x = c.x; x < c.x + c.spanX; x++) {
- for (int y = c.y; y < c.y + c.spanY; y++) {
- if (occupied[x - deltaX][y - deltaY]) {
- pushed = true;
- break;
- }
- if (pushed) break;
+ int[] edge = getEdge(whichEdge);
+
+ switch (whichEdge) {
+ case LEFT:
+ for (int i = cs.y; i < cs.y + cs.spanY; i++) {
+ if (edge[i] == cs.x + cs.spanX) {
+ return true;
}
}
- if (pushed) {
- views.add(child);
+ break;
+ case RIGHT:
+ for (int i = cs.y; i < cs.y + cs.spanY; i++) {
+ if (edge[i] == cs.x) {
+ return true;
+ }
+ }
+ break;
+ case TOP:
+ for (int i = cs.x; i < cs.x + cs.spanX; i++) {
+ if (edge[i] == cs.y + cs.spanY) {
+ return true;
+ }
+ }
+ break;
+ case BOTTOM:
+ for (int i = cs.x; i < cs.x + cs.spanX; i++) {
+ if (edge[i] == cs.y) {
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+ }
+
+ void shift(int whichEdge, int delta) {
+ for (View v: views) {
+ CellAndSpan c = config.map.get(v);
+ switch (whichEdge) {
+ case LEFT:
+ c.x -= delta;
+ break;
+ case RIGHT:
+ c.x += delta;
+ break;
+ case TOP:
+ c.y -= delta;
+ break;
+ case BOTTOM:
+ default:
+ c.y += delta;
+ break;
+ }
+ }
+ resetEdges();
+ }
+
+ public void addView(View v) {
+ views.add(v);
+ resetEdges();
+ }
+
+ public Rect getBoundingRect() {
+ if (boundingRectDirty) {
+ boolean first = true;
+ for (View v: views) {
+ CellAndSpan c = config.map.get(v);
+ if (first) {
+ boundingRect.set(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
+ first = false;
+ } else {
boundingRect.union(c.x, c.y, c.x + c.spanX, c.y + c.spanY);
- found = true;
}
}
}
+ return boundingRect;
+ }
+
+ public int[] getEdge(int which) {
+ switch (which) {
+ case LEFT:
+ return getLeftEdge();
+ case RIGHT:
+ return getRightEdge();
+ case TOP:
+ return getTopEdge();
+ case BOTTOM:
+ default:
+ return getBottomEdge();
+ }
+ }
+
+ public int[] getLeftEdge() {
+ if (leftEdgeDirty) {
+ computeEdge(LEFT, leftEdge);
+ }
+ return leftEdge;
+ }
+
+ public int[] getRightEdge() {
+ if (rightEdgeDirty) {
+ computeEdge(RIGHT, rightEdge);
+ }
+ return rightEdge;
+ }
+
+ public int[] getTopEdge() {
+ if (topEdgeDirty) {
+ computeEdge(TOP, topEdge);
+ }
+ return topEdge;
+ }
+
+ public int[] getBottomEdge() {
+ if (bottomEdgeDirty) {
+ computeEdge(BOTTOM, bottomEdge);
+ }
+ return bottomEdge;
+ }
+
+ PositionComparator comparator = new PositionComparator();
+ class PositionComparator implements Comparator<View> {
+ int whichEdge = 0;
+ public int compare(View left, View right) {
+ CellAndSpan l = config.map.get(left);
+ CellAndSpan r = config.map.get(right);
+ switch (whichEdge) {
+ case LEFT:
+ return (r.x + r.spanX) - (l.x + l.spanX);
+ case RIGHT:
+ return l.x - r.x;
+ case TOP:
+ return (r.y + r.spanY) - (l.y + l.spanY);
+ case BOTTOM:
+ default:
+ return l.y - r.y;
+ }
+ }
+ }
+
+ public void sortConfigurationForEdgePush(int edge) {
+ comparator.whichEdge = edge;
+ Collections.sort(config.sortedViews, comparator);
}
- return found;
}
- private void completeSetOfViewsToMove(ArrayList<View> views, Rect boundingRect, int[] direction,
- View dragView, ItemConfiguration currentState) {
- Rect r0 = new Rect(boundingRect);
- int minRuns;
+ private boolean pushViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
+ int[] direction, View dragView, ItemConfiguration currentState) {
+
+ ViewCluster cluster = new ViewCluster(views, currentState);
+ Rect clusterRect = cluster.getBoundingRect();
+ int whichEdge;
+ int pushDistance;
+ boolean fail = false;
- // The first thing we do is to reduce the bounding rect to first or last row or column,
- // depending on the direction. Then, we add any necessary views that are already contained
- // by the bounding rect, but aren't in the list of intersecting views, and will be pushed
- // by something already in the intersecting views.
- if (direction[1] < 0) {
- r0.set(r0.left, r0.bottom - 1, r0.right, r0.bottom);
- } else if (direction[1] > 0) {
- r0.set(r0.left, r0.top, r0.right, r0.top + 1);
- } else if (direction[0] < 0) {
- r0.set(r0.right - 1, r0.top, r0.right, r0.bottom);
+ // Determine the edge of the cluster that will be leading the push and how far
+ // the cluster must be shifted.
+ if (direction[0] < 0) {
+ whichEdge = ViewCluster.LEFT;
+ pushDistance = clusterRect.right - rectOccupiedByPotentialDrop.left;
} else if (direction[0] > 0) {
- r0.set(r0.left, r0.top, r0.left + 1, r0.bottom);
+ whichEdge = ViewCluster.RIGHT;
+ pushDistance = rectOccupiedByPotentialDrop.right - clusterRect.left;
+ } else if (direction[1] < 0) {
+ whichEdge = ViewCluster.TOP;
+ pushDistance = clusterRect.bottom - rectOccupiedByPotentialDrop.top;
+ } else {
+ whichEdge = ViewCluster.BOTTOM;
+ pushDistance = rectOccupiedByPotentialDrop.bottom - clusterRect.top;
+ }
+
+ // Break early for invalid push distance.
+ if (pushDistance <= 0) {
+ return false;
}
- minRuns = Math.max(Math.abs(boundingRect.width() - r0.width()),
- Math.abs(boundingRect.height() - r0.height())) + 1;
+ // Mark the occupied state as false for the group of views we want to move.
+ for (View v: views) {
+ CellAndSpan c = currentState.map.get(v);
+ markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, false);
+ }
+
+ // We save the current configuration -- if we fail to find a solution we will revert
+ // to the initial state. The process of finding a solution modifies the configuration
+ // in place, hence the need for revert in the failure case.
+ currentState.save();
+
+ // The pushing algorithm is simplified by considering the views in the order in which
+ // they would be pushed by the cluster. For example, if the cluster is leading with its
+ // left edge, we consider sort the views by their right edge, from right to left.
+ cluster.sortConfigurationForEdgePush(whichEdge);
+
+ while (pushDistance > 0 && !fail) {
+ for (View v: currentState.sortedViews) {
+ // For each view that isn't in the cluster, we see if the leading edge of the
+ // cluster is contacting the edge of that view. If so, we add that view to the
+ // cluster.
+ if (!cluster.views.contains(v) && v != dragView) {
+ if (cluster.isViewTouchingEdge(v, whichEdge)) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ if (!lp.canReorder) {
+ // The push solution includes the all apps button, this is not viable.
+ fail = true;
+ break;
+ }
+ cluster.addView(v);
+ CellAndSpan c = currentState.map.get(v);
+
+ // Adding view to cluster, mark it as not occupied.
+ markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, false);
+ }
+ }
+ }
+ pushDistance--;
- // Here the first number of runs (minRuns) accounts for the the comment above, and
- // further runs execute based on whether the intersecting views / bounding rect need
- // to be expanded to include other views that will be pushed.
- while (addViewInDirection(views, r0, direction, mTmpOccupied,
- dragView, currentState) || minRuns > 0) {
- minRuns--;
+ // The cluster has been completed, now we move the whole thing over in the appropriate
+ // direction.
+ cluster.shift(whichEdge, 1);
}
- boundingRect.union(r0);
+
+ boolean foundSolution = false;
+ clusterRect = cluster.getBoundingRect();
+
+ // Due to the nature of the algorithm, the only check required to verify a valid solution
+ // is to ensure that completed shifted cluster lies completely within the cell layout.
+ if (!fail && clusterRect.left >= 0 && clusterRect.right <= mCountX && clusterRect.top >= 0 &&
+ clusterRect.bottom <= mCountY) {
+ foundSolution = true;
+ } else {
+ currentState.restore();
+ }
+
+ // In either case, we set the occupied array as marked for the location of the views
+ for (View v: cluster.views) {
+ CellAndSpan c = currentState.map.get(v);
+ markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
+ }
+
+ return foundSolution;
}
private boolean addViewsToTempLocation(ArrayList<View> views, Rect rectOccupiedByPotentialDrop,
- int[] direction, boolean push, View dragView, ItemConfiguration currentState) {
+ int[] direction, View dragView, ItemConfiguration currentState) {
if (views.size() == 0) return true;
boolean success = false;
@@ -1742,15 +1927,8 @@ public class CellLayout extends ViewGroup {
}
}
- @SuppressWarnings("unchecked")
- ArrayList<View> dup = (ArrayList<View>) views.clone();
- if (push) {
- completeSetOfViewsToMove(dup, boundingRect, direction, dragView,
- currentState);
- }
-
// Mark the occupied state as false for the group of views we want to move.
- for (View v: dup) {
+ for (View v: views) {
CellAndSpan c = currentState.map.get(v);
markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, false);
}
@@ -1760,26 +1938,21 @@ public class CellLayout extends ViewGroup {
int left = boundingRect.left;
// We mark more precisely which parts of the bounding rect are truly occupied, allowing
// for interlocking.
- for (View v: dup) {
+ for (View v: views) {
CellAndSpan c = currentState.map.get(v);
markCellsForView(c.x - left, c.y - top, c.spanX, c.spanY, blockOccupied, true);
}
markCellsForRect(rectOccupiedByPotentialDrop, mTmpOccupied, true);
- if (push) {
- findNearestAreaInDirection(boundingRect.left, boundingRect.top, boundingRect.width(),
- boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
- } else {
- findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(),
- boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
- }
+ findNearestArea(boundingRect.left, boundingRect.top, boundingRect.width(),
+ boundingRect.height(), direction, mTmpOccupied, blockOccupied, mTempLocation);
// If we successfuly found a location by pushing the block of views, we commit it
if (mTempLocation[0] >= 0 && mTempLocation[1] >= 0) {
int deltaX = mTempLocation[0] - boundingRect.left;
int deltaY = mTempLocation[1] - boundingRect.top;
- for (View v: dup) {
+ for (View v: views) {
CellAndSpan c = currentState.map.get(v);
c.x += deltaX;
c.y += deltaY;
@@ -1788,7 +1961,7 @@ public class CellLayout extends ViewGroup {
}
// In either case, we set the occupied array as marked for the location of the views
- for (View v: dup) {
+ for (View v: views) {
CellAndSpan c = currentState.map.get(v);
markCellsForView(c.x, c.y, c.spanX, c.spanY, mTmpOccupied, true);
}
@@ -1809,14 +1982,16 @@ public class CellLayout extends ViewGroup {
// separately in each of the components.
int temp = direction[1];
direction[1] = 0;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
direction[1] = temp;
temp = direction[0];
direction[0] = 0;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1828,7 +2003,7 @@ public class CellLayout extends ViewGroup {
direction[1] *= -1;
temp = direction[1];
direction[1] = 0;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1836,7 +2011,7 @@ public class CellLayout extends ViewGroup {
direction[1] = temp;
temp = direction[0];
direction[0] = 0;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1848,15 +2023,14 @@ public class CellLayout extends ViewGroup {
} else {
// If the direction vector has a single non-zero component, we push first in the
// direction of the vector
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
-
// Then we try the opposite direction
direction[0] *= -1;
direction[1] *= -1;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1871,7 +2045,7 @@ public class CellLayout extends ViewGroup {
int temp = direction[1];
direction[1] = direction[0];
direction[0] = temp;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1879,7 +2053,7 @@ public class CellLayout extends ViewGroup {
// Then we try the opposite direction
direction[0] *= -1;
direction[1] *= -1;
- if (addViewsToTempLocation(intersectingViews, occupied, direction, true,
+ if (pushViewsToTempLocation(intersectingViews, occupied, direction,
ignoreView, solution)) {
return true;
}
@@ -1935,7 +2109,7 @@ public class CellLayout extends ViewGroup {
}
// Next we try moving the views as a block, but without requiring the push mechanic.
- if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, false, ignoreView,
+ if (addViewsToTempLocation(mIntersectingViews, mOccupiedRect, direction, ignoreView,
solution)) {
return true;
}
@@ -2022,7 +2196,7 @@ public class CellLayout extends ViewGroup {
} else {
c = new CellAndSpan(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan);
}
- solution.map.put(child, c);
+ solution.add(child, c);
}
}
@@ -2492,9 +2666,31 @@ public class CellLayout extends ViewGroup {
private class ItemConfiguration {
HashMap<View, CellAndSpan> map = new HashMap<View, CellAndSpan>();
+ private HashMap<View, CellAndSpan> savedMap = new HashMap<View, CellAndSpan>();
+ ArrayList<View> sortedViews = new ArrayList<View>();
boolean isSolution = false;
int dragViewX, dragViewY, dragViewSpanX, dragViewSpanY;
+ void save() {
+ // Copy current state into savedMap
+ for (View v: map.keySet()) {
+ map.get(v).copy(savedMap.get(v));
+ }
+ }
+
+ void restore() {
+ // Restore current state from savedMap
+ for (View v: savedMap.keySet()) {
+ savedMap.get(v).copy(map.get(v));
+ }
+ }
+
+ void add(View v, CellAndSpan cs) {
+ map.put(v, cs);
+ savedMap.put(v, new CellAndSpan());
+ sortedViews.add(v);
+ }
+
int area() {
return dragViewSpanX * dragViewSpanY;
}
@@ -2504,12 +2700,27 @@ public class CellLayout extends ViewGroup {
int x, y;
int spanX, spanY;
+ public CellAndSpan() {
+ }
+
+ public void copy(CellAndSpan copy) {
+ copy.x = x;
+ copy.y = y;
+ copy.spanX = spanX;
+ copy.spanY = spanY;
+ }
+
public CellAndSpan(int x, int y, int spanX, int spanY) {
this.x = x;
this.y = y;
this.spanX = spanX;
this.spanY = spanY;
}
+
+ public String toString() {
+ return "(" + x + ", " + y + ": " + spanX + ", " + spanY + ")";
+ }
+
}
/**
diff --git a/src/com/cyanogenmod/trebuchet/Launcher.java b/src/com/cyanogenmod/trebuchet/Launcher.java
index bae9389d5..c69ec47be 100644
--- a/src/com/cyanogenmod/trebuchet/Launcher.java
+++ b/src/com/cyanogenmod/trebuchet/Launcher.java
@@ -53,9 +53,11 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@@ -106,7 +108,6 @@ import com.cyanogenmod.trebuchet.preference.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
@@ -155,7 +156,10 @@ public final class Launcher extends Activity
static final int DEFAULT_SCREEN = 2;
private static final String PREFERENCES = "launcher.preferences";
- static final String DUMP_STATE_PROPERTY = "debug.dumpstate";
+ // To turn on these properties, type
+ // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
+ static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
+ static final String DUMP_STATE_PROPERTY = "launcher_dump_state";
// The Intent extra that defines whether to ignore the launch animation
static final String INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION =
@@ -214,6 +218,7 @@ public final class Launcher extends Activity
private Workspace mWorkspace;
private View mQsbDivider;
private View mDockDivider;
+ private View mLauncherView;
private DragLayer mDragLayer;
private DragController mDragController;
@@ -282,6 +287,9 @@ public final class Launcher extends Activity
private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
private static Drawable.ConstantState[] sAppMarketIcon = new Drawable.ConstantState[2];
+ private Drawable mWorkspaceBackgroundDrawable;
+ private Drawable mBlackBackgroundDrawable;
+
private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
static final ArrayList<String> sDumpLogs = new ArrayList<String>();
@@ -324,6 +332,8 @@ public final class Launcher extends Activity
private static ArrayList<PendingAddArguments> sPendingAddList
= new ArrayList<PendingAddArguments>();
+ private static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
+
private static class PendingAddArguments {
int requestCode;
Intent intent;
@@ -333,18 +343,8 @@ public final class Launcher extends Activity
int cellY;
}
-
- private boolean doesFileExist(String filename) {
- FileInputStream fis;
- try {
- fis = openFileInput(filename);
- fis.close();
- return true;
- } catch (java.io.FileNotFoundException e) {
- return false;
- } catch (java.io.IOException e) {
- return true;
- }
+ private static boolean isPropertyEnabled(String propertyName) {
+ return Log.isLoggable(propertyName, Log.VERBOSE);
}
@Override
@@ -748,6 +748,9 @@ public final class Launcher extends Activity
}
mOnResumeState = State.NONE;
+ // Background was set to gradient in onPause(), restore to black if in all apps.
+ setWorkspaceBackground(mState == State.WORKSPACE);
+
// Process any items that were added while Launcher was away
InstallShortcutReceiver.flushInstallQueue(this);
@@ -933,11 +936,16 @@ public final class Launcher extends Activity
private void setupViews() {
final DragController dragController = mDragController;
+ mLauncherView = findViewById(R.id.launcher);
mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
mQsbDivider = findViewById(R.id.qsb_divider);
mDockDivider = findViewById(R.id.dock_divider);
+ mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+ mWorkspaceBackgroundDrawable = getResources().getDrawable(R.drawable.workspace_bg);
+ mBlackBackgroundDrawable = new ColorDrawable(Color.BLACK);
+
// Setup the drag layer
mDragLayer.setup(this, dragController);
@@ -967,12 +975,11 @@ public final class Launcher extends Activity
}
// Setup AppsCustomize
- mAppsCustomizeTabHost = (AppsCustomizeTabHost)
- findViewById(R.id.apps_customize_pane);
+ mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);
mAppsCustomizeContent = (AppsCustomizePagedView)
mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
mAppsCustomizeContent.setup(this, dragController);
-
+
// Setup the drag controller (drop targets have to be added in reverse order in priority)
dragController.setDragScoller(mWorkspace);
dragController.setScrollView(mDragLayer);
@@ -1437,6 +1444,10 @@ public final class Launcher extends Activity
Runnable processIntent = new Runnable() {
public void run() {
+ if (mWorkspace == null) {
+ // Can be cases where mWorkspace is null, this prevents a NPE
+ return;
+ }
Folder openFolder = mWorkspace.getOpenFolder();
// In all these cases, only animate if we're already on home
mWorkspace.exitWidgetResizeMode();
@@ -1923,7 +1934,7 @@ public final class Launcher extends Activity
case KeyEvent.KEYCODE_HOME:
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
- if (doesFileExist(DUMP_STATE_PROPERTY)) {
+ if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {
dumpState();
return true;
}
@@ -2464,6 +2475,7 @@ public final class Launcher extends Activity
}
// Now a part of LauncherModel.Callbacks. Used to reorder loading steps.
+ @Override
public boolean isAllAppsVisible() {
return (mState == State.APPS_CUSTOMIZE) || (mOnResumeState == State.APPS_CUSTOMIZE);
}
@@ -2471,7 +2483,7 @@ public final class Launcher extends Activity
/**
* Helper method for the cameraZoomIn/cameraZoomOut animations
* @param view The view being animated
- *
+ * @param scaleFactor The scale factor used for the zoom
*/
private void setPivotsForZoom(View view) {
view.setPivotX(view.getWidth() / 2.0f);
@@ -2493,6 +2505,11 @@ public final class Launcher extends Activity
updateWallpaperVisibility(visible);
}
+ private void setWorkspaceBackground(boolean workspace) {
+ mLauncherView.setBackground(workspace ?
+ mWorkspaceBackgroundDrawable : mBlackBackgroundDrawable);
+ }
+
void updateWallpaperVisibility(boolean visible) {
int wpflags = visible && mWallpaperVisible ? WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER : 0;
int curflags = getWindow().getAttributes().flags
@@ -2500,6 +2517,7 @@ public final class Launcher extends Activity
if (wpflags != curflags) {
getWindow().setFlags(wpflags, WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
}
+ setWorkspaceBackground(visible);
}
private void updateFullscreenMode(boolean enable) {
@@ -3817,6 +3835,11 @@ public final class Launcher extends Activity
return oriMap[(d.getRotation() + indexOffset) % 4];
}
+ public boolean isRotationEnabled() {
+ boolean enableRotation = sForceEnableRotation ||
+ getResources().getBoolean(R.bool.allow_rotation);
+ return enableRotation;
+ }
public void lockScreenOrientation() {
if (mAutoRotate) {
setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()
@@ -3878,8 +3901,9 @@ public final class Launcher extends Activity
}
private void dismissCling(final Cling cling, final String flag, int duration) {
- if (cling != null && cling.getVisibility() == View.VISIBLE) {
- cling.dismiss();
+ // To catch cases where siblings of top-level views are made invisible, just check whether
+ // the cling is directly set to GONE before dismissing it.
+ if (cling != null && cling.getVisibility() != View.GONE) {
ObjectAnimator anim = LauncherAnimUtils.ofFloat(cling, "alpha", 0f);
anim.setDuration(duration);
anim.addListener(new AnimatorListenerAdapter() {
diff --git a/src/com/cyanogenmod/trebuchet/LauncherAppWidgetInfo.java b/src/com/cyanogenmod/trebuchet/LauncherAppWidgetInfo.java
index 7f6a46c5b..0ab5dae84 100644
--- a/src/com/cyanogenmod/trebuchet/LauncherAppWidgetInfo.java
+++ b/src/com/cyanogenmod/trebuchet/LauncherAppWidgetInfo.java
@@ -19,7 +19,6 @@ package com.cyanogenmod.trebuchet;
import android.appwidget.AppWidgetHostView;
import android.content.ComponentName;
import android.content.ContentValues;
-import android.os.Build;
/**
* Represents a widget (either instantiated or about to be) in the Launcher.
diff --git a/src/com/cyanogenmod/trebuchet/PagedView.java b/src/com/cyanogenmod/trebuchet/PagedView.java
index 667aab27a..42ae9687e 100644
--- a/src/com/cyanogenmod/trebuchet/PagedView.java
+++ b/src/com/cyanogenmod/trebuchet/PagedView.java
@@ -319,13 +319,15 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
* the previous tab page.
*/
protected void updateCurrentPageScroll() {
- int newXY = getChildOffset(mCurrentPage) - getRelativeChildOffset(mCurrentPage);
- scrollTo(!mVertical ? newXY : 0, mVertical ? newXY : 0);
- if (!mVertical) {
- mScroller.setFinalX(newXY);
- } else {
- mScroller.setFinalY(newXY);
- }
+ // If the current page is invalid, just reset the scroll position to zero
+ int newX = 0;
+ if (0 <= mCurrentPage && mCurrentPage < getPageCount()) {
+ int offset = getChildOffset(mCurrentPage);
+ int relOffset = getRelativeChildOffset(mCurrentPage);
+ newX = offset - relOffset;
+ }
+ scrollTo(newX, 0);
+ mScroller.setFinalX(newX);
mScroller.forceFinished(true);
}