Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert SquooshRoot.kt #1938

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,43 +79,36 @@ 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
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
Expand Down Expand Up @@ -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()
}

Expand Down Expand Up @@ -308,7 +302,7 @@ fun SquooshRoot(
val layoutManager = remember(docId) { SquooshLayout.newLayoutManager() }
val layoutIdAllocator = remember(docId) { SquooshLayoutIdAllocator() }
val layoutCache = remember(docId) { HashMap<Int, Int>() }
val layoutValueCache = remember(docId) { HashMap<Int, Layout>() }
val layoutValueCache = remember(docId) { HashMap<Int, LayoutChangedResponse.Layout>() }
val keyEventTracker = remember(docId, rootNodeQuery) { KeyEventTracker() }
DisposableEffect(docId, rootNodeQuery) {
KeyInjectManager.addTracker(keyEventTracker)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -651,7 +644,7 @@ fun SquooshRoot(
setScrollableStateCallback?.invoke(scrollState)
}
Modifier.scrollable(
orientation = orientation.get(),
orientation = orientation,
reverseDirection = true,
state = scrollState,
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -848,7 +840,7 @@ private fun squooshLayoutMeasurePolicy(
transitionRoot: SquooshResolvedNode?,
transitionRootRemovalNodes: HashSet<Int>?,
layoutCache: HashMap<Int, Int>,
layoutValueCache: HashMap<Int, Layout>,
layoutValueCache: HashMap<Int, LayoutChangedResponse.Layout>,
layoutManager: SquooshLayoutManager,
animationJob: AnimationValueHolder,
animPlayTimeNanosState: MutableState<Map<Int, Long>>,
Expand Down
Loading