/** * Method that load the gles texture and apply to the requestor frame (which includes fix the * aspect ratio and/or effects and borders) * * @param requestor The requestor target * @param ti The original texture information (the one with the bitmap one) */ private void applyToRequestor(TextureRequestor requestor, GLESTextureInfo ti) { // Transform requestor dimensions to screen dimensions RectF dimens = requestor.getRequestorDimensions(); Rect pixels = new Rect( 0, 0, (int) (mScreenDimensions.width() * dimens.width() / 2), (int) (mScreenDimensions.height() * dimens.height() / 2)); final Disposition disposition = requestor.getDisposition(); synchronized (mEffectsSync) { if (disposition.hasFlag(Disposition.EFFECT_FLAG)) { ti.effect = mEffects.getNextEffect(); } if (disposition.hasFlag(Disposition.BORDER_FLAG)) { ti.border = mBorders.getNextBorder(); } } // Check if we have to apply any correction to the image GLESTextureInfo dst; if (ti.bitmap != null && Preferences.General.isFixAspectRatio(mContext)) { // Create a texture of power of two here to avoid scaling the bitmap twice int w = pixels.width(); int h = pixels.height(); if (!BitmapUtils.isPowerOfTwo(w, h) && PreferencesProvider.Preferences.General.isPowerOfTwo(mContext)) { w = h = BitmapUtils.calculateUpperPowerOfTwo(Math.min(w, h)); } // Create a thumbnail of the image Bitmap thumb = BitmapUtils.createScaledBitmap(ti.bitmap, w, h, BitmapUtils.ScalingLogic.CROP); if (!thumb.equals(ti.bitmap)) { ti.bitmap.recycle(); } dst = GLESUtil.loadTexture(mContext, thumb, ti.effect, ti.border, pixels); } else { // Load the texture without any correction dst = GLESUtil.loadTexture(mContext, ti.bitmap, ti.effect, ti.border, pixels); } // Swap references ti.bitmap = dst.bitmap; ti.handle = dst.handle; ti.effect = null; ti.border = null; dst.handle = 0; dst.bitmap = null; // And notify to the requestor requestor.setTextureHandle(ti); // Clean up memory if (ti.bitmap != null) { ti.bitmap.recycle(); ti.bitmap = null; } }
/** * Method that converts the resize frame to a dispostion reference * * @return Disposition The disposition reference */ private Disposition resizerToDisposition() { int w = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight()); int h = getMeasuredHeight() - (getPaddingTop() + getPaddingBottom()); int cw = w / mCols; int ch = h / mRows; // Remove overlapped areas Disposition resizer = new Disposition(); resizer.x = Math.round(mResizeFrame.getX() / cw); resizer.y = Math.round(mResizeFrame.getY() / ch); resizer.w = Math.round(mResizeFrame.getWidth() / cw); resizer.h = Math.round(mResizeFrame.getHeight() / ch); // Fix disposition (limits) resizer.x = Math.max(resizer.x, 0); resizer.y = Math.max(resizer.y, 0); resizer.w = Math.min(resizer.w, mCols - resizer.x); resizer.h = Math.min(resizer.h, mRows - resizer.y); return resizer; }
/** * Method that returns all dispositions that matched exactly (in one side) with the argument * disposition. * * @param disposition The disposition to check */ private List<Disposition> findAdjacentsDispositions(Disposition disposition) { if (mDispositions.size() <= 1) return null; // Check left size if (disposition.x != 0) { List<Disposition> dispositions = new ArrayList<Disposition>(); for (Disposition d : mDispositions) { if (d.compareTo(disposition) != 0) { if ((d.x + d.w) == disposition.x && (d.y >= disposition.y) && ((d.y + d.h) <= (disposition.y + disposition.h))) { dispositions.add(d); } } } // Check if the sum of all the dispositions matches the disposition int sum = 0; for (Disposition d : dispositions) { sum += d.h; } if (sum == disposition.h) { return dispositions; } } // Check top size if (disposition.y != 0) { List<Disposition> dispositions = new ArrayList<Disposition>(); for (Disposition d : mDispositions) { if (d.compareTo(disposition) != 0) { if ((d.y + d.h) == disposition.y && (d.x >= disposition.x) && ((d.x + d.w) <= (disposition.x + disposition.w))) { dispositions.add(d); } } } // Check if the sum of all the dispositions matches the disposition int sum = 0; for (Disposition d : dispositions) { sum += d.w; } if (sum == disposition.w) { return dispositions; } } // Check right size if ((disposition.x + disposition.w) != mCols) { List<Disposition> dispositions = new ArrayList<Disposition>(); for (Disposition d : mDispositions) { if (d.compareTo(disposition) != 0) { if ((d.x) == (disposition.x + disposition.w) && (d.y >= disposition.y) && ((d.y + d.h) <= (disposition.y + disposition.h))) { dispositions.add(d); } } } // Check if the sum of all the dispositions matches the disposition int sum = 0; for (Disposition d : dispositions) { sum += d.h; } if (sum == disposition.h) { return dispositions; } } // Check bottom size if ((disposition.y + disposition.h) != mRows) { List<Disposition> dispositions = new ArrayList<Disposition>(); for (Disposition d : mDispositions) { if (d.compareTo(disposition) != 0) { if ((d.y) == (disposition.y + disposition.h) && (d.x >= disposition.x) && ((d.x + d.w) <= (disposition.x + disposition.w))) { dispositions.add(d); } } } // Check if the sum of all the dispositions matches the disposition int sum = 0; for (Disposition d : dispositions) { sum += d.w; } if (sum == disposition.w) { return dispositions; } } return null; }
/** Method that request the deletion of the current selected frame */ @SuppressWarnings("boxing") public void deleteCurrentFrame() { if (mTarget == null) return; if (mResizeFrame == null) return; final Disposition targetDisposition = resizerToDisposition(); // Get valid dispositions to move final List<Disposition> adjacents = findAdjacentsDispositions(targetDisposition); if (adjacents == null) { // Nothing to do Toast.makeText( getContext(), R.string.pref_disposition_unable_delete_advise, Toast.LENGTH_SHORT) .show(); return; } // Hide resizer mResizeFrame.setVisibility(View.GONE); // Animate adjacents views List<Animator> animators = new ArrayList<Animator>(); animators.add(ObjectAnimator.ofFloat(mTarget, "scaleX", 1.0f, 0.0f)); animators.add(ObjectAnimator.ofFloat(mTarget, "scaleY", 1.0f, 0.0f)); Disposition first = null; for (Disposition adjacent : adjacents) { // Extract the view and remove from dispositions View v = findViewFromRect(getLocationFromDisposition(adjacent)); mDispositions.remove(adjacent); // Clone first disposition if (first == null) { first = new Disposition(); first.x = adjacent.x; first.y = adjacent.y; first.w = adjacent.w; first.h = adjacent.h; } // Add animators and fix the adjacent if (v != null) { if (first.x < targetDisposition.x) { // From Left to Right int width = mTarget.getWidth() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.WidthEvaluator(v), v.getWidth(), v.getWidth() + width)); // Update the adjacent adjacent.w += targetDisposition.w; mDispositions.add(adjacent); } else if (first.x > targetDisposition.x) { // From Right to Left int width = mTarget.getWidth() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.WidthEvaluator(v), v.getWidth(), v.getWidth() + width)); animators.add(ObjectAnimator.ofFloat(v, "x", v.getX(), mTarget.getX())); // Update the adjacent adjacent.x = targetDisposition.x; adjacent.w += targetDisposition.w; mDispositions.add(adjacent); } else if (first.y < targetDisposition.y) { // From Top to Bottom int height = mTarget.getHeight() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.HeightEvaluator(v), v.getHeight(), v.getHeight() + height)); // Update the adjacent adjacent.h += targetDisposition.h; mDispositions.add(adjacent); } else if (first.y > targetDisposition.y) { // From Bottom to Top int height = mTarget.getHeight() + mInternalPadding; animators.add( ValueAnimator.ofObject( new Evaluators.HeightEvaluator(v), v.getHeight(), v.getHeight() + height)); animators.add(ObjectAnimator.ofFloat(v, "y", v.getY(), mTarget.getY())); // Update the adjacent adjacent.y = targetDisposition.y; adjacent.h += targetDisposition.h; mDispositions.add(adjacent); } } } if (animators.size() > 0) { AnimatorSet animSet = new AnimatorSet(); animSet.playTogether(animators); animSet.setDuration(getResources().getInteger(R.integer.disposition_hide_anim)); animSet.setInterpolator(new AccelerateInterpolator()); animSet.addListener( new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // Ignore } @Override public void onAnimationRepeat(Animator animation) { // Ignore } @Override public void onAnimationEnd(Animator animation) { finishDeleteAnimation(targetDisposition); } @Override public void onAnimationCancel(Animator animation) { finishDeleteAnimation(targetDisposition); } }); animSet.start(); } }