blob: c2b710ec79ed197ed8b19859aabc2db5d4fdfb75 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher2;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.launcher.R;
/**
* A ViewGroup that coordinates dragging across its descendants
*/
public class DragLayer extends FrameLayout {
private DragController mDragController;
private int[] mTmpXY = new int[2];
// Variables relating to resizing widgets
private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
new ArrayList<AppWidgetResizeFrame>();
private AppWidgetResizeFrame mCurrentResizeFrame;
private int mXDown, mYDown;
/**
* Used to create a new DragLayer from XML.
*
* @param context The application's context.
* @param attrs The attributes set containing the Workspace's customization values.
*/
public DragLayer(Context context, AttributeSet attrs) {
super(context, attrs);
// Disable multitouch across the workspace/all apps/customize tray
setMotionEventSplittingEnabled(false);
}
public void setDragController(DragController controller) {
mDragController = controller;
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}
private boolean handleTouchDown(MotionEvent ev) {
Rect hitRect = new Rect();
int x = (int) ev.getX();
int y = (int) ev.getY();
for (AppWidgetResizeFrame child: mResizeFrames) {
child.getHitRect(hitRect);
if (hitRect.contains(x, y)) {
if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
mCurrentResizeFrame = child;
mXDown = x;
mYDown = y;
requestDisallowInterceptTouchEvent(true);
return true;
}
}
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (handleTouchDown(ev)) {
return true;
}
}
clearAllResizeFrames();
return mDragController.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean handled = false;
int action = ev.getAction();
int x = (int) ev.getX();
int y = (int) ev.getY();
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (handleTouchDown(ev)) {
return true;
}
}
}
if (mCurrentResizeFrame != null) {
handled = true;
switch (action) {
case MotionEvent.ACTION_MOVE:
mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
mCurrentResizeFrame = null;
}
}
if (handled) return true;
return mDragController.onTouchEvent(ev);
}
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
return mDragController.dispatchUnhandledMove(focused, direction);
}
public View createDragView(Bitmap b, int xPos, int yPos) {
ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(b);
imageView.setX(xPos);
imageView.setY(yPos);
addView(imageView, b.getWidth(), b.getHeight());
return imageView;
}
public View createDragView(View v) {
v.getLocationOnScreen(mTmpXY);
return createDragView(mDragController.getViewBitmap(v), mTmpXY[0], mTmpXY[1]);
}
public static class LayoutParams extends FrameLayout.LayoutParams {
public int x, y;
public boolean customPosition = false;
/**
* {@inheritDoc}
*/
public LayoutParams(int width, int height) {
super(width, height);
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return width;
}
public void setHeight(int height) {
this.height = height;
}
public int getHeight() {
return height;
}
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int count = getChildCount();
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
if (flp instanceof LayoutParams) {
final LayoutParams lp = (LayoutParams) flp;
if (lp.customPosition) {
child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
}
}
}
}
public void clearAllResizeFrames() {
if (mResizeFrames.size() > 0) {
for (AppWidgetResizeFrame frame: mResizeFrames) {
removeView(frame);
}
mResizeFrames.clear();
}
}
public boolean hasResizeFrames() {
return mResizeFrames.size() > 0;
}
public boolean isWidgetBeingResized() {
return mCurrentResizeFrame != null;
}
public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
CellLayout cellLayout) {
AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
itemInfo, widget, cellLayout, this);
LayoutParams lp = new LayoutParams(-1, -1);
lp.customPosition = true;
addView(resizeFrame, lp);
mResizeFrames.add(resizeFrame);
resizeFrame.snapToWidget(false);
}
}