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

Commit ef70e618 authored by Lucas Silva's avatar Lucas Silva
Browse files

Implement double shadow text view for dream complications

Bug: 239089588
Test: manually on device, verifying complications are visible on white
dream

Change-Id: I9b833b6f30a4102d65d1e430a3b66ed8e79e9082
parent 84e2c20b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -241,6 +241,10 @@
    <color name="dream_overlay_aqi_very_unhealthy">#AD1457</color>
    <color name="dream_overlay_aqi_hazardous">#880E4F</color>
    <color name="dream_overlay_aqi_unknown">#BDC1C6</color>

    <!-- Dream overlay text shadows -->
    <color name="dream_overlay_clock_key_text_shadow_color">#4D000000</color>
    <color name="dream_overlay_clock_ambient_text_shadow_color">#4D000000</color>
    <color name="dream_overlay_status_bar_key_text_shadow_color">#66000000</color>
    <color name="dream_overlay_status_bar_ambient_text_shadow_color">#59000000</color>
</resources>
+11 −1
Original line number Diff line number Diff line
@@ -1547,10 +1547,20 @@
    <dimen name="broadcast_dialog_btn_text_size">16sp</dimen>
    <dimen name="broadcast_dialog_btn_minHeight">44dp</dimen>
    <dimen name="broadcast_dialog_margin">16dp</dimen>

    <!-- Shadow for dream overlay clock complication -->
    <dimen name="dream_overlay_clock_key_text_shadow_dx">0dp</dimen>
    <dimen name="dream_overlay_clock_key_text_shadow_dy">0dp</dimen>
    <dimen name="dream_overlay_clock_key_text_shadow_radius">5dp</dimen>
    <dimen name="dream_overlay_clock_key_text_shadow_radius">3dp</dimen>
    <dimen name="dream_overlay_clock_ambient_text_shadow_dx">0dp</dimen>
    <dimen name="dream_overlay_clock_ambient_text_shadow_dy">0dp</dimen>
    <dimen name="dream_overlay_clock_ambient_text_shadow_radius">1dp</dimen>

    <!-- Shadow for dream overlay status bar complications -->
    <dimen name="dream_overlay_status_bar_key_text_shadow_dx">0.5dp</dimen>
    <dimen name="dream_overlay_status_bar_key_text_shadow_dy">0.5dp</dimen>
    <dimen name="dream_overlay_status_bar_key_text_shadow_radius">1dp</dimen>
    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dx">0.5dp</dimen>
    <dimen name="dream_overlay_status_bar_ambient_text_shadow_dy">0.5dp</dimen>
    <dimen name="dream_overlay_status_bar_ambient_text_shadow_radius">2dp</dimen>
</resources>
+24 −37
Original line number Diff line number Diff line
@@ -17,24 +17,21 @@
package com.android.systemui.dreams.complication;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextClock;

import com.android.systemui.R;
import com.android.systemui.dreams.complication.DoubleShadowTextHelper.ShadowInfo;

import kotlin.Unit;

/**
 * Extension of {@link TextClock} which draws two shadows on the text (ambient and key shadows)
 */
public class DoubleShadowTextClock extends TextClock {
    private final float mAmbientShadowBlur;
    private final int mAmbientShadowColor;
    private final float mKeyShadowBlur;
    private final float mKeyShadowOffsetX;
    private final float mKeyShadowOffsetY;
    private final int mKeyShadowColor;
    private final float mAmbientShadowOffsetX;
    private final float mAmbientShadowOffsetY;
    private final DoubleShadowTextHelper mShadowHelper;

