aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/wallpapers/photophase/widgets
diff options
context:
space:
mode:
authorJorge Ruesga <jorge@ruesga.com>2013-08-03 01:26:30 +0200
committerJorge Ruesga <jorge@ruesga.com>2013-08-03 01:26:30 +0200
commit300b62fd6d6dd89bb4d249f27f6211ec21e447ef (patch)
treec129f914955caedbbd8369ed6cbd2b690f231b38 /src/org/cyanogenmod/wallpapers/photophase/widgets
parent81f7dab77c5f28c74da332a038bb3411337f80ad (diff)
downloadandroid_packages_wallpapers_PhotoPhase-300b62fd6d6dd89bb4d249f27f6211ec21e447ef.tar.gz
android_packages_wallpapers_PhotoPhase-300b62fd6d6dd89bb4d249f27f6211ec21e447ef.tar.bz2
android_packages_wallpapers_PhotoPhase-300b62fd6d6dd89bb4d249f27f6211ec21e447ef.zip
Disposition enhancements
* Defaults portrait and landscape disposition * Fix disposition calculation * Disposition Preference: Resize widgets (not finished) * CleanUp Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
Diffstat (limited to 'src/org/cyanogenmod/wallpapers/photophase/widgets')
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java207
-rw-r--r--src/org/cyanogenmod/wallpapers/photophase/widgets/ResizeFrame.java301
2 files changed, 502 insertions, 6 deletions
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
index 93b4b76..8ee1973 100644
--- a/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
+++ b/src/org/cyanogenmod/wallpapers/photophase/widgets/DispositionView.java
@@ -18,25 +18,38 @@ package org.cyanogenmod.wallpapers.photophase.widgets;
import android.content.Context;
import android.graphics.Rect;
+import android.os.Vibrator;
import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.ImageView.ScaleType;
import org.cyanogenmod.wallpapers.photophase.R;
import org.cyanogenmod.wallpapers.photophase.model.Disposition;
+import org.cyanogenmod.wallpapers.photophase.widgets.ResizeFrame.OnResizeListener;
import java.util.List;
/**
- * A class that allow to select the frames disposition visually
+ * A class that allow to select the frames disposition visually
*/
-public class DispositionView extends RelativeLayout {
+public class DispositionView extends RelativeLayout implements OnLongClickListener, OnResizeListener {
private List<Disposition> mDispositions;
private int mCols;
private int mRows;
+ private View mTarget;
+ private ResizeFrame mResizeFrame;
+ private int mInternalPadding;
+ private Rect mOldResizeFrameLocation;
+
+ private Vibrator mVibrator;
+
/**
* Constructor of <code>DispositionView</code>.
*
@@ -44,6 +57,7 @@ public class DispositionView extends RelativeLayout {
*/
public DispositionView(Context context) {
super(context);
+ init();
}
/**
@@ -54,6 +68,7 @@ public class DispositionView extends RelativeLayout {
*/
public DispositionView(Context context, AttributeSet attrs) {
super(context, attrs);
+ init();
}
/**
@@ -68,6 +83,15 @@ public class DispositionView extends RelativeLayout {
*/
public DispositionView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ init();
+ }
+
+ /**
+ * Initialize the view
+ */
+ private void init() {
+ mVibrator = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE);
+ mInternalPadding = (int)getResources().getDimension(R.dimen.disposition_frame_padding);
}
/**
@@ -88,6 +112,16 @@ public class DispositionView extends RelativeLayout {
}
/**
+ * Method that sets the resize frame view
+ *
+ * @param resizeFrame The resize frame view
+ */
+ public void setResizeFrame(ResizeFrame resizeFrame) {
+ mResizeFrame = resizeFrame;
+ mResizeFrame.setOnResizeListener(this);
+ }
+
+ /**
* Method that create a new frame to be drawn in the specified location
*
* @param r The location relative to the parent layout
@@ -102,8 +136,7 @@ public class DispositionView extends RelativeLayout {
new RelativeLayout.LayoutParams(r.width() - padding, r.height() - padding);
params.leftMargin = r.left + padding;
params.topMargin = r.top + padding;
- v.setFocusable(true);
- v.setFocusableInTouchMode(true);
+ v.setOnLongClickListener(this);
addView(v, params);
}
@@ -114,8 +147,8 @@ public class DispositionView extends RelativeLayout {
* @return Rect The location on parent view
*/
private Rect getLocationFromDisposition(Disposition disposition) {
- int w = getMeasuredWidth();
- int h = getMeasuredHeight();
+ int w = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
+ int h = getMeasuredHeight() - (getPaddingTop() + getPaddingBottom());
int cw = w / mCols;
int ch = h / mRows;
@@ -126,4 +159,166 @@ public class DispositionView extends RelativeLayout {
location.bottom = location.top + disposition.h * ch;
return location;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onLongClick(View v) {
+ // Do not do long click if we do not have a target
+// if (mTarget != null) return false;
+
+ // Show the resize frame view just in place of the current clicked view
+ mResizeFrame.hide();
+ RelativeLayout.LayoutParams viewParams =
+ (RelativeLayout.LayoutParams)v.getLayoutParams();
+ FrameLayout.LayoutParams frameParams =
+ (FrameLayout.LayoutParams)mResizeFrame.getLayoutParams();
+ int padding = mInternalPadding + mResizeFrame.getNeededPadding();
+ frameParams.width = viewParams.width + (padding * 2);
+ frameParams.height = viewParams.height + (padding * 2);
+ mResizeFrame.setX(v.getLeft() - padding);
+ mResizeFrame.setY(v.getTop() - padding);
+ mVibrator.vibrate(300);
+ mResizeFrame.show();
+
+ // Save the new view
+ mTarget = v;
+
+ return true;
+ }
+
+ @Override
+ public void onStartResize(int mode) {
+ mOldResizeFrameLocation = new Rect(
+ mResizeFrame.getLeft(),
+ mResizeFrame.getTop(),
+ mResizeFrame.getRight(),
+ mResizeFrame.getBottom());
+ }
+
+ @Override
+ public void onResize(int mode, int delta) {
+ if (mTarget == null) return;
+
+ int w = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
+ int h = getMeasuredHeight() - (getPaddingTop() + getPaddingBottom());
+ int minWidth = (w / mCols) + (w / mCols) / 2;
+ int minHeight = (h / mRows) + (h / mRows) / 2;
+
+ FrameLayout.LayoutParams params =
+ (FrameLayout.LayoutParams)mResizeFrame.getLayoutParams();
+ switch (mode) {
+ case Gravity.LEFT:
+ float newpos = mResizeFrame.getX() + delta;
+ if ((delta < 0 && newpos < (getPaddingLeft() * -1)) ||
+ (delta > 0 && newpos > (mResizeFrame.getX() + params.width - minWidth))) {
+ return;
+ }
+ mResizeFrame.setX(newpos);
+ params.width -= delta;
+ break;
+ case Gravity.RIGHT:
+ if ((delta < 0 && ((params.width + delta) < minWidth)) ||
+ (delta > 0 && (mResizeFrame.getX() + delta + params.width) > (getPaddingLeft() + getMeasuredWidth()))) {
+ return;
+ }
+ params.width += delta;
+ break;
+ case Gravity.TOP:
+ newpos = mResizeFrame.getY() + delta;
+ if ((delta < 0 && newpos < (getPaddingTop() * -1)) ||
+ (delta > 0 && newpos > (mResizeFrame.getY() + params.height - minHeight))) {
+ return;
+ }
+ mResizeFrame.setY(newpos);
+ params.height -= delta;
+ break;
+ case Gravity.BOTTOM:
+ if ((delta < 0 && ((params.height + delta) < minHeight)) ||
+ (delta > 0 && (mResizeFrame.getY() + delta + params.height) > (getPaddingTop() + getMeasuredHeight()))) {
+ return;
+ }
+ params.height += delta;
+ break;
+
+ default:
+ break;
+ }
+ mResizeFrame.setLayoutParams(params);
+ }
+
+ @Override
+ public void onEndResize(int mode) {
+ try {
+// int w = getMeasuredWidth();
+// int h = getMeasuredHeight();
+// int cw = w / mCols;
+// int ch = h / mRows;
+//
+// // Retrieve the new layout params
+// int neededPadding = mResizeFrame.getNeededPadding();
+// int padding = (int)getResources().getDimension(R.dimen.disposition_frame_padding)
+// + neededPadding;
+// FrameLayout.LayoutParams params =
+// (FrameLayout.LayoutParams)mResizeFrame.getLayoutParams();
+// switch (mode) {
+// case Gravity.LEFT:
+// int left = params.leftMargin + padding;
+// if (left % cw != 0) {
+// params.leftMargin = ((left / cw) * cw) - padding;
+//// params.width += ((left / cw) * cw) - left + (padding * 2);
+// }
+// break;
+// case Gravity.RIGHT:
+// int right = params.rightMargin + padding;
+// if (right % cw != 0) {
+// params.rightMargin = ((right / cw) * cw) - padding;
+//// params.width += ((right / cw) * cw) - right + (padding * 2);
+// }
+// break;
+// case Gravity.TOP:
+// int top = params.topMargin + padding;
+// if (top % ch != 0) {
+// params.topMargin = ((top / ch) * ch) - padding;
+//// params.height += ((top / cw) * cw) - top + (padding * 2);
+// }
+// break;
+// case Gravity.BOTTOM:
+// int bottom = params.bottomMargin + padding;
+// if (bottom % ch != 0) {
+// params.bottomMargin = ((bottom / ch) * ch) - padding;
+//// params.height += ((bottom / cw) * cw) - bottom + (padding * 2);
+// }
+// break;
+//
+// default:
+// break;
+// }
+// mResizeFrame.setLayoutParams(params);
+// mResizeFrame.invalidate();
+
+ // Recalculate all the dispositions in base to the new positions
+
+ } finally {
+ // Reset vars
+// mOldResizeFrameLocation = null;
+// mTarget = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onCancel() {
+ if (mOldResizeFrameLocation != null) {
+ mTarget.setLeft(mOldResizeFrameLocation.left);
+ mTarget.setRight(mOldResizeFrameLocation.right);
+ mTarget.setTop(mOldResizeFrameLocation.top);
+ mTarget.setBottom(mOldResizeFrameLocation.bottom);
+ }
+// mOldResizeFrameLocation = null;
+// mTarget = null;
+ }
}
diff --git a/src/org/cyanogenmod/wallpapers/photophase/widgets/ResizeFrame.java b/src/org/cyanogenmod/wallpapers/photophase/widgets/ResizeFrame.java
new file mode 100644
index 0000000..218a4e4
--- /dev/null
+++ b/src/org/cyanogenmod/wallpapers/photophase/widgets/ResizeFrame.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2013 The CyanogenMod 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 org.cyanogenmod.wallpapers.photophase.widgets;
+
+import android.content.Context;
+import android.graphics.BitmapFactory;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+
+import org.cyanogenmod.wallpapers.photophase.R;
+
+/**
+ * The hold view to resize a frame. A square with 4 handles in every border
+ * to drag and resize a view
+ */
+public class ResizeFrame extends RelativeLayout {
+
+ /**
+ * An interface to communicate resize event states
+ */
+ public interface OnResizeListener {
+ /**
+ * Called when the resize is going to start
+ *
+ * @param mode The resize mode (left, right, top, bottom)
+ * @see Gravity
+ */
+ void onStartResize(int mode);
+ /**
+ * Called when the resize is going to start
+ *
+ * @param mode The resize mode (left, right, top, bottom)
+ * @param delta The delta motion
+ * @see Gravity
+ */
+ void onResize(int mode, int delta);
+ /**
+ * Called when the resize was ended
+ *
+ * @param mode The resize mode (left, right, top, bottom)
+ * @see Gravity
+ */
+ void onEndResize(int mode);
+ /**
+ * Called when the resize was cancelled
+ *
+ * @param mode The resize mode (left, right, top, bottom)
+ * @see Gravity
+ */
+ void onCancel();
+ }
+
+ private int mNeededPadding;
+
+ private ImageView mLeftHandle;
+ private ImageView mRightHandle;
+ private ImageView mTopHandle;
+ private ImageView mBottomHandle;
+
+ private float mExtraHandlingSpace;
+
+ private View mHandle;
+
+ private float mLastTouchX;
+ private float mLastTouchY;
+
+ private OnResizeListener mOnResizeListener;
+
+ /**
+ * Constructor of <code>ResizeFrame</code>.
+ *
+ * @param context The current context
+ */
+ public ResizeFrame(Context context) {
+ super(context);
+ init();
+ }
+
+ /**
+ * Constructor of <code>ResizeFrame</code>.
+ *
+ * @param context The current context
+ * @param attrs The attributes of the XML tag that is inflating the view.
+ */
+ public ResizeFrame(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ /**
+ * Constructor of <code>ResizeFrame</code>.
+ *
+ * @param context The current context
+ * @param attrs The attributes of the XML tag that is inflating the view.
+ * @param defStyle The default style to apply to this view. If 0, no style
+ * will be applied (beyond what is included in the theme). This may
+ * either be an attribute resource, whose value will be retrieved
+ * from the current theme, or an explicit style resource.
+ */
+ public ResizeFrame(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ /**
+ * Method that initializes the view
+ */
+ @SuppressWarnings("boxing")
+ private void init() {
+ setBackgroundResource(R.drawable.resize_frame);
+ setPadding(0, 0, 0, 0);
+
+ BitmapFactory.Options o = new BitmapFactory.Options();
+ o.inJustDecodeBounds = true;
+ o.inTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
+ BitmapFactory.decodeResource(getContext().getResources(), R.drawable.resize_handle_left, o);
+ mNeededPadding = (int)(o.outWidth / 1.5f);
+
+ LayoutParams lp;
+ mLeftHandle = new ImageView(getContext());
+ mLeftHandle.setImageResource(R.drawable.resize_handle_left);
+ mLeftHandle.setTag(Gravity.LEFT);
+ lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
+ lp.addRule(RelativeLayout.CENTER_VERTICAL);
+ addView(mLeftHandle, lp);
+
+ mRightHandle = new ImageView(getContext());
+ mRightHandle.setImageResource(R.drawable.resize_handle_right);
+ mRightHandle.setTag(Gravity.RIGHT);
+ lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
+ lp.addRule(RelativeLayout.CENTER_VERTICAL);
+ addView(mRightHandle, lp);
+
+ mTopHandle = new ImageView(getContext());
+ mTopHandle.setImageResource(R.drawable.resize_handle_top);
+ mTopHandle.setTag(Gravity.TOP);
+ lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ lp.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
+ lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
+ addView(mTopHandle, lp);
+
+ mBottomHandle = new ImageView(getContext());
+ mBottomHandle.setImageResource(R.drawable.resize_handle_bottom);
+ mBottomHandle.setTag(Gravity.BOTTOM);
+ lp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
+ lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
+ addView(mBottomHandle, lp);
+
+ mExtraHandlingSpace = getResources().getDimension(R.dimen.resize_frame_extra_handling_space);
+ }
+
+ /**
+ * Method that set the callback for resize events
+ *
+ * @param onResizeListener The callback
+ */
+ public void setOnResizeListener(OnResizeListener onResizeListener) {
+ mOnResizeListener = onResizeListener;
+ }
+
+ /**
+ * Method that hides the view
+ */
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ /**
+ * Method that shows the view
+ */
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * Method that returns the extra padding to draw the handlers
+ *
+ * @return The extra padding space
+ */
+ public int getNeededPadding() {
+ return mNeededPadding;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ final int action = ev.getAction();
+ final float x = ev.getX();
+ final float y = ev.getY();
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ mHandle = getHandleFromCoordinates(x, y);
+ if (mHandle != null) {
+ // Start moving the resize frame
+ mLastTouchX = x;
+ mLastTouchY = y;
+
+ // Start motion
+ if (mOnResizeListener != null) {
+ mOnResizeListener.onStartResize(((Integer)mHandle.getTag()).intValue());
+ }
+ return true;
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (mHandle != null) {
+ // Resize
+ if (mOnResizeListener != null) {
+ int handle = ((Integer)mHandle.getTag()).intValue();
+ int delta =
+ handle == Gravity.LEFT || handle == Gravity.RIGHT
+ ? Math.round(x - mLastTouchX)
+ : Math.round(y - mLastTouchY);
+ mOnResizeListener.onResize(handle, delta);
+ invalidate();
+ }
+ mLastTouchX = x;
+ mLastTouchY = y;
+ return true;
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ if (mHandle != null) {
+ if (mOnResizeListener != null) {
+ mOnResizeListener.onEndResize(((Integer)mHandle.getTag()).intValue());
+ return true;
+ }
+ cancelMotion();
+ break;
+ }
+
+ //$FALL-THROUGH$
+ case MotionEvent.ACTION_CANCEL:
+ cancelMotion();
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ /**
+ * Cancel motions
+ */
+ private void cancelMotion() {
+ mHandle = null;
+ mLastTouchX = 0;
+ mLastTouchY = 0;
+ if (mOnResizeListener != null) {
+ mOnResizeListener.onCancel();
+ }
+ }
+
+ /**
+ * Method that returns the resize handle touch from the the screen coordinates
+ *
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @return View The handle view or null if no handle touched
+ */
+ private View getHandleFromCoordinates(float x, float y) {
+ final View[] handles = {mLeftHandle, mRightHandle, mTopHandle, mBottomHandle};
+ for (View v : handles) {
+ if ((v.getLeft() - mExtraHandlingSpace) < x && (v.getRight() + mExtraHandlingSpace) > x &&
+ (v.getTop() - mExtraHandlingSpace) < y && (v.getBottom() + mExtraHandlingSpace) > y) {
+ return v;
+ }
+ }
+ return null;
+ }
+}