DesktopConfigData.kt 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package org.mjdev.desktop.data
  2. import androidx.compose.ui.graphics.Color
  3. import androidx.compose.ui.unit.DpSize
  4. import androidx.compose.ui.unit.dp
  5. import org.mjdev.desktop.helpers.compose.ImagesProvider
  6. import org.mjdev.desktop.interfaces.ITheme
  7. import org.mjdev.desktop.interfaces.IUser
  8. import kotlin.math.roundToInt
  9. /**
  10. * Serializable snapshot of the whole desktop configuration — every tunable that the desktop
  11. * shell exposes ([ITheme]) plus the background [ProviderConfig] list. Persisted as JSON via
  12. * [DesktopConfigStore] at `~/.mjdev/desktop/config.json` and bridged to the live [ITheme]
  13. * with [applyTo] / [fromTheme].
  14. *
  15. * Colors are stored as packed ARGB ints and Dp values as their raw float so the JSON stays
  16. * plain and portable.
  17. */
  18. @Suppress("MemberVisibilityCanBePrivate", "unused")
  19. data class DesktopConfigData(
  20. // background
  21. var backgroundColorArgb: Int = Color(0xFF202020).toArgbInt(),
  22. var backgroundRotationDelay: Long = 60_000L,
  23. // panel
  24. var panelLocation: String = PanelLocation.Bottom.name,
  25. var panelDividerWidth: Float = 12f,
  26. var panelContentPadding: Float = 4f,
  27. var panelHideDelay: Long = 2_000L,
  28. // control center
  29. var controlCenterLocation: String = ControlCenterLocation.Right.name,
  30. var controlPanelHideDelay: Long = 2_000L,
  31. var controlCenterExpandedWidthPercent: Int = 25,
  32. var controlCenterDividerWidth: Float = 12f,
  33. var controlCenterIconSize: Float = 32f,
  34. var controlCenterBackgroundAlpha: Float = 0.6f,
  35. // app menu
  36. var appMenuMinWidthRatio: Float = 0.3f,
  37. var appMenuMinHeightRatio: Float = 0.8f,
  38. var appMenuOuterPadding: Float = 2f,
  39. // background sources
  40. var providers: MutableList<ProviderConfig> = ProviderConfig.defaults(),
  41. ) {
  42. /** Writes every value back onto the live [theme] so the running desktop picks them up. */
  43. fun applyTo(theme: ITheme) {
  44. theme.backgroundColor = Color(backgroundColorArgb)
  45. theme.backgroundRotationDelay = backgroundRotationDelay
  46. theme.panelLocation = panelLocation.toEnum(PanelLocation.Bottom)
  47. theme.panelDividerWidth = panelDividerWidth.dp
  48. theme.panelContentPadding = panelContentPadding.dp
  49. theme.panelHideDelay = panelHideDelay
  50. theme.controlCenterLocation = controlCenterLocation.toEnum(ControlCenterLocation.Right)
  51. theme.controlPanelHideDelay = controlPanelHideDelay
  52. theme.controlCenterExpandedWidthPercent = controlCenterExpandedWidthPercent
  53. theme.controlCenterDividerWidth = controlCenterDividerWidth.dp
  54. theme.controlCenterIconSize = DpSize(controlCenterIconSize.dp, controlCenterIconSize.dp)
  55. theme.controlCenterBackgroundAlpha = controlCenterBackgroundAlpha
  56. theme.appMenuMinWidthRatio = appMenuMinWidthRatio
  57. theme.appMenuMinHeightRatio = appMenuMinHeightRatio
  58. theme.appMenuOuterPadding = appMenuOuterPadding.dp
  59. }
  60. /** Builds the enabled background providers for this config. */
  61. fun buildProviders(user: IUser): List<ImagesProvider> = providers.mapNotNull { it.build(user) }
  62. private inline fun <reified T : Enum<T>> String.toEnum(default: T): T =
  63. enumValues<T>().firstOrNull { it.name == this } ?: default
  64. companion object {
  65. /** Snapshots the current live [theme] into a persistable config, keeping [providers]. */
  66. fun fromTheme(
  67. theme: ITheme,
  68. providers: MutableList<ProviderConfig> = ProviderConfig.defaults(),
  69. ): DesktopConfigData = DesktopConfigData(
  70. backgroundColorArgb = theme.backgroundColor.toArgbInt(),
  71. backgroundRotationDelay = theme.backgroundRotationDelay,
  72. panelLocation = theme.panelLocation.name,
  73. panelDividerWidth = theme.panelDividerWidth.value,
  74. panelContentPadding = theme.panelContentPadding.value,
  75. panelHideDelay = theme.panelHideDelay,
  76. controlCenterLocation = theme.controlCenterLocation.name,
  77. controlPanelHideDelay = theme.controlPanelHideDelay,
  78. controlCenterExpandedWidthPercent = theme.controlCenterExpandedWidthPercent,
  79. controlCenterDividerWidth = theme.controlCenterDividerWidth.value,
  80. controlCenterIconSize = theme.controlCenterIconSize.width.value,
  81. controlCenterBackgroundAlpha = theme.controlCenterBackgroundAlpha,
  82. appMenuMinWidthRatio = theme.appMenuMinWidthRatio,
  83. appMenuMinHeightRatio = theme.appMenuMinHeightRatio,
  84. appMenuOuterPadding = theme.appMenuOuterPadding.value,
  85. providers = providers,
  86. )
  87. private fun Color.toArgbInt(): Int {
  88. val a = (alpha * 255f).roundToInt() and 0xFF
  89. val r = (red * 255f).roundToInt() and 0xFF
  90. val g = (green * 255f).roundToInt() and 0xFF
  91. val b = (blue * 255f).roundToInt() and 0xFF
  92. return (a shl 24) or (r shl 16) or (g shl 8) or b
  93. }
  94. }
  95. }