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

Commit 90f2c1fc authored by Lyn Han's avatar Lyn Han
Browse files

Move manage menu user education into subview

Bug: 161939484
Test: force manage edu to show, press both buttons, force rtl, press
both buttons again, keep using bubbles normally, no regressions

Change-Id: If9ddb75322e0a57358616704e6282619fc963857
parent b19564f7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<com.android.systemui.bubbles.BubbleManageEducationView
<com.android.systemui.bubbles.ManageEducationView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
@@ -87,4 +87,4 @@
                />
        </LinearLayout>
    </LinearLayout>
</com.android.systemui.bubbles.BubbleManageEducationView>
</com.android.systemui.bubbles.ManageEducationView>
+0 −106
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.bubbles;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.R;

/**
 * Educational view to highlight the manage button that allows a user to configure the settings
 * for the bubble. Shown only the first time a user expands a bubble.
 */
public class BubbleManageEducationView extends LinearLayout {

    private View mManageView;
    private TextView mTitleTextView;
    private TextView mDescTextView;

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

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

    public BubbleManageEducationView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public BubbleManageEducationView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

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

        mManageView = findViewById(R.id.manage_education_view);
        mTitleTextView = findViewById(R.id.user_education_title);
        mDescTextView = findViewById(R.id.user_education_description);

        final TypedArray ta = mContext.obtainStyledAttributes(
                new int[] {android.R.attr.colorAccent,
                        android.R.attr.textColorPrimaryInverse});
        final int bgColor = ta.getColor(0, Color.BLACK);
        int textColor = ta.getColor(1, Color.WHITE);
        ta.recycle();

        textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true);
        mTitleTextView.setTextColor(textColor);
        mDescTextView.setTextColor(textColor);
    }

    /**
     * Specifies the position for the manage view.
     */
    public void setManageViewPosition(int x, int y) {
        mManageView.setTranslationX(x);
        mManageView.setTranslationY(y);
    }

    /**
     * @return the height of the view that shows the educational text and pointer.
     */
    public int getManageViewHeight() {
        return mManageView.getHeight();
    }

    @Override
    public void setLayoutDirection(int direction) {
        super.setLayoutDirection(direction);
        if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
            mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg_rtl);
            mTitleTextView.setGravity(Gravity.RIGHT);
            mDescTextView.setGravity(Gravity.RIGHT);
        } else {
            mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg);
            mTitleTextView.setGravity(Gravity.LEFT);
            mDescTextView.setGravity(Gravity.LEFT);
        }
    }
}
+6 −29
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ public class BubbleStackView extends FrameLayout
    private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES;

    /** Animation durations for bubble stack user education views. **/
    private static final int ANIMATE_STACK_USER_EDUCATION_DURATION = 200;
    static final int ANIMATE_STACK_USER_EDUCATION_DURATION = 200;
    private static final int ANIMATE_STACK_USER_EDUCATION_DURATION_SHORT = 40;

    /** How far the flyout needs to be dragged before it's dismissed regardless of velocity. */
@@ -748,7 +748,7 @@ public class BubbleStackView extends FrameLayout
    private View mUserEducationView;

    private boolean mShouldShowManageEducation;
    private BubbleManageEducationView mManageEducationView;
    private ManageEducationView mManageEducationView;
    private boolean mAnimatingManageEducationAway;

    private ViewGroup mManageMenu;
@@ -1135,12 +1135,9 @@ public class BubbleStackView extends FrameLayout
            Log.d(TAG, "shouldShowManageEducation: " + mShouldShowManageEducation);
        }
        if (mShouldShowManageEducation) {
            mManageEducationView = (BubbleManageEducationView)
                    mInflater.inflate(R.layout.bubbles_manage_button_education, this,
            mManageEducationView = (ManageEducationView)
                    mInflater.inflate(R.layout.bubbles_manage_button_education, this /* root */,
                            false /* attachToRoot */);
            mManageEducationView.setVisibility(GONE);
            mManageEducationView.setElevation(mBubbleElevation);
            mManageEducationView.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
            addView(mManageEducationView);
        }
    }
