/* * Copyright (C) 2013 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 org.holoeverywhere.widget.datetimepicker.time; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Align; import android.util.AttributeSet; import android.util.Log; import android.view.View; import org.holoeverywhere.FontLoader; import org.holoeverywhere.R; import java.text.DateFormatSymbols; /** * Draw the two smaller AM and PM circles next to where the larger circle will be. */ public class AmPmCirclesView extends View { private static final String TAG = "AmPmCirclesView"; private static final int AM = TimePickerDialog.AM; private static final int PM = TimePickerDialog.PM; private final Paint mPaint = new Paint(); private int mAmPmTextColor; private float mCircleRadiusMultiplier; private float mAmPmCircleRadiusMultiplier; private String mAmText; private String mPmText; private boolean mIsInitialized; private boolean mDrawValuesReady; private int mAmPmCircleRadius; private int mAmXCenter; private int mPmXCenter; private int mAmPmYCenter; private int mAmOrPm; private int mAmOrPmPressed; private ColorStateList mCircleBackground; private int mCircleBackgroundDefault; public AmPmCirclesView(Context context) { this(context, null); } public AmPmCirclesView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.dateTimePickerStyle); } public AmPmCirclesView(Context context, AttributeSet attrs, int defStyle) { super(context); mIsInitialized = false; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DateTimePicker, defStyle, R.style.Holo_DateTimePicker); mCircleBackground = a.getColorStateList(R.styleable.DateTimePicker_timeAmPmPicker); mCircleBackgroundDefault = a.getColor(R.styleable.DateTimePicker_timeAmPmPickerBackground, 0); mAmPmTextColor = a.getColor(R.styleable.DateTimePicker_timeAmPmPickerTextColor, 0); a.recycle(); } public void initialize(int amOrPm) { if (mIsInitialized) { Log.e(TAG, "AmPmCirclesView may only be initialized once."); return; } Resources res = getContext().getResources(); mPaint.setTypeface(FontLoader.ROBOTO_REGULAR.getTypeface(getContext())); mPaint.setAntiAlias(true); mPaint.setTextAlign(Align.CENTER); mCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.time_circle_radius_multiplier)); mAmPmCircleRadiusMultiplier = Float.parseFloat(res.getString(R.string.time_ampm_circle_radius_multiplier)); String[] amPmTexts = new DateFormatSymbols().getAmPmStrings(); mAmText = amPmTexts[0]; mPmText = amPmTexts[1]; setAmOrPm(amOrPm); mAmOrPmPressed = -1; mIsInitialized = true; } public void setAmOrPm(int amOrPm) { mAmOrPm = amOrPm; } public void setAmOrPmPressed(int amOrPmPressed) { mAmOrPmPressed = amOrPmPressed; } /** * Calculate whether the coordinates are touching the AM or PM circle. */ public int getIsTouchingAmOrPm(float xCoord, float yCoord) { if (!mDrawValuesReady) { return -1; } int squaredYDistance = (int) ((yCoord - mAmPmYCenter) * (yCoord - mAmPmYCenter)); int distanceToAmCenter = (int) Math.sqrt((xCoord - mAmXCenter) * (xCoord - mAmXCenter) + squaredYDistance); if (distanceToAmCenter <= mAmPmCircleRadius) { return AM; } int distanceToPmCenter = (int) Math.sqrt((xCoord - mPmXCenter) * (xCoord - mPmXCenter) + squaredYDistance); if (distanceToPmCenter <= mAmPmCircleRadius) { return PM; } // Neither was close enough. return -1; } @Override public void onDraw(Canvas canvas) { int viewWidth = getWidth(); if (viewWidth == 0 || !mIsInitialized) { return; } if (!mDrawValuesReady) { int layoutXCenter = getWidth() / 2; int layoutYCenter = getHeight() / 2; int circleRadius = (int) (Math.min(layoutXCenter, layoutYCenter) * mCircleRadiusMultiplier); mAmPmCircleRadius = (int) (circleRadius * mAmPmCircleRadiusMultiplier); int textSize = mAmPmCircleRadius * 3 / 4; mPaint.setTextSize(textSize); // Line up the vertical center of the AM/PM circles with the bottom of the main circle. mAmPmYCenter = layoutYCenter - mAmPmCircleRadius / 2 + circleRadius; // Line up the horizontal edges of the AM/PM circles with the horizontal edges // of the main circle. mAmXCenter = layoutXCenter - circleRadius + mAmPmCircleRadius; mPmXCenter = layoutXCenter + circleRadius - mAmPmCircleRadius; mDrawValuesReady = true; } // Draw the two circles. mPaint.setColor(getCircleBackgroundColor(AM)); canvas.drawCircle(mAmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint); mPaint.setColor(getCircleBackgroundColor(PM)); canvas.drawCircle(mPmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint); // Draw the AM/PM texts on top. mPaint.setColor(mAmPmTextColor); int textYCenter = mAmPmYCenter - (int) (mPaint.descent() + mPaint.ascent()) / 2; canvas.drawText(mAmText, mAmXCenter, textYCenter, mPaint); canvas.drawText(mPmText, mPmXCenter, textYCenter, mPaint); } private int getCircleBackgroundColor(int amOrPm) { final boolean pressed = mAmOrPmPressed == amOrPm; final boolean selected = mAmOrPm == amOrPm; final int[] state = {pressed ? android.R.attr.state_pressed : -android.R.attr.state_pressed, selected ? android.R.attr.state_selected : -android.R.attr.state_selected}; return mCircleBackground.getColorForState(state, mCircleBackgroundDefault); } }