package center.sciprog.maps.scheme import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.DpRect import androidx.compose.ui.unit.dp import center.sciprog.maps.features.* import kotlin.math.min class XYViewScope( config: ViewConfig, ) : CoordinateViewScope(config) { override val space: CoordinateSpace get() = XYCoordinateSpace override fun DpOffset.toCoordinates(): XY = XY( (x - canvasSize.width / 2).value / viewPoint.zoom + viewPoint.focus.x, (canvasSize.height / 2 - y).value / viewPoint.zoom + viewPoint.focus.y ) override fun XY.toDpOffset(): DpOffset = DpOffset( (canvasSize.width / 2 + (x.dp - viewPoint.focus.x.dp) * viewPoint.zoom), (canvasSize.height / 2 + (viewPoint.focus.y.dp - y.dp) * viewPoint.zoom) ) override fun computeViewPoint(rectangle: Rectangle): ViewPoint { val scale = min( canvasSize.width.value / rectangle.width, canvasSize.height.value / rectangle.height ) return XYViewPoint(rectangle.center, scale) } override fun ViewPoint.moveBy(x: Dp, y: Dp): ViewPoint { val newCoordinates = XY(focus.x + x.value / zoom, focus.y + y.value / zoom) return XYViewPoint(newCoordinates, zoom) } override fun Rectangle.toDpRect(): DpRect { val topLeft = leftTop.toDpOffset() val bottomRight = rightBottom.toDpOffset() return DpRect(topLeft.x, topLeft.y, bottomRight.x, bottomRight.y) } companion object{ @Composable public fun remember( config: ViewConfig = ViewConfig(), initialViewPoint: ViewPoint? = null, initialRectangle: Rectangle? = null, ): XYViewScope = remember { XYViewScope(config).also { mapState-> if (initialViewPoint != null) { mapState.viewPoint = initialViewPoint } else if (initialRectangle != null) { mapState.viewPoint = mapState.computeViewPoint(initialRectangle) } } } } }