AmPmCirclesView.java revision b8f95646fc0510eebfeaa27864023d630f34090f
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.datetimepicker.time;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Canvas;
22import android.graphics.Paint;
23import android.graphics.Typeface;
24import android.graphics.Paint.Align;
25import android.util.Log;
26import android.view.View;
27
28import com.android.datetimepicker.R;
29
30import java.text.DateFormatSymbols;
31
32public class AmPmCirclesView extends View {
33    private static final String TAG = "AmPmCirclesView";
34
35    private final Paint mPaint = new Paint();
36    private int mWhite;
37    private int mBlack50;
38    private int mBlue;
39    private float mCircleRadiusMultiplier;
40    private float mAmPmCircleRadiusMultiplier;
41    private String mAmText;
42    private String mPmText;
43    private boolean mIsInitialized;
44
45    private static final int AM = TimePickerDialog.AM;
46    private static final int PM = TimePickerDialog.PM;
47
48    private boolean mDrawValuesReady;
49    private int mAmPmCircleRadius;
50    private int mAmXCenter;
51    private int mPmXCenter;
52    private int mAmPmYCenter;
53    private int mAmOrPm;
54    private int mAmOrPmPressed;
55
56    public AmPmCirclesView(Context context) {
57        super(context);
58        mIsInitialized = false;
59    }
60
61    public void initialize(Context context, int amOrPm) {
62        if (mIsInitialized) {
63            Log.e(TAG, "AmPmCirclesView may only be initialized once.");
64            return;
65        }
66
67        Resources res = context.getResources();
68        mWhite = res.getColor(R.color.white);
69        mBlack50 = res.getColor(R.color.black_50);
70        mBlue = res.getColor(R.color.blue);
71        String typefaceFamily = res.getString(R.string.sans_serif);
72        Typeface tf = Typeface.create(typefaceFamily, Typeface.NORMAL);
73        mPaint.setTypeface(tf);
74        mPaint.setAntiAlias(true);
75        mPaint.setTextAlign(Align.CENTER);
76
77        mCircleRadiusMultiplier =
78                Float.parseFloat(res.getString(R.string.circle_radius_multiplier));
79        mAmPmCircleRadiusMultiplier =
80                Float.parseFloat(res.getString(R.string.ampm_circle_radius_multiplier));
81        String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
82        mAmText = amPmTexts[0];
83        mPmText = amPmTexts[1];
84
85        setAmOrPm(amOrPm);
86        mAmOrPmPressed = -1;
87
88        mIsInitialized = true;
89    }
90
91    public void setAmOrPm(int amOrPm) {
92        mAmOrPm = amOrPm;
93    }
94
95    public void setAmOrPmPressed(int amOrPmPressed) {
96        mAmOrPmPressed = amOrPmPressed;
97    }
98
99    public int getIsTouchingAmOrPm(float xCoord, float yCoord) {
100        if (!mDrawValuesReady) {
101            return -1;
102        }
103
104        int squaredYDistance = (int) ((yCoord - mAmPmYCenter)*(yCoord - mAmPmYCenter));
105
106        int distanceToAmCenter =
107                (int) Math.sqrt((xCoord - mAmXCenter)*(xCoord - mAmXCenter) + squaredYDistance);
108        if (distanceToAmCenter <= mAmPmCircleRadius) {
109            return AM;
110        }
111
112        int distanceToPmCenter =
113                (int) Math.sqrt((xCoord - mPmXCenter)*(xCoord - mPmXCenter) + squaredYDistance);
114        if (distanceToPmCenter <= mAmPmCircleRadius) {
115            return PM;
116        }
117
118        // Neither was close enough.
119        return -1;
120    }
121
122    @Override
123    public void onDraw(Canvas canvas) {
124        int viewWidth = getWidth();
125        if (viewWidth == 0 || !mIsInitialized) {
126            return;
127        }
128
129        if (!mDrawValuesReady) {
130            int layoutXCenter = getWidth() / 2;
131            int layoutYCenter = getHeight() / 2;
132            int circleRadius =
133                    (int) (Math.min(layoutXCenter, layoutYCenter) * mCircleRadiusMultiplier);
134            mAmPmCircleRadius = (int) (circleRadius * mAmPmCircleRadiusMultiplier);
135            int textSize = mAmPmCircleRadius * 2 / 3;
136            mPaint.setTextSize(textSize);
137
138            // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
139            mAmPmYCenter = layoutYCenter - mAmPmCircleRadius / 2 + circleRadius;
140            // Line up the horizontal edges of the AM/PM circles with the horizontal edges
141            // of the main circle.
142            mAmXCenter = layoutXCenter - circleRadius + mAmPmCircleRadius;
143            mPmXCenter = layoutXCenter + circleRadius - mAmPmCircleRadius;
144
145            mDrawValuesReady = true;
146        }
147
148        int amColor = mWhite;
149        int amAlpha = 255;
150        int pmColor = mWhite;
151        int pmAlpha = 255;
152        if (mAmOrPm == AM) {
153            amColor = mBlue;
154            amAlpha = 38;
155        } else if (mAmOrPm == PM) {
156            pmColor = mBlue;
157            pmAlpha = 38;
158        }
159        if (mAmOrPmPressed == AM) {
160            amColor = mBlue;
161            amAlpha = 175;
162        } else if (mAmOrPmPressed == PM) {
163            pmColor = mBlue;
164            pmAlpha = 175;
165        }
166
167        mPaint.setColor(amColor);
168        mPaint.setAlpha(amAlpha);
169        canvas.drawCircle(mAmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);
170        mPaint.setColor(pmColor);
171        mPaint.setAlpha(pmAlpha);
172        canvas.drawCircle(mPmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);
173
174        mPaint.setColor(mBlack50);
175        int textYCenter = mAmPmYCenter - (int) (mPaint.descent() + mPaint.ascent()) / 2;
176        canvas.drawText(mAmText, mAmXCenter, textYCenter, mPaint);
177        canvas.drawText(mPmText, mPmXCenter, textYCenter, mPaint);
178    }
179}
180