Kaynağa Gözat

focus fixes

milan jurkulák 2 yıl önce
ebeveyn
işleme
e6bd875c17

+ 21 - 6
src/main/kotlin/eu/mjdev/desktop/Main.kt

@@ -20,6 +20,21 @@ fun main() = application(
     val panelState = rememberVisibilityState()
     val menuState = rememberVisibilityState()
 
+    val handleMenuFocus: (Boolean) -> Unit = { focus ->
+        if (!menuState.isWindowFocus) {
+            menuState.hide()
+        }
+    }
+
+    val handlePanelFocus: (Boolean) -> Unit = { focus ->
+    }
+
+    val handleControlCenterFocus: (Boolean) -> Unit = { focus ->
+        if (!controlCenterState.isWindowFocus) {
+            controlCenterState.hide()
+        }
+    }
+
     MaterialTheme {
         CompositionLocalProvider(
             LocalDesktop provides DesktopProvider(scope)
@@ -30,18 +45,18 @@ fun main() = application(
                 menuState = menuState
             ) {
                 DesktopPanel(
-                    menuState = menuState,
                     panelState = panelState,
-                    onMenuIconClicked = {
-                        menuState.toggle()
-                    }
+                    onMenuIconClicked = { menuState.toggle() },
+                    onFocusChange = { focus -> handlePanelFocus(focus) }
                 )
                 AppsMenu(
                     menuState = menuState,
-                    panelState = panelState
+                    panelState = panelState,
+                    onFocusChange = { focus -> handleMenuFocus(focus) }
                 )
                 ControlCenter(
-                    controlCenterState = controlCenterState
+                    controlCenterState = controlCenterState,
+                    onFocusChange = { focus -> handleControlCenterFocus(focus) }
                 )
             }
         }

+ 6 - 4
src/main/kotlin/eu/mjdev/desktop/components/appsmenu/AppsMenu.kt

@@ -42,6 +42,7 @@ fun AppsMenu(
     enterAnimation: EnterTransition = fadeIn() + slideInVertically(initialOffsetY = { it }),
     exitAnimation: ExitTransition = slideOutVertically(targetOffsetY = { it }) + fadeOut(),
     items: MutableState<List<Any>> = remember(api.appsProvider) { mutableStateOf(api.appsProvider.appCategories) },
+    onFocusChange: (Boolean) -> Unit = {},
 ) = ChromeWindow(
     visible = menuState.isVisible,
     enterAnimation = enterAnimation,
@@ -50,7 +51,10 @@ fun AppsMenu(
         panelState.bounds.x,
         api.containerSize.height - (panelState.bounds.height + appMenuMinHeight)
     ),
-    onFocusChange = { focus -> if (!focus) menuState.hide() }
+    onFocusChange = { focused ->
+        menuState.onFocusChange(focused)
+        onFocusChange(focused)
+    }
 ) {
     Box(
         modifier = Modifier
@@ -59,9 +63,7 @@ fun AppsMenu(
                 min = appMenuMinHeight,
                 max = appMenuMinHeight
             )
-            .onPlaced {
-                // menuState.bounds = it.toDPBounds()
-            }
+            .onPlaced(menuState::onPlaced)
     ) {
         Box(
             modifier = Modifier

+ 5 - 1
src/main/kotlin/eu/mjdev/desktop/components/controlcenter/ControlCenter.kt

@@ -47,6 +47,7 @@ fun ControlCenter(
     scope: CoroutineScope = rememberCoroutineScope(),
     enterAnimation: EnterTransition = fadeIn() + slideInHorizontally(initialOffsetX = { it }),
     exitAnimation: ExitTransition = slideOutHorizontally(targetOffsetX = { it }) + fadeOut(),
+    onFocusChange: (Boolean) -> Unit = {},
 ) = ChromeWindow(
     visible = true,
     enterAnimation = enterAnimation,
@@ -57,7 +58,10 @@ fun ControlCenter(
     } else {
         DpSize(controlCenterDividerWidth, api.containerSize.height)
     },
-    onFocusChange = { focus -> if (!focus) controlCenterState.hide() }
+    onFocusChange = { focused ->
+        controlCenterState.onFocusChange(focused)
+        onFocusChange(focused)
+    }
 ) {
     SlidingMenu(
         modifier = Modifier.fillMaxHeight(),

+ 8 - 6
src/main/kotlin/eu/mjdev/desktop/components/desktoppanel/DesktopPanel.kt

@@ -29,7 +29,6 @@ import eu.mjdev.desktop.components.sliding.SlidingMenu
 import eu.mjdev.desktop.components.sliding.VisibilityState
 import eu.mjdev.desktop.components.sliding.VisibilityState.Companion.rememberVisibilityState
 import eu.mjdev.desktop.extensions.Compose.height
-import eu.mjdev.desktop.helpers.DpBounds.Companion.toDpBounds
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 import eu.mjdev.desktop.provider.data.App
@@ -53,13 +52,13 @@ fun DesktopPanel(
     panelState: VisibilityState = rememberVisibilityState(),
     enterAnimation: EnterTransition = fadeIn() + slideInVertically(initialOffsetY = { it }),
     exitAnimation: ExitTransition = slideOutVertically(targetOffsetY = { it }) + fadeOut(),
-    menuState: VisibilityState = rememberVisibilityState(),
     tooltipData: MutableState<Any?> = mutableStateOf(null),
     onTooltip: (item: Any?) -> Unit = { item -> tooltipData.value = item },
     panelHeight: (visible: Boolean) -> Dp = { visible ->
         if (visible) iconSize.height + iconOuterPadding.height else dividerWidth
     },
     onMenuIconClicked: () -> Unit = {},
+    onFocusChange: (Boolean) -> Unit = {},
 ) = ChromeWindow(
     visible = true,
     enterAnimation = enterAnimation,
@@ -69,7 +68,10 @@ fun DesktopPanel(
         api.containerSize.width,
         panelHeight(panelState.isVisible)
     ),
-    onFocusChange = { focus -> if (!focus && !menuState.isVisible) panelState.hide() }
+    onFocusChange = { focused ->
+        panelState.onFocusChange(focused)
+        onFocusChange(focused)
+    }
 ) {
     SlidingMenu(
         modifier = Modifier.fillMaxWidth(),
@@ -100,9 +102,9 @@ fun DesktopPanel(
                 )
             ) {
                 TopShadow(
-                    modifier = Modifier.fillMaxWidth().wrapContentHeight().onPlaced {
-                        panelState.bounds = it.toDpBounds()
-                    },
+                    modifier = Modifier.fillMaxWidth()
+                        .wrapContentHeight()
+                        .onPlaced(panelState::onPlaced),
                     color = shadowColor,
                     contentBackgroundColor = backgroundColor.copy(alpha = panelAlpha)
                 ) {

+ 14 - 1
src/main/kotlin/eu/mjdev/desktop/components/sliding/VisibilityState.kt

@@ -1,8 +1,10 @@
 package eu.mjdev.desktop.components.sliding
 
 import androidx.compose.runtime.*
+import androidx.compose.ui.layout.LayoutCoordinates
 import androidx.compose.ui.unit.DpSize
 import eu.mjdev.desktop.helpers.DpBounds
+import eu.mjdev.desktop.helpers.DpBounds.Companion.toDpBounds
 import eu.mjdev.desktop.provider.DesktopProvider
 import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
 import kotlinx.coroutines.CoroutineScope
@@ -17,12 +19,12 @@ class VisibilityState(
 ) {
     val visibleState: MutableState<Boolean> = mutableStateOf(startState)
     val boundsState: MutableState<DpBounds> = mutableStateOf(DpBounds.Zero)
+    val focusState: MutableState<Boolean> = mutableStateOf(false)
 
     var bounds: DpBounds
         get() = boundsState.value
         set(value) {
             boundsState.value = value
-            println("Bounds : $value")
         }
 
     var isVisible: Boolean
@@ -35,6 +37,9 @@ class VisibilityState(
             }
         }
 
+    val isWindowFocus
+        get() = isVisible && focusState.value
+
     fun show() {
         if (!isVisible) {
             if (enabled) scope.launch {
@@ -55,6 +60,14 @@ class VisibilityState(
         visibleState.value = !visibleState.value
     }
 
+    fun onPlaced(lc: LayoutCoordinates) {
+        bounds = lc.toDpBounds()
+    }
+
+    fun onFocusChange(focus: Boolean) {
+        focusState.value = focus
+    }
+
     companion object {
         @Composable
         fun rememberVisibilityState(