133 lines
4.3 KiB
Kotlin
Raw Normal View History

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)
)
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)
}