Commit 39ecc0a7 by German Callejas

Libreria para recortar añadida, sin funcionalidad aun.

Cambios en la versión de la bbdd para solucionar el problema entre la 1 y la 2
parent b0215055
Showing with 2243 additions and 4 deletions
...@@ -64,7 +64,7 @@ public final class PCBcontext { ...@@ -64,7 +64,7 @@ public final class PCBcontext {
Log.i(PCBcontext.class.getCanonicalName(), "User set at student " + student.get_name_stu()); Log.i(PCBcontext.class.getCanonicalName(), "User set at student " + student.get_name_stu());
wrapper.setToken(token); wrapper.setToken(token);
pcbdb = new PCBDBHelper(null, 1, student); pcbdb = new PCBDBHelper(null, 2, student);
pcbdb.user_online(token!=null); pcbdb.user_online(token!=null);
room = new Room(); room = new Room();
actionLog = new ActionLog(); actionLog = new ActionLog();
......
package com.yottacode.pictogram.tabletlibrary.cropper;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.yottacode.pictogram.tabletlibrary.R;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle.Handle;
import com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil;
import com.yottacode.pictogram.tabletlibrary.cropper.util.HandleUtil;
import com.yottacode.pictogram.tabletlibrary.cropper.util.PaintUtil;
/**
* Custom view that provides cropping capabilities to an image.
*
* Class to see it on the image to crop
*/
public class CropImageView extends ImageView {
// Private Constants ///////////////////////////////////////////////////////////////////////////
@SuppressWarnings("unused")
private static final String TAG = CropImageView.class.getName();
@SuppressWarnings("unused")
public static final int GUIDELINES_OFF = 0;
public static final int GUIDELINES_ON_TOUCH = 1;
public static final int GUIDELINES_ON = 2;
// Member Variables ////////////////////////////////////////////////////////////////////////////
// The Paint used to draw the white rectangle around the crop area.
private Paint mBorderPaint;
// The Paint used to draw the guidelines within the crop area when pressed.
private Paint mGuidelinePaint;
// The Paint used to draw the corners of the Border
private Paint mCornerPaint;
// The Paint used to darken the surrounding areas outside the crop area.
private Paint mSurroundingAreaOverlayPaint;
// The radius (in pixels) of the touchable area around the handle.
// We are basing this value off of the recommended 48dp touch target size.
private float mHandleRadius;
// An edge of the crop window will snap to the corresponding edge of a
// specified bounding box when the crop window edge is less than or equal to
// this distance (in pixels) away from the bounding box edge.
private float mSnapRadius;
// Thickness of the line (in pixels) used to draw the corner handle.
private float mCornerThickness;
// Thickness of the line (in pixels) used to draw the border of the crop window.
private float mBorderThickness;
// Length of one side of the corner handle.
private float mCornerLength;
// The bounding box around the Bitmap that we are cropping.
@NonNull
private RectF mBitmapRect = new RectF();
// Holds the x and y offset between the exact touch location and the exact
// handle location that is activated. There may be an offset because we
// allow for some leeway (specified by 'mHandleRadius') in activating a
// handle. However, we want to maintain these offset values while the handle
// is being dragged so that the handle doesn't jump.
@NonNull
private PointF mTouchOffset = new PointF();
// The Handle that is currently pressed; null if no Handle is pressed.
private Handle mPressedHandle;
// Flag indicating if the crop area should always be a certain aspect ratio (indicated by mTargetAspectRatio).
private boolean mFixAspectRatio;
// Current aspect ratio of the image.
private int mAspectRatioX = 1;
private int mAspectRatioY = 1;
// Mode indicating how/whether to show the guidelines; must be one of GUIDELINES_OFF, GUIDELINES_ON_TOUCH, GUIDELINES_ON.
private int mGuidelinesMode = 1;
// Constructors ////////////////////////////////////////////////////////////////////////////////
public CropImageView(Context context) {
super(context);
init(context, null);
}
public CropImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CropImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
final TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CropImageView, 0, 0);
mGuidelinesMode = typedArray.getInteger(R.styleable.CropImageView_guidelines, 1);
mFixAspectRatio = typedArray.getBoolean(R.styleable.CropImageView_fixAspectRatio, false);
mAspectRatioX = typedArray.getInteger(R.styleable.CropImageView_aspectRatioX, 1);
mAspectRatioY = typedArray.getInteger(R.styleable.CropImageView_aspectRatioY, 1);
typedArray.recycle();
final Resources resources = context.getResources();
mBorderPaint = PaintUtil.newBorderPaint(resources);
mGuidelinePaint = PaintUtil.newGuidelinePaint(resources);
mSurroundingAreaOverlayPaint = PaintUtil.newSurroundingAreaOverlayPaint(resources);
mCornerPaint = PaintUtil.newCornerPaint(resources);
mHandleRadius = resources.getDimension(R.dimen.target_radius);
mSnapRadius = resources.getDimension(R.dimen.snap_radius);
mBorderThickness = resources.getDimension(R.dimen.border_thickness);
mCornerThickness = resources.getDimension(R.dimen.corner_thickness);
mCornerLength = resources.getDimension(R.dimen.corner_length);
}
// View Methods ////////////////////////////////////////////////////////////////////////////////
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mBitmapRect = getBitmapRect();
initCropWindow(mBitmapRect);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawDarkenedSurroundingArea(canvas);
drawGuidelines(canvas);
drawBorder(canvas);
drawCorners(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// If this View is not enabled, don't allow for touch interactions.
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
onActionDown(event.getX(), event.getY());
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
onActionUp();
return true;
case MotionEvent.ACTION_MOVE:
onActionMove(event.getX(), event.getY());
getParent().requestDisallowInterceptTouchEvent(true);
return true;
default:
return false;
}
}
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Sets the guidelines for the CropOverlayView to be either on, off, or to show when resizing
* the application.
*
* @param guidelinesMode Integer that signals whether the guidelines should be on, off, or only
* showing when resizing.
*/
public void setGuidelines(int guidelinesMode) {
mGuidelinesMode = guidelinesMode;
invalidate(); // Request onDraw() to get called again.
}
/**
* Sets whether the aspect ratio is fixed or not; true fixes the aspect ratio, while false
* allows it to be changed.
*
* @param fixAspectRatio Boolean that signals whether the aspect ratio should be maintained.
*
* @see {@link #setAspectRatio(int, int)}
*/
public void setFixedAspectRatio(boolean fixAspectRatio) {
mFixAspectRatio = fixAspectRatio;
requestLayout(); // Request measure/layout to be run again.
}
/**
* Sets the both the X and Y values of the aspectRatio. These only apply iff fixed aspect ratio
* is set.
*
* @param aspectRatioX new X value of the aspect ratio; must be greater than 0
* @param aspectRatioY new Y value of the aspect ratio; must be greater than 0
*
* @see {@link #setFixedAspectRatio(boolean)}
*/
public void setAspectRatio(int aspectRatioX, int aspectRatioY) {
if (aspectRatioX <= 0 || aspectRatioY <= 0) {
throw new IllegalArgumentException("Cannot set aspect ratio value to a number less than or equal to 0.");
}
mAspectRatioX = aspectRatioX;
mAspectRatioY = aspectRatioY;
if (mFixAspectRatio) {
requestLayout(); // Request measure/layout to be run again.
}
}
/**
* Gets the cropped image based on the current crop window.
*
* @return a new Bitmap representing the cropped image
*/
public Bitmap getCroppedImage() {
// Implementation reference: http://stackoverflow.com/a/26930938/1068656
final Drawable drawable = this.getDrawable();
if (drawable == null || !(drawable instanceof BitmapDrawable)) {
return null;
}
// Get image matrix values and place them in an array.
final float[] matrixValues = new float[9];
this.getImageMatrix().getValues(matrixValues);
// Extract the scale values. Note, we currently do not handle any other transformations (e.g. skew).
final float scaleX = matrixValues[Matrix.MSCALE_X]; //==1
final float scaleY = matrixValues[Matrix.MSCALE_Y]; //==1
// Extract the translation values.
final float transX = matrixValues[Matrix.MTRANS_X];
final float transY = matrixValues[Matrix.MTRANS_Y];
final Bitmap originalBitmap = ((BitmapDrawable) drawable).getBitmap();
Log.i("DETALLES","ScaleX: "+scaleX + "- ScaleY: "+scaleY);
Log.i("DETALLES","transX: "+transX + "- transY: "+transY);
Log.i("DETALLES","Edge Left: "+Edge.LEFT.getCoordinate() + "- Edge Top: "+Edge.TOP.getCoordinate());
Log.i("DETALLES","ancho original: "+originalBitmap.getWidth() + " Alto original: "+originalBitmap.getHeight());
final float cropWidth = Edge.getWidth();
final float cropHeight = Edge.getHeight();
Log.i("DETALLES","ancho original: "+originalBitmap.getWidth() + " Alto original: "+originalBitmap.getHeight());
Log.i("DETALLES","ancho: "+cropWidth + " Alto: "+cropHeight);
// Ensure that the left and top edges are not outside of the ImageView bounds.
/*final float bitmapLeft = (transX < 0) ? Math.abs(transX) : 0;
final float bitmapTop = (transY < 0) ? Math.abs(transY) : 0;*/
// Get the original bitmap object.
//final Bitmap originalBitmap = ((BitmapDrawable) drawable).getBitmap();
final float bitmapLeft = ((findViewById(R.id.ScrollView)).getWidth() - originalBitmap.getWidth())/2;
final float bitmapTop = ((findViewById(R.id.ScrollView)).getHeight() - originalBitmap.getHeight())/2;
Log.i("DETALLES","bitmapLeft: "+bitmapLeft + "- bitmapTop: "+bitmapTop);
// Calculate the top-left corner of the crop window relative to the ~original~ bitmap size.
final float cropX = (bitmapLeft + Edge.LEFT.getCoordinate());
final float cropY = (bitmapTop + Edge.TOP.getCoordinate());
Log.i("DETALLES","Edge Left: "+Edge.LEFT.getCoordinate() + "- Edge Top: "+Edge.TOP.getCoordinate());
Log.i("DETALLES","Posicion X: "+cropX + "- Posicion Y: "+cropY);
// Calculate the crop window size relative to the ~original~ bitmap size.
// Make sure the right and bottom edges are not outside the ImageView bounds (this is just to address rounding discrepancies).
/*final float cropWidth = Edge.getWidth();
final float cropHeight = Edge.getHeight();
Log.i("DETALLES","ancho original: "+originalBitmap.getWidth() + " Alto original: "+originalBitmap.getHeight());
Log.i("DETALLES","ancho: "+cropWidth + " Alto: "+cropHeight);*/
// Crop the subset from the original Bitmap.
return Bitmap.createBitmap(originalBitmap,
(int) cropX,
(int) cropY,
(int) cropWidth,
(int) cropHeight);
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Gets the bounding rectangle of the bitmap within the ImageView.
*/
private RectF getBitmapRect() {
final Drawable drawable = getDrawable();
if (drawable == null) {
return new RectF();
}
// Get image matrix values and place them in an array.
final float[] matrixValues = new float[9];
getImageMatrix().getValues(matrixValues);
// Extract the scale and translation values from the matrix.
final float scaleX = matrixValues[Matrix.MSCALE_X];
final float scaleY = matrixValues[Matrix.MSCALE_Y];
final float transX = matrixValues[Matrix.MTRANS_X];
final float transY = matrixValues[Matrix.MTRANS_Y];
// Get the width and height of the original bitmap.
final int drawableIntrinsicWidth = drawable.getIntrinsicWidth();
final int drawableIntrinsicHeight = drawable.getIntrinsicHeight();
// Calculate the dimensions as seen on screen.
final int drawableDisplayWidth = Math.round(drawableIntrinsicWidth * scaleX);
final int drawableDisplayHeight = Math.round(drawableIntrinsicHeight * scaleY);
// Get the Rect of the displayed image within the ImageView.
final float left = Math.max(transX, 0);
final float top = Math.max(transY, 0);
final float right = Math.min(left + drawableDisplayWidth, getWidth());
final float bottom = Math.min(top + drawableDisplayHeight, getHeight());
return new RectF(left, top, right, bottom);
}
/**
* Initialize the crop window by setting the proper {@link Edge} values.
* <p/>
* If fixed aspect ratio is turned off, the initial crop window will be set to the displayed
* image with 10% margin. If fixed aspect ratio is turned on, the initial crop window will
* conform to the aspect ratio with at least one dimension maximized.
*/
private void initCropWindow(@NonNull RectF bitmapRect) {
if (mFixAspectRatio) {
// Initialize the crop window with the proper aspect ratio.
initCropWindowWithFixedAspectRatio(bitmapRect);
} else {
// Initialize crop window to have 10% padding w/ respect to Drawable's bounds.
final float horizontalPadding = 0.1f * bitmapRect.width();
final float verticalPadding = 0.1f * bitmapRect.height();
Edge.LEFT.setCoordinate(bitmapRect.left + horizontalPadding);
Edge.TOP.setCoordinate(bitmapRect.top + verticalPadding);
Edge.RIGHT.setCoordinate(bitmapRect.right - horizontalPadding);
Edge.BOTTOM.setCoordinate(bitmapRect.bottom - verticalPadding);
}
}
private void initCropWindowWithFixedAspectRatio(@NonNull RectF bitmapRect) {
// If the image aspect ratio is wider than the crop aspect ratio,
// then the image height is the determining initial length. Else, vice-versa.
if (AspectRatioUtil.calculateAspectRatio(bitmapRect) > getTargetAspectRatio()) {
final float cropWidth = AspectRatioUtil.calculateWidth(bitmapRect.height(), getTargetAspectRatio());
Edge.LEFT.setCoordinate(bitmapRect.centerX() - cropWidth / 2f);
Edge.TOP.setCoordinate(bitmapRect.top);
Edge.RIGHT.setCoordinate(bitmapRect.centerX() + cropWidth / 2f);
Edge.BOTTOM.setCoordinate(bitmapRect.bottom);
} else {
final float cropHeight = AspectRatioUtil.calculateHeight(bitmapRect.width(), getTargetAspectRatio());
Edge.LEFT.setCoordinate(bitmapRect.left);
Edge.TOP.setCoordinate(bitmapRect.centerY() - cropHeight / 2f);
Edge.RIGHT.setCoordinate(bitmapRect.right);
Edge.BOTTOM.setCoordinate(bitmapRect.centerY() + cropHeight / 2f);
}
}
private void drawDarkenedSurroundingArea(@NonNull Canvas canvas) {
final RectF bitmapRect = mBitmapRect;
final float left = Edge.LEFT.getCoordinate();
final float top = Edge.TOP.getCoordinate();
final float right = Edge.RIGHT.getCoordinate();
final float bottom = Edge.BOTTOM.getCoordinate();
/*-
-------------------------------------
| top |
-------------------------------------
| | | |
| | | |
| left | | right |
| | | |
| | | |
-------------------------------------
| bottom |
-------------------------------------
*/
// Draw "top", "bottom", "left", then "right" quadrants according to diagram above.
canvas.drawRect(bitmapRect.left, bitmapRect.top, bitmapRect.right, top, mSurroundingAreaOverlayPaint);
canvas.drawRect(bitmapRect.left, bottom, bitmapRect.right, bitmapRect.bottom, mSurroundingAreaOverlayPaint);
canvas.drawRect(bitmapRect.left, top, left, bottom, mSurroundingAreaOverlayPaint);
canvas.drawRect(right, top, bitmapRect.right, bottom, mSurroundingAreaOverlayPaint);
}
private void drawGuidelines(@NonNull Canvas canvas) {
if (!shouldGuidelinesBeShown()) {
return;
}
final float left = Edge.LEFT.getCoordinate();
final float top = Edge.TOP.getCoordinate();
final float right = Edge.RIGHT.getCoordinate();
final float bottom = Edge.BOTTOM.getCoordinate();
// Draw vertical guidelines.
final float oneThirdCropWidth = Edge.getWidth() / 3;
final float x1 = left + oneThirdCropWidth;
canvas.drawLine(x1, top, x1, bottom, mGuidelinePaint);
final float x2 = right - oneThirdCropWidth;
canvas.drawLine(x2, top, x2, bottom, mGuidelinePaint);
// Draw horizontal guidelines.
final float oneThirdCropHeight = Edge.getHeight() / 3;
final float y1 = top + oneThirdCropHeight;
canvas.drawLine(left, y1, right, y1, mGuidelinePaint);
final float y2 = bottom - oneThirdCropHeight;
canvas.drawLine(left, y2, right, y2, mGuidelinePaint);
}
private void drawBorder(@NonNull Canvas canvas) {
canvas.drawRect(Edge.LEFT.getCoordinate(),
Edge.TOP.getCoordinate(),
Edge.RIGHT.getCoordinate(),
Edge.BOTTOM.getCoordinate(),
mBorderPaint);
}
private void drawCorners(@NonNull Canvas canvas) {
final float left = Edge.LEFT.getCoordinate();
final float top = Edge.TOP.getCoordinate();
final float right = Edge.RIGHT.getCoordinate();
final float bottom = Edge.BOTTOM.getCoordinate();
// Absolute value of the offset by which to draw the corner line such that its inner edge is flush with the border's inner edge.
final float lateralOffset = (mCornerThickness - mBorderThickness) / 2f;
// Absolute value of the offset by which to start the corner line such that the line is drawn all the way to form a corner edge with the adjacent side.
final float startOffset = mCornerThickness - (mBorderThickness / 2f);
// Top-left corner: left side
canvas.drawLine(left - lateralOffset, top - startOffset, left - lateralOffset, top + mCornerLength, mCornerPaint);
// Top-left corner: top side
canvas.drawLine(left - startOffset, top - lateralOffset, left + mCornerLength, top - lateralOffset, mCornerPaint);
// Top-right corner: right side
canvas.drawLine(right + lateralOffset, top - startOffset, right + lateralOffset, top + mCornerLength, mCornerPaint);
// Top-right corner: top side
canvas.drawLine(right + startOffset, top - lateralOffset, right - mCornerLength, top - lateralOffset, mCornerPaint);
// Bottom-left corner: left side
canvas.drawLine(left - lateralOffset, bottom + startOffset, left - lateralOffset, bottom - mCornerLength, mCornerPaint);
// Bottom-left corner: bottom side
canvas.drawLine(left - startOffset, bottom + lateralOffset, left + mCornerLength, bottom + lateralOffset, mCornerPaint);
// Bottom-right corner: right side
canvas.drawLine(right + lateralOffset, bottom + startOffset, right + lateralOffset, bottom - mCornerLength, mCornerPaint);
// Bottom-right corner: bottom side
canvas.drawLine(right + startOffset, bottom + lateralOffset, right - mCornerLength, bottom + lateralOffset, mCornerPaint);
}
private boolean shouldGuidelinesBeShown() {
return ((mGuidelinesMode == GUIDELINES_ON)
|| ((mGuidelinesMode == GUIDELINES_ON_TOUCH) && (mPressedHandle != null)));
}
private float getTargetAspectRatio() {
return mAspectRatioX / (float) mAspectRatioY;
}
/**
* Handles a {@link MotionEvent#ACTION_DOWN} event.
*
* @param x the x-coordinate of the down action
* @param y the y-coordinate of the down action
*/
private void onActionDown(float x, float y) {
final float left = Edge.LEFT.getCoordinate();
final float top = Edge.TOP.getCoordinate();
final float right = Edge.RIGHT.getCoordinate();
final float bottom = Edge.BOTTOM.getCoordinate();
mPressedHandle = HandleUtil.getPressedHandle(x, y, left, top, right, bottom, mHandleRadius);
// Calculate the offset of the touch point from the precise location of the handle.
// Save these values in member variable 'mTouchOffset' so that we can maintain this offset as we drag the handle.
if (mPressedHandle != null) {
HandleUtil.getOffset(mPressedHandle, x, y, left, top, right, bottom, mTouchOffset);
invalidate();
}
}
/**
* Handles a {@link MotionEvent#ACTION_UP} or {@link MotionEvent#ACTION_CANCEL} event.
*/
private void onActionUp() {
if (mPressedHandle != null) {
mPressedHandle = null;
invalidate();
}
}
/**
* Handles a {@link MotionEvent#ACTION_MOVE} event.
*
* @param x the x-coordinate of the move event
* @param y the y-coordinate of the move event
*/
private void onActionMove(float x, float y) {
if (mPressedHandle == null) {
return;
}
// Adjust the coordinates for the finger position's offset (i.e. the distance from the initial touch to the precise handle location).
// We want to maintain the initial touch's distance to the pressed handle so that the crop window size does not "jump".
x += mTouchOffset.x;
y += mTouchOffset.y;
// Calculate the new crop window size/position.
if (mFixAspectRatio) {
mPressedHandle.updateCropWindow(x, y, getTargetAspectRatio(), mBitmapRect, mSnapRadius);
} else {
mPressedHandle.updateCropWindow(x, y, mBitmapRect, mSnapRadius);
}
invalidate();
}
}
package com.yottacode.pictogram.tabletlibrary.cropper;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;
import com.yottacode.pictogram.tabletlibrary.cropper.CropImageView;
import com.yottacode.pictogram.tabletlibrary.R;
public class MainCropImage extends Activity {
// Private Constants ///////////////////////////////////////////////////////////////////////////
private static final int GUIDELINES_ON_TOUCH = 1;
// Activity Methods ////////////////////////////////////////////////////////////////////////////
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.crop_layout);
// Initialize Views.
//final ToggleButton fixedAspectRatioToggleButton = (ToggleButton) findViewById(R.id.fixedAspectRatioToggle);
//final TextView aspectRatioXTextView = (TextView) findViewById(R.id.aspectRatioX);
//final SeekBar aspectRatioXSeekBar = (SeekBar) findViewById(R.id.aspectRatioXSeek);
//final TextView aspectRatioYTextView = (TextView) findViewById(R.id.aspectRatioY);
//final SeekBar aspectRatioYSeekBar = (SeekBar) findViewById(R.id.aspectRatioYSeek);
//final Spinner guidelinesSpinner = (Spinner) findViewById(R.id.showGuidelinesSpin);
final CropImageView cropImageView = (CropImageView) findViewById(R.id.CropImageView);
final ImageView croppedImageView = (ImageView) findViewById(R.id.croppedImageView);
final Button cropButton = (Button) findViewById(R.id.Button_crop);
cropImageView.setGuidelines(CropImageView.GUIDELINES_ON); //To show the guidelines
cropImageView.setAspectRatio(1,1);
// Initializes fixedAspectRatio toggle button.
/*fixedAspectRatioToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
cropImageView.setFixedAspectRatio(isChecked);
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioXSeekBar.setEnabled(isChecked);
aspectRatioYSeekBar.setEnabled(isChecked);
}
});*/
// Set seek bars to be disabled until toggle button is checked.
/*aspectRatioXSeekBar.setEnabled(false);
aspectRatioYSeekBar.setEnabled(false);
aspectRatioXTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));
aspectRatioYTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));*/
// Initialize aspect ratio X SeekBar.
/*aspectRatioXSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioXSeekBar, int progress, boolean fromUser) {
if (progress < 1) {
aspectRatioXSeekBar.setProgress(1);
}
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioXTextView.setText(String.valueOf(aspectRatioXSeekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
});*/
// Initialize aspect ratio Y SeekBar.
/*aspectRatioYSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar aspectRatioYSeekBar, int progress, boolean fromUser) {
if (progress < 1) {
aspectRatioYSeekBar.setProgress(1);
}
cropImageView.setAspectRatio(aspectRatioXSeekBar.getProgress(), aspectRatioYSeekBar.getProgress());
aspectRatioYTextView.setText(String.valueOf(aspectRatioYSeekBar.getProgress()));
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Do nothing.
}
});*/
// Set up the Guidelines Spinner.
/*guidelinesSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
cropImageView.setGuidelines(i);
}
public void onNothingSelected(AdapterView<?> adapterView) {
// Do nothing.
}
});
guidelinesSpinner.setSelection(GUIDELINES_ON_TOUCH);*/
// Initialize the Crop button.
cropButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Bitmap croppedImage = cropImageView.getCroppedImage();
croppedImageView.setImageBitmap(croppedImage);
}
});
}
}
/*
* Copyright 2013, Edmodo, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with the License.
* You may obtain a copy of the License in the LICENSE file, or 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.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil;
/**
* Enum representing an edge in the crop window.
*/
public enum Edge {
LEFT,
TOP,
RIGHT,
BOTTOM;
// Private Constants ///////////////////////////////////////////////////////////////////////////
// Minimum distance in pixels that one edge can get to its opposing edge.
// This is an arbitrary value that simply prevents the crop window from becoming too small.
public static final int MIN_CROP_LENGTH_PX = 40;
// Member Variables ////////////////////////////////////////////////////////////////////////////
// The coordinate value of this edge.
// This will be the x-coordinate for LEFT and RIGHT edges and the y-coordinate for TOP and BOTTOM edges.
private float mCoordinate;
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Sets the coordinate of the Edge. The coordinate will represent the x-coordinate for LEFT and
* RIGHT Edges and the y-coordinate for TOP and BOTTOM edges.
*
* @param coordinate the position of the edge
*/
public void setCoordinate(float coordinate) {
mCoordinate = coordinate;
}
/**
* Add the given number of pixels to the current coordinate position of this Edge.
*
* @param distance the number of pixels to add
*/
public void offset(float distance) {
mCoordinate += distance;
}
/**
* Gets the coordinate of the Edge
*
* @return the Edge coordinate (x-coordinate for LEFT and RIGHT Edges and the y-coordinate for
* TOP and BOTTOM edges)
*/
public float getCoordinate() {
return mCoordinate;
}
/**
* Sets the Edge to the given x-y coordinate but also adjusting for snapping to the image bounds
* and parent view border constraints.
*
* @param x the x-coordinate
* @param y the y-coordinate
* @param imageRect the bounding rectangle of the image
* @param imageSnapRadius the radius (in pixels) at which the edge should snap to the image
*/
public void adjustCoordinate(float x, float y, @NonNull RectF imageRect, float imageSnapRadius, float aspectRatio) {
switch (this) {
case LEFT:
mCoordinate = adjustLeft(x, imageRect, imageSnapRadius, aspectRatio);
break;
case TOP:
mCoordinate = adjustTop(y, imageRect, imageSnapRadius, aspectRatio);
break;
case RIGHT:
mCoordinate = adjustRight(x, imageRect, imageSnapRadius, aspectRatio);
break;
case BOTTOM:
mCoordinate = adjustBottom(y, imageRect, imageSnapRadius, aspectRatio);
break;
}
}
/**
* Adjusts this Edge position such that the resulting window will have the given aspect ratio.
*
* @param aspectRatio the aspect ratio to achieve
*/
public void adjustCoordinate(float aspectRatio) {
final float left = Edge.LEFT.getCoordinate();
final float top = Edge.TOP.getCoordinate();
final float right = Edge.RIGHT.getCoordinate();
final float bottom = Edge.BOTTOM.getCoordinate();
switch (this) {
case LEFT:
mCoordinate = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
break;
case TOP:
mCoordinate = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
break;
case RIGHT:
mCoordinate = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
break;
case BOTTOM:
mCoordinate = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
break;
}
}
/**
* Returns whether or not you can re-scale the image based on whether any edge would be out of
* bounds. Checks all the edges for a possibility of jumping out of bounds.
*
* @param edge the Edge that is about to be expanded
* @param imageRect the rectangle of the picture
* @param aspectRatio the desired aspectRatio of the picture
*
* @return whether or not the new image would be out of bounds.
*/
public boolean isNewRectangleOutOfBounds(@NonNull Edge edge, @NonNull RectF imageRect, float aspectRatio) {
final float offset = edge.snapOffset(imageRect);
switch (this) {
case LEFT:
if (edge.equals(Edge.TOP)) {
final float top = imageRect.top;
final float bottom = Edge.BOTTOM.getCoordinate() - offset;
final float right = Edge.RIGHT.getCoordinate();
final float left = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
} else if (edge.equals(Edge.BOTTOM)) {
final float bottom = imageRect.bottom;
final float top = Edge.TOP.getCoordinate() - offset;
final float right = Edge.RIGHT.getCoordinate();
final float left = AspectRatioUtil.calculateLeft(top, right, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
}
break;
case TOP:
if (edge.equals(Edge.LEFT)) {
final float left = imageRect.left;
final float right = Edge.RIGHT.getCoordinate() - offset;
final float bottom = Edge.BOTTOM.getCoordinate();
final float top = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
} else if (edge.equals(Edge.RIGHT)) {
final float right = imageRect.right;
final float left = Edge.LEFT.getCoordinate() - offset;
final float bottom = Edge.BOTTOM.getCoordinate();
final float top = AspectRatioUtil.calculateTop(left, right, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
}
break;
case RIGHT:
if (edge.equals(Edge.TOP)) {
final float top = imageRect.top;
final float bottom = Edge.BOTTOM.getCoordinate() - offset;
final float left = Edge.LEFT.getCoordinate();
final float right = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
} else if (edge.equals(Edge.BOTTOM)) {
final float bottom = imageRect.bottom;
final float top = Edge.TOP.getCoordinate() - offset;
final float left = Edge.LEFT.getCoordinate();
final float right = AspectRatioUtil.calculateRight(left, top, bottom, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
}
break;
case BOTTOM:
if (edge.equals(Edge.LEFT)) {
final float left = imageRect.left;
final float right = Edge.RIGHT.getCoordinate() - offset;
final float top = Edge.TOP.getCoordinate();
final float bottom = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
} else if (edge.equals(Edge.RIGHT)) {
final float right = imageRect.right;
final float left = Edge.LEFT.getCoordinate() - offset;
final float top = Edge.TOP.getCoordinate();
final float bottom = AspectRatioUtil.calculateBottom(left, top, right, aspectRatio);
return isOutOfBounds(top, left, bottom, right, imageRect);
}
break;
}
return true;
}
/**
* Returns whether the new rectangle would be out of bounds.
*
* @param imageRect the Image to be compared with
*
* @return whether it would be out of bounds
*/
private boolean isOutOfBounds(float top, float left, float bottom, float right, @NonNull RectF imageRect) {
return (top < imageRect.top || left < imageRect.left || bottom > imageRect.bottom || right > imageRect.right);
}
/**
* Snap this Edge to the given image boundaries.
*
* @param imageRect the bounding rectangle of the image to snap to
*
* @return the amount (in pixels) that this coordinate was changed (i.e. the new coordinate
* minus the old coordinate value)
*/
public float snapToRect(@NonNull RectF imageRect) {
final float oldCoordinate = mCoordinate;
switch (this) {
case LEFT:
mCoordinate = imageRect.left;
break;
case TOP:
mCoordinate = imageRect.top;
break;
case RIGHT:
mCoordinate = imageRect.right;
break;
case BOTTOM:
mCoordinate = imageRect.bottom;
break;
}
return mCoordinate - oldCoordinate;
}
/**
* Returns the potential snap offset of snapToRect, without changing the coordinate.
*
* @param imageRect the bounding rectangle of the image to snap to
*
* @return the amount (in pixels) that this coordinate was changed (i.e. the new coordinate
* minus the old coordinate value)
*/
public float snapOffset(@NonNull RectF imageRect) {
final float oldCoordinate = mCoordinate;
final float newCoordinate;
switch (this) {
case LEFT:
newCoordinate = imageRect.left;
break;
case TOP:
newCoordinate = imageRect.top;
break;
case RIGHT:
newCoordinate = imageRect.right;
break;
default: // BOTTOM
newCoordinate = imageRect.bottom;
break;
}
return newCoordinate - oldCoordinate;
}
/**
* Gets the current width of the crop window.
*/
public static float getWidth() {
return Edge.RIGHT.getCoordinate() - Edge.LEFT.getCoordinate();
}
/**
* Gets the current height of the crop window.
*/
public static float getHeight() {
return Edge.BOTTOM.getCoordinate() - Edge.TOP.getCoordinate();
}
/**
* Determines if this Edge is outside the inner margins of the given bounding rectangle. The
* margins come inside the actual frame by SNAPRADIUS amount; therefore, determines if the point
* is outside the inner "margin" frame.
*/
public boolean isOutsideMargin(@NonNull RectF rect, float margin) {
final boolean result;
switch (this) {
case LEFT:
result = mCoordinate - rect.left < margin;
break;
case TOP:
result = mCoordinate - rect.top < margin;
break;
case RIGHT:
result = rect.right - mCoordinate < margin;
break;
default: // BOTTOM
result = rect.bottom - mCoordinate < margin;
break;
}
return result;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Get the resulting x-position of the left edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param x the x-position that the left edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual x-position of the left edge
*/
private static float adjustLeft(float x, @NonNull RectF imageRect, float imageSnapRadius, float aspectRatio) {
final float resultX;
if (x - imageRect.left < imageSnapRadius) {
resultX = imageRect.left;
} else {
// Select the minimum of the three possible values to use
float resultXHoriz = Float.POSITIVE_INFINITY;
float resultXVert = Float.POSITIVE_INFINITY;
// Checks if the window is too small horizontally
if (x >= Edge.RIGHT.getCoordinate() - MIN_CROP_LENGTH_PX) {
resultXHoriz = Edge.RIGHT.getCoordinate() - MIN_CROP_LENGTH_PX;
}
// Checks if the window is too small vertically
if (((Edge.RIGHT.getCoordinate() - x) / aspectRatio) <= MIN_CROP_LENGTH_PX) {
resultXVert = Edge.RIGHT.getCoordinate() - (MIN_CROP_LENGTH_PX * aspectRatio);
}
resultX = Math.min(x, Math.min(resultXHoriz, resultXVert));
}
return resultX;
}
/**
* Get the resulting x-position of the right edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param x the x-position that the right edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual x-position of the right edge
*/
private static float adjustRight(float x, @NonNull RectF imageRect, float imageSnapRadius, float aspectRatio) {
final float resultX;
// If close to the edge...
if (imageRect.right - x < imageSnapRadius) {
resultX = imageRect.right;
} else {
// Select the maximum of the three possible values to use
float resultXHoriz = Float.NEGATIVE_INFINITY;
float resultXVert = Float.NEGATIVE_INFINITY;
// Checks if the window is too small horizontally
if (x <= Edge.LEFT.getCoordinate() + MIN_CROP_LENGTH_PX) {
resultXHoriz = Edge.LEFT.getCoordinate() + MIN_CROP_LENGTH_PX;
}
// Checks if the window is too small vertically
if (((x - Edge.LEFT.getCoordinate()) / aspectRatio) <= MIN_CROP_LENGTH_PX) {
resultXVert = Edge.LEFT.getCoordinate() + (MIN_CROP_LENGTH_PX * aspectRatio);
}
resultX = Math.max(x, Math.max(resultXHoriz, resultXVert));
}
return resultX;
}
/**
* Get the resulting y-position of the top edge of the crop window given the handle's position
* and the image's bounding box and snap radius.
*
* @param y the x-position that the top edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual y-position of the top edge
*/
private static float adjustTop(float y, @NonNull RectF imageRect, float imageSnapRadius, float aspectRatio) {
final float resultY;
if (y - imageRect.top < imageSnapRadius) {
resultY = imageRect.top;
} else {
// Select the minimum of the three possible values to use
float resultYVert = Float.POSITIVE_INFINITY;
float resultYHoriz = Float.POSITIVE_INFINITY;
// Checks if the window is too small vertically
if (y >= Edge.BOTTOM.getCoordinate() - MIN_CROP_LENGTH_PX)
resultYHoriz = Edge.BOTTOM.getCoordinate() - MIN_CROP_LENGTH_PX;
// Checks if the window is too small horizontally
if (((Edge.BOTTOM.getCoordinate() - y) * aspectRatio) <= MIN_CROP_LENGTH_PX)
resultYVert = Edge.BOTTOM.getCoordinate() - (MIN_CROP_LENGTH_PX / aspectRatio);
resultY = Math.min(y, Math.min(resultYHoriz, resultYVert));
}
return resultY;
}
/**
* Get the resulting y-position of the bottom edge of the crop window given the handle's
* position and the image's bounding box and snap radius.
*
* @param y the x-position that the bottom edge is dragged to
* @param imageRect the bounding box of the image that is being cropped
* @param imageSnapRadius the snap distance to the image edge (in pixels)
*
* @return the actual y-position of the bottom edge
*/
private static float adjustBottom(float y, @NonNull RectF imageRect, float imageSnapRadius, float aspectRatio) {
final float resultY;
if (imageRect.bottom - y < imageSnapRadius) {
resultY = imageRect.bottom;
} else {
// Select the maximum of the three possible values to use
float resultYVert = Float.NEGATIVE_INFINITY;
float resultYHoriz = Float.NEGATIVE_INFINITY;
// Checks if the window is too small vertically
if (y <= Edge.TOP.getCoordinate() + MIN_CROP_LENGTH_PX) {
resultYVert = Edge.TOP.getCoordinate() + MIN_CROP_LENGTH_PX;
}
// Checks if the window is too small horizontally
if (((y - Edge.TOP.getCoordinate()) * aspectRatio) <= MIN_CROP_LENGTH_PX) {
resultYHoriz = Edge.TOP.getCoordinate() + (MIN_CROP_LENGTH_PX / aspectRatio);
}
resultY = Math.max(y, Math.max(resultYHoriz, resultYVert));
}
return resultY;
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge;
/**
* Simple class to hold a pair of Edges.
*/
public class EdgePair {
// Member Variables ////////////////////////////////////////////////////////
public Edge primary;
public Edge secondary;
// Constructor /////////////////////////////////////////////////////////////
public EdgePair(Edge edge1, Edge edge2) {
primary = edge1;
secondary = edge2;
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
/**
* HandleHelper class to handle the center handle.
*/
class CenterHandleHelper extends HandleHelper {
// Constructor /////////////////////////////////////////////////////////////////////////////////
CenterHandleHelper() {
super(null, null);
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void updateCropWindow(float x,
float y,
@NonNull RectF imageRect,
float snapRadius) {
float left = Edge.LEFT.getCoordinate();
float top = Edge.TOP.getCoordinate();
float right = Edge.RIGHT.getCoordinate();
float bottom = Edge.BOTTOM.getCoordinate();
final float currentCenterX = (left + right) / 2;
final float currentCenterY = (top + bottom) / 2;
final float offsetX = x - currentCenterX;
final float offsetY = y - currentCenterY;
// Adjust the crop window.
Edge.LEFT.offset(offsetX);
Edge.TOP.offset(offsetY);
Edge.RIGHT.offset(offsetX);
Edge.BOTTOM.offset(offsetY);
// Check if we have gone out of bounds on the sides, and fix.
if (Edge.LEFT.isOutsideMargin(imageRect, snapRadius)) {
final float offset = Edge.LEFT.snapToRect(imageRect);
Edge.RIGHT.offset(offset);
} else if (Edge.RIGHT.isOutsideMargin(imageRect, snapRadius)) {
final float offset = Edge.RIGHT.snapToRect(imageRect);
Edge.LEFT.offset(offset);
}
// Check if we have gone out of bounds on the top or bottom, and fix.
if (Edge.TOP.isOutsideMargin(imageRect, snapRadius)) {
final float offset = Edge.TOP.snapToRect(imageRect);
Edge.BOTTOM.offset(offset);
} else if (Edge.BOTTOM.isOutsideMargin(imageRect, snapRadius)) {
final float offset = Edge.BOTTOM.snapToRect(imageRect);
Edge.TOP.offset(offset);
}
}
@Override
void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius) {
updateCropWindow(x, y, imageRect, snapRadius);
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.EdgePair;
/**
* HandleHelper class to handle corner Handles (i.e. top-left, top-right, bottom-left, and
* bottom-right handles).
*/
class CornerHandleHelper extends HandleHelper {
// Constructor /////////////////////////////////////////////////////////////////////////////////
CornerHandleHelper(Edge horizontalEdge, Edge verticalEdge) {
super(horizontalEdge, verticalEdge);
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius) {
final EdgePair activeEdges = getActiveEdges(x, y, targetAspectRatio);
final Edge primaryEdge = activeEdges.primary;
final Edge secondaryEdge = activeEdges.secondary;
primaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
secondaryEdge.adjustCoordinate(targetAspectRatio);
if (secondaryEdge.isOutsideMargin(imageRect, snapRadius)) {
secondaryEdge.snapToRect(imageRect);
primaryEdge.adjustCoordinate(targetAspectRatio);
}
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
/**
* Enum representing a pressable, draggable Handle on the crop window.
*/
public enum Handle {
TOP_LEFT(new CornerHandleHelper(Edge.TOP, Edge.LEFT)),
TOP_RIGHT(new CornerHandleHelper(Edge.TOP, Edge.RIGHT)),
BOTTOM_LEFT(new CornerHandleHelper(Edge.BOTTOM, Edge.LEFT)),
BOTTOM_RIGHT(new CornerHandleHelper(Edge.BOTTOM, Edge.RIGHT)),
LEFT(new VerticalHandleHelper(Edge.LEFT)),
TOP(new HorizontalHandleHelper(Edge.TOP)),
RIGHT(new VerticalHandleHelper(Edge.RIGHT)),
BOTTOM(new HorizontalHandleHelper(Edge.BOTTOM)),
CENTER(new CenterHandleHelper());
// Member Variables ////////////////////////////////////////////////////////////////////////////
private HandleHelper mHelper;
// Constructors ////////////////////////////////////////////////////////////////////////////////
Handle(HandleHelper helper) {
mHelper = helper;
}
// Public Methods //////////////////////////////////////////////////////////
public void updateCropWindow(float x,
float y,
@NonNull RectF imageRect,
float snapRadius) {
mHelper.updateCropWindow(x, y, imageRect, snapRadius);
}
public void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius) {
mHelper.updateCropWindow(x, y, targetAspectRatio, imageRect, snapRadius);
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.EdgePair;
import com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil;
/**
* Abstract helper class to handle operations on a crop window Handle.
*/
abstract class HandleHelper {
// Member Variables ////////////////////////////////////////////////////////
private static final float UNFIXED_ASPECT_RATIO_CONSTANT = 1;
private Edge mHorizontalEdge;
private Edge mVerticalEdge;
// Save the Pair object as a member variable to avoid having to instantiate
// a new Object every time getActiveEdges() is called.
private EdgePair mActiveEdges;
// Constructor /////////////////////////////////////////////////////////////////////////////////
/**
* Constructor.
*
* @param horizontalEdge the horizontal edge associated with this handle; may be null
* @param verticalEdge the vertical edge associated with this handle; may be null
*/
HandleHelper(Edge horizontalEdge, Edge verticalEdge) {
mHorizontalEdge = horizontalEdge;
mVerticalEdge = verticalEdge;
mActiveEdges = new EdgePair(mHorizontalEdge, mVerticalEdge);
}
// Package-Private Methods /////////////////////////////////////////////////////////////////////
/**
* Updates the crop window by directly setting the Edge coordinates.
*
* @param x the new x-coordinate of this handle
* @param y the new y-coordinate of this handle
* @param imageRect the bounding rectangle of the image
* @param snapRadius the maximum distance (in pixels) at which the crop window should snap to
* the image
*/
void updateCropWindow(float x,
float y,
@NonNull RectF imageRect,
float snapRadius) {
final EdgePair activeEdges = getActiveEdges();
final Edge primaryEdge = activeEdges.primary;
final Edge secondaryEdge = activeEdges.secondary;
if (primaryEdge != null)
primaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT);
if (secondaryEdge != null)
secondaryEdge.adjustCoordinate(x, y, imageRect, snapRadius, UNFIXED_ASPECT_RATIO_CONSTANT);
}
/**
* Updates the crop window by directly setting the Edge coordinates; this method maintains a
* given aspect ratio.
*
* @param x the new x-coordinate of this handle
* @param y the new y-coordinate of this handle
* @param targetAspectRatio the aspect ratio to maintain
* @param imageRect the bounding rectangle of the image
* @param snapRadius the maximum distance (in pixels) at which the crop window should
* snap to the image
*/
abstract void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius);
/**
* Gets the Edges associated with this handle (i.e. the Edges that should be moved when this
* handle is dragged). This is used when we are not maintaining the aspect ratio.
*
* @return the active edge as a pair (the pair may contain null values for the
* <code>primary</code>, <code>secondary</code> or both fields)
*/
EdgePair getActiveEdges() {
return mActiveEdges;
}
/**
* Gets the Edges associated with this handle as an ordered Pair. The <code>primary</code> Edge
* in the pair is the determining side. This method is used when we need to maintain the aspect
* ratio.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param targetAspectRatio the aspect ratio that we are maintaining
*
* @return the active edges as an ordered pair
*/
EdgePair getActiveEdges(float x, float y, float targetAspectRatio) {
// Calculate the aspect ratio if this handle were dragged to the given x-y coordinate.
final float potentialAspectRatio = getAspectRatio(x, y);
// If the touched point is wider than the aspect ratio, then x is the determining side. Else, y is the determining side.
if (potentialAspectRatio > targetAspectRatio) {
mActiveEdges.primary = mVerticalEdge;
mActiveEdges.secondary = mHorizontalEdge;
} else {
mActiveEdges.primary = mHorizontalEdge;
mActiveEdges.secondary = mVerticalEdge;
}
return mActiveEdges;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Gets the aspect ratio of the resulting crop window if this handle were dragged to the given
* point.
*
* @param x the x-coordinate
* @param y the y-coordinate
*
* @return the aspect ratio
*/
private float getAspectRatio(float x, float y) {
// Replace the active edge coordinate with the given touch coordinate.
final float left = (mVerticalEdge == Edge.LEFT) ? x : Edge.LEFT.getCoordinate();
final float top = (mHorizontalEdge == Edge.TOP) ? y : Edge.TOP.getCoordinate();
final float right = (mVerticalEdge == Edge.RIGHT) ? x : Edge.RIGHT.getCoordinate();
final float bottom = (mHorizontalEdge == Edge.BOTTOM) ? y : Edge.BOTTOM.getCoordinate();
return AspectRatioUtil.calculateAspectRatio(left, top, right, bottom);
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
import com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil;
/**
* Handle helper class to handle horizontal handles (i.e. top and bottom handles).
*/
class HorizontalHandleHelper extends HandleHelper {
// Member Variables ////////////////////////////////////////////////////////////////////////////
private Edge mEdge;
// Constructor /////////////////////////////////////////////////////////////////////////////////
HorizontalHandleHelper(Edge edge) {
super(edge, null);
mEdge = edge;
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius) {
// Adjust this Edge accordingly.
mEdge.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
float left = Edge.LEFT.getCoordinate();
float right = Edge.RIGHT.getCoordinate();
// After this Edge is moved, our crop window is now out of proportion.
final float targetWidth = AspectRatioUtil.calculateWidth(Edge.getHeight(), targetAspectRatio);
// Adjust the crop window so that it maintains the given aspect ratio by
// moving the adjacent edges symmetrically in or out.
final float difference = targetWidth - Edge.getWidth();
final float halfDifference = difference / 2;
left -= halfDifference;
right += halfDifference;
Edge.LEFT.setCoordinate(left);
Edge.RIGHT.setCoordinate(right);
// Check if we have gone out of bounds on the sides, and fix.
if (Edge.LEFT.isOutsideMargin(imageRect, snapRadius)
&& !mEdge.isNewRectangleOutOfBounds(Edge.LEFT, imageRect, targetAspectRatio)) {
final float offset = Edge.LEFT.snapToRect(imageRect);
Edge.RIGHT.offset(-offset);
mEdge.adjustCoordinate(targetAspectRatio);
}
if (Edge.RIGHT.isOutsideMargin(imageRect, snapRadius)
&& !mEdge.isNewRectangleOutOfBounds(Edge.RIGHT, imageRect, targetAspectRatio)) {
final float offset = Edge.RIGHT.snapToRect(imageRect);
Edge.LEFT.offset(-offset);
mEdge.adjustCoordinate(targetAspectRatio);
}
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle;
import android.graphics.RectF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.edge.Edge;
import com.yottacode.pictogram.tabletlibrary.cropper.util.AspectRatioUtil;
/**
* HandleHelper class to handle vertical handles (i.e. left and right handles).
*/
class VerticalHandleHelper extends HandleHelper {
// Member Variables ////////////////////////////////////////////////////////////////////////////
private Edge mEdge;
// Constructor /////////////////////////////////////////////////////////////////////////////////
VerticalHandleHelper(Edge edge) {
super(null, edge);
mEdge = edge;
}
// HandleHelper Methods ////////////////////////////////////////////////////////////////////////
@Override
void updateCropWindow(float x,
float y,
float targetAspectRatio,
@NonNull RectF imageRect,
float snapRadius) {
// Adjust this Edge accordingly.
mEdge.adjustCoordinate(x, y, imageRect, snapRadius, targetAspectRatio);
float top = Edge.TOP.getCoordinate();
float bottom = Edge.BOTTOM.getCoordinate();
// After this Edge is moved, our crop window is now out of proportion.
final float targetHeight = AspectRatioUtil.calculateHeight(Edge.getWidth(), targetAspectRatio);
// Adjust the crop window so that it maintains the given aspect ratio by
// moving the adjacent edges symmetrically in or out.
final float difference = targetHeight - Edge.getHeight();
final float halfDifference = difference / 2;
top -= halfDifference;
bottom += halfDifference;
Edge.TOP.setCoordinate(top);
Edge.BOTTOM.setCoordinate(bottom);
// Check if we have gone out of bounds on the top or bottom, and fix.
if (Edge.TOP.isOutsideMargin(imageRect, snapRadius)
&& !mEdge.isNewRectangleOutOfBounds(Edge.TOP, imageRect, targetAspectRatio)) {
final float offset = Edge.TOP.snapToRect(imageRect);
Edge.BOTTOM.offset(-offset);
mEdge.adjustCoordinate(targetAspectRatio);
}
if (Edge.BOTTOM.isOutsideMargin(imageRect, snapRadius)
&& !mEdge.isNewRectangleOutOfBounds(Edge.BOTTOM, imageRect, targetAspectRatio)) {
final float offset = Edge.BOTTOM.snapToRect(imageRect);
Edge.TOP.offset(-offset);
mEdge.adjustCoordinate(targetAspectRatio);
}
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.util;
import android.graphics.RectF;
import android.support.annotation.NonNull;
/**
* Utility class for handling calculations involving a fixed aspect ratio.
*/
public class AspectRatioUtil {
/**
* Calculates the aspect ratio given a rectangle.
*/
public static float calculateAspectRatio(float left, float top, float right, float bottom) {
final float width = right - left;
final float height = bottom - top;
return width / height;
}
/**
* Calculates the aspect ratio given a rectangle.
*/
public static float calculateAspectRatio(@NonNull RectF rect) {
return rect.width() / rect.height();
}
/**
* Calculates the x-coordinate of the left edge given the other sides of the rectangle and an
* aspect ratio.
*/
public static float calculateLeft(float top, float right, float bottom, float targetAspectRatio) {
final float height = bottom - top;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// right - left = targetAspectRatio * height
return right - (targetAspectRatio * height);
}
/**
* Calculates the y-coordinate of the top edge given the other sides of the rectangle and an
* aspect ratio.
*/
public static float calculateTop(float left, float right, float bottom, float targetAspectRatio) {
final float width = right - left;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// height = width / targetAspectRatio
// bottom - top = width / targetAspectRatio
return bottom - (width / targetAspectRatio);
}
/**
* Calculates the x-coordinate of the right edge given the other sides of the rectangle and an
* aspect ratio.
*/
public static float calculateRight(float left, float top, float bottom, float targetAspectRatio) {
final float height = bottom - top;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// right - left = targetAspectRatio * height
return (targetAspectRatio * height) + left;
}
/**
* Calculates the y-coordinate of the bottom edge given the other sides of the rectangle and an
* aspect ratio.
*/
public static float calculateBottom(float left, float top, float right, float targetAspectRatio) {
final float width = right - left;
// targetAspectRatio = width / height
// width = targetAspectRatio * height
// height = width / targetAspectRatio
// bottom - top = width / targetAspectRatio
return (width / targetAspectRatio) + top;
}
/**
* Calculates the width of a rectangle given the top and bottom edges and an aspect ratio.
*/
public static float calculateWidth(float height, float targetAspectRatio) {
return targetAspectRatio * height;
}
/**
* Calculates the height of a rectangle given the left and right edges and an aspect ratio.
*/
public static float calculateHeight(float width, float targetAspectRatio) {
return width / targetAspectRatio;
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.util;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.cropper.cropwindow.handle.Handle;
/**
* Utility class to perform basic operations with Handles.
*/
public class HandleUtil {
// Public Methods //////////////////////////////////////////////////////////////////////////////
/**
* Determines which, if any, of the handles are pressed given the touch coordinates, the
* bounding box, and the touch radius.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param left the x-coordinate of the left bound
* @param top the y-coordinate of the top bound
* @param right the x-coordinate of the right bound
* @param bottom the y-coordinate of the bottom bound
* @param targetRadius the target radius in pixels
*
* @return the Handle that was pressed; null if no Handle was pressed
*/
public static Handle getPressedHandle(float x,
float y,
float left,
float top,
float right,
float bottom,
float targetRadius) {
// Find the closest corner handle to the touch point.
// If the touch point is in the target zone of this closest handle, then this is the pressed handle.
// Else, check if any of the edges are in the target zone of the touch point.
// Else, check if the touch point is within the crop window bounds; if so, then choose the center handle.
Handle closestHandle = null;
float closestDistance = Float.POSITIVE_INFINITY;
final float distanceToTopLeft = MathUtil.calculateDistance(x, y, left, top);
if (distanceToTopLeft < closestDistance) {
closestDistance = distanceToTopLeft;
closestHandle = Handle.TOP_LEFT;
}
final float distanceToTopRight = MathUtil.calculateDistance(x, y, right, top);
if (distanceToTopRight < closestDistance) {
closestDistance = distanceToTopRight;
closestHandle = Handle.TOP_RIGHT;
}
final float distanceToBottomLeft = MathUtil.calculateDistance(x, y, left, bottom);
if (distanceToBottomLeft < closestDistance) {
closestDistance = distanceToBottomLeft;
closestHandle = Handle.BOTTOM_LEFT;
}
final float distanceToBottomRight = MathUtil.calculateDistance(x, y, right, bottom);
if (distanceToBottomRight < closestDistance) {
closestDistance = distanceToBottomRight;
closestHandle = Handle.BOTTOM_RIGHT;
}
if (closestDistance <= targetRadius) {
return closestHandle;
}
// If we get to this point, none of the corner handles were in the touch target zone, so then we check the edges.
if (HandleUtil.isInHorizontalTargetZone(x, y, left, right, top, targetRadius)) {
return Handle.TOP;
} else if (HandleUtil.isInHorizontalTargetZone(x, y, left, right, bottom, targetRadius)) {
return Handle.BOTTOM;
} else if (HandleUtil.isInVerticalTargetZone(x, y, left, top, bottom, targetRadius)) {
return Handle.LEFT;
} else if (HandleUtil.isInVerticalTargetZone(x, y, right, top, bottom, targetRadius)) {
return Handle.RIGHT;
}
// If we get to this point, none of the corners or edges are in the touch target zone.
// Check to see if the touch point is within the bounds of the crop window. If so, choose the center handle.
if (isWithinBounds(x, y, left, top, right, bottom)) {
return Handle.CENTER;
}
return null;
}
/**
* Calculates the offset of the touch point from the precise location of the specified handle.
* <p/>
* The offset will be returned in the 'touchOffsetOutput' parameter; the x-offset will be the
* first value and the y-offset will be the second value.
*/
public static void getOffset(@NonNull Handle handle,
float x,
float y,
float left,
float top,
float right,
float bottom,
@NonNull PointF touchOffsetOutput) {
float touchOffsetX = 0;
float touchOffsetY = 0;
// Calculate the offset from the appropriate handle.
switch (handle) {
case TOP_LEFT:
touchOffsetX = left - x;
touchOffsetY = top - y;
break;
case TOP_RIGHT:
touchOffsetX = right - x;
touchOffsetY = top - y;
break;
case BOTTOM_LEFT:
touchOffsetX = left - x;
touchOffsetY = bottom - y;
break;
case BOTTOM_RIGHT:
touchOffsetX = right - x;
touchOffsetY = bottom - y;
break;
case LEFT:
touchOffsetX = left - x;
touchOffsetY = 0;
break;
case TOP:
touchOffsetX = 0;
touchOffsetY = top - y;
break;
case RIGHT:
touchOffsetX = right - x;
touchOffsetY = 0;
break;
case BOTTOM:
touchOffsetX = 0;
touchOffsetY = bottom - y;
break;
case CENTER:
final float centerX = (right + left) / 2;
final float centerY = (top + bottom) / 2;
touchOffsetX = centerX - x;
touchOffsetY = centerY - y;
break;
}
touchOffsetOutput.x = touchOffsetX;
touchOffsetOutput.y = touchOffsetY;
}
// Private Methods /////////////////////////////////////////////////////////////////////////////
/**
* Determines if the specified coordinate is in the target touch zone for a horizontal bar
* handle.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param handleXStart the left x-coordinate of the horizontal bar handle
* @param handleXEnd the right x-coordinate of the horizontal bar handle
* @param handleY the y-coordinate of the horizontal bar handle
* @param targetRadius the target radius in pixels
*
* @return true if the touch point is in the target touch zone; false otherwise
*/
private static boolean isInHorizontalTargetZone(float x,
float y,
float handleXStart,
float handleXEnd,
float handleY,
float targetRadius) {
return (x > handleXStart && x < handleXEnd && Math.abs(y - handleY) <= targetRadius);
}
/**
* Determines if the specified coordinate is in the target touch zone for a vertical bar
* handle.
*
* @param x the x-coordinate of the touch point
* @param y the y-coordinate of the touch point
* @param handleX the x-coordinate of the vertical bar handle
* @param handleYStart the top y-coordinate of the vertical bar handle
* @param handleYEnd the bottom y-coordinate of the vertical bar handle
* @param targetRadius the target radius in pixels
*
* @return true if the touch point is in the target touch zone; false otherwise
*/
private static boolean isInVerticalTargetZone(float x,
float y,
float handleX,
float handleYStart,
float handleYEnd,
float targetRadius) {
return (Math.abs(x - handleX) <= targetRadius && y > handleYStart && y < handleYEnd);
}
private static boolean isWithinBounds(float x, float y, float left, float top, float right, float bottom) {
return x >= left && x <= right && y >= top && y <= bottom;
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.util;
public class MathUtil {
/**
* Calculates the distance between two points (x1, y1) and (x2, y2).
*/
public static float calculateDistance(float x1, float y1, float x2, float y2) {
final float side1 = x2 - x1;
final float side2 = y2 - y1;
return (float) Math.sqrt(side1 * side1 + side2 * side2);
}
}
package com.yottacode.pictogram.tabletlibrary.cropper.util;
import android.content.res.Resources;
import android.graphics.Paint;
import android.support.annotation.NonNull;
import com.yottacode.pictogram.tabletlibrary.R;
/**
* Utility class for handling all of the Paint used to draw the CropOverlayView.
*/
public class PaintUtil {
// Public Methods //////////////////////////////////////////////////////////
/**
* Creates the Paint object for drawing the crop window border.
*/
public static Paint newBorderPaint(@NonNull Resources resources) {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.border_thickness));
paint.setColor(resources.getColor(R.color.border));
return paint;
}
/**
* Creates the Paint object for drawing the crop window guidelines.
*/
public static Paint newGuidelinePaint(@NonNull Resources resources) {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.guideline_thickness));
paint.setColor(resources.getColor(R.color.guideline));
return paint;
}
/**
* Creates the Paint object for drawing the translucent overlay outside the crop window.
*
* @return the new Paint object
*/
public static Paint newSurroundingAreaOverlayPaint(@NonNull Resources resources) {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(resources.getColor(R.color.surrounding_area));
return paint;
}
/**
* Creates the Paint object for drawing the corners of the border
*/
public static Paint newCornerPaint(@NonNull Resources resources) {
final Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(resources.getDimension(R.dimen.corner_thickness));
paint.setColor(resources.getColor(R.color.corner));
return paint;
}
}
...@@ -6,12 +6,14 @@ import android.content.Context; ...@@ -6,12 +6,14 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.text.InputType; import android.text.InputType;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
...@@ -24,6 +26,7 @@ import com.yottacode.pictogram.grammar.Vocabulary; ...@@ -24,6 +26,7 @@ import com.yottacode.pictogram.grammar.Vocabulary;
import com.yottacode.pictogram.grammar.iLocalPicto; import com.yottacode.pictogram.grammar.iLocalPicto;
import com.yottacode.pictogram.net.PictoUploader; import com.yottacode.pictogram.net.PictoUploader;
import com.yottacode.pictogram.tabletlibrary.R; import com.yottacode.pictogram.tabletlibrary.R;
import com.yottacode.pictogram.tabletlibrary.cropper.CropImageView;
import com.yottacode.pictogram.tools.PCBcontext; import com.yottacode.pictogram.tools.PCBcontext;
import java.io.IOException; import java.io.IOException;
...@@ -417,8 +420,29 @@ public class PictoMenu { ...@@ -417,8 +420,29 @@ public class PictoMenu {
public List<RadialMenuWidget.RadialMenuEntry> getChildren() { return children; } public List<RadialMenuWidget.RadialMenuEntry> getChildren() { return children; }
public void menuActiviated() public void menuActiviated()
{ {
ll.getChildAt(1).setX(ll.getChildAt(1).getX() + 30); /*ll.getChildAt(1).setX(ll.getChildAt(1).getX() + 30);
children = new ArrayList<>(Arrays.asList(new EditTextPicto(p),new EditImage(p))); children = new ArrayList<>(Arrays.asList(new EditTextPicto(p),new EditImage(p)));*/
activity.setContentView(R.layout.crop_layout);
final CropImageView cropImageView = (CropImageView) activity.findViewById(R.id.CropImageView);
cropImageView.setImageResource(R.drawable.descarga);
final ImageView croppedImageView = (ImageView) activity.findViewById(R.id.croppedImageView);
final Button cropButton = (Button) activity.findViewById(R.id.Button_crop);
cropImageView.setGuidelines(CropImageView.GUIDELINES_ON); //To show the guidelines
cropImageView.setFixedAspectRatio(true);
cropImageView.setAspectRatio(1,1);
cropButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Bitmap croppedImage = cropImageView.getCroppedImage();
croppedImageView.setImageBitmap(croppedImage);
}
});
} }
public void menuDisabled(){ public void menuDisabled(){
ll.getChildAt(1).setX(ll.getChildAt(1).getX() - 30); ll.getChildAt(1).setX(ll.getChildAt(1).getX() - 30);
......
<?xml version="1.0" encoding="utf-8"?>
<!--<ScrollView
android:id="@+id/scrollview"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".cropper.MainCropImage"
android:background="@color/black_translucent">
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black_translucent"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:id="@+id/ScrollView">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/TotalLayout">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/titleCropper"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="@color/common_google_signin_btn_text_dark_pressed"
android:layout_weight="1"
android:textAlignment="center"
android:layout_gravity="top"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<com.yottacode.pictogram.tabletlibrary.cropper.CropImageView
android:id="@+id/CropImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:layout_below="@+id/title"
android:layout_alignParentStart="true" />
<Button
android:id="@+id/Button_crop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="120dp"
android:text="@string/crop"
android:textColor="#33B5E5"
android:textSize="20sp"
android:layout_gravity="center_vertical"
android:layout_marginTop="2dp"
android:layout_below="@+id/title"
android:layout_centerHorizontal="true" />
<ImageView
android:id="@+id/croppedImageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:adjustViewBounds="true"
android:contentDescription="@string/croppedImageDesc"
android:scaleType="centerInside"/>
</RelativeLayout>
</ScrollView>
<resources>
<declare-styleable name="CropImageView">
<attr name="guidelines">
<enum name="off" value="0"/>
<enum name="onTouch" value="1"/>
<enum name="on" value="2"/>
</attr>
<attr name="fixAspectRatio" format="boolean"/>
<attr name="aspectRatioX" format="integer"/>
<attr name="aspectRatioY" format="integer"/>
</declare-styleable>
</resources>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white_translucent">#AAFFFFFF</color>
<color name="black_translucent">#b0000000</color>
<color name="border">@color/white_translucent</color>
<color name="guideline">@color/white_translucent</color>
<color name="corner">@android:color/white</color>
<color name="surrounding_area">@color/black_translucent</color>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="border_thickness">3dp</dimen>
<dimen name="corner_thickness">5dp</dimen>
<dimen name="guideline_thickness">1px</dimen>
<dimen name="target_radius">24dp</dimen>
<dimen name="snap_radius">3dp</dimen>
<dimen name="corner_length">20dp</dimen>
<dimen name="content_padding">16dp</dimen>
<dimen name="content_padding_half">8dp</dimen>
</resources>
...@@ -37,4 +37,20 @@ ...@@ -37,4 +37,20 @@
<string name="session_eval_notevuated">no evaluado</string> <string name="session_eval_notevuated">no evaluado</string>
<string name="session_eval_discarded">inválido</string> <string name="session_eval_discarded">inválido</string>
<!-- Cropper -->
<string name="titleCropper">Cropper</string>
<string name="fixedAspectRatio">fixedAspectRatio =\u0020</string>
<string name="aspectRatioXHeader">aspectRatioX =\u0020</string>
<string name="aspectRatioYHeader">aspectRatioY =\u0020</string>
<string name="showGuidelines">showGuidelines =\u0020</string>
<string name="crop">Crop</string>
<string name="croppedImageDesc">The cropped image.</string>
<string-array name="showGuidelinesArray">
<item>Off</item>
<item>On Touch</item>
<item>On</item>
</string-array>
</resources> </resources>
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
<facet type="android" name="Android"> <facet type="android" name="Android">
<configuration> <configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" /> <option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks> <afterSyncTasks>
...@@ -25,7 +26,7 @@ ...@@ -25,7 +26,7 @@
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" /> <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
<option name="PROJECT_TYPE" value="1" /> <option name="LIBRARY_PROJECT" value="true" />
</configuration> </configuration>
</facet> </facet>
</component> </component>
...@@ -53,6 +54,7 @@ ...@@ -53,6 +54,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
...@@ -60,6 +62,7 @@ ...@@ -60,6 +62,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
...@@ -67,6 +70,7 @@ ...@@ -67,6 +70,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
...@@ -74,6 +78,7 @@ ...@@ -74,6 +78,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
...@@ -81,6 +86,7 @@ ...@@ -81,6 +86,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
...@@ -124,6 +130,7 @@ ...@@ -124,6 +130,7 @@
<orderEntry type="library" exported="" name="support-vector-drawable-24.2.1" level="project" /> <orderEntry type="library" exported="" name="support-vector-drawable-24.2.1" level="project" />
<orderEntry type="library" exported="" name="support-core-utils-24.2.1" level="project" /> <orderEntry type="library" exported="" name="support-core-utils-24.2.1" level="project" />
<orderEntry type="module" module-name="commonlibrary" exported="" /> <orderEntry type="module" module-name="commonlibrary" exported="" />
<orderEntry type="library" exported="" name="android-android-24" level="project" />
<orderEntry type="library" exported="" name="okhttp-ws-2.3.0" level="project" /> <orderEntry type="library" exported="" name="okhttp-ws-2.3.0" level="project" />
<orderEntry type="library" exported="" name="play-services-base-9.2.1" level="project" /> <orderEntry type="library" exported="" name="play-services-base-9.2.1" level="project" />
<orderEntry type="library" exported="" name="socket.io-client-0.5.0" level="project" /> <orderEntry type="library" exported="" name="socket.io-client-0.5.0" level="project" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment