2022-07-23 11:24:37 +03:00
|
|
|
package center.sciprog.maps.scheme
|
2022-07-23 10:27:58 +03:00
|
|
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
import androidx.compose.runtime.mutableStateMapOf
|
|
|
|
import androidx.compose.runtime.snapshots.SnapshotStateMap
|
|
|
|
import androidx.compose.ui.geometry.Size
|
|
|
|
import androidx.compose.ui.graphics.Color
|
|
|
|
import androidx.compose.ui.graphics.drawscope.DrawScope
|
|
|
|
import androidx.compose.ui.graphics.painter.Painter
|
|
|
|
import androidx.compose.ui.graphics.vector.ImageVector
|
|
|
|
import androidx.compose.ui.unit.DpSize
|
|
|
|
import androidx.compose.ui.unit.dp
|
2022-07-23 11:24:37 +03:00
|
|
|
import center.sciprog.maps.scheme.SchemeFeature.Companion.defaultScaleRange
|
2022-07-23 10:27:58 +03:00
|
|
|
|
|
|
|
typealias FeatureId = String
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
interface SchemeFeatureBuilder {
|
2022-07-23 10:27:58 +03:00
|
|
|
fun addFeature(id: FeatureId?, feature: SchemeFeature): FeatureId
|
|
|
|
|
|
|
|
fun build(): SnapshotStateMap<FeatureId, SchemeFeature>
|
|
|
|
}
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
internal class SchemeFeatureBuilderImpl(
|
|
|
|
initialFeatures: Map<FeatureId, SchemeFeature>,
|
|
|
|
) : SchemeFeatureBuilder {
|
2022-07-23 10:27:58 +03:00
|
|
|
|
|
|
|
private val content: SnapshotStateMap<FeatureId, SchemeFeature> =
|
|
|
|
mutableStateMapOf<FeatureId, SchemeFeature>().apply {
|
|
|
|
putAll(initialFeatures)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun generateID(feature: SchemeFeature): FeatureId = "@feature[${feature.hashCode().toUInt()}]"
|
|
|
|
|
|
|
|
override fun addFeature(id: FeatureId?, feature: SchemeFeature): FeatureId {
|
|
|
|
val safeId = id ?: generateID(feature)
|
|
|
|
content[id ?: generateID(feature)] = feature
|
|
|
|
return safeId
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun build(): SnapshotStateMap<FeatureId, SchemeFeature> = content
|
|
|
|
}
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.background(
|
2022-07-23 10:27:58 +03:00
|
|
|
painter: Painter,
|
|
|
|
box: SchemeCoordinateBox,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
): FeatureId = addFeature(
|
|
|
|
id,
|
|
|
|
SchemeBackgroundFeature(box, painter)
|
|
|
|
)
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.background(
|
2022-07-23 10:27:58 +03:00
|
|
|
painter: Painter,
|
|
|
|
size: Size = painter.intrinsicSize,
|
|
|
|
offset: SchemeCoordinates = SchemeCoordinates(0f, 0f),
|
|
|
|
id: FeatureId? = null,
|
|
|
|
): FeatureId {
|
|
|
|
val box = SchemeCoordinateBox(
|
|
|
|
offset,
|
|
|
|
SchemeCoordinates(size.width + offset.x, size.height + offset.y)
|
|
|
|
)
|
|
|
|
return background(painter, box, id)
|
|
|
|
}
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.circle(
|
2022-07-23 10:27:58 +03:00
|
|
|
center: SchemeCoordinates,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
size: Float = 5f,
|
|
|
|
color: Color = Color.Red,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(
|
|
|
|
id, SchemeCircleFeature(center, scaleRange, size, color)
|
|
|
|
)
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.circle(
|
2022-07-23 10:27:58 +03:00
|
|
|
centerCoordinates: Pair<Number, Number>,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
size: Float = 5f,
|
|
|
|
color: Color = Color.Red,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(
|
|
|
|
id, SchemeCircleFeature(centerCoordinates.toCoordinates(), scaleRange, size, color)
|
|
|
|
)
|
|
|
|
|
2022-07-23 18:37:14 +03:00
|
|
|
fun SchemeFeatureBuilder.draw(
|
2022-07-23 10:27:58 +03:00
|
|
|
position: Pair<Number, Number>,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
drawFeature: DrawScope.() -> Unit,
|
|
|
|
) = addFeature(id, SchemeDrawFeature(position.toCoordinates(), scaleRange, drawFeature))
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.line(
|
2022-07-23 10:27:58 +03:00
|
|
|
aCoordinates: Pair<Number, Number>,
|
|
|
|
bCoordinates: Pair<Number, Number>,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
color: Color = Color.Red,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(id, SchemeLineFeature(aCoordinates.toCoordinates(), bCoordinates.toCoordinates(), scaleRange, color))
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.text(
|
2022-07-23 10:27:58 +03:00
|
|
|
position: SchemeCoordinates,
|
|
|
|
text: String,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
color: Color = Color.Red,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(id, SchemeTextFeature(position, text, scaleRange, color))
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.text(
|
2022-07-23 10:27:58 +03:00
|
|
|
position: Pair<Number, Number>,
|
|
|
|
text: String,
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
color: Color = Color.Red,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(id, SchemeTextFeature(position.toCoordinates(), text, scaleRange, color))
|
|
|
|
|
|
|
|
@Composable
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.image(
|
2022-07-23 10:27:58 +03:00
|
|
|
position: Pair<Number, Number>,
|
|
|
|
image: ImageVector,
|
|
|
|
size: DpSize = DpSize(20.dp, 20.dp),
|
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
id: FeatureId? = null,
|
|
|
|
) = addFeature(id, SchemeVectorImageFeature(position.toCoordinates(), image, size, scaleRange))
|
|
|
|
|
2022-07-23 13:49:47 +03:00
|
|
|
fun SchemeFeatureBuilder.group(
|
2022-07-23 10:27:58 +03:00
|
|
|
scaleRange: FloatRange = defaultScaleRange,
|
|
|
|
id: FeatureId? = null,
|
2022-07-23 13:49:47 +03:00
|
|
|
builder: SchemeFeatureBuilder.() -> Unit,
|
2022-07-23 10:27:58 +03:00
|
|
|
): FeatureId {
|
2022-07-23 13:49:47 +03:00
|
|
|
val map = SchemeFeatureBuilderImpl(emptyMap()).apply(builder).build()
|
2022-07-23 10:27:58 +03:00
|
|
|
val feature = SchemeFeatureGroup(map, scaleRange)
|
|
|
|
return addFeature(id, feature)
|
|
|
|
}
|