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

Commit 329fa240 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Split AM/PM from the rest of the time in expanded QS

This allows us to scale AM/PM independently of the rest of the time
string to allow for a different scale when QS is expanded.

Bug: 16177564
Change-Id: I472db549c875f6975583a6a426cb1ebc2fc37ac3
parent 6223aa10
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2014 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
  -->

<!-- Extends LinearLayout -->
<com.android.systemui.statusbar.policy.SplitClockView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    <TextClock
        android:id="@+id/time_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
        />
    <TextClock
        android:id="@+id/am_pm_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
        />
</com.android.systemui.statusbar.policy.SplitClockView>
 No newline at end of file
+1 −6
Original line number Diff line number Diff line
@@ -98,13 +98,8 @@
        android:background="?android:attr/selectableItemBackground"
        android:enabled="false"
        >
        <com.android.systemui.statusbar.policy.Clock
        <include layout="@layout/split_clock_view"
            android:id="@+id/clock"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
            systemui:amPmStyle="normal"
            />

        <com.android.systemui.statusbar.policy.DateView android:id="@+id/date_collapsed"
+24 −10
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
    private ViewGroup mSystemIconsContainer;
    private View mSystemIconsSuperContainer;
    private View mDateTime;
    private TextView mClock;
    private View mTime;
    private View mAmPm;
    private View mKeyguardCarrierText;
    private MultiUserSwitch mMultiUserSwitch;
    private ImageView mMultiUserAvatar;
@@ -108,7 +109,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
        mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container);
        mSystemIconsSuperContainer.setOnClickListener(this);
        mDateTime = findViewById(R.id.datetime);
        mClock = (TextView) findViewById(R.id.clock);
        mTime = findViewById(R.id.time_view);
        mAmPm = findViewById(R.id.am_pm_view);
        mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text);
        mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
        mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
@@ -132,8 +134,12 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
                    // width changed, update clipping
                    setClipping(getHeight());
                }
                mClock.setPivotX(0);
                mClock.setPivotY(mClock.getBaseline());
                boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
                mTime.setPivotX(rtl ? mTime.getWidth() : 0);
                mTime.setPivotY(mTime.getBaseline());
                mAmPm.setPivotX(rtl ? mAmPm.getWidth() : 0);
                mAmPm.setPivotY(mAmPm.getBaseline());
                updateAmPmTranslation();
            }
        });
    }
@@ -164,8 +170,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
                getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size)
                / (float) mMultiUserAvatar.getLayoutParams().width;
        mClockCollapsedScaleFactor =
                getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size)
                / mClock.getTextSize();
                (float) getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size)
                / (float) getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size);
        mBatteryPaddingEnd =
                getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end);
    }
@@ -315,13 +321,21 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
    }

    private void updateClockScale() {
        mAmPm.setScaleX(mClockCollapsedScaleFactor);
        mAmPm.setScaleY(mClockCollapsedScaleFactor);
        if (!mExpanded || mOverscrolled) {
            mClock.setScaleX(mClockCollapsedScaleFactor);
            mClock.setScaleY(mClockCollapsedScaleFactor);
            mTime.setScaleX(mClockCollapsedScaleFactor);
            mTime.setScaleY(mClockCollapsedScaleFactor);
        } else {
            mClock.setScaleX(1f);
            mClock.setScaleY(1f);
            mTime.setScaleX(1f);
            mTime.setScaleY(1f);
        }
        updateAmPmTranslation();
    }

    private void updateAmPmTranslation() {
        boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
        mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX()));
    }

    private void updateBatteryLevelPaddingEnd() {
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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 com.android.systemui.statusbar.policy;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextClock;

import com.android.systemui.R;

/**
 * Container for a clock which has two separate views for the clock itself and AM/PM indicator. This
 * is used to scale the clock independently of AM/PM.
 */
public class SplitClockView extends LinearLayout {

    private TextClock mTimeView;
    private TextClock mAmPmView;

    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (Intent.ACTION_TIME_CHANGED.equals(action)
                    || Intent.ACTION_TIMEZONE_CHANGED.equals(action)
                    || Intent.ACTION_LOCALE_CHANGED.equals(action)) {
                updatePatterns();
            }
        }
    };

    public SplitClockView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mTimeView = (TextClock) findViewById(R.id.time_view);
        mAmPmView = (TextClock) findViewById(R.id.am_pm_view);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        filter.addAction(Intent.ACTION_LOCALE_CHANGED);
        getContext().registerReceiver(mIntentReceiver, filter, null, null);

        updatePatterns();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        getContext().unregisterReceiver(mIntentReceiver);
    }

    private void updatePatterns() {
        String formatString = DateFormat.getTimeFormatString(getContext());
        int index = getAmPmPartEndIndex(formatString);
        String timeString;
        String amPmString;
        if (index == -1) {
            timeString = formatString;
            amPmString = "";
        } else {
            timeString = formatString.substring(0, index);
            amPmString = formatString.substring(index);
        }
        mTimeView.setFormat12Hour(timeString);
        mTimeView.setFormat24Hour(timeString);
        mAmPmView.setFormat12Hour(amPmString);
        mAmPmView.setFormat24Hour(amPmString);
    }

    /**
     * @return the index where the AM/PM part starts at the end in {@code formatString} including
     *         leading white spaces or {@code -1} if no AM/PM part is found or {@code formatString}
     *         doesn't end with AM/PM part
     */
    private static int getAmPmPartEndIndex(String formatString) {
        boolean hasAmPm = false;
        int length = formatString.length();
        for (int i = length - 1; i >= 0; i--) {
            char c = formatString.charAt(i);
            boolean isAmPm = c == 'a';
            boolean isWhitespace = Character.isWhitespace(c);
            if (isAmPm) {
                hasAmPm = true;
            }
            if (isAmPm || isWhitespace) {
                continue;
            }
            if (i == length - 1) {

                // First character was not AM/PM and not whitespace, so it's not ending with AM/PM.
                return -1;
            } else {

                // If we have AM/PM at all, return last index, or -1 to indicate that it's not
                // ending with AM/PM.
                return hasAmPm ? i + 1 : -1;
            }
        }

        // Only AM/PM and whitespaces? The whole string is AM/PM. Else: Only whitespaces in the
        // string.
        return hasAmPm ? 0 : -1;
    }

}