Add a debug panel to the scene + MapScene + Cursor
This commit is contained in:
parent
4e013aa358
commit
ae2c3da582
13 changed files with 858 additions and 153 deletions
|
|
@ -2,15 +2,32 @@ package com.pixelized.desktop.lwa.ui.composable.scene
|
|||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.VectorConverter
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastRoundToInt
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.drawables.SceneLayer
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
|
||||
@Stable
|
||||
class Camera(
|
||||
|
|
@ -98,4 +115,63 @@ class Camera(
|
|||
else -> _zoom.animateTo(targetValue = initialZoom)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SceneCameraDebug(
|
||||
modifier: Modifier = Modifier,
|
||||
camera: Camera,
|
||||
isOpen: Boolean = true,
|
||||
style: LwaTypography.Debug = MaterialTheme.lwa.typography.debug,
|
||||
padding: Dp = MaterialTheme.lwa.dimen.debug.offset,
|
||||
) {
|
||||
val isOpen = remember { mutableStateOf(isOpen) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { isOpen.value = isOpen.value.not() }
|
||||
.widthIn(min = MaterialTheme.lwa.dimen.debug.panelWidth)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
text = "Camera",
|
||||
)
|
||||
if (isOpen.value) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("offset: ") }
|
||||
append(camera.offset.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("size: ") }
|
||||
append(camera.cameraSize.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("zoom: ") }
|
||||
append(camera.zoom.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("size: ") }
|
||||
append(camera.cameraSizeZoomed.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
|
||||
@Stable
|
||||
class Cursor(
|
||||
initial: IntOffset = IntOffset.Zero,
|
||||
) {
|
||||
private val _offset = mutableStateOf(initial)
|
||||
val offset by _offset
|
||||
|
||||
fun change(
|
||||
position: Offset,
|
||||
) {
|
||||
_offset.value = IntOffset(
|
||||
x = position.x.toInt(),
|
||||
y = position.y.toInt(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SceneCursorDebug(
|
||||
modifier: Modifier = Modifier,
|
||||
cursor: Cursor,
|
||||
isOpen: Boolean = true,
|
||||
style: LwaTypography.Debug = MaterialTheme.lwa.typography.debug,
|
||||
padding: Dp = MaterialTheme.lwa.dimen.debug.offset,
|
||||
) {
|
||||
val isOpen = remember { mutableStateOf(isOpen) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { isOpen.value = isOpen.value.not() }
|
||||
.widthIn(min = MaterialTheme.lwa.dimen.debug.panelWidth)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
text = "Cursor",
|
||||
)
|
||||
if (isOpen.value) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("offset: ") }
|
||||
append(cursor.offset.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_center_focus_weak_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_zoom_in_map_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_zoom_out_map_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.icon_d100
|
||||
import lwacharactersheet.composeapp.generated.resources.image_dahome_maps
|
||||
import lwacharactersheet.composeapp.generated.resources.image_dahome_regions
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
||||
@Composable
|
||||
fun MapScene(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val campaign = LocalCampaignLayoutScope.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val map = rememberLayoutFromResource(
|
||||
name = "Dahomé",
|
||||
resource = Res.drawable.image_dahome_maps,
|
||||
)
|
||||
val mapRegionOverlay = rememberLayoutFromResource(
|
||||
name = "Région",
|
||||
resource = Res.drawable.image_dahome_regions,
|
||||
)
|
||||
val element1 = rememberElementFromResource(
|
||||
name = "Group",
|
||||
resource = Res.drawable.icon_d100,
|
||||
offset = IntOffset(
|
||||
x = 2128,
|
||||
y = 1875,
|
||||
),
|
||||
)
|
||||
val element2 = rememberElementFromResource(
|
||||
name = "End",
|
||||
resource = Res.drawable.icon_d100,
|
||||
offset = IntOffset(
|
||||
x = map.size.width,
|
||||
y = map.size.height,
|
||||
)
|
||||
)
|
||||
val element3 = rememberElementFromResource(
|
||||
name = "Start",
|
||||
resource = Res.drawable.icon_d100,
|
||||
offset = IntOffset(
|
||||
x = 0,
|
||||
y = 0,
|
||||
)
|
||||
)
|
||||
val scene = remember(map, mapRegionOverlay, element1, element2) {
|
||||
Scene(
|
||||
camera = Camera(
|
||||
initialZoom = 1f,
|
||||
initialOffset = IntOffset(x = -150, y = -120),
|
||||
),
|
||||
fogOfWar = FogOfWar.NONE,
|
||||
layers = listOf(
|
||||
map,
|
||||
mapRegionOverlay,
|
||||
),
|
||||
elements = listOf(
|
||||
element1,
|
||||
element2,
|
||||
element3,
|
||||
),
|
||||
)
|
||||
}
|
||||
Scene(
|
||||
modifier = modifier,
|
||||
scene = scene,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.BottomEnd)
|
||||
.padding(end = campaign.rightPanel.value.width)
|
||||
.padding(all = 8.dp)
|
||||
) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.handleZoom(
|
||||
zoomIn = true,
|
||||
power = 0.3f,
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_zoom_in_map_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.handleZoom(
|
||||
zoomIn = false,
|
||||
power = 0.3f,
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_zoom_out_map_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.resetPosition()
|
||||
}
|
||||
scope.launch {
|
||||
scene.camera.resetZoom()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_center_focus_weak_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.layers.getOrNull(1)?.let {
|
||||
it.alpha(alpha = if (it.alpha == 0f) 1f else 0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_visibility_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,5 +5,9 @@ import androidx.compose.ui.graphics.Color
|
|||
|
||||
@Stable
|
||||
data class FogOfWar(
|
||||
val color: Color = Color.Black.copy(alpha = 0.5f),
|
||||
)
|
||||
val color: Color = Color.Black.copy(alpha = 0.0f),
|
||||
) {
|
||||
companion object {
|
||||
val NONE = FogOfWar(color = Color.Transparent)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,9 @@ package com.pixelized.desktop.lwa.ui.composable.scene
|
|||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.remember
|
||||
|
|
@ -17,6 +14,9 @@ import androidx.compose.ui.ExperimentalComposeUiApi
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawWithCache
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.pointer.PointerEvent
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
|
|
@ -28,163 +28,107 @@ import androidx.compose.ui.input.pointer.onPointerEvent
|
|||
import androidx.compose.ui.layout.onSizeChanged
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.LocalCampaignLayoutScope
|
||||
import androidx.compose.ui.unit.toSize
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.drawables.SceneElement
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.drawables.SceneLayer
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.utils.global
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.utils.local
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_center_focus_weak_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_zoom_in_map_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_zoom_out_map_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
|
||||
import lwacharactersheet.composeapp.generated.resources.icon_d100
|
||||
import lwacharactersheet.composeapp.generated.resources.image_dahome_maps
|
||||
import lwacharactersheet.composeapp.generated.resources.image_dahome_regions
|
||||
import org.jetbrains.compose.resources.DrawableResource
|
||||
import org.jetbrains.compose.resources.imageResource
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import java.util.UUID
|
||||
import kotlin.math.sign
|
||||
|
||||
@Stable
|
||||
data class Scene(
|
||||
val camera: Camera,
|
||||
val layouts: List<Layout>,
|
||||
val fogOfWar: FogOfWar,
|
||||
val layers: List<SceneLayer>,
|
||||
val elements: List<SceneElement>,
|
||||
) {
|
||||
val size: IntSize = IntSize(
|
||||
width = layouts.maxOf { it.size.width },
|
||||
height = layouts.maxOf { it.size.height },
|
||||
width = layers.maxOf { it.size.width },
|
||||
height = layers.maxOf { it.size.height },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
fun Scene(
|
||||
modifier: Modifier,
|
||||
modifier: Modifier = Modifier,
|
||||
scene: Scene,
|
||||
content: @Composable BoxScope.() -> Unit,
|
||||
) {
|
||||
val campaign = LocalCampaignLayoutScope.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val scene = rememberScene(
|
||||
camera = Camera(
|
||||
initialZoom = 1f,
|
||||
initialOffset = IntOffset(x = -150, y = -120),
|
||||
),
|
||||
fogOfWar = FogOfWar(),
|
||||
rememberLayoutFromResource(
|
||||
resource = Res.drawable.image_dahome_maps,
|
||||
),
|
||||
rememberLayoutFromResource(
|
||||
resource = Res.drawable.image_dahome_regions,
|
||||
),
|
||||
rememberLayoutFromResource(
|
||||
resource = Res.drawable.icon_d100,
|
||||
offset = IntOffset(x = 1740, y = 910),
|
||||
),
|
||||
)
|
||||
val cursors = remember {
|
||||
listOf(
|
||||
Cursor()
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.graphicsLayer { clip = true }
|
||||
.onCameraControl(scope = scope, scene = scene)
|
||||
.drawScene(scene = scene)
|
||||
.fogOfWar(scene = scene)
|
||||
.onCursorControl(camera = scene.camera, cursor = cursors.first())
|
||||
.drawLayers(camera = scene.camera, layers = scene.layers)
|
||||
.drawElements(camera = scene.camera, elements = scene.elements)
|
||||
.drawCursors(camera = scene.camera, cursors = cursors)
|
||||
.drawFogOfWar(scene = scene),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.BottomEnd)
|
||||
.padding(end = campaign.rightPanel.value.width)
|
||||
.padding(all = 8.dp)
|
||||
) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.handleZoom(
|
||||
zoomIn = true,
|
||||
power = 0.3f,
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_zoom_in_map_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.handleZoom(
|
||||
zoomIn = false,
|
||||
power = 0.3f,
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_zoom_out_map_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.camera.resetPosition()
|
||||
}
|
||||
scope.launch {
|
||||
scene.camera.resetZoom()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_center_focus_weak_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
IconButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
scene.layouts.getOrNull(1)?.let {
|
||||
it.alpha(alpha = if (it.alpha == 0f) 1f else 0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(Res.drawable.ic_visibility_24dp),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
content()
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberLayoutFromResource(
|
||||
resource: DrawableResource,
|
||||
offset: IntOffset = IntOffset.Zero,
|
||||
): Layout {
|
||||
val texture = imageResource(
|
||||
resource = resource,
|
||||
)
|
||||
return remember(resource) {
|
||||
Layout(
|
||||
texture = texture,
|
||||
offset = offset,
|
||||
SceneDebugPanel(
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.TopEnd)
|
||||
.padding(paddingValues = MaterialTheme.lwa.dimen.paddingValues),
|
||||
cursor = cursors.first(),
|
||||
scene = scene,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberScene(
|
||||
camera: Camera,
|
||||
fogOfWar: FogOfWar,
|
||||
vararg layouts: Layout,
|
||||
): Scene {
|
||||
return remember {
|
||||
Scene(
|
||||
camera = camera,
|
||||
layouts = layouts.toList(),
|
||||
fogOfWar = fogOfWar,
|
||||
fun rememberLayoutFromResource(
|
||||
name: String,
|
||||
resource: DrawableResource,
|
||||
offset: IntOffset = IntOffset.Zero,
|
||||
): SceneLayer {
|
||||
val texture = imageResource(
|
||||
resource = resource,
|
||||
)
|
||||
return remember(resource) {
|
||||
SceneLayer(
|
||||
id = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
texture = texture,
|
||||
offset = offset,
|
||||
alpha = 1f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Stable
|
||||
fun rememberElementFromResource(
|
||||
name: String,
|
||||
resource: DrawableResource,
|
||||
offset: IntOffset = IntOffset.Zero,
|
||||
): SceneElement {
|
||||
val texture = imageResource(
|
||||
resource = resource,
|
||||
)
|
||||
return remember(resource) {
|
||||
SceneElement(
|
||||
id = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
texture = texture,
|
||||
offset = offset,
|
||||
alpha = 1f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -233,23 +177,81 @@ fun Modifier.onCameraControl(
|
|||
}
|
||||
}
|
||||
|
||||
fun Modifier.drawScene(
|
||||
scene: Scene,
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun Modifier.onCursorControl(
|
||||
camera: Camera,
|
||||
cursor: Cursor,
|
||||
): Modifier = this
|
||||
.onPointerEvent(PointerEventType.Exit) { event: PointerEvent ->
|
||||
cursor.change(
|
||||
position = Offset.Unspecified,
|
||||
)
|
||||
}
|
||||
.onPointerEvent(PointerEventType.Move) { event: PointerEvent ->
|
||||
cursor.change(
|
||||
position = event.changes.first().position.global(camera = camera),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Modifier.drawCursors(
|
||||
camera: Camera,
|
||||
cursors: List<Cursor>,
|
||||
): Modifier = this
|
||||
.drawWithCache {
|
||||
onDrawBehind {
|
||||
cursors.forEach { cursor ->
|
||||
drawRect(
|
||||
color = Color.Green,
|
||||
topLeft = cursor.offset.local(camera = camera),
|
||||
size = Size(10f, 10f),
|
||||
style = Stroke(width = 2f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
fun Modifier.drawLayers(
|
||||
camera: Camera,
|
||||
layers: List<SceneLayer>,
|
||||
): Modifier = this.drawWithCache {
|
||||
onDrawBehind {
|
||||
scene.layouts.forEach { layout ->
|
||||
layers.forEach { layers ->
|
||||
drawImage(
|
||||
image = layout.texture,
|
||||
srcOffset = scene.camera.offset - layout.offset,
|
||||
srcSize = scene.camera.cameraSizeZoomed,
|
||||
dstSize = scene.camera.cameraSize,
|
||||
alpha = layout.alpha,
|
||||
image = layers.texture,
|
||||
srcOffset = camera.offset - layers.offset,
|
||||
srcSize = camera.cameraSizeZoomed,
|
||||
dstSize = camera.cameraSize,
|
||||
alpha = layers.alpha,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifier.fogOfWar(
|
||||
fun Modifier.drawElements(
|
||||
camera: Camera,
|
||||
elements: List<SceneElement>,
|
||||
): Modifier = this.drawWithCache {
|
||||
onDrawBehind {
|
||||
elements.forEach { element ->
|
||||
drawImage(
|
||||
image = element.texture,
|
||||
srcOffset = camera.offset - element.position,
|
||||
srcSize = camera.cameraSizeZoomed,
|
||||
dstSize = camera.cameraSize,
|
||||
alpha = element.alpha,
|
||||
)
|
||||
drawRect(
|
||||
color = Color.Red,
|
||||
topLeft = element.position.local(camera = camera),
|
||||
size = (element.size).toSize() / camera.zoom,
|
||||
style = Stroke(width = 2f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Modifier.drawFogOfWar(
|
||||
scene: Scene,
|
||||
): Modifier = this.drawWithCache {
|
||||
onDrawBehind {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,114 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.drawables.SceneElementDebug
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.drawables.SceneLayerDebug
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
|
||||
@Composable
|
||||
fun SceneDebugPanel(
|
||||
modifier: Modifier = Modifier,
|
||||
paddingValues: PaddingValues = MaterialTheme.lwa.dimen.paddingValues,
|
||||
cursor: Cursor,
|
||||
scene: Scene,
|
||||
) {
|
||||
Card (
|
||||
modifier = modifier,
|
||||
backgroundColor = MaterialTheme.lwa.colorScheme.elevated.base4dp,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(paddingValues = paddingValues),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
) {
|
||||
SceneDebug(
|
||||
scene = scene,
|
||||
)
|
||||
SceneCursorDebug(
|
||||
cursor = cursor,
|
||||
)
|
||||
SceneCameraDebug(
|
||||
camera = scene.camera,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
text = "Layers:(${scene.layers.size})"
|
||||
)
|
||||
scene.layers.forEach { layer ->
|
||||
SceneLayerDebug(
|
||||
modifier = Modifier.padding(start = MaterialTheme.lwa.dimen.debug.offset),
|
||||
isOpen = false,
|
||||
layer = layer,
|
||||
)
|
||||
}
|
||||
}
|
||||
Column {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
text = "Elements:(${scene.elements.size})"
|
||||
)
|
||||
scene.elements.forEach { element ->
|
||||
SceneElementDebug(
|
||||
modifier = Modifier.padding(start = MaterialTheme.lwa.dimen.debug.offset),
|
||||
isOpen = false,
|
||||
element = element,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SceneDebug(
|
||||
modifier: Modifier = Modifier,
|
||||
scene: Scene,
|
||||
isOpen: Boolean = true,
|
||||
style: LwaTypography.Debug = MaterialTheme.lwa.typography.debug,
|
||||
padding: Dp = MaterialTheme.lwa.dimen.debug.offset,
|
||||
) {
|
||||
val isOpen = remember { mutableStateOf(isOpen) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { isOpen.value = isOpen.value.not() }
|
||||
.widthIn(min = MaterialTheme.lwa.dimen.debug.panelWidth)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
text = "Scene",
|
||||
)
|
||||
if (isOpen.value) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("Size: ") }
|
||||
append(scene.size.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene
|
||||
package com.pixelized.desktop.lwa.ui.composable.scene.drawables
|
||||
|
||||
import androidx.compose.animation.core.Animatable
|
||||
import androidx.compose.animation.core.VectorConverter
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
|
||||
@Stable
|
||||
class Layout(
|
||||
open class SceneDrawable(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val texture: ImageBitmap,
|
||||
val offset: IntOffset = IntOffset.Zero,
|
||||
val size: IntSize = IntSize(texture.width, texture.height),
|
||||
private val initialAlpha: Float = 1f,
|
||||
val offset: IntOffset,
|
||||
val size: IntSize,
|
||||
private val initialAlpha: Float,
|
||||
) {
|
||||
private val _alpha = Animatable(
|
||||
initialValue = initialAlpha,
|
||||
typeConverter = Float.VectorConverter,
|
||||
typeConverter = Float.Companion.VectorConverter,
|
||||
)
|
||||
val alpha get() = _alpha.value
|
||||
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene.drawables
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
|
||||
@Stable
|
||||
class SceneElement(
|
||||
id: String,
|
||||
name: String,
|
||||
texture: ImageBitmap,
|
||||
offset: IntOffset = IntOffset.Companion.Zero,
|
||||
size: IntSize = IntSize(texture.width, texture.height),
|
||||
alpha: Float = 1f,
|
||||
) : SceneDrawable(
|
||||
id = id,
|
||||
name = name,
|
||||
texture = texture,
|
||||
offset = offset,
|
||||
size = size,
|
||||
initialAlpha = alpha,
|
||||
) {
|
||||
val position = IntOffset(
|
||||
x = offset.x - size.width / 2,
|
||||
y = offset.y - size.height / 2,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SceneElementDebug(
|
||||
modifier: Modifier = Modifier,
|
||||
element: SceneElement,
|
||||
isOpen: Boolean = true,
|
||||
style: LwaTypography.Debug = MaterialTheme.lwa.typography.debug,
|
||||
padding: Dp = MaterialTheme.lwa.dimen.debug.offset,
|
||||
) {
|
||||
val isOpen = remember { mutableStateOf(isOpen) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { isOpen.value = isOpen.value.not() }
|
||||
.widthIn(min = MaterialTheme.lwa.dimen.debug.panelWidth)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
text = element.name,
|
||||
)
|
||||
if (isOpen.value) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("id: ") }
|
||||
append(element.id)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("offset: ") }
|
||||
append(element.offset.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("size: ") }
|
||||
append(element.size.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("alpha: ") }
|
||||
append(element.alpha.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene.drawables
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ImageBitmap
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
|
||||
|
||||
@Stable
|
||||
class SceneLayer(
|
||||
id : String,
|
||||
name: String,
|
||||
texture: ImageBitmap,
|
||||
offset: IntOffset = IntOffset.Companion.Zero,
|
||||
size: IntSize = IntSize(texture.width, texture.height),
|
||||
alpha: Float = 1f,
|
||||
) : SceneDrawable(
|
||||
id = id,
|
||||
name = name,
|
||||
texture = texture,
|
||||
offset = offset,
|
||||
size = size,
|
||||
initialAlpha = alpha,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun SceneLayerDebug(
|
||||
modifier: Modifier = Modifier,
|
||||
layer: SceneLayer,
|
||||
isOpen: Boolean = true,
|
||||
style: LwaTypography.Debug = MaterialTheme.lwa.typography.debug,
|
||||
padding: Dp = MaterialTheme.lwa.dimen.debug.offset,
|
||||
) {
|
||||
val isOpen = remember { mutableStateOf(isOpen) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable { isOpen.value = isOpen.value.not() }
|
||||
.widthIn(min = MaterialTheme.lwa.dimen.debug.panelWidth)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 2.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.lwa.typography.debug.title,
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
text = layer.name,
|
||||
)
|
||||
if (isOpen.value) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("id: ") }
|
||||
append(layer.id)
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("offset: ") }
|
||||
append(layer.offset.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("size: ") }
|
||||
append(layer.size.toString())
|
||||
},
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(start = padding),
|
||||
style = MaterialTheme.lwa.typography.debug.propertyValue,
|
||||
text = buildAnnotatedString {
|
||||
withStyle(style.propertyId) { append("alpha: ") }
|
||||
append(layer.alpha.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.scene.utils
|
||||
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.Camera
|
||||
|
||||
/**
|
||||
* Convert local positon to global one.
|
||||
* Global position are agnostic from camera, and therefor should be use to position stuff on the map.
|
||||
* A common use case is to share players cursor.
|
||||
*/
|
||||
fun Offset.global(
|
||||
camera: Camera,
|
||||
): Offset = Offset(
|
||||
x = this.x * camera.zoom + camera.offset.x,
|
||||
y = this.y * camera.zoom + camera.offset.y,
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert global positon to local one.
|
||||
* Local position take into account the camera and are use to display stuff on the Scene composable.
|
||||
*/
|
||||
fun Offset.local(
|
||||
camera: Camera,
|
||||
): Offset = Offset(
|
||||
x = (this.x - camera.offset.x) / camera.zoom,
|
||||
y = (this.y - camera.offset.y) / camera.zoom,
|
||||
)
|
||||
|
||||
/**
|
||||
* Convert global positon to local one.
|
||||
* Local position take into account the camera and are use to display stuff on the Scene composable.
|
||||
*/
|
||||
fun IntOffset.local(
|
||||
camera: Camera,
|
||||
): Offset = Offset(
|
||||
x = (this.x.toFloat() - camera.offset.x) / camera.zoom,
|
||||
y = (this.y.toFloat() - camera.offset.y) / camera.zoom,
|
||||
)
|
||||
|
|
@ -44,7 +44,7 @@ import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterShe
|
|||
import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedDialogViewModel
|
||||
import com.pixelized.desktop.lwa.ui.composable.error.ErrorSnackHandler
|
||||
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.Scene
|
||||
import com.pixelized.desktop.lwa.ui.composable.scene.MapScene
|
||||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.navigateToLevelScreen
|
||||
import com.pixelized.desktop.lwa.ui.overlay.portrait.PortraitOverlay
|
||||
|
|
@ -101,7 +101,7 @@ fun CampaignScreen(
|
|||
|
||||
},
|
||||
main = {
|
||||
Scene(
|
||||
MapScene(
|
||||
modifier = Modifier.matchParentSize(),
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ data class LwaDimen(
|
|||
val layout: Layout,
|
||||
val portrait: Portrait,
|
||||
val sheet: Sheet,
|
||||
val debug: Debug,
|
||||
) {
|
||||
@Stable
|
||||
data class Layout(
|
||||
|
|
@ -33,6 +34,12 @@ data class LwaDimen(
|
|||
val subCategory: Dp,
|
||||
val characteristic: DpSize,
|
||||
)
|
||||
|
||||
@Stable
|
||||
data class Debug(
|
||||
val panelWidth: Dp,
|
||||
val offset: Dp,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -52,6 +59,10 @@ fun lwaDimen(
|
|||
detailWidth = 128.dp * 4,
|
||||
chatMaxWidth = 600.dp,
|
||||
),
|
||||
debug: LwaDimen.Debug = LwaDimen.Debug(
|
||||
panelWidth = 200.dp,
|
||||
offset = 8.dp,
|
||||
)
|
||||
): LwaDimen {
|
||||
return remember {
|
||||
LwaDimen(
|
||||
|
|
@ -60,6 +71,7 @@ fun lwaDimen(
|
|||
portrait = portrait,
|
||||
sheet = sheet,
|
||||
layout = layout,
|
||||
debug = debug,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import androidx.compose.ui.graphics.Shadow
|
|||
import androidx.compose.ui.graphics.StrokeJoin
|
||||
import androidx.compose.ui.graphics.drawscope.Fill
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
|
|
@ -30,6 +31,7 @@ data class LwaTypography(
|
|||
val characterSheet: CharacterSheet,
|
||||
val inventory: Inventory,
|
||||
val freeDiceThrow: Dice,
|
||||
val debug: Debug,
|
||||
) {
|
||||
@Stable
|
||||
data class Chat(
|
||||
|
|
@ -73,6 +75,13 @@ data class LwaTypography(
|
|||
val dice: TextStyle,
|
||||
val result: TextStyle,
|
||||
)
|
||||
|
||||
@Stable
|
||||
data class Debug(
|
||||
val title: TextStyle,
|
||||
val propertyId: SpanStyle,
|
||||
val propertyValue: TextStyle,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -196,7 +205,24 @@ fun lwaTypography(
|
|||
result = robotoMono.h4.copy(
|
||||
color = colors.base.onSurface,
|
||||
),
|
||||
)
|
||||
),
|
||||
debug = LwaTypography.Debug(
|
||||
title = robotoMono.caption.copy(
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 14.sp,
|
||||
),
|
||||
propertyId = robotoMono.caption.copy(
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 10.sp,
|
||||
lineHeight = 14.sp,
|
||||
).toSpanStyle(),
|
||||
propertyValue = robotoMono.caption.copy(
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 14.sp,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue