diff --git a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt index 7501e8827..5ee93643e 100644 --- a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt +++ b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt @@ -79,11 +79,15 @@ import com.android.designcompose.LiveUpdateMode import com.android.designcompose.LocalDesignDocSettings import com.android.designcompose.LocalVariableState import com.android.designcompose.VariableState +import com.android.designcompose.android_interface.LayoutChangedResponse import com.android.designcompose.branches import com.android.designcompose.clonedWithAnimatedActionsApplied import com.android.designcompose.common.DesignDocId import com.android.designcompose.common.DocumentServerParams import com.android.designcompose.common.NodeQuery +import com.android.designcompose.definition.element.dimensionProto +import com.android.designcompose.definition.element.size +import com.android.designcompose.definition.view.scrollInfoOrNull import com.android.designcompose.dispatch import com.android.designcompose.doc import com.android.designcompose.getContent @@ -91,31 +95,20 @@ import com.android.designcompose.getKey import com.android.designcompose.getOpenLinkCallback import com.android.designcompose.getScrollCallbacks import com.android.designcompose.getTapCallback -import com.android.designcompose.proto.isPressOrClick -import com.android.designcompose.proto.isTimeout -import com.android.designcompose.proto.layoutStyle -import com.android.designcompose.proto.newDimensionProtoPoints -import com.android.designcompose.proto.overflowDirectionFromInt import com.android.designcompose.registerOpenLinkCallback import com.android.designcompose.rootNode import com.android.designcompose.rootOverlays import com.android.designcompose.sDocRenderStatus import com.android.designcompose.sDocRenderText -import com.android.designcompose.serdegen.Layout -import com.android.designcompose.serdegen.OverflowDirection -import com.android.designcompose.serdegen.Size -import com.android.designcompose.serdegen.TriggerType import com.android.designcompose.squooshAnimatedActions import com.android.designcompose.squooshCompleteAnimatedAction import com.android.designcompose.squooshFailedAnimatedAction import com.android.designcompose.squooshVariantMemory import com.android.designcompose.stateForDoc import com.android.designcompose.unregisterOpenLinkCallback -import java.util.Optional import kotlin.collections.component1 import kotlin.collections.component2 import kotlin.collections.set -import kotlin.jvm.optionals.getOrNull import kotlin.math.roundToInt import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineStart @@ -156,47 +149,48 @@ private fun SquooshResolvedNode.applyLayoutConstraints(constraints: Constraints, val layoutStyleBuilder = view.style.layoutStyle.toBuilder() if (constraints.minWidth != 0) - layoutStyleBuilder.min_width = - newDimensionProtoPoints(constraints.minWidth.toFloat() / density) + layoutStyleBuilder.minWidth = dimensionProto { + points = constraints.minWidth.toFloat() / density + } if (constraints.maxWidth != Constraints.Infinity) - layoutStyleBuilder.max_width = - newDimensionProtoPoints(constraints.maxWidth.toFloat() / density) + layoutStyleBuilder.maxWidth = dimensionProto { + points = constraints.maxWidth.toFloat() / density + } if (constraints.hasFixedWidth) { - layoutStyleBuilder.width = newDimensionProtoPoints(constraints.minWidth.toFloat() / density) + layoutStyleBuilder.width = dimensionProto { + points = constraints.minWidth.toFloat() / density + } // Layout implementation looks for width/height being set and then uses bounding box. - layoutStyleBuilder.bounding_box = - Optional.of( - Size( - constraints.minWidth.toFloat() / density, - layoutStyleBuilder.bounding_box.get().height, - ) - ) + layoutStyleBuilder.boundingBox = size { + width = constraints.minWidth.toFloat() / density + height = layoutStyleBuilder.boundingBox.height + } } if (constraints.minHeight != 0) - layoutStyleBuilder.min_height = - newDimensionProtoPoints(constraints.minHeight.toFloat() / density) + layoutStyleBuilder.minHeight = dimensionProto { + points = constraints.minHeight.toFloat() / density + } if (constraints.maxHeight != Constraints.Infinity) - layoutStyleBuilder.max_height = - newDimensionProtoPoints(constraints.maxHeight.toFloat() / density) + layoutStyleBuilder.maxHeight = dimensionProto { + points = constraints.maxHeight.toFloat() / density + } if (constraints.hasFixedHeight) { - layoutStyleBuilder.height = - newDimensionProtoPoints(constraints.minHeight.toFloat() / density) + layoutStyleBuilder.height = dimensionProto { + points = constraints.minHeight.toFloat() / density + } // Layout implementation looks for width/height being set and then uses bounding box. - layoutStyleBuilder.bounding_box = - Optional.of( - Size( - layoutStyleBuilder.bounding_box.get().width, - constraints.minHeight.toFloat() / density, - ) - ) + layoutStyleBuilder.boundingBox = size { + width = layoutStyleBuilder.boundingBox.width + height = constraints.minHeight.toFloat() / density + } } - rootStyleBuilder.layout_style = Optional.of(layoutStyleBuilder.build()) + rootStyleBuilder.layoutStyle = layoutStyleBuilder.build() style = rootStyleBuilder.build() } @@ -308,7 +302,7 @@ fun SquooshRoot( val layoutManager = remember(docId) { SquooshLayout.newLayoutManager() } val layoutIdAllocator = remember(docId) { SquooshLayoutIdAllocator() } val layoutCache = remember(docId) { HashMap() } - val layoutValueCache = remember(docId) { HashMap() } + val layoutValueCache = remember(docId) { HashMap() } val keyEventTracker = remember(docId, rootNodeQuery) { KeyEventTracker() } DisposableEffect(docId, rootNodeQuery) { KeyInjectManager.addTracker(keyEventTracker) @@ -598,24 +592,22 @@ fun SquooshRoot( val scrollOffset = remember { mutableStateOf(Offset.Zero) } val orientation = - when ( - presentationRoot.view.scroll_info.getOrNull()?.overflow?.let { - overflowDirectionFromInt(it) - } - ) { - is OverflowDirection.VerticalScrolling -> Optional.of(Orientation.Vertical) - is OverflowDirection.HorizontalScrolling -> Optional.of(Orientation.Horizontal) - else -> Optional.empty() + when (presentationRoot.view.scrollInfoOrNull?.overflow) { + com.android.designcompose.definition.layout.OverflowDirection + .OVERFLOW_DIRECTION_VERTICAL_SCROLLING -> Orientation.Vertical + com.android.designcompose.definition.layout.OverflowDirection + .OVERFLOW_DIRECTION_HORIZONTAL_SCROLLING -> Orientation.Horizontal + else -> null } // If a scroll callback customization exists, call it when the scroll state changes val scrollStateChangedCallback = customizationContext.getScrollCallbacks(presentationRoot.view.name)?.scrollStateChanged val scrollState = rememberScrollableState { delta -> - when (orientation.get()) { + when (orientation) { Orientation.Vertical -> { // Bound the scroll offset to the area bounded by content_height - val contentHeight = presentationRoot.computedLayout?.content_height ?: 0F + val contentHeight = presentationRoot.computedLayout?.contentHeight ?: 0F val frameHeight = presentationRoot.computedLayout?.height ?: 0F val maxScroll = (contentHeight - frameHeight).coerceAtLeast(0F) val scrollValue = (scrollOffset.value.y + delta).coerceIn(0F, maxScroll) @@ -626,7 +618,7 @@ fun SquooshRoot( } Orientation.Horizontal -> { // Bound the scroll offset to the area bounded by content_width - val contentWidth = presentationRoot.computedLayout?.content_width ?: 0F + val contentWidth = presentationRoot.computedLayout?.contentWidth ?: 0F val frameWidth = presentationRoot.computedLayout?.width ?: 0F val maxScroll = (contentWidth - frameWidth).coerceAtLeast(0F) val scrollValue = (scrollOffset.value.x + delta).coerceIn(0F, maxScroll) @@ -635,13 +627,14 @@ fun SquooshRoot( DesignScrollState(scrollValue, frameWidth, contentWidth, maxScroll) ) } + else -> {} } delta } // Create a Modifier to handle scroll inputs if this is a scrollable view val scrollModifier = - if (isScrollComponent && orientation.isPresent) { + if (isScrollComponent && orientation != null) { // If a callback to get the scrollable state exists, call it val setScrollableStateCallback = customizationContext @@ -651,7 +644,7 @@ fun SquooshRoot( setScrollableStateCallback?.invoke(scrollState) } Modifier.scrollable( - orientation = orientation.get(), + orientation = orientation, reverseDirection = true, state = scrollState, ) @@ -738,22 +731,21 @@ fun SquooshRoot( // If there are press or click reactions, composition is needed var hasPressClick = customizationContext.getTapCallback(child.node.view) != null - child.node.view.reactions.forEach { - if (it.trigger.isPressOrClick()) hasPressClick = true - else if (it.trigger.isTimeout()) { + child.node.view.reactionsList.forEach { + if (it.trigger.hasPress() || it.trigger.hasClick()) hasPressClick = true + else if (it.trigger.hasAfterTimeout()) { // If there is a timeout trigger, execute the reaction in a suspend // function after the timeout - val timeoutTrigger = - it.trigger.get().trigger_type.get() as TriggerType.AfterTimeout - val timeoutMs = timeoutTrigger.value.timeout + val timeoutTrigger = it.trigger.afterTimeout + val timeoutMs = timeoutTrigger.timeout LaunchedEffect(child.node.view.id, it) { delay((timeoutMs * 1000.0).toLong()) interactionState.dispatch( - it.action.get(), + it.action, findTargetInstanceId( doc, child.parentComponents, - it.action.get(), + it.action, ), customizationContext.getKey(), null, @@ -848,7 +840,7 @@ private fun squooshLayoutMeasurePolicy( transitionRoot: SquooshResolvedNode?, transitionRootRemovalNodes: HashSet?, layoutCache: HashMap, - layoutValueCache: HashMap, + layoutValueCache: HashMap, layoutManager: SquooshLayoutManager, animationJob: AnimationValueHolder, animPlayTimeNanosState: MutableState>,