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.padding
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.collectAsState
|
||||
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.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.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
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 {
|
||||
val state = remember { DesktopState() }
|
||||
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(
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "SHONAR Desktop",
|
||||
state = rememberWindowState(width = 1100.dp, height = 800.dp),
|
||||
) {
|
||||
val baseDensity = LocalDensity.current
|
||||
ShonarTheme {
|
||||
Surface(Modifier.fillMaxSize()) {
|
||||
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)
|
||||
Surface(
|
||||
Modifier.fillMaxSize().onPreviewKeyEvent { e ->
|
||||
if (e.type != KeyEventType.KeyDown || !e.isCtrlPressed) return@onPreviewKeyEvent false
|
||||
when (e.key) {
|
||||
Key.Equals, Key.Plus, Key.NumPadAdd -> {
|
||||
zoom = (zoom * 1.1f).coerceAtMost(3f); true
|
||||
}
|
||||
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