1 /*
<lambda>null2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3.taskbar.bubbles
18 
19 import android.annotation.SuppressLint
20 import android.content.Context
21 import android.graphics.Point
22 import android.view.Gravity.BOTTOM
23 import android.view.Gravity.LEFT
24 import android.view.Gravity.RIGHT
25 import android.view.LayoutInflater
26 import android.view.View
27 import android.widget.FrameLayout
28 import androidx.core.view.updateLayoutParams
29 import com.android.launcher3.R
30 import com.android.wm.shell.common.bubbles.BaseBubblePinController
31 import com.android.wm.shell.common.bubbles.BubbleBarLocation
32 
33 /** Controller to manage pinning bubble bar to left or right when dragging starts from a bubble */
34 class BubblePinController(
35     private val context: Context,
36     private val container: FrameLayout,
37     screenSizeProvider: () -> Point
38 ) : BaseBubblePinController(screenSizeProvider) {
39 
40     var dropTargetSize: Point? = null
41 
42     private lateinit var bubbleBarViewController: BubbleBarViewController
43     private lateinit var bubbleStashController: BubbleStashController
44     private var exclRectWidth: Float = 0f
45     private var exclRectHeight: Float = 0f
46 
47     private var dropTargetView: View? = null
48     // Fallback width and height in case shell has not sent the size over
49     private var dropTargetDefaultWidth: Int = 0
50     private var dropTargetDefaultHeight: Int = 0
51     private var dropTargetMargin: Int = 0
52 
53     fun init(bubbleControllers: BubbleControllers) {
54         bubbleBarViewController = bubbleControllers.bubbleBarViewController
55         bubbleStashController = bubbleControllers.bubbleStashController
56         exclRectWidth = context.resources.getDimension(R.dimen.bubblebar_dismiss_zone_width)
57         exclRectHeight = context.resources.getDimension(R.dimen.bubblebar_dismiss_zone_height)
58         dropTargetDefaultWidth =
59             context.resources.getDimensionPixelSize(
60                 R.dimen.bubble_expanded_view_drop_target_default_width
61             )
62         dropTargetDefaultHeight =
63             context.resources.getDimensionPixelSize(
64                 R.dimen.bubble_expanded_view_drop_target_default_height
65             )
66         dropTargetMargin =
67             context.resources.getDimensionPixelSize(R.dimen.bubble_expanded_view_drop_target_margin)
68     }
69 
70     override fun getExclusionRectWidth(): Float {
71         return exclRectWidth
72     }
73 
74     override fun getExclusionRectHeight(): Float {
75         return exclRectHeight
76     }
77 
78     override fun getDropTargetView(): View? {
79         return dropTargetView
80     }
81 
82     override fun removeDropTargetView(view: View) {
83         container.removeView(view)
84         dropTargetView = null
85     }
86 
87     override fun createDropTargetView(): View {
88         return LayoutInflater.from(context)
89             .inflate(R.layout.bubble_expanded_view_drop_target, container, false)
90             .also { view ->
91                 dropTargetView = view
92                 container.addView(view)
93             }
94     }
95 
96     @SuppressLint("RtlHardcoded")
97     override fun updateLocation(location: BubbleBarLocation) {
98         val onLeft = location.isOnLeft(container.isLayoutRtl)
99 
100         val bubbleBarBounds = bubbleBarViewController.bubbleBarBounds
101         dropTargetView?.updateLayoutParams<FrameLayout.LayoutParams> {
102             gravity = BOTTOM or (if (onLeft) LEFT else RIGHT)
103             width = dropTargetSize?.x ?: dropTargetDefaultWidth
104             height = dropTargetSize?.y ?: dropTargetDefaultHeight
105             bottomMargin =
106                 -bubbleStashController.bubbleBarTranslationY.toInt() +
107                     bubbleBarBounds.height() +
108                     dropTargetMargin
109         }
110     }
111 }
112