From 3d503fbd9468fb2b9fa645f4f7b91e11229edbfa Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 13 Jul 2011 17:25:49 -0700 Subject: [PATCH] Initial changes to add configurable hotseat. Change-Id: I4c2ed4a1c122c057662fabc70bfef7c5c088460b --- res/drawable-hdpi/apps_hotseat_button.png | Bin 0 -> 4932 bytes res/drawable-hdpi/hotseat_bg_panel.9.png | Bin 0 -> 185 bytes res/drawable-hdpi/hotseat_scrubber_holo.9.png | Bin 2878 -> 155 bytes res/drawable-hdpi/hotseat_track_holo.9.png | Bin 122 -> 138 bytes res/drawable-land-hdpi/hotseat_bg_panel.9.png | Bin 0 -> 176 bytes res/drawable-land-mdpi/hotseat_bg_panel.9.png | Bin 0 -> 165 bytes res/drawable-mdpi/apps_hotseat_button.png | Bin 0 -> 5186 bytes res/drawable-mdpi/hotseat_bg_panel.9.png | Bin 0 -> 182 bytes res/drawable-mdpi/hotseat_scrubber_holo.9.png | Bin 132 -> 140 bytes res/drawable-mdpi/hotseat_track_holo.9.png | Bin 122 -> 129 bytes res/layout-land/hotseat.xml | 33 ++ res/layout-land/launcher.xml | 36 +- res/layout-land/search_bar.xml | 4 +- res/layout-port/hotseat.xml | 33 ++ res/layout-port/launcher.xml | 31 +- res/layout-port/search_bar.xml | 4 +- res/values-land/dimens.xml | 6 +- res/values-port/dimens.xml | 10 +- res/values/attrs.xml | 10 + res/values/dimens.xml | 6 +- res/values/strings.xml | 2 + res/xml/default_workspace.xml | 41 +- src/com/android/launcher2/CellLayout.java | 1 + src/com/android/launcher2/FocusHelper.java | 12 +- src/com/android/launcher2/Folder.java | 15 +- src/com/android/launcher2/Hotseat.java | 114 +++++ .../launcher2/InstallShortcutReceiver.java | 21 +- .../launcher2/InstallWidgetReceiver.java | 3 +- src/com/android/launcher2/Launcher.java | 463 ++++++------------ src/com/android/launcher2/LauncherModel.java | 58 ++- .../android/launcher2/LauncherProvider.java | 90 +++- .../android/launcher2/LauncherSettings.java | 1 + src/com/android/launcher2/Workspace.java | 280 +++++++---- 33 files changed, 708 insertions(+), 566 deletions(-) create mode 100644 res/drawable-hdpi/apps_hotseat_button.png create mode 100644 res/drawable-hdpi/hotseat_bg_panel.9.png create mode 100644 res/drawable-land-hdpi/hotseat_bg_panel.9.png create mode 100644 res/drawable-land-mdpi/hotseat_bg_panel.9.png create mode 100644 res/drawable-mdpi/apps_hotseat_button.png create mode 100644 res/drawable-mdpi/hotseat_bg_panel.9.png create mode 100644 res/layout-land/hotseat.xml create mode 100644 res/layout-port/hotseat.xml create mode 100644 src/com/android/launcher2/Hotseat.java diff --git a/res/drawable-hdpi/apps_hotseat_button.png b/res/drawable-hdpi/apps_hotseat_button.png new file mode 100644 index 0000000000000000000000000000000000000000..c459ba8237d1fb08974091a69b5dd560af40b099 GIT binary patch literal 4932 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 bR(l54bE22Oy=JfhTEpP!>gTe~DWM4fp$9p) literal 0 HcmV?d00001 diff --git a/res/drawable-hdpi/hotseat_scrubber_holo.9.png b/res/drawable-hdpi/hotseat_scrubber_holo.9.png index 3400050cae2586712d1d387f8b63c7b1098e2048..3a026f8be1a5edc23a55b88b0c781e9f24ac4ca0 100644 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^9ze{-!3HD~_TPvGQc0dJjv*GOlYjjGZ_muZeDHr@ zPm|(9CbhJAjR``I&rX^(HbK&%V2j9gK9gc~Nz6Ko(M)!Vw`LE%Y@Pwg> zA;YYBs^<=aO;rmVouw8tL>M;rBr=*rc_iyEab#fFc0=fW+bY2iK-(BRUHx3vIVCg! E0K=9wUH||9 literal 2878 zcmV-E3&He>P)00009a7bBm000Y# z000Y#0XNCZtpETDPiaF#P*7-ZbZ>KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z0001KNklpF diff --git a/res/drawable-hdpi/hotseat_track_holo.9.png b/res/drawable-hdpi/hotseat_track_holo.9.png index a058a3a3718f90d6fa40c59ecfab9259c1ced6d1..f49344fe86b7ffbe100a808292d175f9232ee0c8 100644 GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^9ze{-!3HD~_TPvGQh}Z>jv*GOlYjjGZ_muZeDHr@ zPm|(9CbhJAjSm7F_#SAov!wMUS=(J mC7Hs*z2KsgRJ9^66T|tPA4*TzX)^;2XYh3Ob6Mw<&;$UISSo1% literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^?m*1O!3HEJZfU*-q#Qk6978NlC;#~W-=10IkNnYs zGYtIV0?8uE20=-TAO9PxsH*BpA5E}fS1nkec*UUW;0`9s0yoC85At)3yCyQRG90xz Vczlm#-~pgv44$rjF6*2UngHH?B}D)L diff --git a/res/drawable-land-hdpi/hotseat_bg_panel.9.png b/res/drawable-land-hdpi/hotseat_bg_panel.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6a25f46e85069679f2ba995d97227eb2a5aa8941 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^UO>#s!3HEB-K#nQq*#ibJVQ8upoSx*1IXtr@Q5sC zVBqcqVMg5r{ObSyH*zHlTcVDvmgNX`aV(xNgGWU2 z%?wq+hR)fW*P5iyEr0na>ru6{1-oD!M<4~#t+ literal 0 HcmV?d00001 diff --git a/res/drawable-land-mdpi/hotseat_bg_panel.9.png b/res/drawable-land-mdpi/hotseat_bg_panel.9.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe73d4b100b106ce5d2eabb6adc3f0800b59ca2 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^MnKHM!3HGH$mB4BIK@t$Asj$Z!;#Vf4nJ zaCd?*qxs3xYk`99o-U3d8WXQhI>^PKz~Q`n?Z5y1uP^W^$u$>zxN)Jot8I1fJ)=i@ z50g099a6>4Jeaxkp4V2baD%5OI1JA0{rfeu?&OoV@vj*Y|Fc}W#Wepq&`1VPS3j3^ HP6$Zh9AG|8o%G-Ch-^z;PFd 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 Yr*{aK73{rZ3$%m5)78&qol`;+0Ko`4x&QzG literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/hotseat_scrubber_holo.9.png b/res/drawable-mdpi/hotseat_scrubber_holo.9.png index 69f74f7314f56cfaf11e52824bd1906afecaf5c8..de66649e7a2c58919973f5f6b34908dc820140d9 100644 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^hCs~5!3HF=9+zGgvMpCzWs*jEjsOG0-5bn%Js$Gq0F7txboFyt=akR{02k{lQUCw| literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^?m*1O!3HEJZfU*-q`W;{978NlC;#~W-=10IkNnYs zGYuTmXQo>;L@;%Tx>-zPPbw^^IKadyW$@qKP@)!ps@^|u6{1-oD!M + + + + \ No newline at end of file diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 428a0a73a7..4d40adadc6 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" /> - - - - + + - diff --git a/res/layout-land/search_bar.xml b/res/layout-land/search_bar.xml index e3f67a1f24..0dbfd7b353 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" /> - \ No newline at end of file + diff --git a/res/layout-port/hotseat.xml b/res/layout-port/hotseat.xml new file mode 100644 index 0000000000..88dd738674 --- /dev/null +++ b/res/layout-port/hotseat.xml @@ -0,0 +1,33 @@ + + + + + \ No newline at end of file diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index d9750dbd27..fc39034f5e 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" /> - - - - - + android:layout_gravity="bottom" /> + + diff --git a/res/layout-port/search_bar.xml b/res/layout-port/search_bar.xml index f9a202ae0f..0de290a049 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" /> @@ -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 305e730a1c..d4843933f0 100644 --- a/res/values-land/dimens.xml +++ b/res/values-land/dimens.xml @@ -17,7 +17,7 @@ 12dip - 12dip + 10dip @dimen/qsb_bar_height @@ -28,10 +28,6 @@ @dimen/qsb_bar_height @dimen/button_bar_height - 100dip - 74dip - 62dip - 80dp diff --git a/res/values-port/dimens.xml b/res/values-port/dimens.xml index c5fdd68e0c..998bdc2c27 100644 --- a/res/values-port/dimens.xml +++ b/res/values-port/dimens.xml @@ -18,16 +18,10 @@ 0dp 0dp - - 60dp - - 64dp + @dimen/qsb_bar_height + @dimen/button_bar_height 8dp - 74dip - 86dip - 4 5 -1dp diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 55518dfaeb..e093e36f8f 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -38,6 +38,15 @@ + + + + + + + + @@ -125,6 +134,7 @@ + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 083a88741c..bcef13daa3 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -16,7 +16,7 @@ - 56dp + 48dp 80dp 80dp -1dp @@ -42,14 +42,14 @@ 120px - 56dip + 80dip 20dp - 56dip + 80dip diff --git a/res/values/strings.xml b/res/values/strings.xml index dcbc6d926d..cae613ca0f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -120,6 +120,8 @@ Picture frame No more room on this Home screen. + + This widget is too large for the hotseat. Shortcut \"%s\" created. diff --git a/res/xml/default_workspace.xml b/res/xml/default_workspace.xml index 722731cc2e..9189c76e47 100644 --- a/res/xml/default_workspace.xml +++ b/res/xml/default_workspace.xml @@ -15,13 +15,19 @@ --> - + - - - + - + + + + - + + + + + + diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java index ae22507734..bd2a949429 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 d45c9ac15a..2a5f9c433c 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 7641fe7f2a..96cd22b569 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 0000000000..deab13177d --- /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 c67e90ecf4..9d7054cf46 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 b4ce0382f4..6b3763ce08 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 26f41fa537..90bd151ebc 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 bitmaps = - (ArrayList) 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()); + } + Hotseat getHotseat() { + return mHotseat; } - private void showPreviews(View anchor) { - showPreviews(anchor, 0, mWorkspace.getChildCount()); - } - - 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 bitmaps = new ArrayList(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 shortcuts, int start, int end) { - setLoadOnResume(); final Workspace workspace = mWorkspace; - for (int i=start; i= 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) { - // Move internally - final int screen = (mTargetCell[0] < 0) ? - mDragInfo.screen : indexOfChild(dropTargetLayout); + 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 + 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 @@ -2506,6 +2535,15 @@ public class Workspace extends SmoothPagedView cachedInverseMatrix.mapPoints(xy); } + /* + * 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 @@ -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 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 getWorkspaceAndHotseatCellLayouts() { + ArrayList layouts = new ArrayList(); + int screenCount = getChildCount(); for (int screen = 0; screen < screenCount; screen++) { - ViewGroup currentScreen = ((CellLayout) getChildAt(screen)).getChildrenLayout(); - int count = currentScreen.getChildCount(); + 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 getWorkspaceAndHotseatCellLayoutChildren() { + ArrayList childrenLayouts = new ArrayList(); + int screenCount = getChildCount(); + for (int screen = 0; screen < screenCount; screen++) { + childrenLayouts.add(((CellLayout) getChildAt(screen)).getChildrenLayout()); + } + if (mLauncher.getHotseat() != null) { + childrenLayouts.add(mLauncher.getHotseat().getLayout().getChildrenLayout()); + } + return childrenLayouts; + } + + public Folder getFolderForTag(Object tag) { + ArrayList 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 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 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 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 apps) { - final int screenCount = getChildCount(); - for (int i = 0; i < screenCount; i++) { - final ViewGroup layout = ((CellLayout) getChildAt(i)).getChildrenLayout(); + ArrayList 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 {