Fix view change listener

This commit is contained in:
Alexander Nozik 2022-12-28 20:03:08 +03:00
parent 15ad690129
commit d34c5099f6
7 changed files with 23 additions and 64 deletions

View File

@ -5,6 +5,7 @@ import androidx.compose.material.icons.filled.Home
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PointMode import androidx.compose.ui.graphics.PointMode
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
@ -93,10 +94,10 @@ fun App() {
it.copy(color = Color(Random.nextFloat(), Random.nextFloat(), Random.nextFloat())) it.copy(color = Color(Random.nextFloat(), Random.nextFloat(), Random.nextFloat()))
} }
// draw(position = pointThree) { draw(position = pointThree) {
// drawLine(start = Offset(-10f, -10f), end = Offset(10f, 10f), color = Color.Red) drawLine(start = Offset(-10f, -10f), end = Offset(10f, 10f), color = Color.Red)
// drawLine(start = Offset(-10f, 10f), end = Offset(10f, -10f), color = Color.Red) drawLine(start = Offset(-10f, 10f), end = Offset(10f, -10f), color = Color.Red)
// } }
arc(pointOne, 10.0.kilometers, (PI / 4).radians, -Angle.pi / 2) arc(pointOne, 10.0.kilometers, (PI / 4).radians, -Angle.pi / 2)

View File

