2e6da1539b
-> Pulling out the parts of device profile which can (and need to be) initialized and accessed without access to an Activity context, ie. the invariant bits. -> The invariant bits are stored in InvariantDeviceProfile which is initialized statically from LauncherAppState. -> The DeviceProfile contains the Activity context-dependent bits, and we will create one of these for each Activity instance, and this instance is accessed through the Launcher activity. -> It's possible that we can continue to refactor this such that all appropriate dimensions can be computed without an Activity context (by only specifying orientation). This would be an extension of this CL and allow us to know exactly how launcher will look in both orientations from any context. Sets the stage for some improvements around b/19514688 Change-Id: Ia7daccf14d8ca2b9cb340b8780b684769e9f1892
246 lines
8.3 KiB
Java
246 lines
8.3 KiB
Java
/*
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.android.launcher3;
|
|
|
|
import android.app.WallpaperManager;
|
|
import android.content.Context;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Paint;
|
|
import android.graphics.Rect;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.ViewGroup.LayoutParams;
|
|
|
|
public class ShortcutAndWidgetContainer extends ViewGroup {
|
|
static final String TAG = "CellLayoutChildren";
|
|
|
|
// These are temporary variables to prevent having to allocate a new object just to
|
|
// return an (x, y) value from helper functions. Do NOT use them to maintain other state.
|
|
private final int[] mTmpCellXY = new int[2];
|
|
|
|
private final WallpaperManager mWallpaperManager;
|
|
|
|
private boolean mIsHotseatLayout;
|
|
|
|
private int mCellWidth;
|
|
private int mCellHeight;
|
|
|
|
private int mWidthGap;
|
|
private int mHeightGap;
|
|
|
|
private int mCountX;
|
|
private int mCountY;
|
|
|
|
private Launcher mLauncher;
|
|
|
|
private boolean mInvertIfRtl = false;
|
|
|
|
public ShortcutAndWidgetContainer(Context context) {
|
|
super(context);
|
|
mLauncher = (Launcher) context;
|
|
mWallpaperManager = WallpaperManager.getInstance(context);
|
|
}
|
|
|
|
public void setCellDimensions(int cellWidth, int cellHeight, int widthGap, int heightGap,
|
|
int countX, int countY) {
|
|
mCellWidth = cellWidth;
|
|
mCellHeight = cellHeight;
|
|
mWidthGap = widthGap;
|
|
mHeightGap = heightGap;
|
|
mCountX = countX;
|
|
mCountY = countY;
|
|
}
|
|
|
|
public View getChildAt(int x, int y) {
|
|
final int count = getChildCount();
|
|
for (int i = 0; i < count; i++) {
|
|
View child = getChildAt(i);
|
|
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
|
|
|
if ((lp.cellX <= x) && (x < lp.cellX + lp.cellHSpan) &&
|
|
(lp.cellY <= y) && (y < lp.cellY + lp.cellVSpan)) {
|
|
return child;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
protected void dispatchDraw(Canvas canvas) {
|
|
@SuppressWarnings("all") // suppress dead code warning
|
|
final boolean debug = false;
|
|
if (debug) {
|
|
// Debug drawing for hit space
|
|
Paint p = new Paint();
|
|
p.setColor(0x6600FF00);
|
|
for (int i = getChildCount() - 1; i >= 0; i--) {
|
|
final View child = getChildAt(i);
|
|
final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
|
|
|
canvas.drawRect(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height, p);
|
|
}
|
|
}
|
|
super.dispatchDraw(canvas);
|
|
}
|
|
|
|
@Override
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
int count = getChildCount();
|
|
|
|
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
setMeasuredDimension(widthSpecSize, heightSpecSize);
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
View child = getChildAt(i);
|
|
if (child.getVisibility() != GONE) {
|
|
measureChild(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void setupLp(CellLayout.LayoutParams lp) {
|
|
lp.setup(mCellWidth, mCellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
|
|
mCountX);
|
|
}
|
|
|
|
// Set whether or not to invert the layout horizontally if the layout is in RTL mode.
|
|
public void setInvertIfRtl(boolean invert) {
|
|
mInvertIfRtl = invert;
|
|
}
|
|
|
|
public void setIsHotseat(boolean isHotseat) {
|
|
mIsHotseatLayout = isHotseat;
|
|
}
|
|
|
|
int getCellContentWidth() {
|
|
final DeviceProfile grid = mLauncher.getDeviceProfile();
|
|
return Math.min(getMeasuredHeight(), mIsHotseatLayout ?
|
|
grid.hotseatCellWidthPx: grid.cellWidthPx);
|
|
}
|
|
|
|
int getCellContentHeight() {
|
|
final DeviceProfile grid = mLauncher.getDeviceProfile();
|
|
return Math.min(getMeasuredHeight(), mIsHotseatLayout ?
|
|
grid.hotseatCellHeightPx : grid.cellHeightPx);
|
|
}
|
|
|
|
public void measureChild(View child) {
|
|
final DeviceProfile grid = mLauncher.getDeviceProfile();
|
|
final int cellWidth = mCellWidth;
|
|
final int cellHeight = mCellHeight;
|
|
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
|
if (!lp.isFullscreen) {
|
|
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, invertLayoutHorizontally(),
|
|
mCountX);
|
|
|
|
if (child instanceof LauncherAppWidgetHostView) {
|
|
// Widgets have their own padding, so skip
|
|
} else {
|
|
// Otherwise, center the icon
|
|
int cHeight = getCellContentHeight();
|
|
int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f));
|
|
int cellPaddingX = (int) (grid.edgeMarginPx / 2f);
|
|
child.setPadding(cellPaddingX, cellPaddingY, cellPaddingX, 0);
|
|
}
|
|
} else {
|
|
lp.x = 0;
|
|
lp.y = 0;
|
|
lp.width = getMeasuredWidth();
|
|
lp.height = getMeasuredHeight();
|
|
}
|
|
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
|
|
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
|
|
MeasureSpec.EXACTLY);
|
|
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
|
|
}
|
|
|
|
public boolean invertLayoutHorizontally() {
|
|
return mInvertIfRtl && Utilities.isRtl(getResources());
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
int count = getChildCount();
|
|
for (int i = 0; i < count; i++) {
|
|
final View child = getChildAt(i);
|
|
if (child.getVisibility() != GONE) {
|
|
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
|
int childLeft = lp.x;
|
|
int childTop = lp.y;
|
|
child.layout(childLeft, childTop, childLeft + lp.width, childTop + lp.height);
|
|
|
|
if (lp.dropped) {
|
|
lp.dropped = false;
|
|
|
|
final int[] cellXY = mTmpCellXY;
|
|
getLocationOnScreen(cellXY);
|
|
mWallpaperManager.sendWallpaperCommand(getWindowToken(),
|
|
WallpaperManager.COMMAND_DROP,
|
|
cellXY[0] + childLeft + lp.width / 2,
|
|
cellXY[1] + childTop + lp.height / 2, 0, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldDelayChildPressedState() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void requestChildFocus(View child, View focused) {
|
|
super.requestChildFocus(child, focused);
|
|
if (child != null) {
|
|
Rect r = new Rect();
|
|
child.getDrawingRect(r);
|
|
requestRectangleOnScreen(r);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void cancelLongPress() {
|
|
super.cancelLongPress();
|
|
|
|
// Cancel long press for all children
|
|
final int count = getChildCount();
|
|
for (int i = 0; i < count; i++) {
|
|
final View child = getChildAt(i);
|
|
child.cancelLongPress();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void setChildrenDrawingCacheEnabled(boolean enabled) {
|
|
final int count = getChildCount();
|
|
for (int i = 0; i < count; i++) {
|
|
final View view = getChildAt(i);
|
|
view.setDrawingCacheEnabled(enabled);
|
|
// Update the drawing caches
|
|
if (!view.isHardwareAccelerated() && enabled) {
|
|
view.buildDrawingCache(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void setChildrenDrawnWithCacheEnabled(boolean enabled) {
|
|
super.setChildrenDrawnWithCacheEnabled(enabled);
|
|
}
|
|
}
|