2022-12-25 11:07:45 +03:00
|
|
|
package center.sciprog.maps.features
|
|
|
|
|
2023-09-10 13:12:45 +03:00
|
|
|
import androidx.compose.runtime.*
|
2022-12-25 11:07:45 +03:00
|
|
|
import androidx.compose.ui.geometry.Offset
|
|
|
|
import androidx.compose.ui.unit.*
|
2022-12-28 14:41:46 +03:00
|
|
|
|
2023-09-10 13:12:45 +03:00
|
|
|
/**
|
|
|
|
* A state holder for current canvas size and view point. Allows transformation from coordinates to pixels and back
|
|
|
|
*/
|
|
|
|
public abstract class CanvasState<T: Any>(
|
|
|
|
public val viewConfig: ViewConfig<T>
|
|
|
|
){
|
2022-12-25 11:07:45 +03:00
|
|
|
public abstract val space: CoordinateSpace<T>
|
|
|
|
|
2022-12-28 21:02:23 +03:00
|
|
|
private var canvasSizeState: MutableState<DpSize?> = mutableStateOf(null)
|
|
|
|
private var viewPointState: MutableState<ViewPoint<T>?> = mutableStateOf(null)
|
2022-12-28 14:41:46 +03:00
|
|
|
|
|
|
|
public var canvasSize: DpSize
|
|
|
|
get() = canvasSizeState.value ?: DpSize(512.dp, 512.dp)
|
|
|
|
set(value) {
|
|
|
|
canvasSizeState.value = value
|
2023-09-10 13:12:45 +03:00
|
|
|
viewConfig.onCanvasSizeChange(value)
|
2022-12-28 14:41:46 +03:00
|
|
|
}
|
2022-12-25 11:07:45 +03:00
|
|
|
|
|
|
|
public var viewPoint: ViewPoint<T>
|
2022-12-28 14:41:46 +03:00
|
|
|
get() = viewPointState.value ?: space.defaultViewPoint
|
2022-12-25 11:07:45 +03:00
|
|
|
set(value) {
|
|
|
|
viewPointState.value = value
|
2023-09-10 13:12:45 +03:00
|
|
|
viewConfig.onViewChange(viewPoint)
|
2022-12-25 11:07:45 +03:00
|
|
|
}
|
|
|
|
|
2022-12-25 14:33:31 +03:00
|
|
|
public val zoom: Float get() = viewPoint.zoom
|
2022-12-25 11:07:45 +03:00
|
|
|
|
2022-12-28 14:41:46 +03:00
|
|
|
|
|
|
|
// Selection rectangle. If null - no selection
|
|
|
|
public var selectRect: DpRect? by mutableStateOf(null)
|
|
|
|
|
2023-09-10 13:12:45 +03:00
|
|
|
public abstract fun Rectangle<T>.toDpRect(): DpRect
|
|
|
|
|
|
|
|
public abstract fun ViewPoint<T>.moveBy(x: Dp, y: Dp): ViewPoint<T>
|
|
|
|
|
|
|
|
public abstract fun computeViewPoint(rectangle: Rectangle<T>): ViewPoint<T>
|
|
|
|
|
2022-12-25 11:07:45 +03:00
|
|
|
public abstract fun DpOffset.toCoordinates(): T
|
|
|
|
|
2023-01-06 12:36:02 +03:00
|
|
|
|
2022-12-25 11:07:45 +03:00
|
|
|
public abstract fun T.toDpOffset(): DpOffset
|
|
|
|
|
2023-09-10 13:12:45 +03:00
|
|
|
public fun toCoordinates(offset: Offset, density: Density): T = with(density){
|
|
|
|
val dpOffset = DpOffset(offset.x.toDp(), offset.y.toDp())
|
2023-01-06 12:36:02 +03:00
|
|
|
dpOffset.toCoordinates()
|
|
|
|
}
|
|
|
|
|
2023-09-10 13:12:45 +03:00
|
|
|
public fun toOffset(coordinates: T, density: Density): Offset = with(density){
|
|
|
|
val dpOffset = coordinates.toDpOffset()
|
|
|
|
return Offset(dpOffset.x.toPx(), dpOffset.y.toPx())
|
|
|
|
}
|
2022-12-25 11:07:45 +03:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public val DpRect.topLeft: DpOffset get() = DpOffset(left, top)
|
|
|
|
|
|
|
|
public val DpRect.bottomRight: DpOffset get() = DpOffset(right, bottom)
|