    public DoubleShadowTextClock(Context context) {
        this(context, null);
@@ -46,38 +43,28 @@ public class DoubleShadowTextClock extends TextClock {

    public DoubleShadowTextClock(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mKeyShadowBlur = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius);
        mKeyShadowOffsetX = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx);
        mKeyShadowOffsetY = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy);
        mKeyShadowColor = context.getResources().getColor(
                R.color.dream_overlay_clock_key_text_shadow_color);
        mAmbientShadowBlur = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_radius);
        mAmbientShadowColor = context.getResources().getColor(
                R.color.dream_overlay_clock_ambient_text_shadow_color);
        mAmbientShadowOffsetX = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx);
        mAmbientShadowOffsetY = context.getResources()
                .getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy);

        final Resources resources = context.getResources();
        final ShadowInfo keyShadowInfo = new ShadowInfo(
                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_radius),
                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dx),
                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_key_text_shadow_dy),
                resources.getColor(R.color.dream_overlay_clock_key_text_shadow_color));

        final ShadowInfo ambientShadowInfo = new ShadowInfo(
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_clock_ambient_text_shadow_radius),
                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dx),
                resources.getDimensionPixelSize(R.dimen.dream_overlay_clock_ambient_text_shadow_dy),
                resources.getColor(R.color.dream_overlay_clock_ambient_text_shadow_color));
        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
    }

    @Override
    public void onDraw(Canvas canvas) {
        // We enhance the shadow by drawing the shadow twice
        getPaint().setShadowLayer(mAmbientShadowBlur, mAmbientShadowOffsetX, mAmbientShadowOffsetY,
                mAmbientShadowColor);
        super.onDraw(canvas);
        canvas.save();
        canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
                getScrollX() + getWidth(),
                getScrollY() + getHeight());

        getPaint().setShadowLayer(
                mKeyShadowBlur, mKeyShadowOffsetX, mKeyShadowOffsetY, mKeyShadowColor);
        mShadowHelper.applyShadows(this, canvas, () -> {
            super.onDraw(canvas);
        canvas.restore();
            return Unit.INSTANCE;
        });
    }
}
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.dreams.complication

import android.graphics.Canvas
import android.widget.TextView
import androidx.annotation.ColorInt

class DoubleShadowTextHelper
constructor(
    private val keyShadowInfo: ShadowInfo,
    private val ambientShadowInfo: ShadowInfo,
) {
    data class ShadowInfo(
        val blur: Float,
        val offsetX: Float = 0f,
        val offsetY: Float = 0f,
        @ColorInt val color: Int
    )

    fun applyShadows(view: TextView, canvas: Canvas, onDrawCallback: () -> Unit) {
        // We enhance the shadow by drawing the shadow twice
        view.paint.setShadowLayer(
            ambientShadowInfo.blur,
            ambientShadowInfo.offsetX,
            ambientShadowInfo.offsetY,
            ambientShadowInfo.color
        )
        onDrawCallback()
        canvas.save()
        canvas.clipRect(
            view.scrollX,
            view.scrollY + view.extendedPaddingTop,
            view.scrollX + view.width,
            view.scrollY + view.height
        )

        view.paint.setShadowLayer(
            keyShadowInfo.blur,
            keyShadowInfo.offsetX,
            keyShadowInfo.offsetY,
            keyShadowInfo.color
        )
        onDrawCallback()
        canvas.restore()
    }
}
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.dreams.complication;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;

import com.android.systemui.R;

import kotlin.Unit;

/**
 * Extension of {@link TextView} which draws two shadows on the text (ambient and key shadows}
 */
public class DoubleShadowTextView extends TextView {
    private final DoubleShadowTextHelper mShadowHelper;

    public DoubleShadowTextView(Context context) {
        this(context, null);
    }

    public DoubleShadowTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DoubleShadowTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        final Resources resources = context.getResources();
        final DoubleShadowTextHelper.ShadowInfo
                keyShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_key_text_shadow_radius),
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_key_text_shadow_dx),
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_key_text_shadow_dy),
                resources.getColor(R.color.dream_overlay_status_bar_key_text_shadow_color));

        final DoubleShadowTextHelper.ShadowInfo
                ambientShadowInfo = new DoubleShadowTextHelper.ShadowInfo(
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_radius),
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dx),
                resources.getDimensionPixelSize(
                        R.dimen.dream_overlay_status_bar_ambient_text_shadow_dy),
                resources.getColor(R.color.dream_overlay_status_bar_ambient_text_shadow_color));
        mShadowHelper = new DoubleShadowTextHelper(keyShadowInfo, ambientShadowInfo);
    }

    @Override
    public void onDraw(Canvas canvas) {
        mShadowHelper.applyShadows(this, canvas, () -> {
            super.onDraw(canvas);
            return Unit.INSTANCE;
        });
    }
}