Browse Source

windowed elements

milan jurkulák 2 years ago
parent
commit
f91b3f7259

+ 4 - 2
build.gradle.kts

@@ -52,8 +52,10 @@ allprojects {
         // javascript
         // implementation(libs.mozilla.rhino)
         // no log
-        implementation ("org.slf4j:slf4j-nop:2.0.7")
-        implementation ("me.xdrop:fuzzywuzzy:1.4.0")
+        implementation("org.slf4j:slf4j-nop:2.0.7")
+        implementation("me.xdrop:fuzzywuzzy:1.4.0")
+//        implementation("com.github.SmartToolFactory:Compose-Extended-Colors:1.0.0-alpha06")
+//        implementation("com.github.SmartToolFactory:Compose-Extended-Gestures:2.0.0")
 //        implementation ("androidx.compose.ui:ui-text-google-fonts:1.6.8")
     }
 }

+ 4 - 2
src/main/kotlin/eu/mjdev/desktop/Main.kt

@@ -3,10 +3,11 @@ package eu.mjdev.desktop
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.material.MaterialTheme
 import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.window.application
 import eu.mjdev.desktop.components.appsmenu.AppsMenu
-import eu.mjdev.desktop.components.controlpanel.ControlCenter
+import eu.mjdev.desktop.components.controlcenter.ControlCenter
 import eu.mjdev.desktop.components.desktoppanel.DesktopPanel
 import eu.mjdev.desktop.components.slidemenu.VisibilityState.Companion.rememberVisibilityState
 import eu.mjdev.desktop.provider.DesktopProvider
