Desktop: app-wide zoom (Ctrl+=/-, Ctrl+0 resets) via scaled Density
This commit is contained in:
parent
ac77f89ffa
commit
4944fcd162
1 changed files with 47 additions and 7 deletions
|
|
@ -4,31 +4,71 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
|
import androidx.compose.ui.input.key.isCtrlPressed
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
|
import androidx.compose.ui.input.key.type
|
||||||
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
|
import androidx.compose.ui.unit.Density
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.application
|
import androidx.compose.ui.window.application
|
||||||
import androidx.compose.ui.window.rememberWindowState
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
|
|
||||||
|
/** Scales every dp/sp in the app uniformly (fonts, paddings, controls). */
|
||||||
|
private data class ScaledDensity(val base: Density, val zoom: Float) : Density {
|
||||||
|
override val density: Float get() = base.density * zoom
|
||||||
|
override val fontScale: Float get() = base.fontScale * zoom
|
||||||
|
}
|
||||||
|
|
||||||
fun main() = application {
|
fun main() = application {
|
||||||
val state = remember { DesktopState() }
|
val state = remember { DesktopState() }
|
||||||
val screen by state.screen.collectAsState()
|
val screen by state.screen.collectAsState()
|
||||||
|
// Ctrl+= / Ctrl+- zoom the whole app; Ctrl+0 resets (after a zoom).
|
||||||
|
var zoom by remember { mutableStateOf(1f) }
|
||||||
Window(
|
Window(
|
||||||
onCloseRequest = ::exitApplication,
|
onCloseRequest = ::exitApplication,
|
||||||
title = "SHONAR Desktop",
|
title = "SHONAR Desktop",
|
||||||
state = rememberWindowState(width = 1100.dp, height = 800.dp),
|
state = rememberWindowState(width = 1100.dp, height = 800.dp),
|
||||||
) {
|
) {
|
||||||
|
val baseDensity = LocalDensity.current
|
||||||
ShonarTheme {
|
ShonarTheme {
|
||||||
Surface(Modifier.fillMaxSize()) {
|
Surface(
|
||||||
Box(Modifier.fillMaxSize().padding(20.dp)) {
|
Modifier.fillMaxSize().onPreviewKeyEvent { e ->
|
||||||
when (screen) {
|
if (e.type != KeyEventType.KeyDown || !e.isCtrlPressed) return@onPreviewKeyEvent false
|
||||||
DesktopState.Screen.ENGINE -> EngineScreen(state)
|
when (e.key) {
|
||||||
DesktopState.Screen.LIBRARY -> LibraryScreen(state)
|
Key.Equals, Key.Plus, Key.NumPadAdd -> {
|
||||||
DesktopState.Screen.DETAIL -> DetailScreen(state)
|
zoom = (zoom * 1.1f).coerceAtMost(3f); true
|
||||||
DesktopState.Screen.SETTINGS -> SettingsScreen(state)
|
}
|
||||||
|
Key.Minus, Key.NumPadSubtract -> {
|
||||||
|
zoom = (zoom / 1.1f).coerceAtLeast(0.4f); true
|
||||||
|
}
|
||||||
|
Key.Zero, Key.NumPad0 -> {
|
||||||
|
if (zoom != 1f) { zoom = 1f; true } else false
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalDensity provides ScaledDensity(baseDensity, zoom),
|
||||||
|
) {
|
||||||
|
Box(Modifier.fillMaxSize().padding(20.dp)) {
|
||||||
|
when (screen) {
|
||||||
|
DesktopState.Screen.ENGINE -> EngineScreen(state)
|
||||||
|
DesktopState.Screen.LIBRARY -> LibraryScreen(state)
|
||||||
|
DesktopState.Screen.DETAIL -> DetailScreen(state)
|
||||||
|
DesktopState.Screen.SETTINGS -> SettingsScreen(state)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue