-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sargun Vohra <[email protected]>
- Loading branch information
1 parent
8b7b868
commit ef3ff80
Showing
14 changed files
with
570 additions
and
311 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
...se-material3/src/androidMain/kotlin/dev/sargunv/maplibrecompose/material3/util.android.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package dev.sargunv.maplibrecompose.material3 | ||
|
||
import android.icu.util.LocaleData | ||
import android.icu.util.ULocale | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.platform.LocalContext | ||
import dev.sargunv.maplibrecompose.material3.controls.ScaleBarMeasure | ||
|
||
@Composable | ||
internal actual fun systemDefaultPrimaryMeasure(): ScaleBarMeasure? { | ||
if (android.os.Build.VERSION.SDK_INT < 28) return null | ||
val locales = LocalContext.current.resources.configuration.locales | ||
if (locales.isEmpty) return null | ||
return when (LocaleData.getMeasurementSystem(ULocale.forLocale(locales[0]))) { | ||
LocaleData.MeasurementSystem.SI -> ScaleBarMeasure.Metric | ||
LocaleData.MeasurementSystem.US -> ScaleBarMeasure.FeetAndMiles | ||
LocaleData.MeasurementSystem.UK -> ScaleBarMeasure.YardsAndMiles | ||
else -> null | ||
} | ||
} |
3 changes: 0 additions & 3 deletions
3
lib/maplibre-compose-material3/src/commonMain/composeResources/values-es/strings.xml
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...ompose-material3/src/commonMain/kotlin/dev/sargunv/maplibrecompose/material3/DrawScope.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package dev.sargunv.maplibrecompose.material3 | ||
|
||
import androidx.compose.ui.geometry.Offset | ||
import androidx.compose.ui.graphics.BlendMode | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.graphics.ColorFilter | ||
import androidx.compose.ui.graphics.PathEffect | ||
import androidx.compose.ui.graphics.StrokeCap | ||
import androidx.compose.ui.graphics.StrokeJoin | ||
import androidx.compose.ui.graphics.drawscope.DrawScope | ||
import androidx.compose.ui.graphics.drawscope.DrawScope.Companion.DefaultBlendMode | ||
import androidx.compose.ui.graphics.drawscope.Fill | ||
import androidx.compose.ui.graphics.drawscope.Stroke | ||
import androidx.compose.ui.text.TextLayoutResult | ||
import androidx.compose.ui.text.drawText | ||
|
||
/** Draw several lines. Each offset in [path] is relative to the previous. */ | ||
internal fun DrawScope.drawPath( | ||
color: Color, | ||
path: List<Offset>, | ||
strokeWidth: Float = Stroke.HairlineWidth, | ||
cap: StrokeCap = Stroke.DefaultCap, | ||
pathEffect: PathEffect? = null, | ||
alpha: Float = 1.0f, | ||
colorFilter: ColorFilter? = null, | ||
blendMode: BlendMode = DefaultBlendMode, | ||
) { | ||
val it = path.iterator() | ||
if (!it.hasNext()) return | ||
var start = it.next() | ||
while (it.hasNext()) { | ||
val end = start + it.next() | ||
drawLine( | ||
color = color, | ||
start = start, | ||
end = end, | ||
strokeWidth = strokeWidth, | ||
cap = cap, | ||
pathEffect = pathEffect, | ||
alpha = alpha, | ||
colorFilter = colorFilter, | ||
blendMode = blendMode, | ||
) | ||
start = end | ||
} | ||
} | ||
|
||
/** Draw several paths with halo. All halos of all [paths] are behind all strokes. */ | ||
internal fun DrawScope.drawPathsWithHalo( | ||
color: Color, | ||
haloColor: Color, | ||
paths: List<List<Offset>>, | ||
strokeWidth: Float = Stroke.HairlineWidth, | ||
haloWidth: Float = Stroke.HairlineWidth, | ||
cap: StrokeCap = Stroke.DefaultCap, | ||
) { | ||
for (path in paths) { | ||
drawPath(color = haloColor, path = path, strokeWidth = strokeWidth + haloWidth * 2, cap = cap) | ||
} | ||
for (path in paths) { | ||
drawPath(color = color, path = path, strokeWidth = strokeWidth, cap = cap) | ||
} | ||
} | ||
|
||
internal fun DrawScope.drawTextWithHalo( | ||
textLayoutResult: TextLayoutResult, | ||
topLeft: Offset = Offset.Zero, | ||
color: Color = Color.Unspecified, | ||
haloColor: Color = Color.Unspecified, | ||
haloWidth: Float = 0f, | ||
) { | ||
// * 2 because the stroke is painted half outside and half inside of the text shape | ||
val stroke = Stroke(width = haloWidth * 2, cap = StrokeCap.Round, join = StrokeJoin.Round) | ||
drawText( | ||
textLayoutResult = textLayoutResult, | ||
color = haloColor, | ||
topLeft = topLeft, | ||
drawStyle = stroke, | ||
) | ||
drawText(textLayoutResult = textLayoutResult, color = color, topLeft = topLeft, drawStyle = Fill) | ||
} |
82 changes: 82 additions & 0 deletions
82
.../commonMain/kotlin/dev/sargunv/maplibrecompose/material3/controls/DisappearingScaleBar.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package dev.sargunv.maplibrecompose.material3.controls | ||
|
||
import androidx.compose.animation.AnimatedVisibility | ||
import androidx.compose.animation.EnterTransition | ||
import androidx.compose.animation.ExitTransition | ||
import androidx.compose.animation.core.MutableTransitionState | ||
import androidx.compose.animation.fadeIn | ||
import androidx.compose.animation.fadeOut | ||
import androidx.compose.material3.MaterialTheme | ||
import androidx.compose.material3.contentColorFor | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.remember | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.graphics.Color | ||
import androidx.compose.ui.text.TextStyle | ||
import dev.sargunv.maplibrecompose.material3.defaultScaleBarMeasures | ||
import kotlin.time.Duration | ||
import kotlin.time.Duration.Companion.seconds | ||
import kotlinx.coroutines.delay | ||
|
||
/** | ||
* An animated scale bar that appears when the [zoom] level of the map changes, and then disappears | ||
* after [visibilityDuration]. This composable wraps [ScaleBar] with visibility animations. | ||
* | ||
* @param metersPerDp how many meters are displayed in one device independent pixel (dp), i.e. the | ||
* scale. See | ||
* [CameraState.metersPerDpAtTarget][dev.sargunv.maplibrecompose.compose.CameraState.metersPerDpAtTarget] | ||
* @param zoom zoom level of the map | ||
* @param modifier the [Modifier] to be applied to this layout node | ||
* @param measures which measures to show on the scale bar. If `null`, measures will be selected | ||
* based on the system settings or otherwise the user's locale. | ||
* @param haloColor halo for better visibility when displayed on top of the map | ||
* @param color scale bar and text color. | ||
* @param textStyle the text style. The text size is the deciding factor how large the scale bar is | ||
* is displayed. | ||
* @param alignment horizontal alignment of the scale bar and text | ||
* @param visibilityDuration how long it should be visible after the zoom changed | ||
* @param enterTransition EnterTransition(s) used for the appearing animation | ||
* @param exitTransition ExitTransition(s) used for the disappearing animation | ||
*/ | ||
@Composable | ||
public fun DisappearingScaleBar( | ||
metersPerDp: Double, | ||
zoom: Double, | ||
modifier: Modifier = Modifier, | ||
measures: ScaleBarMeasures = defaultScaleBarMeasures(), | ||
haloColor: Color = MaterialTheme.colorScheme.surface, | ||
color: Color = contentColorFor(haloColor), | ||
textStyle: TextStyle = MaterialTheme.typography.labelMedium, | ||
alignment: Alignment.Horizontal = Alignment.Start, | ||
visibilityDuration: Duration = 3.seconds, | ||
enterTransition: EnterTransition = fadeIn(), | ||
exitTransition: ExitTransition = fadeOut(), | ||
) { | ||
val visible = remember { MutableTransitionState(true) } | ||
|
||
LaunchedEffect(zoom) { | ||
// Show ScaleBar | ||
visible.targetState = true | ||
delay(visibilityDuration) | ||
// Hide ScaleBar after timeout period | ||
visible.targetState = false | ||
} | ||
|
||
AnimatedVisibility( | ||
visibleState = visible, | ||
modifier = modifier, | ||
enter = enterTransition, | ||
exit = exitTransition, | ||
) { | ||
ScaleBar( | ||
metersPerDp = metersPerDp, | ||
measures = measures, | ||
haloColor = haloColor, | ||
color = color, | ||
textStyle = textStyle, | ||
alignment = alignment, | ||
) | ||
} | ||
} |
Oops, something went wrong.