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

Commit 55913d53 authored by Mady Mellor's avatar Mady Mellor
Browse files

Creates BubbleBarView & BubbleBarViewController & friends

BubbleBarView shows BubbleViews in a bar similar to transient
taskbar. BubbleBarView can be collapsed (bubbles in a stack) or
expanded (bubbles all visible). When expanded, WMShell will be
notified to show the appropriate expanded bubble view (not part of
this CL).

Also creates BubbleControllers which contains BubbleBarViewController
and will eventually contain other controllers related to stashing
for the bubble bar.

Bug: 253318833
Test: manual, with other CLs, see go/bubble-bar-tests
Flag: WM_BUBBLE_BAR
Change-Id: I990ab3da6614db90ffff8c40281dc7f16b3957f6
parent 47f2dd6a
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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.
  -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/icon_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@null" />

    <!--
        Icon badge size is defined in Launcher3 BaseIconFactory as 0.444 of icon size.
        Constraint guide starts from left, which means for a badge positioned on the right,
        percent has to be 1 - 0.444 to have the same effect.
    -->
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/app_icon_constraint_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.556" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/app_icon_constraint_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.556" />

    <ImageView
        android:id="@+id/app_icon_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:contentDescription="@null"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="@id/app_icon_constraint_vertical"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/app_icon_constraint_horizontal" />

</merge>
 No newline at end of file
+21 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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
  -->
<com.android.launcher3.taskbar.bubbles.BubbleView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/bubble_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
+13 −0
Original line number Diff line number Diff line
@@ -344,6 +344,19 @@
    <!-- Recents overview -->
    <dimen name="recents_filter_icon_size">30dp</dimen>

    <!-- Bubble bar -->
    <dimen name="bubblebar_size">72dp</dimen>
    <dimen name="bubblebar_stashed_handle_width">55dp</dimen>
    <dimen name="bubblebar_stashed_size">@dimen/transient_taskbar_stashed_height</dimen>
    <dimen name="bubblebar_stashed_handle_height">@dimen/taskbar_stashed_handle_height</dimen>
    <dimen name="bubblebar_pointer_size">8dp</dimen>

    <dimen name="bubblebar_icon_size">50dp</dimen>
    <dimen name="bubblebar_badge_size">24dp</dimen>
    <dimen name="bubblebar_icon_overlap">12dp</dimen>
    <dimen name="bubblebar_icon_spacing">3dp</dimen>
    <dimen name="bubblebar_icon_elevation">1dp</dimen>

    <!-- Launcher splash screen -->
    <!-- Note: keep this value in sync with the WindowManager/Shell dimens.xml -->
    <!--     starting_surface_exit_animation_window_shift_length -->
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.launcher3.taskbar.bubbles

import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.drawable.Drawable
import android.graphics.drawable.ShapeDrawable
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.Utilities.mapToRange
import com.android.launcher3.anim.Interpolators
import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound
import com.android.launcher3.taskbar.TaskbarActivityContext
import com.android.wm.shell.common.TriangleShape

/** Drawable for the background of the bubble bar. */
class BubbleBarBackground(context: TaskbarActivityContext, private val backgroundHeight: Float) :
    Drawable() {

    private val DARK_THEME_SHADOW_ALPHA = 51f
    private val LIGHT_THEME_SHADOW_ALPHA = 25f

    private val paint: Paint = Paint()
    private val pointerSize: Float

    private val shadowAlpha: Float
    private var shadowBlur = 0f
    private var keyShadowDistance = 0f

    private var arrowPositionX: Float = 0f
    private var showingArrow: Boolean = false
    private var arrowDrawable: ShapeDrawable

    init {
        paint.color = context.getColor(R.color.taskbar_background)
        paint.flags = Paint.ANTI_ALIAS_FLAG
        paint.style = Paint.Style.FILL

        val res = context.resources
        shadowBlur = res.getDimension(R.dimen.transient_taskbar_shadow_blur)
        keyShadowDistance = res.getDimension(R.dimen.transient_taskbar_key_shadow_distance)
        pointerSize = res.getDimension(R.dimen.bubblebar_pointer_size)

        shadowAlpha =
            if (Utilities.isDarkTheme(context)) DARK_THEME_SHADOW_ALPHA
            else LIGHT_THEME_SHADOW_ALPHA

        arrowDrawable =
            ShapeDrawable(TriangleShape.create(pointerSize, pointerSize, /* pointUp= */ true))
        arrowDrawable.setBounds(0, 0, pointerSize.toInt(), pointerSize.toInt())
        arrowDrawable.paint.flags = Paint.ANTI_ALIAS_FLAG
        arrowDrawable.paint.style = Paint.Style.FILL
        arrowDrawable.paint.color = context.getColor(R.color.taskbar_background)
    }

    fun showArrow(show: Boolean) {
        showingArrow = show
    }

    fun setArrowPosition(x: Float) {
        arrowPositionX = x
    }

    /** Draws the background with the given paint and height, on the provided canvas. */
    override fun draw(canvas: Canvas) {
        canvas.save()

        // TODO (b/277359345): Should animate the alpha similar to taskbar (see TaskbarDragLayer)
        // Draw shadows.
        val newShadowAlpha =
            mapToRange(paint.alpha.toFloat(), 0f, 255f, 0f, shadowAlpha, Interpolators.LINEAR)
        paint.setShadowLayer(
            shadowBlur,
            0f,
            keyShadowDistance,
            setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
        )
        arrowDrawable.paint.setShadowLayer(
            shadowBlur,
            0f,
            keyShadowDistance,
            setColorAlphaBound(Color.BLACK, Math.round(newShadowAlpha))
        )

        // Draw background.
        val radius = backgroundHeight / 2f
        canvas.drawRoundRect(
            0f,
            0f,
            canvas.width.toFloat(),
            canvas.height.toFloat(),
            radius,
            radius,
            paint
        )

        if (showingArrow) {
            // Draw arrow.
            val transX = arrowPositionX - pointerSize / 2f
            canvas.translate(transX, -pointerSize)
            arrowDrawable.draw(canvas)
        }

        canvas.restore()
    }

    override fun getOpacity(): Int {
        return paint.alpha
    }

    override fun setAlpha(alpha: Int) {
        paint.alpha = alpha
    }

    override fun setColorFilter(colorFilter: ColorFilter?) {
        paint.colorFilter = colorFilter
    }
}
+36 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.launcher3.taskbar.bubbles

import android.graphics.Bitmap
import android.graphics.Path
import com.android.wm.shell.common.bubbles.BubbleInfo

/** Contains state info about a bubble in the bubble bar as well as presentation information. */
data class BubbleBarBubble(
    val info: BubbleInfo,
    val view: BubbleView,
    val badge: Bitmap,
    val icon: Bitmap,
    val dotColor: Int,
    val dotPath: Path,
    val appName: String
) {

    fun getKey(): String {
        return info.key
    }
}
Loading