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 pointTwo = 55.929444 to 37.518434
|
||||||
val pointThree = 60.929444 to 37.518434
|
val pointThree = 60.929444 to 37.518434
|
||||||
|
|
||||||
val dragPoint = 55.744 to 37.614
|
|
||||||
|
|
||||||
MapView(
|
MapView(
|
||||||
mapTileProvider = mapTileProvider,
|
mapTileProvider = mapTileProvider,
|
||||||
// initialViewPoint = MapViewPoint(
|
// initialViewPoint = MapViewPoint(
|
||||||
@ -65,7 +63,27 @@ fun App() {
|
|||||||
|
|
||||||
image(pointOne, Icons.Filled.Home)
|
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(
|
||||||
points = listOf(
|
points = listOf(
|
||||||
|
@ -18,10 +18,15 @@ import kotlin.math.floor
|
|||||||
public interface MapFeature {
|
public interface MapFeature {
|
||||||
public val zoomRange: IntRange
|
public val zoomRange: IntRange
|
||||||
public fun getBoundingBox(zoom: Double): GmcRectangle?
|
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
|
public fun withCoordinates(newCoordinates: GeodeticMapCoordinates): MapFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +123,12 @@ public class MapLineFeature(
|
|||||||
public val b: GeodeticMapCoordinates,
|
public val b: GeodeticMapCoordinates,
|
||||||
override val zoomRange: IntRange = defaultZoomRange,
|
override val zoomRange: IntRange = defaultZoomRange,
|
||||||
public val color: Color = Color.Red,
|
public val color: Color = Color.Red,
|
||||||
) : MapFeature {
|
) : SelectableMapFeature {
|
||||||
override fun getBoundingBox(zoom: Double): GmcRectangle = GmcRectangle(a, b)
|
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(
|
public class MapFeaturesState internal constructor(
|
||||||
private val features: MutableMap<FeatureId, MapFeature>,
|
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>
|
public interface Attribute<T>
|
||||||
|
|
||||||
//TODO use context receiver for that
|
//TODO use context receiver for that
|
||||||
public fun FeatureId.draggable(
|
public fun FeatureId.draggable(
|
||||||
//TODO add constraints
|
//TODO add constraints
|
||||||
callback: DragHandle = DragHandle.BYPASS
|
callback: DragHandle = DragHandle.BYPASS,
|
||||||
) {
|
) {
|
||||||
val handle = DragHandle.withPrimaryButton { event, start, end ->
|
val handle = DragHandle.withPrimaryButton { event, start, end ->
|
||||||
val feature = features[this] as? DraggableMapFeature ?: return@withPrimaryButton true
|
val feature = features[this] as? DraggableMapFeature ?: return@withPrimaryButton true
|
||||||
@ -72,7 +72,7 @@ public class MapFeaturesState internal constructor(
|
|||||||
// }.keys
|
// }.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) ->
|
attributes.forEach { (id, attributeMap) ->
|
||||||
attributeMap[key]?.let {
|
attributeMap[key]?.let {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@ -126,6 +126,16 @@ public fun MapFeaturesState.circle(
|
|||||||
id, MapCircleFeature(centerCoordinates.toCoordinates(), zoomRange, size, color)
|
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(
|
public fun MapFeaturesState.rectangle(
|
||||||
centerCoordinates: Pair<Double, Double>,
|
centerCoordinates: Pair<Double, Double>,
|
||||||
zoomRange: IntRange = defaultZoomRange,
|
zoomRange: IntRange = defaultZoomRange,
|
||||||
|
@ -146,11 +146,10 @@ public fun MapView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val featureDrag: DragHandle = DragHandle.withPrimaryButton { event, start, end ->
|
val featureDrag: DragHandle = DragHandle.withPrimaryButton { event, start, end ->
|
||||||
var bypass = true
|
|
||||||
featureState.forEachWithAttribute(DraggableAttribute) { _, handle ->
|
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()
|
val dpEnd = dragChange.position.toDpOffset()
|
||||||
|
|
||||||
//apply drag handle and check if it prohibits the drag even propagation
|
//apply drag handle and check if it prohibits the drag even propagation
|
||||||
if (
|
if (selectionStart == null && !config.dragHandle.handle(
|
||||||
!config.dragHandle.handle(
|
|
||||||
event,
|
event,
|
||||||
MapViewPoint(dpStart.toGeodetic(), viewPoint.zoom),
|
MapViewPoint(dpStart.toGeodetic(), viewPoint.zoom),
|
||||||
MapViewPoint(dpEnd.toGeodetic(), viewPoint.zoom)
|
MapViewPoint(dpEnd.toGeodetic(), viewPoint.zoom)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
//clear selection just in case
|
|
||||||
selectionStart = null
|
|
||||||
return@drag
|
return@drag
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.buttons.isPrimaryPressed) {
|
if (event.buttons.isPrimaryPressed) {
|
||||||
//Evaluating selection frame
|
//If selection process is started, modify the frame
|
||||||
selectionStart?.let { start ->
|
selectionStart?.let { start ->
|
||||||
val offset = dragChange.position
|
val offset = dragChange.position
|
||||||
selectRect = Rect(
|
selectRect = Rect(
|
||||||
@ -141,8 +138,8 @@ public actual fun MapView(
|
|||||||
return@drag
|
return@drag
|
||||||
}
|
}
|
||||||
|
|
||||||
config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom), event)
|
// config.onClick(MapViewPoint(dpPos.toGeodetic(), viewPoint.zoom), event)
|
||||||
|
//If no selection, drag map
|
||||||
setViewPoint(
|
setViewPoint(
|
||||||
viewPoint.move(
|
viewPoint.move(
|
||||||
-dragAmount.x.toDp().value / tileScale,
|
-dragAmount.x.toDp().value / tileScale,
|
||||||
|
Loading…
Reference in New Issue
Block a user