blob: a652a0fe9cdb6de98951360306e4334fcfcffc8f [file] [log] [blame]
/*
* Copyright (C) 2015 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.android.deskclock.timer;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import com.android.deskclock.R;
import com.android.deskclock.ThemeUtils;
import com.android.deskclock.data.Timer;
/**
* Custom view that draws timer progress as a circle.
*/
public final class TimerCircleView extends View {
/** The size of the dot indicating the progress through the timer. */
private final float mDotRadius;
/** The color indicating the remaining portion of the timer. */
private final int mRemainderColor;
/** The color indicating the completed portion of the timer. */
private final int mCompletedColor;
/** The size of the stroke that paints the timer circle. */
private final float mStrokeSize;
private final Paint mPaint = new Paint();
private final Paint mFill = new Paint();
private final RectF mArcRect = new RectF();
private Timer mTimer;
@SuppressWarnings("unused")
public TimerCircleView(Context context) {
this(context, null);
}
public TimerCircleView(Context context, AttributeSet attrs) {
super(context, attrs);
final Resources resources = context.getResources();
mStrokeSize = resources.getDimension(R.dimen.circletimer_circle_size);
mDotRadius = mStrokeSize / 2;
mRemainderColor = ThemeUtils.resolveColor(context, R.attr.colorAccent);
mCompletedColor = resources.getColor(R.color.secondary_color, context.getTheme());
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mFill.setAntiAlias(true);
mFill.setColor(mRemainderColor);
mFill.setStyle(Paint.Style.FILL);
}
void update(Timer timer) {
if (mTimer != timer) {
mTimer = timer;
postInvalidateOnAnimation();
}
}
@Override
public void onDraw(Canvas canvas) {
if (mTimer == null) {
return;
}
// Compute the size and location of the circle to be drawn.
final int xCenter = getWidth() / 2;
final int yCenter = getHeight() / 2;
final float radius = Math.min(xCenter, yCenter) - mStrokeSize;
// Reset old painting state.
mPaint.setColor(mRemainderColor);
mPaint.setStrokeWidth(mStrokeSize);
// If the timer is reset, draw a simple white circle.
final float redPercent;
if (mTimer.isReset()) {
// Draw a complete white circle; no red arc required.
canvas.drawCircle(xCenter, yCenter, radius, mPaint);
// Red percent is 0 since no timer progress has been made.
redPercent = 0;
} else if (mTimer.isExpired()) {
mPaint.setColor(mCompletedColor);
// Draw a complete circle; no arc required.
canvas.drawCircle(xCenter, yCenter, radius, mPaint);
// Red percent is 1 since the timer has expired.
redPercent = 1;
} else {
// Draw a combination of red and white arcs to create a circle.
mArcRect.top = yCenter - radius;
mArcRect.bottom = yCenter + radius;
mArcRect.left = xCenter - radius;
mArcRect.right = xCenter + radius;
redPercent = Math.min(1, (float) mTimer.getElapsedTime() / (float) mTimer.getTotalLength());
final float whitePercent = 1 - redPercent;
// Draw a white arc to indicate the amount of timer that remains.
canvas.drawArc(mArcRect, 270, whitePercent * 360, false, mPaint);
// Draw a red arc to indicate the amount of timer completed.
mPaint.setColor(mCompletedColor);
canvas.drawArc(mArcRect, 270, -redPercent * 360 , false, mPaint);
}
// Draw a dot to indicate current progress through the timer.
final float dotAngleDegrees = 270 - redPercent * 360;
final double dotAngleRadians = Math.toRadians(dotAngleDegrees);
final float dotX = xCenter + (float) (radius * Math.cos(dotAngleRadians));
final float dotY = yCenter + (float) (radius * Math.sin(dotAngleRadians));
canvas.drawCircle(dotX, dotY, mDotRadius, mFill);
if (mTimer.isRunning()) {
postInvalidateOnAnimation();
}
}
}