diff options
author | Steve Kondik <shade@chemlab.org> | 2013-02-15 14:45:54 -0800 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2013-02-15 14:45:54 -0800 |
commit | ed1816e3a828046439da5cb31a65af4641be9076 (patch) | |
tree | 994e4ed51b3e1630e338b3ec255a8f4dce429953 | |
parent | c43d6eebe95dcabcb4ded1c4da8c6cc21d2514f5 (diff) | |
parent | 002c25eede2a33a5378c16c5bb9165179783e729 (diff) | |
download | packages_apps_trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.zip packages_apps_trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.tar.gz packages_apps_trebuchet-ed1816e3a828046439da5cb31a65af4641be9076.tar.bz2 |
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
22 files changed, 783 insertions, 500 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f9271e4..78e4db7 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 Binary files differdeleted file mode 100644 index 5c8ee24..0000000 --- a/res/drawable-hdpi/ic_launcher_wallpaper.png +++ /dev/null diff --git a/res/drawable-mdpi/ic_launcher_wallpaper.png b/res/drawable-mdpi/ic_launcher_wallpaper.png Binary files differdeleted file mode 100644 index d2803b1..0000000 --- a/res/drawable-mdpi/ic_launcher_wallpaper.png +++ /dev/null diff --git a/res/drawable-xhdpi/ic_launcher_wallpaper.png b/res/drawable-xhdpi/ic_launcher_wallpaper.png Binary files differdeleted file mode 100644 index 9b0b7b2..0000000 --- a/res/drawable-xhdpi/ic_launcher_wallpaper.png +++ /dev/null diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index f6ac21d..c6156c1 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 f05aac7..dbfcfce 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 be34045..443db2e 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 Binary files differindex 33d36b0..33d36b0 100755 --- a/res/drawable-hdpi/ic_launcher_home.png +++ b/res/mipmap-hdpi/ic_launcher_home.png diff --git a/res/mipmap-hdpi/ic_launcher_wallpaper.png b/res/mipmap-hdpi/ic_launcher_wallpaper.png Binary files differnew file mode 100644 index 0000000..affee85 --- /dev/null +++ b/res/mipmap-hdpi/ic_launcher_wallpaper.png diff --git a/res/drawable-mdpi/ic_launcher_home.png b/res/mipmap-mdpi/ic_launcher_home.png Binary files differindex 5ab889c..5ab889c 100755 --- a/res/drawable-mdpi/ic_launcher_home.png +++ b/res/mipmap-mdpi/ic_launcher_home.png diff --git a/res/mipmap-mdpi/ic_launcher_wallpaper.png b/res/mipmap-mdpi/ic_launcher_wallpaper.png Binary files differnew file mode 100644 index 0000000..cb4443b --- /dev/null +++ b/res/mipmap-mdpi/ic_launcher_wallpaper.png diff --git a/res/drawable-xhdpi/ic_launcher_home.png b/res/mipmap-xhdpi/ic_launcher_home.png Binary files differindex 70ec475..70ec475 100755 --- a/res/drawable-xhdpi/ic_launcher_home.png +++ b/res/mipmap-xhdpi/ic_launcher_home.png diff --git a/res/mipmap-xhdpi/ic_launcher_wallpaper.png b/res/mipmap-xhdpi/ic_launcher_wallpaper.png Binary files differnew file mode 100644 index 0000000..60f8dce --- /dev/null +++ b/res/mipmap-xhdpi/ic_launcher_wallpaper.png diff --git a/res/mipmap-xxhdpi/ic_launcher_wallpaper.png b/res/mipmap-xxhdpi/ic_launcher_wallpaper.png Binary files differnew file mode 100644 index 0000000..023fb58 --- /dev/null +++ b/res/mipmap-xxhdpi/ic_launcher_wallpaper.png diff --git a/src/com/cyanogenmod/trebuchet/AddAdapter.java b/src/com/cyanogenmod/trebuchet/AddAdapter.java index 5a3d43d..8f4e8fc 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 5b868c1..48d4116 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 8d4e4d7..9f7595d 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 08d9597..067b98f 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 1fd5a5f..a59a96e 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 bae9389..c69ec47 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 7f6a46c..0ab5dae 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 667aab2..42ae968 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); } |