Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d35e923 authored by Robyn Coultas's avatar Robyn Coultas Committed by Android (Google) Code Review
Browse files

Merge "Change Counting Digits to Thin Font" into ics-ub-clock-amazon

parents 4c510966 6a2ab617
Loading
Loading
Loading
Loading
+74 −58
Original line number Diff line number Diff line
@@ -33,32 +33,37 @@ import com.android.deskclock.R;
import com.android.deskclock.Utils;


/**
 * Class to measure and draw the time in the {@link com.android.deskclock.CircleTimerView}.
 * This class manages and sums the work of the four members mBigHours, mBigMinutes,
 * mBigSeconds and mMedHundredths. Those members are each tasked with measuring, sizing and
 * drawing digits (and optional label) of the time set in {@link #setTime(long, boolean, boolean)}
 */
public class CountingTimerView extends View {
    private static final String TWO_DIGITS = "%02d";
    private static final String ONE_DIGIT = "%01d";
    private static final String NEG_TWO_DIGITS = "-%02d";
    private static final String NEG_ONE_DIGIT = "-%01d";
    private static final float TEXT_SIZE_TO_WIDTH_RATIO = 0.75f;
    // This is the ratio of the font typeface we need to offset the font by vertically to align it
    // vertically center.
    // This is the ratio of the font height needed to vertically offset the font for alignment
    // from the center.
    private static final float FONT_VERTICAL_OFFSET = 0.14f;

    private String mHours, mMinutes, mSeconds, mHundredths;

    private boolean mShowTimeStr = true;
    private final Typeface mAndroidClockMonoThin, mAndroidClockMonoBold, mAndroidClockMonoLight;
    private final Typeface mRobotoLabel;
    private final Paint mPaintBig = new Paint();
    private final Paint mPaintBigThin = new Paint();
    private final Paint mPaintMed = new Paint();
    private final Paint mPaintLabel = new Paint();
    private final float mBigFontSize, mSmallFontSize;
    // Hours and minutes are signed for when a timer goes past the set time and thus negative
    private final SignedTime mBigHours, mBigMinutes;
    private final UnsignedTime mBigThinSeconds;
    // Seconds are always shown with minutes, so are never signed
    private final UnsignedTime mBigSeconds;
    private final Hundredths mMedHundredths;
    private float mTextHeight = 0;
    private float mTotalTextWidth;
    private static final String HUNDREDTH_SEPERATOR = ".";
    private static final String HUNDREDTH_SEPARATOR = ".";
    private boolean mRemeasureText = true;

    private int mDefaultColor;
@@ -83,6 +88,11 @@ public class CountingTimerView extends View {

    };

    /**
     * Class to measure and draw the digit pairs of hours, minutes, seconds or hundredths. Digits
     * may have an optional label. for hours, minutes and seconds, this label trails the digits
     * and for seconds, precedes the digits.
     */
    class UnsignedTime {
        protected Paint mPaint;
        protected float mEm;
@@ -169,6 +179,9 @@ public class CountingTimerView extends View {
        }
    }

    /**
     * Special derivation to handle the hundredths painting with the label in front.
     */
    class Hundredths extends UnsignedTime {
        public Hundredths(Paint paint, final String label, final String allDigits) {
            super(paint, label, allDigits);
@@ -183,15 +196,14 @@ public class CountingTimerView extends View {
        }
    }

    /**
     * Special derivation to handle a negative number
     */
    class SignedTime extends UnsignedTime {
        private float mMinusWidth = 0;

        public SignedTime(Paint paint, final String label, final String allDigits) {
            super(paint, label, allDigits);
        }

