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.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PointMode
import androidx.compose.ui.unit.DpSize
@ -93,10 +94,10 @@ fun App() {
it.copy(color = Color(Random.nextFloat(), Random.nextFloat(), Random.nextFloat()))
}
// 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)
// }
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)
}
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.ui.Modifier
import center.sciprog.maps.coordinates.Gmc
import center.sciprog.maps.features.FeatureCollection
import center.sciprog.maps.features.FeatureId
import center.sciprog.maps.features.Rectangle
import center.sciprog.maps.features.ViewConfig
import center.sciprog.maps.features.*
@Composable
@ -31,7 +28,7 @@ public fun MapView(
modifier: Modifier = Modifier.fillMaxSize(),
) {
val featuresState = remember(featureMap) {
val featureState = remember(featureMap) {
FeatureCollection.build(WebMercatorSpace) {
featureMap.forEach { feature(it.key.id, it.value) }
}
@ -40,12 +37,11 @@ public fun MapView(
val mapState: MapViewScope = rememberMapState(
mapTileProvider,
config,
featuresState.features.values,
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 mapState: MapViewScope = rememberMapState(
mapTileProvider,
config,
featureState.features.values,
initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle,
initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(WebMercatorSpace, 1f),
)
MapView(mapState, featureState, modifier)

View File

@ -81,7 +81,6 @@ public class MapViewScope internal constructor(
internal fun rememberMapState(
mapTileProvider: MapTileProvider,
config: ViewConfig<Gmc>,
features: Collection<Feature<Gmc>> = emptyList(),
initialViewPoint: MapViewPoint? = null,
initialRectangle: Rectangle<Gmc>? = null,
): MapViewScope = remember {
@ -90,10 +89,6 @@ internal fun rememberMapState(
mapState.viewPoint = initialViewPoint
} else if (initialRectangle != null) {
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
set(value) {
viewPointState.value = value
config.onViewChange(viewPoint)
}
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)
if (dragResult?.handleNext == false) return@drag
features.values.filterIsInstance<DraggableFeature<T>>()
features.values.asSequence()
.filterIsInstance<DraggableFeature<T>>()
.sortedByDescending { it.z }
.forEach { draggableFeature ->
draggableFeature.attributes[DraggableAttribute]?.let { handler->
if (!handler.handle(event, dragStart, dragEnd).handleNext) return@drag
}
.mapNotNull {
it.attributes[DraggableAttribute]
}.forEach { handler ->
if (!handler.handle(event, dragStart, dragEnd).handleNext) return@drag
}
}

View File

@ -48,7 +48,6 @@ class XYViewScope(
@Composable
public fun rememberMapState(
config: ViewConfig<XY>,
features: Collection<Feature<XY>> = emptyList(),
initialViewPoint: ViewPoint<XY>? = null,
initialRectangle: Rectangle<XY>? = null,
): XYViewScope = remember {
@ -57,10 +56,6 @@ public fun rememberMapState(
mapState.viewPoint = initialViewPoint
} else if (initialRectangle != null) {
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() }
}
Canvas(modifier = modifier.mapControls(state).fillMaxSize()) {
Canvas(modifier = modifier.mapControls(state, featuresState.features).fillMaxSize()) {
if (canvasSize != size.toDpSize()) {
canvasSize = size.toDpSize()
@ -87,7 +87,7 @@ public fun SchemeView(
) {
val featuresState = key(featureMap) {
val featureState = key(featureMap) {
FeatureCollection.build(XYCoordinateSpace) {
featureMap.forEach { feature(it.key.id, it.value) }
}
@ -95,12 +95,11 @@ public fun SchemeView(
val state = rememberMapState(
config,
featuresState.features.values,
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 mapState: XYViewScope = rememberMapState(
config,
featureState.features.values,
initialViewPoint = initialViewPoint,
initialRectangle = initialRectangle,
)
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
initialRectangle = initialRectangle ?: featureState.features.values.computeBoundingBox(XYCoordinateSpace, 1f),
)
SchemeView(mapState, featureState, modifier)