Home | History | Annotate | Download | only in time
      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 
     17 package com.android.datetimepicker.time;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.graphics.Canvas;
     22 import android.graphics.Paint;
     23 import android.graphics.Typeface;
     24 import android.graphics.Paint.Align;
     25 import android.util.Log;
     26 import android.view.View;
     27 
     28 import com.android.datetimepicker.R;
     29 
     30 import java.text.DateFormatSymbols;
     31 
     32 /**
     33  * Draw the two smaller AM and PM circles next to where the larger circle will be.
     34  */
     35 public class AmPmCirclesView extends View {
     36     private static final String TAG = "AmPmCirclesView";
     37 
     38     // Alpha level of blue color for selected circle.
     39     private static final int SELECTED_ALPHA = 51;
     40     // Alpha level of blue color for pressed circle.
     41     private static final int PRESSED_ALPHA = 175;
     42 
     43     private final Paint mPaint = new Paint();
     44     private int mWhite;
     45     private int mAmPmTextColor;
     46     private int mBlue;
     47     private float mCircleRadiusMultiplier;
     48     private float mAmPmCircleRadiusMultiplier;
     49     private String mAmText;
     50     private String mPmText;
     51     private boolean mIsInitialized;
     52 
     53     private static final int AM = TimePickerDialog.AM;
     54     private static final int PM = TimePickerDialog.PM;
     55 
     56     private boolean mDrawValuesReady;
     57     private int mAmPmCircleRadius;
     58     private int mAmXCenter;
     59     private int mPmXCenter;
     60     private int mAmPmYCenter;
     61     private int mAmOrPm;
     62     private int mAmOrPmPressed;
     63 
     64     public AmPmCirclesView(Context context) {
     65         super(context);
     66         mIsInitialized = false;
     67     }
     68 
     69     public void initialize(Context context, int amOrPm) {
     70         if (mIsInitialized) {
     71             Log.e(TAG, "AmPmCirclesView may only be initialized once.");
     72             return;
     73         }
     74 
     75         Resources res = context.getResources();
     76         mWhite = res.getColor(R.color.white);
     77         mAmPmTextColor = res.getColor(R.color.ampm_text_color);
     78         mBlue = res.getColor(R.color.blue);
     79         String typefaceFamily = res.getString(R.string.sans_serif);
     80         Typeface tf = Typeface.create(typefaceFamily, Typeface.NORMAL);
     81         mPaint.setTypeface(tf);
     82         mPaint.setAntiAlias(true);
     83         mPaint.setTextAlign(Align.CENTER);
     84 
     85         mCircleRadiusMultiplier =
     86                 Float.parseFloat(res.getString(R.string.circle_radius_multiplier));
     87         mAmPmCircleRadiusMultiplier =
     88                 Float.parseFloat(res.getString(R.string.ampm_circle_radius_multiplier));
     89         String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
     90         mAmText = amPmTexts[0];
     91         mPmText = amPmTexts[1];
     92 
     93         setAmOrPm(amOrPm);
     94         mAmOrPmPressed = -1;
     95 
     96         mIsInitialized = true;
     97     }
     98 
     99     public void setAmOrPm(int amOrPm) {
    100         mAmOrPm = amOrPm;
    101     }
    102 
    103     public void setAmOrPmPressed(int amOrPmPressed) {
    104         mAmOrPmPressed = amOrPmPressed;
    105     }
    106 
    107     /**
    108      * Calculate whether the coordinates are touching the AM or PM circle.
    109      */
    110     public int getIsTouchingAmOrPm(float xCoord, float yCoord) {
    111         if (!mDrawValuesReady) {
    112             return -1;
    113         }
    114 
    115         int squaredYDistance = (int) ((yCoord - mAmPmYCenter)*(yCoord - mAmPmYCenter));
    116 
    117         int distanceToAmCenter =
    118                 (int) Math.sqrt((xCoord - mAmXCenter)*(xCoord - mAmXCenter) + squaredYDistance);
    119         if (distanceToAmCenter <= mAmPmCircleRadius) {
    120             return AM;
    121         }
    122 
    123         int distanceToPmCenter =
    124                 (int) Math.sqrt((xCoord - mPmXCenter)*(xCoord - mPmXCenter) + squaredYDistance);
    125         if (distanceToPmCenter <= mAmPmCircleRadius) {
    126             return PM;
    127         }
    128 
    129         // Neither was close enough.
    130         return -1;
    131     }
    132 
    133     @Override
    134     public void onDraw(Canvas canvas) {
    135         int viewWidth = getWidth();
    136         if (viewWidth == 0 || !mIsInitialized) {
    137             return;
    138         }
    139 
    140         if (!mDrawValuesReady) {
    141             int layoutXCenter = getWidth() / 2;
    142             int layoutYCenter = getHeight() / 2;
    143             int circleRadius =
    144                     (int) (Math.min(layoutXCenter, layoutYCenter) * mCircleRadiusMultiplier);
    145             mAmPmCircleRadius = (int) (circleRadius * mAmPmCircleRadiusMultiplier);
    146             int textSize = mAmPmCircleRadius * 3 / 4;
    147             mPaint.setTextSize(textSize);
    148 
    149             // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
    150             mAmPmYCenter = layoutYCenter - mAmPmCircleRadius / 2 + circleRadius;
    151             // Line up the horizontal edges of the AM/PM circles with the horizontal edges
    152             // of the main circle.
    153             mAmXCenter = layoutXCenter - circleRadius + mAmPmCircleRadius;
    154             mPmXCenter = layoutXCenter + circleRadius - mAmPmCircleRadius;
    155 
    156             mDrawValuesReady = true;
    157         }
    158 
    159         // We'll need to draw either a lighter blue (for selection), a darker blue (for touching)
    160         // or white (for not selected).
    161         int amColor = mWhite;
    162         int amAlpha = 255;
    163         int pmColor = mWhite;
    164         int pmAlpha = 255;
    165         if (mAmOrPm == AM) {
    166             amColor = mBlue;
    167             amAlpha = SELECTED_ALPHA;
    168         } else if (mAmOrPm == PM) {
    169             pmColor = mBlue;
    170             pmAlpha = SELECTED_ALPHA;
    171         }
    172         if (mAmOrPmPressed == AM) {
    173             amColor = mBlue;
    174             amAlpha = PRESSED_ALPHA;
    175         } else if (mAmOrPmPressed == PM) {
    176             pmColor = mBlue;
    177             pmAlpha = PRESSED_ALPHA;
    178         }
    179 
    180         // Draw the two circles.
    181         mPaint.setColor(amColor);
    182         mPaint.setAlpha(amAlpha);
    183         canvas.drawCircle(mAmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);
    184         mPaint.setColor(pmColor);
    185         mPaint.setAlpha(pmAlpha);
    186         canvas.drawCircle(mPmXCenter, mAmPmYCenter, mAmPmCircleRadius, mPaint);
    187 
    188         // Draw the AM/PM texts on top.
    189         mPaint.setColor(mAmPmTextColor);
    190         int textYCenter = mAmPmYCenter - (int) (mPaint.descent() + mPaint.ascent()) / 2;
    191         canvas.drawText(mAmText, mAmXCenter, textYCenter, mPaint);
    192         canvas.drawText(mPmText, mPmXCenter, textYCenter, mPaint);
    193     }
    194 }
    195