@@ -75,53 +75,56 @@ fun ListPopup(
7575) {
7676 if (! show.value) return
7777
78- val currentOnDismissRequest by rememberUpdatedState(onDismissRequest)
79- val currentContent by rememberUpdatedState(content)
80-
81- var offset by remember { mutableStateOf(IntOffset .Zero ) }
8278 val density = LocalDensity .current
8379 val layoutDirection = LocalLayoutDirection .current
8480
85- val getWindowSizeState = rememberUpdatedState( getWindowSize() )
86- var windowSize by remember { mutableStateOf(IntSize (getWindowSizeState.value. width, getWindowSizeState.value .height)) }
81+ val currentWindowSize = getWindowSize()
82+ var windowSize by remember { mutableStateOf(IntSize (currentWindowSize. width, currentWindowSize .height)) }
8783 var parentBounds by remember { mutableStateOf(IntRect .Zero ) }
8884
89- val windowBounds = with (density) {
90- IntRect (
91- left = WindowInsets .displayCutout.asPaddingValues(density).calculateLeftPadding(layoutDirection).roundToPx(),
92- top = WindowInsets .statusBars.asPaddingValues().calculateTopPadding().roundToPx(),
93- right = windowSize.width -
94- WindowInsets .displayCutout.asPaddingValues(density).calculateRightPadding(layoutDirection).roundToPx (),
95- bottom = windowSize.height -
96- WindowInsets .navigationBars.asPaddingValues().calculateBottomPadding().roundToPx() -
97- WindowInsets .captionBar.asPaddingValues().calculateBottomPadding().roundToPx()
98- )
99- }
100-
101- var popupContentSize by remember { mutableStateOf( IntSize . Zero ) }
85+ Layout (
86+ modifier = Modifier .onGloballyPositioned { childCoordinates ->
87+ childCoordinates.parentLayoutCoordinates?. let { parentLayoutCoordinates ->
88+ val positionInWindow = parentLayoutCoordinates.positionInWindow()
89+ parentBounds = IntRect (
90+ left = positionInWindow.x.toInt (),
91+ top = positionInWindow.y.toInt(),
92+ right = positionInWindow.x.toInt() + parentLayoutCoordinates.size.width,
93+ bottom = positionInWindow.y.toInt() + parentLayoutCoordinates.size.height
94+ )
95+ }
96+ }
97+ ) { _, _ -> layout( 0 , 0 ) {} }
10298
103- val popupMargin = remember(popupPositionProvider, density, layoutDirection ) {
104- val popupMarginsPd = popupPositionProvider.getMargins()
99+ val popupMargin = remember(popupPositionProvider, layoutDirection, density ) {
100+ val pd = popupPositionProvider.getMargins()
105101 with (density) {
106102 IntRect (
107- left = popupMarginsPd .calculateLeftPadding(layoutDirection).roundToPx(),
108- top = popupMarginsPd .calculateTopPadding().roundToPx(),
109- right = popupMarginsPd .calculateRightPadding(layoutDirection).roundToPx(),
110- bottom = popupMarginsPd .calculateBottomPadding().roundToPx()
103+ left = pd .calculateLeftPadding(layoutDirection).roundToPx(),
104+ top = pd .calculateTopPadding().roundToPx(),
105+ right = pd .calculateRightPadding(layoutDirection).roundToPx(),
106+ bottom = pd .calculateBottomPadding().roundToPx()
111107 )
112108 }
113109 }
114110
115- val transformOrigin = remember(parentBounds, popupMargin, windowSize, density, alignment) {
116- val xInWindow = if (alignment in listOf (
117- PopupPositionProvider .Align .Right ,
118- PopupPositionProvider .Align .TopRight ,
119- PopupPositionProvider .Align .BottomRight ,
120- )
121- ) {
122- parentBounds.right - popupMargin.right - with (density) { 64 .dp.roundToPx() }
123- } else {
124- parentBounds.left + popupMargin.left + with (density) { 64 .dp.roundToPx() }
111+ val windowBounds = with (density) {
112+ IntRect (
113+ left = WindowInsets .displayCutout.asPaddingValues().calculateLeftPadding(layoutDirection).roundToPx(),
114+ top = WindowInsets .statusBars.asPaddingValues().calculateTopPadding().roundToPx(),
115+ right = windowSize.width - WindowInsets .displayCutout.asPaddingValues().calculateRightPadding(layoutDirection).roundToPx(),
116+ bottom = windowSize.height - WindowInsets .navigationBars.asPaddingValues().calculateBottomPadding()
117+ .roundToPx() - WindowInsets .captionBar.asPaddingValues().calculateBottomPadding().roundToPx()
118+ )
119+ }
120+
121+ val transformOrigin = remember(parentBounds, popupMargin, windowSize, alignment, density) {
122+ val xInWindow = when (alignment) {
123+ PopupPositionProvider .Align .Right ,
124+ PopupPositionProvider .Align .TopRight ,
125+ PopupPositionProvider .Align .BottomRight -> parentBounds.right - popupMargin.right - with (density) { 64 .dp.roundToPx() }
126+
127+ else -> parentBounds.left + popupMargin.left + with (density) { 64 .dp.roundToPx() }
125128 }
126129 val yInWindow = parentBounds.top + parentBounds.height / 2 - with (density) { 56 .dp.roundToPx() }
127130 safeTransformOrigin(
@@ -130,96 +133,69 @@ fun ListPopup(
130133 )
131134 }
132135
133- // Anchor point for the popup
134- Layout (
135- modifier = Modifier .onGloballyPositioned { childCoordinates ->
136- val parentLayoutCoordinates = childCoordinates.parentLayoutCoordinates
137- if (parentLayoutCoordinates != null ) {
138- val positionInWindow = parentLayoutCoordinates.positionInWindow()
139- parentBounds = IntRect (
140- left = positionInWindow.x.toInt(),
141- top = positionInWindow.y.toInt(),
142- right = positionInWindow.x.toInt() + parentLayoutCoordinates.size.width,
143- bottom = positionInWindow.y.toInt() + parentLayoutCoordinates.size.height
144- )
145- }
146- val newUtilWindowSize = getWindowSizeState.value
147- val newIntSize = IntSize (newUtilWindowSize.width, newUtilWindowSize.height)
148- if (windowSize != newIntSize) {
149- windowSize = newIntSize
150- }
151- }
152- ) { _, _ ->
153- layout(0 , 0 ) {}
154- }
155-
156- PopupLayout (
157- visible = show,
158- enableWindowDim = enableWindowDim,
159- transformOrigin = { transformOrigin },
160- ) {
161- val shape = remember { SmoothRoundedCornerShape (16 .dp) }
162- val elevationPx = with (density) { shadowElevation.toPx() }
136+ if (parentBounds != IntRect .Zero && windowSize != IntSize .Zero ) {
137+ PopupLayout (
138+ visible = show,
139+ enableWindowDim = enableWindowDim,
140+ transformOrigin = { transformOrigin },
141+ ) {
142+ val shape = remember { SmoothRoundedCornerShape (16 .dp) }
143+ val elevationPx = with (density) { shadowElevation.toPx() }
163144
164- Box (
165- modifier = popupModifier
166- .pointerInput(currentOnDismissRequest) {
167- detectTapGestures {
168- currentOnDismissRequest?.invoke()
169- }
170- }
171- .layout { measurable, constraints ->
172- val placeable = measurable.measure(
173- constraints.copy(
174- minWidth = if (minWidth.roundToPx() <= windowSize.width) minWidth.roundToPx() else windowSize.width,
175- minHeight = if (50 .dp.roundToPx() <= windowSize.height) 50 .dp.roundToPx() else windowSize.height,
176- maxHeight = maxHeight?.roundToPx()?.coerceAtLeast(50 .dp.roundToPx())
177- ? : (windowBounds.height - popupMargin.top - popupMargin.bottom).coerceAtLeast(
178- 50 .dp.roundToPx()
179- ),
180- maxWidth = if (minWidth.roundToPx() <= windowSize.width) windowSize.width else minWidth.roundToPx()
145+ Box (
146+ modifier = popupModifier
147+ .pointerInput(onDismissRequest) {
148+ detectTapGestures(
149+ onTap = { onDismissRequest?.invoke() }
181150 )
182- )
183- val measuredSize = IntSize (placeable.width, placeable.height)
184- if (popupContentSize != measuredSize) {
185- popupContentSize = measuredSize
186- }
187-
188- val calculatedOffset = popupPositionProvider.calculatePosition(
189- parentBounds,
190- windowBounds,
191- layoutDirection,
192- measuredSize,
193- popupMargin,
194- alignment
195- )
196- if (offset != calculatedOffset) {
197- offset = calculatedOffset
198151 }
152+ .layout { measurable, constraints ->
153+ val placeable = measurable.measure(
154+ constraints.copy(
155+ minWidth = if (minWidth.roundToPx() <= windowSize.width) minWidth.roundToPx() else windowSize.width,
156+ minHeight = if (50 .dp.roundToPx() <= windowSize.height) 50 .dp.roundToPx() else windowSize.height,
157+ maxHeight = maxHeight?.roundToPx()?.coerceAtLeast(50 .dp.roundToPx())
158+ ? : (windowBounds.height - popupMargin.top - popupMargin.bottom).coerceAtLeast(
159+ 50 .dp.roundToPx()
160+ ),
161+ maxWidth = if (minWidth.roundToPx() <= windowSize.width) windowSize.width else minWidth.roundToPx()
162+ )
163+ )
164+ val measuredSize = IntSize (placeable.width, placeable.height)
165+
166+ val calculatedOffset = popupPositionProvider.calculatePosition(
167+ parentBounds,
168+ windowBounds,
169+ layoutDirection,
170+ measuredSize,
171+ popupMargin,
172+ alignment
173+ )
199174
200- layout(constraints.maxWidth, constraints.maxHeight) {
201- placeable.place(offset)
175+ layout(constraints.maxWidth, constraints.maxHeight) {
176+ placeable.place(calculatedOffset)
177+ }
202178 }
203- }
204- ) {
205- Box (
206- modifier = Modifier
207- .graphicsLayer(
208- clip = true ,
209- shape = shape,
210- shadowElevation = elevationPx,
211- ambientShadowColor = MiuixTheme .colorScheme.windowDimming,
212- spotShadowColor = MiuixTheme .colorScheme.windowDimming
213- )
214- .background(MiuixTheme .colorScheme.surface)
215179 ) {
216- currentContent()
180+ Box (
181+ modifier = Modifier
182+ .graphicsLayer(
183+ clip = true ,
184+ shape = shape,
185+ shadowElevation = elevationPx,
186+ ambientShadowColor = MiuixTheme .colorScheme.windowDimming,
187+ spotShadowColor = MiuixTheme .colorScheme.windowDimming
188+ )
189+ .background(MiuixTheme .colorScheme.surface)
190+ ) {
191+ content()
192+ }
217193 }
218194 }
219195 }
220196
221197 BackHandler (enabled = show.value) {
222- currentOnDismissRequest ?.invoke()
198+ onDismissRequest ?.invoke()
223199 }
224200}
225201
0 commit comments