/*
* Copyright (C) 2008 ZXing authors
*
* 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 cn.mutils.app.zxing;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import cn.mutils.app.zxing.camera.CameraManager;
/**
* This view is overlaid on top of the camera preview. It adds the viewfinder
* rectangle and partial transparency outside it, as well as the laser scanner
* animation and result points.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
@SuppressWarnings("unused")
public final class ViewfinderView extends View {
private Paint paint;
private int maskColor;
private int frameColor;
private int laserColor;
private Drawable laserLine;
protected int lastFrameWidth;
protected int lastFrameHeight;
protected int laserPosition;
protected Rect frame;
protected Matrix matrix;
public ViewfinderView(Context context) {
super(context);
init();
}
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
protected void init() {
paint = new Paint();
paint.setAntiAlias(true);
maskColor = 0x60000000;
frameColor = 0xFF13B0F7;
laserColor = 0xFF10B5F1;
frame = new Rect();
matrix = new Matrix();
}
public void setLaserLine(Drawable laserLine) {
this.laserLine = laserLine;
this.invalidate();
}
public void setLaserColor(ColorStateList laserColor) {
if (laserColor == null) {
return;
}
this.laserColor = laserColor.getDefaultColor();
this.invalidate();
}
public void setFrameColor(ColorStateList frameColor) {
if (frameColor == null) {
return;
}
this.frameColor = frameColor.getDefaultColor();
this.invalidate();
}
public void setMaskColor(ColorStateList maskColor) {
if (maskColor == null) {
return;
}
this.maskColor = maskColor.getDefaultColor();
this.invalidate();
}
public void setFrameColor(int frameColor) {
this.frameColor = frameColor;
this.invalidate();
}
public void setFrameColor(String frameColor) {
try {
this.setFrameColor(Color.parseColor(frameColor));
} catch (Exception e) {
// IllegalArgumentException
}
}
public void setLaserColor(int laserColor) {
this.laserColor = laserColor;
this.invalidate();
}
public void setLaserColor(String laserColor) {
try {
this.setLaserColor(Color.parseColor(laserColor));
} catch (Exception e) {
// IllegalArgumentException
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
int[] location = new int[2];
this.getLocationInWindow(location);
frame.setEmpty();
CameraManager.get().setFramingRect(null);
Rect framingRect = CameraManager.get().getFramingRect();
if (framingRect == null) {
return;
}
frame.set(framingRect);
frame.offset(-frame.left, -frame.top);
frame.offset(location[0] + (this.getWidth() - frame.width()) / 2,
location[1] + (this.getHeight() - frame.height()) / 2);
CameraManager.get().setFramingRect(frame);
frame.offset(-location[0], -location[1]);
this.invalidate();
}
@Override
public void onDraw(Canvas canvas) {
int width = canvas.getWidth();
int height = canvas.getHeight();
// Draw the exterior (i.e. outside the framing rect) darkened
paint.reset();
paint.setColor(maskColor);
if (frame.isEmpty()) {
canvas.drawRect(0, 0, width, height, paint);
return;
}
float laserW = laserLine == null ? 0 : laserLine.getIntrinsicWidth();
float laserH = laserLine == null ? 0 : laserLine.getIntrinsicHeight();
int laserStep = (int) (3 + laserH / 2 + 0.5);
if (this.lastFrameWidth == frame.width()
&& this.lastFrameHeight == frame.height()) {
if (this.laserPosition + laserStep > frame.height()) {
this.laserPosition = laserStep;
}
} else {
this.lastFrameWidth = frame.width();
this.lastFrameHeight = frame.height();
this.laserPosition = laserStep;
}
canvas.drawRect(0, 0, width, frame.top, paint);
canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);
canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1,
paint);
canvas.drawRect(0, frame.bottom + 1, width, height, paint);
if (laserLine == null) {
paint.setColor(laserColor);
paint.setStrokeWidth(3);
canvas.drawLine(frame.left, frame.top + this.laserPosition,
frame.right, frame.top + this.laserPosition, paint);
paint.setStrokeWidth(1);
} else {
float laserNowW = frame.width() - 4;
float laserNowH = laserNowW * laserH / laserW;
int halfLaserNowH = (int) (laserNowH / 2 + 0.5);
laserLine.setBounds(frame.left + 2, frame.top + this.laserPosition
- halfLaserNowH, frame.right - 2, frame.top
+ this.laserPosition + halfLaserNowH);
laserLine.draw(canvas);
}
this.laserPosition += 20;
// Draw a two pixel solid black border inside the framing rect
paint.setColor(frameColor);
paint.setStrokeWidth(5);
drawFrameRect(frame.left, frame.top, frame.right, frame.bottom, canvas,
paint);
paint.setStrokeWidth(1);
// Request another update at the animation interval, but only
// repaint the laser line,
// not the entire viewfinder mask.
postInvalidateDelayed(100, frame.left, frame.top, frame.right,
frame.bottom);
}
protected void drawFrameRect(float left, float top, float right,
float bottom, Canvas canvas, Paint paint) {
int offset = (int) (paint.getStrokeWidth() / 2);
float width = right - left;
float height = bottom - top;
float hSize = width / 10;
float vSize = height / 10;
canvas.drawLine(left - offset, top, left + hSize, top, paint);
canvas.drawLine(right - hSize, top, right + offset, top, paint);
canvas.drawLine(right, top - offset, right, top + vSize, paint);
canvas.drawLine(right, bottom - vSize, right, bottom + offset, paint);
canvas.drawLine(right + offset, bottom, right - hSize, bottom, paint);
canvas.drawLine(left + hSize, bottom, left - offset, bottom, paint);
canvas.drawLine(left, bottom + offset, left, bottom - vSize, paint);
canvas.drawLine(left, top + vSize, left, top - offset, paint);
}
}