@@ -4,15 +4,14 @@ package org.wordpress.aztec.placeholders
44
55import android.graphics.Rect
66import android.graphics.drawable.Drawable
7+ import android.os.Looper
78import android.text.Editable
89import android.text.Layout
910import android.text.Spanned
1011import android.view.View
11- import android.view.ViewTreeObserver
12- import android.os.Looper
13- import android.view.ViewGroup
1412import android.view.View.MeasureSpec
15- import androidx.compose.ui.platform.ComposeView
13+ import android.view.ViewGroup
14+ import android.view.ViewTreeObserver
1615import androidx.compose.foundation.layout.Box
1716import androidx.compose.foundation.layout.height
1817import androidx.compose.foundation.layout.padding
@@ -21,6 +20,7 @@ import androidx.compose.runtime.Composable
2120import androidx.compose.runtime.collectAsState
2221import androidx.compose.runtime.key
2322import androidx.compose.ui.Modifier
23+ import androidx.compose.ui.platform.ComposeView
2424import androidx.compose.ui.platform.LocalDensity
2525import androidx.compose.ui.zIndex
2626import androidx.core.content.ContextCompat
@@ -343,11 +343,23 @@ class ComposePlaceholderManager(
343343 val editorWidth = if (aztecText.width > 0 ) {
344344 aztecText.width - aztecText.paddingStart - aztecText.paddingEnd
345345 } else aztecText.maxImagesWidth
346- val widthPx = adapter.calculateWidth(attrs, editorWidth)
347- val heightPx = computeHeightPx(adapter, attrs, editorWidth, widthPx)
348- // Reserve additional flow space after the placeholder to visually separate following blocks
349- val flowHeight = heightPx + (adapter.bottomSpacingPx(attrs))
350- drawable.setBounds(0 , 0 , widthPx, flowHeight)
346+
347+ if (adapter.sizingPolicy(attrs) != ComposePlaceholderAdapter .SizingPolicy .Unknown ) {
348+ // New behavior with enhanced measuring
349+ val widthPx = adapter.calculateWidth(attrs, editorWidth)
350+ val heightPx = computeHeightPx(adapter, attrs, editorWidth, widthPx)
351+ // Reserve additional flow space after the placeholder to visually separate following blocks
352+ val flowHeight = heightPx + (adapter.bottomSpacingPx(attrs))
353+ drawable.setBounds(0 , 0 , widthPx, flowHeight)
354+ } else {
355+ // Legacy behavior
356+ drawable.setBounds(
357+ 0 ,
358+ 0 ,
359+ adapter.calculateWidth(attrs, editorWidth),
360+ adapter.calculateHeight(attrs, editorWidth)
361+ )
362+ }
351363 return drawable
352364 }
353365
@@ -412,44 +424,96 @@ class ComposePlaceholderManager(
412424
413425 val adapter = adapters[type]!!
414426 val windowWidth = parentTextViewRect.right - parentTextViewRect.left - EDITOR_INNER_PADDING
427+
428+ // Check if using new sizing policy or legacy behavior
429+ val newComposeView = if (adapter.sizingPolicy(attrs) != ComposePlaceholderAdapter .SizingPolicy .Unknown ) {
430+ createComposeViewWithSizingPolicy(
431+ adapter, attrs, uuid, windowWidth, parentTextViewRect, parentTextViewTopAndBottomOffset
432+ )
433+ } else {
434+ createComposeViewWithLegacy(
435+ adapter, attrs, uuid, windowWidth, parentTextViewRect, parentTextViewTopAndBottomOffset
436+ )
437+ }
438+
439+ // Check if view needs updating
440+ val existingView = _composeViewState .value[uuid]
441+ if (existingView != null &&
442+ existingView.width == newComposeView.width &&
443+ existingView.height == newComposeView.height &&
444+ existingView.topMargin == newComposeView.topMargin &&
445+ existingView.leftMargin == newComposeView.leftMargin &&
446+ existingView.attrs == attrs
447+ ) {
448+ return
449+ }
450+
451+ // Update compose view state
452+ _composeViewState .value = _composeViewState .value.toMutableMap().apply {
453+ this [uuid] = newComposeView
454+ }
455+ }
456+
457+ private suspend fun createComposeViewWithSizingPolicy (
458+ adapter : ComposePlaceholderAdapter ,
459+ attrs : AztecAttributes ,
460+ uuid : String ,
461+ windowWidth : Int ,
462+ parentTextViewRect : Rect ,
463+ parentTextViewTopAndBottomOffset : Int
464+ ): ComposeView {
415465 val targetWidth = adapter.calculateWidth(attrs, windowWidth)
416466 val measuredHeight = computeHeightPx(adapter, attrs, windowWidth, targetWidth)
417467 val extraBottom = adapter.bottomSpacingPx(attrs)
418468 val height = measuredHeight + extraBottom
419469 parentTextViewRect.top + = parentTextViewTopAndBottomOffset
420470 parentTextViewRect.bottom = parentTextViewRect.top + height
421471
422- val box = _composeViewState .value[uuid]
423- val newWidth = targetWidth
424- val newHeight = measuredHeight
425472 val overlayPad = adapter.overlayPaddingPx(attrs)
426473 val newLeftPadding = parentTextViewRect.left + overlayPad.left + aztecText.paddingStart
427474 val newTopPadding = parentTextViewRect.top + overlayPad.top
428- box?.let { existingView ->
429- val widthSame = existingView.width == newWidth
430- val heightSame = existingView.height == newHeight
431- val topMarginSame = existingView.topMargin == newTopPadding
432- val leftMarginSame = existingView.leftMargin == newLeftPadding
433- val attrsSame = existingView.attrs == attrs
434- if (widthSame && heightSame && topMarginSame && leftMarginSame && attrsSame) {
435- return
436- }
437- }
438- _composeViewState .value = _composeViewState .value.let { state ->
439- val mutableState = state.toMutableMap()
440- val adjustedHeight = newHeight + (adapter.contentHeightAdjustmentPx(attrs))
441- mutableState[uuid] = ComposeView (
442- uuid = uuid,
443- width = newWidth,
444- height = adjustedHeight,
445- topMargin = newTopPadding,
446- leftMargin = newLeftPadding,
447- visible = true ,
448- adapterKey = adapter.type,
449- attrs = attrs
450- )
451- mutableState
452- }
475+ val adjustedHeight = measuredHeight + adapter.contentHeightAdjustmentPx(attrs)
476+
477+ return ComposeView (
478+ uuid = uuid,
479+ width = targetWidth,
480+ height = adjustedHeight,
481+ topMargin = newTopPadding,
482+ leftMargin = newLeftPadding,
483+ visible = true ,
484+ adapterKey = adapter.type,
485+ attrs = attrs
486+ )
487+ }
488+
489+ private suspend fun createComposeViewWithLegacy (
490+ adapter : ComposePlaceholderAdapter ,
491+ attrs : AztecAttributes ,
492+ uuid : String ,
493+ windowWidth : Int ,
494+ parentTextViewRect : Rect ,
495+ parentTextViewTopAndBottomOffset : Int
496+ ): ComposeView {
497+ val height = adapter.calculateHeight(attrs, windowWidth)
498+ parentTextViewRect.top + = parentTextViewTopAndBottomOffset
499+ parentTextViewRect.bottom = parentTextViewRect.top + height
500+
501+ val newWidth = adapter.calculateWidth(attrs, windowWidth) - EDITOR_INNER_PADDING
502+ val newHeight = height - EDITOR_INNER_PADDING
503+ val padding = 10
504+ val newLeftPadding = parentTextViewRect.left + padding + aztecText.paddingStart
505+ val newTopPadding = parentTextViewRect.top + padding
506+
507+ return ComposeView (
508+ uuid = uuid,
509+ width = newWidth,
510+ height = newHeight,
511+ topMargin = newTopPadding,
512+ leftMargin = newLeftPadding,
513+ visible = true ,
514+ adapterKey = adapter.type,
515+ attrs = attrs
516+ )
453517 }
454518
455519 private suspend fun computeHeightPx (
0 commit comments