DesktopPanel.kt 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package eu.mjdev.desktop.components.desktoppanel
  2. import androidx.compose.animation.*
  3. import androidx.compose.foundation.ExperimentalFoundationApi
  4. import androidx.compose.foundation.TooltipArea
  5. import androidx.compose.foundation.TooltipPlacement
  6. import androidx.compose.foundation.background
  7. import androidx.compose.foundation.gestures.Orientation.Vertical
  8. import androidx.compose.foundation.layout.*
  9. import androidx.compose.material.Divider
  10. import androidx.compose.runtime.Composable
  11. import androidx.compose.runtime.MutableState
  12. import androidx.compose.runtime.mutableStateOf
  13. import androidx.compose.ui.Alignment
  14. import androidx.compose.ui.Modifier
  15. import androidx.compose.ui.graphics.Brush
  16. import androidx.compose.ui.graphics.Color
  17. import androidx.compose.ui.layout.onPlaced
  18. import androidx.compose.ui.unit.Dp
  19. import androidx.compose.ui.unit.DpOffset
  20. import androidx.compose.ui.unit.DpSize
  21. import androidx.compose.ui.unit.dp
  22. import androidx.compose.ui.window.WindowPosition
  23. import eu.mjdev.desktop.components.desktoppanel.applets.DesktopMenuIcon
  24. import eu.mjdev.desktop.components.desktoppanel.applets.DesktopPanelFavoriteApps
  25. import eu.mjdev.desktop.components.desktoppanel.applets.DesktopPanelLanguage
  26. import eu.mjdev.desktop.components.shadow.TopShadow
  27. import eu.mjdev.desktop.components.sliding.SlidingMenu
  28. import eu.mjdev.desktop.components.sliding.VisibilityState
  29. import eu.mjdev.desktop.components.sliding.VisibilityState.Companion.rememberVisibilityState
  30. import eu.mjdev.desktop.extensions.Compose.height
  31. import eu.mjdev.desktop.provider.DesktopProvider
  32. import eu.mjdev.desktop.provider.DesktopProvider.Companion.LocalDesktop
  33. import eu.mjdev.desktop.provider.data.App
  34. import eu.mjdev.desktop.windows.ChromeWindow
  35. @OptIn(ExperimentalFoundationApi::class)
  36. @Suppress("FunctionName")
  37. @Composable
  38. fun DesktopPanel(
  39. api: DesktopProvider = LocalDesktop.current,
  40. backgroundColor: Color = api.currentUser.theme.backgroundColor,
  41. shadowColor: Color = backgroundColor,
  42. iconColor: Color = Color.Black,
  43. iconBackgroundColor: Color = Color.White,
  44. dividerWidth: Dp = 4.dp,
  45. iconSize: DpSize = DpSize(56.dp, 56.dp),
  46. iconPadding: PaddingValues = PaddingValues(4.dp),
  47. iconOuterPadding: PaddingValues = PaddingValues(2.dp),
  48. panelAlpha: Float = 0.7f,
  49. showMenuIcon: Boolean = true,
  50. panelContentPadding: PaddingValues = PaddingValues(4.dp),
  51. panelState: VisibilityState = rememberVisibilityState(),
  52. enterAnimation: EnterTransition = fadeIn() + slideInVertically(initialOffsetY = { it }),
  53. exitAnimation: ExitTransition = slideOutVertically(targetOffsetY = { it }) + fadeOut(),
  54. tooltipHeight: Dp = 64.dp,
  55. tooltipData: MutableState<Any?> = mutableStateOf(null),
  56. onTooltip: (item: Any?) -> Unit = { item -> tooltipData.value = item },
  57. panelHeight: (visible: Boolean) -> Dp = { visible ->
  58. if (visible) iconSize.height + iconOuterPadding.height + tooltipHeight + panelContentPadding.height
  59. else dividerWidth
  60. },
  61. onMenuIconClicked: () -> Unit = {},
  62. onFocusChange: (Boolean) -> Unit = {},
  63. tooltipConverter: (Any?) -> TooltipData = { item ->
  64. when (item) {
  65. is App -> TooltipData(title = item.name, description = item.comment)
  66. else -> TooltipData(title = item.toString())
  67. }
  68. }
  69. ) = ChromeWindow(
  70. visible = true,
  71. enterAnimation = enterAnimation,
  72. exitAnimation = exitAnimation,
  73. position = WindowPosition.Aligned(Alignment.BottomCenter),
  74. size = DpSize(
  75. api.containerSize.width,
  76. panelHeight(panelState.isVisible)
  77. ),
  78. onFocusChange = { focused ->
  79. panelState.onFocusChange(focused)
  80. onFocusChange(focused)
  81. }
  82. ) {
  83. SlidingMenu(
  84. modifier = Modifier.fillMaxWidth(),
  85. orientation = Vertical,
  86. state = panelState,
  87. ) { isVisible ->
  88. Divider(
  89. modifier = Modifier
  90. .fillMaxWidth()
  91. .height(dividerWidth),
  92. color = Color.Transparent,
  93. thickness = dividerWidth
  94. )
  95. if (isVisible) {
  96. TooltipArea(
  97. modifier = Modifier.fillMaxWidth().wrapContentHeight(),
  98. tooltip = {
  99. DesktopPanelTooltip(
  100. tooltipData.value,
  101. converter = tooltipConverter
  102. )
  103. },
  104. tooltipPlacement = TooltipPlacement.CursorPoint(
  105. alignment = Alignment.TopEnd,
  106. offset = DpOffset(32.dp, 32.dp)
  107. )
  108. ) {
  109. Column {
  110. Box(
  111. modifier = Modifier.fillMaxWidth()
  112. .height(tooltipHeight)
  113. )
  114. TopShadow(
  115. modifier = Modifier.fillMaxWidth()
  116. .wrapContentHeight()
  117. .onPlaced(panelState::onPlaced),
  118. color = shadowColor,
  119. contentBackgroundColor = backgroundColor.copy(alpha = panelAlpha)
  120. ) {
  121. Column {
  122. Divider(
  123. modifier = Modifier
  124. .fillMaxWidth()
  125. .height(2.dp),
  126. color = Color.White.copy(0.1f),
  127. thickness = 2.dp
  128. )
  129. Box(
  130. modifier = Modifier.fillMaxWidth()
  131. .wrapContentHeight()
  132. .background(
  133. brush = Brush.verticalGradient(
  134. colors = listOf(
  135. backgroundColor.copy(alpha = 0.3f),
  136. backgroundColor.copy(alpha = 0.7f),
  137. backgroundColor.copy(alpha = 0.3f),
  138. )
  139. )
  140. )
  141. .padding(panelContentPadding)
  142. ) {
  143. if (showMenuIcon) {
  144. DesktopMenuIcon(
  145. modifier = Modifier.align(Alignment.CenterStart),
  146. iconColor = iconColor,
  147. iconBackgroundColor = iconBackgroundColor,
  148. iconSize = iconSize,
  149. iconPadding = iconPadding,
  150. iconOuterPadding = iconOuterPadding,
  151. onTooltip = onTooltip,
  152. onClick = onMenuIconClicked
  153. )
  154. }
  155. DesktopPanelFavoriteApps(
  156. modifier = Modifier.align(Alignment.Center),
  157. iconColor = iconColor,
  158. iconBackgroundColor = iconBackgroundColor,
  159. iconSize = iconSize,
  160. iconPadding = iconPadding,
  161. iconOuterPadding = iconOuterPadding,
  162. onTooltip = onTooltip
  163. )
  164. DesktopPanelLanguage(
  165. modifier = Modifier.align(Alignment.CenterEnd),
  166. onTooltip = onTooltip,
  167. onClick = {
  168. // todo
  169. }
  170. )
  171. }
  172. }
  173. }
  174. }
  175. }
  176. }
  177. }
  178. }