        public SignedTime (SignedTime signedTime, final String label) {
            super(signedTime, label);
        public SignedTime (UnsignedTime unsignedTime, final String label) {
            super(unsignedTime, label);
        }

        @Override
@@ -217,7 +229,7 @@ public class CountingTimerView extends View {
            if (mMinusWidth != 0f) {
                float minusWidth = mMinusWidth / 2;
                x += minusWidth;
                canvas.drawText(time.substring(ii, ii + 1), x, y, mPaint);
                canvas.drawText(time.substring(0, 1), x, y, mPaint);
                x += minusWidth;
                ii++;
            }
@@ -229,48 +241,42 @@ public class CountingTimerView extends View {
        }
    }

    @SuppressWarnings("unused")
    public CountingTimerView(Context context) {
        this(context, null);
    }

    public CountingTimerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mAndroidClockMonoThin = Typeface.createFromAsset(
                context.getAssets(), "fonts/AndroidClockMono-Thin.ttf");
        mAndroidClockMonoBold = Typeface.createFromAsset(
                context.getAssets(), "fonts/AndroidClockMono-Bold.ttf");
        mAndroidClockMonoLight = Typeface.createFromAsset(
                context.getAssets(), "fonts/AndroidClockMono-Light.ttf");
        mAccessibilityManager =
                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        mRobotoLabel= Typeface.create("sans-serif-condensed", Typeface.BOLD);
        Resources r = context.getResources();
        mWhiteColor = r.getColor(R.color.clock_white);
        mDefaultColor = mWhiteColor;
        mPressedColor = r.getColor(Utils.getPressedColorId());
        mRedColor = r.getColor(R.color.clock_red);

        mPaintBig.setAntiAlias(true);
        mPaintBig.setStyle(Paint.Style.STROKE);
        mPaintBig.setTextAlign(Paint.Align.CENTER);
        mPaintBig.setTypeface(mAndroidClockMonoBold);
        mBigFontSize = r.getDimension(R.dimen.big_font_size);
        mSmallFontSize = r.getDimension(R.dimen.small_font_size);

        Typeface androidClockMonoThin = Typeface.
                createFromAsset(context.getAssets(), "fonts/AndroidClockMono-Thin.ttf");
        mPaintBigThin.setAntiAlias(true);
        mPaintBigThin.setStyle(Paint.Style.STROKE);
        mPaintBigThin.setTextAlign(Paint.Align.CENTER);
        mPaintBigThin.setTypeface(mAndroidClockMonoThin);
        mPaintBigThin.setTypeface(androidClockMonoThin);

        Typeface androidClockMonoLight = Typeface.
                createFromAsset(context.getAssets(), "fonts/AndroidClockMono-Light.ttf");
        mPaintMed.setAntiAlias(true);
        mPaintMed.setStyle(Paint.Style.STROKE);
        mPaintMed.setTextAlign(Paint.Align.CENTER);
        mPaintMed.setTypeface(mAndroidClockMonoLight);
        mPaintMed.setTypeface(androidClockMonoLight);

        Typeface robotoLabel = Typeface.create("sans-serif-condensed", Typeface.BOLD);
        mPaintLabel.setAntiAlias(true);
        mPaintLabel.setStyle(Paint.Style.STROKE);
        mPaintLabel.setTextAlign(Paint.Align.LEFT);
        mPaintLabel.setTypeface(mRobotoLabel);
        mPaintLabel.setTypeface(robotoLabel);
        mPaintLabel.setTextSize(r.getDimension(R.dimen.label_font_size));

        resetTextSize();
@@ -278,32 +284,39 @@ public class CountingTimerView extends View {

        // allDigits will contain ten digits: "0123456789" in the default locale
        final String allDigits = String.format("%010d", 123456789);
        mBigHours = new SignedTime(mPaintBig,
                r.getString(R.string.hours_label).toUpperCase(), allDigits);
        mBigMinutes = new SignedTime(mBigHours,
                r.getString(R.string.minutes_label).toUpperCase());
        mBigThinSeconds = new UnsignedTime(mPaintBigThin,
        mBigSeconds = new UnsignedTime(mPaintBigThin,
                r.getString(R.string.seconds_label).toUpperCase(), allDigits);
        mMedHundredths = new Hundredths(mPaintMed, HUNDREDTH_SEPERATOR, allDigits);
        mBigHours = new SignedTime(mBigSeconds, r.getString(R.string.hours_label).toUpperCase());
        mBigMinutes = new SignedTime(mBigSeconds, r.getString(R.string.minutes_label).toUpperCase());
        mMedHundredths = new Hundredths(mPaintMed, HUNDREDTH_SEPARATOR, allDigits);
    }

    protected void resetTextSize() {
        mPaintBig.setTextSize(mBigFontSize);
        mTextHeight = mBigFontSize;
        mPaintBigThin.setTextSize(mBigFontSize);
        mPaintMed.setTextSize(mSmallFontSize);
    }

    protected void setTextColor(int textColor) {
        mPaintBig.setColor(textColor);
        mPaintBigThin.setColor(textColor);
        mPaintMed.setColor(textColor);
        mPaintLabel.setColor(textColor);
    }

    /**
     * Update the time to display. Separates that time into the hours, minutes, seconds and
     * hundredths. If update is true, the view is invalidated so that it will draw again.
     *
     * @param time new time to display - in milliseconds
     * @param showHundredths flag to show hundredths resolution
     * @param update to invalidate the view - otherwise the time is examined to see if it is within
     *               100 milliseconds of zero seconds and when so, invalidate the view.
     */
    // TODO(coultasr):showHundredths S/B attribute or setter - i.e. unchanging over object life
    public void setTime(long time, boolean showHundredths, boolean update) {
        int oldLength = getDigitsLength();
        boolean neg = false, showNeg = false;
        String format = null;
        String format;
        if (time < 0) {
            time = -time;
            neg = showNeg = true;
@@ -318,12 +331,15 @@ public class CountingTimerView extends View {
        if (hours > 999) {
            hours = 0;
        }
        // time may less than a second below zero, since we do not show fractions of seconds
        // The time  can be between 0 and -1 seconds, but the "truncated" equivalent time of hours
        // and minutes and seconds could be zero, so since we do not show fractions of seconds
        // when counting down, do not show the minus sign.
        // TODO(coultasr):does that matter that we do nto look at showHundredths?
        if (hours == 0 && minutes == 0 && seconds == 0) {
            showNeg = false;
        }

        // Normalize and check if it is 'time' to invalidate
        if (!showHundredths) {
            if (!neg && hundreds != 0) {
                seconds++;
@@ -341,8 +357,7 @@ public class CountingTimerView extends View {
            }
        }

        int oldLength = getDigitsLength();

        // Hours may be empty
        if (hours >= 10) {
            format = showNeg ? NEG_TWO_DIGITS : TWO_DIGITS;
            mHours = String.format(format, hours);
@@ -353,6 +368,7 @@ public class CountingTimerView extends View {
            mHours = null;
        }

        // Minutes are never empty and when hours are non-empty, must be two digits
        if (minutes >= 10 || hours > 0) {
            format = (showNeg && hours == 0) ? NEG_TWO_DIGITS : TWO_DIGITS;
            mMinutes = String.format(format, minutes);
@@ -361,7 +377,10 @@ public class CountingTimerView extends View {
            mMinutes = String.format(format, minutes);
        }

        // Seconds are always two digits
        mSeconds = String.format(TWO_DIGITS, seconds);

        // Hundredths are optional and then two digits
        if (showHundredths) {
            mHundredths = String.format(TWO_DIGITS, hundreds);
        } else {
@@ -392,7 +411,7 @@ public class CountingTimerView extends View {

    private void calcTotalTextWidth() {
        mTotalTextWidth = mBigHours.calcTotalWidth(mHours) + mBigMinutes.calcTotalWidth(mMinutes)
                + mBigThinSeconds.calcTotalWidth(mSeconds)
                + mBigSeconds.calcTotalWidth(mSeconds)
                + mMedHundredths.calcTotalWidth(mHundredths);
    }

@@ -408,20 +427,19 @@ public class CountingTimerView extends View {
            while (mTotalTextWidth > wantWidth) {
                // Get fixed and variant parts of the total size
                float fixedWidths = mBigHours.getLabelWidth() + mBigMinutes.getLabelWidth()
                        + mBigThinSeconds.getLabelWidth() + mMedHundredths.getLabelWidth();
                        + mBigSeconds.getLabelWidth() + mMedHundredths.getLabelWidth();
                float varWidths = mBigHours.getWidth() + mBigMinutes.getWidth()
                        + mBigThinSeconds.getWidth() + mMedHundredths.getWidth();
                        + mBigSeconds.getWidth() + mMedHundredths.getWidth();
                // Avoid divide by zero || sizeRatio == 1 || sizeRatio <= 0
                if (varWidths == 0 || fixedWidths == 0 || fixedWidths >= wantWidth) {
                    break;
                }
                // Variant-section reduction
                float sizeRatio = (wantWidth - fixedWidths) / varWidths;
                mPaintBig.setTextSize(mPaintBig.getTextSize() * sizeRatio);
                mPaintBigThin.setTextSize(mPaintBigThin.getTextSize() * sizeRatio);
                mPaintMed.setTextSize(mPaintMed.getTextSize() * sizeRatio);
                //recalculate the new total text width and half text height
                mTextHeight = mPaintBig.getTextSize();
                // Recalculate the new total text height and half-width
                mTextHeight = mPaintBigThin.getTextSize();
                calcTotalTextWidth();
            }
        }
@@ -583,10 +601,10 @@ public class CountingTimerView extends View {
        int xCenter = width / 2;
        int yCenter = getHeight() / 2;

        float textXstart = xCenter - mTotalTextWidth / 2;
        float textYstart = yCenter + mTextHeight/2 - (mTextHeight * FONT_VERTICAL_OFFSET);
        float xTextStart = xCenter - mTotalTextWidth / 2;
        float yTextStart = yCenter + mTextHeight/2 - (mTextHeight * FONT_VERTICAL_OFFSET);
        // align the labels vertically to the top of the rest of the text
        float labelYStart = textYstart - (mTextHeight * (1 - 2 * FONT_VERTICAL_OFFSET))
        float labelYStart = yTextStart - (mTextHeight * (1 - 2 * FONT_VERTICAL_OFFSET))
                + (1 - 2 * FONT_VERTICAL_OFFSET) * mPaintLabel.getTextSize();

        // Text color differs based on pressed state.
@@ -597,24 +615,22 @@ public class CountingTimerView extends View {
        } else {
            textColor = mDefaultColor;
        }
        mPaintBig.setColor(textColor);
        mPaintBigThin.setColor(textColor);
        mPaintLabel.setColor(textColor);
        mPaintMed.setColor(textColor);

        if (mHours != null) {
            textXstart = mBigHours.draw(canvas, mHours, textXstart, textYstart, labelYStart);
            xTextStart = mBigHours.draw(canvas, mHours, xTextStart, yTextStart, labelYStart);
        }
        if (mMinutes != null) {
            textXstart = mBigMinutes.draw(canvas, mMinutes, textXstart, textYstart, labelYStart);
            xTextStart = mBigMinutes.draw(canvas, mMinutes, xTextStart, yTextStart, labelYStart);
        }
        if (mSeconds != null) {
            textXstart = mBigThinSeconds.draw(canvas, mSeconds,
                    textXstart, textYstart, labelYStart);
            xTextStart = mBigSeconds.
                    draw(canvas, mSeconds, xTextStart, yTextStart, labelYStart);
        }
        if (mHundredths != null) {
            textXstart = mMedHundredths.draw(canvas, mHundredths,
                    textXstart, textYstart, textYstart);
            mMedHundredths.draw(canvas, mHundredths, xTextStart, yTextStart, yTextStart);
        }
    }