@@ -1753,28 +1750,8 @@ public class BubbleStackView extends FrameLayout
                && mManageEducationView.getVisibility() != VISIBLE
                && mIsExpanded
                && mExpandedBubble.getExpandedView() != null) {
            mManageEducationView.setAlpha(0);
            mManageEducationView.setVisibility(VISIBLE);
            mManageEducationView.post(() -> {
                mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
                final int viewHeight = mManageEducationView.getManageViewHeight();
                final int inset = getResources().getDimensionPixelSize(
                        R.dimen.bubbles_manage_education_top_inset);
                mManageEducationView.bringToFront();
                mManageEducationView.setManageViewPosition(0, mTempRect.top - viewHeight + inset);
                mManageEducationView.animate()
                        .setDuration(ANIMATE_STACK_USER_EDUCATION_DURATION)
                        .setInterpolator(FAST_OUT_SLOW_IN).alpha(1);
                mManageEducationView.findViewById(R.id.manage).setOnClickListener(view -> {
                            mExpandedBubble.getExpandedView().findViewById(R.id.settings_button)
                                    .performClick();
                            maybeShowManageEducation(false);
                        });
                mManageEducationView.findViewById(R.id.got_it).setOnClickListener(view ->
                        maybeShowManageEducation(false));
                mManageEducationView.setOnClickListener(view ->
                        maybeShowManageEducation(false));
            });
            mManageEducationView.show(mExpandedBubble.getExpandedView(), mTempRect,
                    () -> maybeShowManageEducation(false) /* run on click */);
            Prefs.putBoolean(getContext(), HAS_SEEN_BUBBLES_MANAGE_EDUCATION, true);
        } else if (!show
                && mManageEducationView.getVisibility() == VISIBLE
+117 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.bubbles

import android.content.Context
import android.graphics.Color
import android.graphics.Rect
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import com.android.internal.util.ContrastColorUtil
import com.android.systemui.Interpolators
import com.android.systemui.R

/**
 * Educational view to highlight the manage button that allows a user to configure the settings
 * for the bubble. Shown only the first time a user expands a bubble.
 */
class ManageEducationView @JvmOverloads constructor(
    context: Context?,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {

    private val manageView by lazy { findViewById<View>(R.id.manage_education_view) }
    private val manageButton by lazy { findViewById<Button>(R.id.manage) }
    private val gotItButton by lazy { findViewById<Button>(R.id.got_it) }
    private val titleTextView by lazy { findViewById<TextView>(R.id.user_education_title) }
    private val descTextView by lazy { findViewById<TextView>(R.id.user_education_description) }
    private var isInflated = false

    init {
        this.visibility = View.GONE
        this.elevation = resources.getDimensionPixelSize(R.dimen.bubble_elevation).toFloat()
        this.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
    }

    override fun setLayoutDirection(direction: Int) {
        super.setLayoutDirection(direction)
        // setLayoutDirection runs before onFinishInflate
        // so skip if views haven't inflated; otherwise we'll get NPEs
        if (!isInflated) return
        setDirection()
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        isInflated = true
        setDirection()
        setTextColor()
    }

    private fun setTextColor() {
        val typedArray = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent,
            android.R.attr.textColorPrimaryInverse))
        val bgColor = typedArray.getColor(0 /* index */, Color.BLACK)
        var textColor = typedArray.getColor(1 /* index */, Color.WHITE)
        typedArray.recycle()
        textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true)
        titleTextView.setTextColor(textColor)
        descTextView.setTextColor(textColor)
    }

    fun setDirection() {
        manageView.setBackgroundResource(
            if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL)
                R.drawable.bubble_stack_user_education_bg_rtl
            else R.drawable.bubble_stack_user_education_bg)
        titleTextView.gravity = Gravity.START
        descTextView.gravity = Gravity.START
    }

    fun show(expandedView: BubbleExpandedView, rect : Rect, hideMenu: Runnable) {
        alpha = 0f
        visibility = View.VISIBLE
        post {
            expandedView.getManageButtonBoundsOnScreen(rect)
            with(hideMenu) {
                manageButton
                    .setOnClickListener {
                        expandedView.findViewById<View>(R.id.settings_button).performClick()
                        this.run()
                    }
                gotItButton.setOnClickListener { this.run() }
                setOnClickListener { this.run() }
            }
            with(manageView) {
                translationX = 0f
                val inset = resources.getDimensionPixelSize(
                    R.dimen.bubbles_manage_education_top_inset)
                translationY = (rect.top - manageView.height + inset).toFloat()
            }
            bringToFront()
            animate()
                .setDuration(BubbleStackView.ANIMATE_STACK_USER_EDUCATION_DURATION.toLong())
                .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
                .alpha(1f)
        }
    }
}
 No newline at end of file