summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVineet Patil <vpatil@cyngn.com>2015-11-17 22:23:05 (GMT)
committerVineet Patil <vpatil@cyngn.com>2015-11-18 21:39:02 (GMT)
commit35614fdc7d13179ba9cbc80f15eca6d63cf3229d (patch)
treedfde8498c0ea5a2adb1635120c4f98323f5956ce
parent5fcaab43e603ceabd1d71ec355c8a0b59aac8cf0 (diff)
downloadandroid_packages_apps_Trebuchet-35614fdc7d13179ba9cbc80f15eca6d63cf3229d.zip
android_packages_apps_Trebuchet-35614fdc7d13179ba9cbc80f15eca6d63cf3229d.tar.gz
android_packages_apps_Trebuchet-35614fdc7d13179ba9cbc80f15eca6d63cf3229d.tar.bz2
Implementation of folder animation changes as per cm-13.0
Folder animations in parity with cm. Folder Layout Revision Updated the folder layout to reflect design revisions based on community feedback Change-Id: Ica1bb796dfccf779a954cf0903a1ae94a010ea1a Conflicts: res/drawable-hdpi/folder_bg.9.png res/drawable-hdpi/folder_fill_highlight.9.png res/drawable-mdpi/folder_bg.9.png res/drawable-mdpi/folder_fill_highlight.9.png res/drawable-xhdpi/folder_bg.9.png res/drawable-xhdpi/folder_fill_highlight.9.png res/drawable-xxhdpi/folder_bg.9.png res/drawable-xxhdpi/folder_fill_highlight.9.png res/layout-land/launcher.xml res/layout-port/launcher.xml res/layout-sw720dp/launcher.xml res/layout/user_folder.xml res/values/dimens.xml src/com/android/launcher3/Folder.java src/com/android/launcher3/FolderIcon.java src/com/android/launcher3/Launcher.java Folder animation changes as per cm-13.0 Change-Id: I019511a58bd9f6a60a3c9b68c826726881cec83f Implementing folder animations Change-Id: I83f17c996ecc894ce22fd195b9b33caf58e2e822
-rw-r--r--res/anim/drop_down.xml13
-rw-r--r--res/anim/enter_from_left.xml12
-rw-r--r--res/anim/enter_from_right.xml12
-rw-r--r--res/anim/exit_out_left.xml13
-rw-r--r--res/anim/exit_out_right.xml12
-rw-r--r--res/anim/fade_in_fast.xml23
-rw-r--r--res/anim/fade_out_fast.xml23
-rw-r--r--res/drawable-hdpi/folder_bg.9.pngbin0 -> 823 bytes
-rwxr-xr-xres/drawable-hdpi/folder_bg_opaque.9.pngbin0 -> 199 bytes
-rw-r--r--res/drawable-hdpi/folder_fill_highlight.9.pngbin0 -> 14914 bytes
-rw-r--r--res/drawable-mdpi/folder_bg.9.pngbin0 -> 510 bytes
-rwxr-xr-xres/drawable-mdpi/folder_bg_opaque.9.pngbin0 -> 160 bytes
-rw-r--r--res/drawable-mdpi/folder_fill_highlight.9.pngbin0 -> 14764 bytes
-rw-r--r--res/drawable-xhdpi/folder_bg.9.pngbin0 -> 1023 bytes
-rwxr-xr-xres/drawable-xhdpi/folder_bg_opaque.9.pngbin0 -> 249 bytes
-rw-r--r--res/drawable-xhdpi/folder_fill_highlight.9.pngbin0 -> 15075 bytes
-rw-r--r--res/drawable-xxhdpi/folder_bg.9.pngbin0 -> 1678 bytes
-rwxr-xr-xres/drawable-xxhdpi/folder_bg_opaque.9.pngbin0 -> 312 bytes
-rw-r--r--res/drawable-xxhdpi/folder_fill_highlight.9.pngbin0 -> 15836 bytes
-rw-r--r--res/drawable/folder_container.xml25
-rw-r--r--res/drawable/folder_locked.xml14
-rw-r--r--res/drawable/folder_unlocked.xml13
-rw-r--r--res/layout-land/launcher.xml19
-rw-r--r--res/layout-port/launcher.xml21
-rw-r--r--res/layout-sw720dp/launcher.xml19
-rw-r--r--res/layout/folder_icon.xml50
-rw-r--r--res/layout/user_folder.xml6
-rw-r--r--res/values/attrs.xml14
-rw-r--r--res/values/dimens.xml11
-rw-r--r--res/values/strings.xml5
-rw-r--r--res/values/styles.xml2
-rw-r--r--src/com/android/launcher3/CellLayout.java16
-rw-r--r--src/com/android/launcher3/Folder.java231
-rw-r--r--src/com/android/launcher3/FolderIcon.java142
-rw-r--r--src/com/android/launcher3/FolderInfo.java1
-rw-r--r--src/com/android/launcher3/InsettableFrameLayout.java14
-rw-r--r--src/com/android/launcher3/Launcher.java69
-rw-r--r--src/com/android/launcher3/LauncherSettings.java2
38 files changed, 688 insertions, 94 deletions
diff --git a/res/anim/drop_down.xml b/res/anim/drop_down.xml
new file mode 100644
index 0000000..49059a0
--- /dev/null
+++ b/res/anim/drop_down.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_decelerate">
+ <scale
+ android:fromXScale="1.0"
+ android:toXScale="1.0"
+ android:fromYScale="2.5"
+ android:toYScale="1.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:duration="300"
+ android:fillBefore="false" />
+</set>
diff --git a/res/anim/enter_from_left.xml b/res/anim/enter_from_left.xml
new file mode 100644
index 0000000..e2bdbdd
--- /dev/null
+++ b/res/anim/enter_from_left.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="300"
+ android:propertyName="x"
+ android:valueFrom="-1000"
+ android:valueTo="0"
+ android:valueType="floatType" />
+</set>
diff --git a/res/anim/enter_from_right.xml b/res/anim/enter_from_right.xml
new file mode 100644
index 0000000..02a56c7
--- /dev/null
+++ b/res/anim/enter_from_right.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="300"
+ android:propertyName="x"
+ android:valueFrom="1000"
+ android:valueTo="0"
+ android:valueType="floatType" />
+</set>
diff --git a/res/anim/exit_out_left.xml b/res/anim/exit_out_left.xml
new file mode 100644
index 0000000..eae925a
--- /dev/null
+++ b/res/anim/exit_out_left.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="300"
+ android:propertyName="x"
+ android:valueFrom="0"
+ android:valueTo="-1000"
+ android:valueType="floatType" />
+</set>
+
diff --git a/res/anim/exit_out_right.xml b/res/anim/exit_out_right.xml
new file mode 100644
index 0000000..7345c94
--- /dev/null
+++ b/res/anim/exit_out_right.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <objectAnimator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:duration="300"
+ android:propertyName="x"
+ android:valueFrom="0"
+ android:valueTo="1000"
+ android:valueType="floatType" />
+</set>
diff --git a/res/anim/fade_in_fast.xml b/res/anim/fade_in_fast.xml
new file mode 100644
index 0000000..4fa9847
--- /dev/null
+++ b/res/anim/fade_in_fast.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/accelerate_interpolator"
+
+ android:fromAlpha="0.0"
+ android:toAlpha="1.0"
+
+ android:duration="@android:integer/config_mediumAnimTime" />
diff --git a/res/anim/fade_out_fast.xml b/res/anim/fade_out_fast.xml
new file mode 100644
index 0000000..a061a6c
--- /dev/null
+++ b/res/anim/fade_out_fast.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<alpha xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:anim/accelerate_interpolator"
+
+ android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+
+ android:duration="@android:integer/config_mediumAnimTime" />
diff --git a/res/drawable-hdpi/folder_bg.9.png b/res/drawable-hdpi/folder_bg.9.png
new file mode 100644
index 0000000..ee0090c
--- /dev/null
+++ b/res/drawable-hdpi/folder_bg.9.png
Binary files differ
diff --git a/res/drawable-hdpi/folder_bg_opaque.9.png b/res/drawable-hdpi/folder_bg_opaque.9.png
new file mode 100755
index 0000000..08e152e
--- /dev/null
+++ b/res/drawable-hdpi/folder_bg_opaque.9.png
Binary files differ
diff --git a/res/drawable-hdpi/folder_fill_highlight.9.png b/res/drawable-hdpi/folder_fill_highlight.9.png
new file mode 100644
index 0000000..b82302b
--- /dev/null
+++ b/res/drawable-hdpi/folder_fill_highlight.9.png
Binary files differ
diff --git a/res/drawable-mdpi/folder_bg.9.png b/res/drawable-mdpi/folder_bg.9.png
new file mode 100644
index 0000000..4039da5
--- /dev/null
+++ b/res/drawable-mdpi/folder_bg.9.png
Binary files differ
diff --git a/res/drawable-mdpi/folder_bg_opaque.9.png b/res/drawable-mdpi/folder_bg_opaque.9.png
new file mode 100755
index 0000000..673d740
--- /dev/null
+++ b/res/drawable-mdpi/folder_bg_opaque.9.png
Binary files differ
diff --git a/res/drawable-mdpi/folder_fill_highlight.9.png b/res/drawable-mdpi/folder_fill_highlight.9.png
new file mode 100644
index 0000000..7c6a0d4
--- /dev/null
+++ b/res/drawable-mdpi/folder_fill_highlight.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/folder_bg.9.png b/res/drawable-xhdpi/folder_bg.9.png
new file mode 100644
index 0000000..1fbe1d8
--- /dev/null
+++ b/res/drawable-xhdpi/folder_bg.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/folder_bg_opaque.9.png b/res/drawable-xhdpi/folder_bg_opaque.9.png
new file mode 100755
index 0000000..42a1e1d
--- /dev/null
+++ b/res/drawable-xhdpi/folder_bg_opaque.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/folder_fill_highlight.9.png b/res/drawable-xhdpi/folder_fill_highlight.9.png
new file mode 100644
index 0000000..f5f0bd0
--- /dev/null
+++ b/res/drawable-xhdpi/folder_fill_highlight.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/folder_bg.9.png b/res/drawable-xxhdpi/folder_bg.9.png
new file mode 100644
index 0000000..3b2bc42
--- /dev/null
+++ b/res/drawable-xxhdpi/folder_bg.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/folder_bg_opaque.9.png b/res/drawable-xxhdpi/folder_bg_opaque.9.png
new file mode 100755
index 0000000..25a4fff
--- /dev/null
+++ b/res/drawable-xxhdpi/folder_bg_opaque.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/folder_fill_highlight.9.png b/res/drawable-xxhdpi/folder_fill_highlight.9.png
new file mode 100644
index 0000000..4dc29f4
--- /dev/null
+++ b/res/drawable-xxhdpi/folder_fill_highlight.9.png
Binary files differ
diff --git a/res/drawable/folder_container.xml b/res/drawable/folder_container.xml
new file mode 100644
index 0000000..b0a1c84
--- /dev/null
+++ b/res/drawable/folder_container.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="72dp"
+ android:width="72dp"
+ android:viewportHeight="72"
+ android:viewportWidth="72">
+
+ <group
+ android:name="folder_container">
+ <path
+ android:name="folder_path"
+ android:pathData=" M6,4
+ h60
+ c1.2,0 2,0.8 2,2
+ v60
+ c0,1.2 -0.8,2 -2,2
+ h-60
+ c-1.2,0 -2,-0.8 -2,-2
+ v-60
+ c0,-1.2 0.8,-2 2,-2
+ z"
+ android:fillColor="#ff524e5e"/>
+ </group>
+
+</vector> \ No newline at end of file
diff --git a/res/drawable/folder_locked.xml b/res/drawable/folder_locked.xml
new file mode 100644
index 0000000..8b88789
--- /dev/null
+++ b/res/drawable/folder_locked.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#fafafa"
+ android:pathData="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1 .9 2 2
+2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6-5.1c1.71 0 3.1 1.39 3.1
+3.1v2H9V6h-.1c0-1.71 1.39-3.1 3.1-3.1zM18 20H6V10h12v10zm-6-3c1.1 0 2-.9
+2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z" />
+</vector>
diff --git a/res/drawable/folder_unlocked.xml b/res/drawable/folder_unlocked.xml
new file mode 100644
index 0000000..d34d9b7
--- /dev/null
+++ b/res/drawable/folder_unlocked.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#fafafa"
+ android:pathData="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7
+3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2
+2v10c0 1.1 .9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z" />
+</vector>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 6500ebc..3a93365 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -21,7 +21,24 @@
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:background="@drawable/workspace_bg">
+
+ <FrameLayout
+ android:id="@+id/reveal_fake_page_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ android:alpha="1.0"
+ android:clipToPadding="false">
+
+ <ImageView
+ android:id="@+id/reveal_fake_folder_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ android:background="@drawable/folder_bg_opaque"/>
+ </FrameLayout>
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index d0772ee..cbdb001 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -18,11 +18,30 @@
<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ xmlns:insettable="http://schemas.android.com/apk/res-auto"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:background="@drawable/workspace_bg">
+
+ <FrameLayout
+ android:id="@+id/reveal_fake_page_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ android:alpha="1.0"
+ insettable:layout_ignoreInsets="true"
+ android:clipToPadding="false">
+
+ <ImageView
+ android:id="@+id/reveal_fake_folder_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ android:background="@drawable/folder_bg_opaque"/>
+ </FrameLayout>
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 802922e..c448e76 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -21,7 +21,24 @@
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:background="@drawable/workspace_bg">
+
+ <FrameLayout
+ android:id="@+id/reveal_fake_page_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible"
+ android:alpha="1.0"
+ android:clipToPadding="false">
+
+ <ImageView
+ android:id="@+id/reveal_fake_folder_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ android:background="@drawable/folder_bg_opaque"/>
+ </FrameLayout>
<com.android.launcher3.DragLayer
android:id="@+id/drag_layer"
diff --git a/res/layout/folder_icon.xml b/res/layout/folder_icon.xml
index 237af68..5e29a1a 100644
--- a/res/layout/folder_icon.xml
+++ b/res/layout/folder_icon.xml
@@ -20,17 +20,53 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true" >
- <ImageView
+ <RelativeLayout
android:id="@+id/preview_background"
- android:layout_gravity="center_horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:antialias="true"
- android:src="@drawable/portal_ring_inner"/>
+ android:layout_width="@dimen/folder_icon"
+ android:layout_height="@dimen/folder_icon"
+ android:layout_gravity="center_horizontal|top"
+ android:background="@drawable/folder_bg" >
+ <ImageView
+ android:id="@+id/folder_lock_image"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:src="@drawable/folder_locked"
+ android:scaleType="center"
+ android:visibility="invisible" />
+ <ImageView
+ android:id="@+id/app_0"
+ android:layout_width="@dimen/folder_icon_app_preview"
+ android:layout_height="@dimen/folder_icon_app_preview"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:antialias="true"/>
+ <ImageView
+ android:id="@+id/app_1"
+ android:layout_width="@dimen/folder_icon_app_preview"
+ android:layout_height="@dimen/folder_icon_app_preview"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentRight="true"
+ android:antialias="true"/>
+ <ImageView
+ android:id="@+id/app_2"
+ android:layout_width="@dimen/folder_icon_app_preview"
+ android:layout_height="@dimen/folder_icon_app_preview"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentBottom="true"
+ android:antialias="true"/>
+ <ImageView
+ android:id="@+id/app_3"
+ android:layout_width="@dimen/folder_icon_app_preview"
+ android:layout_height="@dimen/folder_icon_app_preview"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentRight="true"
+ android:antialias="true"/>
+ </RelativeLayout>
+
<com.android.launcher3.BubbleTextView
style="@style/Icon"
android:id="@+id/folder_icon_name"
- android:layout_gravity="top"
+ android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.launcher3.FolderIcon>
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 252ebf0..2152a99 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -18,7 +18,7 @@
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/quantum_panel"
+ android:background="@drawable/folder_bg"
android:elevation="5dp"
android:orientation="vertical" >
@@ -67,7 +67,7 @@
android:paddingBottom="8dp"
android:paddingTop="4dp"
android:singleLine="true"
- android:textColor="#ff777777"
+ android:textColor="@color/workspace_icon_text_color"
android:textColorHighlight="#ffCCCCCC"
android:textColorHint="#ff808080"
android:textSize="14sp" />
@@ -81,4 +81,4 @@
</LinearLayout>
-</com.android.launcher3.Folder> \ No newline at end of file
+</com.android.launcher3.Folder>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 827332a..7ffebce 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -113,7 +113,19 @@
<attr name="indicatorSize" format="dimension" />
</declare-styleable>
+ <attr name="layout_ignoreInsets" format="boolean" />
+ <attr name="layout_ignoreBottomInsets" format="boolean" />
+ <attr name="layout_ignoreTopInsets" format="boolean" />
+
<declare-styleable name="InsettableFrameLayout_Layout">
- <attr name="layout_ignoreInsets" format="boolean" />
+ <attr name="layout_ignoreInsets" />
+ <attr name="layout_ignoreTopInsets" />
+ <attr name="layout_ignoreBottomInsets" />
+ </declare-styleable>
+
+ <declare-styleable name="InsettableLinearLayout_Layout">
+ <attr name="layout_ignoreInsets" />
+ <attr name="layout_ignoreTopInsets" />
+ <attr name="layout_ignoreBottomInsets" />
</declare-styleable>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3672179..e3c8194 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -121,6 +121,13 @@
<!-- Folders -->
<!-- The amount that the preview contents are inset from the preview background -->
<dimen name="folder_preview_padding">4dp</dimen>
+ <dimen name="folder_lock_margin">6dp</dimen>
+ <dimen name="folder_name_padding">10dp</dimen>
+ <dimen name="folder_lock_icon">48dp</dimen>
+
+ <!-- Folder icon dimens -->
+ <dimen name="folder_icon">64dp</dimen>
+ <dimen name="folder_icon_app_preview">22dp</dimen>
<!-- Sizes for managed profile badges -->
<dimen name="profile_badge_size">24dp</dimen>
@@ -137,4 +144,8 @@
<dimen name="pending_widget_min_padding">8dp</dimen>
<dimen name="pending_widget_elevation">2dp</dimen>
+<!-- Folder open animation -->
+ <integer name="folder_translate_y_dist">300</integer>
+ <integer name="folder_icon_translate_y_dist">100</integer>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fefadef..b544788 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -31,7 +31,7 @@
<string name="receive_first_load_broadcast_permission" translatable="false">com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST</string>
<!-- Application name -->
- <string name="application_name">Launcher3</string>
+ <string name="app_name">Launcher3</string>
<!-- Default folder name -->
<string name="folder_name"></string>
<!-- Work folder name -->
@@ -103,6 +103,9 @@
<string name="permdesc_write_settings">Allows the app to change the settings and
shortcuts in Home.</string>
+ <!-- Toast shown on clicking a direct call shortcut. [CHAR_LIMIT=80] -->
+ <string name="msg_no_phone_permission"><xliff:g id="app_name" example="Launcher3">%1$s</xliff:g> is not allowed to make phone calls</string>
+
<!-- Widgets: -->
<skip />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7d60cbe..9104bc9 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -49,7 +49,7 @@
<style name="Icon.Folder">
<item name="android:background">@null</item>
- <item name="android:textColor">@color/quantum_panel_text_color</item>
+ <item name="android:textColor">@color/workspace_icon_text_color</item>
<item name="android:shadowRadius">0</item>
<item name="customShadows">false</item>
</style>
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 84e2d49..a99d791 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -504,13 +504,15 @@ public class CellLayout extends ViewGroup implements BubbleTextShadowHandler {
// Draw inner ring
d = FolderRingAnimator.sSharedInnerRingDrawable;
- width = (int) (fra.getInnerRingSize() * getChildrenScale());
- height = width;
- canvas.save();
- canvas.translate(centerX - width / 2, centerY - width / 2);
- d.setBounds(0, 0, width, height);
- d.draw(canvas);
- canvas.restore();
+ if (d != null) {
+ width = (int) (fra.getInnerRingSize() * getChildrenScale());
+ height = width;
+ canvas.save();
+ canvas.translate(centerX - width / 2, centerY - width / 2);
+ d.setBounds(0, 0, width, height);
+ d.draw(canvas);
+ canvas.restore();
+ }
}
}
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index c1aa356..994d7d3 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -25,11 +25,15 @@ import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
+import android.os.PowerManager;
+import android.provider.Settings;
import android.text.InputType;
import android.text.Selection;
import android.text.Spannable;
@@ -46,8 +50,10 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -89,6 +95,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
*/
public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY;
+ private static final int CLOSE_FOLDER_DELAY_MS = 150;
+
+ private static final int ALPHA_DELAY_MULT = 15;
+
/**
* Fraction of icon width which behave as scroll region.
*/
@@ -96,6 +106,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private static final int FOLDER_NAME_ANIMATION_DURATION = 633;
+ private static final int REORDER_ANIMATION_DURATION = 230;
private static final int REORDER_DELAY = 250;
private static final int ON_EXIT_CLOSE_DELAY = 400;
private static final Rect sTempRect = new Rect();
@@ -116,6 +127,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
private final InputMethodManager mInputMethodManager;
+ private final PowerManager mPowerManager;
+
protected final Launcher mLauncher;
protected DragController mDragController;
protected FolderInfo mInfo;
@@ -171,6 +184,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mInputMethodManager = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+
Resources res = getResources();
mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration);
mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration);
@@ -440,9 +455,41 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
setScaleY(1f);
setAlpha(1f);
mState = STATE_SMALL;
+
+ View reveal = mLauncher.findViewById(R.id.reveal_fake_page_container);
+ reveal.setVisibility(View.VISIBLE);
+ View revealFolderIcon = mLauncher.findViewById(R.id.reveal_fake_folder_icon);
+ revealFolderIcon.setVisibility(View.INVISIBLE);
+ }
+
+ private void prepareFakeFolderIcon() {
+ mFolderIcon.buildDrawingCache(true);
+
+ Bitmap fakeFolderIcon = Bitmap.createBitmap(mFolderIcon.getDrawingCache());
+ View fakeFolderIconView = mLauncher.findViewById(R.id.reveal_fake_folder_icon);
+ FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams)
+ fakeFolderIconView.getLayoutParams();
+
+ // Get globalVisibleRect of the folderIcon. getWidth and getHeight are inaccurate for
+ // hotseat icons
+ Rect rect = new Rect();
+ mFolderIcon.getGlobalVisibleRect(rect);
+
+ flp.height = rect.height();
+ flp.width = rect.width();
+
+ fakeFolderIconView.setLayoutParams(flp);
+
+ int [] folderIconXY = new int[2];
+ mFolderIcon.getLocationOnScreen(folderIconXY);
+ fakeFolderIconView.setX(folderIconXY[0]);
+ fakeFolderIconView.setY(folderIconXY[1]);
+
+ fakeFolderIconView.setBackground(new BitmapDrawable(null, fakeFolderIcon));
+ fakeFolderIconView.setVisibility(View.INVISIBLE);
}
- public void animateOpen() {
+ public void animateOpen(Workspace workspace, int[] folderTouch) {
if (!(getParent() instanceof DragLayer)) return;
mContent.completePendingPageChanges();
@@ -473,7 +520,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
};
} else {
- prepareReveal();
centerAboutIcon();
AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
@@ -490,7 +536,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
Animator drift = ObjectAnimator.ofPropertyValuesHolder(this, tx, ty);
drift.setDuration(mMaterialExpandDuration);
drift.setStartDelay(mMaterialExpandStagger);
- drift.setInterpolator(new LogDecelerateInterpolator(100, 0));
+ drift.setInterpolator(new LogDecelerateInterpolator(60, 0));
int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX());
int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY());
@@ -513,6 +559,34 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
textAlpha.setStartDelay(mMaterialExpandStagger);
textAlpha.setInterpolator(new AccelerateInterpolator(1.5f));
+ prepareFakeFolderIcon();
+ float iconTransY = getResources().getInteger(R.integer.folder_icon_translate_y_dist);
+
+ final View fakeFolderIconView = mLauncher.findViewById(R.id.reveal_fake_folder_icon);
+ float baseIconTranslationY = fakeFolderIconView.getTranslationY();
+ PropertyValuesHolder iconty = PropertyValuesHolder.ofFloat("translationY",
+ baseIconTranslationY, baseIconTranslationY + iconTransY);
+ PropertyValuesHolder iconAlpha = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);
+
+ Animator fakeFolderIcon = LauncherAnimUtils.ofPropertyValuesHolder(fakeFolderIconView,
+ iconty, iconAlpha);
+ fakeFolderIcon.setDuration(mMaterialExpandDuration);
+ fakeFolderIcon.setInterpolator(new AccelerateInterpolator(1.5f));
+ fakeFolderIcon.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mFolderIcon.setAlpha(0);
+ fakeFolderIconView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ fakeFolderIconView.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ prepareReveal();
+
anim.play(drift);
anim.play(iconsAlpha);
anim.play(textAlpha);
@@ -526,7 +600,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
@Override
public void run() {
mContentWrapper.setLayerType(LAYER_TYPE_NONE, null);
- mContentWrapper.setLayerType(LAYER_TYPE_NONE, null);
}
};
}
@@ -535,6 +608,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
public void onAnimationStart(Animator animation) {
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
mContent.getAccessibilityDescription());
+ hideWorkspace();
mState = STATE_ANIMATING;
}
@Override
@@ -628,31 +702,120 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
}
- public void animateClosed() {
+ public int getState() {
+ return mState;
+ }
+
+ public void animateClosed(final boolean animate) {
if (!(getParent() instanceof DragLayer)) return;
- PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
- PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f);
- PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f);
- final ObjectAnimator oa =
- LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
+ AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
- oa.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- onCloseComplete();
- setLayerType(LAYER_TYPE_NONE, null);
- mState = STATE_SMALL;
- }
+ PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
+ float transY = getResources().getInteger(R.integer.folder_translate_y_dist);
+ PropertyValuesHolder translationY = PropertyValuesHolder.ofFloat("translationY", 0f,
+ transY);
+
+ setLayerType(LAYER_TYPE_HARDWARE, null);
+
+ float animatorDurationScale = Settings.Global.getFloat(getContext().getContentResolver(),
+ Settings.Global.ANIMATOR_DURATION_SCALE, 1);
+ ObjectAnimator oa;
+ if (mPowerManager.isPowerSaveMode() || animatorDurationScale < 0.01f) {
+ // power save mode is no fun - skip alpha animation and just set it to 0
+ // otherwise the icons will stay around until the duration of the animation
+ oa = LauncherAnimUtils.ofPropertyValuesHolder(this, translationY);
+ setAlpha(0f);
+ } else {
+ oa = LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, translationY);
+ }
+
+ oa.setDuration(mMaterialExpandDuration);
+ oa.setInterpolator(new LogDecelerateInterpolator(60, 0));
+ anim.play(oa);
+
+ Animator reverseRevealAnim = null;
+ Animator fakeFolderIconAnim = null;
+
+ if (animate) {
+
+ prepareFakeFolderIcon();
+ float iconTransY = getResources().getInteger(R.integer.folder_icon_translate_y_dist);
+
+ final View fakeFolderIconView = mLauncher.findViewById(R.id.reveal_fake_folder_icon);
+ float baseIconTranslationY = fakeFolderIconView.getTranslationY();
+ PropertyValuesHolder iconty = PropertyValuesHolder.ofFloat("translationY",
+ baseIconTranslationY + iconTransY, baseIconTranslationY);
+ PropertyValuesHolder iconAlpha = PropertyValuesHolder.ofFloat("alpha", 0f, 1f);
+
+ fakeFolderIconAnim = LauncherAnimUtils.ofPropertyValuesHolder(fakeFolderIconView,
+ iconty, iconAlpha);
+ fakeFolderIconAnim.setDuration(mMaterialExpandDuration);
+ fakeFolderIconAnim.setInterpolator(new DecelerateInterpolator(2f));
+ fakeFolderIconAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mFolderIcon.setAlpha(0);
+ fakeFolderIconView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ fakeFolderIconView.setVisibility(View.INVISIBLE);
+ mFolderIcon.setAlpha(1);
+
+ View revealView = mLauncher.findViewById(R.id.reveal_fake_page_container);
+ revealView.setVisibility(View.INVISIBLE);
+ }
+ });
+ } else {
+ View revealView = mLauncher.findViewById(R.id.reveal_fake_page_container);
+ revealView.setVisibility(View.INVISIBLE);
+ mFolderIcon.setAlpha(1);
+ }
+
+ if (reverseRevealAnim != null) {
+ anim.play(reverseRevealAnim);
+ }
+ if (fakeFolderIconAnim != null) {
+ anim.play(fakeFolderIconAnim);
+ }
+
+ anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
getContext().getString(R.string.folder_closed));
+ unHideWorkspace();
mState = STATE_ANIMATING;
}
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ onCloseComplete();
+ setLayerType(LAYER_TYPE_NONE, null);
+ mState = STATE_SMALL;
+ }
});
- oa.setDuration(mExpandDuration);
- setLayerType(LAYER_TYPE_HARDWARE, null);
- oa.start();
+
+ anim.start();
+ }
+
+ private int mSavedWidgetsVisibilityState = INVISIBLE;
+ private void hideWorkspace() {
+ mSavedWidgetsVisibilityState = mLauncher.getWidgetsView().getVisibility();
+ mLauncher.getWidgetsView().setVisibility(INVISIBLE);
+ mLauncher.getWorkspace().setVisibility(INVISIBLE);
+ mLauncher.getHotseat().setVisibility(INVISIBLE);
+ mLauncher.getSearchDropTargetBar().setVisibility(INVISIBLE);
+ mLauncher.getPageIndicator().setVisibility(INVISIBLE);
+ }
+
+ private void unHideWorkspace() {
+ mLauncher.getWidgetsView().setVisibility(mSavedWidgetsVisibilityState);
+ mLauncher.getWorkspace().setVisibility(VISIBLE);
+ mLauncher.getHotseat().setVisibility(VISIBLE);
+ mLauncher.getSearchDropTargetBar().setVisibility(VISIBLE);
+ mLauncher.getPageIndicator().setVisibility(VISIBLE);
}
public boolean acceptDrop(DragObject d) {
@@ -966,22 +1129,22 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
int centerY = (int) (sTempRect.top + sTempRect.height() * scale / 2);
int centeredLeft = centerX - width / 2;
int centeredTop = centerY - height / 2;
+ int currentPage = mLauncher.getWorkspace().getNextPage();
+
+ // We first fetch the currently visible CellLayoutChildren
+ CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage);
+ ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets();
+ Rect bounds = new Rect();
+ parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);
- // We need to bound the folder to the currently visible workspace area
- mLauncher.getWorkspace().getPageAreaRelativeToDragLayer(sTempRect);
- int left = Math.min(Math.max(sTempRect.left, centeredLeft),
- sTempRect.left + sTempRect.width() - width);
- int top = Math.min(Math.max(sTempRect.top, centeredTop),
- sTempRect.top + sTempRect.height() - height);
- if (grid.isPhone && (grid.availableWidthPx - width) < grid.iconSizePx) {
- // Center the folder if it is full (on phones only)
- left = (grid.availableWidthPx - width) / 2;
- } else if (width >= sTempRect.width()) {
+ // Center the folder
+ int left = (grid.availableWidthPx - width) / 2;
+ // Drop the top down a little so it isn't bounded by the page indicators
+ int top = (int) (bounds.top + (bounds.height() * 1.15) - height);
+
+ if (width >= bounds.width()) {
// If the folder doesn't fit within the bounds, center it about the desired bounds
- left = sTempRect.left + (sTempRect.width() - width) / 2;
- }
- if (height >= sTempRect.height()) {
- top = sTempRect.top + (sTempRect.height() - height) / 2;
+ left = bounds.left + (bounds.width() - width) / 2;
}
int folderPivotX = width / 2 + (centeredLeft - left);
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 8d534d2..85e3c33 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -39,6 +39,7 @@ import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.launcher3.DropTarget.DragObject;
@@ -60,17 +61,17 @@ public class FolderIcon extends FrameLayout implements FolderListener {
private StylusEventHelper mStylusEventHelper;
// The number of icons to display in the
- public static final int NUM_ITEMS_IN_PREVIEW = 3;
+ public static final int NUM_ITEMS_IN_PREVIEW = 4;
private static final int CONSUMPTION_ANIMATION_DURATION = 100;
private static final int DROP_IN_ANIMATION_DURATION = 400;
private static final int INITIAL_ITEM_ANIMATION_DURATION = 350;
private static final int FINAL_ITEM_ANIMATION_DURATION = 200;
// The degree to which the inner ring grows when accepting drop
- private static final float INNER_RING_GROWTH_FACTOR = 0.15f;
+ private static final float INNER_RING_GROWTH_FACTOR = 0.0f;
// The degree to which the outer ring is scaled in its natural state
- private static final float OUTER_RING_GROWTH_FACTOR = 0.3f;
+ private static final float OUTER_RING_GROWTH_FACTOR = 0.1f;
// The amount of vertical spread between items in the stack [0...1]
private static final float PERSPECTIVE_SHIFT_FACTOR = 0.18f;
@@ -90,7 +91,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
public static Drawable sSharedFolderLeaveBehind = null;
- @Thunk ImageView mPreviewBackground;
+ @Thunk View mPreviewBackground;
@Thunk BubbleTextView mFolderName;
FolderRingAnimator mFolderRingAnimator = null;
@@ -161,11 +162,11 @@ public class FolderIcon extends FrameLayout implements FolderListener {
lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx;
// Offset the preview background to center this view accordingly
- icon.mPreviewBackground = (ImageView) icon.findViewById(R.id.preview_background);
+ icon.mPreviewBackground = icon.findViewById(R.id.preview_background);
lp = (FrameLayout.LayoutParams) icon.mPreviewBackground.getLayoutParams();
- lp.topMargin = grid.folderBackgroundOffset;
- lp.width = grid.folderIconSizePx;
- lp.height = grid.folderIconSizePx;
+ lp.width = grid.iconSizePx;
+ lp.height = grid.iconSizePx;
+ icon.mPreviewBackground.setLayoutParams(lp);
icon.setTag(folderInfo);
icon.setOnClickListener(launcher);
@@ -183,6 +184,58 @@ public class FolderIcon extends FrameLayout implements FolderListener {
folderInfo.addListener(icon);
icon.setOnFocusChangeListener(launcher.mFocusHandler);
+ icon.setDrawingCacheEnabled(true);
+
+ // get dimen for the icon size
+ // padding is equal to 1/8 of icon size
+ // padding gets used at start and end accounting for 2/8
+ // small icons are separated by 1/2 padding
+ // Total padding equals 2.5/8 leaving 5.5/8 for icons
+ // 5.5/8 remaining, divided by 2 equals 2.75 for each small icon
+ int padding = grid.iconSizePx / 8;
+ int smallIconSize = (int) (padding * 2.75);
+
+ for (int i = NUM_ITEMS_IN_PREVIEW; i >= 0; i--) {
+ ImageView appIcon = null;
+ int marginLeft = 0, marginRight = 0, marginTop = 0, marginBottom = 0;
+ switch(i) {
+ case 0:
+ appIcon = (ImageView) icon.findViewById(R.id.app_0);
+ marginLeft = padding;
+ marginTop = padding;
+ break;
+ case 1:
+ appIcon = (ImageView) icon.findViewById(R.id.app_1);
+ marginTop = padding;
+ marginRight = padding;
+ break;
+ case 2:
+ appIcon = (ImageView) icon.findViewById(R.id.app_2);
+ marginBottom = padding;
+ marginLeft = padding;
+ break;
+ case 3:
+ appIcon = (ImageView) icon.findViewById(R.id.app_3);
+ marginBottom = padding;
+ marginRight = padding;
+ break;
+ }
+
+ if (appIcon != null) {
+ RelativeLayout.LayoutParams layoutParams
+ = (RelativeLayout.LayoutParams) appIcon.getLayoutParams();
+
+ layoutParams.width = smallIconSize;
+ layoutParams.height = smallIconSize;
+ layoutParams.leftMargin = marginLeft;
+ layoutParams.rightMargin = marginRight;
+ layoutParams.topMargin = marginTop;
+ layoutParams.bottomMargin = marginBottom;
+
+ appIcon.setLayoutParams(layoutParams);
+ }
+ }
+
return icon;
}
@@ -220,11 +273,11 @@ public class FolderIcon extends FrameLayout implements FolderListener {
}
DeviceProfile grid = launcher.getDeviceProfile();
- sPreviewSize = grid.folderIconSizePx;
+ sPreviewSize = grid.iconSizePx;
sPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding);
- sSharedOuterRingDrawable = res.getDrawable(R.drawable.portal_ring_outer);
- sSharedInnerRingDrawable = res.getDrawable(R.drawable.portal_ring_inner_nolip);
- sSharedFolderLeaveBehind = res.getDrawable(R.drawable.portal_ring_rest);
+ sSharedOuterRingDrawable = res.getDrawable(R.drawable.folder_fill_highlight);
+ sSharedInnerRingDrawable = null;
+ sSharedFolderLeaveBehind = res.getDrawable(R.drawable.folder_bg);
sStaticValuesDirty = false;
}
}
@@ -375,7 +428,14 @@ public class FolderIcon extends FrameLayout implements FolderListener {
item = (ShortcutInfo) mDragInfo;
}
mFolder.beginExternalDrag(item);
- mLauncher.openFolder(FolderIcon.this);
+ mFolderRingAnimator.mCellLayout.hideFolderAccept(mFolderRingAnimator);
+
+ int[] folderTouchXY = new int[2];
+ mFolder.getLocationOnScreen(folderTouchXY);
+ int[] folderTouchXYOffset = {folderTouchXY[0] + mFolder.getWidth() / 2,
+ folderTouchXY[1] + mFolder.getHeight() / 2};
+
+ mLauncher.openFolder(FolderIcon.this, folderTouchXYOffset);
}
};
@@ -482,6 +542,15 @@ public class FolderIcon extends FrameLayout implements FolderListener {
if (d.dragInfo instanceof AppInfo) {
// Came from all apps -- make a copy
item = ((AppInfo) d.dragInfo).makeShortcut();
+ } else if (d.dragInfo instanceof FolderInfo) {
+ FolderInfo folder = (FolderInfo) d.dragInfo;
+ mFolder.notifyDrop();
+ for (ShortcutInfo fItem : folder.contents) {
+ onDrop(fItem, d.dragView, null, 1.0f, mInfo.contents.size(), d.postAnimationRunnable, d);
+ }
+ mLauncher.removeFolder(folder);
+ LauncherModel.deleteItemFromDatabase(mLauncher, folder);
+ return;
} else {
item = (ShortcutInfo) d.dragInfo;
}
@@ -511,7 +580,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
mMaxPerspectiveShift = mBaselineIconSize * PERSPECTIVE_SHIFT_FACTOR;
mPreviewOffsetX = (mTotalWidth - mAvailableSpaceInPreview) / 2;
- mPreviewOffsetY = previewPadding + grid.folderBackgroundOffset;
+ mPreviewOffsetY = grid.folderBackgroundOffset;
}
}
@@ -622,13 +691,35 @@ public class FolderIcon extends FrameLayout implements FolderListener {
int nItemsInPreview = Math.min(items.size(), NUM_ITEMS_IN_PREVIEW);
if (!mAnimating) {
- for (int i = nItemsInPreview - 1; i >= 0; i--) {
- v = (TextView) items.get(i);
- if (!mHiddenItems.contains(v.getTag())) {
- d = getTopDrawable(v);
- mParams = computePreviewItemDrawingParams(i, mParams);
- mParams.drawable = d;
- drawPreviewItem(canvas, mParams);
+ for (int i = NUM_ITEMS_IN_PREVIEW; i >= 0; i--) {
+ d = null;
+ if (i < items.size()) {
+ v = (TextView) items.get(i);
+ if (!mHiddenItems.contains(v.getTag())) {
+ d = getTopDrawable(v);
+ mParams = computePreviewItemDrawingParams(i, mParams);
+ mParams.drawable = d;
+ }
+ }
+
+ ImageView appIcon = null;
+ switch(i) {
+ case 0:
+ appIcon = (ImageView) findViewById(R.id.app_0);
+ break;
+ case 1:
+ appIcon = (ImageView) findViewById(R.id.app_1);
+ break;
+ case 2:
+ appIcon = (ImageView) findViewById(R.id.app_2);
+ break;
+ case 3:
+ appIcon = (ImageView) findViewById(R.id.app_3);
+ break;
+ }
+
+ if (appIcon != null) {
+ appIcon.setImageDrawable(d);
}
}
} else {
@@ -645,10 +736,9 @@ public class FolderIcon extends FrameLayout implements FolderListener {
final Runnable onCompleteRunnable) {
final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null);
- float iconSize = mLauncher.getDeviceProfile().iconSizePx;
- final float scale0 = iconSize / d.getIntrinsicWidth() ;
- final float transX0 = (mAvailableSpaceInPreview - iconSize) / 2;
- final float transY0 = (mAvailableSpaceInPreview - iconSize) / 2 + getPaddingTop();
+ final float scale0 = 1.0f;
+ final float transX0 = (mAvailableSpaceInPreview - d.getIntrinsicWidth()) / 2;
+ final float transY0 = (mAvailableSpaceInPreview - d.getIntrinsicHeight()) / 2 + getPaddingTop();
mAnimParams.drawable = d;
ValueAnimator va = LauncherAnimUtils.ofFloat(this, 0f, 1.0f);
@@ -675,7 +765,7 @@ public class FolderIcon extends FrameLayout implements FolderListener {
public void onAnimationEnd(Animator animation) {
mAnimating = false;
if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
+ mLauncher.runOnUiThread(onCompleteRunnable);
}
}
});
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index aea21c9..32d752a 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -103,7 +103,6 @@ public class FolderInfo extends ItemInfo {
super.onAddToDatabase(context, values);
values.put(LauncherSettings.Favorites.TITLE, title.toString());
values.put(LauncherSettings.Favorites.OPTIONS, options);
-
}
void addListener(FolderListener listener) {
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
index 7343bf6..6400a0f 100644
--- a/src/com/android/launcher3/InsettableFrameLayout.java
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -24,10 +24,14 @@ public class InsettableFrameLayout extends FrameLayout implements
if (child instanceof Insettable) {
((Insettable) child).setInsets(newInsets);
} else if (!lp.ignoreInsets) {
- lp.topMargin += (newInsets.top - oldInsets.top);
+ if (!lp.ignoreTopInsets) {
+ lp.topMargin += (newInsets.top - oldInsets.top);
+ }
lp.leftMargin += (newInsets.left - oldInsets.left);
lp.rightMargin += (newInsets.right - oldInsets.right);
- lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
+ if (!lp.ignoreBottomInsets) {
+ lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
+ }
}
child.setLayoutParams(lp);
}
@@ -65,6 +69,8 @@ public class InsettableFrameLayout extends FrameLayout implements
public static class LayoutParams extends FrameLayout.LayoutParams {
boolean ignoreInsets = false;
+ boolean ignoreTopInsets = false;
+ boolean ignoreBottomInsets = false;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
@@ -72,6 +78,10 @@ public class InsettableFrameLayout extends FrameLayout implements
R.styleable.InsettableFrameLayout_Layout);
ignoreInsets = a.getBoolean(
R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false);
+ ignoreTopInsets = a.getBoolean(
+ R.styleable.InsettableFrameLayout_Layout_layout_ignoreTopInsets, false);
+ ignoreBottomInsets = a.getBoolean(
+ R.styleable.InsettableFrameLayout_Layout_layout_ignoreBottomInsets, false);
a.recycle();
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1f843cb..6faea20 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -150,6 +151,8 @@ public class Launcher extends Activity
private static final int REQUEST_BIND_APPWIDGET = 11;
private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;
+ private static final int REQUEST_PERMISSION_CALL_PHONE = 13;
+
private static final int WORKSPACE_BACKGROUND_GRADIENT = 0;
private static final int WORKSPACE_BACKGROUND_TRANSPARENT = 1;
private static final int WORKSPACE_BACKGROUND_BLACK = 2;
@@ -867,6 +870,24 @@ public class Launcher extends Activity
/** @Override for MNC */
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
+ if (requestCode == REQUEST_PERMISSION_CALL_PHONE && sPendingAddItem != null
+ && sPendingAddItem.requestCode == REQUEST_PERMISSION_CALL_PHONE) {
+ View v = null;
+ CellLayout layout = getCellLayout(sPendingAddItem.container, sPendingAddItem.screenId);
+ if (layout != null) {
+ v = layout.getChildAt(sPendingAddItem.cellX, sPendingAddItem.cellY);
+ }
+ Intent intent = sPendingAddItem.intent;
+ sPendingAddItem = null;
+ if (grantResults.length > 0
+ && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ startActivity(v, intent, null);
+ } else {
+ // TODO: Show a snack bar with link to settings
+ Toast.makeText(this, getString(R.string.msg_no_phone_permission,
+ getString(R.string.app_name)), Toast.LENGTH_SHORT).show();
+ }
+ }
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onRequestPermissionsResult(requestCode, permissions,
grantResults);
@@ -1821,6 +1842,10 @@ public class Launcher extends Activity
return mHotseat;
}
+ public View getPageIndicator() {
+ return mPageIndicators;
+ }
+
public ViewGroup getOverviewPanel() {
return mOverviewPanel;
}
@@ -2688,6 +2713,11 @@ public class Launcher extends Activity
final FolderInfo info = folderIcon.getFolderInfo();
Folder openFolder = mWorkspace.getFolderForTag(info);
+ int[] folderTouchXY = new int[2];
+ v.getLocationOnScreen(folderTouchXY);
+ int[] folderTouchXYOffset = {folderTouchXY[0] + v.getWidth() / 2,
+ folderTouchXY[1] + v.getHeight() / 2};
+
// If the folder info reports that the associated folder is open, then verify that
// it is actually opened. There have been a few instances where this gets out of sync.
if (info.opened && openFolder == null) {
@@ -2700,7 +2730,7 @@ public class Launcher extends Activity
// Close any open folder
closeFolder();
// Open the requested folder
- openFolder(folderIcon);
+ openFolder(folderIcon, folderTouchXYOffset);
} else {
// Find the open folder...
int folderScreen;
@@ -2712,7 +2742,7 @@ public class Launcher extends Activity
// Close any folder open on the current screen
closeFolder();
// Pull the folder onto this screen
- openFolder(folderIcon);
+ openFolder(folderIcon, folderTouchXYOffset);
}
}
}
@@ -2926,6 +2956,22 @@ public class Launcher extends Activity
}
return true;
} catch (SecurityException e) {
+ if (Utilities.ATLEAST_MARSHMALLOW && tag instanceof ItemInfo) {
+ // Due to legacy reasons, direct call shortcuts require Launchers to have the
+ // corresponding permission. Show the appropriate permission prompt if that
+ // is the case.
+ if (intent.getComponent() == null
+ && Intent.ACTION_CALL.equals(intent.getAction())
+ && checkSelfPermission(Manifest.permission.CALL_PHONE) !=
+ PackageManager.PERMISSION_GRANTED) {
+ // TODO: Rename sPendingAddItem to a generic name.
+ sPendingAddItem = preparePendingAddArgs(REQUEST_PERMISSION_CALL_PHONE, intent,
+ 0, (ItemInfo) tag);
+ requestPermissions(new String[]{Manifest.permission.CALL_PHONE},
+ REQUEST_PERMISSION_CALL_PHONE);
+ return false;
+ }
+ }
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Launcher does not have the permission to launch " + intent +
". Make sure to create a MAIN intent-filter for the corresponding activity " +
@@ -3063,8 +3109,13 @@ public class Launcher extends Activity
*
* @param folderInfo The FolderInfo describing the folder to open.
*/
- public void openFolder(FolderIcon folderIcon) {
+ public void openFolder(FolderIcon folderIcon, int[] folderTouch) {
Folder folder = folderIcon.getFolder();
+
+ if (folder.getState() == Folder.STATE_ANIMATING) {
+ return;
+ }
+
Folder openFolder = mWorkspace != null ? mWorkspace.getOpenFolder() : null;
if (openFolder != null && openFolder != folder) {
// Close any open folder before opening a folder.
@@ -3087,8 +3138,8 @@ public class Launcher extends Activity
Log.w(TAG, "Opening folder (" + folder + ") which already has a parent (" +
folder.getParent() + ").");
}
- folder.animateOpen();
- growAndFadeOutFolderIcon(folderIcon);
+ folder.animateOpen(getWorkspace(), folderTouch);
+ /*growAndFadeOutFolderIcon(folderIcon);*/
// Notify the accessibility manager that this folder "window" has appeared and occluded
// the workspace items
@@ -3107,17 +3158,21 @@ public class Launcher extends Activity
}
public void closeFolder(Folder folder) {
+ closeFolder(folder, true);
+ }
+
+ public void closeFolder(Folder folder, boolean animate) {
folder.getInfo().opened = false;
ViewGroup parent = (ViewGroup) folder.getParent().getParent();
if (parent != null) {
FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo);
- shrinkAndFadeInFolderIcon(fi);
+ /*shrinkAndFadeInFolderIcon(fi);*/
if (fi != null) {
((CellLayout.LayoutParams) fi.getLayoutParams()).canReorder = true;
}
}
- folder.animateClosed();
+ folder.animateClosed(animate);
// Notify the accessibility manager that this folder "window" has disappeard and no
// longer occludeds the workspace items
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 8a5804f..5cde2e5 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -40,7 +40,7 @@ public class LauncherSettings {
* <P>Type: TEXT</P>
*/
public static final String TITLE = "title";
-
+
/**
* The Intent URL of the gesture, describing what it points to. This
* value is given to {@link android.content.Intent#parseUri(String, int)} to create