Workspacepublic class Workspace extends android.view.ViewGroup implements DropTarget, DragSource, DragScrollerThe 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. |
Fields Summary |
---|
private static final int | INVALID_SCREEN | private static final int | SNAP_VELOCITYThe velocity at which a fling gesture will cause us to snap to the next screen | private int | mDefaultScreen | private android.graphics.Paint | mPaint | private android.graphics.Bitmap | mWallpaper | private int | mWallpaperWidth | private int | mWallpaperHeight | private float | mWallpaperOffset | private boolean | mWallpaperLoaded | private boolean | mFirstLayout | private int | mCurrentScreen | private int | mNextScreen | private android.widget.Scroller | mScroller | private android.view.VelocityTracker | mVelocityTracker | private CellLayout.CellInfo | mDragInfoCellInfo for the cell that is currently being dragged | private float | mLastMotionX | private float | mLastMotionY | private static final int | TOUCH_STATE_REST | private static final int | TOUCH_STATE_SCROLLING | private int | mTouchState | private OnLongClickListener | mLongClickListener | private Launcher | mLauncher | private DragController | mDragger | private int[] | mTempCell | private boolean | mAllowLongPress | private boolean | mLocked | private int | mTouchSlop | final android.graphics.Rect | mDrawerBounds | final android.graphics.Rect | mClipBounds | int | mDrawerContentHeight | int | mDrawerContentWidth |
Constructors Summary |
---|
public Workspace(android.content.Context context, android.util.AttributeSet attrs)Used to inflate the Workspace from XML.
this(context, attrs, 0);
| public Workspace(android.content.Context context, android.util.AttributeSet attrs, int defStyle)Used to inflate the Workspace from XML.
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Workspace, defStyle, 0);
mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 1);
a.recycle();
initWorkspace();
|
Methods Summary |
---|
public boolean | acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, java.lang.Object dragInfo)
final CellLayout.CellInfo cellInfo = mDragInfo;
int cellHSpan = cellInfo == null ? 1 : cellInfo.spanX;
int cellVSpan = cellInfo == null ? 1 : cellInfo.spanY;
return ((CellLayout) getChildAt(mCurrentScreen)).acceptChildDrop(x - xOffset, y - yOffset,
cellHSpan, cellVSpan, cellInfo == null ? null : cellInfo.cell);
| void | addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo)
addApplicationShortcut(info, cellInfo, false);
| void | addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo, boolean insertAtFirst)
final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen);
final int[] result = new int[2];
layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result);
onDropExternal(result[0], result[1], info, layout, insertAtFirst);
| public void | addFocusables(java.util.ArrayList views, int direction)
if (mLauncher.isDrawerDown()) {
final Folder openFolder = getOpenFolder();
if (openFolder == null) {
getChildAt(mCurrentScreen).addFocusables(views, direction);
if (direction == View.FOCUS_LEFT) {
if (mCurrentScreen > 0) {
getChildAt(mCurrentScreen - 1).addFocusables(views, direction);
}
} else if (direction == View.FOCUS_RIGHT){
if (mCurrentScreen < getChildCount() - 1) {
getChildAt(mCurrentScreen + 1).addFocusables(views, direction);
}
}
} else {
openFolder.addFocusables(views, direction);
}
}
| void | addInCurrentScreen(android.view.View child, int x, int y, int spanX, int spanY)Adds the specified child in the current screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
addInScreen(child, mCurrentScreen, x, y, spanX, spanY, false);
| void | addInCurrentScreen(android.view.View child, int x, int y, int spanX, int spanY, boolean insert)Adds the specified child in the current screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
addInScreen(child, mCurrentScreen, x, y, spanX, spanY, insert);
| void | addInScreen(android.view.View child, int screen, int x, int y, int spanX, int spanY)Adds the specified child in the specified screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
addInScreen(child, screen, x, y, spanX, spanY, false);
| void | addInScreen(android.view.View child, int screen, int x, int y, int spanX, int spanY, boolean insert)Adds the specified child in the specified screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
if (screen < 0 || screen >= getChildCount()) {
throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount());
}
final CellLayout group = (CellLayout) getChildAt(screen);
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
if (lp == null) {
lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
} else {
lp.cellX = x;
lp.cellY = y;
lp.cellHSpan = spanX;
lp.cellVSpan = spanY;
}
group.addView(child, insert ? 0 : -1, lp);
if (!(child instanceof Folder)) {
child.setOnLongClickListener(mLongClickListener);
}
| public void | addView(android.view.View child, int index, LayoutParams params)
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
super.addView(child, index, params);
| public void | addView(android.view.View child)
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
super.addView(child);
| public void | addView(android.view.View child, int index)
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
super.addView(child, index);
| public void | addView(android.view.View child, int width, int height)
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
super.addView(child, width, height);
| public void | addView(android.view.View child, LayoutParams params)
if (!(child instanceof CellLayout)) {
throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
}
super.addView(child, params);
| void | addWidget(android.view.View view, Widget widget)
addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX,
widget.spanY, false);
| void | addWidget(android.view.View view, Widget widget, boolean insert)
addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX,
widget.spanY, insert);
| public boolean | allowLongPress()
return mAllowLongPress;
| public void | cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, android.graphics.RectF rect)Computes a bounding rectangle for a range of cells
((CellLayout)getChildAt(mCurrentScreen)).cellToRect(cellX, cellY,
cellHSpan, cellVSpan, rect);
| void | clearChildrenCache()
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final CellLayout layout = (CellLayout) getChildAt(i);
layout.setChildrenDrawnWithCacheEnabled(false);
}
| public void | computeScroll()
if (mScroller.computeScrollOffset()) {
mScrollX = mScroller.getCurrX();
mScrollY = mScroller.getCurrY();
postInvalidate();
} else if (mNextScreen != INVALID_SCREEN) {
mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1));
Launcher.setScreen(mCurrentScreen);
mNextScreen = INVALID_SCREEN;
clearChildrenCache();
}
| protected void | dispatchDraw(android.graphics.Canvas canvas)
boolean restore = false;
// If the all apps drawer is open and the drawing region for the workspace
// is contained within the drawer's bounds, we skip the drawing. This requires
// the drawer to be fully opaque.
if (mLauncher.isDrawerUp()) {
final Rect clipBounds = mClipBounds;
canvas.getClipBounds(clipBounds);
clipBounds.offset(-mScrollX, -mScrollY);
if (mDrawerBounds.contains(clipBounds)) {
return;
}
} else if (mLauncher.isDrawerMoving()) {
restore = true;
canvas.save(Canvas.CLIP_SAVE_FLAG);
final View view = mLauncher.getDrawerHandle();
final int top = view.getTop() + view.getHeight();
canvas.clipRect(mScrollX, top, mScrollX + mDrawerContentWidth,
top + mDrawerContentHeight, Region.Op.DIFFERENCE);
}
float x = mScrollX * mWallpaperOffset;
if (x + mWallpaperWidth < mRight - mLeft) {
x = mRight - mLeft - mWallpaperWidth;
}
canvas.drawBitmap(mWallpaper, x, (mBottom - mTop - mWallpaperHeight) / 2, mPaint);
// ViewGroup.dispatchDraw() supports many features we don't need:
// clip to padding, layout animation, animation listener, disappearing
// children, etc. The following implementation attempts to fast-track
// the drawing dispatch by drawing only what we know needs to be drawn.
boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN;
// If we are not scrolling or flinging, draw only the current screen
if (fastDraw) {
drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime());
} else {
final long drawingTime = getDrawingTime();
// If we are flinging, draw only the current screen and the target screen
if (mNextScreen >= 0 && mNextScreen < getChildCount() &&
Math.abs(mCurrentScreen - mNextScreen) == 1) {
drawChild(canvas, getChildAt(mCurrentScreen), drawingTime);
drawChild(canvas, getChildAt(mNextScreen), drawingTime);
} else {
// If we are scrolling, draw all of our children
final int count = getChildCount();
for (int i = 0; i < count; i++) {
drawChild(canvas, getChildAt(i), drawingTime);
}
}
}
if (restore) {
canvas.restore();
}
| public boolean | dispatchUnhandledMove(android.view.View focused, int direction)
if (direction == View.FOCUS_LEFT) {
if (getCurrentScreen() > 0) {
snapToScreen(getCurrentScreen() - 1);
return true;
}
} else if (direction == View.FOCUS_RIGHT) {
if (getCurrentScreen() < getChildCount() - 1) {
snapToScreen(getCurrentScreen() + 1);
return true;
}
}
return super.dispatchUnhandledMove(focused, direction);
| void | enableChildrenCache()
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final CellLayout layout = (CellLayout) getChildAt(i);
layout.setChildrenDrawnWithCacheEnabled(true);
layout.setChildrenDrawingCacheEnabled(true);
}
| CellLayout.CellInfo | findAllVacantCells(boolean[] occupied)
CellLayout group = (CellLayout) getChildAt(mCurrentScreen);
if (group != null) {
return group.findAllVacantCells(occupied);
}
return null;
| private Search | findSearchWidget(CellLayout screen)Find a search widget on the given screen
final int count = screen.getChildCount();
for (int i = 0; i < count; i++) {
View v = screen.getChildAt(i);
if (v instanceof Search) {
return (Search) v;
}
}
return null;
| void | fitInCurrentScreen(android.view.View child, int spanX, int spanY)Adds the specified child in the current screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
fitInScreen(child, mCurrentScreen, spanX, spanY);
| void | fitInScreen(android.view.View child, int screen, int spanX, int spanY)Adds the specified child in the specified screen. The position and dimension of
the child are defined by x, y, spanX and spanY.
if (screen < 0 || screen >= getChildCount()) {
throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount());
}
final CellLayout group = (CellLayout) getChildAt(screen);
boolean vacant = group.getVacantCell(mTempCell, spanX, spanY);
if (vacant) {
group.addView(child,
new CellLayout.LayoutParams(mTempCell[0], mTempCell[1], spanX, spanY));
child.setOnLongClickListener(mLongClickListener);
if (!(child instanceof Folder)) {
child.setOnLongClickListener(mLongClickListener);
}
}
| private boolean | focusOnSearch(int screen)Focuses on the search widget on the specified screen,
if there is one. Also clears the current search selection so we don't
CellLayout currentScreen = (CellLayout) getChildAt(screen);
final Search searchWidget = findSearchWidget(currentScreen);
if (searchWidget != null) {
// This is necessary when focus on search is requested from the menu
// If the workspace was not in touch mode before the menu is invoked
// and the user clicks "Search" by touching the menu item, the following
// happens:
//
// - We request focus from touch on the search widget
// - The search widget gains focus
// - The window focus comes back to Home's window
// - The touch mode change is propagated to Home's window
// - The search widget is not focusable in touch mode and ViewRoot
// clears its focus
//
// Forcing focusable in touch mode ensures the search widget will
// keep the focus no matter what happens.
//
// Note: the search input field disables focusable in touch mode
// after the window gets the focus back, see SearchAutoCompleteTextView
final SearchAutoCompleteTextView input = searchWidget.getSearchInputField();
input.setFocusableInTouchMode(true);
input.showKeyboardOnNextFocus();
if (isInTouchMode()) {
searchWidget.requestFocusFromTouch();
} else {
searchWidget.requestFocus();
}
searchWidget.clearQuery();
return true;
}
return false;
| int | getCurrentScreen()Returns the index of the currently displayed screen.
return mCurrentScreen;
| public Folder | getFolderForTag(java.lang.Object tag)
int screenCount = getChildCount();
for (int screen = 0; screen < screenCount; screen++) {
CellLayout currentScreen = ((CellLayout) getChildAt(screen));
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) {
Folder f = (Folder) child;
if (f.getInfo() == tag) {
return f;
}
}
}
}
return null;
| Folder | getOpenFolder()
CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen);
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;
}
}
return null;
| java.util.ArrayList | getOpenFolders()
final int screens = getChildCount();
ArrayList<Folder> folders = new ArrayList<Folder>(screens);
for (int screen = 0; screen < screens; screen++) {
CellLayout currentScreen = (CellLayout) getChildAt(screen);
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);
break;
}
}
}
return folders;
| public int | getScreenForView(android.view.View v)
int result = -1;
if (v != null) {
ViewParent vp = v.getParent();
int count = getChildCount();
for (int i = 0; i < count; i++) {
if (vp == getChildAt(i)) {
return i;
}
}
}
return result;
| boolean | getVacantCell(int[] vacant, int spanX, int spanY)Returns the coordinate of a vacant cell for the current screen.
CellLayout group = (CellLayout) getChildAt(mCurrentScreen);
if (group != null) {
return group.getVacantCell(vacant, spanX, spanY);
}
return false;
| public android.view.View | getViewForTag(java.lang.Object tag)
int screenCount = getChildCount();
for (int screen = 0; screen < screenCount; screen++) {
CellLayout currentScreen = ((CellLayout) getChildAt(screen));
int count = currentScreen.getChildCount();
for (int i = 0; i < count; i++) {
View child = currentScreen.getChildAt(i);
if (child.getTag() == tag) {
return child;
}
}
}
return null;
| private void | initWorkspace()Initializes various states for this workspace.
mScroller = new Scroller(getContext());
mCurrentScreen = mDefaultScreen;
Launcher.setScreen(mCurrentScreen);
mPaint = new Paint();
mPaint.setDither(false);
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
| boolean | isDefaultScreenShowing()
return mCurrentScreen == mDefaultScreen;
| void | loadWallpaper(android.graphics.Bitmap bitmap)Set the background's wallpaper.
mWallpaper = bitmap;
mWallpaperLoaded = true;
requestLayout();
invalidate();
| public void | lock()Locks the SlidingDrawer so that touch events are ignores.
mLocked = true;
| void | moveToDefaultScreen()
snapToScreen(mDefaultScreen);
getChildAt(mDefaultScreen).requestFocus();
| public void | onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, java.lang.Object dragInfo)
| public void | onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, java.lang.Object dragInfo)
| public void | onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, java.lang.Object dragInfo)
| public void | onDrop(DragSource source, int x, int y, int xOffset, int yOffset, java.lang.Object dragInfo)
final CellLayout cellLayout = (CellLayout) getChildAt(mCurrentScreen);
if (source != this) {
onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout);
} else {
// Move internally
if (mDragInfo != null) {
final View cell = mDragInfo.cell;
if (mCurrentScreen != mDragInfo.screen) {
final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
originalCellLayout.removeView(cell);
cellLayout.addView(cell);
}
cellLayout.onDropChild(cell, x - xOffset, y - yOffset);
final ItemInfo info = (ItemInfo)cell.getTag();
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
LauncherModel.moveItemInDatabase(mLauncher, info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
}
}
| public void | onDropCompleted(android.view.View target, boolean success)
if (success){
if (target != this && mDragInfo != null) {
final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
cellLayout.removeView(mDragInfo.cell);
final Object tag = mDragInfo.cell.getTag();
Launcher.getModel().removeDesktopItem((ItemInfo) tag);
}
} else {
if (mDragInfo != null) {
final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
cellLayout.onDropAborted(mDragInfo.cell);
}
}
mDragInfo = null;
| private void | onDropExternal(int x, int y, java.lang.Object dragInfo, CellLayout cellLayout)
onDropExternal(x, y, dragInfo, cellLayout, false);
| private void | onDropExternal(int x, int y, java.lang.Object dragInfo, CellLayout cellLayout, boolean insertAtFirst)
// Drag from somewhere else
ItemInfo info = (ItemInfo) dragInfo;
View view;
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
if (info.container == NO_ID) {
// Came from all apps -- make a copy
info = new ApplicationInfo((ApplicationInfo) info);
}
view = mLauncher.createShortcut(R.layout.application, cellLayout,
(ApplicationInfo) info);
break;
case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
(ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info));
break;
default:
throw new IllegalStateException("Unknown item type: " + info.itemType);
}
cellLayout.addView(view, insertAtFirst ? 0 : -1);
view.setOnLongClickListener(mLongClickListener);
cellLayout.onDropChild(view, x, y);
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
final LauncherModel model = Launcher.getModel();
model.addDesktopItem(info);
LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY);
| public boolean | onInterceptTouchEvent(android.view.MotionEvent ev)
if (mLocked || !mLauncher.isDrawerDown()) {
return true;
}
/*
* This method JUST determines whether we want to intercept the motion.
* If we return true, onTouchEvent will be called and we do the actual
* scrolling there.
*/
/*
* Shortcut the most recurring case: the user is in the dragging
* state and he is moving his finger. We want to intercept this
* motion.
*/
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
return true;
}
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_MOVE:
/*
* mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
* whether the user has moved far enough from his original down touch.
*/
/*
* Locally do absolute value. mLastMotionX is set to the y value
* of the down event.
*/
final int xDiff = (int) Math.abs(x - mLastMotionX);
final int yDiff = (int) Math.abs(y - mLastMotionY);
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;
enableChildrenCache();
}
// Either way, cancel any pending longpress
if (mAllowLongPress) {
mAllowLongPress = false;
// Try canceling the long press. It could also have been scheduled
// by a distant descendant, so use the mAllowLongPress flag to block
// everything
final View currentScreen = getChildAt(mCurrentScreen);
currentScreen.cancelLongPress();
}
}
break;
case MotionEvent.ACTION_DOWN:
// Remember location of down touch
mLastMotionX = x;
mLastMotionY = y;
mAllowLongPress = true;
/*
* If being flinged and user touches the screen, initiate drag;
* otherwise don't. mScroller.isFinished should be false when
* being flinged.
*/
mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// Release the drag
clearChildrenCache();
mTouchState = TOUCH_STATE_REST;
mAllowLongPress = false;
break;
}
/*
* The only time we want to intercept motion events is if we are in the
* drag mode.
*/
return mTouchState != TOUCH_STATE_REST;
| protected void | onLayout(boolean changed, int left, int top, int right, int bottom)
int childLeft = 0;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight());
childLeft += childWidth;
}
}
| protected void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
}
// The children are given the same width and height as the workspace
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
if (mWallpaperLoaded) {
mWallpaperLoaded = false;
mWallpaper = Utilities.centerToFit(mWallpaper, width,
MeasureSpec.getSize(heightMeasureSpec), getContext());
mWallpaperWidth = mWallpaper.getWidth();
mWallpaperHeight = mWallpaper.getHeight();
}
final int wallpaperWidth = mWallpaperWidth;
mWallpaperOffset = wallpaperWidth > width ? (count * width - wallpaperWidth) /
((count - 1) * (float) width) : 1.0f;
if (mFirstLayout) {
scrollTo(mCurrentScreen * width, 0);
mFirstLayout = false;
}
| protected boolean | onRequestFocusInDescendants(int direction, android.graphics.Rect previouslyFocusedRect)
if (mLauncher.isDrawerDown()) {
final Folder openFolder = getOpenFolder();
if (openFolder != null) {
return openFolder.requestFocus(direction, previouslyFocusedRect);
} else {
int focusableScreen;
if (mNextScreen != INVALID_SCREEN) {
focusableScreen = mNextScreen;
} else {
focusableScreen = mCurrentScreen;
}
getChildAt(focusableScreen).requestFocus(direction, previouslyFocusedRect);
}
}
return false;
| protected void | onRestoreInstanceState(android.os.Parcelable state)
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
if (savedState.currentScreen != -1) {
mCurrentScreen = savedState.currentScreen;
Launcher.setScreen(mCurrentScreen);
}
| protected android.os.Parcelable | onSaveInstanceState()
final SavedState state = new SavedState(super.onSaveInstanceState());
state.currentScreen = mCurrentScreen;
return state;
| public boolean | onTouchEvent(android.view.MotionEvent ev)
if (mLocked || !mLauncher.isDrawerDown()) {
return true;
}
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
final int action = ev.getAction();
final float x = ev.getX();
switch (action) {
case MotionEvent.ACTION_DOWN:
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
*/
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
// Remember where the motion event started
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
if (mTouchState == TOUCH_STATE_SCROLLING) {
// Scroll to follow the motion event
final int deltaX = (int) (mLastMotionX - x);
mLastMotionX = x;
if (deltaX < 0) {
if (mScrollX > 0) {
scrollBy(Math.max(-mScrollX, deltaX), 0);
}
} else if (deltaX > 0) {
final int availableToScroll = getChildAt(getChildCount() - 1).getRight() -
mScrollX - getWidth();
if (availableToScroll > 0) {
scrollBy(Math.min(availableToScroll, deltaX), 0);
}
}
}
break;
case MotionEvent.ACTION_UP:
if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) {
// Fling hard enough to move left
snapToScreen(mCurrentScreen - 1);
} else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) {
// Fling hard enough to move right
snapToScreen(mCurrentScreen + 1);
} else {
snapToDestination();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
mTouchState = TOUCH_STATE_REST;
break;
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST;
}
return true;
| void | removeShortcutsForPackage(java.lang.String packageName)
final ArrayList<View> childrenToRemove = new ArrayList<View>();
final LauncherModel model = Launcher.getModel();
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final CellLayout layout = (CellLayout) getChildAt(i);
int childCount = layout.getChildCount();
childrenToRemove.clear();
for (int j = 0; j < childCount; j++) {
final View view = layout.getChildAt(j);
Object tag = view.getTag();
if (tag instanceof ApplicationInfo) {
ApplicationInfo info = (ApplicationInfo) tag;
// We need to check for ACTION_MAIN otherwise getComponent() might
// return null for some shortcuts (for instance, for shortcuts to
// web pages.)
final Intent intent = info.intent;
final ComponentName name = intent.getComponent();
if (Intent.ACTION_MAIN.equals(intent.getAction()) &&
name != null && packageName.equals(name.getPackageName())) {
model.removeDesktopItem(info);
LauncherModel.deleteItemFromDatabase(mLauncher, info);
childrenToRemove.add(view);
}
}
}
childCount = childrenToRemove.size();
for (int j = 0; j < childCount; j++) {
layout.removeViewInLayout(childrenToRemove.get(j));
}
if (childCount > 0) {
layout.requestLayout();
layout.invalidate();
}
}
| public boolean | requestChildRectangleOnScreen(android.view.View child, android.graphics.Rect rectangle, boolean immediate)
int screen = indexOfChild(child);
if (screen != mCurrentScreen || !mScroller.isFinished()) {
if (!mLauncher.isWorkspaceLocked()) {
snapToScreen(screen);
}
return true;
}
return false;
| public void | scrollLeft()
if (mNextScreen == INVALID_SCREEN && mCurrentScreen > 0 && mScroller.isFinished()) {
snapToScreen(mCurrentScreen - 1);
}
| public void | scrollRight()
if (mNextScreen == INVALID_SCREEN && mCurrentScreen < getChildCount() -1 &&
mScroller.isFinished()) {
snapToScreen(mCurrentScreen + 1);
}
| public void | setAllowLongPress(boolean allowLongPress)Set true to allow long-press events to be triggered, usually checked by
{@link Launcher} to accept or block dpad-initiated long-presses.
mAllowLongPress = allowLongPress;
| void | setCurrentScreen(int currentScreen)Sets the current screen.
mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1));
scrollTo(mCurrentScreen * getWidth(), 0);
invalidate();
| public void | setDragger(DragController dragger)
mDragger = dragger;
| void | setLauncher(Launcher launcher)
mLauncher = launcher;
| public void | setOnLongClickListener(OnLongClickListener l)Registers the specified listener on each screen contained in this workspace.
mLongClickListener = l;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).setOnLongClickListener(l);
}
| void | showDefaultScreen()Shows the default screen (defined by the firstScreen attribute in XML.)
setCurrentScreen(mDefaultScreen);
| private void | snapToDestination()
final int screenWidth = getWidth();
final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth;
snapToScreen(whichScreen);
| void | snapToScreen(int whichScreen)
enableChildrenCache();
whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));
boolean changingScreens = whichScreen != mCurrentScreen;
mNextScreen = whichScreen;
View focusedChild = getFocusedChild();
if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) {
focusedChild.clearFocus();
}
final int newX = whichScreen * getWidth();
final int delta = newX - mScrollX;
mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 2);
invalidate();
| public boolean | snapToSearch()Snap to the nearest screen with a search widget and give it focus
// The screen we are searching
int current = mCurrentScreen;
// first position scanned so far
int first = current;
// last position scanned so far
int last = current;
// True if we should move down on the next iteration
boolean next = false;
// True when we have looked at the first item in the data
boolean hitFirst;
// True when we have looked at the last item in the data
boolean hitLast;
final int count = getChildCount();
while (true) {
if (focusOnSearch(current)) {
return true;
}
hitLast = last == count - 1;
hitFirst = first == 0;
if (hitLast && hitFirst) {
// Looked at everything
break;
}
if (hitFirst || (next && !hitLast)) {
// Either we hit the top, or we are trying to move down
last++;
current = last;
// Try going up next time
next = false;
} else {
// Either we hit the bottom, or we are trying to move up
first--;
current = first;
// Try going down next time
next = true;
}
}
return false;
| 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.
// Note that Search takes focus when clicked rather than entering touch mode
if (!child.isInTouchMode() && !(child instanceof Search)) {
return;
}
mDragInfo = cellInfo;
mDragInfo.screen = mCurrentScreen;
CellLayout current = ((CellLayout) getChildAt(mCurrentScreen));
current.onDragChild(child);
mDragger.startDrag(child, this, child.getTag(), DragController.DRAG_ACTION_MOVE);
invalidate();
| public void | unlock()Unlocks the SlidingDrawer so that touch events are processed.
mLocked = false;
| void | updateShortcutsForPackage(java.lang.String packageName)
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final CellLayout layout = (CellLayout) getChildAt(i);
int childCount = layout.getChildCount();
for (int j = 0; j < childCount; j++) {
final View view = layout.getChildAt(j);
Object tag = view.getTag();
if (tag instanceof ApplicationInfo) {
ApplicationInfo info = (ApplicationInfo) tag;
// We need to check for ACTION_MAIN otherwise getComponent() might
// return null for some shortcuts (for instance, for shortcuts to
// web pages.)
final Intent intent = info.intent;
final ComponentName name = intent.getComponent();
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
Intent.ACTION_MAIN.equals(intent.getAction()) && name != null &&
packageName.equals(name.getPackageName())) {
final Drawable icon = Launcher.getModel().getApplicationInfoIcon(
mLauncher.getPackageManager(), info);
if (icon != null && icon != info.icon) {
info.icon.setCallback(null);
info.icon = Utilities.createIconThumbnail(icon, mContext);
info.filtered = true;
((TextView) view).setCompoundDrawablesWithIntrinsicBounds(null,
info.icon, null, null);
}
}
}
}
}
|
|