Fixed multi-drag issue. Added demo for bounded drag.
This commit is contained in:
parent
5561a4188c
commit
5448929d31
@ -45,8 +45,6 @@ fun App() {
|
||||
val pointTwo = 55.929444 to 37.518434
|
||||
val pointThree = 60.929444 to 37.518434
|
||||
|
||||
val dragPoint = 55.744 to 37.614
|
||||
|
||||
MapView(
|
||||
mapTileProvider = mapTileProvider,
|
||||
// initialViewPoint = MapViewPoint(
|
||||
@ -65,7 +63,27 @@ fun App() {
|
||||
|
||||
image(pointOne, Icons.Filled.Home)
|
||||
|
||||
rectangle(dragPoint, id = "dragMe", size = DpSize(10.dp, 10.dp)).draggable()
|
||||
var drag1 = Gmc.ofDegrees(55.744, 37.614)
|
||||
|
||||
var drag2 = Gmc.ofDegrees(55.8, 37.5)
|
||||
|
||||
fun updateLine() {
|
||||
line(drag1, drag2, id = "connection", color = Color.Magenta)
|
||||
}
|
||||
|
||||
rectangle(drag1, size = DpSize(10.dp, 10.dp)).draggable { _, _, end ->
|
||||
drag1 = end.focus
|
||||
updateLine()
|
||||
true
|
||||
}
|
||||
|
||||
rectangle(drag2, size = DpSize(10.dp, 10.dp)).draggable { _, _, end ->
|
||||
drag2 = end.focus
|
||||
updateLine()
|
||||
true
|
||||
}
|
||||
|
||||
updateLine()
|
||||
|
||||
points(
|
||||
points = listOf(
|
||||
|
@ -18,10 +18,15 @@ import kotlin.math.floor
|
||||
public interface MapFeature {
|
||||
public val zoomRange: IntRange
|
||||
public fun getBoundingBox(zoom: Double): GmcRectangle?
|
||||
|
||||
}
|
||||
|
||||
public interface DraggableMapFeature : MapFeature {
|
||||
public interface SelectableMapFeature : MapFeature {
|
||||
public operator fun contains(point: MapViewPoint): Boolean = getBoundingBox(point.zoom)?.let {
|
||||
point.focus in it
|
||||
} ?: false
|
||||
}
|
||||
|
||||
public interface DraggableMapFeature : SelectableMapFeature {
|
||||
public fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature
|
||||
}
|
||||
|
||||
@ -118,8 +123,12 @@ public class MapLineFeature(
|
||||
public val b: GeodeticMapCoordinates,
|
||||
override val zoomRange: IntRange = defaultZoomRange,
|
||||
public val color: Color = Color.Red,
|
||||
) : MapFeature {
|
||||
) : SelectableMapFeature {
|
||||
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(a, b)
|
||||
|
||||
override fun contains(point: MapViewPoint): Boolean {
|
||||
return super.contains(point)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,14 +18,14 @@ public object DraggableAttribute : MapFeaturesState.Attribute<DragHandle>
|
||||
|
||||
public class MapFeaturesState internal constructor(
|
||||
private val features: MutableMap<FeatureId, MapFeature>,
|
||||
private val attributes: MutableMap<FeatureId, SnapshotStateMap<Attribute<out Any?>, in Any?>>,
|
||||
@PublishedApi internal val attributes: MutableMap<FeatureId, SnapshotStateMap<Attribute<out Any?>, in Any?>>,
|
||||
) {
|
||||
public interface Attribute<T>
|
||||
|
||||
//TODO use context receiver for that
|
||||
public fun FeatureId.draggable(
|
||||
//TODO add constraints
|
||||
callback: DragHandle = DragHandle.BYPASS
|
||||
callback: DragHandle = DragHandle.BYPASS,
|
||||
) {
|
||||
val handle = DragHandle.withPrimaryButton { event, start, end ->
|
||||
val feature = features[this] as? DraggableMapFeature ?: return@withPrimaryButton true
|
||||
@ -72,7 +72,7 @@ public class MapFeaturesState internal constructor(
|
||||
// }.keys
|
||||
// }
|
||||
|
||||
public fun <T> forEachWithAttribute(key: Attribute<T>, block: (id: FeatureId, attributeValue: T) -> Unit) {
|
||||
public inline fun <T> forEachWithAttribute(key: Attribute<T>, block: (id: FeatureId, attributeValue: T) -> Unit) {
|
||||
attributes.forEach { (id, attributeMap) ->
|
||||
attributeMap[key]?.let {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@ -126,6 +126,16 @@ public fun MapFeaturesState.circle(
|
||||
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
|
||||
)
|
||||
|
||||
public fun MapFeaturesState.rectangle(
|
||||
centerCoordinates: Gmc,
|
||||
zoomRange: IntRange = defaultZoomRange,
|
||||
size: DpSize = DpSize(5.dp, 5.dp),
|
||||
color: Color = Color.Red,
|
||||
id: FeatureId? = null,
|
||||
): FeatureId = addFeature(
|
||||
id, MapRectangleFeature(centerCoordinates, zoomRange, size, color)
|
||||
)
|
||||
|
||||
public fun MapFeaturesState.rectangle(
|
||||
centerCoordinates: Pair<Double, Double>,
|
||||
zoomRange: IntRange = defaultZoomRange,
|
||||
|
@ -146,11 +146,10 @@ public fun MapView(
|
||||
}
|
||||
|
||||
val featureDrag: DragHandle = DragHandle.withPrimaryButton { event, start, end ->
|
||||
var bypass = true
|
||||
featureState.forEachWithAttribute(DraggableAttribute) { _, handle ->
|
||||
bypass = bypass and handle.handle(event, start, end)
|
||||
if(!handle.handle(event, start, end)) return@withPrimaryButton false
|
||||
}
|
||||
bypass
|
||||
true
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,20 +116,17 @@ public actual fun MapView(
|
||||
val dpEnd = dragChange.position.toDpOffset()
|
||||
|
||||
//apply drag handle and check if it prohibits the drag even propagation
|
||||
if (
|
||||
!config.dragHandle.handle(
|
||||
if (selectionStart == null && !config.dragHandle.handle(
|
||||
event,
|
||||
MapViewPoint(dpStart.toGeodetic(), viewPoint.zoom),
|
||||
MapViewPoint(dpEnd.toGeodetic(), viewPoint.zoom)
|
||||
)
|
||||
) {
|
||||
//clear selection just in case
|
||||
selectionStart = null
|
||||
return@drag
|
||||
}
|
||||
|
||||
if (event.buttons.isPrimaryPressed) {
|
||||
//Evaluating selection frame
|
||||
//If selection process is started, modify the frame
|
||||
selectionStart?.let { start ->
|
||||
val offset = dragChange.position
|
||||
selectRect = Rect(
|
||||
@ -141,8 +138,8 @@ public actual fun MapView(
|
||||
return@drag
|
||||
}
|
||||
|
||||
config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom), event)
|
||||
|
||||
// config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom), event)
|
||||
//If no selection, drag map
|
||||
setViewPoint(
|
||||
viewPoint.move(
|
||||
-dragAmount.x.toDp().value / tileScale,
|
||||
|
Loading…
Reference in New Issue
Block a user