Allow for NxM layout and in-place rotation of items on homescreen.
Currently, rotation is disabled as designs are still in flux, but the NxM grid is enabled (8x4). Change-Id: I0026f88c674719e3d67de6d6d481d2d4cd606362
This commit is contained in:
parent
6404116682
commit
aafa03cbb9
|
@ -75,6 +75,7 @@
|
|||
android:stateNotNeeded="true"
|
||||
android:theme="@style/Theme"
|
||||
android:screenOrientation="nosensor"
|
||||
android:configChanges="orientation"
|
||||
android:windowSoftInputMode="stateUnspecified|adjustPan">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
@ -29,14 +29,14 @@
|
|||
android:id="@+id/workspace"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
launcher:defaultScreen="2">
|
||||
launcher:canonicalDeviceWidth="8"
|
||||
launcher:canonicalDeviceHeight="4">
|
||||
|
||||
<include android:id="@+id/cell1" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell2" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell3" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell4" layout="@layout/workspace_screen" />
|
||||
<include android:id="@+id/cell5" layout="@layout/workspace_screen" />
|
||||
|
||||
</com.android.launcher2.Workspace>
|
||||
|
||||
<com.android.launcher2.DeleteZone
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
|
||||
<com.android.launcher2.CellLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res/com.android.launcher"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hapticFeedbackEnabled="false"
|
||||
|
||||
launcher:cellWidth="@dimen/workspace_cell_width"
|
||||
launcher:cellHeight="@dimen/workspace_cell_height"
|
||||
launcher:longAxisStartPadding="8dip"
|
||||
launcher:longAxisEndPadding="8dip"
|
||||
launcher:shortAxisStartPadding="8dip"
|
||||
launcher:shortAxisEndPadding="8dip"
|
||||
launcher:shortAxisCells="4"
|
||||
launcher:longAxisCells="8" />
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2009 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="workspace_cell_width">76dip</dimen>
|
||||
<dimen name="workspace_cell_height">76dip</dimen>
|
||||
</resources>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<style name="WorkspaceIcon.Portrait">
|
||||
<item name="android:drawablePadding">4dip</item>
|
||||
<item name="android:paddingTop">1dip</item>
|
||||
</style>
|
||||
|
||||
<style name="WorkspaceIcon.Landscape">
|
||||
<item name="android:drawablePadding">4dip</item>
|
||||
<item name="android:paddingTop">1dip</item>
|
||||
</style>
|
||||
</resources>
|
|
@ -32,6 +32,10 @@
|
|||
<declare-styleable name="Workspace">
|
||||
<!-- The first screen the workspace should display. -->
|
||||
<attr name="defaultScreen" format="integer" />
|
||||
<!-- The number of horizontal cells for the device in its natural orientation -->
|
||||
<attr name="canonicalDeviceWidth" format="integer" />
|
||||
<!-- The number of vertical cells for the device in its natural orientation -->
|
||||
<attr name="canonicalDeviceHeight" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- CellLayout specific attributes. These attributes are used to customize
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
@ -25,20 +28,16 @@ import android.graphics.Color;
|
|||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
|
@ -29,11 +33,9 @@ import android.renderscript.ProgramFragment;
|
|||
import android.renderscript.ProgramStore;
|
||||
import android.renderscript.ProgramVertex;
|
||||
import android.renderscript.RSSurfaceView;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.renderscript.RenderScript;
|
||||
import android.renderscript.RenderScriptGL;
|
||||
import android.renderscript.Sampler;
|
||||
import android.renderscript.Script;
|
||||
import android.renderscript.ScriptC;
|
||||
import android.renderscript.SimpleMesh;
|
||||
import android.renderscript.Type;
|
||||
import android.util.AttributeSet;
|
||||
|
@ -48,10 +50,6 @@ import android.view.View;
|
|||
import android.view.ViewConfiguration;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
public class AllApps3D extends RSSurfaceView
|
||||
|
|
|
@ -16,17 +16,16 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Stores the list of all applications for the all apps view.
|
||||
|
|
|
@ -16,17 +16,14 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents an app in AllAppsView.
|
||||
*/
|
||||
|
|
|
@ -16,36 +16,44 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Canvas;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewDebug;
|
||||
import android.view.ViewGroup;
|
||||
import android.app.WallpaperManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LayoutAnimationController;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
public class CellLayout extends ViewGroup {
|
||||
static final String TAG = "CellLayout";
|
||||
|
||||
private boolean mPortrait;
|
||||
|
||||
private int mCellWidth;
|
||||
private int mCellHeight;
|
||||
|
||||
|
||||
private int mLongAxisStartPadding;
|
||||
private int mLongAxisEndPadding;
|
||||
|
||||
private int mShortAxisStartPadding;
|
||||
private int mShortAxisEndPadding;
|
||||
|
||||
private int mLeftPadding;
|
||||
private int mRightPadding;
|
||||
private int mTopPadding;
|
||||
private int mBottomPadding;
|
||||
|
||||
private int mShortAxisCells;
|
||||
private int mLongAxisCells;
|
||||
|
||||
|
@ -54,7 +62,7 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
private final Rect mRect = new Rect();
|
||||
private final CellInfo mCellInfo = new CellInfo();
|
||||
|
||||
|
||||
int[] mCellXY = new int[2];
|
||||
boolean[][] mOccupied;
|
||||
|
||||
|
@ -62,8 +70,8 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
private boolean mDirtyTag;
|
||||
private boolean mLastDownOnOccupiedCell = false;
|
||||
|
||||
private final WallpaperManager mWallpaperManager;
|
||||
|
||||
private final WallpaperManager mWallpaperManager;
|
||||
|
||||
public CellLayout(Context context) {
|
||||
this(context, null);
|
||||
|
@ -79,16 +87,16 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
mCellWidth = a.getDimensionPixelSize(R.styleable.CellLayout_cellWidth, 10);
|
||||
mCellHeight = a.getDimensionPixelSize(R.styleable.CellLayout_cellHeight, 10);
|
||||
|
||||
mLongAxisStartPadding =
|
||||
|
||||
mLongAxisStartPadding =
|
||||
a.getDimensionPixelSize(R.styleable.CellLayout_longAxisStartPadding, 10);
|
||||
mLongAxisEndPadding =
|
||||
mLongAxisEndPadding =
|
||||
a.getDimensionPixelSize(R.styleable.CellLayout_longAxisEndPadding, 10);
|
||||
mShortAxisStartPadding =
|
||||
a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisStartPadding, 10);
|
||||
mShortAxisEndPadding =
|
||||
mShortAxisEndPadding =
|
||||
a.getDimensionPixelSize(R.styleable.CellLayout_shortAxisEndPadding, 10);
|
||||
|
||||
|
||||
mShortAxisCells = a.getInt(R.styleable.CellLayout_shortAxisCells, 4);
|
||||
mLongAxisCells = a.getInt(R.styleable.CellLayout_longAxisCells, 4);
|
||||
|
||||
|
@ -96,14 +104,6 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
setAlwaysDrawnWithCacheEnabled(false);
|
||||
|
||||
if (mOccupied == null) {
|
||||
if (mPortrait) {
|
||||
mOccupied = new boolean[mShortAxisCells][mLongAxisCells];
|
||||
} else {
|
||||
mOccupied = new boolean[mLongAxisCells][mShortAxisCells];
|
||||
}
|
||||
}
|
||||
|
||||
mWallpaperManager = WallpaperManager.getInstance(getContext());
|
||||
}
|
||||
|
||||
|
@ -132,14 +132,24 @@ public class CellLayout extends ViewGroup {
|
|||
return mPortrait ? mLongAxisCells : mShortAxisCells;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
||||
// Takes canonical layout parameters
|
||||
public boolean addViewToCellLayout(View child, int index, int childId, LayoutParams params) {
|
||||
final LayoutParams lp = params;
|
||||
|
||||
// Generate an id for each view, this assumes we have at most 256x256 cells
|
||||
// per workspace screen
|
||||
final LayoutParams lp = (LayoutParams) params;
|
||||
child.setId(((getId() & 0xFF) << 16) | (lp.cellX & 0xFF) << 8 | (lp.cellY & 0xFF));
|
||||
if (lp.cellX >= 0 && lp.cellX <= getCountX() - 1 && lp.cellY >= 0 && lp.cellY <= getCountY() - 1) {
|
||||
// If the horizontal or vertical span is set to -1, it is taken to
|
||||
// mean that it spans the extent of the CellLayout
|
||||
if (lp.cellHSpan < 0) lp.cellHSpan = getCountX();
|
||||
if (lp.cellVSpan < 0) lp.cellVSpan = getCountY();
|
||||
|
||||
super.addView(child, index, params);
|
||||
child.setId(childId);
|
||||
|
||||
addView(child, index, lp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,7 +195,7 @@ public class CellLayout extends ViewGroup {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mLastDownOnOccupiedCell = found;
|
||||
|
||||
if (!found) {
|
||||
|
@ -217,6 +227,7 @@ public class CellLayout extends ViewGroup {
|
|||
setTag(cellInfo);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
final int action = ev.getAction();
|
||||
|
@ -256,8 +267,8 @@ public class CellLayout extends ViewGroup {
|
|||
return info;
|
||||
}
|
||||
|
||||
private static void findIntersectingVacantCells(CellInfo cellInfo, int x, int y,
|
||||
int xCount, int yCount, boolean[][] occupied) {
|
||||
private static void findIntersectingVacantCells(CellInfo cellInfo, int x,
|
||||
int y, int xCount, int yCount, boolean[][] occupied) {
|
||||
|
||||
cellInfo.maxVacantSpanX = Integer.MIN_VALUE;
|
||||
cellInfo.maxVacantSpanXSpanY = Integer.MIN_VALUE;
|
||||
|
@ -392,21 +403,21 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
// Assume the caller will perform their own cell searching, otherwise we
|
||||
// risk causing an unnecessary rebuild after findCellForSpan()
|
||||
|
||||
|
||||
return cellInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a point, return the cell that strictly encloses that point
|
||||
* Given a point, return the cell that strictly encloses that point
|
||||
* @param x X coordinate of the point
|
||||
* @param y Y coordinate of the point
|
||||
* @param result Array of 2 ints to hold the x and y coordinate of the cell
|
||||
*/
|
||||
void pointToCellExact(int x, int y, int[] result) {
|
||||
final boolean portrait = mPortrait;
|
||||
|
||||
final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
|
||||
final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
|
||||
|
||||
final int hStartPadding = getLeftPadding();
|
||||
final int vStartPadding = getTopPadding();
|
||||
|
||||
result[0] = (x - hStartPadding) / (mCellWidth + mWidthGap);
|
||||
result[1] = (y - vStartPadding) / (mCellHeight + mHeightGap);
|
||||
|
@ -419,7 +430,7 @@ public class CellLayout extends ViewGroup {
|
|||
if (result[1] < 0) result[1] = 0;
|
||||
if (result[1] >= yAxis) result[1] = yAxis - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a point, return the cell that most closely encloses that point
|
||||
* @param x X coordinate of the point
|
||||
|
@ -432,18 +443,15 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
/**
|
||||
* Given a cell coordinate, return the point that represents the upper left corner of that cell
|
||||
*
|
||||
* @param cellX X coordinate of the cell
|
||||
*
|
||||
* @param cellX X coordinate of the cell
|
||||
* @param cellY Y coordinate of the cell
|
||||
*
|
||||
*
|
||||
* @param result Array of 2 ints to hold the x and y coordinate of the point
|
||||
*/
|
||||
void cellToPoint(int cellX, int cellY, int[] result) {
|
||||
final boolean portrait = mPortrait;
|
||||
|
||||
final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
|
||||
final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
|
||||
|
||||
final int hStartPadding = getLeftPadding();
|
||||
final int vStartPadding = getTopPadding();
|
||||
|
||||
result[0] = hStartPadding + cellX * (mCellWidth + mWidthGap);
|
||||
result[1] = vStartPadding + cellY * (mCellHeight + mHeightGap);
|
||||
|
@ -458,92 +466,117 @@ public class CellLayout extends ViewGroup {
|
|||
}
|
||||
|
||||
int getLeftPadding() {
|
||||
return mPortrait ? mShortAxisStartPadding : mLongAxisStartPadding;
|
||||
return mLeftPadding;
|
||||
}
|
||||
|
||||
int getTopPadding() {
|
||||
return mPortrait ? mLongAxisStartPadding : mShortAxisStartPadding;
|
||||
return mTopPadding;
|
||||
}
|
||||
|
||||
int getRightPadding() {
|
||||
return mPortrait ? mShortAxisEndPadding : mLongAxisEndPadding;
|
||||
return mRightPadding;
|
||||
}
|
||||
|
||||
int getBottomPadding() {
|
||||
return mPortrait ? mLongAxisEndPadding : mShortAxisEndPadding;
|
||||
return mBottomPadding;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// TODO: currently ignoring padding
|
||||
|
||||
|
||||
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
|
||||
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
|
||||
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
|
||||
if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {
|
||||
throw new RuntimeException("CellLayout cannot have UNSPECIFIED dimensions");
|
||||
}
|
||||
|
||||
final int shortAxisCells = mShortAxisCells;
|
||||
final int longAxisCells = mLongAxisCells;
|
||||
final int longAxisStartPadding = mLongAxisStartPadding;
|
||||
final int longAxisEndPadding = mLongAxisEndPadding;
|
||||
final int shortAxisStartPadding = mShortAxisStartPadding;
|
||||
final int shortAxisEndPadding = mShortAxisEndPadding;
|
||||
final int cellWidth = mCellWidth;
|
||||
final int cellHeight = mCellHeight;
|
||||
|
||||
mPortrait = heightSpecSize > widthSpecSize;
|
||||
boolean portrait = heightSpecSize > widthSpecSize;
|
||||
if (portrait != mPortrait || mOccupied == null) {
|
||||
if (portrait) {
|
||||
mOccupied = new boolean[mShortAxisCells][mLongAxisCells];
|
||||
} else {
|
||||
mOccupied = new boolean[mLongAxisCells][mShortAxisCells];
|
||||
}
|
||||
}
|
||||
mPortrait = portrait;
|
||||
|
||||
int numShortGaps = shortAxisCells - 1;
|
||||
int numLongGaps = longAxisCells - 1;
|
||||
|
||||
if (mPortrait) {
|
||||
int vSpaceLeft = heightSpecSize - longAxisStartPadding - longAxisEndPadding
|
||||
- (cellHeight * longAxisCells);
|
||||
int vSpaceLeft = heightSpecSize - mLongAxisStartPadding
|
||||
- mLongAxisEndPadding - (cellHeight * longAxisCells);
|
||||
mHeightGap = vSpaceLeft / numLongGaps;
|
||||
|
||||
int hSpaceLeft = widthSpecSize - shortAxisStartPadding - shortAxisEndPadding
|
||||
- (cellWidth * shortAxisCells);
|
||||
int hSpaceLeft = widthSpecSize - mShortAxisStartPadding
|
||||
- mShortAxisEndPadding - (cellWidth * shortAxisCells);
|
||||
if (numShortGaps > 0) {
|
||||
mWidthGap = hSpaceLeft / numShortGaps;
|
||||
} else {
|
||||
mWidthGap = 0;
|
||||
}
|
||||
|
||||
if (LauncherApplication.isInPlaceRotationEnabled()) {
|
||||
mWidthGap = mHeightGap = Math.min(mHeightGap, mWidthGap);
|
||||
mLeftPadding = mRightPadding = (widthSpecSize - cellWidth
|
||||
* shortAxisCells - (shortAxisCells - 1) * mWidthGap) / 2;
|
||||
mTopPadding = mBottomPadding = (heightSpecSize - cellHeight
|
||||
* longAxisCells - (longAxisCells - 1) * mHeightGap) / 2;
|
||||
} else {
|
||||
mLeftPadding = mShortAxisStartPadding;
|
||||
mRightPadding = mShortAxisEndPadding;
|
||||
mTopPadding = mLongAxisStartPadding;
|
||||
mBottomPadding = mLongAxisEndPadding;
|
||||
}
|
||||
} else {
|
||||
int hSpaceLeft = widthSpecSize - longAxisStartPadding - longAxisEndPadding
|
||||
- (cellWidth * longAxisCells);
|
||||
int hSpaceLeft = widthSpecSize - mLongAxisStartPadding
|
||||
- mLongAxisEndPadding - (cellWidth * longAxisCells);
|
||||
mWidthGap = hSpaceLeft / numLongGaps;
|
||||
|
||||
int vSpaceLeft = heightSpecSize - shortAxisStartPadding - shortAxisEndPadding
|
||||
- (cellHeight * shortAxisCells);
|
||||
int vSpaceLeft = heightSpecSize - mShortAxisStartPadding
|
||||
- mShortAxisEndPadding - (cellHeight * shortAxisCells);
|
||||
if (numShortGaps > 0) {
|
||||
mHeightGap = vSpaceLeft / numShortGaps;
|
||||
} else {
|
||||
mHeightGap = 0;
|
||||
}
|
||||
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
mWidthGap = mHeightGap = Math.min(mHeightGap, mWidthGap);
|
||||
mLeftPadding = mRightPadding = (widthSpecSize - cellWidth
|
||||
* longAxisCells - (longAxisCells - 1) * mWidthGap) / 2 ;
|
||||
mTopPadding = mBottomPadding = (heightSpecSize - cellHeight
|
||||
* shortAxisCells - (shortAxisCells - 1) * mHeightGap) / 2;
|
||||
} else {
|
||||
mLeftPadding = mLongAxisStartPadding;
|
||||
mRightPadding = mLongAxisEndPadding;
|
||||
mTopPadding = mShortAxisStartPadding;
|
||||
mBottomPadding = mShortAxisEndPadding;
|
||||
}
|
||||
}
|
||||
|
||||
int count = getChildCount();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap,
|
||||
mLeftPadding, mTopPadding);
|
||||
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
|
||||
MeasureSpec.EXACTLY);
|
||||
int childheightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
|
||||
MeasureSpec.EXACTLY);
|
||||
|
||||
if (mPortrait) {
|
||||
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, shortAxisStartPadding,
|
||||
longAxisStartPadding);
|
||||
} else {
|
||||
lp.setup(cellWidth, cellHeight, mWidthGap, mHeightGap, longAxisStartPadding,
|
||||
shortAxisStartPadding);
|
||||
}
|
||||
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
|
||||
int childheightMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
|
||||
child.measure(childWidthMeasureSpec, childheightMeasureSpec);
|
||||
}
|
||||
|
||||
|
@ -596,7 +629,7 @@ public class CellLayout extends ViewGroup {
|
|||
/**
|
||||
* Find a vacant area that will fit the given bounds nearest the requested
|
||||
* cell location. Uses Euclidean distance to score multiple vacant areas.
|
||||
*
|
||||
*
|
||||
* @param pixelX The X location at which you want to search for a vacant area.
|
||||
* @param pixelY The Y location at which you want to search for a vacant area.
|
||||
* @param spanX Horizontal span of the object.
|
||||
|
@ -608,12 +641,12 @@ public class CellLayout extends ViewGroup {
|
|||
*/
|
||||
int[] findNearestVacantArea(int pixelX, int pixelY, int spanX, int spanY,
|
||||
CellInfo vacantCells, int[] recycle) {
|
||||
|
||||
|
||||
// Keep track of best-scoring drop area
|
||||
final int[] bestXY = recycle != null ? recycle : new int[2];
|
||||
final int[] cellXY = mCellXY;
|
||||
double bestDistance = Double.MAX_VALUE;
|
||||
|
||||
|
||||
// Bail early if vacant cells aren't valid
|
||||
if (!vacantCells.valid) {
|
||||
return null;
|
||||
|
@ -623,17 +656,17 @@ public class CellLayout extends ViewGroup {
|
|||
final int size = vacantCells.vacantCells.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final CellInfo.VacantCell cell = vacantCells.vacantCells.get(i);
|
||||
|
||||
|
||||
// Reject if vacant cell isn't our exact size
|
||||
if (cell.spanX != spanX || cell.spanY != spanY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Score is center distance from requested pixel
|
||||
cellToPoint(cell.cellX, cell.cellY, cellXY);
|
||||
|
||||
double distance = Math.sqrt(Math.pow(cellXY[0] - pixelX, 2) +
|
||||
Math.pow(cellXY[1] - pixelY, 2));
|
||||
|
||||
double distance = Math.sqrt(Math.pow(cellXY[0] - pixelX, 2)
|
||||
+ Math.pow(cellXY[1] - pixelY, 2));
|
||||
if (distance <= bestDistance) {
|
||||
bestDistance = distance;
|
||||
bestXY[0] = cell.cellX;
|
||||
|
@ -641,25 +674,22 @@ public class CellLayout extends ViewGroup {
|
|||
}
|
||||
}
|
||||
|
||||
// Return null if no suitable location found
|
||||
// Return null if no suitable location found
|
||||
if (bestDistance < Double.MAX_VALUE) {
|
||||
return bestXY;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drop a child at the specified position
|
||||
* Mark a child as having been dropped.
|
||||
*
|
||||
* @param child The child that is being dropped
|
||||
* @param targetXY Destination area to move to
|
||||
*/
|
||||
void onDropChild(View child, int[] targetXY) {
|
||||
void onDropChild(View child) {
|
||||
if (child != null) {
|
||||
LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
lp.cellX = targetXY[0];
|
||||
lp.cellY = targetXY[1];
|
||||
lp.isDragging = false;
|
||||
lp.dropped = true;
|
||||
mDragRect.setEmpty();
|
||||
|
@ -678,7 +708,7 @@ public class CellLayout extends ViewGroup {
|
|||
|
||||
/**
|
||||
* Start dragging the specified child
|
||||
*
|
||||
*
|
||||
* @param child The child that is being dragged
|
||||
*/
|
||||
void onDragChild(View child) {
|
||||
|
@ -686,13 +716,13 @@ public class CellLayout extends ViewGroup {
|
|||
lp.isDragging = true;
|
||||
mDragRect.setEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Drag a child over the specified position
|
||||
*
|
||||
*
|
||||
* @param child The child that is being dropped
|
||||
* @param cellX The child's new x cell location
|
||||
* @param cellY The child's new y cell location
|
||||
* @param cellY The child's new y cell location
|
||||
*/
|
||||
void onDragOverChild(View child, int cellX, int cellY) {
|
||||
int[] cellXY = mCellXY;
|
||||
|
@ -701,39 +731,38 @@ public class CellLayout extends ViewGroup {
|
|||
cellToRect(cellXY[0], cellXY[1], lp.cellHSpan, lp.cellVSpan, mDragRect);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes a bounding rectangle for a range of cells
|
||||
*
|
||||
*
|
||||
* @param cellX X coordinate of upper left corner expressed as a cell position
|
||||
* @param cellY Y coordinate of upper left corner expressed as a cell position
|
||||
* @param cellHSpan Width in cells
|
||||
* @param cellHSpan Width in cells
|
||||
* @param cellVSpan Height in cells
|
||||
* @param dragRect Rectnagle into which to put the results
|
||||
*/
|
||||
public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF dragRect) {
|
||||
final boolean portrait = mPortrait;
|
||||
final int cellWidth = mCellWidth;
|
||||
final int cellHeight = mCellHeight;
|
||||
final int widthGap = mWidthGap;
|
||||
final int heightGap = mHeightGap;
|
||||
|
||||
final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
|
||||
final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
|
||||
|
||||
|
||||
final int hStartPadding = getLeftPadding();
|
||||
final int vStartPadding = getTopPadding();
|
||||
|
||||
int width = cellHSpan * cellWidth + ((cellHSpan - 1) * widthGap);
|
||||
int height = cellVSpan * cellHeight + ((cellVSpan - 1) * heightGap);
|
||||
|
||||
int x = hStartPadding + cellX * (cellWidth + widthGap);
|
||||
int y = vStartPadding + cellY * (cellHeight + heightGap);
|
||||
|
||||
|
||||
dragRect.set(x, y, x + width, y + height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the required horizontal and vertical cell spans to always
|
||||
* Computes the required horizontal and vertical cell spans to always
|
||||
* fit the given rectangle.
|
||||
*
|
||||
*
|
||||
* @param width Width in pixels
|
||||
* @param height Height in pixels
|
||||
*/
|
||||
|
@ -758,7 +787,7 @@ public class CellLayout extends ViewGroup {
|
|||
* @param vacant Holds the x and y coordinate of the vacant cell
|
||||
* @param spanX Horizontal cell span.
|
||||
* @param spanY Vertical cell span.
|
||||
*
|
||||
*
|
||||
* @return True if a vacant cell was found
|
||||
*/
|
||||
public boolean getVacantCell(int[] vacant, int spanX, int spanY) {
|
||||
|
@ -852,6 +881,17 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
return new CellLayout.LayoutParams(p);
|
||||
}
|
||||
|
||||
public static class CellLayoutAnimationController extends LayoutAnimationController {
|
||||
public CellLayoutAnimationController(Animation animation, float delay) {
|
||||
super(animation, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getDelayForView(View view) {
|
||||
return (int) (Math.random() * 150);
|
||||
}
|
||||
}
|
||||
|
||||
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
|
||||
/**
|
||||
* Horizontal location of the item in the grid.
|
||||
|
@ -876,7 +916,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
*/
|
||||
@ViewDebug.ExportedProperty
|
||||
public int cellVSpan;
|
||||
|
||||
|
||||
/**
|
||||
* Is this item currently being dragged
|
||||
*/
|
||||
|
@ -902,7 +942,15 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
cellHSpan = 1;
|
||||
cellVSpan = 1;
|
||||
}
|
||||
|
||||
|
||||
public LayoutParams(LayoutParams source) {
|
||||
super(source);
|
||||
this.cellX = source.cellX;
|
||||
this.cellY = source.cellY;
|
||||
this.cellHSpan = source.cellHSpan;
|
||||
this.cellVSpan = source.cellVSpan;
|
||||
}
|
||||
|
||||
public LayoutParams(int cellX, int cellY, int cellHSpan, int cellVSpan) {
|
||||
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||
this.cellX = cellX;
|
||||
|
@ -913,12 +961,12 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
|
||||
public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap,
|
||||
int hStartPadding, int vStartPadding) {
|
||||
|
||||
|
||||
final int myCellHSpan = cellHSpan;
|
||||
final int myCellVSpan = cellVSpan;
|
||||
final int myCellX = cellX;
|
||||
final int myCellY = cellY;
|
||||
|
||||
|
||||
width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
|
||||
leftMargin - rightMargin;
|
||||
height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
|
||||
|
@ -927,14 +975,18 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
|
||||
y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "(" + this.cellX + ", " + this.cellY + ")";
|
||||
}
|
||||
}
|
||||
|
||||
static final class CellInfo implements ContextMenu.ContextMenuInfo {
|
||||
/**
|
||||
* See View.AttachInfo.InvalidateInfo for futher explanations about
|
||||
* the recycling mechanism. In this case, we recycle the vacant cells
|
||||
* instances because up to several hundreds can be instanciated when
|
||||
* the user long presses an empty cell.
|
||||
* See View.AttachInfo.InvalidateInfo for futher explanations about the
|
||||
* recycling mechanism. In this case, we recycle the vacant cells
|
||||
* instances because up to several hundreds can be instanciated when the
|
||||
* user long presses an empty cell.
|
||||
*/
|
||||
static final class VacantCell {
|
||||
int cellX;
|
||||
|
@ -945,7 +997,7 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
// We can create up to 523 vacant cells on a 4x4 grid, 100 seems
|
||||
// like a reasonable compromise given the size of a VacantCell and
|
||||
// the fact that the user is not likely to touch an empty 4x4 grid
|
||||
// very often
|
||||
// very often
|
||||
private static final int POOL_LIMIT = 100;
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
|
@ -980,8 +1032,8 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX=" + spanX +
|
||||
", spanY=" + spanY + "]";
|
||||
return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX="
|
||||
+ spanX + ", spanY=" + spanY + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1056,9 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
final ArrayList<VacantCell> list = vacantCells;
|
||||
final int count = list.size();
|
||||
|
||||
for (int i = 0; i < count; i++) list.get(i).release();
|
||||
for (int i = 0; i < count; i++) {
|
||||
list.get(i).release();
|
||||
}
|
||||
|
||||
list.clear();
|
||||
}
|
||||
|
@ -1078,15 +1132,17 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
}
|
||||
}
|
||||
|
||||
if (clear) clearVacantCells();
|
||||
if (clear) {
|
||||
clearVacantCells();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Cell[view=" + (cell == null ? "null" : cell.getClass()) + ", x=" + cellX +
|
||||
", y=" + cellY + "]";
|
||||
return "Cell[view=" + (cell == null ? "null" : cell.getClass())
|
||||
+ ", x=" + cellX + ", y=" + cellY + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1094,5 +1150,3 @@ out: for (int i = x; i < x + spanX - 1 && x < xCount; i++) {
|
|||
return mLastDownOnOccupiedCell;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,13 +16,12 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.MessageQueue;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Queue of things to run on a looper thread. Items posted with {@link #post} will not
|
||||
|
|
|
@ -18,20 +18,15 @@
|
|||
package com.android.launcher2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.os.IBinder;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManagerImpl;
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ import android.graphics.Rect;
|
|||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ContentResolver;
|
||||
import android.database.Cursor;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
@ -86,38 +86,24 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
|||
private static boolean findEmptyCell(Context context, int[] xy, int screen) {
|
||||
final int xCount = Launcher.NUMBER_CELLS_X;
|
||||
final int yCount = Launcher.NUMBER_CELLS_Y;
|
||||
|
||||
boolean[][] occupied = new boolean[xCount][yCount];
|
||||
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
|
||||
new String[] { LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
|
||||
LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY },
|
||||
LauncherSettings.Favorites.SCREEN + "=?",
|
||||
new String[] { String.valueOf(screen) }, null);
|
||||
|
||||
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
|
||||
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
|
||||
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
|
||||
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
|
||||
|
||||
try {
|
||||
while (c.moveToNext()) {
|
||||
int cellX = c.getInt(cellXIndex);
|
||||
int cellY = c.getInt(cellYIndex);
|
||||
int spanX = c.getInt(spanXIndex);
|
||||
int spanY = c.getInt(spanYIndex);
|
||||
|
||||
ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
|
||||
ItemInfo item = null;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
|
||||
return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied);
|
||||
|
|
|
@ -112,6 +112,11 @@ class ItemInfo {
|
|||
}
|
||||
}
|
||||
|
||||
void updateValuesWithCoordinates(ContentValues values, int cellX, int cellY) {
|
||||
values.put(LauncherSettings.Favorites.CELLX, cellX);
|
||||
values.put(LauncherSettings.Favorites.CELLY, cellY);
|
||||
}
|
||||
|
||||
static byte[] flattenBitmap(Bitmap bitmap) {
|
||||
// Try go guesstimate how much space the icon will take when serialized
|
||||
// to avoid unnecessary allocations/copies during the write.
|
||||
|
|
|
@ -16,8 +16,13 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
|
@ -36,6 +41,7 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -67,6 +73,7 @@ import android.view.Menu;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.View.OnLongClickListener;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
@ -77,13 +84,8 @@ import android.widget.PopupWindow;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import com.android.common.Search;
|
||||
import com.android.launcher.R;
|
||||
|
||||
/**
|
||||
* Default launcher application.
|
||||
|
@ -211,10 +213,17 @@ public final class Launcher extends Activity
|
|||
private Drawable[] mHotseatIcons = null;
|
||||
private CharSequence[] mHotseatLabels = null;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (LauncherApplication.isInPlaceRotationEnabled()) {
|
||||
// hide the status bar (temporary until we get the status bar design figured out)
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
|
||||
}
|
||||
|
||||
LauncherApplication app = ((LauncherApplication)getApplication());
|
||||
mModel = app.setLauncher(this);
|
||||
mIconCache = app.getIconCache();
|
||||
|
@ -232,8 +241,8 @@ public final class Launcher extends Activity
|
|||
loadHotseats();
|
||||
checkForLocaleChange();
|
||||
setWallpaperDimension();
|
||||
|
||||
setContentView(R.layout.launcher);
|
||||
|
||||
setupViews();
|
||||
|
||||
registerContentObservers();
|
||||
|
@ -259,6 +268,19 @@ public final class Launcher extends Activity
|
|||
registerReceiver(mCloseSystemDialogsReceiver, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
// TODO Auto-generated method stub
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (LauncherApplication.isInPlaceRotationEnabled()) {
|
||||
mModel.updateOrientation();
|
||||
mWorkspace.refreshWorkspaceChildren();
|
||||
mWorkspace.rotateCurrentScreensChildren();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkForLocaleChange() {
|
||||
final LocaleConfiguration localeConfiguration = new LocaleConfiguration();
|
||||
readConfiguration(this, localeConfiguration);
|
||||
|
@ -419,7 +441,7 @@ public final class Launcher extends Activity
|
|||
// note: if the user launches this without a default set, she
|
||||
// will always be taken to the default URL above; this is
|
||||
// unavoidable as we must specify a valid URL in order for the
|
||||
// chooser to appear, and once the user selects something, that
|
||||
// chooser to appear, and once the user selects something, that
|
||||
// URL is unavoidably sent to the chosen app.
|
||||
} else {
|
||||
try {
|
||||
|
@ -429,7 +451,7 @@ public final class Launcher extends Activity
|
|||
// bogus; leave intent=null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (intent == null) {
|
||||
mHotseats[i] = null;
|
||||
mHotseatLabels[i] = getText(R.string.activity_not_found);
|
||||
|
@ -437,15 +459,15 @@ public final class Launcher extends Activity
|
|||
}
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " initial intent=["
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " initial intent=["
|
||||
+ intent.toUri(Intent.URI_INTENT_SCHEME)
|
||||
+ "]");
|
||||
}
|
||||
|
||||
ResolveInfo bestMatch = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
List<ResolveInfo> allMatches = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if (LOGD) {
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "Best match for intent: " + bestMatch);
|
||||
Log.d(TAG, "All matches: ");
|
||||
for (ResolveInfo ri : allMatches) {
|
||||
|
@ -454,8 +476,8 @@ public final class Launcher extends Activity
|
|||
}
|
||||
// did this resolve to a single app, or the resolver?
|
||||
if (allMatches.size() == 0 || bestMatch == null) {
|
||||
// can't find any activity to handle this. let's leave the
|
||||
// intent as-is and let Launcher show a toast when it fails
|
||||
// can't find any activity to handle this. let's leave the
|
||||
// intent as-is and let Launcher show a toast when it fails
|
||||
// to launch.
|
||||
mHotseats[i] = intent;
|
||||
|
||||
|
@ -471,7 +493,7 @@ public final class Launcher extends Activity
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!found) {
|
||||
if (LOGD) Log.d(TAG, "Multiple options, no default yet");
|
||||
// the bestMatch is probably the ResolveActivity, meaning the
|
||||
|
@ -496,8 +518,8 @@ public final class Launcher extends Activity
|
|||
}
|
||||
|
||||
if (LOGD) {
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " final intent=["
|
||||
Log.d(TAG, "loadHotseats: hotseat " + i
|
||||
+ " final intent=["
|
||||
+ ((mHotseats[i] == null)
|
||||
? "null"
|
||||
: mHotseats[i].toUri(Intent.URI_INTENT_SCHEME))
|
||||
|
@ -712,7 +734,7 @@ public final class Launcher extends Activity
|
|||
mAllAppsGrid.setDragController(dragController);
|
||||
((View) mAllAppsGrid).setWillNotDraw(false); // We don't want a hole punched in our window.
|
||||
// Manage focusability manually since this thing is always visible
|
||||
((View) mAllAppsGrid).setFocusable(false);
|
||||
((View) mAllAppsGrid).setFocusable(false);
|
||||
|
||||
mWorkspace = (Workspace) dragLayer.findViewById(R.id.workspace);
|
||||
final Workspace workspace = mWorkspace;
|
||||
|
@ -757,7 +779,7 @@ public final class Launcher extends Activity
|
|||
|
||||
deleteZone.setLauncher(this);
|
||||
deleteZone.setDragController(dragController);
|
||||
int deleteZoneHandleId = isScreenXLarge() ? R.id.add_button : R.id.all_apps_button_cluster;
|
||||
int deleteZoneHandleId = LauncherApplication.isScreenXLarge() ? R.id.add_button : R.id.all_apps_button_cluster;
|
||||
deleteZone.setHandle(findViewById(deleteZoneHandleId));
|
||||
|
||||
dragController.setDragScoller(workspace);
|
||||
|
@ -805,7 +827,7 @@ public final class Launcher extends Activity
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a view representing a shortcut.
|
||||
*
|
||||
|
@ -1048,7 +1070,7 @@ public final class Launcher extends Activity
|
|||
unbindDesktopItems();
|
||||
|
||||
getContentResolver().unregisterContentObserver(mWidgetObserver);
|
||||
|
||||
|
||||
dismissPreview(mPreviousView);
|
||||
dismissPreview(mNextView);
|
||||
|
||||
|
@ -1179,11 +1201,6 @@ public final class Launcher extends Activity
|
|||
showAddDialog(mMenuAddInfo);
|
||||
}
|
||||
|
||||
boolean isScreenXLarge() {
|
||||
int screenLayout = getResources().getConfiguration().screenLayout;
|
||||
return (screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
}
|
||||
|
||||
void addAppWidgetFromDrop(ComponentName appWidgetProvider, CellLayout.CellInfo cellInfo) {
|
||||
mAddItemCellInfo = cellInfo;
|
||||
int appWidgetId = getAppWidgetHost().allocateAppWidgetId();
|
||||
|
@ -1518,7 +1535,7 @@ public final class Launcher extends Activity
|
|||
+ "tag="+ tag + " intent=" + intent, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void startActivityForResultSafely(Intent intent, int requestCode) {
|
||||
try {
|
||||
startActivityForResult(intent, requestCode);
|
||||
|
@ -1563,7 +1580,7 @@ public final class Launcher extends Activity
|
|||
*
|
||||
* @param folderInfo The FolderInfo describing the folder to open.
|
||||
*/
|
||||
private void openFolder(FolderInfo folderInfo) {
|
||||
public void openFolder(FolderInfo folderInfo) {
|
||||
Folder openFolder;
|
||||
|
||||
if (folderInfo instanceof UserFolderInfo) {
|
||||
|
@ -1580,7 +1597,8 @@ public final class Launcher extends Activity
|
|||
openFolder.bind(folderInfo);
|
||||
folderInfo.opened = true;
|
||||
|
||||
mWorkspace.addInScreen(openFolder, folderInfo.screen, 0, 0, 4, 4);
|
||||
mWorkspace.addInFullScreen(openFolder, folderInfo.screen);
|
||||
|
||||
openFolder.onOpen();
|
||||
}
|
||||
|
||||
|
@ -1678,9 +1696,9 @@ public final class Launcher extends Activity
|
|||
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);
|
||||
|
@ -1731,7 +1749,7 @@ public final class Launcher extends Activity
|
|||
preview.addView(image,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
bitmaps.add(bitmap);
|
||||
bitmaps.add(bitmap);
|
||||
}
|
||||
|
||||
final PopupWindow p = new PopupWindow(this);
|
||||
|
@ -1752,7 +1770,7 @@ public final class Launcher extends Activity
|
|||
|
||||
anchor.setTag(p);
|
||||
anchor.setTag(R.id.workspace, preview);
|
||||
anchor.setTag(R.id.icon, bitmaps);
|
||||
anchor.setTag(R.id.icon, bitmaps);
|
||||
}
|
||||
|
||||
class PreviewTouchHandler implements View.OnClickListener, Runnable, View.OnFocusChangeListener {
|
||||
|
@ -1768,7 +1786,7 @@ public final class Launcher extends Activity
|
|||
}
|
||||
|
||||
public void run() {
|
||||
dismissPreview(mAnchor);
|
||||
dismissPreview(mAnchor);
|
||||
}
|
||||
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
|
@ -1939,7 +1957,7 @@ public final class Launcher extends Activity
|
|||
|
||||
((View) mAllAppsGrid).setFocusable(true);
|
||||
((View) mAllAppsGrid).requestFocus();
|
||||
|
||||
|
||||
// TODO: fade these two too
|
||||
mDeleteZone.setVisibility(View.GONE);
|
||||
}
|
||||
|
@ -2100,7 +2118,7 @@ public final class Launcher extends Activity
|
|||
}
|
||||
|
||||
public void onShow(DialogInterface dialog) {
|
||||
mWaitingForResult = true;
|
||||
mWaitingForResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.app.Application;
|
|||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Handler;
|
||||
import dalvik.system.VMRuntime;
|
||||
|
@ -27,6 +28,8 @@ import dalvik.system.VMRuntime;
|
|||
public class LauncherApplication extends Application {
|
||||
public LauncherModel mModel;
|
||||
public IconCache mIconCache;
|
||||
private static boolean sIsScreenXLarge;
|
||||
private static final boolean ENABLE_ROTATION = false;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
@ -36,6 +39,7 @@ public class LauncherApplication extends Application {
|
|||
|
||||
mIconCache = new IconCache(this);
|
||||
mModel = new LauncherModel(this, mIconCache);
|
||||
sIsScreenXLarge = (getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE;
|
||||
|
||||
// Register intent receivers
|
||||
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
|
||||
|
@ -89,4 +93,12 @@ public class LauncherApplication extends Application {
|
|||
LauncherModel getModel() {
|
||||
return mModel;
|
||||
}
|
||||
|
||||
public static boolean isInPlaceRotationEnabled() {
|
||||
return sIsScreenXLarge && ENABLE_ROTATION;
|
||||
}
|
||||
|
||||
public static boolean isScreenXLarge() {
|
||||
return sIsScreenXLarge;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,15 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -23,9 +32,9 @@ import android.content.ComponentName;
|
|||
import android.content.ContentProviderClient;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.Intent.ShortcutIconResource;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ProviderInfo;
|
||||
|
@ -38,20 +47,10 @@ import android.net.Uri;
|
|||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
|
@ -91,6 +90,8 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
|
||||
private Bitmap mDefaultIcon;
|
||||
|
||||
private static LauncherModelOrientationHelper mModelOrientationHelper;
|
||||
|
||||
public interface Callbacks {
|
||||
public int getCurrentWorkspaceScreen();
|
||||
public void startBinding();
|
||||
|
@ -109,6 +110,7 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
mApp = app;
|
||||
mAllAppsList = new AllAppsList(iconCache);
|
||||
mIconCache = iconCache;
|
||||
mModelOrientationHelper = new LauncherModelOrientationHelper(mApp);
|
||||
|
||||
mDefaultIcon = Utilities.createIconBitmap(
|
||||
app.getPackageManager().getDefaultActivityIcon(), app);
|
||||
|
@ -141,11 +143,20 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
static int getCurrentOrientation() {
|
||||
return mModelOrientationHelper.getCurrentOrientation();
|
||||
}
|
||||
|
||||
static int getPreviousOrientationRelativeToCurrent() {
|
||||
return mModelOrientationHelper.getPreviousOrientationRelativeToCurrent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move an item in the DB to a new <container, screen, cellX, cellY>
|
||||
*/
|
||||
static void moveItemInDatabase(Context context, ItemInfo item, long container, int screen,
|
||||
int cellX, int cellY) {
|
||||
|
||||
item.container = container;
|
||||
item.screen = screen;
|
||||
item.cellX = cellX;
|
||||
|
@ -153,10 +164,11 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
|
||||
final ContentValues values = new ContentValues();
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
final LauncherModelOrientationHelper.Coordinates coord = mModelOrientationHelper.getCanonicalCoordinates(item);
|
||||
|
||||
values.put(LauncherSettings.Favorites.CONTAINER, item.container);
|
||||
values.put(LauncherSettings.Favorites.CELLX, item.cellX);
|
||||
values.put(LauncherSettings.Favorites.CELLY, item.cellY);
|
||||
values.put(LauncherSettings.Favorites.CELLX, coord.x);
|
||||
values.put(LauncherSettings.Favorites.CELLY, coord.y);
|
||||
values.put(LauncherSettings.Favorites.SCREEN, item.screen);
|
||||
|
||||
cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
|
||||
|
@ -180,6 +192,48 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ItemInfo array containing all the items in the LauncherModel.
|
||||
* The ItemInfo.id is not set through this function.
|
||||
*/
|
||||
static ArrayList<ItemInfo> getItemsInLocalCoordinates(Context context) {
|
||||
ArrayList<ItemInfo> items = new ArrayList<ItemInfo>();
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, new String[] {
|
||||
LauncherSettings.Favorites.ITEM_TYPE, LauncherSettings.Favorites.CONTAINER,
|
||||
LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
|
||||
LauncherSettings.Favorites.SPANX, LauncherSettings.Favorites.SPANY }, null, null, null);
|
||||
|
||||
final int itemTypeIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.ITEM_TYPE);
|
||||
final int containerIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CONTAINER);
|
||||
final int screenIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SCREEN);
|
||||
final int cellXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLX);
|
||||
final int cellYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.CELLY);
|
||||
final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX);
|
||||
final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY);
|
||||
|
||||
try {
|
||||
while (c.moveToNext()) {
|
||||
ItemInfo item = new ItemInfo();
|
||||
item.cellX = c.getInt(cellXIndex);
|
||||
item.cellY = c.getInt(cellYIndex);
|
||||
item.spanX = c.getInt(spanXIndex);
|
||||
item.spanY = c.getInt(spanYIndex);
|
||||
item.container = c.getInt(containerIndex);
|
||||
item.itemType = c.getInt(itemTypeIndex);
|
||||
item.screen = c.getInt(screenIndex);
|
||||
|
||||
items.add(item);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
items.clear();
|
||||
} finally {
|
||||
c.close();
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a folder in the db, creating the FolderInfo if necessary, and adding it to folderList.
|
||||
*/
|
||||
|
@ -210,12 +264,13 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
break;
|
||||
}
|
||||
|
||||
final LauncherModelOrientationHelper.Coordinates coord = mModelOrientationHelper.getLocalCoordinates(c.getInt(cellXIndex), c.getInt(cellYIndex), 1, 1);
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
folderInfo.id = id;
|
||||
folderInfo.container = c.getInt(containerIndex);
|
||||
folderInfo.screen = c.getInt(screenIndex);
|
||||
folderInfo.cellX = c.getInt(cellXIndex);
|
||||
folderInfo.cellY = c.getInt(cellYIndex);
|
||||
folderInfo.cellX = coord.x;
|
||||
folderInfo.cellY = coord.y;
|
||||
|
||||
return folderInfo;
|
||||
}
|
||||
|
@ -239,9 +294,12 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
|
||||
final ContentValues values = new ContentValues();
|
||||
final ContentResolver cr = context.getContentResolver();
|
||||
|
||||
item.onAddToDatabase(values);
|
||||
|
||||
// update the values to be written with their canonical counterparts
|
||||
final LauncherModelOrientationHelper.Coordinates coord = mModelOrientationHelper.getCanonicalCoordinates(item);
|
||||
item.updateValuesWithCoordinates(values, coord.x, coord.y);
|
||||
|
||||
Uri result = cr.insert(notify ? LauncherSettings.Favorites.CONTENT_URI :
|
||||
LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, values);
|
||||
|
||||
|
@ -250,6 +308,44 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new unique child id, for a given cell span across all layouts.
|
||||
*/
|
||||
static int getCanonicalCellLayoutChildId(int cellId, int screen, int localCellX, int localCellY, int spanX, int spanY) {
|
||||
if (LauncherApplication.isInPlaceRotationEnabled()) {
|
||||
LauncherModelOrientationHelper.Coordinates coord = mModelOrientationHelper.getCanonicalCoordinates(localCellX, localCellY, spanX, spanY);
|
||||
return ((screen & 0xFF) << 16) | (coord.x & 0xFF) << 8 | (coord.y & 0xFF);
|
||||
} else {
|
||||
return ((cellId & 0xFF) << 16) | (localCellX & 0xFF) << 8 | (localCellY & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience functions to help return the local device width and height.
|
||||
*/
|
||||
static int getLocalDeviceWidth() {
|
||||
return mModelOrientationHelper.getLocalDeviceWidth();
|
||||
}
|
||||
|
||||
static int getLocalDeviceHeight() {
|
||||
return mModelOrientationHelper.getLocalDeviceHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the new local coordinates given the local coordinates from the previous orientation.
|
||||
*/
|
||||
static LauncherModelOrientationHelper.Coordinates getLocalCoordinatesFromPreviousLocalCoordinates(CellLayout.LayoutParams lp) {
|
||||
return mModelOrientationHelper.getLocalCoordinatesFromPreviousLocalCoordinates(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the model orientation helper to take into account the current layout dimensions
|
||||
* when performing local/canonical coordinate transformations.
|
||||
*/
|
||||
static void updateWorkspaceLayoutCells(int shortAxisCellCount, int longAxisCellCount) {
|
||||
mModelOrientationHelper.updateDeviceDimensions(shortAxisCellCount, longAxisCellCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an item to the database in a specified container.
|
||||
*/
|
||||
|
@ -259,6 +355,10 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
|
||||
item.onAddToDatabase(values);
|
||||
|
||||
// update the values to be written with their canonical counterparts
|
||||
final LauncherModelOrientationHelper.Coordinates coord = mModelOrientationHelper.getCanonicalCoordinates(item);
|
||||
item.updateValuesWithCoordinates(values, coord.x, coord.y);
|
||||
|
||||
cr.update(LauncherSettings.Favorites.getContentUri(item.id, false), values, null, null);
|
||||
}
|
||||
|
||||
|
@ -293,13 +393,18 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
public void updateOrientation() {
|
||||
// we update the LauncherModelOrientationHelper orientation whenever we re-initialize
|
||||
mModelOrientationHelper.updateOrientation(mApp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call from the handler for ACTION_PACKAGE_ADDED, ACTION_PACKAGE_REMOVED and
|
||||
* ACTION_PACKAGE_CHANGED.
|
||||
*/
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (DEBUG_LOADERS) Log.d(TAG, "onReceive intent=" + intent);
|
||||
|
||||
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (Intent.ACTION_PACKAGE_CHANGED.equals(action)
|
||||
|
@ -343,7 +448,6 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
||||
enqueuePackageUpdated(new PackageUpdatedTask(
|
||||
PackageUpdatedTask.OP_UNAVAILABLE, packages));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,7 +553,7 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
if (DEBUG_LOADERS) {
|
||||
Log.d(TAG, "waited "
|
||||
+ (SystemClock.uptimeMillis()-workspaceWaitTime)
|
||||
+ (SystemClock.uptimeMillis()-workspaceWaitTime)
|
||||
+ "ms for previous step to finish binding");
|
||||
}
|
||||
}
|
||||
|
@ -469,7 +573,6 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
android.os.Process.setThreadPriority(mIsLaunching
|
||||
? Process.THREAD_PRIORITY_DEFAULT : Process.THREAD_PRIORITY_BACKGROUND);
|
||||
}
|
||||
|
||||
if (loadWorkspaceFirst) {
|
||||
if (DEBUG_LOADERS) Log.d(TAG, "step 1: loading workspace");
|
||||
loadAndBindWorkspace();
|
||||
|
@ -571,14 +674,13 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int x = item.cellX; x < (item.cellX+item.spanX); x++) {
|
||||
for (int y = item.cellY; y < (item.cellY+item.spanY); y++) {
|
||||
if (occupied[item.screen][x][y] != null) {
|
||||
Log.e(TAG, "Error loading shortcut " + item
|
||||
+ " into cell (" + item.screen + ":"
|
||||
+ " into cell (" + item.screen + ":"
|
||||
+ x + "," + y
|
||||
+ ") occupied by "
|
||||
+ ") occupied by "
|
||||
+ occupied[item.screen][x][y]);
|
||||
return false;
|
||||
}
|
||||
|
@ -645,6 +747,11 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
final int displayModeIndex = c.getColumnIndexOrThrow(
|
||||
LauncherSettings.Favorites.DISPLAY_MODE);
|
||||
|
||||
|
||||
LauncherModelOrientationHelper.Coordinates localCoords;
|
||||
int cellX;
|
||||
int cellY;
|
||||
|
||||
ShortcutInfo info;
|
||||
String intentDescription;
|
||||
LauncherAppWidgetInfo appWidgetInfo;
|
||||
|
@ -678,13 +785,17 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
if (info != null) {
|
||||
updateSavedIcon(context, info, c, iconIndex);
|
||||
|
||||
cellX = c.getInt(cellXIndex);
|
||||
cellY = c.getInt(cellYIndex);
|
||||
localCoords = mModelOrientationHelper.getLocalCoordinates(cellX, cellY, 1, 1);
|
||||
|
||||
info.intent = intent;
|
||||
info.id = c.getLong(idIndex);
|
||||
container = c.getInt(containerIndex);
|
||||
info.container = container;
|
||||
info.screen = c.getInt(screenIndex);
|
||||
info.cellX = c.getInt(cellXIndex);
|
||||
info.cellY = c.getInt(cellYIndex);
|
||||
info.cellX = localCoords.x;
|
||||
info.cellY = localCoords.y;
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, info)) {
|
||||
|
@ -718,20 +829,22 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
id = c.getLong(idIndex);
|
||||
UserFolderInfo folderInfo = findOrMakeUserFolder(mFolders, id);
|
||||
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
cellX = c.getInt(cellXIndex);
|
||||
cellY = c.getInt(cellYIndex);
|
||||
localCoords = mModelOrientationHelper.getLocalCoordinates(cellX, cellY, 1, 1);
|
||||
|
||||
folderInfo.title = c.getString(titleIndex);
|
||||
folderInfo.id = id;
|
||||
container = c.getInt(containerIndex);
|
||||
folderInfo.container = container;
|
||||
folderInfo.screen = c.getInt(screenIndex);
|
||||
folderInfo.cellX = c.getInt(cellXIndex);
|
||||
folderInfo.cellY = c.getInt(cellYIndex);
|
||||
folderInfo.cellX = localCoords.x;
|
||||
folderInfo.cellY = localCoords.y;
|
||||
|
||||
// check & update map of what's occupied
|
||||
if (!checkItemPlacement(occupied, folderInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (container) {
|
||||
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
|
||||
mItems.add(folderInfo);
|
||||
|
@ -754,7 +867,6 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
itemsToRemove.add(id);
|
||||
} else {
|
||||
LiveFolderInfo liveFolderInfo = findOrMakeLiveFolder(mFolders, id);
|
||||
|
||||
intentDescription = c.getString(intentIndex);
|
||||
intent = null;
|
||||
if (intentDescription != null) {
|
||||
|
@ -765,14 +877,18 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
}
|
||||
}
|
||||
|
||||
cellX = c.getInt(cellXIndex);
|
||||
cellY = c.getInt(cellYIndex);
|
||||
localCoords = mModelOrientationHelper.getLocalCoordinates(cellX, cellY, 1, 1);
|
||||
|
||||
liveFolderInfo.title = c.getString(titleIndex);
|
||||
liveFolderInfo.id = id;
|
||||
liveFolderInfo.uri = uri;
|
||||
container = c.getInt(containerIndex);
|
||||
liveFolderInfo.container = container;
|
||||
liveFolderInfo.screen = c.getInt(screenIndex);
|
||||
liveFolderInfo.cellX = c.getInt(cellXIndex);
|
||||
liveFolderInfo.cellY = c.getInt(cellYIndex);
|
||||
liveFolderInfo.cellX = localCoords.x;
|
||||
liveFolderInfo.cellY = localCoords.y;
|
||||
liveFolderInfo.baseIntent = intent;
|
||||
liveFolderInfo.displayMode = c.getInt(displayModeIndex);
|
||||
|
||||
|
@ -800,20 +916,26 @@ public class LauncherModel extends BroadcastReceiver {
|
|||
|
||||
final AppWidgetProviderInfo provider =
|
||||
widgets.getAppWidgetInfo(appWidgetId);
|
||||
|
||||
|
||||
if (!isSafeMode && (provider == null || provider.provider == null ||
|
||||
provider.provider.getPackageName() == null)) {
|
||||
Log.e(TAG, "Deleting widget that isn't installed anymore: id="
|
||||
+ id + " appWidgetId=" + appWidgetId);
|
||||
itemsToRemove.add(id);
|
||||
} else {
|
||||
cellX = c.getInt(cellXIndex);
|
||||
cellY = c.getInt(cellYIndex);
|
||||
int spanX = c.getInt(spanXIndex);
|
||||
int spanY = c.getInt(spanYIndex);
|
||||
localCoords = mModelOrientationHelper.getLocalCoordinates(cellX, cellY, spanX, spanY);
|
||||
|
||||
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId);
|
||||
appWidgetInfo.id = id;
|
||||
appWidgetInfo.screen = c.getInt(screenIndex);
|
||||
appWidgetInfo.cellX = c.getInt(cellXIndex);
|
||||
appWidgetInfo.cellY = c.getInt(cellYIndex);
|
||||
appWidgetInfo.spanX = c.getInt(spanXIndex);
|
||||
appWidgetInfo.spanY = c.getInt(spanYIndex);
|
||||
appWidgetInfo.cellX = localCoords.x;
|
||||
appWidgetInfo.cellY = localCoords.y;
|
||||
appWidgetInfo.spanX = spanX;
|
||||
appWidgetInfo.spanY = spanY;
|
||||
|
||||
container = c.getInt(containerIndex);
|
||||
if (container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class LauncherModelOrientationHelper {
|
||||
|
||||
static final String TAG = "LauncherModelOrientationHelper";
|
||||
|
||||
public class Coordinates {
|
||||
public Coordinates(int newX, int newY) {
|
||||
x = newX;
|
||||
y = newY;
|
||||
}
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
}
|
||||
|
||||
private int mOrientation;
|
||||
private int mLocalDeviceWidth;
|
||||
private int mLocalDeviceHeight;
|
||||
private int mPreviousOrientation;
|
||||
private int mPreviousLocalDeviceWidth;
|
||||
private int mPreviousLocalDeviceHeight;
|
||||
private int mCanonicalDeviceWidth;
|
||||
private int mCanonicalDeviceHeight;
|
||||
|
||||
protected LauncherModelOrientationHelper(Context ctx) {
|
||||
updateOrientation(ctx);
|
||||
}
|
||||
|
||||
public int getCurrentOrientation() {
|
||||
return mOrientation;
|
||||
}
|
||||
|
||||
public int getPreviousOrientationRelativeToCurrent() {
|
||||
int orientationDifference = -(mOrientation - mPreviousOrientation);
|
||||
|
||||
if (Math.abs(orientationDifference) > 180) {
|
||||
orientationDifference = (int) -Math.signum(orientationDifference)
|
||||
* (360 - Math.abs(orientationDifference));
|
||||
}
|
||||
return orientationDifference;
|
||||
}
|
||||
|
||||
private void updateLocalDeviceDimensions() {
|
||||
mPreviousLocalDeviceHeight = mLocalDeviceHeight;
|
||||
mPreviousLocalDeviceWidth = mLocalDeviceWidth;
|
||||
|
||||
if (mOrientation % 180 != 0) {
|
||||
mLocalDeviceWidth = mCanonicalDeviceHeight;
|
||||
mLocalDeviceHeight = mCanonicalDeviceWidth;
|
||||
} else {
|
||||
mLocalDeviceWidth = mCanonicalDeviceWidth;
|
||||
mLocalDeviceHeight = mCanonicalDeviceHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateOrientation(Context ctx) {
|
||||
Display display = ((WindowManager) ctx
|
||||
.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
|
||||
mPreviousOrientation = mOrientation;
|
||||
switch (display.getRotation()) {
|
||||
case Surface.ROTATION_0:
|
||||
mOrientation = 0;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
mOrientation = 90;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
mOrientation = 180;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
mOrientation = 270;
|
||||
break;
|
||||
}
|
||||
updateLocalDeviceDimensions();
|
||||
}
|
||||
|
||||
public void updateDeviceDimensions(int deviceWidth, int deviceHeight) {
|
||||
mCanonicalDeviceWidth = deviceWidth;
|
||||
mCanonicalDeviceHeight = deviceHeight;
|
||||
|
||||
updateLocalDeviceDimensions();
|
||||
}
|
||||
|
||||
public Coordinates getLocalCoordinatesFromPreviousLocalCoordinates(
|
||||
int cellX, int cellY, int spanX, int spanY) {
|
||||
return getTransformedLayoutParams(cellX, cellY, spanX, spanY,
|
||||
getPreviousOrientationRelativeToCurrent(),
|
||||
mPreviousLocalDeviceWidth, mPreviousLocalDeviceHeight);
|
||||
}
|
||||
|
||||
public Coordinates getCanonicalCoordinates(ItemInfo localItem) {
|
||||
return getTransformedLayoutParams(localItem.cellX, localItem.cellY,
|
||||
localItem.spanX, localItem.spanY, mOrientation,
|
||||
mLocalDeviceWidth, mLocalDeviceHeight);
|
||||
}
|
||||
|
||||
public Coordinates getCanonicalCoordinates(int cellX, int cellY,
|
||||
int spanX, int spanY) {
|
||||
return getTransformedLayoutParams(cellX, cellY, spanX, spanY,
|
||||
mOrientation, mLocalDeviceWidth, mLocalDeviceHeight);
|
||||
}
|
||||
|
||||
public Coordinates getLocalCoordinates(int cellX, int cellY, int spanX,
|
||||
int spanY) {
|
||||
return getTransformedLayoutParams(cellX, cellY, spanX, spanY,
|
||||
-mOrientation, mCanonicalDeviceWidth, mCanonicalDeviceHeight);
|
||||
}
|
||||
|
||||
public int getLocalDeviceWidth() {
|
||||
return mLocalDeviceWidth;
|
||||
}
|
||||
|
||||
public int getLocalDeviceHeight() {
|
||||
return mLocalDeviceHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the coordinates based on the current device rotation
|
||||
*/
|
||||
private Coordinates getTransformedLayoutParams(int cellX, int cellY,
|
||||
int spanX, int spanY, int deviceRotationClockwise,
|
||||
int initialDeviceWidth, int initialDeviceHeight) {
|
||||
if (LauncherApplication.isScreenXLarge()) {
|
||||
int x = cellX;
|
||||
int y = cellY;
|
||||
int width = spanX;
|
||||
int height = spanY;
|
||||
int finalDeviceWidth = initialDeviceWidth;
|
||||
int finalDeviceHeight = initialDeviceHeight;
|
||||
|
||||
// item rotation is opposite of device rotation to maintain an
|
||||
// absolute
|
||||
// spatial layout
|
||||
double phi = Math.toRadians(-deviceRotationClockwise);
|
||||
|
||||
double x1 = x + width / 2.0f - initialDeviceWidth / 2.0f;
|
||||
double y1 = y + height / 2.0f - initialDeviceHeight / 2.0f;
|
||||
|
||||
// multiply x and y by a clockwise rotation matrix
|
||||
double x2 = x1 * Math.cos(phi) + y1 * Math.sin(phi);
|
||||
double y2 = -x1 * Math.sin(phi) + y1 * Math.cos(phi);
|
||||
|
||||
// Get the rotated device dimensions
|
||||
if (deviceRotationClockwise % 180 != 0) {
|
||||
finalDeviceWidth = initialDeviceHeight;
|
||||
finalDeviceHeight = initialDeviceWidth;
|
||||
}
|
||||
|
||||
x2 = x2 + finalDeviceWidth / 2.0f - width / 2.0f;
|
||||
y2 = y2 + finalDeviceHeight / 2.0f - height / 2.0f;
|
||||
|
||||
return new Coordinates((int) Math.round(x2), (int) Math.round(y2));
|
||||
} else {
|
||||
return new Coordinates(cellX, cellY);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@ package com.android.launcher2;
|
|||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@ package com.android.launcher2;
|
|||
import android.renderscript.*;
|
||||
import android.content.res.Resources;
|
||||
import android.util.Log;
|
||||
import android.renderscript.Element;
|
||||
import android.renderscript.FieldPacker;
|
||||
import android.renderscript.Float2;
|
||||
import android.renderscript.Float4;
|
||||
import android.renderscript.RenderScript;
|
||||
|
||||
public class ScriptField_VpConsts extends android.renderscript.Script.FieldBase {
|
||||
static public class Item {
|
||||
|
|
|
@ -16,16 +16,14 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents a launchable icon on the workspaces and in folders.
|
||||
*/
|
||||
|
|
|
@ -16,16 +16,15 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
package com.android.launcher2;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Provides an animation between 0.0f and 1.0f over a given duration.
|
||||
|
|
|
@ -3,10 +3,8 @@ package com.android.launcher2;
|
|||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
|
|
|
@ -16,9 +16,8 @@
|
|||
|
||||
package com.android.launcher2;
|
||||
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PaintDrawable;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BlurMaskFilter;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -26,19 +25,19 @@ import android.graphics.ColorMatrix;
|
|||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.TableMaskFilter;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Layout.Alignment;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PaintDrawable;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.Layout.Alignment;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.content.res.Resources;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.launcher.R;
|
||||
|
||||
|
|
|
@ -42,7 +42,10 @@ import android.view.View;
|
|||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.RotateAnimation;
|
||||
import android.view.animation.Animation.AnimationListener;
|
||||
import android.widget.Scroller;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -50,22 +53,23 @@ import java.util.ArrayList;
|
|||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* The workspace is a wide area with a wallpaper and a finite number of screens. Each
|
||||
* screen contains a number of icons, folders or widgets the user can interact with.
|
||||
* A workspace is meant to be used with a fixed width only.
|
||||
* The workspace is a wide area with a wallpaper and a finite number of screens.
|
||||
* Each screen contains a number of icons, folders or widgets the user can
|
||||
* interact with. A workspace is meant to be used with a fixed width only.
|
||||
*/
|
||||
public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller {
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
private static final String TAG = "Launcher.Workspace";
|
||||
private static final int INVALID_SCREEN = -1;
|
||||
|
||||
|
||||
/**
|
||||
* The velocity at which a fling gesture will cause us to snap to the next screen
|
||||
* The velocity at which a fling gesture will cause us to snap to the next
|
||||
* screen
|
||||
*/
|
||||
private static final int SNAP_VELOCITY = 600;
|
||||
|
||||
private final WallpaperManager mWallpaperManager;
|
||||
|
||||
|
||||
private int mDefaultScreen;
|
||||
|
||||
private boolean mFirstLayout = true;
|
||||
|
@ -79,7 +83,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
* CellInfo for the cell that is currently being dragged
|
||||
*/
|
||||
private CellLayout.CellInfo mDragInfo;
|
||||
|
||||
|
||||
/**
|
||||
* Target drop area calculated during last acceptDrop call.
|
||||
*/
|
||||
|
@ -87,7 +91,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
private float mLastMotionX;
|
||||
private float mLastMotionY;
|
||||
|
||||
|
||||
private final static int TOUCH_STATE_REST = 0;
|
||||
private final static int TOUCH_STATE_SCROLLING = 1;
|
||||
|
||||
|
@ -98,12 +102,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
private Launcher mLauncher;
|
||||
private IconCache mIconCache;
|
||||
private DragController mDragController;
|
||||
|
||||
|
||||
/**
|
||||
* Cache of vacant cells, used during drag events and invalidated as needed.
|
||||
*/
|
||||
private CellLayout.CellInfo mVacantCache = null;
|
||||
|
||||
|
||||
private int[] mTempCell = new int[2];
|
||||
private int[] mTempEstimate = new int[2];
|
||||
|
||||
|
@ -111,14 +115,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
private int mTouchSlop;
|
||||
private int mMaximumVelocity;
|
||||
|
||||
|
||||
private static final int INVALID_POINTER = -1;
|
||||
|
||||
private int mActivePointerId = INVALID_POINTER;
|
||||
|
||||
|
||||
private Drawable mPreviousIndicator;
|
||||
private Drawable mNextIndicator;
|
||||
|
||||
|
||||
private static final float NANOTIME_DIV = 1000000000.0f;
|
||||
private static final float SMOOTHING_SPEED = 0.75f;
|
||||
private static final float SMOOTHING_CONSTANT = (float) (0.016 / Math.log(SMOOTHING_SPEED));
|
||||
|
@ -129,7 +133,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
private static final float BASELINE_FLING_VELOCITY = 2500.f;
|
||||
private static final float FLING_VELOCITY_INFLUENCE = 0.4f;
|
||||
|
||||
|
||||
private static class WorkspaceOvershootInterpolator implements Interpolator {
|
||||
private static final float DEFAULT_TENSION = 1.3f;
|
||||
private float mTension;
|
||||
|
@ -137,7 +141,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
public WorkspaceOvershootInterpolator() {
|
||||
mTension = DEFAULT_TENSION;
|
||||
}
|
||||
|
||||
|
||||
public void setDistance(int distance) {
|
||||
mTension = distance > 0 ? DEFAULT_TENSION / distance : DEFAULT_TENSION;
|
||||
}
|
||||
|
@ -153,7 +157,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
return t * t * ((mTension + 1) * t + mTension) + 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
|
@ -175,11 +179,16 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
super(context, attrs, defStyle);
|
||||
|
||||
mWallpaperManager = WallpaperManager.getInstance(context);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Workspace, defStyle, 0);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.Workspace, defStyle, 0);
|
||||
int canonicalDeviceWidth = a.getInt(R.styleable.Workspace_canonicalDeviceWidth, 4);
|
||||
int canonicalDeviceHeight = a.getInt(R.styleable.Workspace_canonicalDeviceHeight, 4);
|
||||
mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 1);
|
||||
a.recycle();
|
||||
|
||||
LauncherModel.updateWorkspaceLayoutCells(canonicalDeviceWidth,
|
||||
canonicalDeviceHeight);
|
||||
setHapticFeedbackEnabled(false);
|
||||
initWorkspace();
|
||||
}
|
||||
|
@ -249,9 +258,10 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
int count = currentScreen.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = currentScreen.getChildAt(i);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
|
||||
return (Folder) child;
|
||||
if (child instanceof Folder) {
|
||||
Folder folder = (Folder) child;
|
||||
if (folder.getInfo().opened)
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -266,9 +276,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
int count = currentScreen.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = currentScreen.getChildAt(i);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
|
||||
folders.add((Folder) child);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child
|
||||
.getLayoutParams();
|
||||
if (child instanceof Folder) {
|
||||
Folder folder = (Folder) child;
|
||||
if (folder.getInfo().opened)
|
||||
folders.add(folder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -296,11 +309,15 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
* @param currentScreen
|
||||
*/
|
||||
void setCurrentScreen(int currentScreen) {
|
||||
if (!mScroller.isFinished()) mScroller.abortAnimation();
|
||||
if (!mScroller.isFinished())
|
||||
mScroller.abortAnimation();
|
||||
clearVacantCache();
|
||||
mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));
|
||||
mPreviousIndicator.setLevel(mCurrentScreen);
|
||||
mNextIndicator.setLevel(mCurrentScreen);
|
||||
if (mPreviousIndicator != null) {
|
||||
mPreviousIndicator.setLevel(mCurrentScreen);
|
||||
mNextIndicator.setLevel(mCurrentScreen);
|
||||
}
|
||||
|
||||
scrollTo(mCurrentScreen * getWidth(), 0);
|
||||
updateWallpaperOffset();
|
||||
invalidate();
|
||||
|
@ -350,6 +367,85 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
addInScreen(child, screen, x, y, spanX, spanY, false);
|
||||
}
|
||||
|
||||
void addInFullScreen(View child, int screen) {
|
||||
addInScreen(child, screen, 0, 0, -1, -1);
|
||||
}
|
||||
|
||||
public void rotateCurrentScreensChildren() {
|
||||
|
||||
// close all the folders first
|
||||
final ArrayList<Folder> openFolders = getOpenFolders();
|
||||
|
||||
WorkspaceOvershootInterpolator wi = new WorkspaceOvershootInterpolator();
|
||||
RotateAnimation ra = new RotateAnimation((float) LauncherModel
|
||||
.getPreviousOrientationRelativeToCurrent(), 0,
|
||||
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
|
||||
0.5f);
|
||||
ra.setInterpolator(wi);
|
||||
CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);
|
||||
ra.setStartOffset(150);
|
||||
ra.setDuration(650 + (int) (Math.random() * 400) - 200);
|
||||
|
||||
CellLayout.CellLayoutAnimationController animationController = new CellLayout.CellLayoutAnimationController(
|
||||
ra, 0.0f);
|
||||
currentScreen.setLayoutAnimation(animationController);
|
||||
currentScreen.setLayoutAnimationListener(new AnimationListener() {
|
||||
public void onAnimationStart(Animation animation) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
for (int j = 0; j < openFolders.size(); ++j) {
|
||||
Folder folder = openFolders.get(j);
|
||||
if (!folder.getInfo().opened) {
|
||||
mLauncher.openFolder(folder.getInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
animationController.start();
|
||||
|
||||
for (int j = 0; j < openFolders.size(); ++j) {
|
||||
mLauncher.closeFolder(openFolders.get(j));
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshWorkspaceChildren() {
|
||||
final int count = getChildCount();
|
||||
View child;
|
||||
|
||||
CellLayout.LayoutParams lp;
|
||||
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(LauncherModel
|
||||
.getLocalDeviceWidth(), MeasureSpec.EXACTLY);
|
||||
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(LauncherModel
|
||||
.getLocalDeviceHeight(), MeasureSpec.EXACTLY);
|
||||
|
||||
clearVacantCache();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
final CellLayout layout = (CellLayout) getChildAt(i);
|
||||
int numChildren = layout.getChildCount();
|
||||
|
||||
// save reference to all current children
|
||||
for (int j = 0; j < numChildren; j++) {
|
||||
child = layout.getChildAt(j);
|
||||
|
||||
lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
LauncherModelOrientationHelper.Coordinates localCoord = LauncherModel
|
||||
.getLocalCoordinatesFromPreviousLocalCoordinates(lp);
|
||||
|
||||
lp.cellX = localCoord.x;
|
||||
lp.cellY = localCoord.y;
|
||||
}
|
||||
|
||||
layout.measure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified child in the specified screen. The position and dimension of
|
||||
* the child are defined by x, y, spanX and spanY.
|
||||
|
@ -381,13 +477,23 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
lp.cellHSpan = spanX;
|
||||
lp.cellVSpan = spanY;
|
||||
}
|
||||
group.addView(child, insert ? 0 : -1, lp);
|
||||
|
||||
// get the canonical child id to uniquely represent this view in this
|
||||
// screen
|
||||
int childId = LauncherModel.getCanonicalCellLayoutChildId(child.getId(), screen, x, y, spanX, spanY);
|
||||
if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp)) {
|
||||
// TODO: This branch occurs when the workspace is adding views
|
||||
// outside of the defined grid
|
||||
// maybe we should be deleting these items from the LauncherMode?
|
||||
Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout");
|
||||
}
|
||||
|
||||
if (!(child instanceof Folder)) {
|
||||
child.setHapticFeedbackEnabled(false);
|
||||
child.setOnLongClickListener(mLongClickListener);
|
||||
}
|
||||
if (child instanceof DropTarget) {
|
||||
mDragController.addDropTarget((DropTarget)child);
|
||||
mDragController.addDropTarget((DropTarget) child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,14 +538,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void scrollTo(int x, int y) {
|
||||
super.scrollTo(x, y);
|
||||
mTouchX = x;
|
||||
mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void computeScroll() {
|
||||
if (mScroller.computeScrollOffset()) {
|
||||
|
@ -531,7 +637,6 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
|
||||
if (mFirstLayout) {
|
||||
setHorizontalScrollBarEnabled(false);
|
||||
scrollTo(mCurrentScreen * width, 0);
|
||||
|
@ -554,6 +659,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
childLeft += childWidth;
|
||||
}
|
||||
}
|
||||
|
||||
if (LauncherApplication.isInPlaceRotationEnabled()) {
|
||||
// When the device is rotated, the scroll position of the current screen
|
||||
// needs to be refreshed
|
||||
setCurrentScreen(getCurrentScreen());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -613,7 +724,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
if (mCurrentScreen > 0) {
|
||||
getChildAt(mCurrentScreen - 1).addFocusables(views, direction);
|
||||
}
|
||||
} else if (direction == View.FOCUS_RIGHT){
|
||||
} else if (direction == View.FOCUS_RIGHT) {
|
||||
if (mCurrentScreen < getChildCount() - 1) {
|
||||
getChildAt(mCurrentScreen + 1).addFocusables(views, direction);
|
||||
}
|
||||
|
@ -662,7 +773,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
mVelocityTracker.addMovement(ev);
|
||||
|
||||
|
||||
switch (action & MotionEvent.ACTION_MASK) {
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
/*
|
||||
|
@ -683,9 +794,9 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
final int touchSlop = mTouchSlop;
|
||||
boolean xMoved = xDiff > touchSlop;
|
||||
boolean yMoved = yDiff > touchSlop;
|
||||
|
||||
|
||||
if (xMoved || yMoved) {
|
||||
|
||||
|
||||
if (xMoved) {
|
||||
// Scroll if the user moved far enough along the X axis
|
||||
mTouchState = TOUCH_STATE_SCROLLING;
|
||||
|
@ -707,14 +818,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
break;
|
||||
}
|
||||
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
final float x = ev.getX();
|
||||
final float y = ev.getY();
|
||||
// Remember location of down touch
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
mAllowLongPress = true;
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
final float x = ev.getX();
|
||||
final float y = ev.getY();
|
||||
// Remember location of down touch
|
||||
mLastMotionX = x;
|
||||
mLastMotionY = y;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
mAllowLongPress = true;
|
||||
|
||||
/*
|
||||
* If being flinged and user touches the screen, initiate drag;
|
||||
|
@ -727,36 +838,36 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
|
||||
|
||||
if (mTouchState != TOUCH_STATE_SCROLLING) {
|
||||
final CellLayout currentScreen = (CellLayout)getChildAt(mCurrentScreen);
|
||||
if (!currentScreen.lastDownOnOccupiedCell()) {
|
||||
getLocationOnScreen(mTempCell);
|
||||
// Send a tap to the wallpaper if the last down was on empty space
|
||||
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
mWallpaperManager.sendWallpaperCommand(getWindowToken(),
|
||||
mWallpaperManager.sendWallpaperCommand(getWindowToken(),
|
||||
"android.wallpaper.tap",
|
||||
mTempCell[0] + (int) ev.getX(pointerIndex),
|
||||
mTempCell[1] + (int) ev.getY(pointerIndex), 0, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Release the drag
|
||||
clearChildrenCache();
|
||||
mTouchState = TOUCH_STATE_REST;
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
mAllowLongPress = false;
|
||||
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
onSecondaryPointerUp(ev);
|
||||
break;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
onSecondaryPointerUp(ev);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -765,7 +876,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
*/
|
||||
return mTouchState != TOUCH_STATE_REST;
|
||||
}
|
||||
|
||||
|
||||
private void onSecondaryPointerUp(MotionEvent ev) {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
|
||||
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
|
@ -805,7 +916,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
}
|
||||
ViewParent parent = v.getParent();
|
||||
if (parent instanceof View) {
|
||||
v = (View)v.getParent();
|
||||
v = (View) v.getParent();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
@ -818,7 +929,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
fromScreen = toScreen;
|
||||
toScreen = temp;
|
||||
}
|
||||
|
||||
|
||||
final int count = getChildCount();
|
||||
|
||||
fromScreen = Math.max(fromScreen, 0);
|
||||
|
@ -841,7 +952,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
|
||||
|
||||
if (mLauncher.isWorkspaceLocked()) {
|
||||
return false; // We don't want the events. Let them fall through to the all apps view.
|
||||
}
|
||||
|
@ -910,11 +1021,11 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
final int velocityX = (int) velocityTracker.getXVelocity(mActivePointerId);
|
||||
|
||||
|
||||
final int screenWidth = getWidth();
|
||||
final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;
|
||||
final float scrolledPos = (float) mScrollX / screenWidth;
|
||||
|
||||
|
||||
if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
|
||||
// Fling hard enough to move left.
|
||||
// Don't fling across more than one screen at a time.
|
||||
|
@ -950,24 +1061,24 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void snapToScreen(int whichScreen) {
|
||||
snapToScreen(whichScreen, 0, false);
|
||||
}
|
||||
|
||||
private void snapToScreen(int whichScreen, int velocity, boolean settle) {
|
||||
//if (!mScroller.isFinished()) return;
|
||||
// if (!mScroller.isFinished()) return;
|
||||
|
||||
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
|
||||
|
||||
|
||||
clearVacantCache();
|
||||
enableChildrenCache(mCurrentScreen, whichScreen);
|
||||
|
||||
mNextScreen = whichScreen;
|
||||
|
||||
if (mPreviousIndicator != null) {
|
||||
mPreviousIndicator.setLevel(mNextScreen);
|
||||
mNextIndicator.setLevel(mNextScreen);
|
||||
mPreviousIndicator.setLevel(mNextScreen);
|
||||
mNextIndicator.setLevel(mNextScreen);
|
||||
}
|
||||
|
||||
View focusedChild = getFocusedChild();
|
||||
|
@ -975,7 +1086,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
focusedChild == getChildAt(mCurrentScreen)) {
|
||||
focusedChild.clearFocus();
|
||||
}
|
||||
|
||||
|
||||
final int screenDelta = Math.max(1, Math.abs(whichScreen - mCurrentScreen));
|
||||
final int newX = whichScreen * getWidth();
|
||||
final int delta = newX - mScrollX;
|
||||
|
@ -984,13 +1095,13 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
if (!mScroller.isFinished()) {
|
||||
mScroller.abortAnimation();
|
||||
}
|
||||
|
||||
|
||||
if (settle) {
|
||||
mScrollInterpolator.setDistance(screenDelta);
|
||||
} else {
|
||||
mScrollInterpolator.disableSettle();
|
||||
}
|
||||
|
||||
|
||||
velocity = Math.abs(velocity);
|
||||
if (velocity > 0) {
|
||||
duration += (duration / (velocity / BASELINE_FLING_VELOCITY))
|
||||
|
@ -1006,15 +1117,15 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
void startDrag(CellLayout.CellInfo cellInfo) {
|
||||
View child = cellInfo.cell;
|
||||
|
||||
|
||||
// Make sure the drag was started by a long press as opposed to a long click.
|
||||
if (!child.isInTouchMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mDragInfo = cellInfo;
|
||||
mDragInfo.screen = mCurrentScreen;
|
||||
|
||||
|
||||
CellLayout current = ((CellLayout) getChildAt(mCurrentScreen));
|
||||
|
||||
current.onDragChild(child);
|
||||
|
@ -1061,44 +1172,53 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
// Move internally
|
||||
if (mDragInfo != null) {
|
||||
final View cell = mDragInfo.cell;
|
||||
int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen;
|
||||
int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen;
|
||||
if (index != mDragInfo.screen) {
|
||||
final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
|
||||
originalCellLayout.removeView(cell);
|
||||
cellLayout.addView(cell);
|
||||
addInScreen(cell, index, mDragInfo.cellX, mDragInfo.cellY,
|
||||
mDragInfo.spanX, mDragInfo.spanY);
|
||||
}
|
||||
mTargetCell = estimateDropCell(x - xOffset, y - yOffset,
|
||||
mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(cell, mTargetCell);
|
||||
mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout,
|
||||
mTargetCell);
|
||||
cellLayout.onDropChild(cell);
|
||||
|
||||
// update the item's position after drop
|
||||
final ItemInfo info = (ItemInfo) cell.getTag();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell
|
||||
.getLayoutParams();
|
||||
lp.cellX = mTargetCell[0];
|
||||
lp.cellY = mTargetCell[1];
|
||||
|
||||
LauncherModel.moveItemInDatabase(mLauncher, info,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, index, lp.cellX, lp.cellY);
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, index,
|
||||
lp.cellX, lp.cellY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
public void onDragEnter(DragSource source, int x, int y, int xOffset,
|
||||
int yOffset, DragView dragView, Object dragInfo) {
|
||||
clearVacantCache();
|
||||
}
|
||||
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
public void onDragOver(DragSource source, int x, int y, int xOffset,
|
||||
int yOffset, DragView dragView, Object dragInfo) {
|
||||
}
|
||||
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
|
||||
DragView dragView, Object dragInfo) {
|
||||
public void onDragExit(DragSource source, int x, int y, int xOffset,
|
||||
int yOffset, DragView dragView, Object dragInfo) {
|
||||
clearVacantCache();
|
||||
}
|
||||
|
||||
private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout) {
|
||||
private void onDropExternal(int x, int y, Object dragInfo,
|
||||
CellLayout cellLayout) {
|
||||
onDropExternal(x, y, dragInfo, cellLayout, false);
|
||||
}
|
||||
|
||||
private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout,
|
||||
boolean insertAtFirst) {
|
||||
|
||||
private void onDropExternal(int x, int y, Object dragInfo,
|
||||
CellLayout cellLayout, boolean insertAtFirst) {
|
||||
// Drag from somewhere else
|
||||
ItemInfo info = (ItemInfo) dragInfo;
|
||||
|
||||
|
@ -1109,41 +1229,42 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||
if (info.container == NO_ID && info instanceof ApplicationInfo) {
|
||||
// Came from all apps -- make a copy
|
||||
info = new ShortcutInfo((ApplicationInfo)info);
|
||||
info = new ShortcutInfo((ApplicationInfo) info);
|
||||
}
|
||||
view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo)info);
|
||||
view = mLauncher.createShortcut(R.layout.application, cellLayout,
|
||||
(ShortcutInfo) info);
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
|
||||
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
|
||||
(ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info));
|
||||
(ViewGroup) getChildAt(mCurrentScreen),
|
||||
((UserFolderInfo) info));
|
||||
break;
|
||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
||||
cellLayout.setTagToCellInfoForPoint(x, y);
|
||||
mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, cellLayout.getTag());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown item type: " + info.itemType);
|
||||
throw new IllegalStateException("Unknown item type: "
|
||||
+ info.itemType);
|
||||
}
|
||||
|
||||
// addAppWidgetFromDrop already took care of attaching the widget view to the appropriate cell
|
||||
// TODO why aren't we calling addInScreen here?
|
||||
if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) {
|
||||
cellLayout.addView(view, insertAtFirst ? 0 : -1);
|
||||
view.setHapticFeedbackEnabled(false);
|
||||
view.setOnLongClickListener(mLongClickListener);
|
||||
if (view instanceof DropTarget) {
|
||||
mDragController.addDropTarget((DropTarget) view);
|
||||
}
|
||||
|
||||
mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell);
|
||||
cellLayout.onDropChild(view, mTargetCell);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
|
||||
mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout,
|
||||
mTargetCell);
|
||||
addInScreen(view, indexOfChild(cellLayout), mTargetCell[0],
|
||||
mTargetCell[1], info.spanX, info.spanY, insertAtFirst);
|
||||
cellLayout.onDropChild(view);
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view
|
||||
.getLayoutParams();
|
||||
|
||||
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
|
||||
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen,
|
||||
lp.cellX, lp.cellY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current {@link CellLayout}, correctly picking the destination
|
||||
* screen while a scroll is in progress.
|
||||
|
@ -1170,37 +1291,37 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
|
||||
return mVacantCache.findCellForSpan(mTempEstimate, spanX, spanY, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Rect estimateDropLocation(DragSource source, int x, int y,
|
||||
int xOffset, int yOffset, DragView dragView, Object dragInfo, Rect recycle) {
|
||||
final CellLayout layout = getCurrentDropLayout();
|
||||
|
||||
|
||||
final CellLayout.CellInfo cellInfo = mDragInfo;
|
||||
final int spanX = cellInfo == null ? 1 : cellInfo.spanX;
|
||||
final int spanY = cellInfo == null ? 1 : cellInfo.spanY;
|
||||
final View ignoreView = cellInfo == null ? null : cellInfo.cell;
|
||||
|
||||
|
||||
final Rect location = recycle != null ? recycle : new Rect();
|
||||
|
||||
|
||||
// Find drop cell and convert into rectangle
|
||||
int[] dropCell = estimateDropCell(x - xOffset, y - yOffset,
|
||||
spanX, spanY, ignoreView, layout, mTempCell);
|
||||
|
||||
int[] dropCell = estimateDropCell(x - xOffset, y - yOffset, spanX,
|
||||
spanY, ignoreView, layout, mTempCell);
|
||||
|
||||
if (dropCell == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
layout.cellToPoint(dropCell[0], dropCell[1], mTempEstimate);
|
||||
location.left = mTempEstimate[0];
|
||||
location.top = mTempEstimate[1];
|
||||
|
||||
|
||||
layout.cellToPoint(dropCell[0] + spanX, dropCell[1] + spanY, mTempEstimate);
|
||||
location.right = mTempEstimate[0];
|
||||
location.bottom = mTempEstimate[1];
|
||||
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
|
@ -1218,7 +1339,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
return layout.findNearestVacantArea(pixelX, pixelY,
|
||||
spanX, spanY, mVacantCache, recycle);
|
||||
}
|
||||
|
||||
|
||||
void setLauncher(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
@ -1230,14 +1351,14 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
public void onDropCompleted(View target, boolean success) {
|
||||
clearVacantCache();
|
||||
|
||||
if (success){
|
||||
if (success) {
|
||||
if (target != this && mDragInfo != null) {
|
||||
final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
|
||||
cellLayout.removeView(mDragInfo.cell);
|
||||
if (mDragInfo.cell instanceof DropTarget) {
|
||||
mDragController.removeDropTarget((DropTarget)mDragInfo.cell);
|
||||
}
|
||||
//final Object tag = mDragInfo.cell.getTag();
|
||||
// final Object tag = mDragInfo.cell.getTag();
|
||||
}
|
||||
} else {
|
||||
if (mDragInfo != null) {
|
||||
|
@ -1252,18 +1373,22 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
public void scrollLeft() {
|
||||
clearVacantCache();
|
||||
if (mScroller.isFinished()) {
|
||||
if (mCurrentScreen > 0) snapToScreen(mCurrentScreen - 1);
|
||||
if (mCurrentScreen > 0)
|
||||
snapToScreen(mCurrentScreen - 1);
|
||||
} else {
|
||||
if (mNextScreen > 0) snapToScreen(mNextScreen - 1);
|
||||
if (mNextScreen > 0)
|
||||
snapToScreen(mNextScreen - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void scrollRight() {
|
||||
clearVacantCache();
|
||||
if (mScroller.isFinished()) {
|
||||
if (mCurrentScreen < getChildCount() -1) snapToScreen(mCurrentScreen + 1);
|
||||
if (mCurrentScreen < getChildCount() - 1)
|
||||
snapToScreen(mCurrentScreen + 1);
|
||||
} else {
|
||||
if (mNextScreen < getChildCount() -1) snapToScreen(mNextScreen + 1);
|
||||
if (mNextScreen < getChildCount() - 1)
|
||||
snapToScreen(mNextScreen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1291,7 +1416,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
|
||||
Folder f = (Folder) child;
|
||||
if (f.getInfo() == tag) {
|
||||
if (f.getInfo() == tag && f.getInfo().opened) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
@ -1321,7 +1446,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
public boolean allowLongPress() {
|
||||
return mAllowLongPress;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set true to allow long-press events to be triggered, usually checked by
|
||||
* {@link Launcher} to accept or block dpad-initiated long-presses.
|
||||
|
@ -1349,17 +1474,17 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
public void run() {
|
||||
final ArrayList<View> childrenToRemove = new ArrayList<View>();
|
||||
childrenToRemove.clear();
|
||||
|
||||
|
||||
int childCount = layout.getChildCount();
|
||||
for (int j = 0; j < childCount; j++) {
|
||||
final View view = layout.getChildAt(j);
|
||||
Object tag = view.getTag();
|
||||
|
||||
|
||||
if (tag instanceof ShortcutInfo) {
|
||||
final ShortcutInfo info = (ShortcutInfo) tag;
|
||||
final Intent intent = info.intent;
|
||||
final ComponentName name = intent.getComponent();
|
||||
|
||||
|
||||
if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
|
||||
for (String packageName: packageNames) {
|
||||
if (packageName.equals(name.getPackageName())) {
|
||||
|
@ -1375,12 +1500,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1);
|
||||
final int contentsCount = contents.size();
|
||||
boolean removedFromFolder = false;
|
||||
|
||||
|
||||
for (int k = 0; k < contentsCount; k++) {
|
||||
final ShortcutInfo appInfo = contents.get(k);
|
||||
final Intent intent = appInfo.intent;
|
||||
final ComponentName name = intent.getComponent();
|
||||
|
||||
|
||||
if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
|
||||
for (String packageName: packageNames) {
|
||||
if (packageName.equals(name.getPackageName())) {
|
||||
|
@ -1393,11 +1518,12 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contents.removeAll(toRemove);
|
||||
if (removedFromFolder) {
|
||||
final Folder folder = getOpenFolder();
|
||||
if (folder != null) folder.notifyDataSetChanged();
|
||||
if (folder != null)
|
||||
folder.notifyDataSetChanged();
|
||||
}
|
||||
} else if (tag instanceof LiveFolderInfo) {
|
||||
final LiveFolderInfo info = (LiveFolderInfo) tag;
|
||||
|
@ -1410,7 +1536,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
if (packageName.equals(providerInfo.packageName)) {
|
||||
// TODO: This should probably be done on a worker thread
|
||||
LauncherModel.deleteItemFromDatabase(mLauncher, info);
|
||||
childrenToRemove.add(view);
|
||||
childrenToRemove.add(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1423,13 +1549,13 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
if (packageName.equals(provider.provider.getPackageName())) {
|
||||
// TODO: This should probably be done on a worker thread
|
||||
LauncherModel.deleteItemFromDatabase(mLauncher, info);
|
||||
childrenToRemove.add(view);
|
||||
childrenToRemove.add(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
childCount = childrenToRemove.size();
|
||||
for (int j = 0; j < childCount; j++) {
|
||||
View child = childrenToRemove.get(j);
|
||||
|
@ -1438,7 +1564,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
mDragController.removeDropTarget((DropTarget)child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (childCount > 0) {
|
||||
layout.requestLayout();
|
||||
layout.invalidate();
|
||||
|
@ -1468,7 +1594,7 @@ public class Workspace extends ViewGroup implements DropTarget, DragSource, Drag
|
|||
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
|
||||
Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
|
||||
final int appCount = apps.size();
|
||||
for (int k=0; k<appCount; k++) {
|
||||
for (int k = 0; k < appCount; k++) {
|
||||
ApplicationInfo app = apps.get(k);
|
||||
if (app.componentName.equals(name)) {
|
||||
info.setIcon(mIconCache.getIcon(info.intent));
|
||||
|
|
Loading…
Reference in New Issue