/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.numix.calculator.view;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Window;
import android.widget.FrameLayout;
import com.numix.calculator.Calculator;
import com.numix.calculator.R;
public class Cling extends FrameLayout {
public static final int SHOW_CLING_DURATION = 550;
public static final int DISMISS_CLING_DURATION = 250;
public static final String SIMPLE_CLING_DISMISSED_KEY = "cling.simple.dismissed";
public static final String MATRIX_CLING_DISMISSED_KEY = "cling.matrix.dismissed";
public static final String HEX_CLING_DISMISSED_KEY = "cling.hex.dismissed";
public static final String GRAPH_CLING_DISMISSED_KEY = "cling.graph.dismissed";
private Calculator mCalculator;
private boolean mIsInitialized;
private Drawable mBackground;
private Drawable mPunchThroughGraphic;
private Drawable mHandTouchGraphic;
private int mPunchThroughGraphicCenterRadius;
private float mRevealRadius;
private int[] mPositionData;
private boolean mShowHand;
private boolean mDismissed;
private Paint mErasePaint;
public Cling(Context context) {
this(context, null, 0);
}
public Cling(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Cling(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void init(Calculator c, int[] positionData, float revealRadius, boolean showHand) {
if(!mIsInitialized) {
mCalculator = c;
mPositionData = positionData;
mShowHand = showHand;
mDismissed = false;
Resources r = getContext().getResources();
mPunchThroughGraphic = r.getDrawable(R.drawable.cling);
mPunchThroughGraphicCenterRadius = r.getDimensionPixelSize(R.dimen.clingPunchThroughGraphicCenterRadius);
mRevealRadius = revealRadius;
mErasePaint = new Paint();
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
mErasePaint.setColor(0xFFFFFF);
mErasePaint.setAlpha(0);
mIsInitialized = true;
}
}
public void dismiss() {
mDismissed = true;
}
boolean isDismissed() {
return mDismissed;
}
public void cleanup() {
mBackground = null;
mPunchThroughGraphic = null;
mHandTouchGraphic = null;
mIsInitialized = false;
}
private int[] getPunchThroughPosition() {
if(mPositionData != null) {
return mPositionData;
}
return new int[] { -1, -1, -1 };
}
@Override
public boolean onTouchEvent(android.view.MotionEvent event) {
int[] pos = getPunchThroughPosition();
double diff = Math.sqrt(Math.pow(event.getX() - pos[0], 2) + Math.pow(event.getY() - pos[1], 2));
if(diff < mRevealRadius) {
return false;
}
return true;
};
@Override
protected void dispatchDraw(Canvas canvas) {
if(mIsInitialized) {
DisplayMetrics metrics = new DisplayMetrics();
mCalculator.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// Initialize the draw buffer (to allow punching through)
Bitmap b = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
// Draw the background
if(mBackground == null) {
mBackground = getResources().getDrawable(R.drawable.bg_cling);
}
if(mBackground != null) {
mBackground.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
mBackground.draw(c);
}
else {
c.drawColor(0x99000000);
}
int cx = -1;
int cy = -1;
int cz = -1;
float scale = mRevealRadius / mPunchThroughGraphicCenterRadius;
int dw = (int) (scale * mPunchThroughGraphic.getIntrinsicWidth());
int dh = (int) (scale * mPunchThroughGraphic.getIntrinsicHeight());
// Determine where to draw the punch through graphic
Rect rect = new Rect();
Window window = ((Activity) getContext()).getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
int[] pos = getPunchThroughPosition();
cx = pos[0];
cy = pos[1] - statusBarHeight;
cz = pos[2];
if(cx > -1 && cy > -1 && scale > 0) {
c.drawCircle(cx, cy, mRevealRadius, mErasePaint);
mPunchThroughGraphic.setBounds(cx - dw / 2, cy - dh / 2, cx + dw / 2, cy + dh / 2);
mPunchThroughGraphic.draw(c);
}
// Draw the hand graphic
if(mShowHand) {
if(mHandTouchGraphic == null) {
mHandTouchGraphic = getResources().getDrawable(R.drawable.hand);
}
int offset = cz;
mHandTouchGraphic.setBounds(cx + offset, cy + offset, cx + mHandTouchGraphic.getIntrinsicWidth() + offset,
cy + mHandTouchGraphic.getIntrinsicHeight() + offset);
mHandTouchGraphic.draw(c);
}
canvas.drawBitmap(b, 0, 0, null);
c.setBitmap(null);
b = null;
}
// Draw the rest of the cling
super.dispatchDraw(canvas);
};
}