16e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein/*
26e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * Copyright (C) 2013 The Android Open Source Project
36e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein *
46e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * Licensed under the Apache License, Version 2.0 (the "License");
56e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * you may not use this file except in compliance with the License.
66e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * You may obtain a copy of the License at
76e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein *
86e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein *      http://www.apache.org/licenses/LICENSE-2.0
96e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein *
106e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * Unless required by applicable law or agreed to in writing, software
116e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * distributed under the License is distributed on an "AS IS" BASIS,
126e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * See the License for the specific language governing permissions and
146e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein * limitations under the License.
156e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein */
166e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
17b8f95646fc0510eebfeaa27864023d630f34090fSam Blitzsteinpackage com.android.datetimepicker.time;
186e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
196e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.content.Context;
206e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.content.res.Resources;
216e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.graphics.Canvas;
226e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.graphics.Paint;
236e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.util.Log;
246e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport android.view.View;
256e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
266e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinimport com.android.datetimepicker.R;
276e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
28f3b38bd61d583d31200c501f5a74392aac510657Sam Blitzstein/**
29f3b38bd61d583d31200c501f5a74392aac510657Sam Blitzstein * Draws a simple white circle on which the numbers will be drawn.
30f3b38bd61d583d31200c501f5a74392aac510657Sam Blitzstein */
316e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzsteinpublic class CircleView extends View {
326e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private static final String TAG = "CircleView";
336e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
346e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private final Paint mPaint = new Paint();
356e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private boolean mIs24HourMode;
361f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein    private int mCircleColor;
371f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein    private int mDotColor;
386e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private float mCircleRadiusMultiplier;
396e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private float mAmPmCircleRadiusMultiplier;
406e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private boolean mIsInitialized;
416e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
426e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private boolean mDrawValuesReady;
436e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private int mXCenter;
446e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private int mYCenter;
456e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    private int mCircleRadius;
466e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
476e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    public CircleView(Context context) {
486e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        super(context);
496e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
506e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        Resources res = context.getResources();
511f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        mCircleColor = res.getColor(R.color.white);
521f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        mDotColor = res.getColor(R.color.numbers_text_color);
536e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        mPaint.setAntiAlias(true);
546e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
556e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        mIsInitialized = false;
566e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    }
576e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
586e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    public void initialize(Context context, boolean is24HourMode) {
596e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        if (mIsInitialized) {
606e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            Log.e(TAG, "CircleView may only be initialized once.");
616e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            return;
626e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        }
636e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
646e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        Resources res = context.getResources();
656e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        mIs24HourMode = is24HourMode;
666e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        if (is24HourMode) {
676e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mCircleRadiusMultiplier = Float.parseFloat(
686e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                    res.getString(R.string.circle_radius_multiplier_24HourMode));
696e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        } else {
706e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mCircleRadiusMultiplier = Float.parseFloat(
716e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                    res.getString(R.string.circle_radius_multiplier));
726e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mAmPmCircleRadiusMultiplier =
736e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                    Float.parseFloat(res.getString(R.string.ampm_circle_radius_multiplier));
746e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        }
756e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
766e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        mIsInitialized = true;
776e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    }
786e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
791f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein    /* package */ void setTheme(Context context, boolean dark) {
801f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        Resources res = context.getResources();
811f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        if (dark) {
821f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein            mCircleColor = res.getColor(R.color.dark_gray);
831f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein            mDotColor = res.getColor(R.color.light_gray);
841f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        } else {
851f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein            mCircleColor = res.getColor(R.color.white);
861f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein            mDotColor = res.getColor(R.color.numbers_text_color);
871f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        }
881f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein    }
891f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein
906e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
916e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    @Override
926e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    public void onDraw(Canvas canvas) {
936e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        int viewWidth = getWidth();
946e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        if (viewWidth == 0 || !mIsInitialized) {
956e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            return;
966e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        }
976e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
986e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        if (!mDrawValuesReady) {
996e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mXCenter = getWidth() / 2;
1006e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mYCenter = getHeight() / 2;
1016e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mCircleRadius = (int) (Math.min(mXCenter, mYCenter) * mCircleRadiusMultiplier);
1026e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
1036e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            if (!mIs24HourMode) {
1046e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                // We'll need to draw the AM/PM circles, so the main circle will need to have
1056e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                // a slightly higher center. To keep the entire view centered vertically, we'll
1066e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                // have to push it up by half the radius of the AM/PM circles.
1076e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                int amPmCircleRadius = (int) (mCircleRadius * mAmPmCircleRadiusMultiplier);
1086e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein                mYCenter -= amPmCircleRadius / 2;
1096e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            }
1106e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
1116e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein            mDrawValuesReady = true;
1126e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        }
1136e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
114f3b38bd61d583d31200c501f5a74392aac510657Sam Blitzstein        // Draw the white circle.
1151f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        mPaint.setColor(mCircleColor);
1166e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius, mPaint);
1176e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein
118f3b38bd61d583d31200c501f5a74392aac510657Sam Blitzstein        // Draw a small black circle in the center.
1191f129e23db2dc5837a856f7734b15a5a8be6be94Sam Blitzstein        mPaint.setColor(mDotColor);
1206e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein        canvas.drawCircle(mXCenter, mYCenter, 2, mPaint);
1216e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein    }
1226e896f805cac499b777c98755149f07ccd7ba5c3Sam Blitzstein}
123