summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/layout-land/launcher.xml4
-rw-r--r--res/layout-port/launcher.xml4
-rw-r--r--res/layout-sw720dp/launcher.xml4
-rw-r--r--res/layout/apps_customize_pane.xml62
-rw-r--r--res/layout/apps_list_row_view.xml2
-rw-r--r--res/layout/widget_cell.xml (renamed from res/layout/apps_customize_widget.xml)64
-rw-r--r--res/layout/widgets_list_row_view.xml89
-rw-r--r--res/layout/widgets_view.xml49
-rw-r--r--res/values-land/dimens.xml5
-rw-r--r--res/values-sw600dp/dimens.xml8
-rw-r--r--res/values-v17/styles.xml4
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/dimens.xml28
-rw-r--r--res/values/styles.xml4
-rw-r--r--src/com/android/launcher3/AppInfo.java13
-rw-r--r--src/com/android/launcher3/AppsCustomizePagedView.java1060
-rw-r--r--src/com/android/launcher3/AppsCustomizeTabHost.java228
-rw-r--r--src/com/android/launcher3/CellLayout.java4
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java15
-rw-r--r--src/com/android/launcher3/DeviceProfile.java62
-rw-r--r--src/com/android/launcher3/DragSource.java2
-rw-r--r--src/com/android/launcher3/FastBitmapDrawable.java4
-rw-r--r--src/com/android/launcher3/IconCache.java12
-rw-r--r--src/com/android/launcher3/Insettable.java4
-rw-r--r--src/com/android/launcher3/ItemInfo.java14
-rw-r--r--src/com/android/launcher3/Launcher.java118
-rw-r--r--src/com/android/launcher3/LauncherAppState.java2
-rw-r--r--src/com/android/launcher3/LauncherAppWidgetProviderInfo.java15
-rw-r--r--src/com/android/launcher3/LauncherModel.java2
-rw-r--r--src/com/android/launcher3/LauncherSettings.java8
-rw-r--r--src/com/android/launcher3/LauncherStateTransitionAnimation.java56
-rw-r--r--src/com/android/launcher3/PagedViewWithDraggableItems.java174
-rw-r--r--src/com/android/launcher3/PendingAddItemInfo.java88
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java16
-rw-r--r--src/com/android/launcher3/WidgetsContainerView.java84
-rw-r--r--src/com/android/launcher3/Workspace.java2
-rw-r--r--src/com/android/launcher3/widget/PackageItemInfo.java57
-rw-r--r--src/com/android/launcher3/widget/PendingAddShortcutInfo.java44
-rw-r--r--src/com/android/launcher3/widget/PendingAddWidgetInfo.java91
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java (renamed from src/com/android/launcher3/PagedViewWidget.java)75
-rw-r--r--src/com/android/launcher3/widget/WidgetImageView.java (renamed from src/com/android/launcher3/PagedViewWidgetImageView.java)7
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java376
-rw-r--r--src/com/android/launcher3/widget/WidgetsListAdapter.java188
-rw-r--r--src/com/android/launcher3/widget/WidgetsModel.java136
-rw-r--r--src/com/android/launcher3/widget/WidgetsRowView.java (renamed from src/com/android/launcher3/PagedViewGridLayout.java)77
-rw-r--r--src/com/android/launcher3/widget/WidgetsRowViewHolder.java36
46 files changed, 1332 insertions, 2069 deletions
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index b13984a26..d5dd91ab4 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -57,8 +57,8 @@
android:id="@+id/overview_panel"
android:visibility="gone" />
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
+ <include layout="@layout/widgets_view"
+ android:id="@+id/widgets_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 3cb338efe..5a018c516 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -66,8 +66,8 @@
android:id="@+id/search_drop_target_bar"
layout="@layout/search_drop_target_bar" />
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
+ <include layout="@layout/widgets_view"
+ android:id="@+id/widgets_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index a3d502cf4..8bd827a25 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -66,8 +66,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
- <include layout="@layout/apps_customize_pane"
- android:id="@+id/apps_customize_pane"
+ <include layout="@layout/widgets_view"
+ android:id="@+id/widget_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible" />
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
deleted file mode 100644
index e42576ffe..000000000
--- a/res/layout/apps_customize_pane.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.AppsCustomizeTabHost
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:clipChildren="false">
-
- <LinearLayout
- android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:orientation="vertical">
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:clipChildren="false">
- <FrameLayout
- android:id="@+id/fake_page_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:clipToPadding="false">
- <FrameLayout
- android:id="@+id/fake_page"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible"
- android:clipToPadding="false" />
- </FrameLayout>
- <com.android.launcher3.AppsCustomizePagedView
- android:id="@+id/apps_customize_pane_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- launcher:widgetCountX="@integer/apps_customize_widget_cell_count_x"
- launcher:widgetCountY="@integer/apps_customize_widget_cell_count_y"
- launcher:maxGap="@dimen/workspace_max_gap"
- launcher:pageIndicator="@+id/apps_customize_page_indicator" />
- </FrameLayout>
- <include
- android:id="@+id/apps_customize_page_indicator"
- layout="@layout/page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center" />
- </LinearLayout>
-</com.android.launcher3.AppsCustomizeTabHost>
diff --git a/res/layout/apps_list_row_view.xml b/res/layout/apps_list_row_view.xml
index 83c175bb8..e80285b95 100644
--- a/res/layout/apps_list_row_view.xml
+++ b/res/layout/apps_list_row_view.xml
@@ -30,4 +30,4 @@
android:textColor="@color/apps_view_section_text_color"
android:textSize="@dimen/apps_view_section_text_size"
android:focusable="false" />
-</LinearLayout> \ No newline at end of file
+</LinearLayout>
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/widget_cell.xml
index a8344e3ff..1286a622b 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/widget_cell.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2015 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.
@@ -13,58 +13,26 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.PagedViewWidget
+<com.android.launcher3.widget.WidgetCell
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
-
android:background="@drawable/focusable_view_bg"
android:focusable="true">
<LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1">
- <FrameLayout
- android:id="@+id/left_border"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:background="@color/widget_text_panel"
- android:visibility="gone" />
-
- <!-- The preview of the widget or shortcut. -->
- <com.android.launcher3.PagedViewWidgetImageView
- android:id="@+id/widget_preview"
- style="@style/PagedViewWidgetImageView"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:paddingTop="@dimen/app_widget_preview_padding_top"
- android:paddingEnd="@dimen/app_widget_preview_padding_right"
- android:paddingRight="@dimen/app_widget_preview_padding_right"
- android:scaleType="matrix" />
- <FrameLayout
- android:id="@+id/right_border"
- android:layout_width="1dp"
- android:layout_height="match_parent"
- android:background="@color/widget_text_panel"
- android:visibility="gone" />
- </LinearLayout>
-
- <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="@dimen/app_widget_preview_label_vertical_padding"
- android:paddingBottom="@dimen/app_widget_preview_label_vertical_padding"
- android:paddingLeft="@dimen/app_widget_preview_label_horizontal_padding"
- android:paddingRight="@dimen/app_widget_preview_label_horizontal_padding"
- android:background="@color/widget_text_panel"
+ android:paddingTop="@dimen/widget_preview_label_vertical_padding"
+ android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
+ android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
+ android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
android:orientation="horizontal">
+
<!-- The name of the widget. -->
<TextView
android:id="@+id/widget_name"
@@ -91,6 +59,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="5dp"
+ android:layout_marginLeft="5dp"
android:layout_weight="0"
android:gravity="start"
@@ -101,5 +70,16 @@
android:shadowColor="#B0000000" />
</LinearLayout>
+ <!-- The image of the widget. -->
+ <com.android.launcher3.widget.WidgetImageView
+ android:id="@+id/widget_preview"
+ style="@style/WidgetImageView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="@dimen/widget_preview_padding_top"
+ android:paddingEnd="@dimen/widget_preview_padding_right"
+ android:paddingRight="@dimen/widget_preview_padding_right"
+ android:scaleType="matrix" />
-</com.android.launcher3.PagedViewWidget>
+</com.android.launcher3.widget.WidgetCell>
diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml
new file mode 100644
index 000000000..c7863c7c3
--- /dev/null
+++ b/res/layout/widgets_list_row_view.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/widgets_cell_list_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg"
+ android:descendantFocusability="afterDescendants">
+
+ <!-- Section info -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:focusable="true"
+ android:background="@drawable/focusable_view_bg"
+ android:descendantFocusability="afterDescendants">
+ <ImageView
+ android:id="@+id/section_image"
+ android:layout_width="@dimen/widget_section_height"
+ android:layout_height="@dimen/widget_section_height"
+ android:paddingLeft="@dimen/widget_section_icon_padding"
+ android:paddingRight="@dimen/widget_section_icon_padding"
+ android:paddingTop="@dimen/widget_section_icon_padding"
+ android:paddingBottom="@dimen/widget_section_icon_padding"
+ android:background="@color/widget_text_panel"
+ />
+ <TextView
+ android:id="@+id/section"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/widget_section_height"
+ android:paddingTop="8dp"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:gravity="start|center_vertical"
+ android:textColor="@color/widgets_view_section_text_color"
+ android:background="@color/widget_text_panel"
+ android:textSize="20sp"
+ android:focusable="false" />
+ </LinearLayout>
+
+ <!-- Widget list -->
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="end"
+ >
+ <!-- TODO(hyunyoungs): replace the indicator with actual assets. -->
+ <FrameLayout
+ android:id="@+id/scrollable_indicator"
+ android:layout_gravity="center_vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@drawable/ic_pageindicator_default"
+ android:visibility="invisible"
+ />
+ <HorizontalScrollView
+ android:id="@+id/widgets_scroll_container"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/widget_cell_height"
+ android:scrollbars="none" >
+ <LinearLayout
+ android:id="@+id/widgets_cell_list"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" />
+ </HorizontalScrollView>
+ </RelativeLayout>
+</LinearLayout>
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
new file mode 100644
index 000000000..8e7ed161a
--- /dev/null
+++ b/res/layout/widgets_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<!-- The top and bottom paddings are defined in this container, but since we want
+ the list view to span the full width (for touch interception purposes), we
+ will bake the left/right padding into that view's background itself. -->
+<com.android.launcher3.widget.WidgetsContainerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/widgets_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="@dimen/widget_container_inset"
+ android:paddingBottom="@dimen/widget_container_inset"
+ android:descendantFocusability="afterDescendants">
+
+ <!-- Temporary until finalizing on animation. -->
+ <include
+ android:id="@+id/widgets_reveal_view"
+ layout="@layout/apps_reveal_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+
+ <LinearLayout
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipChildren="false"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.RecyclerView
+ android:id="@+id/widgets_list_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/quantum_panel_dark"/>
+ </LinearLayout>
+</com.android.launcher3.widget.WidgetsContainerView> \ No newline at end of file
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 1b3418154..06a99842e 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -18,9 +18,4 @@
<!-- QSB -->
<dimen name="toolbar_button_vertical_padding">8dip</dimen>
<dimen name="toolbar_button_horizontal_padding">0dip</dimen>
-
-<!-- AppsCustomize -->
- <dimen name="apps_customize_tab_bar_height">42dp</dimen>
- <integer name="apps_customize_widget_cell_count_x">3</integer>
- <integer name="apps_customize_widget_cell_count_y">2</integer>
</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index d80f18c9e..13a1f4098 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -24,11 +24,9 @@
<dimen name="apps_view_row_height">76dp</dimen>
<!-- AppsCustomize -->
- <dimen name="apps_customize_tab_bar_height">60dp</dimen>
- <dimen name="apps_customize_tab_bar_margin_top">8dp</dimen>
- <dimen name="app_widget_preview_label_margin_top">8dp</dimen>
- <dimen name="app_widget_preview_label_margin_left">@dimen/app_widget_preview_padding_left</dimen>
- <dimen name="app_widget_preview_label_margin_right">@dimen/app_widget_preview_padding_right</dimen>
+ <dimen name="widget_preview_label_margin_top">8dp</dimen>
+ <dimen name="widget_preview_label_margin_left">@dimen/widget_preview_padding_left</dimen>
+ <dimen name="widget_preview_label_margin_right">@dimen/widget_preview_padding_right</dimen>
<!-- Cling -->
<dimen name="cling_migration_logo_height">400dp</dimen>
diff --git a/res/values-v17/styles.xml b/res/values-v17/styles.xml
index 11d2a1f82..229375f85 100644
--- a/res/values-v17/styles.xml
+++ b/res/values-v17/styles.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="PagedViewWidgetImageView">
- <item name="android:paddingStart">@dimen/app_widget_preview_padding_left</item>
+ <style name="WidgetImageView">
+ <item name="android:paddingStart">@dimen/widget_preview_padding_left</item>
</style>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 590a8872b..3a06bd95a 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,8 +36,10 @@
<color name="outline_color">#FFFFFFFF</color>
<color name="widget_text_panel">#FF374248</color>
-<!-- Apps view -->
+ <!-- Apps view -->
<color name="apps_view_scrollbar_thumb_color">#009688</color>
<color name="apps_view_section_text_color">#009688</color>
+ <!-- Widgetss view -->
+ <color name="widgets_view_section_text_color">#009688</color>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 735373d69..7c99278a8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -60,18 +60,9 @@
<dimen name="apps_view_fast_scroll_text_size">40dp</dimen>
<!-- AllApps/Customize/AppsCustomize -->
- <!-- The height of the tab bar - if this changes, we should update the
- external icon width/height above to compensate -->
- <dimen name="apps_customize_tab_bar_height">52dp</dimen>
- <dimen name="apps_customize_tab_bar_margin_top">0dp</dimen>
<dimen name="app_icon_size">48dp</dimen>
<dimen name="apps_customize_horizontal_padding">0dp</dimen>
- <!-- The AppsCustomize page indicator -->
- <dimen name="apps_customize_page_indicator_height">12dp</dimen>
- <dimen name="apps_customize_page_indicator_margin">4dp</dimen>
- <dimen name="apps_customize_page_indicator_offset">16dp</dimen>
-
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">14dp</dimen>
<dimen name="drop_target_text_size">14sp</dimen>
@@ -85,12 +76,19 @@
should be. If 0, it will not be scaled at all. -->
<dimen name="dragViewScale">12dp</dimen>
- <!-- Padding applied to AppWidget previews -->
- <dimen name="app_widget_preview_padding_left">16dp</dimen>
- <dimen name="app_widget_preview_padding_right">16dp</dimen>
- <dimen name="app_widget_preview_padding_top">32dp</dimen>
- <dimen name="app_widget_preview_label_vertical_padding">8dp</dimen>
- <dimen name="app_widget_preview_label_horizontal_padding">8dp</dimen>
+<!-- Widget tray -->
+ <dimen name="widget_container_inset">8dp</dimen>
+ <dimen name="widget_preview_size">140dp</dimen>
+ <dimen name="widget_preview_padding_left">16dp</dimen>
+ <dimen name="widget_preview_padding_right">16dp</dimen>
+ <dimen name="widget_preview_padding_top">8dp</dimen>
+ <dimen name="widget_preview_label_vertical_padding">8dp</dimen>
+ <dimen name="widget_preview_label_horizontal_padding">8dp</dimen>
+
+ <dimen name="widget_section_height">52dp</dimen>
+ <dimen name="widget_section_icon_padding">8dp</dimen>
+
+ <dimen name="widget_cell_height">160dp</dimen>
<!-- Padding applied to shortcut previews -->
<dimen name="shortcut_preview_padding_left">0dp</dimen>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 77798f174..94efebc06 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -91,8 +91,8 @@
</style>
<!-- Overridden in device overlays -->
- <style name="PagedViewWidgetImageView">
- <item name="android:paddingLeft">@dimen/app_widget_preview_padding_left</item>
+ <style name="WidgetImageView">
+ <item name="android:paddingLeft">@dimen/widget_preview_padding_left</item>
</style>
</resources>
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index a1391b232..7c6b0664c 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -43,7 +43,7 @@ public class AppInfo extends ItemInfo {
/**
* A bitmap version of the application icon.
*/
- Bitmap iconBitmap;
+ public Bitmap iconBitmap;
/**
* Indicates whether we're using a low res icon
@@ -55,7 +55,7 @@ public class AppInfo extends ItemInfo {
*/
long firstInstallTime;
- ComponentName componentName;
+ public ComponentName componentName;
static final int DOWNLOADED_FLAG = 1;
static final int UPDATED_SYSTEM_APP_FLAG = 2;
@@ -121,12 +121,15 @@ public class AppInfo extends ItemInfo {
+ " user=" + user + ")";
}
+ /**
+ * Helper method used for debugging.
+ */
public static void dumpApplicationInfoList(String tag, String label, ArrayList<AppInfo> list) {
Log.d(tag, label + " size=" + list.size());
for (AppInfo info: list) {
- Log.d(tag, " title=\"" + info.title + "\" iconBitmap="
- + info.iconBitmap + " firstInstallTime="
- + info.firstInstallTime);
+ Log.d(tag, " title=\"" + info.title + "\" iconBitmap=" + info.iconBitmap
+ + " firstInstallTime=" + info.firstInstallTime
+ + " componentName=" + info.componentName.getPackageName());
}
}
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
deleted file mode 100644
index 58bcf1dbe..000000000
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.appwidget.AppWidgetHostView;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.GridLayout;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.FocusHelper.PagedViewKeyListener;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.util.Thunk;
-
-import java.util.ArrayList;
-
-/**
- * The Apps/Customize page that displays all the applications, widgets, and shortcuts.
- */
-public class AppsCustomizePagedView extends PagedViewWithDraggableItems implements
- View.OnClickListener, DragSource,
- PagedViewWidget.ShortPressListener, LauncherTransitionable {
- static final String TAG = "AppsCustomizePagedView";
-
- private static Rect sTmpRect = new Rect();
- private static final int[] sTempPosArray = new int[2];
-
- /**
- * The different content types that this paged view can show.
- */
- public enum ContentType {
- Widgets
- }
- private ContentType mContentType = ContentType.Widgets;
-
- // Refs
- @Thunk Launcher mLauncher;
- private DragController mDragController;
- private final LayoutInflater mLayoutInflater;
- private final PackageManager mPackageManager;
-
- // Save and Restore
- private int mSaveInstanceStateItemIndex = -1;
-
- // Content
- private ArrayList<Object> mWidgets;
-
- // Caching
- private IconCache mIconCache;
-
- // Dimens
- private int mContentWidth, mContentHeight;
- @Thunk int mWidgetCountX, mWidgetCountY;
- private int mNumWidgetPages;
-
- private final PagedViewKeyListener mKeyListener = new PagedViewKeyListener();
-
- private Runnable mInflateWidgetRunnable = null;
- private Runnable mBindWidgetRunnable = null;
- static final int WIDGET_NO_CLEANUP_REQUIRED = -1;
- static final int WIDGET_PRELOAD_PENDING = 0;
- static final int WIDGET_BOUND = 1;
- static final int WIDGET_INFLATED = 2;
- int mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
- int mWidgetLoadingId = -1;
- PendingAddWidgetInfo mCreateWidgetInfo = null;
- private boolean mDraggingWidget = false;
- boolean mPageBackgroundsVisible = true;
-
- private Toast mWidgetInstructionToast;
-
- // Deferral of loading widget previews during launcher transitions
- private boolean mInTransition;
-
- WidgetPreviewLoader mWidgetPreviewLoader;
-
- private boolean mInBulkBind;
- private boolean mNeedToUpdatePageCountsAndInvalidateData;
-
- public AppsCustomizePagedView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mLayoutInflater = LayoutInflater.from(context);
- mPackageManager = context.getPackageManager();
- mWidgets = new ArrayList<>();
- mIconCache = (LauncherAppState.getInstance()).getIconCache();
-
- // Save the default widget preview background
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AppsCustomizePagedView, 0, 0);
- mWidgetCountX = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountX, 2);
- mWidgetCountY = a.getInt(R.styleable.AppsCustomizePagedView_widgetCountY, 2);
- a.recycle();
-
- // The padding on the non-matched dimension for the default widget preview icons
- // (top + bottom)
- mFadeInAdjacentScreens = false;
-
- // Unless otherwise specified this view is important for accessibility.
- if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
- setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- }
- setSinglePageInViewport();
- }
-
- @Override
- protected void init() {
- super.init();
- mCenterPagesVertically = false;
-
- Context context = getContext();
- Resources r = context.getResources();
- setDragSlopeThreshold(r.getInteger(R.integer.config_appsCustomizeDragSlopeThreshold)/100f);
- }
-
- public void onFinishInflate() {
- super.onFinishInflate();
-
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- setPadding(grid.edgeMarginPx, 2 * grid.edgeMarginPx,
- grid.edgeMarginPx, 2 * grid.edgeMarginPx);
- }
-
- void setWidgetsPageIndicatorPadding(int pageIndicatorHeight) {
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), pageIndicatorHeight);
- }
-
- WidgetPreviewLoader getWidgetPreviewLoader() {
- if (mWidgetPreviewLoader == null) {
- mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
- }
- return mWidgetPreviewLoader;
- }
-
- /** Returns the item index of the center item on this page so that we can restore to this
- * item index when we rotate. */
- private int getMiddleComponentIndexOnCurrentPage() {
- int i = -1;
- if (getPageCount() > 0) {
- int currentPage = getCurrentPage();
- if (mContentType == ContentType.Widgets) {
- PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(currentPage);
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
- int childCount = layout.getChildCount();
- if (childCount > 0) {
- i = (currentPage * numItemsPerPage) + (childCount / 2);
- }
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
- }
- return i;
- }
-
- /** Get the index of the item to restore to if we need to restore the current page. */
- int getSaveInstanceStateIndex() {
- if (mSaveInstanceStateItemIndex == -1) {
- mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage();
- }
- return mSaveInstanceStateItemIndex;
- }
-
- /** Returns the page in the current orientation which is expected to contain the specified
- * item index. */
- int getPageForComponent(int index) {
- if (index < 0) return 0;
-
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
- return index / numItemsPerPage;
- }
-
- /** Restores the page for an item at the specified index */
- void restorePageForIndex(int index) {
- if (index < 0) return;
- mSaveInstanceStateItemIndex = index;
- }
-
- private void updatePageCounts() {
- mNumWidgetPages = (int) Math.ceil(mWidgets.size() /
- (float) (mWidgetCountX * mWidgetCountY));
- }
-
- protected void onDataReady(int width, int height) {
- updatePageCounts();
-
- // Force a measure to update recalculate the gaps
- mContentWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
- mContentHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
-
- final boolean hostIsTransitioning = getTabHost().isInTransition();
- int page = getPageForComponent(mSaveInstanceStateItemIndex);
- invalidatePageData(Math.max(0, page), hostIsTransitioning);
- }
-
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
-
- if (!isDataReady()) {
- if (!mWidgets.isEmpty()) {
- post(new Runnable() {
- // This code triggers requestLayout so must be posted outside of the
- // layout pass.
- public void run() {
- if (Utilities.isViewAttachedToWindow(AppsCustomizePagedView.this)) {
- setDataIsReady();
- onDataReady(getMeasuredWidth(), getMeasuredHeight());
- }
- }
- });
- }
- }
- }
-
- public void onPackagesUpdated(ArrayList<Object> widgetsAndShortcuts) {
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-
- // Get the list of widgets and shortcuts
- mWidgets.clear();
- for (Object o : widgetsAndShortcuts) {
- if (o instanceof LauncherAppWidgetProviderInfo) {
- LauncherAppWidgetProviderInfo widget = (LauncherAppWidgetProviderInfo) o;
- if (!app.shouldShowAppOrWidgetProvider(widget.provider) && !widget.isCustomWidget) {
- continue;
- }
-
- if (widget.minSpanX > 0 && widget.minSpanY > 0) {
- // Ensure that all widgets we show can be added on a workspace of this size
- int[] spanXY = Launcher.getSpanForWidget(mLauncher, widget);
- int[] minSpanXY = Launcher.getMinSpanForWidget(mLauncher, widget);
- int minSpanX = Math.min(spanXY[0], minSpanXY[0]);
- int minSpanY = Math.min(spanXY[1], minSpanXY[1]);
- if (minSpanX <= (int) grid.numColumns &&
- minSpanY <= (int) grid.numRows) {
- mWidgets.add(widget);
- } else {
- Log.e(TAG, "Widget " + widget.provider + " can not fit on this device (" +
- widget.minWidth + ", " + widget.minHeight + ")");
- }
- } else {
- Log.e(TAG, "Widget " + widget.provider + " has invalid dimensions (" +
- widget.minWidth + ", " + widget.minHeight + ")");
- }
- } else {
- // just add shortcuts
- mWidgets.add(o);
- }
- }
-
- updatePageCountsAndInvalidateData();
- }
-
- public void setBulkBind(boolean bulkBind) {
- if (bulkBind) {
- mInBulkBind = true;
- } else {
- mInBulkBind = false;
- if (mNeedToUpdatePageCountsAndInvalidateData) {
- updatePageCountsAndInvalidateData();
- }
- }
- }
-
- private void updatePageCountsAndInvalidateData() {
- if (mInBulkBind) {
- mNeedToUpdatePageCountsAndInvalidateData = true;
- } else {
- updatePageCounts();
- invalidateOnDataChange();
- mNeedToUpdatePageCountsAndInvalidateData = false;
- }
- }
-
- @Override
- public void onClick(View v) {
- // When we have exited all apps or are in transition, disregard clicks
- if (!mLauncher.isWidgetsViewVisible()
- || mLauncher.getWorkspace().isSwitchingState()
- || !(v instanceof PagedViewWidget)) return;
-
- // Let the user know that they have to long press to add a widget
- if (mWidgetInstructionToast != null) {
- mWidgetInstructionToast.cancel();
- }
- mWidgetInstructionToast = Toast.makeText(getContext(),R.string.long_press_widget_to_add,
- Toast.LENGTH_SHORT);
- mWidgetInstructionToast.show();
- }
-
- /*
- * PagedViewWithDraggableItems implementation
- */
- @Override
- protected void determineDraggingStart(android.view.MotionEvent ev) {
- }
-
- static Bundle getDefaultOptionsForWidget(Launcher launcher, PendingAddWidgetInfo info) {
- Bundle options = null;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- AppWidgetResizeFrame.getWidgetSizeRanges(launcher, info.spanX, info.spanY, sTmpRect);
- Rect padding = AppWidgetHostView.getDefaultPaddingForWidget(launcher,
- info.componentName, null);
-
- float density = launcher.getResources().getDisplayMetrics().density;
- int xPaddingDips = (int) ((padding.left + padding.right) / density);
- int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
-
- options = new Bundle();
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
- sTmpRect.left - xPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
- sTmpRect.top - yPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
- sTmpRect.right - xPaddingDips);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
- sTmpRect.bottom - yPaddingDips);
- }
- return options;
- }
-
- private void preloadWidget(final PendingAddWidgetInfo info) {
- final LauncherAppWidgetProviderInfo pInfo = info.info;
- final Bundle options = pInfo.isCustomWidget ? null :
- getDefaultOptionsForWidget(mLauncher, info);
-
- if (pInfo.configure != null) {
- info.bindOptions = options;
- return;
- }
-
- mWidgetCleanupState = WIDGET_PRELOAD_PENDING;
- mBindWidgetRunnable = new Runnable() {
- @Override
- public void run() {
- if (pInfo.isCustomWidget) {
- mWidgetCleanupState = WIDGET_BOUND;
- return;
- }
-
- mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
- if(AppWidgetManagerCompat.getInstance(mLauncher).bindAppWidgetIdIfAllowed(
- mWidgetLoadingId, pInfo, options)) {
- mWidgetCleanupState = WIDGET_BOUND;
- }
-
- }
- };
- post(mBindWidgetRunnable);
-
- mInflateWidgetRunnable = new Runnable() {
- @Override
- public void run() {
- if (mWidgetCleanupState != WIDGET_BOUND) {
- return;
- }
- AppWidgetHostView hostView = mLauncher.getAppWidgetHost().createView(
- getContext(), mWidgetLoadingId, pInfo);
- info.boundWidget = hostView;
- mWidgetCleanupState = WIDGET_INFLATED;
- hostView.setVisibility(INVISIBLE);
- int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(info, false);
-
- // We want the first widget layout to be the correct size. This will be important
- // for width size reporting to the AppWidgetManager.
- DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0],
- unScaledSize[1]);
- lp.x = lp.y = 0;
- lp.customPosition = true;
- hostView.setLayoutParams(lp);
- mLauncher.getDragLayer().addView(hostView);
- }
- };
- post(mInflateWidgetRunnable);
- }
-
- @Override
- public void onShortPress(View v) {
- // We are anticipating a long press, and we use this time to load bind and instantiate
- // the widget. This will need to be cleaned up if it turns out no long press occurs.
- if (mCreateWidgetInfo != null) {
- // Just in case the cleanup process wasn't properly executed. This shouldn't happen.
- cleanupWidgetPreloading(false);
- }
- mCreateWidgetInfo = new PendingAddWidgetInfo((PendingAddWidgetInfo) v.getTag());
- preloadWidget(mCreateWidgetInfo);
- }
-
- private void cleanupWidgetPreloading(boolean widgetWasAdded) {
- if (!widgetWasAdded) {
- // If the widget was not added, we may need to do further cleanup.
- PendingAddWidgetInfo info = mCreateWidgetInfo;
- mCreateWidgetInfo = null;
-
- if (mWidgetCleanupState == WIDGET_PRELOAD_PENDING) {
- // We never did any preloading, so just remove pending callbacks to do so
- removeCallbacks(mBindWidgetRunnable);
- removeCallbacks(mInflateWidgetRunnable);
- } else if (mWidgetCleanupState == WIDGET_BOUND) {
- // Delete the widget id which was allocated
- if (mWidgetLoadingId != -1 && !info.isCustomWidget()) {
- mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
- }
-
- // We never got around to inflating the widget, so remove the callback to do so.
- removeCallbacks(mInflateWidgetRunnable);
- } else if (mWidgetCleanupState == WIDGET_INFLATED) {
- // Delete the widget id which was allocated
- if (mWidgetLoadingId != -1 && !info.isCustomWidget()) {
- mLauncher.getAppWidgetHost().deleteAppWidgetId(mWidgetLoadingId);
- }
-
- // The widget was inflated and added to the DragLayer -- remove it.
- AppWidgetHostView widget = info.boundWidget;
- mLauncher.getDragLayer().removeView(widget);
- }
- }
- mWidgetCleanupState = WIDGET_NO_CLEANUP_REQUIRED;
- mWidgetLoadingId = -1;
- mCreateWidgetInfo = null;
- PagedViewWidget.resetShortPressTarget();
- }
-
- @Override
- public void cleanUpShortPress(View v) {
- if (!mDraggingWidget) {
- cleanupWidgetPreloading(false);
- }
- }
-
- private boolean beginDraggingWidget(PagedViewWidget v) {
- mDraggingWidget = true;
- // Get the widget preview as the drag representation
- ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
- PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
-
- // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
- // we abort the drag.
- if (image.getDrawable() == null) {
- mDraggingWidget = false;
- return false;
- }
-
- // Compose the drag image
- Bitmap preview;
- Bitmap outline;
- float scale = 1f;
- Point previewPadding = null;
-
- if (createItemInfo instanceof PendingAddWidgetInfo) {
- // This can happen in some weird cases involving multi-touch. We can't start dragging
- // the widget if this is null, so we break out.
- if (mCreateWidgetInfo == null) {
- return false;
- }
-
- PendingAddWidgetInfo createWidgetInfo = mCreateWidgetInfo;
- createItemInfo = createWidgetInfo;
- int[] size = mLauncher.getWorkspace().estimateItemSize(createWidgetInfo, true);
-
- FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable();
- float minScale = 1.25f;
- int maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]);
-
- int[] previewSizeBeforeScale = new int[1];
- preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.info,
- maxWidth, null, previewSizeBeforeScale);
- // Compare the size of the drag preview to the preview in the AppsCustomize tray
- int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0],
- v.getActualItemWidth());
- scale = previewWidthInAppsCustomize / (float) preview.getWidth();
-
- // The bitmap in the AppsCustomize tray is always the the same size, so there
- // might be extra pixels around the preview itself - this accounts for that
- if (previewWidthInAppsCustomize < previewDrawable.getIntrinsicWidth()) {
- int padding =
- (previewDrawable.getIntrinsicWidth() - previewWidthInAppsCustomize) / 2;
- previewPadding = new Point(padding, 0);
- }
- } else {
- PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
- Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.shortcutActivityInfo);
- preview = Utilities.createIconBitmap(icon, mLauncher);
- createItemInfo.spanX = createItemInfo.spanY = 1;
- }
-
- // Don't clip alpha values for the drag outline if we're using the default widget preview
- boolean clipAlpha = !(createItemInfo instanceof PendingAddWidgetInfo &&
- (((PendingAddWidgetInfo) createItemInfo).previewImage == 0));
-
- // Save the preview for the outline generation, then dim the preview
- outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(),
- false);
-
- // Start the drag
- mLauncher.lockScreenOrientation();
- mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, outline, clipAlpha);
- mDragController.startDrag(image, preview, this, createItemInfo,
- DragController.DRAG_ACTION_COPY, previewPadding, scale);
- outline.recycle();
- preview.recycle();
- return true;
- }
-
- @Override
- protected boolean beginDragging(final View v) {
- if (!super.beginDragging(v)) return false;
-
- if (v instanceof PagedViewWidget) {
- if (!beginDraggingWidget((PagedViewWidget) v)) {
- return false;
- }
- } else {
- Log.e(TAG, "Unexpected dragging view: " + v);
- }
-
- // We delay entering spring-loaded mode slightly to make sure the UI
- // thready is free of any work.
- postDelayed(new Runnable() {
- @Override
- public void run() {
- // We don't enter spring-loaded mode if the drag has been cancelled
- if (mLauncher.getDragController().isDragging()) {
- // Go into spring loaded mode (must happen before we startDrag())
- mLauncher.enterSpringLoadedDragMode();
- }
- }
- }, 150);
-
- return true;
- }
-
- /**
- * Clean up after dragging.
- *
- * @param target where the item was dragged to (can be null if the item was flung)
- */
- private void endDragging(View target, boolean isFlingToDelete, boolean success) {
- if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
- !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
- // Exit spring loaded mode if we have not successfully dropped or have not handled the
- // drop in Workspace
- mLauncher.exitSpringLoadedDragModeDelayed(true,
- Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
- mLauncher.unlockScreenOrientation(false);
- } else {
- mLauncher.unlockScreenOrientation(false);
- }
- }
-
- @Override
- public View getContent() {
- if (getChildCount() > 0) {
- return getChildAt(0);
- }
- return null;
- }
-
- @Override
- public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
- mInTransition = true;
- if (toWorkspace) {
- cancelAllTasks(false);
- }
- }
-
- @Override
- public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
- }
-
- @Override
- public void onLauncherTransitionStep(Launcher l, float t) {
- }
-
- @Override
- public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
- mInTransition = false;
- mForceDrawAllChildrenNextFrame = !toWorkspace;
- if (!toWorkspace) {
- loadPreviewsForPage(getNextPage());
- }
- }
-
- @Override
- public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
- boolean success) {
- // Return early and wait for onFlingToDeleteCompleted if this was the result of a fling
- if (isFlingToDelete) return;
-
- endDragging(target, false, success);
-
- // Display an error message if the drag failed due to there not being enough space on the
- // target layout we were dropping on.
- if (!success) {
- boolean showOutOfSpaceMessage = false;
- if (target instanceof Workspace) {
- int currentScreen = mLauncher.getCurrentWorkspaceScreen();
- Workspace workspace = (Workspace) target;
- CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
- ItemInfo itemInfo = (ItemInfo) d.dragInfo;
- if (layout != null) {
- layout.calculateSpans(itemInfo);
- showOutOfSpaceMessage =
- !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
- }
- }
- if (showOutOfSpaceMessage) {
- mLauncher.showOutOfSpaceMessage(false);
- }
-
- d.deferDragViewCleanupPostAnimation = false;
- }
- cleanupWidgetPreloading(success);
- mDraggingWidget = false;
- }
-
- @Override
- public void onFlingToDeleteCompleted() {
- // We just dismiss the drag when we fling, so cleanup here
- endDragging(null, true, true);
- cleanupWidgetPreloading(false);
- mDraggingWidget = false;
- }
-
- @Override
- public boolean supportsFlingToDelete() {
- return true;
- }
-
- @Override
- public boolean supportsAppInfoDropTarget() {
- return true;
- }
-
- @Override
- public boolean supportsDeleteDropTarget() {
- return false;
- }
-
- @Override
- public float getIntrinsicIconScaleFactor() {
- LauncherAppState app = LauncherAppState.getInstance();
- DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
- return (float) grid.allAppsIconSizePx / grid.iconSizePx;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- cancelAllTasks(true);
- }
-
- @Override
- public void trimMemory() {
- super.trimMemory();
- cancelAllTasks(true);
- }
-
- private void cancelAllTasks(boolean clearCompletedTasks) {
- for (int page = getPageCount() - 1; page >= 0; page--) {
- final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
- if (layout != null) {
- for (int i = 0; i < layout.getChildCount(); i++) {
- ((PagedViewWidget) layout.getChildAt(i)).deletePreview(clearCompletedTasks);
- }
- }
- }
- }
-
-
- public void setContentType(ContentType type) {
- // Widgets appear to be cleared every time you leave, always force invalidate for them
- if (mContentType != type || type == ContentType.Widgets) {
- int page = (mContentType != type) ? 0 : getCurrentPage();
- mContentType = type;
- invalidatePageData(page, true);
- }
- }
-
- public ContentType getContentType() {
- return mContentType;
- }
-
- public void setPageBackgroundsVisible(boolean visible) {
- mPageBackgroundsVisible = visible;
- int childCount = getChildCount();
- for (int i = 0; i < childCount; ++i) {
- Drawable bg = getChildAt(i).getBackground();
- if (bg != null) {
- bg.setAlpha(visible ? 255 : 0);
- }
- }
- }
-
- /*
- * Widgets PagedView implementation
- */
- private void setupPage(PagedViewGridLayout layout) {
- // Note: We force a measure here to get around the fact that when we do layout calculations
- // immediately after syncing, we don't have a proper width.
- int widthSpec = MeasureSpec.makeMeasureSpec(mContentWidth, MeasureSpec.AT_MOST);
- int heightSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.AT_MOST);
-
- Drawable bg = getContext().getResources().getDrawable(R.drawable.quantum_panel_dark);
- if (bg != null) {
- bg.setAlpha(mPageBackgroundsVisible ? 255 : 0);
- layout.setBackground(bg);
- }
- layout.measure(widthSpec, heightSpec);
- }
-
- public void syncWidgetPageItems(final int page, final boolean immediate) {
- int numItemsPerPage = mWidgetCountX * mWidgetCountY;
-
- final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
-
- // Calculate the dimensions of each cell we are giving to each widget
- final ArrayList<Object> items = new ArrayList<Object>();
- int contentWidth = mContentWidth - layout.getPaddingLeft() - layout.getPaddingRight();
- final int cellWidth = contentWidth / mWidgetCountX;
- int contentHeight = mContentHeight - layout.getPaddingTop() - layout.getPaddingBottom();
-
- final int cellHeight = contentHeight / mWidgetCountY;
-
- // Prepare the set of widgets to load previews for in the background
- int offset = page * numItemsPerPage;
- for (int i = offset; i < Math.min(offset + numItemsPerPage, mWidgets.size()); ++i) {
- items.add(mWidgets.get(i));
- }
-
- // Prepopulate the pages with the other widget info, and fill in the previews later
- layout.setColumnCount(layout.getCellCountX());
- for (int i = 0; i < items.size(); ++i) {
- Object rawInfo = items.get(i);
- PendingAddItemInfo createItemInfo = null;
- PagedViewWidget widget = (PagedViewWidget) mLayoutInflater.inflate(
- R.layout.apps_customize_widget, layout, false);
-
- if (rawInfo instanceof LauncherAppWidgetProviderInfo) {
- // Fill in the widget information
- LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) rawInfo;
- createItemInfo = new PendingAddWidgetInfo(info, null);
-
- widget.applyFromAppWidgetProviderInfo(info, -1, getWidgetPreviewLoader());
- widget.setTag(createItemInfo);
- widget.setShortPressListener(this);
- } else if (rawInfo instanceof ResolveInfo) {
- // Fill in the shortcuts information
- ResolveInfo info = (ResolveInfo) rawInfo;
- createItemInfo = new PendingAddShortcutInfo(info.activityInfo);
- createItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
- createItemInfo.componentName = new ComponentName(info.activityInfo.packageName,
- info.activityInfo.name);
- widget.applyFromResolveInfo(mPackageManager, info, getWidgetPreviewLoader());
- widget.setTag(createItemInfo);
- }
-
- widget.setOnClickListener(this);
- widget.setOnLongClickListener(this);
- widget.setOnTouchListener(this);
- widget.setOnKeyListener(mKeyListener);
-
- // Layout each widget
- int ix = i % mWidgetCountX;
- int iy = i / mWidgetCountX;
-
- if (ix > 0) {
- View border = widget.findViewById(R.id.left_border);
- border.setVisibility(View.VISIBLE);
- }
- if (ix < mWidgetCountX - 1) {
- View border = widget.findViewById(R.id.right_border);
- border.setVisibility(View.VISIBLE);
- }
-
- GridLayout.LayoutParams lp = new GridLayout.LayoutParams(
- GridLayout.spec(iy, GridLayout.START),
- GridLayout.spec(ix, GridLayout.TOP));
- lp.width = cellWidth;
- lp.height = cellHeight;
- lp.setGravity(Gravity.TOP | Gravity.START);
- layout.addView(widget, lp);
- }
-
- if (immediate && !mInTransition) {
- loadPreviewsForPage(page);
- }
- }
-
- private void loadPreviewsForPage(int page) {
- final PagedViewGridLayout layout = (PagedViewGridLayout) getPageAt(page);
-
- if (layout != null) {
- for (int i = 0; i < layout.getChildCount(); i++) {
- ((PagedViewWidget) layout.getChildAt(i)).ensurePreview();
- }
- }
- }
-
- @Override
- public void syncPages() {
- disablePagedViewAnimations();
-
- removeAllViews();
- cancelAllTasks(true);
-
- Context context = getContext();
- if (mContentType == ContentType.Widgets) {
- for (int j = 0; j < mNumWidgetPages; ++j) {
- PagedViewGridLayout layout = new PagedViewGridLayout(context, mWidgetCountX,
- mWidgetCountY);
- setupPage(layout);
- addView(layout, new PagedView.LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT));
- }
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
-
- enablePagedViewAnimations();
- }
-
- @Override
- public void syncPageItems(int page, boolean immediate) {
- if (mContentType == ContentType.Widgets) {
- syncWidgetPageItems(page, immediate);
- } else {
- Log.e(TAG, "Unexpected ContentType");
- }
- }
-
- // We want our pages to be z-ordered such that the further a page is to the left, the higher
- // it is in the z-order. This is important to insure touch events are handled correctly.
- View getPageAt(int index) {
- return getChildAt(indexToPage(index));
- }
-
- @Override
- protected int indexToPage(int index) {
- return getChildCount() - index - 1;
- }
-
- // In apps customize, we have a scrolling effect which emulates pulling cards off of a stack.
- @Override
- protected void screenScrolled(int screenCenter) {
- super.screenScrolled(screenCenter);
- enableHwLayersOnVisiblePages();
- }
-
- private void enableHwLayersOnVisiblePages() {
- final int screenCount = getChildCount();
-
- getVisiblePages(mTempVisiblePagesRange);
- int leftScreen = mTempVisiblePagesRange[0];
- int rightScreen = mTempVisiblePagesRange[1];
- int forceDrawScreen = -1;
- if (leftScreen == rightScreen) {
- // make sure we're caching at least two pages always
- if (rightScreen < screenCount - 1) {
- rightScreen++;
- forceDrawScreen = rightScreen;
- } else if (leftScreen > 0) {
- leftScreen--;
- forceDrawScreen = leftScreen;
- }
- } else {
- forceDrawScreen = leftScreen + 1;
- }
-
- for (int i = 0; i < screenCount; i++) {
- final View layout = (View) getPageAt(i);
- if (!(leftScreen <= i && i <= rightScreen &&
- (i == forceDrawScreen || shouldDrawChild(layout)))) {
- layout.setLayerType(LAYER_TYPE_NONE, null);
- }
- }
-
- for (int i = 0; i < screenCount; i++) {
- final View layout = (View) getPageAt(i);
-
- if (leftScreen <= i && i <= rightScreen &&
- (i == forceDrawScreen || shouldDrawChild(layout))) {
- if (layout.getLayerType() != LAYER_TYPE_HARDWARE) {
- layout.setLayerType(LAYER_TYPE_HARDWARE, null);
- }
- }
- }
- }
-
- protected void overScroll(float amount) {
- dampedOverScroll(amount);
- }
-
- /**
- * Used by the parent to get the content width to set the tab bar to
- * @return
- */
- public int getPageContentWidth() {
- return mContentWidth;
- }
-
- @Override
- protected void onPageEndMoving() {
- super.onPageEndMoving();
- mForceDrawAllChildrenNextFrame = true;
- // We reset the save index when we change pages so that it will be recalculated on next
- // rotation
- mSaveInstanceStateItemIndex = -1;
- }
-
- @Override
- protected void onPageBeginMoving() {
- super.onPageBeginMoving();
- if (!mInTransition) {
- getVisiblePages(sTempPosArray);
- for (int i = sTempPosArray[0]; i <= sTempPosArray[1]; i++) {
- loadPreviewsForPage(i);
- }
- }
- }
-
- /*
- * AllAppsView implementation
- */
- public void setup(Launcher launcher, DragController dragController) {
- mLauncher = launcher;
- mDragController = dragController;
- }
-
- /**
- * We should call thise method whenever the core data changes (mWidgets) so that we can
- * appropriately determine when to invalidate the PagedView page data. In cases where the data
- * has yet to be set, we can requestLayout() and wait for onDataReady() to be called in the
- * next onMeasure() pass, which will trigger an invalidatePageData() itself.
- */
- private void invalidateOnDataChange() {
- if (!isDataReady()) {
- // The next layout pass will trigger data-ready if both widgets and apps are set, so
- // request a layout to trigger the page data when ready.
- requestLayout();
- } else {
- cancelAllTasks(false);
- invalidatePageData();
- }
- }
-
- public void reset() {
- // If we have reset, then we should not continue to restore the previous state
- mSaveInstanceStateItemIndex = -1;
-
- if (mContentType != ContentType.Widgets) {
- setContentType(ContentType.Widgets);
- }
-
- if (mCurrentPage != 0) {
- invalidatePageData(0);
- }
- }
-
- private AppsCustomizeTabHost getTabHost() {
- return (AppsCustomizeTabHost) mLauncher.findViewById(R.id.apps_customize_pane);
- }
-
- public void dumpState() {
- // TODO: Dump information related to current list of Applications, Widgets, etc.
- dumpAppWidgetProviderInfoList(TAG, "mWidgets", mWidgets);
- }
-
- private void dumpAppWidgetProviderInfoList(String tag, String label,
- ArrayList<Object> list) {
- Log.d(tag, label + " size=" + list.size());
- for (Object i: list) {
- if (i instanceof AppWidgetProviderInfo) {
- AppWidgetProviderInfo info = (AppWidgetProviderInfo) i;
- Log.d(tag, " label=\"" + info.label + "\" previewImage=" + info.previewImage
- + " resizeMode=" + info.resizeMode + " configure=" + info.configure
- + " initialLayout=" + info.initialLayout
- + " minWidth=" + info.minWidth + " minHeight=" + info.minHeight);
- } else if (i instanceof ResolveInfo) {
- ResolveInfo info = (ResolveInfo) i;
- Log.d(tag, " label=\"" + info.loadLabel(mPackageManager) + "\" icon="
- + info.icon);
- }
- }
- }
-
- public void surrender() {
- // TODO: If we are in the middle of any process (ie. for holographic outlines, etc) we
- // should stop this now.
-
- // Stop all background tasks
- cancelAllTasks(true);
- }
-
- /*
- * We load an extra page on each side to prevent flashes from scrolling and loading of the
- * widget previews in the background with the AsyncTasks.
- */
- final static int sLookBehindPageCount = 2;
- final static int sLookAheadPageCount = 2;
- protected int getAssociatedLowerPageBound(int page) {
- final int count = getChildCount();
- int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1);
- int windowMinIndex = Math.max(Math.min(page - sLookBehindPageCount, count - windowSize), 0);
- return windowMinIndex;
- }
- protected int getAssociatedUpperPageBound(int page) {
- final int count = getChildCount();
- int windowSize = Math.min(count, sLookBehindPageCount + sLookAheadPageCount + 1);
- int windowMaxIndex = Math.min(Math.max(page + sLookAheadPageCount, windowSize - 1),
- count - 1);
- return windowMaxIndex;
- }
-
- protected String getCurrentPageDescription() {
- int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
- int stringId = R.string.default_scroll_format;
- int count = 0;
-
- if (mContentType == ContentType.Widgets) {
- stringId = R.string.apps_customize_widgets_scroll_format;
- count = mNumWidgetPages;
- } else {
- throw new RuntimeException("Invalid ContentType");
- }
-
- return String.format(getContext().getString(stringId), page + 1, count);
- }
-}
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
deleted file mode 100644
index 5e2f05c61..000000000
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.FrameLayout;
-
-public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable {
- static final String LOG_TAG = "AppsCustomizeTabHost";
-
- private static final String WIDGETS_TAB_TAG = "WIDGETS";
-
- private AppsCustomizePagedView mPagedView;
- private View mContent;
- private boolean mInTransition = false;
-
- private final Rect mInsets = new Rect();
-
- public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * Convenience methods to select specific tabs. We want to set the content type immediately
- * in these cases, but we note that we still call setCurrentTabByTag() so that the tab view
- * reflects the new content (but doesn't do the animation and logic associated with changing
- * tabs manually).
- */
- void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) {
- mPagedView.setContentType(type);
- }
-
- @Override
- public void setInsets(Rect insets) {
- mInsets.set(insets);
- LayoutParams flp = (LayoutParams) mContent.getLayoutParams();
- flp.topMargin = insets.top;
- flp.bottomMargin = insets.bottom;
- flp.leftMargin = insets.left;
- flp.rightMargin = insets.right;
- mContent.setLayoutParams(flp);
- }
-
- /**
- * Setup the tab host and create all necessary tabs.
- */
- @Override
- protected void onFinishInflate() {
- mPagedView = (AppsCustomizePagedView) findViewById(R.id.apps_customize_pane_content);
- mContent = findViewById(R.id.content);
- }
-
- public String getContentTag() {
- return getTabTagForContentType(mPagedView.getContentType());
- }
-
- /**
- * Returns the content view used for the launcher transitions.
- */
- public View getContentView() {
- return findViewById(R.id.apps_customize_pane_content);
- }
-
- /**
- * Returns the reveal view used for the launcher transitions.
- */
- public View getRevealView() {
- return findViewById(R.id.fake_page);
- }
-
- /**
- * Returns the page indicators view.
- */
- public View getPageIndicators() {
- return findViewById(R.id.apps_customize_page_indicator);
- }
-
- /**
- * Returns the content type for the specified tab tag.
- */
- public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
- return AppsCustomizePagedView.ContentType.Widgets;
- }
-
- /**
- * Returns the tab tag for a given content type.
- */
- public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
- return WIDGETS_TAB_TAG;
- }
-
- /**
- * Disable focus on anything under this view in the hierarchy if we are not visible.
- */
- @Override
- public int getDescendantFocusability() {
- if (getVisibility() != View.VISIBLE) {
- return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
- }
- return super.getDescendantFocusability();
- }
-
- void reset() {
- // Reset immediately
- mPagedView.reset();
- }
-
- void trimMemory() {
- mPagedView.trimMemory();
- }
-
- public void onWindowVisible() {
- if (getVisibility() == VISIBLE) {
- mContent.setVisibility(VISIBLE);
- // We unload the widget previews when the UI is hidden, so need to reload pages
- // Load the current page synchronously, and the neighboring pages asynchronously
- mPagedView.loadAssociatedPages(mPagedView.getCurrentPage(), true);
- mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
- }
- }
- @Override
- public ViewGroup getContent() {
- return mPagedView;
- }
-
- public boolean isInTransition() {
- return mInTransition;
- }
-
- /* LauncherTransitionable overrides */
- @Override
- public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
- mPagedView.onLauncherTransitionPrepare(l, animated, toWorkspace);
- mInTransition = true;
-
- if (toWorkspace) {
- // Going from All Apps -> Workspace
- setVisibilityOfSiblingsWithLowerZOrder(VISIBLE);
- } else {
- // Going from Workspace -> All Apps
- mContent.setVisibility(VISIBLE);
-
- // Make sure the current page is loaded (we start loading the side pages after the
- // transition to prevent slowing down the animation)
- // TODO: revisit this
- mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
- }
- }
-
- @Override
- public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
- mPagedView.onLauncherTransitionStart(l, animated, toWorkspace);
- }
-
- @Override
- public void onLauncherTransitionStep(Launcher l, float t) {
- mPagedView.onLauncherTransitionStep(l, t);
- }
-
- @Override
- public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
- mPagedView.onLauncherTransitionEnd(l, animated, toWorkspace);
- mInTransition = false;
-
- if (!toWorkspace) {
- // Make sure adjacent pages are loaded (we wait until after the transition to
- // prevent slowing down the animation)
- mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
-
- // Opening apps, need to announce what page we are on.
- AccessibilityManager am = (AccessibilityManager)
- getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
- if (am.isEnabled()) {
- // Notify the user when the page changes
- announceForAccessibility(mPagedView.getCurrentPageDescription());
- }
-
- // 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);
- }
- }
-
- private void setVisibilityOfSiblingsWithLowerZOrder(int visibility) {
- ViewGroup parent = (ViewGroup) getParent();
- if (parent == null) return;
-
- View appsView = ((Launcher) getContext()).getAppsView();
- View overviewPanel = ((Launcher) getContext()).getOverviewPanel();
- final int count = parent.getChildCount();
- if (!isChildrenDrawingOrderEnabled()) {
- for (int i = 0; i < count; i++) {
- final View child = parent.getChildAt(i);
- if (child == this) {
- break;
- } else {
- if (child.getVisibility() == GONE || child == overviewPanel ||
- child == appsView) {
- continue;
- }
- child.setVisibility(visibility);
- }
- }
- } else {
- throw new RuntimeException("Failed; can't get z-order of views");
- }
- }
-}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 63afa3091..f4afb954d 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -45,7 +45,6 @@ import android.util.Log;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
@@ -56,6 +55,7 @@ import android.view.animation.LayoutAnimationController;
import com.android.launcher3.FolderIcon.FolderRingAnimator;
import com.android.launcher3.LauncherAccessibilityDelegate.DragType;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PendingAddWidgetInfo;
import java.util.ArrayList;
import java.util.Arrays;
@@ -3025,7 +3025,7 @@ public class CellLayout extends ViewGroup {
*
* @return True if a vacant cell of the specified dimension was found, false otherwise.
*/
- boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
+ public boolean findCellForSpan(int[] cellXY, int spanX, int spanY) {
return findCellForSpanThatIntersectsIgnoring(cellXY, spanX, spanY, -1, -1, null, mOccupied);
}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 1f0dad221..62aa285ab 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -42,6 +42,7 @@ import android.view.animation.LinearInterpolator;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.WidgetsContainerView;
public class DeleteDropTarget extends ButtonDropTarget {
private static int DELETE_ANIMATION_DURATION = 285;
@@ -100,8 +101,9 @@ public class DeleteDropTarget extends ButtonDropTarget {
private boolean isAllAppsApplication(DragSource source, Object info) {
return source.supportsAppInfoDropTarget() && (info instanceof AppInfo);
}
- private boolean isAllAppsWidget(DragSource source, Object info) {
- if (source instanceof AppsCustomizePagedView) {
+
+ private boolean isWidget(DragSource source, Object info) {
+ if (source instanceof WidgetsContainerView) {
if (info instanceof PendingAddItemInfo) {
PendingAddItemInfo addInfo = (PendingAddItemInfo) info;
switch (addInfo.itemType) {
@@ -173,7 +175,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
// If we are dragging an application from AppsCustomize, only show the control if we can
// delete the app (it was downloaded), and rename the string to "uninstall" in such a case.
// Hide the delete target if it is a widget from AppsCustomize.
- if (!willAcceptDrop(info) || isAllAppsWidget(source, info)) {
+ if (!willAcceptDrop(info) || isWidget(source, info)) {
isVisible = false;
}
if (useUninstallLabel) {
@@ -489,13 +491,14 @@ public class DeleteDropTarget extends ButtonDropTarget {
}
public void onFlingToDelete(final DragObject d, int x, int y, PointF vel) {
- final boolean isAllApps = d.dragSource instanceof AppsCustomizePagedView;
+ final boolean isWidgets = d.dragSource instanceof WidgetsContainerView;
+ final boolean isAllapps = d.dragSource instanceof AppsContainerView;
// Don't highlight the icon as it's animating
d.dragView.setColor(0);
d.dragView.updateInitialScaleToCurrentScale();
// Don't highlight the target if we are flinging from AllApps
- if (isAllApps) {
+ if (isWidgets || isAllapps) {
resetHoverColor();
}
@@ -545,7 +548,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
public void run() {
// If we are dragging from AllApps, then we allow AppsCustomizePagedView to clean up
// itself, otherwise, complete the drop to initiate the deletion process
- if (!isAllApps) {
+ if (!isWidgets || !isAllapps) {
mLauncher.exitSpringLoadedDragMode();
completeDrop(d);
}
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 331695acc..ea2852080 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -106,8 +106,8 @@ public class DeviceProfile {
public int cellWidthPx;
public int cellHeightPx;
- int iconSizePx;
- int iconTextSizePx;
+ public int iconSizePx;
+ public int iconTextSizePx;
int iconDrawablePaddingPx;
int allAppsIconSizePx;
int allAppsIconTextSizePx;
@@ -803,64 +803,6 @@ public class DeviceProfile {
}
}
- // Layout AllApps
- AppsCustomizeTabHost host = (AppsCustomizeTabHost)
- launcher.findViewById(R.id.apps_customize_pane);
- if (host != null) {
- // Center the all apps page indicator
- int pageIndicatorHeight = (int) (pageIndicatorHeightPx * Math.min(1f,
- (allAppsIconSizePx / DynamicGrid.DEFAULT_ICON_SIZE_PX)));
- pageIndicator = host.findViewById(R.id.apps_customize_page_indicator);
- if (pageIndicator != null) {
- LinearLayout.LayoutParams lllp = (LinearLayout.LayoutParams) pageIndicator.getLayoutParams();
- lllp.width = LayoutParams.WRAP_CONTENT;
- lllp.height = pageIndicatorHeight;
- pageIndicator.setLayoutParams(lllp);
- }
-
- AppsCustomizePagedView pagedView = (AppsCustomizePagedView)
- host.findViewById(R.id.apps_customize_pane_content);
-
- FrameLayout fakePageContainer = (FrameLayout)
- host.findViewById(R.id.fake_page_container);
- FrameLayout fakePage = (FrameLayout) host.findViewById(R.id.fake_page);
-
- padding = new Rect();
- if (pagedView != null) {
- // Constrain the dimensions of all apps so that it does not span the full width
- int paddingLR = (availableWidthPx - (allAppsCellWidthPx * allAppsNumCols)) /
- (2 * (allAppsNumCols + 1));
- int paddingTB = (availableHeightPx - (allAppsCellHeightPx * allAppsNumRows)) /
- (2 * (allAppsNumRows + 1));
- paddingLR = Math.min(paddingLR, (int)((paddingLR + paddingTB) * 0.75f));
- paddingTB = Math.min(paddingTB, (int)((paddingLR + paddingTB) * 0.75f));
- int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR));
- int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2;
- // Only adjust the side paddings on landscape phones, or tablets
- if ((isTablet() || isLandscape) && gridPaddingLR > (allAppsCellWidthPx / 4)) {
- padding.left = padding.right = gridPaddingLR;
- }
-
- // The icons are centered, so we can't just offset by the page indicator height
- // because the empty space will actually be pageIndicatorHeight + paddingTB
- padding.bottom = Math.max(0, pageIndicatorHeight - paddingTB);
-
- pagedView.setWidgetsPageIndicatorPadding(pageIndicatorHeight);
- fakePage.setBackground(res.getDrawable(R.drawable.quantum_panel));
-
- // Horizontal padding for the whole paged view
- int pagedFixedViewPadding =
- res.getDimensionPixelSize(R.dimen.apps_customize_horizontal_padding);
-
- padding.left += pagedFixedViewPadding;
- padding.right += pagedFixedViewPadding;
-
- pagedView.setPadding(padding.left, padding.top, padding.right, padding.bottom);
- fakePageContainer.setPadding(padding.left, padding.top, padding.right, padding.bottom);
-
- }
- }
-
// Layout the Overview Mode
ViewGroup overviewMode = launcher.getOverviewPanel();
if (overviewMode != null) {
diff --git a/src/com/android/launcher3/DragSource.java b/src/com/android/launcher3/DragSource.java
index 7369eeac2..2a1346ef5 100644
--- a/src/com/android/launcher3/DragSource.java
+++ b/src/com/android/launcher3/DragSource.java
@@ -22,9 +22,9 @@ import com.android.launcher3.DropTarget.DragObject;
/**
* Interface defining an object that can originate a drag.
- *
*/
public interface DragSource {
+
/**
* @return whether items dragged from this source supports
*/
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index ff02bbbc3..28e923e67 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -32,7 +32,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.SparseArray;
-class FastBitmapDrawable extends Drawable {
+public class FastBitmapDrawable extends Drawable {
static final TimeInterpolator CLICK_FEEDBACK_INTERPOLATOR = new TimeInterpolator() {
@@ -72,7 +72,7 @@ class FastBitmapDrawable extends Drawable {
private boolean mPressed = false;
private ObjectAnimator mPressedAnimator;
- FastBitmapDrawable(Bitmap b) {
+ public FastBitmapDrawable(Bitmap b) {
mAlpha = 255;
mBitmap = b;
setBounds(0, 0, b.getWidth(), b.getHeight());
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index f4af7f542..f6238dab2 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -44,6 +44,7 @@ import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PackageItemInfo;
import java.util.HashMap;
import java.util.HashSet;
@@ -454,12 +455,13 @@ public class IconCache {
* Fill in {@param appInfo} with the icon and label for {@param packageName}
*/
public synchronized void getTitleAndIconForApp(
- String packageName, UserHandleCompat user, boolean useLowResIcon, AppInfo appInfoOut) {
+ String packageName, UserHandleCompat user, boolean useLowResIcon,
+ PackageItemInfo infoOut) {
CacheEntry entry = getEntryForPackageLocked(packageName, user, useLowResIcon);
- appInfoOut.iconBitmap = entry.icon;
- appInfoOut.title = entry.title;
- appInfoOut.usingLowResIcon = entry.isLowResIcon;
- appInfoOut.contentDescription = entry.contentDescription;
+ infoOut.iconBitmap = entry.icon;
+ infoOut.title = entry.title;
+ infoOut.usingLowResIcon = entry.isLowResIcon;
+ infoOut.contentDescription = entry.contentDescription;
}
public synchronized Bitmap getDefaultIcon(UserHandleCompat user) {
diff --git a/src/com/android/launcher3/Insettable.java b/src/com/android/launcher3/Insettable.java
index 1d2356c65..3b8ef2f93 100644
--- a/src/com/android/launcher3/Insettable.java
+++ b/src/com/android/launcher3/Insettable.java
@@ -18,6 +18,10 @@ package com.android.launcher3;
import android.graphics.Rect;
+/**
+ * Allows the implementing {@link View} to not draw underneath system bars.
+ * e.g., notification bar on top and home key area on the bottom.
+ */
public interface Insettable {
void setInsets(Rect insets);
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index f114de221..f7e0ea488 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -36,7 +36,7 @@ public class ItemInfo {
*/
static final String EXTRA_PROFILE = "profile";
- static final int NO_ID = -1;
+ public static final int NO_ID = -1;
/**
* The id in the settings database for this item
@@ -82,7 +82,7 @@ public class ItemInfo {
/**
* Indicates the Y cell span.
*/
- int spanY = 1;
+ public int spanY = 1;
/**
* Indicates the minimum X cell span.
@@ -107,21 +107,21 @@ public class ItemInfo {
/**
* Title of the item
*/
- CharSequence title;
+ public CharSequence title;
/**
* Content description of the item.
*/
- CharSequence contentDescription;
+ public CharSequence contentDescription;
/**
* The position of the item in a drag-and-drop operation.
*/
- int[] dropPos = null;
+ public int[] dropPos = null;
- UserHandleCompat user;
+ public UserHandleCompat user;
- ItemInfo() {
+ public ItemInfo() {
user = UserHandleCompat.myUserHandle();
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2fa2f4ad7..068934e1b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -103,6 +103,8 @@ import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.WidgetsContainerView;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -130,11 +132,11 @@ public class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
View.OnTouchListener, PageSwitchListener, LauncherProviderChangeListener,
LauncherStateTransitionAnimation.Callbacks {
- static final String TAG = "Launcher";
- static final boolean LOGD = false;
+ static final String TAG = "Launcher - MERONG";
+ static final boolean LOGD = true;
static final boolean PROFILE_STARTUP = false;
- static final boolean DEBUG_WIDGETS = false;
+ static final boolean DEBUG_WIDGETS = true;
static final boolean DEBUG_STRICT_MODE = false;
static final boolean DEBUG_RESUME_TIME = false;
static final boolean DEBUG_DUMP_LOG = false;
@@ -264,9 +266,13 @@ public class Launcher extends Activity
private View mAllAppsButton;
private SearchDropTargetBar mSearchDropTargetBar;
+
+ // Main container view for the all apps screen.
@Thunk AppsContainerView mAppsView;
- @Thunk AppsCustomizeTabHost mAppsCustomizeTabHost;
- private AppsCustomizePagedView mAppsCustomizeContent;
+
+ // Main container view for the widget tray screen.
+ private WidgetsContainerView mWidgetsView;
+
private boolean mAutoAdvanceRunning = false;
private AppWidgetHostView mQsb;
@@ -672,7 +678,7 @@ public class Launcher extends Activity
return mInflater;
}
- boolean isDraggingEnabled() {
+ public boolean isDraggingEnabled() {
// We prevent dragging when we are loading the workspace as it is possible to pick up a view
// that is subsequently removed from the workspace in startBinding().
return !mModel.isLoadingWorkspace();
@@ -1013,15 +1019,9 @@ public class Launcher extends Activity
startTimeCallbacks = System.currentTimeMillis();
}
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.setBulkBind(true);
- }
for (int i = 0; i < mBindOnResumeCallbacks.size(); i++) {
mBindOnResumeCallbacks.get(i).run();
}
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.setBulkBind(false);
- }
mBindOnResumeCallbacks.clear();
if (DEBUG_RESUME_TIME) {
Log.d(TAG, "Time spent processing callbacks in onResume: " +
@@ -1213,9 +1213,8 @@ public class Launcher extends Activity
if (mModel.isCurrentCallbacks(this)) {
mModel.stopLoader();
}
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.surrender();
- }
+ //TODO(hyunyoungs): stop the widgets loader when there is a rotation.
+
return Boolean.TRUE;
}
@@ -1336,19 +1335,6 @@ public class Launcher extends Activity
mRestoring = true;
}
- // Restore the AppsCustomize tab
- if (mAppsCustomizeTabHost != null) {
- String curTab = savedState.getString("apps_customize_currentTab");
- if (curTab != null) {
- mAppsCustomizeTabHost.setContentTypeImmediate(
- mAppsCustomizeTabHost.getContentTypeForTabTag(curTab));
- mAppsCustomizeContent.loadAssociatedPages(
- mAppsCustomizeContent.getCurrentPage());
- }
-
- int currentIndex = savedState.getInt("apps_customize_currentIndex");
- mAppsCustomizeContent.restorePageForIndex(currentIndex);
- }
mItemIdToViewId = (HashMap<Integer, Integer>)
savedState.getSerializable(RUNTIME_STATE_VIEW_IDS);
}
@@ -1434,10 +1420,7 @@ public class Launcher extends Activity
mAppsView = (AppsContainerView) findViewById(R.id.apps_view);
// Setup AppsCustomize
- mAppsCustomizeTabHost = (AppsCustomizeTabHost) findViewById(R.id.apps_customize_pane);
- mAppsCustomizeContent = (AppsCustomizePagedView)
- mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content);
- mAppsCustomizeContent.setup(this, dragController);
+ mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
// Setup the drag controller (drop targets have to be added in reverse order in priority)
dragController.setDragScoller(mWorkspace);
@@ -1651,7 +1634,7 @@ public class Launcher extends Activity
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
- if (mAppsView != null && mAppsCustomizeTabHost != null &&
+ if (mAppsView != null && mWidgetsView != null &&
mPendingAddInfo.container == ItemInfo.NO_ID) {
showWorkspace(false);
}
@@ -1735,7 +1718,6 @@ public class Launcher extends Activity
// you're in All Apps and click home to go to the workspace. onWindowVisibilityChanged
// is a more appropriate event to handle
if (mVisible) {
- mAppsCustomizeTabHost.onWindowVisible();
if (!mWorkspaceLoading) {
final ViewTreeObserver observer = mWorkspace.getViewTreeObserver();
// We want to let Launcher draw itself at least once before we force it to build
@@ -1839,7 +1821,7 @@ public class Launcher extends Activity
launcherInfo.hostView = null;
}
- void showOutOfSpaceMessage(boolean isHotseatLayout) {
+ public void showOutOfSpaceMessage(boolean isHotseatLayout) {
int strId = (isHotseatLayout ? R.string.hotseat_out_of_space : R.string.out_of_space);
Toast.makeText(this, getString(strId), Toast.LENGTH_SHORT).show();
}
@@ -1852,8 +1834,8 @@ public class Launcher extends Activity
return mAppsView;
}
- public AppsCustomizeTabHost getWidgetsView() {
- return mAppsCustomizeTabHost;
+ public WidgetsContainerView getWidgetsView() {
+ return mWidgetsView;
}
public Workspace getWorkspace() {
@@ -1946,9 +1928,9 @@ public class Launcher extends Activity
mAppsView.scrollToTop();
}
- // Reset the apps customize page
- if (!alreadyOnHome && mAppsCustomizeTabHost != null) {
- mAppsCustomizeTabHost.reset();
+ // Reset the widgets view
+ if (!alreadyOnHome && mWidgetsView != null) {
+ mWidgetsView.scrollToTop();
}
if (mLauncherCallbacks != null) {
@@ -2003,16 +1985,8 @@ public class Launcher extends Activity
outState.putLong(RUNTIME_STATE_PENDING_FOLDER_RENAME_ID, mFolderInfo.id);
}
- // Save the current AppsCustomize tab
- if (mAppsCustomizeTabHost != null) {
- AppsCustomizePagedView.ContentType type = mAppsCustomizeContent.getContentType();
- String currentTabTag = mAppsCustomizeTabHost.getTabTagForContentType(type);
- if (currentTabTag != null) {
- outState.putString("apps_customize_currentTab", currentTabTag);
- }
- int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();
- outState.putInt("apps_customize_currentIndex", currentIndex);
- }
+ // Save the current widgets tray?
+ // TODO(hyunyoungs)
outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
if (mLauncherCallbacks != null) {
@@ -3276,9 +3250,7 @@ public class Launcher extends Activity
SQLiteDatabase.releaseMemory();
// This clears all widget bitmaps from the widget tray
- if (mAppsCustomizeTabHost != null) {
- mAppsCustomizeTabHost.trimMemory();
- }
+ // TODO(hyunyoungs)
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onTrimMemory(level);
@@ -3355,15 +3327,16 @@ public class Launcher extends Activity
* Shows the widgets view.
*/
void showWidgetsView(boolean animated, boolean resetPageToZero) {
+ Log.d(TAG, "showWidgetsView:" + animated + " resetPageToZero:" + resetPageToZero);
if (resetPageToZero) {
- mAppsCustomizeTabHost.reset();
+ mWidgetsView.scrollToTop();
}
showAppsOrWidgets(animated, State.WIDGETS);
- mAppsCustomizeTabHost.post(new Runnable() {
+
+ mWidgetsView.post(new Runnable() {
@Override
public void run() {
- // We post this in-case the all apps view isn't yet constructed.
- mAppsCustomizeTabHost.requestFocus();
+ mWidgetsView.requestFocus();
}
});
}
@@ -3394,7 +3367,9 @@ public class Launcher extends Activity
.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
- void enterSpringLoadedDragMode() {
+ public void enterSpringLoadedDragMode() {
+ Log.d(TAG, String.format("enterSpringLoadedDragMode [mState=%s",
+ mState.name()));
if (mState == State.WORKSPACE || mState == State.APPS_SPRING_LOADED ||
mState == State.WIDGETS_SPRING_LOADED) {
return;
@@ -3405,7 +3380,7 @@ public class Launcher extends Activity
mState = isAppsViewVisible() ? State.APPS_SPRING_LOADED : State.WIDGETS_SPRING_LOADED;
}
- void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,
+ public void exitSpringLoadedDragModeDelayed(final boolean successfulDrop, int delay,
final Runnable onCompleteRunnable) {
if (mState != State.APPS_SPRING_LOADED && mState != State.WIDGETS_SPRING_LOADED) return;
@@ -3413,10 +3388,12 @@ public class Launcher extends Activity
@Override
public void run() {
if (successfulDrop) {
+ // TODO(hyunyoungs): verify if this hack is still needed, if not, delete.
+ //
// Before we show workspace, hide all apps again because
// exitSpringLoadedDragMode made it visible. This is a bit hacky; we should
// clean up our state transition functions
- mAppsCustomizeTabHost.setVisibility(View.GONE);
+ mWidgetsView.setVisibility(View.GONE);
showWorkspace(true, onCompleteRunnable);
} else {
exitSpringLoadedDragMode();
@@ -3918,8 +3895,8 @@ public class Launcher extends Activity
pendingInfo.spanY = item.spanY;
pendingInfo.minSpanX = item.minSpanX;
pendingInfo.minSpanY = item.minSpanY;
- Bundle options =
- AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);
+ Bundle options = null;
+ // AppsCustomizePagedView.getDefaultOptionsForWidget(this, pendingInfo);
int newWidgetId = mAppWidgetHost.allocateAppWidgetId();
boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed(
@@ -4122,9 +4099,9 @@ public class Launcher extends Activity
if (mAppsView != null) {
mAppsView.setApps(apps);
}
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.onPackagesUpdated(
- LauncherModel.getSortedWidgetsAndShortcuts(this, false /* refresh */));
+ if (mWidgetsView != null) {
+ mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
+ getPackageManager());
}
if (mLauncherCallbacks != null) {
mLauncherCallbacks.bindAllApplications(apps);
@@ -4276,15 +4253,16 @@ public class Launcher extends Activity
mWidgetsAndShortcuts = null;
}
};
+
public void bindPackagesUpdated(final ArrayList<Object> widgetsAndShortcuts) {
if (waitUntilResume(mBindPackagesUpdatedRunnable, true)) {
mWidgetsAndShortcuts = widgetsAndShortcuts;
return;
}
- // Update the widgets pane
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.onPackagesUpdated(widgetsAndShortcuts);
+ if (mWidgetsView != null) {
+ mWidgetsView.addWidgets(LauncherModel.getSortedWidgetsAndShortcuts(this, false),
+ getPackageManager());
}
}
@@ -4577,10 +4555,8 @@ public class Launcher extends Activity
Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState);
Log.d(TAG, "sFolders.size=" + sFolders.size());
mModel.dumpState();
+ // TODO(hyunyoungs): add mWidgetsView.dumpState(); or mWidgetsModel.dumpState();
- if (mAppsCustomizeContent != null) {
- mAppsCustomizeContent.dumpState();
- }
Log.d(TAG, "END launcher3 dump state");
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 2a08b8176..3bd385028 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -141,7 +141,7 @@ public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
return mModel;
}
- LauncherAccessibilityDelegate getAccessibilityDelegate() {
+ public LauncherAccessibilityDelegate getAccessibilityDelegate() {
return mAccessibilityDelegate;
}
diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
index aeef0daeb..bb4580ce7 100644
--- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
@@ -16,10 +16,10 @@ import android.os.Parcel;
public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
public boolean isCustomWidget = false;
- int spanX = -1;
- int spanY = -1;
- int minSpanX = -1;
- int minSpanY = -1;
+ public int spanX = -1;
+ public int spanY = -1;
+ public int minSpanX = -1;
+ public int minSpanY = -1;
public static LauncherAppWidgetProviderInfo fromProviderInfo(Context context,
AppWidgetProviderInfo info) {
@@ -78,10 +78,11 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
return super.loadIcon(context, cache.getFullResIconDpi());
}
- public String toString() {
+ public String toString(PackageManager pm) {
if (isCustomWidget) {
- return "LauncherAppWidgetProviderInfo(" + provider + ")";
+ return "WidgetProviderInfo(" + provider + ")";
}
- return super.toString();
+ return String.format("WidgetProviderInfo provider:%s package:%s short:%s label:%s span(%d, %d) minSpan(%d, %d)",
+ provider.toString(), provider.getPackageName(), provider.getShortClassName(), getLabel(pm), spanX, spanY, minSpanX, minSpanY);
}
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 1f36331ec..98ba09bc6 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -3628,7 +3628,7 @@ public class LauncherModel extends BroadcastReceiver
private final HashMap<Object, String> mLabelCache;
private final Collator mCollator;
- WidgetAndShortcutNameComparator(Context context) {
+ public WidgetAndShortcutNameComparator(Context context) {
mManager = AppWidgetManagerCompat.getInstance(context);
mPackageManager = context.getPackageManager();
mLabelCache = new HashMap<Object, String>();
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index d657cb50f..111de409e 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -22,7 +22,7 @@ import android.provider.BaseColumns;
/**
* Settings related utilities.
*/
-class LauncherSettings {
+public class LauncherSettings {
/** Columns required on table staht will be subject to backup and restore. */
static interface ChangeLogColumns extends BaseColumns {
/**
@@ -121,7 +121,7 @@ class LauncherSettings {
/**
* Favorites.
*/
- static final class Favorites implements BaseLauncherColumns {
+ public static final class Favorites implements BaseLauncherColumns {
/**
* The content:// style URL for this table
*/
@@ -217,12 +217,12 @@ class LauncherSettings {
/**
* The favorite is a widget
*/
- static final int ITEM_TYPE_APPWIDGET = 4;
+ public static final int ITEM_TYPE_APPWIDGET = 4;
/**
* The favorite is a custom widget provided by the launcher
*/
- static final int ITEM_TYPE_CUSTOM_APPWIDGET = 5;
+ public static final int ITEM_TYPE_CUSTOM_APPWIDGET = 5;
/**
* The favorite is a clock
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index eacf3415e..e92bfb053 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -23,6 +23,7 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.content.res.Resources;
+import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewAnimationUtils;
@@ -30,6 +31,7 @@ import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.WidgetsContainerView;
import java.util.HashMap;
@@ -179,20 +181,12 @@ public class LauncherStateTransitionAnimation {
* Starts an animation to the widgets view.
*/
public void startAnimationToWidgets(final boolean animated) {
- final AppsCustomizeTabHost toView = mLauncher.getWidgetsView();
+ final WidgetsContainerView toView = mLauncher.getWidgetsView();
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
@Override
public void onRevealViewVisible(View revealView, View contentView,
View allAppsButtonView) {
- // Hide the real page background, and swap in the fake one
- ((AppsCustomizePagedView) contentView).setPageBackgroundsVisible(false);
- revealView.setBackground(
- mLauncher.getResources().getDrawable(R.drawable.quantum_panel_dark));
- }
- @Override
- public void onAnimationComplete(View revealView, View contentView, View allAppsButtonView) {
- // Show the real page background
- ((AppsCustomizePagedView) contentView).setPageBackgroundsVisible(true);
+ revealView.setBackground(mLauncher.getDrawable(R.drawable.quantum_panel_dark));
}
@Override
public float getMaterialRevealViewFinalAlpha(View revealView) {
@@ -204,7 +198,7 @@ public class LauncherStateTransitionAnimation {
}
};
startAnimationToOverlay(Workspace.State.OVERVIEW_HIDDEN, toView, toView.getContentView(),
- toView.getRevealView(), toView.getPageIndicators(), animated, cb);
+ toView.getRevealView(), null, animated, cb);
}
/**
@@ -500,45 +494,9 @@ public class LauncherStateTransitionAnimation {
private void startAnimationToWorkspaceFromWidgets(final Launcher.State fromState,
final Workspace.State toWorkspaceState, final boolean animated,
final Runnable onCompleteRunnable) {
- AppsCustomizeTabHost widgetsView = mLauncher.getWidgetsView();
+ WidgetsContainerView widgetsView = mLauncher.getWidgetsView();
PrivateTransitionCallbacks cb = new PrivateTransitionCallbacks() {
@Override
- public void onRevealViewVisible(View revealView, View contentView, View allAppsButtonView) {
- AppsCustomizePagedView pagedView = ((AppsCustomizePagedView) contentView);
-
- // Hide the real page background, and swap in the fake one
- pagedView.stopScrolling();
- pagedView.setPageBackgroundsVisible(false);
- revealView.setBackground(
- mLauncher.getResources().getDrawable(R.drawable.quantum_panel_dark));
-
- // Hide the side pages of the Widget tray to avoid some ugly edge cases
- final View currentPage = pagedView.getPageAt(pagedView.getNextPage());
- int count = pagedView.getChildCount();
- for (int i = 0; i < count; i++) {
- View child = pagedView.getChildAt(i);
- if (child != currentPage) {
- child.setVisibility(View.INVISIBLE);
- }
- }
- }
- @Override
- public void onAnimationComplete(View revealView, View contentView, View allAppsButtonView) {
- AppsCustomizePagedView pagedView = ((AppsCustomizePagedView) contentView);
-
- // Show the real page background and force-update the page
- pagedView.setPageBackgroundsVisible(true);
- pagedView.setCurrentPage(pagedView.getNextPage());
- pagedView.updateCurrentPageScroll();
-
- // Unhide the side pages
- int count = pagedView.getChildCount();
- for (int i = 0; i < count; i++) {
- View child = pagedView.getChildAt(i);
- child.setVisibility(View.VISIBLE);
- }
- }
- @Override
public float getMaterialRevealViewFinalYDrift(View revealView) {
return revealView.getMeasuredHeight() / 2;
}
@@ -559,7 +517,7 @@ public class LauncherStateTransitionAnimation {
};
startAnimationToWorkspaceFromOverlay(toWorkspaceState, widgetsView,
widgetsView.getContentView(), widgetsView.getRevealView(),
- widgetsView.getPageIndicators(), animated, onCompleteRunnable, cb);
+ null, animated, onCompleteRunnable, cb);
}
/**
diff --git a/src/com/android/launcher3/PagedViewWithDraggableItems.java b/src/com/android/launcher3/PagedViewWithDraggableItems.java
deleted file mode 100644
index f0743cf1c..000000000
--- a/src/com/android/launcher3/PagedViewWithDraggableItems.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-
-/* Class that does most of the work of enabling dragging items out of a PagedView by performing a
- * vertical drag. Used by both CustomizePagedView and AllAppsPagedView.
- * Subclasses must do the following:
- * * call setDragSlopeThreshold after making an instance of the PagedViewWithDraggableItems
- * * call child.setOnLongClickListener(this) and child.setOnTouchListener(this) on all children
- * (good place to do it is in syncPageItems)
- * * override beginDragging(View) (but be careful to call super.beginDragging(View)
- *
- */
-public abstract class PagedViewWithDraggableItems extends PagedView
- implements View.OnLongClickListener, View.OnTouchListener {
- private View mLastTouchedItem;
- private boolean mIsDragging;
- private boolean mIsDragEnabled;
- private float mDragSlopeThreshold;
- private Launcher mLauncher;
-
- public PagedViewWithDraggableItems(Context context) {
- this(context, null);
- }
-
- public PagedViewWithDraggableItems(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public PagedViewWithDraggableItems(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mLauncher = (Launcher) context;
- }
-
- protected boolean beginDragging(View v) {
- boolean wasDragging = mIsDragging;
- mIsDragging = true;
- return !wasDragging;
- }
-
- protected void cancelDragging() {
- mIsDragging = false;
- mLastTouchedItem = null;
- mIsDragEnabled = false;
- }
-
- private void handleTouchEvent(MotionEvent ev) {
- final int action = ev.getAction();
- switch (action & MotionEvent.ACTION_MASK) {
- case MotionEvent.ACTION_DOWN:
- cancelDragging();
- mIsDragEnabled = true;
- break;
- case MotionEvent.ACTION_MOVE:
- if (mTouchState != TOUCH_STATE_SCROLLING && !mIsDragging && mIsDragEnabled) {
- determineDraggingStart(ev);
- }
- break;
- }
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- handleTouchEvent(ev);
- return super.onInterceptTouchEvent(ev);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- handleTouchEvent(ev);
- return super.onTouchEvent(ev);
- }
-
- public void trimMemory() {
- mLastTouchedItem = null;
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- mLastTouchedItem = v;
- mIsDragEnabled = true;
- return false;
- }
-
- @Override
- public boolean onLongClick(View v) {
- // Return early if this is not initiated from a touch
- if (!v.isInTouchMode()) return false;
- // Return early if we are still animating the pages
- if (mNextPage != INVALID_PAGE) return false;
- // When we have exited all apps or are in transition, disregard long clicks
- if (!mLauncher.isWidgetsViewVisible() ||
- mLauncher.getWorkspace().isSwitchingState()) return false;
- // Return if global dragging is not enabled
- if (!mLauncher.isDraggingEnabled()) return false;
-
- return beginDragging(v);
- }
-
- /*
- * Determines if we should change the touch state to start scrolling after the
- * user moves their touch point too far.
- */
- protected void determineScrollingStart(MotionEvent ev) {
- if (!mIsDragging) super.determineScrollingStart(ev);
- }
-
- /*
- * Determines if we should change the touch state to start dragging after the
- * user moves their touch point far enough.
- */
- protected void determineDraggingStart(MotionEvent ev) {
- /*
- * Locally do absolute value. mLastMotionX is set to the y value
- * of the down event.
- */
- final int pointerIndex = ev.findPointerIndex(mActivePointerId);
- final float x = ev.getX(pointerIndex);
- final float y = ev.getY(pointerIndex);
- final int xDiff = (int) Math.abs(x - mLastMotionX);
- final int yDiff = (int) Math.abs(y - mLastMotionY);
-
- final int touchSlop = mTouchSlop;
- boolean yMoved = yDiff > touchSlop;
- boolean isUpwardMotion = (yDiff / (float) xDiff) > mDragSlopeThreshold;
-
- if (isUpwardMotion && yMoved && mLastTouchedItem != null) {
- // Drag if the user moved far enough along the Y axis
- beginDragging(mLastTouchedItem);
-
- // Cancel any pending long press
- if (mAllowLongPress) {
- mAllowLongPress = false;
- // Try canceling the long press. It could also have been scheduled
- // by a distant descendant, so use the mAllowLongPress flag to block
- // everything
- final View currentPage = getPageAt(mCurrentPage);
- if (currentPage != null) {
- currentPage.cancelLongPress();
- }
- }
- }
- }
-
- public void setDragSlopeThreshold(float dragSlopeThreshold) {
- mDragSlopeThreshold = dragSlopeThreshold;
- }
-
- @Override
- protected void onDetachedFromWindow() {
- cancelDragging();
- super.onDetachedFromWindow();
- }
-}
diff --git a/src/com/android/launcher3/PendingAddItemInfo.java b/src/com/android/launcher3/PendingAddItemInfo.java
index ac54a262f..1aaf85bbd 100644
--- a/src/com/android/launcher3/PendingAddItemInfo.java
+++ b/src/com/android/launcher3/PendingAddItemInfo.java
@@ -16,93 +16,17 @@
package com.android.launcher3;
-import android.appwidget.AppWidgetHostView;
import android.content.ComponentName;
-import android.content.pm.ActivityInfo;
-import android.os.Bundle;
-import android.os.Parcelable;
/**
- * We pass this object with a drag from the customization tray
+ * Meta data that is used for deferred binding.
+ * e.g., this object is used to pass information on dragable targets when they are dropped onto
+ * the workspace from another container.
*/
-class PendingAddItemInfo extends ItemInfo {
+public class PendingAddItemInfo extends ItemInfo {
+
/**
* The component that will be created.
*/
- ComponentName componentName;
-}
-
-class PendingAddShortcutInfo extends PendingAddItemInfo {
-
- ActivityInfo shortcutActivityInfo;
-
- public PendingAddShortcutInfo(ActivityInfo activityInfo) {
- shortcutActivityInfo = activityInfo;
- }
-
- @Override
- public String toString() {
- return "Shortcut: " + shortcutActivityInfo.packageName;
- }
-}
-
-class PendingAddWidgetInfo extends PendingAddItemInfo {
- int minWidth;
- int minHeight;
- int minResizeWidth;
- int minResizeHeight;
- int previewImage;
- int icon;
- LauncherAppWidgetProviderInfo info;
- AppWidgetHostView boundWidget;
- Bundle bindOptions = null;
-
- public PendingAddWidgetInfo(LauncherAppWidgetProviderInfo i, Parcelable data) {
- if (i.isCustomWidget) {
- itemType = LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
- } else {
- itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
- }
- this.info = i;
- componentName = i.provider;
- minWidth = i.minWidth;
- minHeight = i.minHeight;
- minResizeWidth = i.minResizeWidth;
- minResizeHeight = i.minResizeHeight;
- previewImage = i.previewImage;
- icon = i.icon;
-
- spanX = i.spanX;
- spanY = i.spanY;
- minSpanX = i.minSpanX;
- minSpanY = i.minSpanY;
- }
-
- public boolean isCustomWidget() {
- return itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
- }
-
- // Copy constructor
- public PendingAddWidgetInfo(PendingAddWidgetInfo copy) {
- minWidth = copy.minWidth;
- minHeight = copy.minHeight;
- minResizeWidth = copy.minResizeWidth;
- minResizeHeight = copy.minResizeHeight;
- previewImage = copy.previewImage;
- icon = copy.icon;
- info = copy.info;
- boundWidget = copy.boundWidget;
- componentName = copy.componentName;
- itemType = copy.itemType;
- spanX = copy.spanX;
- spanY = copy.spanY;
- minSpanX = copy.minSpanX;
- minSpanY = copy.minSpanY;
- bindOptions = copy.bindOptions == null ? null : (Bundle) copy.bindOptions.clone();
- }
-
- @Override
- public String toString() {
- return "Widget: " + componentName.toShortString();
- }
+ public ComponentName componentName;
}
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 1043e2ee0..5c3ed9272 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -32,6 +32,7 @@ import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.WidgetCell;
import java.lang.ref.WeakReference;
import java.util.Collections;
@@ -45,6 +46,7 @@ import java.util.concurrent.ExecutionException;
public class WidgetPreviewLoader {
private static final String TAG = "WidgetPreviewLoader";
+ private static final boolean DEBUG = false;
private static final float WIDGET_PREVIEW_ICON_PADDING_PERCENTAGE = 0.25f;
@@ -78,7 +80,7 @@ public class WidgetPreviewLoader {
* @return a request id which can be used to cancel the request.
*/
public PreviewLoadRequest getPreview(final Object o, int previewWidth, int previewHeight,
- PagedViewWidget caller, Bitmap[] immediateResult) {
+ WidgetCell caller, Bitmap[] immediateResult) {
String size = previewWidth + "x" + previewHeight;
WidgetCacheKey key = getObjectKey(o, size);
@@ -576,21 +578,26 @@ public class WidgetPreviewLoader {
private final Object mInfo;
private final int mPreviewHeight;
private final int mPreviewWidth;
- private final PagedViewWidget mCaller;
+ private final WidgetCell mCaller;
PreviewLoadTask(WidgetCacheKey key, Object info, int previewWidth,
- int previewHeight, PagedViewWidget caller) {
+ int previewHeight, WidgetCell caller) {
mKey = key;
mInfo = info;
mPreviewHeight = previewHeight;
mPreviewWidth = previewWidth;
mCaller = caller;
+ if (DEBUG) {
+ Log.d(TAG, String.format("%s, %s, %d, %d",
+ mKey, mInfo, mPreviewHeight, mPreviewWidth));
+ }
}
-
@Override
protected Bitmap doInBackground(Void... params) {
Bitmap unusedBitmap = null;
+
+ // TODO(hyunyoungs): Figure out why this path causes concurrency issue.
synchronized (mUnusedBitmaps) {
// Check if we can use a bitmap
for (Bitmap candidate : mUnusedBitmaps) {
@@ -608,7 +615,6 @@ public class WidgetPreviewLoader {
mUnusedBitmaps.remove(unusedBitmap);
}
}
-
if (isCancelled()) {
return null;
}
diff --git a/src/com/android/launcher3/WidgetsContainerView.java b/src/com/android/launcher3/WidgetsContainerView.java
deleted file mode 100644
index 7004d8b29..000000000
--- a/src/com/android/launcher3/WidgetsContainerView.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.android.launcher3;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-
-class SectionedWidgetsRow {
- String section;
- List<List<Object>> widgets;
-
- public SectionedWidgetsRow(String sc) {
- section = sc;
- }
-}
-
-class SectionedWidgetsAlgorithm {
- public List<SectionedWidgetsRow> computeSectionedWidgetRows(List<Object> sortedWidgets,
- int widgetsPerRow) {
- List<SectionedWidgetsRow> rows = new ArrayList<>();
- LinkedHashMap<String, List<Object>> sections = computeSectionedApps(sortedWidgets);
- for (Map.Entry<String, List<Object>> sectionEntry : sections.entrySet()) {
- String section = sectionEntry.getKey();
- SectionedWidgetsRow row = new SectionedWidgetsRow(section);
- List<Object> widgets = sectionEntry.getValue();
- int numRows = (int) Math.ceil((float) widgets.size() / widgetsPerRow);
- for (int i = 0; i < numRows; i++) {
- List<Object> widgetsInRow = new ArrayList<>();
- int offset = i * widgetsPerRow;
- for (int j = 0; j < widgetsPerRow; j++) {
- widgetsInRow.add(widgets.get(offset + j));
- }
- row.widgets.add(widgetsInRow);
- }
- }
- return rows;
- }
-
- private LinkedHashMap<String, List<Object>> computeSectionedApps(List<Object> sortedWidgets) {
- LinkedHashMap<String, List<Object>> sections = new LinkedHashMap<>();
- for (Object info : sortedWidgets) {
- String section = getSection(info);
- List<Object> sectionedWidgets = sections.get(section);
- if (sectionedWidgets == null) {
- sectionedWidgets = new ArrayList<>();
- sections.put(section, sectionedWidgets);
- }
- sectionedWidgets.add(info);
- }
- return sections;
- }
-
- private String getSection(Object widgetOrShortcut) {
- return "UNKNOWN";
- }
-}
-
-/**
- * The widgets list view container.
- */
-public class WidgetsContainerView extends FrameLayout {
-
-
- public WidgetsContainerView(Context context) {
- this(context, null);
- }
-
- public WidgetsContainerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public WidgetsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void onFinishInflate() {
- }
-}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a79add05f..8cc99a044 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -71,6 +71,8 @@ import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.WallpaperUtils;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
+import com.android.launcher3.widget.PendingAddWidgetInfo;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/src/com/android/launcher3/widget/PackageItemInfo.java b/src/com/android/launcher3/widget/PackageItemInfo.java
new file mode 100644
index 000000000..d7edf2294
--- /dev/null
+++ b/src/com/android/launcher3/widget/PackageItemInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.widget;
+
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+
+import com.android.launcher3.ItemInfo;
+
+import java.util.Arrays;
+
+/**
+ * Represents a {@link Package} in the widget tray section.
+ */
+public class PackageItemInfo extends ItemInfo {
+ private static final String TAG = "PackageInfo";
+
+ /**
+ * A bitmap version of the application icon.
+ */
+ public Bitmap iconBitmap;
+
+ /**
+ * Indicates whether we're using a low res icon
+ */
+ public boolean usingLowResIcon;
+
+ public ComponentName componentName;
+
+ int flags = 0;
+
+ PackageItemInfo() {
+ }
+
+ @Override
+ public String toString() {
+ return "PackageItemInfo(title=" + title.toString() + " id=" + this.id
+ + " type=" + this.itemType + " container=" + this.container
+ + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY
+ + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos)
+ + " user=" + user + ")";
+ }
+}
diff --git a/src/com/android/launcher3/widget/PendingAddShortcutInfo.java b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
new file mode 100644
index 000000000..a56985083
--- /dev/null
+++ b/src/com/android/launcher3/widget/PendingAddShortcutInfo.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget;
+
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.PendingAddItemInfo;
+
+/**
+ * Meta data used for late binding of the short cuts.
+ *
+ * @see {@link PendingAddItemInfo}
+ */
+public class PendingAddShortcutInfo extends PendingAddItemInfo {
+
+ ActivityInfo activityInfo;
+
+ public PendingAddShortcutInfo(ActivityInfo activityInfo) {
+ this.activityInfo = activityInfo;
+ componentName = new ComponentName(activityInfo.packageName, activityInfo.name);
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("PendingAddShortcutInfo package=%s, name=%s",
+ activityInfo.packageName, activityInfo.name);
+ }
+}
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
new file mode 100644
index 000000000..db1699818
--- /dev/null
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget;
+
+import android.appwidget.AppWidgetHostView;
+import android.os.Bundle;
+import android.os.Parcelable;
+
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.PendingAddItemInfo;
+
+/**
+ * Meta data used for late binding of {@link LauncherAppWidgetProviderInfo}.
+ *
+ * @see {@link PendingAddItemInfo}
+ */
+public class PendingAddWidgetInfo extends PendingAddItemInfo {
+ public int minWidth;
+ public int minHeight;
+ public int minResizeWidth;
+ public int minResizeHeight;
+ public int previewImage;
+ public int icon;
+ public LauncherAppWidgetProviderInfo info;
+ public AppWidgetHostView boundWidget;
+ public Bundle bindOptions = null;
+
+ public PendingAddWidgetInfo(LauncherAppWidgetProviderInfo i, Parcelable data) {
+ if (i.isCustomWidget) {
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
+ } else {
+ itemType = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET;
+ }
+ this.info = i;
+ componentName = i.provider;
+ minWidth = i.minWidth;
+ minHeight = i.minHeight;
+ minResizeWidth = i.minResizeWidth;
+ minResizeHeight = i.minResizeHeight;
+ previewImage = i.previewImage;
+ icon = i.icon;
+
+ spanX = i.spanX;
+ spanY = i.spanY;
+ minSpanX = i.minSpanX;
+ minSpanY = i.minSpanY;
+ }
+
+ public boolean isCustomWidget() {
+ return itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
+ }
+
+ // Copy constructor
+ public PendingAddWidgetInfo(PendingAddWidgetInfo copy) {
+ minWidth = copy.minWidth;
+ minHeight = copy.minHeight;
+ minResizeWidth = copy.minResizeWidth;
+ minResizeHeight = copy.minResizeHeight;
+ previewImage = copy.previewImage;
+ icon = copy.icon;
+ info = copy.info;
+ boundWidget = copy.boundWidget;
+ componentName = copy.componentName;
+ itemType = copy.itemType;
+ spanX = copy.spanX;
+ spanY = copy.spanY;
+ minSpanX = copy.minSpanX;
+ minSpanY = copy.minSpanY;
+ bindOptions = copy.bindOptions == null ? null : (Bundle) copy.bindOptions.clone();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("PendingAddWidgetInfo package=%s, name=%s",
+ componentName.getPackageName(), componentName.getShortClassName());
+ }
+}
diff --git a/src/com/android/launcher3/PagedViewWidget.java b/src/com/android/launcher3/widget/WidgetCell.java
index d9ca7be87..ccd67ce41 100644
--- a/src/com/android/launcher3/PagedViewWidget.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.widget;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -23,6 +23,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
@@ -31,15 +32,31 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.WidgetPreviewLoader;
import com.android.launcher3.WidgetPreviewLoader.PreviewLoadRequest;
import com.android.launcher3.compat.AppWidgetManagerCompat;
/**
- * The linear layout used strictly for the widget/wallpaper tab of the customization tray
+ * The linear layout used strictly for the widget tray.
*/
-public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListener {
+public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
- private static PagedViewWidget sShortpressTarget = null;
+ private static final String TAG = "PagedViewWidget";
+ private static final boolean DEBUG = false;
+
+ // Temporary preset width and height of the image to keep them aligned.
+ //private static final int PRESET_PREVIEW_HEIGHT = 480;
+ //private static final int PRESET_PREVIEW_WIDTH = 480;
+
+ private int mPresetPreviewSize;
+
+ private static WidgetCell sShortpressTarget = null;
private final Rect mOriginalImagePadding = new Rect();
@@ -53,23 +70,25 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
private WidgetPreviewLoader mWidgetPreviewLoader;
private PreviewLoadRequest mActiveRequest;
- public PagedViewWidget(Context context) {
+ public WidgetCell(Context context) {
this(context, null);
}
- public PagedViewWidget(Context context, AttributeSet attrs) {
+ public WidgetCell(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public PagedViewWidget(Context context, AttributeSet attrs, int defStyle) {
+ public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
final Resources r = context.getResources();
mDimensionsFormatString = r.getString(R.string.widget_dims_format);
+ mPresetPreviewSize = r.getDimensionPixelSize(R.dimen.widget_preview_size);
setWillNotDraw(false);
setClipToPadding(false);
setAccessibilityDelegate(LauncherAppState.getInstance().getAccessibilityDelegate());
+
}
@Override
@@ -97,8 +116,11 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
@Override
protected void onDetachedFromWindow() {
+ if (DEBUG) {
+ Log.d(TAG, String.format("[tag=%s] onDetachedFromWindow", getTagToString()));
+ }
super.onDetachedFromWindow();
- deletePreview(true);
+ deletePreview(false);
}
public void deletePreview(boolean recycleImage) {
@@ -154,15 +176,19 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
public int[] getPreviewSize() {
final ImageView i = (ImageView) findViewById(R.id.widget_preview);
int[] maxSize = new int[2];
- maxSize[0] = i.getWidth() - mOriginalImagePadding.left - mOriginalImagePadding.right;
- maxSize[1] = i.getHeight() - mOriginalImagePadding.top;
+ maxSize[0] = mPresetPreviewSize;
+ maxSize[1] = mPresetPreviewSize;
return maxSize;
}
public void applyPreview(Bitmap bitmap) {
FastBitmapDrawable preview = new FastBitmapDrawable(bitmap);
- final PagedViewWidgetImageView image =
- (PagedViewWidgetImageView) findViewById(R.id.widget_preview);
+ final WidgetImageView image =
+ (WidgetImageView) findViewById(R.id.widget_preview);
+ if (DEBUG) {
+ Log.d(TAG, String.format("[tag=%s] applyPreview preview: %s",
+ getTagToString(), preview));
+ }
if (preview != null) {
image.mAllowRequestLayout = false;
image.setImageDrawable(preview);
@@ -177,6 +203,7 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
}
image.setAlpha(1f);
image.mAllowRequestLayout = true;
+ image.requestLayout();
}
}
@@ -193,8 +220,8 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
public void run() {
if (sShortpressTarget != null) return;
if (mShortPressListener != null) {
- mShortPressListener.onShortPress(PagedViewWidget.this);
- sShortpressTarget = PagedViewWidget.this;
+ mShortPressListener.onShortPress(WidgetCell.this);
+ sShortpressTarget = WidgetCell.this;
}
mShortPressTriggered = true;
}
@@ -221,7 +248,7 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
removeShortPressCallback();
if (mShortPressTriggered) {
if (mShortPressListener != null) {
- mShortPressListener.cleanUpShortPress(PagedViewWidget.this);
+ mShortPressListener.cleanUpShortPress(WidgetCell.this);
}
mShortPressTriggered = false;
}
@@ -264,6 +291,10 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
return;
}
int[] size = getPreviewSize();
+ if (DEBUG) {
+ Log.d(TAG, String.format("[tag=%s] ensurePreview (%d, %d):",
+ getTagToString(), size[0], size[1]));
+ }
if (size[0] <= 0 || size[1] <= 0) {
addOnLayoutChangeListener(this);
@@ -292,4 +323,16 @@ public class PagedViewWidget extends LinearLayout implements OnLayoutChangeListe
return Math.min(size[0], info.spanX * cellWidth);
}
+
+ /**
+ * Helper method to get the string info of the tag.
+ */
+ private String getTagToString() {
+ if (getTag() instanceof PendingAddWidgetInfo) {
+ return ((PendingAddWidgetInfo)getTag()).toString();
+ } else if (getTag() instanceof PendingAddShortcutInfo) {
+ return ((PendingAddShortcutInfo)getTag()).toString();
+ }
+ return "";
+ }
}
diff --git a/src/com/android/launcher3/PagedViewWidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java
index 7d8279547..75167bc7d 100644
--- a/src/com/android/launcher3/PagedViewWidgetImageView.java
+++ b/src/com/android/launcher3/widget/WidgetImageView.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ImageView;
-public class PagedViewWidgetImageView extends ImageView {
+public class WidgetImageView extends ImageView {
public boolean mAllowRequestLayout = true;
- public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
+ public WidgetImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -44,6 +44,5 @@ public class PagedViewWidgetImageView extends ImageView {
super.onDraw(canvas);
canvas.restore();
-
}
}
diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java
new file mode 100644
index 000000000..6580ab4ff
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetsContainerView.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.widget;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.DeleteDropTarget;
+import com.android.launcher3.DragController;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.FastBitmapDrawable;
+import com.android.launcher3.Folder;
+import com.android.launcher3.IconCache;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.PendingAddItemInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.WidgetPreviewLoader;
+import com.android.launcher3.Workspace;
+
+import java.util.ArrayList;
+
+/**
+ * The widgets list view container.
+ */
+public class WidgetsContainerView extends FrameLayout implements Insettable, View.OnTouchListener,
+ View.OnLongClickListener, DragSource{
+
+ private static final String TAG = "WidgetContainerView";
+ private static final boolean DEBUG = false;
+
+ /* {@link RecyclerView} will keep following # of views in cache, before recycling. */
+ private static final int WIDGET_CACHE_SIZE = 2;
+
+ /* Global instances that are used inside this container. */
+ private Launcher mLauncher;
+ private DragController mDragController;
+ private IconCache mIconCache;
+
+ /* Data model for the widget */
+ private WidgetsModel mWidgets;
+
+ /* Recycler view related member variables */
+ private RecyclerView mView;
+ private WidgetsListAdapter mAdapter;
+
+ /* Dragging related. */
+ private boolean mDraggingWidget = false; // TODO(hyunyoungs): seems not needed? check!
+ private Point mLastTouchDownPos = new Point();
+
+ /* Rendering related. */
+ private WidgetPreviewLoader mWidgetPreviewLoader;
+ private Rect mPadding = new Rect();
+
+ public WidgetsContainerView(Context context) {
+ this(context, null);
+ }
+
+ public WidgetsContainerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public WidgetsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public WidgetsContainerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr);
+ mLauncher = (Launcher) context;
+ mDragController = mLauncher.getDragController();
+
+ mAdapter = new WidgetsListAdapter(context, this, mLauncher, this, mLauncher);
+ mWidgets = new WidgetsModel(context, mAdapter);
+ mAdapter.setWidgetsModel(mWidgets);
+ mIconCache = (LauncherAppState.getInstance()).getIconCache();
+
+ if (DEBUG) {
+ Log.d(TAG, "WidgetsContainerView constructor");
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ if (DEBUG) {
+ Log.d(TAG, String.format("onFinishInflate [widgets size=%d]",
+ mWidgets.getPackageSize()));
+ }
+ mView = (RecyclerView) findViewById(R.id.widgets_list_view);
+ mView.setAdapter(mAdapter);
+ mView.setLayoutManager(new LinearLayoutManager(getContext()));
+ mView.setItemViewCacheSize(WIDGET_CACHE_SIZE);
+
+ mPadding.set(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+ getPaddingBottom());
+ }
+
+ //
+ // Returns views used for launcher transitions.
+ //
+
+ public View getContentView() {
+ return findViewById(R.id.widgets_list_view);
+ }
+
+ public View getRevealView() {
+ // TODO(hyunyoungs): temporarily use apps view transition.
+ return findViewById(R.id.widgets_reveal_view);
+ }
+
+ public void scrollToTop() {
+ mView.scrollToPosition(0);
+ if (DEBUG) {
+ Log.d(TAG, String.format("scrollToTop, [widgets size=%d]",
+ mWidgets.getPackageSize()));
+ }
+ }
+
+ //
+ // Touch related handling.
+ //
+
+ @Override
+ public boolean onLongClick(View v) {
+ if (DEBUG) {
+ Log.d(TAG, String.format("onLonglick [v=%s]", v));
+ }
+
+ // Return early if this is not initiated from a touch
+ if (!v.isInTouchMode()) return false;
+ // When we have exited all apps or are in transition, disregard long clicks
+ if (!mLauncher.isWidgetsViewVisible() ||
+ mLauncher.getWorkspace().isSwitchingState()) return false;
+ // Return if global dragging is not enabled
+ Log.d(TAG, String.format("onLonglick dragging enabled?.", v));
+ if (!mLauncher.isDraggingEnabled()) return false;
+
+ return beginDragging(v);
+ }
+
+ private boolean beginDragging(View v) {
+ if (v instanceof WidgetCell) {
+ if (!beginDraggingWidget((WidgetCell) v)) {
+ return false;
+ }
+ } else {
+ Log.e(TAG, "Unexpected dragging view: " + v);
+ }
+
+ // We delay entering spring-loaded mode slightly to make sure the UI
+ // thready is free of any work.
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // We don't enter spring-loaded mode if the drag has been cancelled
+ if (mLauncher.getDragController().isDragging()) {
+ // Go into spring loaded mode (must happen before we startDrag())
+ mLauncher.enterSpringLoadedDragMode();
+ }
+ }
+ }, 150);
+
+ return true;
+ }
+
+ private boolean beginDraggingWidget(WidgetCell v) {
+ mDraggingWidget = true;
+ // Get the widget preview as the drag representation
+ ImageView image = (ImageView) v.findViewById(R.id.widget_preview);
+ PendingAddItemInfo createItemInfo = (PendingAddItemInfo) v.getTag();
+
+ // If the ImageView doesn't have a drawable yet, the widget preview hasn't been loaded and
+ // we abort the drag.
+ if (image.getDrawable() == null) {
+ mDraggingWidget = false;
+ return false;
+ }
+
+ // Compose the drag image
+ Bitmap preview;
+ Bitmap outline;
+ float scale = 1f;
+ Point previewPadding = null;
+
+ if (createItemInfo instanceof PendingAddWidgetInfo) {
+ // This can happen in some weird cases involving multi-touch. We can't start dragging
+ // the widget if this is null, so we break out.
+
+ PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) createItemInfo;
+ int[] size = mLauncher.getWorkspace().estimateItemSize(createWidgetInfo, true);
+
+ FastBitmapDrawable previewDrawable = (FastBitmapDrawable) image.getDrawable();
+ float minScale = 1.25f;
+ int maxWidth = Math.min((int) (previewDrawable.getIntrinsicWidth() * minScale), size[0]);
+
+ int[] previewSizeBeforeScale = new int[1];
+ preview = getWidgetPreviewLoader().generateWidgetPreview(createWidgetInfo.info,
+ maxWidth, null, previewSizeBeforeScale);
+ // Compare the size of the drag preview to the preview in the AppsCustomize tray
+ int previewWidthInAppsCustomize = Math.min(previewSizeBeforeScale[0],
+ v.getActualItemWidth());
+ scale = previewWidthInAppsCustomize / (float) preview.getWidth();
+
+ // The bitmap in the AppsCustomize tray is always the the same size, so there
+ // might be extra pixels around the preview itself - this accounts for that
+ if (previewWidthInAppsCustomize < previewDrawable.getIntrinsicWidth()) {
+ int padding =
+ (previewDrawable.getIntrinsicWidth() - previewWidthInAppsCustomize) / 2;
+ previewPadding = new Point(padding, 0);
+ }
+ } else {
+ PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) v.getTag();
+ Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.activityInfo);
+ preview = Utilities.createIconBitmap(icon, mLauncher);
+ createItemInfo.spanX = createItemInfo.spanY = 1;
+ }
+
+ // Don't clip alpha values for the drag outline if we're using the default widget preview
+ boolean clipAlpha = !(createItemInfo instanceof PendingAddWidgetInfo &&
+ (((PendingAddWidgetInfo) createItemInfo).previewImage == 0));
+
+ // Save the preview for the outline generation, then dim the preview
+ outline = Bitmap.createScaledBitmap(preview, preview.getWidth(), preview.getHeight(),
+ false);
+
+ // Start the drag
+ mLauncher.lockScreenOrientation();
+ mLauncher.getWorkspace().onDragStartedWithItem(createItemInfo, outline, clipAlpha);
+ mDragController.startDrag(image, preview, this, createItemInfo,
+ DragController.DRAG_ACTION_COPY, previewPadding, scale);
+ outline.recycle();
+ preview.recycle();
+ return true;
+ }
+
+ /*
+ * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
+ */
+ @Override
+ public boolean onTouch(View v, MotionEvent ev) {
+ Log.d(TAG, String.format("onTouch [MotionEvent=%s]", ev));
+ if (ev.getAction() == MotionEvent.ACTION_DOWN ||
+ ev.getAction() == MotionEvent.ACTION_MOVE) {
+ mLastTouchDownPos.set((int) ev.getX(), (int) ev.getY());
+ }
+ return false;
+ }
+
+ //
+ // Drag related handling methods that implement {@link DragSource} interface.
+ //
+
+ @Override
+ public boolean supportsFlingToDelete() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsAppInfoDropTarget() {
+ return true;
+ }
+
+ /*
+ * Both this method and {@link #supportsFlingToDelete} has to return {@code false} for the
+ * {@link DeleteDropTarget} to be invisible.)
+ */
+ @Override
+ public boolean supportsDeleteDropTarget() {
+ return false;
+ }
+
+ @Override
+ public float getIntrinsicIconScaleFactor() {
+ return 0;
+ }
+
+ @Override
+ public void onFlingToDeleteCompleted() {
+ // We just dismiss the drag when we fling, so cleanup here
+ mLauncher.exitSpringLoadedDragModeDelayed(true,
+ Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
+ mLauncher.unlockScreenOrientation(false);
+ }
+
+ @Override
+ public void onDropCompleted(View target, DragObject d, boolean isFlingToDelete,
+ boolean success) {
+ if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
+ !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
+ // Exit spring loaded mode if we have not successfully dropped or have not handled the
+ // drop in Workspace
+ mLauncher.exitSpringLoadedDragModeDelayed(true,
+ Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
+ }
+ mLauncher.unlockScreenOrientation(false);
+
+ // Display an error message if the drag failed due to there not being enough space on the
+ // target layout we were dropping on.
+ if (!success) {
+ boolean showOutOfSpaceMessage = false;
+ if (target instanceof Workspace) {
+ int currentScreen = mLauncher.getCurrentWorkspaceScreen();
+ Workspace workspace = (Workspace) target;
+ CellLayout layout = (CellLayout) workspace.getChildAt(currentScreen);
+ ItemInfo itemInfo = (ItemInfo) d.dragInfo;
+ if (layout != null) {
+ layout.calculateSpans(itemInfo);
+ showOutOfSpaceMessage =
+ !layout.findCellForSpan(null, itemInfo.spanX, itemInfo.spanY);
+ }
+ }
+ if (showOutOfSpaceMessage) {
+ mLauncher.showOutOfSpaceMessage(false);
+ }
+ d.deferDragViewCleanupPostAnimation = false;
+ }
+ }
+
+ //
+ // Container rendering related.
+ //
+
+ /*
+ * @see Insettable#setInsets(Rect)
+ */
+ @Override
+ public void setInsets(Rect insets) {
+ setPadding(mPadding.left + insets.left, mPadding.top + insets.top,
+ mPadding.right + insets.right, mPadding.bottom + insets.bottom);
+ }
+
+ /**
+ * Initialize the widget data model.
+ */
+ public void addWidgets(ArrayList<Object> widgetsShortcuts, PackageManager pm) {
+ mWidgets.addWidgetsAndShortcuts(widgetsShortcuts, pm);
+ }
+
+ private WidgetPreviewLoader getWidgetPreviewLoader() {
+ if (mWidgetPreviewLoader == null) {
+ mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+ }
+ return mWidgetPreviewLoader;
+ }
+
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java
new file mode 100644
index 000000000..d0d1e60b4
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget;
+
+import android.content.Context;
+import android.content.pm.ResolveInfo;
+import android.support.v7.widget.RecyclerView.Adapter;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.R;
+import com.android.launcher3.WidgetPreviewLoader;
+import com.android.launcher3.compat.UserHandleCompat;
+
+import java.util.List;
+
+/**
+ * List view adapter for the widget tray.
+ *
+ * <p>Memory vs. Performance:
+ * The less number of types of views are inserted into a {@link RecyclerView}, the more recycling
+ * happens and less memory is consumed. {@link #getItemViewType} was not overridden as there is
+ * only a single type of view.
+ */
+public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> {
+
+ private static final String TAG = "WidgetsListAdapter";
+ private static final boolean DEBUG = false;
+
+ private Context mContext;
+ private Launcher mLauncher;
+ private LayoutInflater mLayoutInflater;
+ private IconCache mIconCache;
+
+ private WidgetsModel mWidgetsModel;
+ private WidgetPreviewLoader mWidgetPreviewLoader;
+
+ private View.OnTouchListener mTouchListener;
+ private View.OnClickListener mIconClickListener;
+ private View.OnLongClickListener mIconLongClickListener;
+
+
+ public WidgetsListAdapter(Context context,
+ View.OnTouchListener touchListener,
+ View.OnClickListener iconClickListener,
+ View.OnLongClickListener iconLongClickListener,
+ Launcher launcher) {
+ mLayoutInflater = LayoutInflater.from(context);
+ mContext = context;
+
+ mTouchListener = touchListener;
+ mIconClickListener = iconClickListener;
+ mIconLongClickListener = iconLongClickListener;
+
+ mLauncher = launcher;
+ mIconCache = LauncherAppState.getInstance().getIconCache();
+ }
+
+ public void setWidgetsModel(WidgetsModel w) {
+ mWidgetsModel = w;
+ }
+
+ @Override
+ public int getItemCount() {
+ return mWidgetsModel.getPackageSize();
+ }
+
+ @Override
+ public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) {
+ String packageName = mWidgetsModel.getPackageName(pos);
+ List<Object> infoList = mWidgetsModel.getSortedWidgets(packageName);
+
+ ViewGroup row = ((ViewGroup) holder.getContent().findViewById(R.id.widgets_cell_list));
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "onBindViewHolder [pos=%d, packageName=%s, widget#=%d, row.getChildCount=%d]",
+ pos, packageName, infoList.size(), row.getChildCount()));
+ }
+
+ // Add more views.
+ // if there are too many, hide them.
+ int diff = infoList.size() - row.getChildCount();
+ if (diff > 0) {
+ for (int i = 0; i < diff; i++) {
+ WidgetCell widget = new WidgetCell(mContext);
+ widget = (WidgetCell) mLayoutInflater.inflate(
+ R.layout.widget_cell, row, false);
+
+ // set up touch.
+ widget.setOnClickListener(mIconClickListener);
+ widget.setOnLongClickListener(mIconLongClickListener);
+ widget.setOnTouchListener(mTouchListener);
+ row.addView(widget);
+ }
+ } else if (diff < 0) {
+ for (int i=infoList.size() ; i < row.getChildCount(); i++) {
+ row.getChildAt(i).setVisibility(View.GONE);
+ }
+ }
+
+ // Bind the views in the application info section.
+ PackageItemInfo infoOut = mWidgetsModel.getPackageItemInfo(packageName);
+ if (infoOut.usingLowResIcon) {
+ mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(),
+ false /* useLowResIcon */, infoOut);
+ }
+ ((TextView) holder.getContent().findViewById(R.id.section)).setText(infoOut.title);
+ ImageView iv = (ImageView) holder.getContent().findViewById(R.id.section_image);
+ iv.setImageBitmap(infoOut.iconBitmap);
+
+ // Bind the view in the widget horizontal tray region.
+ for (int i=0; i < infoList.size(); i++) {
+ WidgetCell widget = (WidgetCell) row.getChildAt(i);
+ if (getWidgetPreviewLoader() == null || widget == null) {
+ return;
+ }
+ if (infoList.get(i) instanceof LauncherAppWidgetProviderInfo) {
+ LauncherAppWidgetProviderInfo info = (LauncherAppWidgetProviderInfo) infoList.get(i);
+ PendingAddWidgetInfo pawi = new PendingAddWidgetInfo(info, null);
+ widget.setTag(pawi);
+ widget.applyFromAppWidgetProviderInfo(info, -1, mWidgetPreviewLoader);
+ } else if (infoList.get(i) instanceof ResolveInfo) {
+ ResolveInfo info = (ResolveInfo) infoList.get(i);
+ PendingAddShortcutInfo pasi = new PendingAddShortcutInfo(info.activityInfo);
+ widget.setTag(pasi);
+ widget.applyFromResolveInfo(mLauncher.getPackageManager(), info, mWidgetPreviewLoader);
+ }
+ widget.setVisibility(View.VISIBLE);
+ widget.ensurePreview();
+ }
+ // TODO(hyunyoungs): Draw the scrollable indicator.
+ }
+
+ @Override
+ public WidgetsRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ if (DEBUG) {
+ Log.v(TAG, String.format("\nonCreateViewHolder, [widget#=%d]", viewType));
+ }
+
+ ViewGroup container = (ViewGroup) mLayoutInflater.inflate(
+ R.layout.widgets_list_row_view, parent, false);
+ return new WidgetsRowViewHolder(container);
+ }
+
+ @Override
+ public long getItemId(int pos) {
+ return pos;
+ }
+
+ private WidgetPreviewLoader getWidgetPreviewLoader() {
+ if (mWidgetPreviewLoader == null) {
+ mWidgetPreviewLoader = LauncherAppState.getInstance().getWidgetCache();
+ }
+ return mWidgetPreviewLoader;
+ }
+
+ /**
+ * TODO(hyunyoungs): this is temporary. Figure out the width of each widget cell
+ * and then check if the total sum is longer than the parent width.
+ */
+ private void addScrollableIndicator(int contentSize, ViewGroup parent) {
+ if (contentSize > 2) {
+ ViewGroup indicator = (ViewGroup) parent.findViewById(R.id.scrollable_indicator);
+ indicator.setVisibility(View.VISIBLE);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/widget/WidgetsModel.java b/src/com/android/launcher3/widget/WidgetsModel.java
new file mode 100644
index 000000000..c400d6366
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetsModel.java
@@ -0,0 +1,136 @@
+
+package com.android.launcher3.widget;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
+
+import com.android.launcher3.IconCache;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.LauncherModel.WidgetAndShortcutNameComparator;
+import com.android.launcher3.compat.UserHandleCompat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Widgets data model that is used by the adapters of the widget views and controllers.
+ *
+ * <p> The widgets and shortcuts are organized using package name as its index.
+ */
+public class WidgetsModel {
+
+ private static final String TAG = "WidgetsModel";
+ private static final boolean DEBUG = false;
+
+ /* List of packages that is tracked by this model. */
+ private List<String> mPackageNames = new ArrayList<>();
+
+ private Map<String, PackageItemInfo> mPackageItemInfoList = new HashMap<>();
+
+ /* Map of widgets and shortcuts that are tracked per package. */
+ private Map<String, ArrayList<Object>> mWidgetsList = new HashMap<>();
+
+ /* Notifies the adapter when data changes. */
+ private RecyclerView.Adapter mAdapter;
+
+ private Comparator mWidgetAndShortcutNameComparator;
+
+ private IconCache mIconCache;
+
+ public WidgetsModel(Context context, RecyclerView.Adapter adapter) {
+ mAdapter = adapter;
+ mWidgetAndShortcutNameComparator = new WidgetAndShortcutNameComparator(context);
+ mIconCache = LauncherAppState.getInstance().getIconCache();
+ }
+
+ // Access methods that may be deleted if the private fields are made package-private.
+ public int getPackageSize() {
+ return mPackageNames.size();
+ }
+
+ // Access methods that may be deleted if the private fields are made package-private.
+ public String getPackageName(int pos) {
+ return mPackageNames.get(pos);
+ }
+
+ public PackageItemInfo getPackageItemInfo(String packageName) {
+ return mPackageItemInfoList.get(packageName);
+ }
+
+ public List<Object> getSortedWidgets(String packageName) {
+ return mWidgetsList.get(packageName);
+ }
+
+ public void addWidgetsAndShortcuts(ArrayList<Object> widgetsShortcuts, PackageManager pm) {
+ if (DEBUG) {
+ Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + widgetsShortcuts.size());
+ }
+
+ // clear the lists.
+ mPackageNames.clear();
+ mWidgetsList.clear();
+
+ // add and update.
+ for (Object o: widgetsShortcuts) {
+ String packageName = "";
+ if (o instanceof LauncherAppWidgetProviderInfo) {
+ LauncherAppWidgetProviderInfo widgetInfo = (LauncherAppWidgetProviderInfo) o;
+ packageName = widgetInfo.provider.getPackageName();
+ } else if (o instanceof ResolveInfo) {
+ ResolveInfo resolveInfo = (ResolveInfo) o;
+ packageName = resolveInfo.activityInfo.packageName;
+ } else {
+ Log.e(TAG, String.format("addWidgetsAndShortcuts, nothing added for class=%s",
+ o.getClass().toString()));
+
+ }
+
+ ArrayList<Object> widgetsShortcutsList = mWidgetsList.get(packageName);
+ if (widgetsShortcutsList != null) {
+ widgetsShortcutsList.add(o);
+ } else {
+ widgetsShortcutsList = new ArrayList<Object>();
+ widgetsShortcutsList.add(o);
+ mWidgetsList.put(packageName, widgetsShortcutsList);
+ mPackageNames.add(packageName);
+ }
+ }
+ for (String packageName: mPackageNames) {
+ PackageItemInfo pInfo = mPackageItemInfoList.get(packageName);
+ if (pInfo == null) {
+ pInfo = new PackageItemInfo();
+ mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(),
+ true /* useLowResIcon */, pInfo);
+ mPackageItemInfoList.put(packageName, pInfo);
+ }
+ }
+
+ // sort.
+ sortPackageList();
+ for (String packageName: mPackageNames) {
+ Collections.sort(mWidgetsList.get(packageName), mWidgetAndShortcutNameComparator);
+ }
+
+ // notify.
+ mAdapter.notifyDataSetChanged();
+ }
+
+ private void sortPackageList() {
+ Collections.sort(mPackageNames, new Comparator<String>() {
+ @Override
+ public int compare(String lhs, String rhs) {
+ String lhsTitle = mPackageItemInfoList.get(lhs).title.toString();
+ String rhsTitle = mPackageItemInfoList.get(rhs).title.toString();
+ return lhsTitle.compareTo(rhsTitle);
+ }
+ });
+ }
+}
diff --git a/src/com/android/launcher3/PagedViewGridLayout.java b/src/com/android/launcher3/widget/WidgetsRowView.java
index f69fa562d..54667384b 100644
--- a/src/com/android/launcher3/PagedViewGridLayout.java
+++ b/src/com/android/launcher3/widget/WidgetsRowView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,36 +14,31 @@
* limitations under the License.
*/
-package com.android.launcher3;
+package com.android.launcher3.widget;
import android.content.Context;
import android.view.MotionEvent;
-import android.view.View;
import android.widget.FrameLayout;
-import android.widget.GridLayout;
+import android.widget.HorizontalScrollView;
+import android.widget.TextView;
+
+import com.android.launcher3.R;
/**
- * The grid based layout used strictly for the widget/wallpaper tab of the AppsCustomize pane
+ * Layout used for widget tray rows for each app. For performance, this view can be replaced with
+ * a {@link RecyclerView} in the future if we settle on scrollable single row for the widgets.
+ * If we decide on collapsable grid, then HorizontalScrollView can be replaced with a
+ * {@link GridLayout}.
*/
-public class PagedViewGridLayout extends GridLayout implements Page {
- static final String TAG = "PagedViewGridLayout";
+public class WidgetsRowView extends HorizontalScrollView {
+ static final String TAG = "WidgetsRow";
- private int mCellCountX;
- private int mCellCountY;
private Runnable mOnLayoutListener;
+ private String mAppName;
- public PagedViewGridLayout(Context context, int cellCountX, int cellCountY) {
+ public WidgetsRowView(Context context, String appName) {
super(context, null, 0);
- mCellCountX = cellCountX;
- mCellCountY = cellCountY;
- }
-
- int getCellCountX() {
- return mCellCountX;
- }
-
- int getCellCountY() {
- return mCellCountY;
+ mAppName = appName;
}
/**
@@ -57,6 +52,13 @@ public class PagedViewGridLayout extends GridLayout implements Page {
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ TextView tv = (TextView) findViewById(R.id.widget_name);
+ tv.setText(mAppName);
+ }
+
+ @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mOnLayoutListener = null;
@@ -66,6 +68,7 @@ public class PagedViewGridLayout extends GridLayout implements Page {
mOnLayoutListener = r;
}
+ @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mOnLayoutListener != null) {
@@ -76,43 +79,9 @@ public class PagedViewGridLayout extends GridLayout implements Page {
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = super.onTouchEvent(event);
- int count = getPageChildCount();
- if (count > 0) {
- // We only intercept the touch if we are tapping in empty space after the final row
- View child = getChildOnPageAt(count - 1);
- int bottom = child.getBottom();
- result = result || (event.getY() < bottom);
- }
return result;
}
- @Override
- public void removeAllViewsOnPage() {
- removeAllViews();
- mOnLayoutListener = null;
- setLayerType(LAYER_TYPE_NONE, null);
- }
-
- @Override
- public void removeViewOnPageAt(int index) {
- removeViewAt(index);
- }
-
- @Override
- public int getPageChildCount() {
- return getChildCount();
- }
-
- @Override
- public View getChildOnPageAt(int i) {
- return getChildAt(i);
- }
-
- @Override
- public int indexOfChildOnPage(View v) {
- return indexOfChild(v);
- }
-
public static class LayoutParams extends FrameLayout.LayoutParams {
public LayoutParams(int width, int height) {
super(width, height);
diff --git a/src/com/android/launcher3/widget/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java
new file mode 100644
index 000000000..99a192c89
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.widget;
+
+import android.support.v7.widget.RecyclerView.ViewHolder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class WidgetsRowViewHolder extends ViewHolder {
+
+ ViewGroup mContent;
+
+ public WidgetsRowViewHolder(ViewGroup v) {
+ super(v);
+ mContent = v;
+ }
+
+ ViewGroup getContent() {
+ return mContent;
+ }
+}