refactor: merge context menu style to AreaBoxStyle

This commit is contained in:
2023-11-16 00:00:09 +08:00
parent 2c5767d7a7
commit 0c19398487

View File

@@ -26,15 +26,9 @@ package com.highcapable.flexiui.component
import androidx.compose.foundation.ContextMenuItem import androidx.compose.foundation.ContextMenuItem
import androidx.compose.foundation.ContextMenuRepresentation import androidx.compose.foundation.ContextMenuRepresentation
import androidx.compose.foundation.ContextMenuState import androidx.compose.foundation.ContextMenuState
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.sizeIn import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@@ -50,12 +44,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.FocusDirection import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.input.InputMode import androidx.compose.ui.input.InputMode
import androidx.compose.ui.input.InputModeManager import androidx.compose.ui.input.InputModeManager
import androidx.compose.ui.input.key.KeyEventType import androidx.compose.ui.input.key.KeyEventType
@@ -66,7 +57,6 @@ import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalInputModeManager import androidx.compose.ui.platform.LocalInputModeManager
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties import androidx.compose.ui.window.PopupProperties
@@ -80,12 +70,10 @@ import java.awt.event.KeyEvent
@Immutable @Immutable
data class ContextMenuStyle( data class ContextMenuStyle(
val backgroundColor: Color, val contentColor: Color,
val textColor: Color, val borderColor: Color,
val padding: Dp, val contentStyle: AreaBoxStyle?,
val shadowSize: Dp, val borderStyle: AreaBoxStyle?
val contentShape: Shape?,
val borderShape: Shape?
) )
internal class DesktopContextMenuRepresentation(private val style: ContextMenuStyle) : ContextMenuRepresentation { internal class DesktopContextMenuRepresentation(private val style: ContextMenuStyle) : ContextMenuRepresentation {
@@ -94,8 +82,8 @@ internal class DesktopContextMenuRepresentation(private val style: ContextMenuSt
override fun Representation(state: ContextMenuState, items: () -> List<ContextMenuItem>) { override fun Representation(state: ContextMenuState, items: () -> List<ContextMenuItem>) {
val status = state.status val status = state.status
if (status is ContextMenuState.Status.Open) { if (status is ContextMenuState.Status.Open) {
val contentShape = style.contentShape ?: return val contentStyle = style.contentStyle ?: return
val borderShape = style.borderShape ?: return val borderStyle = style.borderStyle ?: return
var focusManager: FocusManager? by mutableStateOf(null) var focusManager: FocusManager? by mutableStateOf(null)
var inputModeManager: InputModeManager? by mutableStateOf(null) var inputModeManager: InputModeManager? by mutableStateOf(null)
Popup( Popup(
@@ -120,22 +108,21 @@ internal class DesktopContextMenuRepresentation(private val style: ContextMenuSt
}) { }) {
focusManager = LocalFocusManager.current focusManager = LocalFocusManager.current
inputModeManager = LocalInputModeManager.current inputModeManager = LocalInputModeManager.current
Column( AreaColumn(
modifier = Modifier modifier = Modifier
.shadow(style.shadowSize, borderShape)
.background(style.backgroundColor, borderShape)
.padding(style.padding)
.width(IntrinsicSize.Max) .width(IntrinsicSize.Max)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState()),
color = style.borderColor,
style = borderStyle
) { ) {
items().forEach { item -> items().forEach { item ->
MenuItemContent( MenuItemContent(
shape = contentShape, style = contentStyle,
onClick = { onClick = {
state.status = ContextMenuState.Status.Closed state.status = ContextMenuState.Status.Closed
item.onClick() item.onClick()
} }
) { Text(text = item.label) } ) { Text(text = item.label, color = style.contentColor) }
} }
} }
} }
@@ -145,32 +132,23 @@ internal class DesktopContextMenuRepresentation(private val style: ContextMenuSt
@Composable @Composable
private fun MenuItemContent( private fun MenuItemContent(
shape: Shape, style: AreaBoxStyle,
onClick: () -> Unit, onClick: () -> Unit,
content: @Composable RowScope.() -> Unit content: @Composable RowScope.() -> Unit
) { ) {
var hovered by remember { mutableStateOf(false) } var hovered by remember { mutableStateOf(false) }
Row( AreaRow(
modifier = Modifier modifier = Modifier
.clip(shape) .rippleClickable(onClick = onClick)
.rippleClickable(
onClick = onClick,
interactionSource = remember { MutableInteractionSource() }
)
.onHover { hovered = it } .onHover { hovered = it }
.fillMaxWidth() .fillMaxWidth()
// Preferred min and max width used during the intrinsic measurement.
.sizeIn( .sizeIn(
minWidth = 112.dp, minWidth = DefaultDesktopContextMenuContentMinWidth,
maxWidth = 280.dp, maxWidth = DefaultDesktopContextMenuContentMaxWidth,
minHeight = 32.dp minHeight = DefaultDesktopContextMenuContentMinHeight
)
.padding(
PaddingValues(
horizontal = 16.dp,
vertical = 0.dp
)
), ),
color = Color.Transparent,
style = style,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { content() } ) { content() }
} }
@@ -196,22 +174,32 @@ object DesktopContextMenu {
val LocalContextMenuStyle = compositionLocalOf { val LocalContextMenuStyle = compositionLocalOf {
ContextMenuStyle( ContextMenuStyle(
backgroundColor = Color.Unspecified, borderColor = Color.Unspecified,
textColor = Color.Unspecified, contentColor = Color.Unspecified,
padding = Dp.Unspecified, contentStyle = null,
shadowSize = Dp.Unspecified, borderStyle = null
contentShape = null,
borderShape = null
) )
} }
@Composable @Composable
@ReadOnlyComposable @ReadOnlyComposable
internal fun defaultContextMenuStyle() = ContextMenuStyle( internal fun defaultContextMenuStyle() = ContextMenuStyle(
backgroundColor = LocalContextMenuStyle.current.backgroundColor.orElse() ?: LocalColors.current.foregroundPrimary, contentColor = LocalContextMenuStyle.current.contentColor.orElse() ?: LocalColors.current.textPrimary,
textColor = LocalContextMenuStyle.current.textColor.orElse() ?: LocalColors.current.textPrimary, borderColor = LocalContextMenuStyle.current.borderColor.orElse() ?: AreaBox.color,
padding = LocalContextMenuStyle.current.padding.orElse() ?: LocalSizes.current.spacingTertiary, contentStyle = LocalContextMenuStyle.current.contentStyle ?: AreaBox.style.copy(
shadowSize = LocalContextMenuStyle.current.shadowSize.orElse() ?: LocalSizes.current.zoomSizeTertiary, padding = 0.dp,
contentShape = LocalContextMenuStyle.current.contentShape ?: LocalShapes.current.secondary, startPadding = DefaultDesktopContextMenuContentPadding,
borderShape = LocalContextMenuStyle.current.borderShape ?: LocalShapes.current.primary endPadding = DefaultDesktopContextMenuContentPadding,
shape = LocalShapes.current.secondary
),
borderStyle = LocalContextMenuStyle.current.borderStyle ?: AreaBox.style.copy(
padding = LocalSizes.current.spacingTertiary,
shadowSize = LocalSizes.current.zoomSizeTertiary,
shape = LocalShapes.current.primary
) )
)
private val DefaultDesktopContextMenuContentMinWidth = 112.dp
private val DefaultDesktopContextMenuContentMaxWidth = 280.dp
private val DefaultDesktopContextMenuContentMinHeight = 32.dp
private val DefaultDesktopContextMenuContentPadding = 16.dp