diff options
author | Winson Chung <winsonc@google.com> | 2011-07-13 17:25:49 -0700 |
---|---|---|
committer | Winson Chung <winsonc@google.com> | 2011-07-20 14:12:20 -0700 |
commit | 3d503fbd9468fb2b9fa645f4f7b91e11229edbfa (patch) | |
tree | 38d8bb61f62a47a731b97520a274e07cefbec20c | |
parent | ec8a2eee50290e7d9c95936041b937b6e94bb152 (diff) | |
download | packages_apps_trebuchet-3d503fbd9468fb2b9fa645f4f7b91e11229edbfa.zip packages_apps_trebuchet-3d503fbd9468fb2b9fa645f4f7b91e11229edbfa.tar.gz packages_apps_trebuchet-3d503fbd9468fb2b9fa645f4f7b91e11229edbfa.tar.bz2 |
Initial changes to add configurable hotseat.
Change-Id: I4c2ed4a1c122c057662fabc70bfef7c5c088460b
33 files changed, 707 insertions, 565 deletions
diff --git a/res/drawable-hdpi/apps_hotseat_button.png b/res/drawable-hdpi/apps_hotseat_button.png Binary files differnew file mode 100644 index 0000000..c459ba8 --- /dev/null +++ b/res/drawable-hdpi/apps_hotseat_button.png diff --git a/res/drawable-hdpi/hotseat_bg_panel.9.png b/res/drawable-hdpi/hotseat_bg_panel.9.png Binary files differnew file mode 100644 index 0000000..ae718d4 --- /dev/null +++ b/res/drawable-hdpi/hotseat_bg_panel.9.png diff --git a/res/drawable-hdpi/hotseat_scrubber_holo.9.png b/res/drawable-hdpi/hotseat_scrubber_holo.9.png Binary files differindex 3400050..3a026f8 100644 --- a/res/drawable-hdpi/hotseat_scrubber_holo.9.png +++ b/res/drawable-hdpi/hotseat_scrubber_holo.9.png diff --git a/res/drawable-hdpi/hotseat_track_holo.9.png b/res/drawable-hdpi/hotseat_track_holo.9.png Binary files differindex a058a3a..f49344f 100644 --- a/res/drawable-hdpi/hotseat_track_holo.9.png +++ b/res/drawable-hdpi/hotseat_track_holo.9.png diff --git a/res/drawable-land-hdpi/hotseat_bg_panel.9.png b/res/drawable-land-hdpi/hotseat_bg_panel.9.png Binary files differnew file mode 100644 index 0000000..6a25f46 --- /dev/null +++ b/res/drawable-land-hdpi/hotseat_bg_panel.9.png diff --git a/res/drawable-land-mdpi/hotseat_bg_panel.9.png b/res/drawable-land-mdpi/hotseat_bg_panel.9.png Binary files differnew file mode 100644 index 0000000..dbe73d4 --- /dev/null +++ b/res/drawable-land-mdpi/hotseat_bg_panel.9.png diff --git a/res/drawable-mdpi/apps_hotseat_button.png b/res/drawable-mdpi/apps_hotseat_button.png Binary files differnew file mode 100644 index 0000000..f9006a4 --- /dev/null +++ b/res/drawable-mdpi/apps_hotseat_button.png diff --git a/res/drawable-mdpi/hotseat_bg_panel.9.png b/res/drawable-mdpi/hotseat_bg_panel.9.png Binary files differnew file mode 100644 index 0000000..1074d61 --- /dev/null +++ b/res/drawable-mdpi/hotseat_bg_panel.9.png diff --git a/res/drawable-mdpi/hotseat_scrubber_holo.9.png b/res/drawable-mdpi/hotseat_scrubber_holo.9.png Binary files differindex 69f74f7..de66649 100644 --- a/res/drawable-mdpi/hotseat_scrubber_holo.9.png +++ b/res/drawable-mdpi/hotseat_scrubber_holo.9.png diff --git a/res/drawable-mdpi/hotseat_track_holo.9.png b/res/drawable-mdpi/hotseat_track_holo.9.png Binary files differindex a058a3a..3dcab67 100644 --- a/res/drawable-mdpi/hotseat_track_holo.9.png +++ b/res/drawable-mdpi/hotseat_track_holo.9.png diff --git a/res/layout-land/hotseat.xml b/res/layout-land/hotseat.xml new file mode 100644 index 0000000..79661a7 --- /dev/null +++ b/res/layout-land/hotseat.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<com.android.launcher2.Hotseat + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" + android:background="@drawable/hotseat_bg_panel" + launcher:cellCountX="1" + launcher:cellCountY="-1"> + <com.android.launcher2.CellLayout + android:id="@+id/layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingTop="@dimen/workspace_top_padding" + android:paddingBottom="@dimen/workspace_bottom_padding" + launcher:cellWidth="@dimen/workspace_cell_width" + launcher:cellHeight="@dimen/workspace_cell_height" + launcher:widthGap="-1dp" + launcher:heightGap="-1dp" + launcher:maxGap="@dimen/workspace_max_gap" /> +</com.android.launcher2.Hotseat>
\ No newline at end of file diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 428a0a7..4d40ada 100644 --- a/res/layout-land/launcher.xml +++ b/res/layout-land/launcher.xml @@ -40,8 +40,8 @@ android:id="@+id/workspace" android:layout_width="match_parent" android:layout_height="match_parent" - android:scrollbars="horizontal" - android:fadeScrollbars="true" + android:paddingLeft="@dimen/qsb_bar_height" + android:paddingRight="@dimen/button_bar_height" launcher:defaultScreen="2" launcher:cellCountX="4" launcher:cellCountY="4" @@ -66,31 +66,11 @@ android:layout_height="match_parent" android:visibility="invisible" /> - <RelativeLayout - android:id="@+id/all_apps_button_cluster" - android:layout_height="fill_parent" - android:layout_width="@dimen/button_bar_height_portrait" - android:layout_gravity="right|center_vertical" - android:layout_marginBottom="@dimen/half_status_bar_height"> - <ImageView - android:id="@+id/hotseat_left" - style="@style/HotseatButton.Left" - android:layout_below="@id/all_apps_button" - android:src="@drawable/hotseat_phone" - android:onClick="launchHotSeat" /> - <com.android.launcher2.HandleView - style="@style/HotseatButton" - android:id="@+id/all_apps_button" - android:layout_centerVertical="true" - android:layout_alignParentRight="true" - android:src="@drawable/all_apps_button" - launcher:direction="vertical" /> - <ImageView - android:id="@+id/hotseat_right" - style="@style/HotseatButton.Right" - android:layout_above="@id/all_apps_button" - android:src="@drawable/hotseat_browser" - android:onClick="launchHotSeat" /> + <include layout="@layout/hotseat" + android:id="@+id/hotseat" + android:layout_width="@dimen/button_bar_height" + android:layout_height="match_parent" + android:layout_gravity="right" /> + - </RelativeLayout> </com.android.launcher2.DragLayer> diff --git a/res/layout-land/search_bar.xml b/res/layout-land/search_bar.xml index e3f67a1..0dbfd7b 100644 --- a/res/layout-land/search_bar.xml +++ b/res/layout-land/search_bar.xml @@ -26,6 +26,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/ic_search_normal_holo" + android:adjustViewBounds="true" android:background="@drawable/button_bg" android:onClick="onClickSearchButton" android:focusable="true" @@ -47,9 +48,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/ic_voice_search_holo" + android:adjustViewBounds="true" android:background="@drawable/button_bg" android:onClick="onClickVoiceButton" android:focusable="true" android:clickable="true" android:contentDescription="@string/accessibility_voice_search_button" /> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/res/layout-port/hotseat.xml b/res/layout-port/hotseat.xml new file mode 100644 index 0000000..88dd738 --- /dev/null +++ b/res/layout-port/hotseat.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<com.android.launcher2.Hotseat + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher" + android:background="@drawable/hotseat_bg_panel" + launcher:cellCountX="-1" + launcher:cellCountY="1"> + <com.android.launcher2.CellLayout + android:id="@+id/layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/workspace_left_padding" + android:paddingRight="@dimen/workspace_right_padding" + launcher:cellWidth="@dimen/workspace_cell_width" + launcher:cellHeight="@dimen/workspace_cell_height" + launcher:widthGap="-1dp" + launcher:heightGap="-1dp" + launcher:maxGap="@dimen/workspace_max_gap" /> +</com.android.launcher2.Hotseat>
\ No newline at end of file diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index d9750db..fc39034 100644 --- a/res/layout-port/launcher.xml +++ b/res/layout-port/launcher.xml @@ -68,31 +68,12 @@ android:layout_height="match_parent" android:visibility="invisible" /> - <RelativeLayout - android:id="@+id/all_apps_button_cluster" - android:layout_width="fill_parent" + <include layout="@layout/hotseat" + android:id="@+id/hotseat" + android:layout_width="match_parent" android:layout_height="@dimen/button_bar_height" - android:layout_gravity="bottom|center_horizontal" - android:paddingTop="2dip"> - <ImageView - android:id="@+id/hotseat_left" - style="@style/HotseatButton.Left" - android:layout_toLeftOf="@id/all_apps_button" - android:src="@drawable/hotseat_phone" - android:onClick="launchHotSeat" /> - <com.android.launcher2.HandleView - style="@style/HotseatButton" - android:id="@+id/all_apps_button" - android:layout_centerHorizontal="true" - android:layout_alignParentBottom="true" - android:src="@drawable/all_apps_button" - launcher:direction="horizontal" /> - <ImageView - android:id="@+id/hotseat_right" - style="@style/HotseatButton.Right" - android:layout_toRightOf="@id/all_apps_button" - android:src="@drawable/hotseat_browser" - android:onClick="launchHotSeat" /> - </RelativeLayout> + android:layout_gravity="bottom" /> + + </com.android.launcher2.DragLayer> diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml index f9a202a..0de290a 100644 --- a/res/layout-port/search_bar.xml +++ b/res/layout-port/search_bar.xml @@ -36,7 +36,8 @@ android:id="@+id/search_button" android:layout_width="wrap_content" android:layout_height="match_parent" - android:src="@drawable/ic_search_normal_holo" /> + android:src="@drawable/ic_search_normal_holo" + android:adjustViewBounds="true" /> </LinearLayout> <!-- Voice search icon --> @@ -48,6 +49,7 @@ android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:src="@drawable/ic_voice_search_holo" + android:adjustViewBounds="true" android:background="@drawable/button_bg" android:onClick="onClickVoiceButton" android:focusable="true" diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml index 305e730..d484393 100644 --- a/res/values-land/dimens.xml +++ b/res/values-land/dimens.xml @@ -17,7 +17,7 @@ <resources> <!-- QSB --> <dimen name="toolbar_button_vertical_padding">12dip</dimen> - <dimen name="toolbar_button_horizontal_padding">12dip</dimen> + <dimen name="toolbar_button_horizontal_padding">10dip</dimen> <!-- Workspace --> <dimen name="workspace_left_padding">@dimen/qsb_bar_height</dimen> @@ -28,10 +28,6 @@ <dimen name="scroll_track_padding_left">@dimen/qsb_bar_height</dimen> <dimen name="scroll_track_padding_right">@dimen/button_bar_height</dimen> - <dimen name="folder_cell_width">100dip</dimen> - <dimen name="folder_cell_height">74dip</dimen> - <dimen name="button_bar_height">62dip</dimen> - <!-- AppsCustomize --> <dimen name="apps_customize_cell_width">80dp</dimen> <!-- The width can be 76dp because we don't have B padding --> diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml index c5fdd68..998bdc2 100644 --- a/res/values-port/dimens.xml +++ b/res/values-port/dimens.xml @@ -18,16 +18,10 @@ <!-- Workspace --> <dimen name="workspace_left_padding">0dp</dimen> <dimen name="workspace_right_padding">0dp</dimen> - <!-- NOTE: This padding is the @dimen/qsb_bar_height + some padding --> - <dimen name="workspace_top_padding">60dp</dimen> - <!-- NOTE: This padding is the @dimen/button_bar_height + some padding - for signposting --> - <dimen name="workspace_bottom_padding">64dp</dimen> + <dimen name="workspace_top_padding">@dimen/qsb_bar_height</dimen> + <dimen name="workspace_bottom_padding">@dimen/button_bar_height</dimen> <dimen name="workspace_page_spacing">8dp</dimen> - <dimen name="folder_cell_width">74dip</dimen> - <dimen name="folder_cell_height">86dip</dimen> - <integer name="apps_customize_cellCountX">4</integer> <integer name="apps_customize_cellCountY">5</integer> <dimen name="apps_customize_pageLayoutWidthGap">-1dp</dimen> diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 55518df..e093e36 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -38,6 +38,15 @@ <attr name="cellCountY" format="integer" /> </declare-styleable> + <!-- Hotseat specific attributes. These attributes are used to customize + the hotseat in XML files. --> + <declare-styleable name="Hotseat"> + <!-- The number of horizontal cells in the CellLayout --> + <attr name="cellCountX" /> + <!-- The number of vertical cells in the CellLayout --> + <attr name="cellCountY" /> + </declare-styleable> + <!-- CellLayout specific attributes. These attributes are used to customize a CellLayout view in XML files. --> <declare-styleable name="CellLayout"> @@ -125,6 +134,7 @@ <declare-styleable name="Favorite"> <attr name="className" format="string" /> <attr name="packageName" format="string" /> + <attr name="container" format="string" /> <attr name="screen" format="string" /> <attr name="x" format="string" /> <attr name="y" format="string" /> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 083a887..bcef13d 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -16,7 +16,7 @@ <resources> <!-- Workspace --> - <dimen name="qsb_bar_height">56dp</dimen> + <dimen name="qsb_bar_height">48dp</dimen> <dimen name="workspace_cell_width">80dp</dimen> <dimen name="workspace_cell_height">80dp</dimen> <dimen name="workspace_width_gap">-1dp</dimen> @@ -42,14 +42,14 @@ <dimen name="title_texture_width">120px</dimen> <!-- height of the bottom row of controls --> - <dimen name="button_bar_height">56dip</dimen> + <dimen name="button_bar_height">80dip</dimen> <!-- Drag padding to add to the drop targets --> <dimen name="drop_target_drag_padding">20dp</dimen> <!-- so we have access to this dimension in landscape mode even though button_bar_height changes --> - <dimen name="button_bar_height_portrait">56dip</dimen> + <dimen name="button_bar_height_portrait">80dip</dimen> <!-- extra horizontal spacing between mini screen thumbnails ie. in all apps and in customization mode --> diff --git a/res/values/strings.xml b/res/values/strings.xml index dcbc6d9..cae613c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -120,6 +120,8 @@ <string name="add_photo_frame">Picture frame</string> <!-- Error message when user has filled a home screen, possibly not used --> <string name="out_of_space">No more room on this Home screen.</string> + <!-- Error message when user tries to drop an invalid item on the hotseat --> + <string name="invalid_hotseat_item">This widget is too large for the hotseat.</string> <!-- Message displayed when a shortcut is created by an external application --> <string name="shortcut_installed">Shortcut \"<xliff:g id="name" example="Browser">%s</xliff:g>\" created.</string> <!-- Message displayed when a shortcut is uninstalled by an external application --> diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml index 722731c..9189c76 100644 --- a/res/xml/default_workspace.xml +++ b/res/xml/default_workspace.xml @@ -15,13 +15,19 @@ --> <favorites xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"> - <!-- Far-left screen [0] --> + <!-- Far-left screen [0] --> - <!-- Left screen [1] --> - - <!-- Middle screen [2] --> + <!-- Left screen [1] --> - <!-- Right screen [3] --> + <!-- Middle screen [2] --> + <favorite + launcher:packageName="com.google.android.camera" + launcher:className="com.android.camera.Camera" + launcher:screen="2" + launcher:x="0" + launcher:y="3" /> + + <!-- Right screen [3] --> <appwidget launcher:packageName="com.android.music" launcher:className="com.android.music.MediaAppWidgetProvider" @@ -31,6 +37,29 @@ launcher:spanX="4" launcher:spanY="1" /> - <!-- Far-right screen [4] --> + <!-- Far-right screen [4] --> + + <!-- Hotseat (We use the screen as the position of the item in the hotseat) --> + <favorite + launcher:packageName="com.android.contacts" + launcher:className="com.android.contacts.activities.DialtactsActivity" + launcher:container="-101" + launcher:screen="1" + launcher:x="0" + launcher:y="0" /> + <favorite + launcher:packageName="com.android.contacts" + launcher:className="com.android.contacts.activities.PeopleActivity" + launcher:container="-101" + launcher:screen="2" + launcher:x="0" + launcher:y="0" /> + <favorite + launcher:packageName="com.android.browser" + launcher:className="com.android.browser.BrowserActivity" + launcher:container="-101" + launcher:screen="3" + launcher:x="0" + launcher:y="0" /> </favorites> diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index ae22507..bd2a949 100644 --- a/src/com/android/launcher2/CellLayout.java +++ b/src/com/android/launcher2/CellLayout.java @@ -1863,6 +1863,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) { int spanX; int spanY; int screen; + long container; boolean valid; @Override diff --git a/src/com/android/launcher2/FocusHelper.java b/src/com/android/launcher2/FocusHelper.java index d45c9ac..2a5f9c4 100644 --- a/src/com/android/launcher2/FocusHelper.java +++ b/src/com/android/launcher2/FocusHelper.java @@ -41,13 +41,13 @@ class ButtonBarKeyEventListener implements View.OnKeyListener { } /** - * A keyboard listener we set on all the dock buttons. + * A keyboard listener we set on all the hotseat buttons. */ -class DockKeyEventListener implements View.OnKeyListener { +class HotseatKeyEventListener implements View.OnKeyListener { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { final Configuration configuration = v.getResources().getConfiguration(); - return FocusHelper.handleDockButtonKeyEvent(v, keyCode, event, configuration.orientation); + return FocusHelper.handleHotseatButtonKeyEvent(v, keyCode, event, configuration.orientation); } } @@ -535,9 +535,9 @@ public class FocusHelper { } /** - * Handles key events in the workspace dock (bottom of the screen). + * Handles key events in the workspace hotseat (bottom of the screen). */ - static boolean handleDockButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) { + static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) { final ViewGroup parent = (ViewGroup) v.getParent(); final ViewGroup launcher = (ViewGroup) parent.getParent(); final Workspace workspace = (Workspace) launcher.findViewById(R.id.workspace); @@ -547,7 +547,7 @@ public class FocusHelper { final int pageCount = workspace.getChildCount(); // NOTE: currently we don't special case for the phone UI in different - // orientations, even though the dock is on the side in landscape mode. This + // orientations, even though the hotseat is on the side in landscape mode. This // is to ensure that accessibility consistency is maintained across rotations. final int action = e.getAction(); diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java index 7641fe7..96cd22b 100644 --- a/src/com/android/launcher2/Folder.java +++ b/src/com/android/launcher2/Folder.java @@ -732,8 +732,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList int centeredTop = centerY - height / 2; // We first fetch the currently visible CellLayoutChildren - int page = mLauncher.getWorkspace().getCurrentPage(); - CellLayout currentPage = (CellLayout) mLauncher.getWorkspace().getChildAt(page); + CellLayout currentPage = mLauncher.getWorkspace().getCurrentDropLayout(); CellLayoutChildren boundingLayout = currentPage.getChildrenLayout(); Rect bounds = new Rect(); parent.getDescendantRectRelativeToSelf(boundingLayout, bounds); @@ -851,8 +850,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } // Remove the folder completely - final CellLayout cellLayout = (CellLayout) - mLauncher.getWorkspace().getChildAt(mInfo.screen); + CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen); cellLayout.removeView(mFolderIcon); if (mFolderIcon instanceof DropTarget) { mDragController.removeDropTarget((DropTarget) mFolderIcon); @@ -860,9 +858,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mLauncher.removeFolder(mInfo); if (finalItem != null) { - LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, - LauncherSettings.Favorites.CONTAINER_DESKTOP, mInfo.screen, - mInfo.cellX, mInfo.cellY); + LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, + mInfo.screen, mInfo.cellX, mInfo.cellY); } LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); @@ -871,8 +868,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList View child = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) finalItem); - mLauncher.getWorkspace().addInScreen(child, mInfo.screen, mInfo.cellX, mInfo.cellY, - mInfo.spanX, mInfo.spanY); + mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen, mInfo.cellX, + mInfo.cellY, mInfo.spanX, mInfo.spanY); } } diff --git a/src/com/android/launcher2/Hotseat.java b/src/com/android/launcher2/Hotseat.java new file mode 100644 index 0000000..deab131 --- /dev/null +++ b/src/com/android/launcher2/Hotseat.java @@ -0,0 +1,114 @@ +/* + * 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.launcher2; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.FrameLayout; + +import com.android.launcher.R; + +public class Hotseat extends FrameLayout { + static final String TAG = "Hotseat"; + + private Launcher mLauncher; + private CellLayout mContent; + + private int mCellCountX; + private int mCellCountY; + private boolean mIsLandscape; + + public Hotseat(Context context) { + this(context, null); + } + + public Hotseat(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public Hotseat(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.Hotseat, defStyle, 0); + mCellCountX = a.getInt(R.styleable.Hotseat_cellCountX, -1); + mCellCountY = a.getInt(R.styleable.Hotseat_cellCountY, -1); + mIsLandscape = context.getResources().getConfiguration().orientation == + Configuration.ORIENTATION_LANDSCAPE; + } + + public void setup(Launcher launcher) { + mLauncher = launcher; + } + + CellLayout getLayout() { + return mContent; + } + + /* Get the orientation invariant order of the item in the hotseat for persistence. */ + int getOrderInHotseat(int x, int y) { + return mIsLandscape ? (mContent.getCountY() - y - 1) : x; + } + /* Get the orientation specific coordinates given an invariant order in the hotseat. */ + int getCellXFromOrder(int rank) { + return mIsLandscape ? 0 : rank; + } + int getCellYFromOrder(int rank) { + return mIsLandscape ? (mContent.getCountY() - (rank + 1)) : 0; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + if (mCellCountX < 0) mCellCountX = LauncherModel.getCellCountX(); + if (mCellCountY < 0) mCellCountY = LauncherModel.getCellCountY(); + mContent = (CellLayout) findViewById(R.id.layout); + mContent.setGridSize(mCellCountX, mCellCountY); + + resetLayout(); + } + + void resetLayout() { + mContent.removeAllViewsInLayout(); + + // Add the Apps button + Context context = getContext(); + LayoutInflater inflater = LayoutInflater.from(context); + BubbleTextView allAppsButton = (BubbleTextView) + inflater.inflate(R.layout.application, mContent, false); + allAppsButton.setCompoundDrawablesWithIntrinsicBounds(null, + context.getResources().getDrawable(R.drawable.apps_hotseat_button), null, null); + // button.setText(context.getString(R.string.all_apps_button_label)); + allAppsButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(android.view.View v) { + mLauncher.showAllApps(true); + } + }); + + // Note: We do this to ensure that the hotseat is always laid out in the orientation of + // the hotseat in order regardless of which orientation they were added + int x = getCellXFromOrder(0); + int y = getCellYFromOrder(0); + mContent.addViewToCellLayout(allAppsButton, -1, 0, new CellLayout.LayoutParams(x,y,1,1), + true); + } +} diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java index c67e90e..9d7054c 100644 --- a/src/com/android/launcher2/InstallShortcutReceiver.java +++ b/src/com/android/launcher2/InstallShortcutReceiver.java @@ -65,7 +65,8 @@ public class InstallShortcutReceiver extends BroadcastReceiver { boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true); if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) { LauncherApplication app = (LauncherApplication) context.getApplicationContext(); - app.getModel().addShortcut(context, data, screen, mCoordinates[0], + app.getModel().addShortcut(context, data, + LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0], mCoordinates[1], true); Toast.makeText(context, context.getString(R.string.shortcut_installed, name), Toast.LENGTH_SHORT).show(); @@ -94,14 +95,16 @@ public class InstallShortcutReceiver extends BroadcastReceiver { int cellX, cellY, spanX, spanY; for (int i = 0; i < items.size(); ++i) { item = items.get(i); - if (item.screen == screen) { - cellX = item.cellX; - cellY = item.cellY; - spanX = item.spanX; - spanY = item.spanY; - for (int x = cellX; x < cellX + spanX && x < xCount; x++) { - for (int y = cellY; y < cellY + spanY && y < yCount; y++) { - occupied[x][y] = true; + if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (item.screen == screen) { + cellX = item.cellX; + cellY = item.cellY; + spanX = item.spanX; + spanY = item.spanY; + for (int x = cellX; x < cellX + spanX && x < xCount; x++) { + for (int y = cellY; y < cellY + spanY && y < yCount; y++) { + occupied[x][y] = true; + } } } } diff --git a/src/com/android/launcher2/InstallWidgetReceiver.java b/src/com/android/launcher2/InstallWidgetReceiver.java index b4ce038..6b3763c 100644 --- a/src/com/android/launcher2/InstallWidgetReceiver.java +++ b/src/com/android/launcher2/InstallWidgetReceiver.java @@ -188,7 +188,8 @@ public class InstallWidgetReceiver { final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType, mClipData); - mLauncher.addAppWidgetFromDrop(createInfo, mTargetLayoutScreen, null, mTargetLayoutPos); + mLauncher.addAppWidgetFromDrop(createInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP, + mTargetLayoutScreen, null, mTargetLayoutPos); } } } diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 26f41fa..90bd151 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -115,7 +115,6 @@ public final class Launcher extends Activity static final boolean PROFILE_STARTUP = false; static final boolean DEBUG_WIDGETS = false; - static final boolean DEBUG_USER_INTERFACE = false; private static final int MENU_GROUP_ADD = 1; private static final int MENU_GROUP_WALLPAPER = MENU_GROUP_ADD + 1; @@ -149,6 +148,8 @@ public final class Launcher extends Activity // Type: int private static final String RUNTIME_STATE = "launcher.state"; // Type: int + private static final String RUNTIME_STATE_PENDING_ADD_CONTAINER = "launcher.add_container"; + // Type: int private static final String RUNTIME_STATE_PENDING_ADD_SCREEN = "launcher.add_screen"; // Type: int private static final String RUNTIME_STATE_PENDING_ADD_CELL_X = "launcher.add_cell_x"; @@ -185,16 +186,14 @@ public final class Launcher extends Activity private AppWidgetManager mAppWidgetManager; private LauncherAppWidgetHost mAppWidgetHost; - private int mAddScreen = -1; - private int mAddCellX = -1; - private int mAddCellY = -1; - private int[] mAddDropPosition; + private ItemInfo mPendingAddInfo = new ItemInfo(); private int[] mTmpAddItemCellCoordinates = new int[2]; private FolderInfo mFolderInfo; - private ViewGroup mButtonCluster; + private Hotseat mHotseat; private View mAllAppsButton; + private SearchDropTargetBar mSearchDeleteBar; private AppsCustomizeTabHost mAppsCustomizeTabHost; private AppsCustomizePagedView mAppsCustomizeContent; @@ -259,6 +258,7 @@ public final class Launcher extends Activity private static class PendingAddArguments { int requestCode; Intent intent; + long container; int screen; int cellX; int cellY; @@ -600,20 +600,22 @@ public final class Launcher extends Activity private boolean completeAdd(PendingAddArguments args) { switch (args.requestCode) { case REQUEST_PICK_APPLICATION: - completeAddApplication(args.intent, args.screen, args.cellX, args.cellY); + completeAddApplication(args.intent, args.container, args.screen, args.cellX, + args.cellY); break; case REQUEST_PICK_SHORTCUT: processShortcut(args.intent); break; case REQUEST_CREATE_SHORTCUT: - completeAddShortcut(args.intent, args.screen, args.cellX, args.cellY); + completeAddShortcut(args.intent, args.container, args.screen, args.cellX, + args.cellY); return true; case REQUEST_PICK_APPWIDGET: addAppWidgetFromPick(args.intent); break; case REQUEST_CREATE_APPWIDGET: int appWidgetId = args.intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); - completeAddAppWidget(appWidgetId, args.screen); + completeAddAppWidget(appWidgetId, args.container, args.screen); return true; case REQUEST_PICK_WALLPAPER: // We just wanted the activity result here so we can clear mWaitingForResult @@ -632,13 +634,15 @@ public final class Launcher extends Activity // For example, the user would PICK_SHORTCUT for "Music playlist", and we // launch over to the Music app to actually CREATE_SHORTCUT. - if (resultCode == RESULT_OK && mAddScreen != -1) { + if (resultCode == RESULT_OK && mPendingAddInfo.container != ItemInfo.NO_ID && + mPendingAddInfo.screen > -1) { final PendingAddArguments args = new PendingAddArguments(); args.requestCode = requestCode; args.intent = data; - args.screen = mAddScreen; - args.cellX = mAddCellX; - args.cellY = mAddCellY; + args.container = mPendingAddInfo.container; + args.screen = mPendingAddInfo.screen; + args.cellX = mPendingAddInfo.cellX; + args.cellY = mPendingAddInfo.cellY; // If the loader is still running, defer the add until it is done. if (isWorkspaceLocked()) { @@ -797,12 +801,15 @@ public final class Launcher extends Activity mWorkspace.setCurrentPage(currentScreen); } - final int addScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1); + final long pendingAddContainer = savedState.getLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, -1); + final int pendingAddScreen = savedState.getInt(RUNTIME_STATE_PENDING_ADD_SCREEN, -1); + - if (addScreen > -1) { - mAddScreen = addScreen; - mAddCellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X); - mAddCellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y); + if (pendingAddContainer != ItemInfo.NO_ID && pendingAddScreen > -1) { + mPendingAddInfo.container = pendingAddContainer; + mPendingAddInfo.screen = pendingAddScreen; + mPendingAddInfo.cellX = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_X); + mPendingAddInfo.cellY = savedState.getInt(RUNTIME_STATE_PENDING_ADD_CELL_Y); mRestoring = true; } @@ -841,6 +848,12 @@ public final class Launcher extends Activity // Setup the drag layer mDragLayer.setup(this, dragController); + // Setup the hotseat + mHotseat = (Hotseat) findViewById(R.id.hotseat); + if (mHotseat != null) { + mHotseat.setup(this); + } + // Setup the workspace mWorkspace.setHapticFeedbackEnabled(false); mWorkspace.setOnLongClickListener(this); @@ -857,47 +870,9 @@ public final class Launcher extends Activity mAppsCustomizeTabHost.findViewById(R.id.apps_customize_pane_content); mAppsCustomizeContent.setup(this, dragController); - // Setup AppsCustomize button - mAllAppsButton = mDragLayer.findViewById(R.id.all_apps_button); - mAllAppsButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - onClickAllAppsButton(v); - } - }); - if (!LauncherApplication.isScreenLarge()) { - // Setup AppsCustomize button on the phone - HandleView handleView = (HandleView) mAllAppsButton; - handleView.setLauncher(this); - handleView.setOnLongClickListener(this); - - // Setup Hotseat - ImageView hotseatLeft = (ImageView) findViewById(R.id.hotseat_left); - hotseatLeft.setContentDescription(mHotseatLabels[0]); - hotseatLeft.setImageDrawable(mHotseatIcons[0]); - ImageView hotseatRight = (ImageView) findViewById(R.id.hotseat_right); - hotseatRight.setContentDescription(mHotseatLabels[1]); - hotseatRight.setImageDrawable(mHotseatIcons[1]); - } - - if (!LauncherApplication.isScreenLarge()) { - // Setup keylistener for button cluster - mButtonCluster = (ViewGroup) findViewById(R.id.all_apps_button_cluster); - View.OnKeyListener listener = null; - if (LauncherApplication.isScreenLarge()) { - // For tablets, AllApps lives in the button bar at the top - listener = new ButtonBarKeyEventListener(); - } else { - // For phones, AppsCustomize lives in the "dock" at the bottom - listener = new DockKeyEventListener(); - } - int buttonCount = mButtonCluster.getChildCount(); - for (int i = 0; i < buttonCount; ++i) { - mButtonCluster.getChildAt(i).setOnKeyListener(listener); - } - } - // Setup the drag controller (the drop targets have to be added in reverse order) + // Setup the drag controller (drop targets have to be added in reverse order in priority) dragController.setDragScoller(mWorkspace); dragController.setScrollView(mDragLayer); dragController.setMoveTarget(mWorkspace); @@ -907,40 +882,7 @@ public final class Launcher extends Activity } } - @SuppressWarnings({"UnusedDeclaration"}) - public void previousScreen(View v) { - if (mState != State.APPS_CUSTOMIZE) { - mWorkspace.scrollLeft(); - } - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void nextScreen(View v) { - if (mState != State.APPS_CUSTOMIZE) { - mWorkspace.scrollRight(); - } - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void launchHotSeat(View v) { - if (mState == State.APPS_CUSTOMIZE) return; - - int index = -1; - if (v.getId() == R.id.hotseat_left) { - index = 0; - } else if (v.getId() == R.id.hotseat_right) { - index = 1; - } - // reload these every tap; you never know when they might change - loadHotseats(); - if (index >= 0 && index < mHotseats.length && mHotseats[index] != null) { - startActivitySafely( - mHotseats[index], - "hotseat" - ); - } - } /** * Creates a view representing a shortcut. @@ -976,9 +918,9 @@ public final class Launcher extends Activity * @param data The intent describing the application. * @param cellInfo The position on screen where to create the shortcut. */ - void completeAddApplication(Intent data, int screen, int cellX, int cellY) { + void completeAddApplication(Intent data, long container, int screen, int cellX, int cellY) { final int[] cellXY = mTmpAddItemCellCoordinates; - final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen); + final CellLayout layout = getCellLayout(container, screen); // First we check if we already know the exact location where we want to add this item. if (cellX >= 0 && cellY >= 0) { @@ -995,7 +937,7 @@ public final class Launcher extends Activity info.setActivity(data.getComponent(), Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); info.container = ItemInfo.NO_ID; - mWorkspace.addApplicationShortcut(info, screen, cellXY[0], cellXY[1], + mWorkspace.addApplicationShortcut(info, layout, container, screen, cellXY[0], cellXY[1], isWorkspaceLocked(), cellX, cellY); } else { Log.e(TAG, "Couldn't find ActivityInfo for selected application: " + data); @@ -1008,11 +950,12 @@ public final class Launcher extends Activity * @param data The intent describing the shortcut. * @param cellInfo The position on screen where to create the shortcut. */ - private void completeAddShortcut(Intent data, int screen, int cellX, int cellY) { - final int[] cellXY = mTmpAddItemCellCoordinates; - final CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen); + private void completeAddShortcut(Intent data, long container, int screen, int cellX, + int cellY) { + int[] cellXY = mTmpAddItemCellCoordinates; + int[] touchXY = mPendingAddInfo.dropPos; + CellLayout layout = getCellLayout(container, screen); - int[] touchXY = mAddDropPosition; boolean foundCellSpan = false; // First we check if we already know the exact location where we want to add this item. @@ -1022,9 +965,7 @@ public final class Launcher extends Activity foundCellSpan = true; } else if (touchXY != null) { // when dragging and dropping, just find the closest free spot - CellLayout screenLayout = (CellLayout) mWorkspace.getChildAt(screen); - int[] result = screenLayout.findNearestVacantArea( - touchXY[0], touchXY[1], 1, 1, cellXY); + int[] result = layout.findNearestVacantArea(touchXY[0], touchXY[1], 1, 1, cellXY); foundCellSpan = (result != null); } else { foundCellSpan = layout.findCellForSpan(cellXY, 1, 1); @@ -1036,11 +977,12 @@ public final class Launcher extends Activity } final ShortcutInfo info = mModel.addShortcut( - this, data, screen, cellXY[0], cellXY[1], false); + this, data, container, screen, cellXY[0], cellXY[1], false); if (!mRestoring) { final View view = createShortcut(info); - mWorkspace.addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, isWorkspaceLocked()); + mWorkspace.addInScreen(view, container, screen, cellXY[0], cellXY[1], 1, 1, + isWorkspaceLocked()); } } @@ -1050,11 +992,11 @@ public final class Launcher extends Activity * @param appWidgetId The app widget id * @param cellInfo The position on screen where to create the widget. */ - private void completeAddAppWidget(final int appWidgetId, int screen) { + private void completeAddAppWidget(final int appWidgetId, long container, int screen) { AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); // Calculate the grid spans needed to fit this widget - CellLayout layout = (CellLayout) mWorkspace.getChildAt(screen); + CellLayout layout = getCellLayout(container, screen); // We want to account for the extra amount of padding that we are adding to the widget // to ensure that it gets the full amount of space that it has requested @@ -1070,18 +1012,16 @@ public final class Launcher extends Activity // Try finding open space on Launcher screen // We have saved the position to which the widget was dragged-- this really only matters // if we are placing widgets on a "spring-loaded" screen - final int[] cellXY = mTmpAddItemCellCoordinates; - - int[] touchXY = mAddDropPosition; + int[] cellXY = mTmpAddItemCellCoordinates; + int[] touchXY = mPendingAddInfo.dropPos; boolean foundCellSpan = false; - if (mAddCellX >= 0 && mAddCellY >= 0) { - cellXY[0] = mAddCellX; - cellXY[1] = mAddCellY; + if (mPendingAddInfo.cellX >= 0 && mPendingAddInfo.cellY >= 0) { + cellXY[0] = mPendingAddInfo.cellX; + cellXY[1] = mPendingAddInfo.cellY; foundCellSpan = true; } else if (touchXY != null) { // when dragging and dropping, just find the closest free spot - CellLayout screenLayout = (CellLayout) mWorkspace.getChildAt(screen); - int[] result = screenLayout.findNearestVacantArea( + int[] result = layout.findNearestVacantArea( touchXY[0], touchXY[1], spanXY[0], spanXY[1], cellXY); foundCellSpan = (result != null); } else { @@ -1108,8 +1048,7 @@ public final class Launcher extends Activity launcherInfo.spanY = spanXY[1]; LauncherModel.addItemToDatabase(this, launcherInfo, - LauncherSettings.Favorites.CONTAINER_DESKTOP, - screen, cellXY[0], cellXY[1], false); + container, screen, cellXY[0], cellXY[1], false); if (!mRestoring) { // Perform actual inflation because we're live @@ -1118,7 +1057,7 @@ public final class Launcher extends Activity launcherInfo.hostView.setAppWidget(appWidgetId, appWidgetInfo); launcherInfo.hostView.setTag(launcherInfo); - mWorkspace.addInScreen(launcherInfo.hostView, screen, cellXY[0], cellXY[1], + mWorkspace.addInScreen(launcherInfo.hostView, container, screen, cellXY[0], cellXY[1], launcherInfo.spanX, launcherInfo.spanY, isWorkspaceLocked()); addWidgetToAutoAdvanceIfNeeded(launcherInfo.hostView, appWidgetInfo); @@ -1331,10 +1270,12 @@ public final class Launcher extends Activity // this state is reflected. closeFolder(); - if (mAddScreen > -1 && mWaitingForResult) { - outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, mAddScreen); - outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mAddCellX); - outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mAddCellY); + if (mPendingAddInfo.container != ItemInfo.NO_ID && mPendingAddInfo.screen > -1 && + mWaitingForResult) { + outState.putLong(RUNTIME_STATE_PENDING_ADD_CONTAINER, mPendingAddInfo.container); + outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, mPendingAddInfo.screen); + outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_X, mPendingAddInfo.cellX); + outState.putInt(RUNTIME_STATE_PENDING_ADD_CELL_Y, mPendingAddInfo.cellY); } if (mFolderInfo != null && mWaitingForResult) { @@ -1372,7 +1313,7 @@ public final class Launcher extends Activity TextKeyListener.getInstance().release(); - unbindWorkspaceItems(); + unbindWorkspaceAndHotseatItems(); getContentResolver().unregisterContentObserver(mWidgetObserver); unregisterReceiver(mCloseSystemDialogsReceiver); @@ -1507,10 +1448,11 @@ public final class Launcher extends Activity } private void resetAddInfo() { - mAddScreen = -1; - mAddCellX = -1; - mAddCellY = -1; - mAddDropPosition = null; + mPendingAddInfo.container = ItemInfo.NO_ID; + mPendingAddInfo.screen = -1; + mPendingAddInfo.cellX = mPendingAddInfo.cellY = -1; + mPendingAddInfo.spanX = mPendingAddInfo.spanY = -1; + mPendingAddInfo.dropPos = null; } private void manageApps() { @@ -1566,7 +1508,7 @@ public final class Launcher extends Activity startActivityForResultSafely(intent, REQUEST_CREATE_APPWIDGET); } else { // Otherwise just add it - completeAddAppWidget(appWidgetId, mAddScreen); + completeAddAppWidget(appWidgetId, info.container, info.screen); // Exit spring loaded mode if necessary after adding the widget exitSpringLoadedDragModeDelayed(false); @@ -1581,14 +1523,16 @@ public final class Launcher extends Activity * @param cell The cell it should be added to, optional * @param position The location on the screen where it was dropped, optional */ - void processShortcutFromDrop(ComponentName componentName, int screen, int[] cell, int[] loc) { + void processShortcutFromDrop(ComponentName componentName, long container, int screen, + int[] cell, int[] loc) { resetAddInfo(); - mAddScreen = screen; - mAddDropPosition = loc; + mPendingAddInfo.container = container; + mPendingAddInfo.screen = screen; + mPendingAddInfo.dropPos = loc; if (cell != null) { - mAddCellX = cell[0]; - mAddCellY = cell[1]; + mPendingAddInfo.cellX = cell[0]; + mPendingAddInfo.cellY = cell[1]; } Intent createShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT); @@ -1604,14 +1548,15 @@ public final class Launcher extends Activity * @param cell The cell it should be added to, optional * @param position The location on the screen where it was dropped, optional */ - void addAppWidgetFromDrop(PendingAddWidgetInfo info, int screen, int[] cell, int[] loc) { + void addAppWidgetFromDrop(PendingAddWidgetInfo info, long container, int screen, + int[] cell, int[] loc) { resetAddInfo(); - mAddScreen = screen; - mAddDropPosition = loc; - + mPendingAddInfo.container = info.container = container; + mPendingAddInfo.screen = info.screen = screen; + mPendingAddInfo.dropPos = loc; if (cell != null) { - mAddCellX = cell[0]; - mAddCellY = cell[1]; + mPendingAddInfo.cellX = cell[0]; + mPendingAddInfo.cellY = cell[1]; } int appWidgetId = getAppWidgetHost().allocateAppWidgetId(); @@ -1641,21 +1586,21 @@ public final class Launcher extends Activity startActivityForResult(intent, REQUEST_PICK_WALLPAPER); } - FolderIcon addFolder(final int screen, int cellX, int cellY) { + FolderIcon addFolder(CellLayout layout, long container, final int screen, int cellX, + int cellY) { final FolderInfo folderInfo = new FolderInfo(); folderInfo.title = getText(R.string.folder_name); // Update the model - LauncherModel.addItemToDatabase(Launcher.this, folderInfo, - LauncherSettings.Favorites.CONTAINER_DESKTOP, - screen, cellX, cellY, false); + LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screen, cellX, cellY, + false); sFolders.put(folderInfo.id, folderInfo); // Create the view - FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, - (ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), - folderInfo, mIconCache); - mWorkspace.addInScreen(newFolder, screen, cellX, cellY, 1, 1, isWorkspaceLocked()); + FolderIcon newFolder = + FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo, mIconCache); + mWorkspace.addInScreen(newFolder, container, screen, cellX, cellY, 1, 1, + isWorkspaceLocked()); return newFolder; } @@ -1753,8 +1698,7 @@ public final class Launcher extends Activity ViewGroup parent = (ViewGroup) folder.getParent().getParent(); if (parent != null) { - CellLayout cl = (CellLayout) mWorkspace.getChildAt(folder.mInfo.screen); - FolderIcon fi = (FolderIcon) cl.getChildAt(folder.mInfo.cellX, folder.mInfo.cellY); + FolderIcon fi = (FolderIcon) mWorkspace.getViewForTag(folder.mInfo); shrinkAndFadeInFolderIcon(fi); mDragController.removeDropTarget((DropTarget)folder); } @@ -1774,7 +1718,7 @@ public final class Launcher extends Activity * Go through the and disconnect any of the callbacks in the drawables and the views or we * leak the previous Home screen on orientation change. */ - private void unbindWorkspaceItems() { + private void unbindWorkspaceAndHotseatItems() { LauncherModel.unbindWorkspaceItems(); } @@ -1995,16 +1939,6 @@ public final class Launcher extends Activity return false; } - switch (v.getId()) { - case R.id.all_apps_button: - if (mState != State.APPS_CUSTOMIZE) { - mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, - HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); - showPreviews(v); - } - return true; - } - if (isWorkspaceLocked()) { return false; } @@ -2020,12 +1954,13 @@ public final class Launcher extends Activity return true; } + // The hotseat touch handling does not go through Workspace, and we always allow long press + // on hotseat items. final View itemUnderLongClick = longClickCellInfo.cell; - - if (mWorkspace.allowLongPress() && !mDragController.isDragging()) { + boolean allowLongPress = isHotseatLayout(v) || mWorkspace.allowLongPress(); + if (allowLongPress && !mDragController.isDragging()) { if (itemUnderLongClick == null) { // User long pressed on empty space - mWorkspace.setAllowLongPress(false); mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING); addItems(); @@ -2041,137 +1976,26 @@ public final class Launcher extends Activity return true; } - @SuppressWarnings({"unchecked"}) - private void dismissPreview(final View v) { - final PopupWindow window = (PopupWindow) v.getTag(); - if (window != null) { - window.setOnDismissListener(new PopupWindow.OnDismissListener() { - public void onDismiss() { - ViewGroup group = (ViewGroup) v.getTag(R.id.workspace); - int count = group.getChildCount(); - for (int i = 0; i < count; i++) { - ((ImageView) group.getChildAt(i)).setImageDrawable(null); - } - ArrayList<Bitmap> bitmaps = - (ArrayList<Bitmap>) v.getTag(R.id.all_apps_button_cluster); - for (Bitmap bitmap : bitmaps) bitmap.recycle(); - - v.setTag(R.id.workspace, null); - v.setTag(R.id.all_apps_button_cluster, null); - window.setOnDismissListener(null); - } - }); - window.dismiss(); - } - v.setTag(null); + boolean isHotseatLayout(View layout) { + return mHotseat != null && layout != null && + (layout instanceof CellLayout) && (layout == mHotseat.getLayout()); } - - private void showPreviews(View anchor) { - showPreviews(anchor, 0, mWorkspace.getChildCount()); + Hotseat getHotseat() { + return mHotseat; } - private void showPreviews(final View anchor, int start, int end) { - final Resources resources = getResources(); - final Workspace workspace = mWorkspace; - - CellLayout cell = ((CellLayout) workspace.getChildAt(start)); - - float max = workspace.getChildCount(); - - final Rect r = new Rect(); - resources.getDrawable(R.drawable.preview_background).getPadding(r); - int extraW = (int) ((r.left + r.right) * max); - int extraH = r.top + r.bottom; - - int aW = cell.getWidth() - extraW; - float w = aW / max; - - int width = cell.getWidth(); - int height = cell.getHeight(); - int x = cell.getPaddingLeft(); - int y = cell.getPaddingTop(); - width -= (x + cell.getPaddingRight()); - height -= (y + cell.getPaddingBottom()); - - float scale = w / width; - - int count = end - start; - - final float sWidth = width * scale; - float sHeight = height * scale; - - LinearLayout preview = new LinearLayout(this); - - PreviewTouchHandler handler = new PreviewTouchHandler(anchor); - ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(count); - - for (int i = start; i < end; i++) { - ImageView image = new ImageView(this); - cell = (CellLayout) workspace.getChildAt(i); - - final Bitmap bitmap = Bitmap.createBitmap((int) sWidth, (int) sHeight, - Bitmap.Config.ARGB_8888); - - final Canvas c = new Canvas(bitmap); - c.scale(scale, scale); - c.translate(-cell.getPaddingLeft(), -cell.getPaddingTop()); - cell.drawChildren(c); - - image.setBackgroundDrawable(resources.getDrawable(R.drawable.preview_background)); - image.setImageBitmap(bitmap); - image.setTag(i); - image.setOnClickListener(handler); - image.setOnFocusChangeListener(handler); - image.setFocusable(true); - if (i == mWorkspace.getCurrentPage()) image.requestFocus(); - - preview.addView(image, - LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - - bitmaps.add(bitmap); - } - - final PopupWindow p = new PopupWindow(this); - p.setContentView(preview); - p.setWidth((int) (sWidth * count + extraW)); - p.setHeight((int) (sHeight + extraH)); - p.setAnimationStyle(R.style.AnimationPreview); - p.setOutsideTouchable(true); - p.setFocusable(true); - p.setBackgroundDrawable(new ColorDrawable(0)); - p.showAsDropDown(anchor, 0, 0); - - p.setOnDismissListener(new PopupWindow.OnDismissListener() { - public void onDismiss() { - dismissPreview(anchor); - } - }); - - anchor.setTag(p); - anchor.setTag(R.id.workspace, preview); - anchor.setTag(R.id.all_apps_button_cluster, bitmaps); - } - - class PreviewTouchHandler implements View.OnClickListener, Runnable, View.OnFocusChangeListener { - private final View mAnchor; - - public PreviewTouchHandler(View anchor) { - mAnchor = anchor; - } - - public void onClick(View v) { - mWorkspace.snapToPage((Integer) v.getTag()); - v.post(this); - } - - public void run() { - dismissPreview(mAnchor); - } - - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - mWorkspace.snapToPage((Integer) v.getTag()); + /** + * Returns the CellLayout of the specified container at the specified screen. + */ + CellLayout getCellLayout(long container, int screen) { + if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { + if (mHotseat != null) { + return mHotseat.getLayout(); + } else { + return null; } + } else { + return (CellLayout) mWorkspace.getChildAt(screen); } } @@ -2215,7 +2039,8 @@ public final class Launcher extends Activity private void showAddDialog() { resetAddInfo(); - mAddScreen = mWorkspace.getCurrentPage(); + mPendingAddInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP; + mPendingAddInfo.screen = mWorkspace.getCurrentPage(); mWaitingForResult = true; showDialog(DIALOG_CREATE_SHORTCUT); } @@ -2594,29 +2419,29 @@ public final class Launcher extends Activity } /** - * Shows the dock/hotseat area. + * Shows the hotseat area. */ - void showDock(boolean animated) { + void showHotseat(boolean animated) { if (!LauncherApplication.isScreenLarge()) { if (animated) { int duration = mSearchDeleteBar.getTransitionInDuration(); - mButtonCluster.animate().alpha(1f).setDuration(duration); + mHotseat.animate().alpha(1f).setDuration(duration); } else { - mButtonCluster.setAlpha(1f); + mHotseat.setAlpha(1f); } } } /** - * Hides the dock/hotseat area. + * Hides the hotseat area. */ - void hideDock(boolean animated) { + void hideHotseat(boolean animated) { if (!LauncherApplication.isScreenLarge()) { if (animated) { int duration = mSearchDeleteBar.getTransitionOutDuration(); - mButtonCluster.animate().alpha(0f).setDuration(duration); + mHotseat.animate().alpha(0f).setDuration(duration); } else { - mButtonCluster.setAlpha(0f); + mHotseat.setAlpha(0f); } } } @@ -2627,9 +2452,9 @@ public final class Launcher extends Activity cameraZoomOut(State.APPS_CUSTOMIZE, animated, false); mAppsCustomizeTabHost.requestFocus(); - // Hide the search bar and dock + // Hide the search bar and hotseat mSearchDeleteBar.hideSearchBar(animated); - hideDock(animated); + hideHotseat(animated); // Change the state *after* we've called all the transition code mState = State.APPS_CUSTOMIZE; @@ -2686,12 +2511,14 @@ public final class Launcher extends Activity mWorkspace.setVisibility(View.VISIBLE); cameraZoomIn(State.APPS_CUSTOMIZE, animated, false); - // Show the search bar and dock + // Show the search bar and hotseat mSearchDeleteBar.showSearchBar(animated); - showDock(animated); + showHotseat(animated); // Set focus to the AppsCustomize button - findViewById(R.id.all_apps_button).requestFocus(); + if (mAllAppsButton != null) { + mAllAppsButton.requestFocus(); + } } } @@ -3024,21 +2851,12 @@ public final class Launcher extends Activity final CellLayout layoutParent = (CellLayout) workspace.getChildAt(i); layoutParent.removeAllViewsInLayout(); } - - if (DEBUG_USER_INTERFACE) { - android.widget.Button finishButton = new android.widget.Button(this); - finishButton.setText("Finish"); - workspace.addInScreen(finishButton, 1, 0, 0, 1, 1); - - finishButton.setOnClickListener(new android.widget.Button.OnClickListener() { - public void onClick(View v) { - finish(); - } - }); + if (mHotseat != null) { + mHotseat.resetLayout(); } // This wasn't being called before which resulted in a leak of AppWidgetHostViews - unbindWorkspaceItems(); + unbindWorkspaceAndHotseatItems(); } /** @@ -3047,30 +2865,27 @@ public final class Launcher extends Activity * Implementation of the method from LauncherModel.Callbacks. */ public void bindItems(ArrayList<ItemInfo> shortcuts, int start, int end) { - setLoadOnResume(); final Workspace workspace = mWorkspace; - for (int i=start; i<end; i++) { final ItemInfo item = shortcuts.get(i); switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: - final View shortcut = createShortcut((ShortcutInfo)item); - workspace.addInScreen(shortcut, item.screen, item.cellX, item.cellY, 1, 1, - false); + View shortcut = createShortcut((ShortcutInfo)item); + workspace.addInScreen(shortcut, item.container, item.screen, item.cellX, + item.cellY, 1, 1, false); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, + FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()), (FolderInfo) item, mIconCache); - workspace.addInScreen(newFolder, item.screen, item.cellX, item.cellY, 1, 1, - false); + workspace.addInScreen(newFolder, item.container, item.screen, item.cellX, + item.cellY, 1, 1, false); break; } } - workspace.requestLayout(); } @@ -3108,7 +2923,7 @@ public final class Launcher extends Activity item.hostView.setAppWidget(appWidgetId, appWidgetInfo); item.hostView.setTag(item); - workspace.addInScreen(item.hostView, item.screen, item.cellX, + workspace.addInScreen(item.hostView, item.container, item.screen, item.cellX, item.cellY, item.spanX, item.spanY, false); addWidgetToAutoAdvanceIfNeeded(item.hostView, appWidgetInfo); diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index b4e632a..c8cf1f8 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -178,17 +178,24 @@ public class LauncherModel extends BroadcastReceiver { static void moveItemInDatabase(Context context, final ItemInfo item, final long container, final int screen, final int cellX, final int cellY) { item.container = container; - item.screen = screen; item.cellX = cellX; item.cellY = cellY; + // We store hotseat items in canonical form which is this orientation invariant position + // in the hotseat + if (context instanceof Launcher && screen < 0 && + container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { + item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); + } else { + item.screen = screen; + } final Uri uri = LauncherSettings.Favorites.getContentUri(item.id, false); final ContentValues values = new ContentValues(); final ContentResolver cr = context.getContentResolver(); values.put(LauncherSettings.Favorites.CONTAINER, item.container); - values.put(LauncherSettings.Favorites.CELLX, cellX); - values.put(LauncherSettings.Favorites.CELLY, cellY); + values.put(LauncherSettings.Favorites.CELLX, item.cellX); + values.put(LauncherSettings.Favorites.CELLY, item.cellY); values.put(LauncherSettings.Favorites.SCREEN, item.screen); sWorker.post(new Runnable() { @@ -205,7 +212,8 @@ public class LauncherModel extends BroadcastReceiver { // Items are added/removed from the corresponding FolderInfo elsewhere, such // as in Workspace.onDrop. Here, we just add/remove them from the list of items // that are on the desktop, as appropriate - if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || + modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { if (!sWorkspaceItems.contains(modelItem)) { sWorkspaceItems.add(modelItem); } @@ -356,12 +364,19 @@ public class LauncherModel extends BroadcastReceiver { * Add an item to the database in a specified container. Sets the container, screen, cellX and * cellY fields of the item. Also assigns an ID to the item. */ - static void addItemToDatabase(Context context, final ItemInfo item, long container, - int screen, int cellX, int cellY, final boolean notify) { + static void addItemToDatabase(Context context, final ItemInfo item, final long container, + final int screen, final int cellX, final int cellY, final boolean notify) { item.container = container; - item.screen = screen; item.cellX = cellX; item.cellY = cellY; + // We store hotseat items in canonical form which is this orientation invariant position + // in the hotseat + if (context instanceof Launcher && screen < 0 && + container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { + item.screen = ((Launcher) context).getHotseat().getOrderInHotseat(cellX, cellY); + } else { + item.screen = screen; + } final ContentValues values = new ContentValues(); final ContentResolver cr = context.getContentResolver(); @@ -371,7 +386,7 @@ public class LauncherModel extends BroadcastReceiver { LauncherApplication app = (LauncherApplication) l.getApplication(); item.id = app.getLauncherProvider().generateNewId(); values.put(LauncherSettings.Favorites._ID, item.id); - item.updateValuesWithCoordinates(values, cellX, cellY); + item.updateValuesWithCoordinates(values, item.cellX, item.cellY); sWorker.post(new Runnable() { public void run() { @@ -382,13 +397,11 @@ public class LauncherModel extends BroadcastReceiver { switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: sFolders.put(item.id, (FolderInfo) item); - if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { - sWorkspaceItems.add(item); - } - break; + // Fall through case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: - if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP || + item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { sWorkspaceItems.add(item); } break; @@ -404,8 +417,8 @@ public class LauncherModel extends BroadcastReceiver { * Creates a new unique child id, for a given cell span across all layouts. */ static int getCellLayoutChildId( - int cellId, int screen, int localCellX, int localCellY, int spanX, int spanY) { - return ((cellId & 0xFF) << 24) + long container, int screen, int localCellX, int localCellY, int spanX, int spanY) { + return (((int) container & 0xFF) << 24) | (screen & 0xFF) << 16 | (localCellX & 0xFF) << 8 | (localCellY & 0xFF); } @@ -928,6 +941,7 @@ public class LauncherModel extends BroadcastReceiver { switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: + case LauncherSettings.Favorites.CONTAINER_HOTSEAT: sWorkspaceItems.add(info); break; default: @@ -972,6 +986,7 @@ public class LauncherModel extends BroadcastReceiver { } switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: + case LauncherSettings.Favorites.CONTAINER_HOTSEAT: sWorkspaceItems.add(folderInfo); break; } @@ -1003,9 +1018,10 @@ public class LauncherModel extends BroadcastReceiver { appWidgetInfo.spanY = c.getInt(spanYIndex); container = c.getInt(containerIndex); - if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP && + container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) { Log.e(TAG, "Widget found where container " - + "!= CONTAINER_DESKTOP -- ignoring!"); + + "!= CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!"); continue; } appWidgetInfo.container = c.getInt(containerIndex); @@ -1607,12 +1623,10 @@ public class LauncherModel extends BroadcastReceiver { } } - ShortcutInfo addShortcut(Context context, Intent data, - int screen, int cellX, int cellY, boolean notify) { - + ShortcutInfo addShortcut(Context context, Intent data, long container, int screen, + int cellX, int cellY, boolean notify) { final ShortcutInfo info = infoFromShortcutIntent(context, data, null); - addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP, - screen, cellX, cellY, notify); + addItemToDatabase(context, info, container, screen, cellX, cellY, notify); return info; } diff --git a/src/com/android/launcher2/LauncherProvider.java b/src/com/android/launcher2/LauncherProvider.java index 5ffd984..96cc63c 100644 --- a/src/com/android/launcher2/LauncherProvider.java +++ b/src/com/android/launcher2/LauncherProvider.java @@ -65,11 +65,11 @@ public class LauncherProvider extends ContentProvider { private static final boolean LOGD = false; private static final String DATABASE_NAME = "launcher.db"; - - private static final int DATABASE_VERSION = 8; + + private static final int DATABASE_VERSION = 9; static final String AUTHORITY = "com.android.launcher2.settings"; - + static final String TABLE_FAVORITES = "favorites"; static final String PARAMETER_NOTIFY = "notify"; @@ -199,7 +199,7 @@ public class LauncherProvider extends ContentProvider { private static final String TAG_SEARCH = "search"; private static final String TAG_APPWIDGET = "appwidget"; private static final String TAG_SHORTCUT = "shortcut"; - + private final Context mContext; private final AppWidgetHost mAppWidgetHost; private long mMaxId = -1; @@ -208,7 +208,12 @@ public class LauncherProvider extends ContentProvider { super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = context; mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID); - mMaxId = initializeMaxId(getWritableDatabase()); + + // In the case where neither onCreate nor onUpgrade gets called, we read the maxId from + // the DB here + if (mMaxId == -1) { + mMaxId = initializeMaxId(getWritableDatabase()); + } } /** @@ -254,10 +259,10 @@ public class LauncherProvider extends ContentProvider { mAppWidgetHost.deleteHost(); sendAppWidgetResetNotify(); } - + if (!convertDatabase(db)) { // Populate favorites table with initial favorites - loadFavorites(db); + loadFavorites(db, ItemInfo.NO_ID); } } @@ -427,6 +432,18 @@ public class LauncherProvider extends ContentProvider { version = 8; } + if (version < 9) { + // The max id is not yet set at this point (onUpgrade is triggered in the ctor + // before it gets a change to get set, so we need to read it here when we use it) + if (mMaxId == -1) { + mMaxId = initializeMaxId(db); + } + + // Add default hotseat icons + loadFavorites(db, LauncherSettings.Favorites.CONTAINER_HOTSEAT); + version = 9; + } + if (version != DATABASE_VERSION) { Log.w(TAG, "Destroying all old data."); db.execSQL("DROP TABLE IF EXISTS " + TABLE_FAVORITES); @@ -672,8 +689,9 @@ public class LauncherProvider extends ContentProvider { * Loads the default set of favorite packages from an xml file. * * @param db The database to write the values into + * @param filterContainerId The specific container id of items to load */ - private int loadFavorites(SQLiteDatabase db) { + private int loadFavorites(SQLiteDatabase db, long filterContainerId) { Intent intent = new Intent(Intent.ACTION_MAIN, null); intent.addCategory(Intent.CATEGORY_LAUNCHER); ContentValues values = new ContentValues(); @@ -700,26 +718,42 @@ public class LauncherProvider extends ContentProvider { TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.Favorite); - values.clear(); - values.put(LauncherSettings.Favorites.CONTAINER, - LauncherSettings.Favorites.CONTAINER_DESKTOP); - values.put(LauncherSettings.Favorites.SCREEN, - a.getString(R.styleable.Favorite_screen)); - values.put(LauncherSettings.Favorites.CELLX, - a.getString(R.styleable.Favorite_x)); - values.put(LauncherSettings.Favorites.CELLY, - a.getString(R.styleable.Favorite_y)); - - if (TAG_FAVORITE.equals(name)) { - added = addAppShortcut(db, values, a, packageManager, intent); - } else if (TAG_SEARCH.equals(name)) { - added = addSearchWidget(db, values); - } else if (TAG_CLOCK.equals(name)) { - added = addClockWidget(db, values); - } else if (TAG_APPWIDGET.equals(name)) { - added = addAppWidget(db, values, a, packageManager); - } else if (TAG_SHORTCUT.equals(name)) { - added = addUriShortcut(db, values, a); + long container = LauncherSettings.Favorites.CONTAINER_DESKTOP; + if (a.hasValue(R.styleable.Favorite_container)) { + container = Long.valueOf(a.getString(R.styleable.Favorite_container)); + } + if (filterContainerId == ItemInfo.NO_ID || filterContainerId == container) { + String screen = a.getString(R.styleable.Favorite_screen); + String x = a.getString(R.styleable.Favorite_x); + String y = a.getString(R.styleable.Favorite_y); + + // If we are adding to the hotset, the screen is used as the position in the + // hotset. This screen can't be at position 0 because AllApps is in the + // zeroth position. + if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT && + Integer.valueOf(screen) <= 0) { + throw new RuntimeException("Invalid screen position for hotseat item"); + } + + values.clear(); + values.put(LauncherSettings.Favorites.CONTAINER, container); + values.put(LauncherSettings.Favorites.SCREEN, screen); + values.put(LauncherSettings.Favorites.CELLX, x); + values.put(LauncherSettings.Favorites.CELLY, y); + + System.out.println("Adding item to container: " + container); + + if (TAG_FAVORITE.equals(name)) { + added = addAppShortcut(db, values, a, packageManager, intent); + } else if (TAG_SEARCH.equals(name)) { + added = addSearchWidget(db, values); + } else if (TAG_CLOCK.equals(name)) { + added = addClockWidget(db, values); + } else if (TAG_APPWIDGET.equals(name)) { + added = addAppWidget(db, values, a, packageManager); + } else if (TAG_SHORTCUT.equals(name)) { + added = addUriShortcut(db, values, a); + } } if (added) i++; @@ -730,6 +764,8 @@ public class LauncherProvider extends ContentProvider { Log.w(TAG, "Got exception parsing favorites.", e); } catch (IOException e) { Log.w(TAG, "Got exception parsing favorites.", e); + } catch (RuntimeException e) { + Log.w(TAG, "Got exception parsing favorites.", e); } return i; diff --git a/src/com/android/launcher2/LauncherSettings.java b/src/com/android/launcher2/LauncherSettings.java index c378405..fcacdec 100644 --- a/src/com/android/launcher2/LauncherSettings.java +++ b/src/com/android/launcher2/LauncherSettings.java @@ -133,6 +133,7 @@ class LauncherSettings { * The icon is a resource identified by a package name and an integer id. */ static final int CONTAINER_DESKTOP = -100; + static final int CONTAINER_HOTSEAT = -101; /** * The screen holding the favorite (if container is CONTAINER_DESKTOP) diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java index 4fbf70f..ed4ae20 100644 --- a/src/com/android/launcher2/Workspace.java +++ b/src/com/android/launcher2/Workspace.java @@ -424,12 +424,8 @@ public class Workspace extends SmoothPagedView * @param spanX The number of cells spanned horizontally by the child. * @param spanY The number of cells spanned vertically by the child. */ - void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) { - addInScreen(child, screen, x, y, spanX, spanY, false); - } - - void addInFullScreen(View child, int screen) { - addInScreen(child, screen, 0, 0, -1, -1); + void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY) { + addInScreen(child, container, screen, x, y, spanX, spanY, false); } /** @@ -444,14 +440,32 @@ public class Workspace extends SmoothPagedView * @param spanY The number of cells spanned vertically by the child. * @param insert When true, the child is inserted at the beginning of the children list. */ - void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) { - if (screen < 0 || screen >= getChildCount()) { - Log.e(TAG, "The screen must be >= 0 and < " + getChildCount() - + " (was " + screen + "); skipping child"); - return; + void addInScreen(View child, long container, int screen, int x, int y, int spanX, int spanY, + boolean insert) { + if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { + if (screen < 0 || screen >= getChildCount()) { + Log.e(TAG, "The screen must be >= 0 and < " + getChildCount() + + " (was " + screen + "); skipping child"); + return; + } + } + + final CellLayout layout; + if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { + layout = mLauncher.getHotseat().getLayout(); + + if (screen < 0) { + screen = mLauncher.getHotseat().getOrderInHotseat(x, y); + } else { + // Note: We do this to ensure that the hotseat is always laid out in the orientation + // of the hotseat in order regardless of which orientation they were added + x = mLauncher.getHotseat().getCellXFromOrder(screen); + y = mLauncher.getHotseat().getCellYFromOrder(screen); + } + } else { + layout = (CellLayout) getChildAt(screen); } - final CellLayout group = (CellLayout) getChildAt(screen); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); if (lp == null) { lp = new CellLayout.LayoutParams(x, y, spanX, spanY); @@ -467,9 +481,9 @@ public class Workspace extends SmoothPagedView } // Get the canonical child id to uniquely represent this view in this screen - int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY); + int childId = LauncherModel.getCellLayoutChildId(container, screen, x, y, spanX, spanY); boolean markCellsAsOccupied = !(child instanceof Folder); - if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) { + if (!layout.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) { // TODO: This branch occurs when the workspace is adding views // outside of the defined grid // maybe we should be deleting these items from the LauncherModel? @@ -1959,7 +1973,7 @@ public class Workspace extends SmoothPagedView mDragInfo = cellInfo; - CellLayout current = (CellLayout) getChildAt(cellInfo.screen); + CellLayout current = getParentCellLayoutForView(cellInfo.cell); current.onDragChild(child); child.clearFocus(); @@ -2008,17 +2022,15 @@ public class Workspace extends SmoothPagedView b.recycle(); } - void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY, - boolean insertAtFirst, int intersectX, int intersectY) { - final CellLayout cellLayout = (CellLayout) getChildAt(screen); - View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info); + void addApplicationShortcut(ShortcutInfo info, CellLayout target, long container, int screen, + int cellX, int cellY, boolean insertAtFirst, int intersectX, int intersectY) { + View view = mLauncher.createShortcut(R.layout.application, target, (ShortcutInfo) info); final int[] cellXY = new int[2]; - cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY); - addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst); - LauncherModel.addOrMoveItemInDatabase(mLauncher, info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, - cellXY[0], cellXY[1]); + target.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY); + addInScreen(view, container, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst); + LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screen, cellXY[0], + cellXY[1]); } /** @@ -2051,7 +2063,6 @@ public class Workspace extends SmoothPagedView mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], spanX, spanY, mDragTargetLayout, mTargetCell); - if (willCreateUserFolder((ItemInfo) d.dragInfo, mDragTargetLayout, mTargetCell, true)) { return true; } @@ -2074,8 +2085,12 @@ public class Workspace extends SmoothPagedView boolean considerTimeout) { View dropOverView = target.getChildAt(targetCell[0], targetCell[1]); - boolean hasntMoved = mDragInfo != null && (mDragInfo.cellX == targetCell[0] && - mDragInfo.cellY == targetCell[1]) && mDragInfo.screen == indexOfChild(target); + boolean hasntMoved = false; + if (mDragInfo != null) { + CellLayout cellParent = getParentCellLayoutForView(mDragInfo.cell); + hasntMoved = (mDragInfo.cellX == targetCell[0] && + mDragInfo.cellY == targetCell[1]) && (cellParent == target); + } if (dropOverView == null || hasntMoved || (considerTimeout && !mCreateUserFolderOnDrop)) { return false; @@ -2100,7 +2115,7 @@ public class Workspace extends SmoothPagedView return false; } - boolean createUserFolderIfNecessary(View newView, CellLayout target, + boolean createUserFolderIfNecessary(View newView, long container, CellLayout target, int[] targetCell, boolean external, DragView dragView, Runnable postAnimationRunnable) { View v = target.getChildAt(targetCell[0], targetCell[1]); boolean hasntMoved = mDragInfo != null @@ -2118,16 +2133,15 @@ public class Workspace extends SmoothPagedView ShortcutInfo destInfo = (ShortcutInfo) v.getTag(); // if the drag started here, we need to remove it from the workspace if (!external) { - int fromScreen = mDragInfo.screen; - CellLayout sourceLayout = (CellLayout) getChildAt(fromScreen); - sourceLayout.removeView(newView); + getParentCellLayoutForView(mDragInfo.cell).removeView(mDragInfo.cell); } Rect folderLocation = new Rect(); float scale = mLauncher.getDragLayer().getDescendantRectRelativeToSelf(v, folderLocation); target.removeView(v); - FolderIcon fi = mLauncher.addFolder(screen, targetCell[0], targetCell[1]); + FolderIcon fi = + mLauncher.addFolder(target, container, screen, targetCell[0], targetCell[1]); destInfo.cellX = -1; destInfo.cellY = -1; sourceInfo.cellX = -1; @@ -2150,9 +2164,7 @@ public class Workspace extends SmoothPagedView // if the drag started here, we need to remove it from the workspace if (!external) { - int fromScreen = mDragInfo.screen; - CellLayout sourceLayout = (CellLayout) getChildAt(fromScreen); - sourceLayout.removeView(newView); + getParentCellLayoutForView(mDragInfo.cell).removeView(mDragInfo.cell); } return true; } @@ -2166,7 +2178,11 @@ public class Workspace extends SmoothPagedView // We want the point to be mapped to the dragTarget. if (mDragTargetLayout != null) { - mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); + if (mLauncher.isHotseatLayout(mDragTargetLayout)) { + mapPointFromSelfToSibling(mLauncher.getHotseat(), mDragViewVisualCenter); + } else { + mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); + } } // When you are in customization mode and drag to a particular screen, make that the @@ -2186,11 +2202,23 @@ public class Workspace extends SmoothPagedView } else if (mDragInfo != null) { final View cell = mDragInfo.cell; - if (dropTargetLayout != null) { + boolean continueDrop = true; + if (mLauncher.isHotseatLayout(mDragTargetLayout) && d.dragInfo instanceof ItemInfo) { + ItemInfo info = (ItemInfo) d.dragInfo; + if (info.spanX > 1 || info.spanY > 1) { + continueDrop = false; + Toast.makeText(getContext(), R.string.invalid_hotseat_item, + Toast.LENGTH_SHORT).show(); + } + } + + if (continueDrop && dropTargetLayout != null) { // Move internally - final int screen = (mTargetCell[0] < 0) ? + long container = mLauncher.isHotseatLayout(dropTargetLayout) ? + LauncherSettings.Favorites.CONTAINER_HOTSEAT : + LauncherSettings.Favorites.CONTAINER_DESKTOP; + int screen = (mTargetCell[0] < 0) ? mDragInfo.screen : indexOfChild(dropTargetLayout); - int spanX = mDragInfo != null ? mDragInfo.spanX : 1; int spanY = mDragInfo != null ? mDragInfo.spanY : 1; // First we find the cell nearest to point at which the item is @@ -2199,10 +2227,10 @@ public class Workspace extends SmoothPagedView mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell); // If the item being dropped is a shortcut and the nearest drop // cell also contains a shortcut, then create a folder with the two shortcuts. - boolean dropInscrollArea = mCurrentPage != screen; + boolean dropInscrollArea = mCurrentPage != screen && screen > -1; - if (!dropInscrollArea && createUserFolderIfNecessary(cell, dropTargetLayout, - mTargetCell, false, d.dragView, null)) { + if (!dropInscrollArea && createUserFolderIfNecessary(cell, container, + dropTargetLayout, mTargetCell, false, d.dragView, null)) { return; } @@ -2220,25 +2248,26 @@ public class Workspace extends SmoothPagedView snapToPage(screen); } + if (mTargetCell[0] >= 0 && mTargetCell[1] >= 0) { if (screen != mDragInfo.screen) { // Reparent the view - ((CellLayout) getChildAt(mDragInfo.screen)).removeView(cell); - addInScreen(cell, screen, mTargetCell[0], mTargetCell[1], mDragInfo.spanX, - mDragInfo.spanY); + getParentCellLayoutForView(cell).removeView(cell); + addInScreen(cell, container, screen, mTargetCell[0], mTargetCell[1], + mDragInfo.spanX, mDragInfo.spanY); } - // update the item's position after drop final ItemInfo info = (ItemInfo) cell.getTag(); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); dropTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]); lp.cellX = mTargetCell[0]; lp.cellY = mTargetCell[1]; - cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen, + cell.setId(LauncherModel.getCellLayoutChildId(container, mDragInfo.screen, mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY)); - if (cell instanceof LauncherAppWidgetHostView) { + if (container != LauncherSettings.Favorites.CONTAINER_HOTSEAT && + cell instanceof LauncherAppWidgetHostView) { final CellLayout cellLayout = dropTargetLayout; // We post this call so that the widget has a chance to be placed // in its final location @@ -2264,9 +2293,8 @@ public class Workspace extends SmoothPagedView } } - LauncherModel.moveItemInDatabase(mLauncher, info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, - lp.cellX, lp.cellY); + LauncherModel.moveItemInDatabase(mLauncher, info, container, screen, lp.cellX, + lp.cellY); } } @@ -2446,7 +2474,8 @@ public class Workspace extends SmoothPagedView final AppWidgetProviderInfo widgetInfo = widgets.get(0).widgetInfo; final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mimeType, data); - mLauncher.addAppWidgetFromDrop(createInfo, mCurrentPage, null, pos); + mLauncher.addAppWidgetFromDrop(createInfo, + LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentPage, null, pos); } else { // Show the widget picker dialog if there is more than one widget // that can handle this data type @@ -2507,6 +2536,15 @@ public class Workspace extends SmoothPagedView } /* + * Maps a point from the Workspace's coordinate system to another sibling view's. (Workspace + * covers the full screen) + */ + void mapPointFromSelfToSibling(View v, float[] xy) { + xy[0] = xy[0] - v.getLeft(); + xy[1] = xy[1] - v.getTop(); + } + + /* * * Convert the 2D coordinate xy from this CellLayout's coordinate space to * the parent View's coordinate space. The argument xy is modified with the return result. @@ -2581,7 +2619,7 @@ public class Workspace extends SmoothPagedView float smallestDistSoFar = Float.MAX_VALUE; for (int i = 0; i < screenCount; i++) { - CellLayout cl = (CellLayout)getChildAt(i); + CellLayout cl = (CellLayout) getChildAt(i); final float[] touchXy = mTempTouchCoordinates; touchXy[0] = originX + offsetX; @@ -2657,7 +2695,7 @@ public class Workspace extends SmoothPagedView if (mInScrollArea) return; if (mIsSwitchingState) return; - CellLayout layout; + CellLayout layout = null; ItemInfo item = (ItemInfo) d.dragInfo; // Ensure that we have proper spans for the item that we are dropping @@ -2690,7 +2728,17 @@ public class Workspace extends SmoothPagedView } } } else { - layout = getCurrentDropLayout(); + // Test to see if we are over the hotseat otherwise just use the current page + Rect r = new Rect(); + if (mLauncher.getHotseat() != null) { + mLauncher.getHotseat().getHitRect(r); + if (r.contains(d.x, d.y)) { + layout = mLauncher.getHotseat().getLayout(); + } + } + if (layout == null) { + layout = getCurrentDropLayout(); + } if (layout != mDragTargetLayout) { if (mDragTargetLayout != null) { mDragTargetLayout.setIsDragOverlapping(false); @@ -2710,7 +2758,11 @@ public class Workspace extends SmoothPagedView d.dragView, mDragViewVisualCenter); // We want the point to be mapped to the dragTarget. - mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); + if (mLauncher.isHotseatLayout(mDragTargetLayout)) { + mapPointFromSelfToSibling(mLauncher.getHotseat(), mDragViewVisualCenter); + } else { + mapPointFromSelfToChild(mDragTargetLayout, mDragViewVisualCenter, null); + } ItemInfo info = (ItemInfo) d.dragInfo; mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], @@ -2845,8 +2897,12 @@ public class Workspace extends SmoothPagedView spanY = mDragInfo.spanY; } + final long container = mLauncher.isHotseatLayout(cellLayout) ? + LauncherSettings.Favorites.CONTAINER_HOTSEAT : + LauncherSettings.Favorites.CONTAINER_DESKTOP; final int screen = indexOfChild(cellLayout); - if (screen != mCurrentPage && mState != State.SPRING_LOADED) { + if (!mLauncher.isHotseatLayout(cellLayout) && screen != mCurrentPage + && mState != State.SPRING_LOADED) { snapToPage(screen); } @@ -2863,11 +2919,11 @@ public class Workspace extends SmoothPagedView switch (pendingInfo.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) pendingInfo, - screen, mTargetCell, null); + container, screen, mTargetCell, null); break; case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: mLauncher.processShortcutFromDrop(pendingInfo.componentName, - screen, mTargetCell, null); + container, screen, mTargetCell, null); break; default: throw new IllegalStateException("Unknown item type: " + @@ -2923,8 +2979,8 @@ public class Workspace extends SmoothPagedView mTargetCell = findNearestArea((int) touchXY[0], (int) touchXY[1], spanX, spanY, cellLayout, mTargetCell); d.postAnimationRunnable = exitSpringLoadedRunnable; - if (createUserFolderIfNecessary(view, cellLayout, mTargetCell, true, d.dragView, - d.postAnimationRunnable)) { + if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, true, + d.dragView, d.postAnimationRunnable)) { return; } if (addToExistingFolderIfNecessary(view, cellLayout, mTargetCell, d, true)) { @@ -2939,15 +2995,14 @@ public class Workspace extends SmoothPagedView } else { cellLayout.findCellForSpan(mTargetCell, 1, 1); } - addInScreen(view, indexOfChild(cellLayout), mTargetCell[0], - mTargetCell[1], info.spanX, info.spanY, insertAtFirst); + addInScreen(view, container, screen, mTargetCell[0], mTargetCell[1], info.spanX, + info.spanY, insertAtFirst); cellLayout.onDropChild(view); cellLayout.animateDrop(); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); cellLayout.getChildrenLayout().measureChild(view); - LauncherModel.addOrMoveItemInDatabase(mLauncher, info, - LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, + LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screen, lp.cellX, lp.cellY); if (d.dragView != null) { @@ -3016,8 +3071,7 @@ public class Workspace extends SmoothPagedView if (success) { if (target != this) { if (mDragInfo != null) { - final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); - cellLayout.removeView(mDragInfo.cell); + getParentCellLayoutForView(mDragInfo.cell).removeView(mDragInfo.cell); if (mDragInfo.cell instanceof DropTarget) { mDragController.removeDropTarget((DropTarget) mDragInfo.cell); } @@ -3028,7 +3082,13 @@ public class Workspace extends SmoothPagedView // calling onDropCompleted(). We call it ourselves here, but maybe this should be // moved into DragController.cancelDrag(). doDragExit(null); - ((CellLayout) getChildAt(mDragInfo.screen)).onDropChild(mDragInfo.cell); + CellLayout cellLayout; + if (mLauncher.isHotseatLayout(target)) { + cellLayout = mLauncher.getHotseat().getLayout(); + } else { + cellLayout = (CellLayout) getChildAt(mDragInfo.screen); + } + cellLayout.onDropChild(mDragInfo.cell); } mDragOutline = null; mDragInfo = null; @@ -3125,15 +3185,58 @@ public class Workspace extends SmoothPagedView mInScrollArea = false; } - public Folder getFolderForTag(Object tag) { - final int screenCount = getChildCount(); + /** + * Returns a specific CellLayout + */ + CellLayout getParentCellLayoutForView(View v) { + ArrayList<CellLayout> layouts = getWorkspaceAndHotseatCellLayouts(); + for (CellLayout layout : layouts) { + if (layout.getChildrenLayout().indexOfChild(v) > -1) { + return layout; + } + } + return null; + } + + /** + * Returns a list of all the CellLayouts in the workspace. + */ + ArrayList<CellLayout> getWorkspaceAndHotseatCellLayouts() { + ArrayList<CellLayout> layouts = new ArrayList<CellLayout>(); + int screenCount = getChildCount(); + for (int screen = 0; screen < screenCount; screen++) { + layouts.add(((CellLayout) getChildAt(screen))); + } + if (mLauncher.getHotseat() != null) { + layouts.add(mLauncher.getHotseat().getLayout()); + } + return layouts; + } + + /** + * We should only use this to search for specific children. Do not use this method to modify + * CellLayoutChildren directly. + */ + ArrayList<CellLayoutChildren> getWorkspaceAndHotseatCellLayoutChildren() { + ArrayList<CellLayoutChildren> childrenLayouts = new ArrayList<CellLayoutChildren>(); + int screenCount = getChildCount(); for (int screen = 0; screen < screenCount; screen++) { - ViewGroup currentScreen = ((CellLayout) getChildAt(screen)).getChildrenLayout(); - int count = currentScreen.getChildCount(); + childrenLayouts.add(((CellLayout) getChildAt(screen)).getChildrenLayout()); + } + if (mLauncher.getHotseat() != null) { + childrenLayouts.add(mLauncher.getHotseat().getLayout().getChildrenLayout()); + } + return childrenLayouts; + } + + public Folder getFolderForTag(Object tag) { + ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren(); + for (CellLayoutChildren layout: childrenLayouts) { + int count = layout.getChildCount(); for (int i = 0; i < count; i++) { - View child = currentScreen.getChildAt(i); + View child = layout.getChildAt(i); CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); - if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { + if (child instanceof Folder) { Folder f = (Folder) child; if (f.getInfo() == tag && f.getInfo().opened) { return f; @@ -3145,12 +3248,11 @@ public class Workspace extends SmoothPagedView } public View getViewForTag(Object tag) { - int screenCount = getChildCount(); - for (int screen = 0; screen < screenCount; screen++) { - ViewGroup currentScreen = ((CellLayout) getChildAt(screen)).getChildrenLayout(); - int count = currentScreen.getChildCount(); + ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren(); + for (CellLayoutChildren layout: childrenLayouts) { + int count = layout.getChildCount(); for (int i = 0; i < count; i++) { - View child = currentScreen.getChildAt(i); + View child = layout.getChildAt(i); if (child.getTag() == tag) { return child; } @@ -3160,11 +3262,8 @@ public class Workspace extends SmoothPagedView } void clearDropTargets() { - final int screenCount = getChildCount(); - - for (int i = 0; i < screenCount; i++) { - final CellLayout layoutParent = (CellLayout) getChildAt(i); - final ViewGroup layout = layoutParent.getChildrenLayout(); + ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren(); + for (CellLayoutChildren layout: childrenLayouts) { int childCount = layout.getChildCount(); for (int j = 0; j < childCount; j++) { View v = layout.getChildAt(j); @@ -3185,8 +3284,8 @@ public class Workspace extends SmoothPagedView packageNames.add(apps.get(i).componentName.getPackageName()); } - for (int i = 0; i < screenCount; i++) { - final CellLayout layoutParent = (CellLayout) getChildAt(i); + ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts(); + for (final CellLayout layoutParent: cellLayouts) { final ViewGroup layout = layoutParent.getChildrenLayout(); // Avoid ANRs by treating each screen separately @@ -3273,9 +3372,8 @@ public class Workspace extends SmoothPagedView } void updateShortcuts(ArrayList<ApplicationInfo> apps) { - final int screenCount = getChildCount(); - for (int i = 0; i < screenCount; i++) { - final ViewGroup layout = ((CellLayout) getChildAt(i)).getChildrenLayout(); + ArrayList<CellLayoutChildren> childrenLayouts = getWorkspaceAndHotseatCellLayoutChildren(); + for (CellLayoutChildren layout: childrenLayouts) { int childCount = layout.getChildCount(); for (int j = 0; j < childCount; j++) { final View view = layout.getChildAt(j); @@ -3307,7 +3405,7 @@ public class Workspace extends SmoothPagedView void moveToDefaultScreen(boolean animate) { if (isSmall() || mIsSwitchingState) { - mLauncher.showWorkspace(animate, (CellLayout)getChildAt(mDefaultPage)); + mLauncher.showWorkspace(animate, (CellLayout) getChildAt(mDefaultPage)); } else if (animate) { snapToPage(mDefaultPage); } else { |