@@ -17,8 +18,9 @@ import eu.mjdev.desktop.windows.MainWindow
 fun main() = application(
     exitProcessOnExit = true
 ) {
+    val scope = rememberCoroutineScope()
     CompositionLocalProvider(
-        LocalDesktop provides DesktopProvider()
+        LocalDesktop provides DesktopProvider(scope)
     ) {
         MaterialTheme {
             val api: DesktopProvider = LocalDesktop.current

+ 12 - 1
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/ControlCenter.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/ControlCenter.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel
+package eu.mjdev.desktop.components.controlcenter
 
 import androidx.compose.animation.*
 import androidx.compose.foundation.ExperimentalFoundationApi
@@ -15,6 +15,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.Divider
 import androidx.compose.material.Icon
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -176,5 +177,15 @@ fun ControlCenter(
             val height = api.containerSize.height
             window.setWindowBounds(x, y, width, height)
         }
+        DisposableEffect(Unit) {
+            scope.launch {
+                pagerState.scrollToPage(0)
+            }
+            onDispose {
+                scope.launch {
+                    pagerState.scrollToPage(0)
+                }
+            }
+        }
     }
 }

+ 1 - 1
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/ControlCenterPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/ControlCenterPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel
+package eu.mjdev.desktop.components.controlcenter
 
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Settings

+ 2 - 2
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/pages/BluetoothSettingsPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/BluetoothSettingsPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel.pages
+package eu.mjdev.desktop.components.controlcenter.pages
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Bluetooth
 import androidx.compose.ui.Modifier
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
 
 @Suppress("FunctionName")
 fun BluetoothSettingsPage() = ControlCenterPage(

+ 2 - 2
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/pages/DisplaySettingsPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/DisplaySettingsPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel.pages
+package eu.mjdev.desktop.components.controlcenter.pages
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.ScreenshotMonitor
 import androidx.compose.ui.Modifier
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
 
 @Suppress("FunctionName")
 fun DisplaySettingsPage() = ControlCenterPage(

+ 2 - 2
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/pages/MainSettingsPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/MainSettingsPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel.pages
+package eu.mjdev.desktop.components.controlcenter.pages
 
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.layout.*
@@ -9,7 +9,7 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
 import eu.mjdev.desktop.components.custom.DateTime
 import eu.mjdev.desktop.components.custom.PowerBlock
 import eu.mjdev.desktop.components.custom.UserAvatar

+ 2 - 2
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/pages/SoundSettingsPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/SoundSettingsPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel.pages
+package eu.mjdev.desktop.components.controlcenter.pages
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Headphones
 import androidx.compose.ui.Modifier
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
 
 @Suppress("FunctionName")
 fun SoundSettingsPage() = ControlCenterPage(

+ 2 - 2
src/main/kotlin/eu/mjdev/desktop/components/controlpanel/pages/WifiSettingsPage.kt → src/main/kotlin/eu/mjdev/desktop/components/controlcenter/pages/WifiSettingsPage.kt

@@ -1,4 +1,4 @@
-package eu.mjdev.desktop.components.controlpanel.pages
+package eu.mjdev.desktop.components.controlcenter.pages
 
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Wifi
 import androidx.compose.ui.Modifier
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
 
 @Suppress("FunctionName")
 fun WifiSettingsPage() = ControlCenterPage(

+ 7 - 3
src/main/kotlin/eu/mjdev/desktop/provider/AppsProvider.kt

@@ -130,9 +130,13 @@ class AppsProvider(
             ).let { json ->
                 Gson().fromJson(json ?: "[]", List::class.java)
             }.mapNotNull { appName ->
-                val deskFile = desktopFiles.firstOrNull { deskFile ->
-                    deskFile?.file?.name?.contentEquals(appName.toString()) == true
-                }
+                val deskFile = desktopFiles.filter { deskFile ->
+                    deskFile?.file?.name?.contains(appName.toString()) == true
+                }.map { deskFile ->
+                    Pair(FuzzySearch.ratio(appName.toString(), deskFile.file.name), deskFile)
+                }.maxByOrNull {
+                    it.first
+                }?.second
                 if (deskFile != null) {
                     App(desktopFile = deskFile, file = deskFile?.file)
                 } else {

+ 13 - 11
src/main/kotlin/eu/mjdev/desktop/provider/DesktopProvider.kt

@@ -5,9 +5,10 @@ import androidx.compose.runtime.compositionLocalOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import eu.mjdev.desktop.components.controlpanel.ControlCenterPage
-import eu.mjdev.desktop.components.controlpanel.pages.*
+import eu.mjdev.desktop.components.controlcenter.ControlCenterPage
+import eu.mjdev.desktop.components.controlcenter.pages.*
 import eu.mjdev.desktop.provider.data.User
+import kotlinx.coroutines.CoroutineScope
 import java.awt.Toolkit
 import java.io.BufferedReader
 import java.io.File
@@ -19,7 +20,8 @@ import javax.script.ScriptEngineManager
 
 @Suppress("unused")
 class DesktopProvider(
-    val currentUser: User = User.Empty, // todo
+    private val scope: CoroutineScope? = null,
+    val currentUser: User = User.load(scope), // todo
 ) {
     private val _currentUser: MutableState<User> = mutableStateOf(currentUser)
 
@@ -76,16 +78,16 @@ class DesktopProvider(
     }
 
     fun runCommandForOutput(vararg cmd: String): String? = runCatching {
-        val pb = ProcessBuilder(*cmd)
-        val p: Process
+        val sj = StringJoiner(System.lineSeparator())
         var result = ""
         try {
-            p = pb.start()
-            val reader = BufferedReader(InputStreamReader(p.inputStream))
-            val sj = StringJoiner(System.lineSeparator())
-            reader.lines().iterator().forEachRemaining { newElement: String? ->
-                sj.add(newElement)
-            }
+            val p = ProcessBuilder(*cmd).start()
+            BufferedReader(InputStreamReader(p.inputStream))
+                .lines()
+                .iterator()
+                .forEachRemaining { newElement: String? ->
+                    sj.add(newElement)
+                }
             result = sj.toString()
             p.waitFor()
             p.destroy()

+ 13 - 0
src/main/kotlin/eu/mjdev/desktop/provider/data/App.kt

@@ -1,7 +1,9 @@
 package eu.mjdev.desktop.provider.data
 
 import androidx.compose.ui.graphics.Color
+import me.xdrop.fuzzywuzzy.FuzzySearch
 import java.io.File
+import kotlin.reflect.full.companionObjectInstance
 
 @Suppress("unused", "MemberVisibilityCanBePrivate")
 class App(
@@ -32,6 +34,9 @@ class App(
     var enabled: Boolean = true
     var iconTint: Color? = null
 
+    val iconBackground: Color
+        get() : Color = runCatching { colorFromName() }.getOrNull() ?: Color.White
+
     fun start() = runCatching {
         println("Starting app: $name [$exec]")
         ProcessBuilder("/bin/bash", "-c", exec).start()
@@ -39,6 +44,14 @@ class App(
         error.printStackTrace()
     }
 
+    private fun colorFromName(): Color {
+        val companion = Color::class.companionObjectInstance
+        val members = if (companion != null) companion::class.members.toList() else emptyList()
+        return members.map {
+            Pair(FuzzySearch.ratio(name, it.name), it)
+        }.maxByOrNull { it.first }?.second?.call(null) as? Color ?: Color.White
+    }
+
     companion object {
         val Empty: App = App()
 

+ 16 - 3
src/main/kotlin/eu/mjdev/desktop/provider/data/Theme.kt

@@ -1,5 +1,7 @@
 package eu.mjdev.desktop.provider.data
 
+import androidx.compose.animation.Animatable
+import androidx.compose.animation.core.tween
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.Dp
@@ -8,10 +10,13 @@ import androidx.compose.ui.unit.dp
 import eu.mjdev.desktop.components.fonticon.MaterialIconFont
 import eu.mjdev.desktop.components.fonticon.MaterialSymbolsSharp
 import eu.mjdev.desktop.extensions.Compose.SuperDarkGray
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 // todo all customizable
 @Suppress("unused", "MemberVisibilityCanBePrivate")
 class Theme(
+    val scope: CoroutineScope?,
     backgroundColor: Color,
     backgroundRotationDelay: Long,
 
@@ -30,7 +35,7 @@ class Theme(
     iconSet: MaterialIconFont,
 ) {
 
-    val backgroundColorState = mutableStateOf(backgroundColor)
+    val backgroundColorState = Animatable(backgroundColor)
     val panelLocationState = mutableStateOf(panelLocation)
     val panelHideDelayState = mutableStateOf(panelHideDelay)
     val controlCenterLocationState = mutableStateOf(controlCenterLocation)
@@ -47,7 +52,11 @@ class Theme(
     var backgroundColor
         get() = backgroundColorState.value
         set(value) {
-            backgroundColorState.value = value
+            scope?.launch {
+                backgroundColorState.animateTo(value, animationSpec = tween(1500))
+            } ?: {
+                println("Can not set background color")
+            }
         }
     val panelLocation get() = panelLocationState.value
     val panelHideDelay get() = panelHideDelayState.value
@@ -67,7 +76,11 @@ class Theme(
     val backgroundRotationDelay get() = backgroundRotationDelayState.value
 
     companion object {
-        val Default = Theme(
+        @Suppress("FunctionName")
+        fun Default(
+            scope: CoroutineScope?
+        ) = Theme(
+            scope = scope,
             iconSet = MaterialSymbolsSharp,
 
             backgroundColor = Color.SuperDarkGray,

+ 6 - 2
src/main/kotlin/eu/mjdev/desktop/provider/data/User.kt

@@ -4,6 +4,7 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.AccountCircle
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.graphics.vector.ImageVector
+import kotlinx.coroutines.CoroutineScope
 
 @Suppress("MemberVisibilityCanBePrivate")
 class User(
@@ -23,11 +24,14 @@ class User(
     val theme get() = themeState.value
 
     companion object {
-        val Empty = User(
+        // todo
+        fun load(
+            scope: CoroutineScope?
+        ) = User(
             name = null,
             picture = Icons.Filled.AccountCircle,
             config = DesktopConfig.Default,
-            theme = Theme.Default
+            theme = Theme.Default(scope)
         )
     }
 }