@ -5,10 +5,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import center.sciprog.maps.coordinates.Gmc import center.sciprog.maps.coordinates.Gmc
import center.sciprog.maps.features.FeatureCollection import center.sciprog.maps.features.*
import center.sciprog.maps.features.FeatureId
import center.sciprog.maps.features.Rectangle
import center.sciprog.maps.features.ViewConfig
@Composable @Composable
@ -31,7 +28,7 @@ public fun MapView(
modifier: Modifier = Modifier.fillMaxSize(), modifier: Modifier = Modifier.fillMaxSize(),
) { ) {
val featuresState = remember(featureMap) { val featureState = remember(featureMap) {
FeatureCollection.build(WebMercatorSpace) { FeatureCollection.build(WebMercatorSpace) {
featureMap.forEach { feature(it.key.id, it.value) } featureMap.forEach { feature(it.key.id, it.value) }
} }
@ -40,12 +37,11 @@ public fun MapView(
val mapState: MapViewScope = rememberMapState( val mapState: MapViewScope = rememberMapState(
mapTileProvider, mapTileProvider,
config, config,
featuresState.features.values,
initialViewPoint = initialViewPoint, initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle, initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(WebMercatorSpace, 1f),
) )
MapView(mapState, featuresState, modifier) MapView(mapState, featureState, modifier)
} }
/** /**
@ -66,12 +62,12 @@ public fun MapView(
) { ) {
val featureState = FeatureCollection.remember(WebMercatorSpace, buildFeatures) val featureState = FeatureCollection.remember(WebMercatorSpace, buildFeatures)
val mapState: MapViewScope = rememberMapState( val mapState: MapViewScope = rememberMapState(
mapTileProvider, mapTileProvider,
config, config,
featureState.features.values,
initialViewPoint = initialViewPoint, initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle, initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(WebMercatorSpace, 1f),
) )
MapView(mapState, featureState, modifier) MapView(mapState, featureState, modifier)

View File

@ -81,7 +81,6 @@ public class MapViewScope internal constructor(
internal fun rememberMapState( internal fun rememberMapState(
mapTileProvider: MapTileProvider, mapTileProvider: MapTileProvider,
config: ViewConfig<Gmc>, config: ViewConfig<Gmc>,
features: Collection<Feature<Gmc>> = emptyList(),
initialViewPoint: MapViewPoint? = null, initialViewPoint: MapViewPoint? = null,
initialRectangle: Rectangle<Gmc>? = null, initialRectangle: Rectangle<Gmc>? = null,
): MapViewScope = remember { ): MapViewScope = remember {
@ -90,10 +89,6 @@ internal fun rememberMapState(
mapState.viewPoint = initialViewPoint mapState.viewPoint = initialViewPoint
} else if (initialRectangle != null) { } else if (initialRectangle != null) {
mapState.viewPoint = mapState.computeViewPoint(initialRectangle) mapState.viewPoint = mapState.computeViewPoint(initialRectangle)
} else {
features.computeBoundingBox(WebMercatorSpace, 1f)?.let {
mapState.viewPoint = mapState.computeViewPoint(it)
}
} }
} }
} }

View File

@ -30,6 +30,7 @@ public abstract class CoordinateViewScope<T : Any>(
get() = viewPointState.value ?: space.defaultViewPoint get() = viewPointState.value ?: space.defaultViewPoint
set(value) { set(value) {
viewPointState.value = value viewPointState.value = value
config.onViewChange(viewPoint)
} }
public val zoom: Float get() = viewPoint.zoom public val zoom: Float get() = viewPoint.zoom

View File

@ -93,12 +93,13 @@ public fun <T : Any> Modifier.mapControls(
val dragResult = config.dragHandle?.handle(event, dragStart, dragEnd) val dragResult = config.dragHandle?.handle(event, dragStart, dragEnd)
if (dragResult?.handleNext == false) return@drag if (dragResult?.handleNext == false) return@drag
features.values.filterIsInstance<DraggableFeature<T>>() features.values.asSequence()
.filterIsInstance<DraggableFeature<T>>()
.sortedByDescending { it.z } .sortedByDescending { it.z }
.forEach { draggableFeature -> .mapNotNull {
draggableFeature.attributes[DraggableAttribute]?.let { handler-> it.attributes[DraggableAttribute]
if (!handler.handle(event, dragStart, dragEnd).handleNext) return@drag }.forEach { handler ->
} if (!handler.handle(event, dragStart, dragEnd).handleNext) return@drag
} }
} }

View File

@ -48,7 +48,6 @@ class XYViewScope(
@Composable @Composable
public fun rememberMapState( public fun rememberMapState(
config: ViewConfig<XY>, config: ViewConfig<XY>,
features: Collection<Feature<XY>> = emptyList(),
initialViewPoint: ViewPoint<XY>? = null, initialViewPoint: ViewPoint<XY>? = null,
initialRectangle: Rectangle<XY>? = null, initialRectangle: Rectangle<XY>? = null,
): XYViewScope = remember { ): XYViewScope = remember {
@ -57,10 +56,6 @@ public fun rememberMapState(
mapState.viewPoint = initialViewPoint mapState.viewPoint = initialViewPoint
} else if (initialRectangle != null) { } else if (initialRectangle != null) {
mapState.viewPoint = mapState.computeViewPoint(initialRectangle) mapState.viewPoint = mapState.computeViewPoint(initialRectangle)
} else {
features.computeBoundingBox(XYCoordinateSpace, 1f)?.let {
mapState.viewPoint = mapState.computeViewPoint(it)
}
} }
} }
} }

View File

@ -30,7 +30,7 @@ public fun SchemeView(
featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() } featuresState.features.values.filterIsInstance<PainterFeature<XY>>().associateWith { it.getPainter() }
} }
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) { Canvas(modifier = modifier.mapControls(state, featuresState.features).fillMaxSize()) {
if (canvasSize != size.toDpSize()) { if (canvasSize != size.toDpSize()) {
canvasSize = size.toDpSize() canvasSize = size.toDpSize()
@ -87,7 +87,7 @@ public fun SchemeView(
) { ) {
val featuresState = key(featureMap) { val featureState = key(featureMap) {
FeatureCollection.build(XYCoordinateSpace) { FeatureCollection.build(XYCoordinateSpace) {
featureMap.forEach { feature(it.key.id, it.value) } featureMap.forEach { feature(it.key.id, it.value) }
} }
@ -95,12 +95,11 @@ public fun SchemeView(
val state = rememberMapState( val state = rememberMapState(
config, config,
featuresState.features.values,
initialViewPoint = initialViewPoint, initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle, initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(XYCoordinateSpace, 1f),
) )
SchemeView(state, featuresState, modifier) SchemeView(state, featureState, modifier)
} }
/** /**
@ -121,37 +120,8 @@ public fun SchemeView(
val featureState = FeatureCollection.remember(XYCoordinateSpace, buildFeatures) val featureState = FeatureCollection.remember(XYCoordinateSpace, buildFeatures)
val mapState: XYViewScope = rememberMapState( val mapState: XYViewScope = rememberMapState(
config, config,
featureState.features.values,
initialViewPoint = initialViewPoint, initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle, initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(XYCoordinateSpace, 1f),
)
val featureDrag: DragHandle<XY> = DragHandle.withPrimaryButton { event, start, end ->
featureState.forEachWithAttribute(DraggableAttribute) { _, handle ->
@Suppress("UNCHECKED_CAST")
(handle as DragHandle<XY>)
.handle(event, start, end)
.takeIf { !it.handleNext }
?.let {
//we expect it already have no bypass
return@withPrimaryButton it
}
}
//bypass
DragResult(end)
}
val featureClick: ClickListener<XY> = ClickListener.withPrimaryButton { event, click ->
featureState.forEachWithAttribute(ClickableListenerAttribute) { _, handle ->
@Suppress("UNCHECKED_CAST")
(handle as ClickListener<XY>).handle(event, click)
config.onClick?.handle(event, click)
}
}
val newConfig = config.copy(
dragHandle = config.dragHandle?.let { DragHandle.combine(featureDrag, it) } ?: featureDrag,
onClick = featureClick
) )
SchemeView(mapState, featureState, modifier) SchemeView(mapState, featureState, modifier)