Skip to content

Commit

Permalink
feat: implement some desktop features
Browse files Browse the repository at this point in the history
  • Loading branch information
sargunv committed Dec 30, 2024
1 parent 61f93cc commit 9553fd0
Show file tree
Hide file tree
Showing 25 changed files with 912 additions and 245 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.sargunv.maplibrecompose.demoapp

actual object Platform {
actual val supportsBlending = true
actual val supportsFps = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,16 @@ import dev.sargunv.maplibrecompose.material3.controls.AttributionButton
import dev.sargunv.maplibrecompose.material3.controls.DisappearingCompassButton
import dev.sargunv.maplibrecompose.material3.controls.DisappearingScaleBar

private val DEMOS =
listOf(
MarkersDemo,
EdgeToEdgeDemo,
StyleSwitcherDemo,
ClusteredPointsDemo,
AnimatedLayerDemo,
CameraStateDemo,
CameraFollowDemo,
FrameRateDemo,
)
private val DEMOS = buildList {
add(MarkersDemo)
if (Platform.supportsBlending) add(EdgeToEdgeDemo)
add(StyleSwitcherDemo)
add(ClusteredPointsDemo)
add(AnimatedLayerDemo)
add(CameraStateDemo)
add(CameraFollowDemo)
if (Platform.supportsFps) add(FrameRateDemo)
}

@Composable
fun DemoApp(navController: NavHostController = rememberNavController()) {
Expand Down Expand Up @@ -121,8 +120,10 @@ fun DemoAppBar(demo: Demo, navigateUp: () -> Unit, alpha: Float = 1f) {
}
},
actions = {
IconButton(onClick = { showInfo = true }) {
Icon(imageVector = Icons.Default.Info, contentDescription = "Info")
if (Platform.supportsBlending) {
IconButton(onClick = { showInfo = true }) {
Icon(imageVector = Icons.Default.Info, contentDescription = "Info")
}
}
},
)
Expand Down Expand Up @@ -151,20 +152,24 @@ fun DemoMapControls(
modifier: Modifier = Modifier,
onCompassClick: () -> Unit = {},
) {
Box(modifier = modifier.fillMaxSize().padding(8.dp)) {
DisappearingScaleBar(cameraState, modifier = Modifier.align(Alignment.TopStart))
DisappearingCompassButton(
cameraState,
modifier = Modifier.align(Alignment.TopEnd),
onClick = onCompassClick,
)
AttributionButton(styleState, modifier = Modifier.align(Alignment.BottomEnd))
if (Platform.supportsBlending) {
Box(modifier = modifier.fillMaxSize().padding(8.dp)) {
DisappearingScaleBar(cameraState, modifier = Modifier.align(Alignment.TopStart))
DisappearingCompassButton(
cameraState,
modifier = Modifier.align(Alignment.TopEnd),
onClick = onCompassClick,
)
AttributionButton(styleState, modifier = Modifier.align(Alignment.BottomEnd))
}
}
}

fun DemoOrnamentSettings(padding: PaddingValues = PaddingValues(0.dp)) =
OrnamentSettings.AllDisabled.copy(
padding = padding,
isLogoEnabled = true,
logoAlignment = Alignment.BottomStart,
)
if (Platform.supportsBlending)
OrnamentSettings.AllDisabled.copy(
padding = padding,
isLogoEnabled = true,
logoAlignment = Alignment.BottomStart,
)
else OrnamentSettings.AllEnabled
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.sargunv.maplibrecompose.demoapp

expect object Platform {
val supportsBlending: Boolean
val supportsFps: Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.sargunv.maplibrecompose.demoapp

actual object Platform {
actual val supportsBlending = false
actual val supportsFps = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package dev.sargunv.maplibrecompose.demoapp

actual object Platform {
actual val supportsBlending = true
actual val supportsFps = true
}
2 changes: 1 addition & 1 deletion docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Desktop support is implemented with [MapLibre GL JS][maplibre-js] and
| ------------------------------------------------- | ------------------ | ------------------ | ------------------ | --- |
| Render a map | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Load Compose resource URIs | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Configure ornaments (compass, logo, attribution) | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Configure ornaments (compass, logo, attribution) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| Configure gestures (pan, zoom, rotate, pitch) | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Respond to a map click or long click | :white_check_mark: | :white_check_mark: | :x: | :x: |
| Query visible map features | :white_check_mark: | :white_check_mark: | :x: | :x: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,168 @@ import org.w3c.dom.HTMLElement
/** [Map](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/) */
@JsName("Map")
public external class Maplibre public constructor(options: MapOptions) {
public var repaint: Boolean
public var showCollisionBoxes: Boolean
public var showOverdrawInspector: Boolean
public var showPadding: Boolean
public var showTileBoundaries: Boolean
public val version: String

public fun setStyle(style: String)

public fun remove()

public fun getBearing(): Double

public fun getCenter(): LngLat

public fun getPitch(): Double

public fun getZoom(): Double

public fun setBearing(bearing: Double)

public fun setCenter(center: LngLat)

public fun setPitch(pitch: Double)

public fun setZoom(zoom: Double)

public fun setMaxZoom(max: Double)

public fun setMinZoom(min: Double)

public fun setMaxPitch(max: Double)

public fun setMinPitch(min: Double)

public fun jumpTo(options: JumpToOptions)

public fun flyTo(options: FlyToOptions)

public fun addControl(control: IControl, position: String)

public fun removeControl(control: IControl)
}

/** [LogoControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/LogoControl/) */
public external class LogoControl
public constructor(options: LogoControlOptions = definedExternally) : IControl {
override fun onAdd(map: Maplibre): HTMLElement

override fun onRemove(map: Maplibre)
}

/**
* [LogoControlOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/LogoControlOptions/)
*/
public external interface LogoControlOptions {
public var compact: Boolean?
}

/** [ScaleControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/ScaleControl/) */
public external class ScaleControl
public constructor(options: ScaleControlOptions = definedExternally) : IControl {
override fun onAdd(map: Maplibre): HTMLElement

override fun onRemove(map: Maplibre)
}

/**
* [ScaleControlOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/ScaleControlOptions/)
*/
public external interface ScaleControlOptions {
public var maxWidth: Double?
public var unit: String?
}

/**
* [AttributionControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/AttributionControl/)
*/
public external class AttributionControl
public constructor(options: AttributionControlOptions = definedExternally) : IControl {
override fun onAdd(map: Maplibre): HTMLElement

override fun onRemove(map: Maplibre)
}

/**
* [AttributionControlOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/AttributionControlOptions/)
*/
public external interface AttributionControlOptions {
public var compact: Boolean?
public var customAttribution: String?
}

/** [NavigationControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/NavigationControl/) */
public external class NavigationControl
public constructor(options: NavigationControlOptions = definedExternally) : IControl {
override fun onAdd(map: Maplibre): HTMLElement

override fun onRemove(map: Maplibre)
}

/**
* [NavigationControlOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/NavigationControlOptions/)
*/
public external interface NavigationControlOptions {
public var showCompass: Boolean?
public var showZoom: Boolean?
public var visualizePitch: Boolean?
}

/** [IControl](https://maplibre.org/maplibre-gl-js/docs/API/interfaces/IControl/) */
public external interface IControl {
public fun onAdd(map: Maplibre): HTMLElement

public fun onRemove(map: Maplibre)
}

/** [LngLat](https://maplibre.org/maplibre-gl-js/docs/API/classes/LngLat/) */
public external class LngLat(public val lng: Double, public val lat: Double) {
public fun toArray(): DoubleArray
}

/** [JumpToOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/JumpToOptions/) */
public sealed external interface JumpToOptions : CameraOptions {
public var padding: PaddingOptions?
}

/** [FlyToOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/FlyToOptions/) */
public sealed external interface FlyToOptions : CameraOptions {
public var curve: Double?
public var maxDuration: Double?
public var minZoom: Double?
public var padding: PaddingOptions?
public var speed: Double?
public var screenSpeed: Double?
}

/** [CameraOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/CameraOptions/) */
public sealed external interface CameraOptions : CenterZoomBearing {
public var around: LngLat?
public var pitch: Double?
}

/**
* [CenterZoomBearing](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/CenterZoomBearing/)
*/
public sealed external interface CenterZoomBearing {
public var bearing: Double?
public var center: LngLat?
public var zoom: Double?
}

/** [PaddingOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/PaddingOptions/) */
public sealed external interface PaddingOptions {
public var bottom: Double
public var left: Double
public var right: Double
public var top: Double
}

/** [MapOptions](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/) */
public sealed external interface MapOptions {
public var container: HTMLElement
public var attributionControl: dynamic // false | AttributionControlOptions
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,92 @@ internal fun <T : Any> jso(): T = js("({})") as T

internal inline fun <T : Any> jso(block: T.() -> Unit): T = jso<T>().apply(block)

public fun MapOptions(container: HTMLElement): MapOptions = jso { this.container = container }
public fun MapOptions(
container: HTMLElement,
disableAttributionControl: Boolean = false,
): MapOptions = jso {
this.container = container
if (disableAttributionControl) {
this.attributionControl = false
}
}

public fun LogoControlOptions(compact: Boolean? = null): LogoControlOptions = jso {
compact?.let { this.compact = it }
}

public fun ScaleControlOptions(
maxWidth: Double? = null,
unit: String? = null,
): ScaleControlOptions = jso {
maxWidth?.let { this.maxWidth = it }
unit?.let { this.unit = it }
}

public fun AttributionControlOptions(
compact: Boolean? = null,
customAttribution: String? = null,
): AttributionControlOptions = jso {
compact?.let { this.compact = it }
customAttribution?.let { this.customAttribution = it }
}

public fun NavigationControlOptions(
showCompass: Boolean? = null,
showZoom: Boolean? = null,
visualizePitch: Boolean? = null,
): NavigationControlOptions = jso {
showCompass?.let { this.showCompass = it }
showZoom?.let { this.showZoom = it }
visualizePitch?.let { this.visualizePitch = it }
}

public fun JumpToOptions(
center: LngLat? = null,
zoom: Double? = null,
bearing: Double? = null,
pitch: Double? = null,
padding: PaddingOptions? = null,
): JumpToOptions = jso {
center?.let { this.center = it }
zoom?.let { this.zoom = it }
bearing?.let { this.bearing = it }
pitch?.let { this.pitch = it }
padding?.let { this.padding = it }
}

public fun PaddingOptions(
top: Double? = null,
bottom: Double? = null,
left: Double? = null,
right: Double? = null,
): PaddingOptions = jso {
top?.let { this.top = it }
bottom?.let { this.bottom = it }
left?.let { this.left = it }
right?.let { this.right = it }
}

public fun FlyToOptions(
center: LngLat? = null,
zoom: Double? = null,
bearing: Double? = null,
pitch: Double? = null,
speed: Double? = null,
curve: Double? = null,
maxDuration: Double? = null,
minZoom: Double? = null,
padding: PaddingOptions? = null,
screenSpeed: Double? = null,
): FlyToOptions = jso {
center?.let { this.center = it }
zoom?.let { this.zoom = it }
bearing?.let { this.bearing = it }
pitch?.let { this.pitch = it }
speed?.let { this.speed = it }
curve?.let { this.curve = it }
maxDuration?.let { this.maxDuration = it }
minZoom?.let { this.minZoom = it }
padding?.let { this.padding = it }
screenSpeed?.let { this.screenSpeed = it }
}
1 change: 1 addition & 0 deletions lib/maplibre-compose-webview/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ kotlin {

useEsModules()
binaries.executable()
generateTypeScriptDefinitions()
}

sourceSets {
Expand Down
Loading

0 comments on commit 9553fd0

Please sign in to comment.