|
|
|
@ -1,12 +1,24 @@
|
|
|
|
|
package com.iqball.app.component
|
|
|
|
|
|
|
|
|
|
import androidx.compose.animation.animateContentSize
|
|
|
|
|
import androidx.compose.foundation.Image
|
|
|
|
|
import androidx.compose.foundation.background
|
|
|
|
|
import androidx.compose.foundation.layout.Box
|
|
|
|
|
import androidx.compose.foundation.layout.IntrinsicSize
|
|
|
|
|
import androidx.compose.foundation.layout.fillMaxSize
|
|
|
|
|
import androidx.compose.foundation.layout.height
|
|
|
|
|
import androidx.compose.foundation.layout.requiredHeight
|
|
|
|
|
import androidx.compose.foundation.layout.requiredWidth
|
|
|
|
|
import androidx.compose.foundation.layout.width
|
|
|
|
|
import androidx.compose.foundation.layout.wrapContentSize
|
|
|
|
|
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
|
import androidx.compose.runtime.MutableState
|
|
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
|
import androidx.compose.runtime.mutableStateMapOf
|
|
|
|
|
import androidx.compose.runtime.mutableStateOf
|
|
|
|
|
import androidx.compose.runtime.remember
|
|
|
|
|
import androidx.compose.runtime.setValue
|
|
|
|
|
import androidx.compose.ui.Alignment
|
|
|
|
|
import androidx.compose.ui.Modifier
|
|
|
|
@ -14,11 +26,13 @@ import androidx.compose.ui.draw.drawWithContent
|
|
|
|
|
import androidx.compose.ui.geometry.Offset
|
|
|
|
|
import androidx.compose.ui.geometry.Rect
|
|
|
|
|
import androidx.compose.ui.graphics.Color
|
|
|
|
|
import androidx.compose.ui.layout.boundsInParent
|
|
|
|
|
import androidx.compose.ui.layout.boundsInRoot
|
|
|
|
|
import androidx.compose.ui.layout.onGloballyPositioned
|
|
|
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
|
|
|
import androidx.compose.ui.res.painterResource
|
|
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
|
|
import arrow.core.getOrNone
|
|
|
|
|
import com.iqball.app.R
|
|
|
|
|
import com.iqball.app.domains.getPlayerInfo
|
|
|
|
|
import com.iqball.app.geo.toVector
|
|
|
|
@ -50,34 +64,42 @@ fun BasketCourt(
|
|
|
|
|
CourtType.Half -> R.drawable.half_court
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var courtArea by state.courtArea
|
|
|
|
|
val zoomState = state.zoomState
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Box(
|
|
|
|
|
modifier = modifier,
|
|
|
|
|
modifier = modifier
|
|
|
|
|
.background(Color.LightGray)
|
|
|
|
|
.fillMaxSize(),
|
|
|
|
|
contentAlignment = Alignment.Center
|
|
|
|
|
) {
|
|
|
|
|
Box(
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.width(IntrinsicSize.Min)
|
|
|
|
|
.zoomable(zoomState),
|
|
|
|
|
contentAlignment = Alignment.Center,
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
Image(
|
|
|
|
|
painter = painterResource(id = courtImg),
|
|
|
|
|
contentDescription = "court",
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.background(Color.White)
|
|
|
|
|
.onGloballyPositioned {
|
|
|
|
|
if (courtArea == Rect.Zero)
|
|
|
|
|
courtArea = it.boundsInRoot()
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
CourtContent(
|
|
|
|
|
courtAreaState = state.courtArea,
|
|
|
|
|
courtArea = courtArea,
|
|
|
|
|
content = content,
|
|
|
|
|
offsets = state.stepComponentsOffsets,
|
|
|
|
|
isFromParent = false
|
|
|
|
|
)
|
|
|
|
|
if (parentContent != null) {
|
|
|
|
|
CourtContent(
|
|
|
|
|
courtAreaState = state.courtArea,
|
|
|
|
|
courtArea = courtArea,
|
|
|
|
|
content = parentContent,
|
|
|
|
|
offsets = state.parentComponentsOffsets,
|
|
|
|
|
isFromParent = true
|
|
|
|
@ -89,26 +111,31 @@ fun BasketCourt(
|
|
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
|
private fun CourtContent(
|
|
|
|
|
courtAreaState: MutableState<Rect>,
|
|
|
|
|
courtArea: Rect,
|
|
|
|
|
content: StepContent,
|
|
|
|
|
offsets: MutableMap<ComponentId, Offset>,
|
|
|
|
|
isFromParent: Boolean
|
|
|
|
|
) {
|
|
|
|
|
var courtArea by courtAreaState
|
|
|
|
|
|
|
|
|
|
val playersPixelsRadius = LocalDensity.current.run { PlayerPieceDiameterDp.dp.toPx() / 2 }
|
|
|
|
|
|
|
|
|
|
val width = LocalDensity.current.run { courtArea.width.toDp() }
|
|
|
|
|
val height = LocalDensity.current.run { courtArea.height.toDp() }
|
|
|
|
|
|
|
|
|
|
Box(
|
|
|
|
|
modifier = Modifier
|
|
|
|
|
.fillMaxSize()
|
|
|
|
|
.onGloballyPositioned {
|
|
|
|
|
if (courtArea == Rect.Zero)
|
|
|
|
|
courtArea = it.boundsInRoot()
|
|
|
|
|
}
|
|
|
|
|
.requiredWidth(width)
|
|
|
|
|
.requiredHeight(height)
|
|
|
|
|
.drawWithContent {
|
|
|
|
|
val relativeOffsets =
|
|
|
|
|
offsets.mapValues { (it.value - courtArea.topLeft).toVector() }
|
|
|
|
|
drawActions(this, content, relativeOffsets, courtArea, playersPixelsRadius, if (isFromParent) Color.Gray else Color.Black)
|
|
|
|
|
offsets.mapValues { (it.value).toVector() }
|
|
|
|
|
drawActions(
|
|
|
|
|
this,
|
|
|
|
|
content,
|
|
|
|
|
relativeOffsets,
|
|
|
|
|
courtArea,
|
|
|
|
|
playersPixelsRadius,
|
|
|
|
|
if (isFromParent) Color.Gray else Color.Black
|
|
|
|
|
)
|
|
|
|
|
drawContent()
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
@ -117,8 +144,8 @@ private fun CourtContent(
|
|
|
|
|
for (component in content.components) {
|
|
|
|
|
val componentModifier = Modifier
|
|
|
|
|
.onGloballyPositioned {
|
|
|
|
|
if (!offsets.containsKey(component.id))
|
|
|
|
|
offsets[component.id] = it.boundsInRoot().center
|
|
|
|
|
if (!offsets.getOrNone(component.id).isSome { it != Offset.Zero })
|
|
|
|
|
offsets[component.id] = it.boundsInParent().center
|
|
|
|
|
}
|
|
|
|
|
when (component) {
|
|
|
|
|
is PlayerLike -> {
|
|
|
|
|