blob: ff06045404c7f533ac1c6d73fd3fcc4bacc76a77 [file] [log] [blame]
Michael Jurka8c920dd2011-01-20 14:16:56 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Michael Jurka8c920dd2011-01-20 14:16:56 -080018
19import android.app.WallpaperManager;
20import android.content.Context;
Winson Chungeecf02d2012-03-02 17:14:58 -080021import android.graphics.Canvas;
22import android.graphics.Paint;
Michael Jurka8c920dd2011-01-20 14:16:56 -080023import android.graphics.Rect;
24import android.view.View;
Michael Jurkacf6125c2011-01-28 15:20:01 -080025import android.view.ViewGroup;
Adam Cohen59400422014-03-05 18:07:04 -080026import android.view.ViewGroup.LayoutParams;
Michael Jurka8c920dd2011-01-20 14:16:56 -080027
Michael Jurkaa52570f2012-03-20 03:18:20 -070028public class ShortcutAndWidgetContainer extends ViewGroup {
Michael Jurka8c920dd2011-01-20 14:16:56 -080029 static final String TAG = "CellLayoutChildren";
30
31 // These are temporary variables to prevent having to allocate a new object just to
32 // return an (x, y) value from helper functions. Do NOT use them to maintain other state.
33 private final int[] mTmpCellXY = new int[2];
34
35 private final WallpaperManager mWallpaperManager;
36
Winson Chung5f8afe62013-08-12 16:19:28 -070037 private boolean mIsHotseatLayout;
38
Adam Cohend4844c32011-02-18 19:25:06 -080039 private int mCellWidth;
40 private int mCellHeight;
41
Michael Jurka8c920dd2011-01-20 14:16:56 -080042 private int mWidthGap;
43 private int mHeightGap;
44
Adam Cohen2374abf2013-04-16 14:56:57 -070045 private int mCountX;
Winson Chung5f8afe62013-08-12 16:19:28 -070046 private int mCountY;
Adam Cohen2374abf2013-04-16 14:56:57 -070047
48 private boolean mInvertIfRtl = false;
49
Michael Jurkaa52570f2012-03-20 03:18:20 -070050 public ShortcutAndWidgetContainer(Context context) {
Michael Jurka8c920dd2011-01-20 14:16:56 -080051 super(context);
52 mWallpaperManager = WallpaperManager.getInstance(context);
Adam Cohen2801caf2011-05-13 20:57:39 -070053 }
54
Adam Cohen2374abf2013-04-16 14:56:57 -070055 public void setCellDimensions(int cellWidth, int cellHeight, int widthGap, int heightGap,
Winson Chung5f8afe62013-08-12 16:19:28 -070056 int countX, int countY) {
Michael Jurka8c920dd2011-01-20 14:16:56 -080057 mCellWidth = cellWidth;
58 mCellHeight = cellHeight;
Michael Jurka8c920dd2011-01-20 14:16:56 -080059 mWidthGap = widthGap;
60 mHeightGap = heightGap;
Adam Cohen2374abf2013-04-16 14:56:57 -070061 mCountX = countX;
Winson Chung5f8afe62013-08-12 16:19:28 -070062 mCountY = countY;
Michael Jurka8c920dd2011-01-20 14:16:56 -080063 }
64
65 public View getChildAt(int x, int y) {
66 final int count = getChildCount();
67 for (int i = 0; i < count; i++) {
68 View child = getChildAt(i);
69 CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
70
71 if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
Adam Cohenf579b502011-04-19 17:03:08 -070072 (lp.cellY <= y) && (y < lp.cellY + lp.cellVSpan)) {
Michael Jurka8c920dd2011-01-20 14:16:56 -080073 return child;
74 }
75 }
76 return null;
77 }
78
Adam Cohen59400422014-03-05 18:07:04 -080079 public void addView(View child, int index, LayoutParams params, boolean inLayout) {
80 if (!inLayout) {
81 addView(child, index, params);
82 } else {
83 addViewInLayout(child, index, params, false);
84 }
85 }
86
Michael Jurka8c920dd2011-01-20 14:16:56 -080087 @Override
Winson Chungeecf02d2012-03-02 17:14:58 -080088 protected void dispatchDraw(Canvas canvas) {
Michael Jurka3a9fced2012-04-13 14:44:29 -070089 @SuppressWarnings("all") // suppress dead code warning
90 final boolean debug = false;
91 if (debug) {
92 // Debug drawing for hit space
Winson Chungeecf02d2012-03-02 17:14:58 -080093 Paint p = new Paint();
94 p.setColor(0x6600FF00);
95 for (int i = getChildCount() - 1; i >= 0; i--) {
96 final View child = getChildAt(i);
97 final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
98
99 canvas.drawRect(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height, p);
100 }
101 }
102 super.dispatchDraw(canvas);
103 }
104
105 @Override
Michael Jurka8c920dd2011-01-20 14:16:56 -0800106 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Michael Jurka8c920dd2011-01-20 14:16:56 -0800107 int count = getChildCount();
Adam Cohenec40b2b2013-07-23 15:52:40 -0700108
109 int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
110 int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
111 setMeasuredDimension(widthSpecSize, heightSpecSize);
112
Michael Jurka8c920dd2011-01-20 14:16:56 -0800113 for (int i = 0; i < count; i++) {
114 View child = getChildAt(i);
Vladimir Marko2824b072013-10-04 16:42:17 +0100115 if (child.getVisibility() != GONE) {
116 measureChild(child);
117 }
Michael Jurka8c920dd2011-01-20 14:16:56 -0800118 }
Michael Jurka8c920dd2011-01-20 14:16:56 -0800119 }
120
Adam Cohenbfbfd262011-06-13 16:55:12 -0700121 public void setupLp(CellLayout.LayoutParams lp) {
Adam Cohen2374abf2013-04-16 14:56:57 -0700122 lp.setup(mCellWidth, mCellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
123 mCountX);
124 }
125
126 // Set whether or not to invert the layout horizontally if the layout is in RTL mode.
127 public void setInvertIfRtl(boolean invert) {
128 mInvertIfRtl = invert;
Adam Cohenbfbfd262011-06-13 16:55:12 -0700129 }
130
Winson Chung5f8afe62013-08-12 16:19:28 -0700131 public void setIsHotseat(boolean isHotseat) {
132 mIsHotseatLayout = isHotseat;
133 }
134
Winson Chung3a6e7f32013-10-09 15:50:52 -0700135 int getCellContentWidth() {
136 final LauncherAppState app = LauncherAppState.getInstance();
137 final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
138 return Math.min(getMeasuredHeight(), mIsHotseatLayout ?
139 grid.hotseatCellWidthPx: grid.cellWidthPx);
140 }
141
Winson Chung69737c32013-10-08 17:00:19 -0700142 int getCellContentHeight() {
143 final LauncherAppState app = LauncherAppState.getInstance();
144 final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
145 return Math.min(getMeasuredHeight(), mIsHotseatLayout ?
146 grid.hotseatCellHeightPx : grid.cellHeightPx);
147 }
148
Adam Cohend5e42732011-03-28 17:33:39 -0700149 public void measureChild(View child) {
Winson Chung5f8afe62013-08-12 16:19:28 -0700150 final LauncherAppState app = LauncherAppState.getInstance();
151 final DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
Adam Cohend5e42732011-03-28 17:33:39 -0700152 final int cellWidth = mCellWidth;
153 final int cellHeight = mCellHeight;
154 CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
Adam Cohenec40b2b2013-07-23 15:52:40 -0700155 if (!lp.isFullscreen) {
156 lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
157 mCountX);
Winson Chung5f8afe62013-08-12 16:19:28 -0700158
159 if (child instanceof LauncherAppWidgetHostView) {
160 // Widgets have their own padding, so skip
161 } else {
162 // Otherwise, center the icon
Winson Chung69737c32013-10-08 17:00:19 -0700163 int cHeight = getCellContentHeight();
Winson Chung5f8afe62013-08-12 16:19:28 -0700164 int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
Winson Chungcdef0442013-09-19 17:32:58 -0700165 int cellPaddingX = (int) (grid.edgeMarginPx / 2f);
166 child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
Winson Chung5f8afe62013-08-12 16:19:28 -0700167 }
Adam Cohenec40b2b2013-07-23 15:52:40 -0700168 } else {
169 lp.x = 0;
170 lp.y = 0;
171 lp.width = getMeasuredWidth();
172 lp.height = getMeasuredHeight();
173 }
Adam Cohend5e42732011-03-28 17:33:39 -0700174 int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
175 int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
176 MeasureSpec.EXACTLY);
Adam Cohend5e42732011-03-28 17:33:39 -0700177 child.measure(childWidthMeasureSpec, childheightMeasureSpec);
178 }
179
Adam Cohen2374abf2013-04-16 14:56:57 -0700180 private boolean invertLayoutHorizontally() {
181 return mInvertIfRtl && isLayoutRtl();
182 }
183
184 public boolean isLayoutRtl() {
185 return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
186 }
187
Michael Jurka8c920dd2011-01-20 14:16:56 -0800188 @Override
189 protected void onLayout(boolean changed, int l, int t, int r, int b) {
Michael Jurka8c920dd2011-01-20 14:16:56 -0800190 int count = getChildCount();
191 for (int i = 0; i < count; i++) {
192 final View child = getChildAt(i);
193 if (child.getVisibility() != GONE) {
194 CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
Michael Jurka8c920dd2011-01-20 14:16:56 -0800195 int childLeft = lp.x;
196 int childTop = lp.y;
197 child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
198
199 if (lp.dropped) {
200 lp.dropped = false;
201
202 final int[] cellXY = mTmpCellXY;
203 getLocationOnScreen(cellXY);
204 mWallpaperManager.sendWallpaperCommand(getWindowToken(),
205 WallpaperManager.COMMAND_DROP,
206 cellXY[0] + childLeft + lp.width / 2,
207 cellXY[1] + childTop + lp.height / 2, 0, null);
Michael Jurka8c920dd2011-01-20 14:16:56 -0800208 }
209 }
210 }
211 }
212
213 @Override
Michael Jurkae6235dd2011-10-04 15:02:05 -0700214 public boolean shouldDelayChildPressedState() {
215 return false;
216 }
217
218 @Override
Michael Jurka8c920dd2011-01-20 14:16:56 -0800219 public void requestChildFocus(View child, View focused) {
220 super.requestChildFocus(child, focused);
221 if (child != null) {
222 Rect r = new Rect();
223 child.getDrawingRect(r);
224 requestRectangleOnScreen(r);
225 }
226 }
227
228 @Override
229 public void cancelLongPress() {
230 super.cancelLongPress();
231
232 // Cancel long press for all children
233 final int count = getChildCount();
234 for (int i = 0; i < count; i++) {
235 final View child = getChildAt(i);
236 child.cancelLongPress();
237 }
238 }
239
240 @Override
241 protected void setChildrenDrawingCacheEnabled(boolean enabled) {
242 final int count = getChildCount();
243 for (int i = 0; i < count; i++) {
244 final View view = getChildAt(i);
245 view.setDrawingCacheEnabled(enabled);
246 // Update the drawing caches
Adam Cohen8182e5b2011-08-01 15:43:31 -0700247 if (!view.isHardwareAccelerated() && enabled) {
Michael Jurka8c920dd2011-01-20 14:16:56 -0800248 view.buildDrawingCache(true);
249 }
250 }
251 }
252
253 @Override
254 protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
255 super.setChildrenDrawnWithCacheEnabled(enabled);
256 }
Adam Cohend4844c32011-02-18 19:25:06 -0800257}