From b3c24ac5ea233fbdb06f3321a90f38a9f27f40d6 Mon Sep 17 00:00:00 2001 From: Kirill Grouchnikov Date: Mon, 13 Feb 2023 12:13:26 -0500 Subject: [PATCH] Wire level 2 presentation states For #56 --- .../component/ribbon/RibbonApplicationMenu.kt | 8 +- .../RibbonApplicationMenuPopupHandler.kt | 89 ++++++++++--------- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/ribbon/RibbonApplicationMenu.kt b/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/ribbon/RibbonApplicationMenu.kt index 37adafd6..73c1a287 100644 --- a/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/ribbon/RibbonApplicationMenu.kt +++ b/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/ribbon/RibbonApplicationMenu.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.* import org.pushingpixels.aurora.component.layout.CommandButtonLayoutManager +import org.pushingpixels.aurora.component.layout.CommandButtonLayoutManagerTile import org.pushingpixels.aurora.component.model.* import org.pushingpixels.aurora.component.projection.BaseCommandButtonProjection import org.pushingpixels.aurora.component.utils.popup.RibbonApplicationMenuPopupHandler @@ -175,7 +176,12 @@ object RibbonApplicationMenuButtonPresentationStates { textStyle: TextStyle, fontFamilyResolver: FontFamily.Resolver ): CommandButtonLayoutManager { - throw UnsupportedOperationException() + return CommandButtonLayoutManagerTile( + layoutDirection, + density, + textStyle, + fontFamilyResolver + ) } } } diff --git a/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/utils/popup/RibbonApplicationMenuPopupHandler.kt b/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/utils/popup/RibbonApplicationMenuPopupHandler.kt index 8d86d1ce..b5a1cd4b 100644 --- a/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/utils/popup/RibbonApplicationMenuPopupHandler.kt +++ b/component/src/desktopMain/kotlin/org/pushingpixels/aurora/component/utils/popup/RibbonApplicationMenuPopupHandler.kt @@ -38,6 +38,7 @@ import org.pushingpixels.aurora.component.projection.BaseCommandButtonProjection import org.pushingpixels.aurora.component.projection.CommandButtonProjection import org.pushingpixels.aurora.component.ribbon.RibbonApplicationMenuCommandPopupMenuPresentationModel import org.pushingpixels.aurora.component.ribbon.RibbonApplicationMenuContentModel +import org.pushingpixels.aurora.component.utils.TitleLabel import org.pushingpixels.aurora.component.utils.getPlacementAwarePopupShift import org.pushingpixels.aurora.theming.* import org.pushingpixels.aurora.theming.colorscheme.AuroraSkinColors @@ -219,7 +220,6 @@ internal class RibbonApplicationMenuPopupHandler( menuContentModel: RibbonApplicationMenuContentModel, menuPresentationModel: RibbonApplicationMenuCommandPopupMenuPresentationModel, overlays: Map, - popupHandler: BaseCommandMenuHandler, onLevel1ActionRollover: (Command) -> Unit, level1ContentLayoutInfo: RibbonApplicationMenuLevel1ContentLayoutInfo ) { @@ -240,6 +240,32 @@ internal class RibbonApplicationMenuPopupHandler( val currSecondaryPresentationModel = if (hasOverlay) itemButtonPresentationModel.overlayWith(overlays[secondaryCommand]!!) else itemButtonPresentationModel + + val level2PopupHandler = + object : BaseCommandMenuHandler { + override fun showPopupContent( + popupOriginator: Component, + layoutDirection: LayoutDirection, + density: Density, + textStyle: TextStyle, + fontFamilyResolver: FontFamily.Resolver, + skinColors: AuroraSkinColors, + skinPainters: AuroraPainters, + decorationAreaType: DecorationAreaType, + compositionLocalContext: CompositionLocalContext, + anchorBoundsInWindow: Rect, + popupTriggerAreaInWindow: Rect, + contentModel: State, + presentationModel: CommandPopupMenuPresentationModel, + displayPrototypeCommand: BaseCommand?, + toDismissPopupsOnActivation: Boolean, + popupPlacementStrategy: PopupPlacementStrategy, + overlays: Map + ) { + onLevel1ActionRollover.invoke(secondaryCommand) + } + } + // Project a command button for each level 1 command, passing the same // overlays into it. val actionInteractionSource: MutableInteractionSource = remember { MutableInteractionSource() } @@ -247,7 +273,7 @@ internal class RibbonApplicationMenuPopupHandler( contentModel = secondaryCommand, presentationModel = currSecondaryPresentationModel, overlays = overlays, - popupHandler = popupHandler + popupHandler = level2PopupHandler ).project( modifier = Modifier.fillMaxWidth(), actionInteractionSource = actionInteractionSource, @@ -269,7 +295,7 @@ internal class RibbonApplicationMenuPopupHandler( @Composable private fun generateLevel2Content( modifier: Modifier, - menuContentModel: CommandMenuContentModel?, + level1Command: Command?, itemPresentationState: CommandButtonPresentationState, overlays: Map ) { @@ -290,8 +316,18 @@ internal class RibbonApplicationMenuPopupHandler( .background(color = backgroundColorScheme.backgroundFillColor) .padding(all = 1.0.dp) ) { - if (menuContentModel != null) { - for (commandGroup in menuContentModel.groups) { + if (level1Command?.secondaryContentModel != null) { + for (commandGroup in level1Command.secondaryContentModel.groups) { + if (commandGroup.title != null) { + TitleLabel( + modifier = Modifier.fillMaxWidth(), + title = commandGroup.title, + presentationModel = LabelPresentationModel( + horizontalAlignment = HorizontalAlignment.Leading + ) + ) + } + for (secondaryCommand in commandGroup.commands) { // Check if we have a presentation overlay for this level 2 command val hasOverlay = overlays.containsKey(secondaryCommand) @@ -519,33 +555,7 @@ internal class RibbonApplicationMenuPopupHandler( val popupMenu = AuroraSwingPopupMenu(toDismissPopupsOnActivation) popupContent.setContent { - var currentLevel2Model by remember { mutableStateOf(null) } - val level2PopupHandler = - object : BaseCommandMenuHandler { - override fun showPopupContent( - popupOriginator: Component, - layoutDirection: LayoutDirection, - density: Density, - textStyle: TextStyle, - fontFamilyResolver: FontFamily.Resolver, - skinColors: AuroraSkinColors, - skinPainters: AuroraPainters, - decorationAreaType: DecorationAreaType, - compositionLocalContext: CompositionLocalContext, - anchorBoundsInWindow: Rect, - popupTriggerAreaInWindow: Rect, - contentModel: State, - presentationModel: CommandPopupMenuPresentationModel, - displayPrototypeCommand: BaseCommand?, - toDismissPopupsOnActivation: Boolean, - popupPlacementStrategy: PopupPlacementStrategy, - overlays: Map - ) { - currentLevel2Model = contentModel.value - val commandCount = currentLevel2Model?.groups?.sumOf { it.commands.size } ?: 0 - println("Level2 with $commandCount commands") - } - } + var activeLevel1Command by remember { mutableStateOf(null) } // Get the current composition context CompositionLocalProvider(compositionLocalContext) { @@ -568,19 +578,18 @@ internal class RibbonApplicationMenuPopupHandler( menuContentModel = contentModel.value!!, menuPresentationModel = presentationModel, overlays = overlays, - popupHandler = level2PopupHandler, - onLevel1ActionRollover = { command -> - if (command.secondaryContentModel == null) { - currentLevel2Model = null - println("Level2 clearing") - } + onLevel1ActionRollover = { + activeLevel1Command = it }, level1ContentLayoutInfo = level1ContentLayoutInfo ) + val level2PresentationState = if ((secondaryStates != null) && (activeLevel1Command != null)) + secondaryStates.getOrDefault(activeLevel1Command!!, CommandButtonPresentationState.Medium) + else CommandButtonPresentationState.Medium generateLevel2Content( modifier = Modifier.weight(1.0f, true), - menuContentModel = currentLevel2Model, - itemPresentationState = CommandButtonPresentationState.Medium, + level1Command = activeLevel1Command, + itemPresentationState = level2PresentationState, overlays = overlays ) }