From 84e9c3628012a109bb11d3fbfc0977d1903948c6 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sun, 15 May 2022 14:24:38 +0200 Subject: [PATCH 1/2] Menus: support rounded selection --- .../com/formdev/flatlaf/ui/FlatMenuBarUI.java | 3 + .../flatlaf/ui/FlatMenuItemRenderer.java | 51 +++++++++++++---- .../com/formdev/flatlaf/ui/FlatMenuUI.java | 57 ++++++++++++++++--- .../com/formdev/flatlaf/FlatLaf.properties | 5 ++ .../flatlaf/ui/TestFlatStyleableInfo.java | 6 ++ .../formdev/flatlaf/ui/TestFlatStyling.java | 6 ++ .../dumps/uidefaults/FlatDarkLaf_1.8.0.txt | 5 ++ .../dumps/uidefaults/FlatLightLaf_1.8.0.txt | 5 ++ .../dumps/uidefaults/FlatTestLaf_1.8.0.txt | 5 ++ .../flatlaf/testing/FlatTestLaf.properties | 10 ++++ .../flatlaf/themeeditor/FlatLafUIKeys.txt | 5 ++ 11 files changed, 138 insertions(+), 20 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java index 273fb080d..1c0ed4da6 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java @@ -70,6 +70,9 @@ public class FlatMenuBarUI /** @since 2 */ @Styleable protected Insets itemMargins; // used in FlatMenuUI + /** @since 3 */ @Styleable protected Insets selectionInsets; + /** @since 3 */ @Styleable protected Insets selectionEmbeddedInsets; + /** @since 3 */ @Styleable protected int selectionArc = -1; /** @since 2 */ @Styleable protected Color hoverBackground; /** @since 2 */ @Styleable protected Color underlineSelectionBackground; /** @since 2 */ @Styleable protected Color underlineSelectionColor; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java index a995be727..bdd093a58 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuItemRenderer.java @@ -63,6 +63,8 @@ * @uiDefault MenuItem.acceleratorArrowGap int * @uiDefault MenuItem.checkBackground Color * @uiDefault MenuItem.checkMargins Insets + * @uiDefault MenuItem.selectionInsets Insets + * @uiDefault MenuItem.selectionArc int * @uiDefault MenuItem.selectionType String null (default) or underline * @uiDefault MenuItem.underlineSelectionBackground Color * @uiDefault MenuItem.underlineSelectionCheckBackground Color @@ -91,6 +93,9 @@ public class FlatMenuItemRenderer @Styleable protected Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" ); @Styleable protected Insets checkMargins = UIManager.getInsets( "MenuItem.checkMargins" ); + /** @since 3 */ @Styleable protected Insets selectionInsets = UIManager.getInsets( "MenuItem.selectionInsets" ); + /** @since 3 */ @Styleable protected int selectionArc = UIManager.getInt( "MenuItem.selectionArc" ); + @Styleable protected Color underlineSelectionBackground = UIManager.getColor( "MenuItem.underlineSelectionBackground" ); @Styleable protected Color underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" ); @Styleable protected Color underlineSelectionColor = UIManager.getColor( "MenuItem.underlineSelectionColor" ); @@ -321,10 +326,16 @@ protected void paintMenuItem( Graphics g, Color selectionBackground, Color selec g.setColor( Color.orange ); g.drawRect( arrowRect.x, arrowRect.y, arrowRect.width - 1, arrowRect.height - 1 ); debug*/ + boolean armedOrSelected = isArmedOrSelected( menuItem ); boolean underlineSelection = isUnderlineSelection(); - paintBackground( g, underlineSelection ? underlineSelectionBackground : selectionBackground ); - if( underlineSelection && isArmedOrSelected( menuItem ) ) - paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight ); + + paintBackground( g ); + if( armedOrSelected ) { + if( underlineSelection ) + paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight ); + else + paintSelection( g, selectionBackground, selectionInsets, selectionArc ); + } paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground ); paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground ); paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground ); @@ -332,21 +343,39 @@ protected void paintMenuItem( Graphics g, Color selectionBackground, Color selec paintArrowIcon( g, arrowRect, arrowIcon ); } - protected void paintBackground( Graphics g, Color selectionBackground ) { - boolean armedOrSelected = isArmedOrSelected( menuItem ); - if( menuItem.isOpaque() || armedOrSelected ) { - // paint background - g.setColor( armedOrSelected - ? deriveBackground( selectionBackground ) - : menuItem.getBackground() ); + /** @since 3 */ + protected void paintBackground( Graphics g ) { + if( menuItem.isOpaque() ) { + g.setColor( menuItem.getBackground() ); g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); } } - protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) { + /** @since 3 */ + protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) { + Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( menuItem.getSize() ), scale( selectionInsets ) ); + + g.setColor( deriveBackground( selectionBackground ) ); + if( selectionArc > 0 ) { + Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g ); + FlatUIUtils.paintComponentBackground( (Graphics2D) g, r.x, r.y, r.width, r.height, 0, scale( selectionArc ) ); + FlatUIUtils.resetRenderingHints( g, oldRenderingHints ); + } else + g.fillRect( r.x, r.y, r.width, r.height ); + } + + /** @since 3 */ + protected void paintUnderlineSelection( Graphics g, Color underlineSelectionBackground, + Color underlineSelectionColor, int underlineSelectionHeight ) + { int width = menuItem.getWidth(); int height = menuItem.getHeight(); + // paint background + g.setColor( deriveBackground( underlineSelectionBackground ) ); + g.fillRect( 0, 0, width, height ); + + // paint underline int underlineHeight = scale( underlineSelectionHeight ); g.setColor( underlineSelectionColor ); if( isTopLevelMenu( menuItem ) ) { diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java index be04f3937..f6e7cba5e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java @@ -20,6 +20,8 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Window; import java.awt.event.MouseEvent; import java.beans.PropertyChangeListener; import java.util.Map; @@ -30,7 +32,9 @@ import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JRootPane; import javax.swing.LookAndFeel; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.MouseInputListener; import javax.swing.plaf.ComponentUI; @@ -71,6 +75,9 @@ * * * + * @uiDefault MenuBar.selectionInsets Insets + * @uiDefault MenuBar.selectionEmbeddedInsets Insets + * @uiDefault MenuBar.selectionArc int * @uiDefault MenuBar.hoverBackground Color * @uiDefault MenuBar.underlineSelectionBackground Color * @uiDefault MenuBar.underlineSelectionColor Color @@ -215,6 +222,9 @@ public void paint( Graphics g, JComponent c ) { protected class FlatMenuRenderer extends FlatMenuItemRenderer { + /** @since 3 */ protected Insets menuBarSelectionInsets = UIManager.getInsets( "MenuBar.selectionInsets" ); + /** @since 3 */ protected Insets menuBarSelectionEmbeddedInsets = UIManager.getInsets( "MenuBar.selectionEmbeddedInsets" ); + /** @since 3 */ protected int menuBarSelectionArc = UIManager.getInt( "MenuBar.selectionArc" ); protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" ); protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground ); protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor ); @@ -226,32 +236,61 @@ protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon, super( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter ); } + /** @since 3 */ @Override - protected void paintBackground( Graphics g, Color selectionBackground ) { + protected void paintBackground( Graphics g ) { if( ((JMenu)menuItem).isTopLevelMenu() ) { - if( isUnderlineSelection() ) - selectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground ); - ButtonModel model = menuItem.getModel(); if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) { - g.setColor( deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ) ); - g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); + // paint hover background + Color color = deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ); + if( isUnderlineSelection() ) { + g.setColor( color ); + g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); + } else + paintSelection( g, color, selectionInsets, selectionArc ); return; } } - super.paintBackground( g, selectionBackground ); + super.paintBackground( g ); } + /** @since 3 */ @Override - protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) { + protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, + int selectionArc ) + { + if( ((JMenu)menuItem).isTopLevelMenu() ) { + JMenuBar menuBar = (JMenuBar) menuItem.getParent(); + JRootPane rootPane = SwingUtilities.getRootPane( menuBar ); + if( rootPane != null && rootPane.getParent() instanceof Window && + rootPane.getJMenuBar() == menuBar && + FlatRootPaneUI.isMenuBarEmbedded( rootPane ) ) + { + selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionEmbeddedInsets, menuBarSelectionEmbeddedInsets ); + } else + selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionInsets, menuBarSelectionInsets ); + selectionArc = getStyleFromMenuBarUI( ui -> (ui.selectionArc != -1) + ? ui.selectionArc : null, menuBarSelectionArc ); + } + + super.paintSelection( g, selectionBackground, selectionInsets, selectionArc ); + } + + /** @since 3 */ + @Override + protected void paintUnderlineSelection( Graphics g, Color underlineSelectionBackground, + Color underlineSelectionColor, int underlineSelectionHeight ) + { if( ((JMenu)menuItem).isTopLevelMenu() ) { + underlineSelectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground ); underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor ); underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1) ? ui.underlineSelectionHeight : null, menuBarUnderlineSelectionHeight ); } - super.paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight ); + super.paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight ); } private T getStyleFromMenuBarUI( Function f, T defaultValue ) { diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index eaf3b1d95..066ce7613 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -422,6 +422,9 @@ MenuBar.border = com.formdev.flatlaf.ui.FlatMenuBarBorder MenuBar.background = @menuBackground MenuBar.hoverBackground = @menuHoverBackground MenuBar.itemMargins = 3,8,3,8 +MenuBar.selectionInsets = 0,0,0,0 +MenuBar.selectionEmbeddedInsets = 0,0,0,0 +MenuBar.selectionArc = 0 #---- MenuItem ---- @@ -444,6 +447,8 @@ MenuItem.textNoAcceleratorGap = 6 MenuItem.acceleratorArrowGap = 2 MenuItem.acceleratorDelimiter = + [mac]MenuItem.acceleratorDelimiter = +MenuItem.selectionInsets = 0,0,0,0 +MenuItem.selectionArc = 0 # for MenuItem.selectionType = underline MenuItem.underlineSelectionBackground = @menuHoverBackground diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java index 3101f1250..044860d66 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java @@ -271,6 +271,9 @@ void menuBar() { Map> expected = expectedMap( "itemMargins", Insets.class, + "selectionInsets", Insets.class, + "selectionEmbeddedInsets", Insets.class, + "selectionArc", int.class, "hoverBackground", Color.class, "underlineSelectionBackground", Color.class, "underlineSelectionColor", Color.class, @@ -355,6 +358,9 @@ private void menuItemRenderer( Map> expected ) { "checkBackground", Color.class, "checkMargins", Insets.class, + "selectionInsets", Insets.class, + "selectionArc", int.class, + "underlineSelectionBackground", Color.class, "underlineSelectionCheckBackground", Color.class, "underlineSelectionColor", Color.class, diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index 4f60e4c5d..c9f9da9a8 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -423,6 +423,9 @@ void menuBar() { FlatMenuBarUI ui = (FlatMenuBarUI) c.getUI(); ui.applyStyle( "itemMargins: 1,2,3,4" ); + ui.applyStyle( "selectionInsets: 1,2,3,4" ); + ui.applyStyle( "selectionEmbeddedInsets: 1,2,3,4" ); + ui.applyStyle( "selectionArc: 8" ); ui.applyStyle( "hoverBackground: #fff" ); ui.applyStyle( "underlineSelectionBackground: #fff" ); ui.applyStyle( "underlineSelectionColor: #fff" ); @@ -509,6 +512,9 @@ private void menuItemRenderer( Consumer applyStyle ) { applyStyle.accept( "checkBackground: #fff" ); applyStyle.accept( "checkMargins: 1,2,3,4" ); + applyStyle.accept( "selectionInsets: 1,2,3,4" ); + applyStyle.accept( "selectionArc: 8" ); + applyStyle.accept( "underlineSelectionBackground: #fff" ); applyStyle.accept( "underlineSelectionCheckBackground: #fff" ); applyStyle.accept( "underlineSelectionColor: #fff" ); diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt index dbaf40eb5..7f0612117 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt @@ -593,6 +593,9 @@ MenuBar.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.Colo MenuBar.highlight #232324 HSL 240 1 14 javax.swing.plaf.ColorUIResource [UI] MenuBar.hoverBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) MenuBar.itemMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionArc 0 +MenuBar.selectionEmbeddedInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] MenuBar.shadow #616365 HSL 210 2 39 javax.swing.plaf.ColorUIResource [UI] MenuBar.windowBindings length=2 [Ljava.lang.Object; [0] F10 @@ -621,8 +624,10 @@ MenuItem.margin 3,6,3,6 javax.swing.plaf.InsetsUIResource [UI] MenuItem.minimumIconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] MenuItem.minimumWidth 72 MenuItem.opaque false +MenuItem.selectionArc 0 MenuItem.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI] MenuItem.selectionForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI] +MenuItem.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] MenuItem.textAcceleratorGap 24 MenuItem.textNoAcceleratorGap 6 MenuItem.underlineSelectionBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt index 6c536ec79..23f4fe7c8 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt @@ -598,6 +598,9 @@ MenuBar.foreground #000000 HSL 0 0 0 javax.swing.plaf.Colo MenuBar.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] MenuBar.hoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) MenuBar.itemMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionArc 0 +MenuBar.selectionEmbeddedInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] MenuBar.shadow #c2c2c2 HSL 0 0 76 javax.swing.plaf.ColorUIResource [UI] MenuBar.windowBindings length=2 [Ljava.lang.Object; [0] F10 @@ -626,8 +629,10 @@ MenuItem.margin 3,6,3,6 javax.swing.plaf.InsetsUIResource [UI] MenuItem.minimumIconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] MenuItem.minimumWidth 72 MenuItem.opaque false +MenuItem.selectionArc 0 MenuItem.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI] MenuItem.selectionForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] +MenuItem.selectionInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] MenuItem.textAcceleratorGap 24 MenuItem.textNoAcceleratorGap 6 MenuItem.underlineSelectionBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt index aa5760b6e..3101df678 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt @@ -600,6 +600,9 @@ MenuBar.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.Colo MenuBar.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] MenuBar.hoverBackground #ffdddd HSL 0 100 93 javax.swing.plaf.ColorUIResource [UI] MenuBar.itemMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionArc 8 +MenuBar.selectionEmbeddedInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionInsets 1,3,1,3 javax.swing.plaf.InsetsUIResource [UI] MenuBar.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI] MenuBar.underlineSelectionBackground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] MenuBar.underlineSelectionColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI] @@ -631,8 +634,10 @@ MenuItem.margin 3,6,3,6 javax.swing.plaf.InsetsUIResource [UI] MenuItem.minimumIconSize 16,16 javax.swing.plaf.DimensionUIResource [UI] MenuItem.minimumWidth 72 MenuItem.opaque false +MenuItem.selectionArc 8 MenuItem.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI] MenuItem.selectionForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI] +MenuItem.selectionInsets 0,3,0,3 javax.swing.plaf.InsetsUIResource [UI] MenuItem.textAcceleratorGap 24 MenuItem.textNoAcceleratorGap 6 MenuItem.underlineSelectionBackground #e6e6e6 HSL 0 0 90 javax.swing.plaf.ColorUIResource [UI] diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties index 28e9c5990..f31817e11 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties @@ -241,6 +241,9 @@ Menu.icon.disabledArrowColor = #ABABAB #---- MenuBar ---- +MenuBar.selectionInsets = 1,3,1,3 +MenuBar.selectionArc = 8 + MenuBar.borderColor = #44f MenuBar.hoverBackground = #fdd @@ -248,6 +251,13 @@ MenuBar.underlineSelectionBackground = #0f0 MenuBar.underlineSelectionColor = #ff0 MenuBar.underlineSelectionHeight = 5 + +#---- MenuItem ---- + +MenuItem.selectionInsets = 0,3,0,3 +MenuItem.selectionArc = 8 + + #---- OptionPane ---- OptionPane.background = #fdd diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt index e7cdd3b8d..22cf9d7f8 100644 --- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt +++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt @@ -462,6 +462,9 @@ MenuBar.foreground MenuBar.highlight MenuBar.hoverBackground MenuBar.itemMargins +MenuBar.selectionArc +MenuBar.selectionEmbeddedInsets +MenuBar.selectionInsets MenuBar.shadow MenuBar.underlineSelectionBackground MenuBar.underlineSelectionColor @@ -487,8 +490,10 @@ MenuItem.margin MenuItem.minimumIconSize MenuItem.minimumWidth MenuItem.opaque +MenuItem.selectionArc MenuItem.selectionBackground MenuItem.selectionForeground +MenuItem.selectionInsets MenuItem.textAcceleratorGap MenuItem.textNoAcceleratorGap MenuItem.underlineSelectionBackground From f1792e46c6b9135a6f94929cc3460ec2df9d7460 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sun, 15 May 2022 16:39:11 +0200 Subject: [PATCH 2/2] Menus: - support different selection colors for top-level JMenus - fixed styling of underline selection properties for top-level JMenus --- .../com/formdev/flatlaf/ui/FlatMenuBarUI.java | 2 + .../com/formdev/flatlaf/ui/FlatMenuUI.java | 65 ++++++++++++------- .../com/formdev/flatlaf/FlatLaf.properties | 6 +- .../flatlaf/ui/TestFlatStyleableInfo.java | 2 + .../formdev/flatlaf/ui/TestFlatStyling.java | 2 + .../dumps/uidefaults/FlatTestLaf_1.8.0.txt | 4 +- .../flatlaf/testing/FlatTestLaf.properties | 3 + .../flatlaf/themeeditor/FlatLafUIKeys.txt | 2 + 8 files changed, 60 insertions(+), 26 deletions(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java index 1c0ed4da6..4361e203c 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuBarUI.java @@ -74,6 +74,8 @@ public class FlatMenuBarUI /** @since 3 */ @Styleable protected Insets selectionEmbeddedInsets; /** @since 3 */ @Styleable protected int selectionArc = -1; /** @since 2 */ @Styleable protected Color hoverBackground; + /** @since 3 */ @Styleable protected Color selectionBackground; + /** @since 3 */ @Styleable protected Color selectionForeground; /** @since 2 */ @Styleable protected Color underlineSelectionBackground; /** @since 2 */ @Styleable protected Color underlineSelectionColor; /** @since 2 */ @Styleable protected int underlineSelectionHeight = -1; diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java index f6e7cba5e..b572d7488 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatMenuUI.java @@ -21,6 +21,7 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; +import java.awt.Rectangle; import java.awt.Window; import java.awt.event.MouseEvent; import java.beans.PropertyChangeListener; @@ -79,6 +80,8 @@ * @uiDefault MenuBar.selectionEmbeddedInsets Insets * @uiDefault MenuBar.selectionArc int * @uiDefault MenuBar.hoverBackground Color + * @uiDefault MenuBar.selectionBackground Color optional; defaults to Menu.selectionBackground + * @uiDefault MenuBar.selectionForeground Color optional; defaults to Menu.selectionForeground * @uiDefault MenuBar.underlineSelectionBackground Color * @uiDefault MenuBar.underlineSelectionColor Color * @uiDefault MenuBar.underlineSelectionHeight int @@ -226,9 +229,11 @@ protected class FlatMenuRenderer /** @since 3 */ protected Insets menuBarSelectionEmbeddedInsets = UIManager.getInsets( "MenuBar.selectionEmbeddedInsets" ); /** @since 3 */ protected int menuBarSelectionArc = UIManager.getInt( "MenuBar.selectionArc" ); protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" ); - protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground ); - protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor ); - protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight ); + /** @since 3 */ protected Color menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" ); + /** @since 3 */ protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" ); + protected Color menuBarUnderlineSelectionBackground = UIManager.getColor( "MenuBar.underlineSelectionBackground" ); + protected Color menuBarUnderlineSelectionColor = UIManager.getColor( "MenuBar.underlineSelectionColor" ); + protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", -1 ); protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon, Font acceleratorFont, String acceleratorDelimiter ) @@ -239,18 +244,15 @@ protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon, /** @since 3 */ @Override protected void paintBackground( Graphics g ) { - if( ((JMenu)menuItem).isTopLevelMenu() ) { - ButtonModel model = menuItem.getModel(); - if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) { - // paint hover background - Color color = deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ); - if( isUnderlineSelection() ) { - g.setColor( color ); - g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); - } else - paintSelection( g, color, selectionInsets, selectionArc ); - return; - } + if( ((JMenu)menuItem).isTopLevelMenu() && isHover() ) { + // paint hover background + Color color = deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ); + if( isUnderlineSelection() ) { + g.setColor( color ); + g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() ); + } else + paintSelection( g, color, selectionInsets, selectionArc ); + return; } super.paintBackground( g ); @@ -258,10 +260,11 @@ protected void paintBackground( Graphics g ) { /** @since 3 */ @Override - protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, - int selectionArc ) - { + protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) { if( ((JMenu)menuItem).isTopLevelMenu() ) { + if( !isHover() ) + selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground, menuBarSelectionBackground, selectionBackground ); + JMenuBar menuBar = (JMenuBar) menuItem.getParent(); JRootPane rootPane = SwingUtilities.getRootPane( menuBar ); if( rootPane != null && rootPane.getParent() instanceof Window && @@ -271,6 +274,7 @@ protected void paintSelection( Graphics g, Color selectionBackground, Insets sel selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionEmbeddedInsets, menuBarSelectionEmbeddedInsets ); } else selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionInsets, menuBarSelectionInsets ); + selectionArc = getStyleFromMenuBarUI( ui -> (ui.selectionArc != -1) ? ui.selectionArc : null, menuBarSelectionArc ); } @@ -284,15 +288,32 @@ protected void paintUnderlineSelection( Graphics g, Color underlineSelectionBack Color underlineSelectionColor, int underlineSelectionHeight ) { if( ((JMenu)menuItem).isTopLevelMenu() ) { - underlineSelectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground ); - underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor ); - underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1) - ? ui.underlineSelectionHeight : null, menuBarUnderlineSelectionHeight ); + underlineSelectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground, underlineSelectionBackground ); + underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor, underlineSelectionColor ); + underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1) ? ui.underlineSelectionHeight : null, + (menuBarUnderlineSelectionHeight != -1) ? menuBarUnderlineSelectionHeight : underlineSelectionHeight ); } super.paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight ); } + @Override + protected void paintText( Graphics g, Rectangle textRect, String text, Color selectionForeground, Color disabledForeground ) { + if( ((JMenu)menuItem).isTopLevelMenu() ) + selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground, menuBarSelectionForeground, selectionForeground ); + + super.paintText( g, textRect, text, selectionForeground, disabledForeground ); + } + + private boolean isHover() { + ButtonModel model = menuItem.getModel(); + return model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled(); + } + + private T getStyleFromMenuBarUI( Function f, T defaultValue, T defaultValue2 ) { + return getStyleFromMenuBarUI( f, (defaultValue != null) ? defaultValue : defaultValue2 ); + } + private T getStyleFromMenuBarUI( Function f, T defaultValue ) { MenuBarUI ui = ((JMenuBar)menuItem.getParent()).getUI(); if( !(ui instanceof FlatMenuBarUI) ) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 066ce7613..807f3df3f 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -422,9 +422,9 @@ MenuBar.border = com.formdev.flatlaf.ui.FlatMenuBarBorder MenuBar.background = @menuBackground MenuBar.hoverBackground = @menuHoverBackground MenuBar.itemMargins = 3,8,3,8 -MenuBar.selectionInsets = 0,0,0,0 -MenuBar.selectionEmbeddedInsets = 0,0,0,0 -MenuBar.selectionArc = 0 +MenuBar.selectionInsets = $MenuItem.selectionInsets +MenuBar.selectionEmbeddedInsets = $MenuItem.selectionInsets +MenuBar.selectionArc = $MenuItem.selectionArc #---- MenuItem ---- diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java index 044860d66..f577dde7c 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java @@ -275,6 +275,8 @@ void menuBar() { "selectionEmbeddedInsets", Insets.class, "selectionArc", int.class, "hoverBackground", Color.class, + "selectionBackground", Color.class, + "selectionForeground", Color.class, "underlineSelectionBackground", Color.class, "underlineSelectionColor", Color.class, "underlineSelectionHeight", int.class, diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index c9f9da9a8..51c107dbb 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -427,6 +427,8 @@ void menuBar() { ui.applyStyle( "selectionEmbeddedInsets: 1,2,3,4" ); ui.applyStyle( "selectionArc: 8" ); ui.applyStyle( "hoverBackground: #fff" ); + ui.applyStyle( "selectionBackground: #fff" ); + ui.applyStyle( "selectionForeground: #fff" ); ui.applyStyle( "underlineSelectionBackground: #fff" ); ui.applyStyle( "underlineSelectionColor: #fff" ); ui.applyStyle( "underlineSelectionHeight: 3" ); diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt index 3101df678..10bfa958a 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt @@ -601,7 +601,9 @@ MenuBar.highlight #ffffff HSL 0 0 100 javax.swing.plaf.Colo MenuBar.hoverBackground #ffdddd HSL 0 100 93 javax.swing.plaf.ColorUIResource [UI] MenuBar.itemMargins 3,8,3,8 javax.swing.plaf.InsetsUIResource [UI] MenuBar.selectionArc 8 -MenuBar.selectionEmbeddedInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionBackground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] +MenuBar.selectionEmbeddedInsets 2,3,2,3 javax.swing.plaf.InsetsUIResource [UI] +MenuBar.selectionForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] MenuBar.selectionInsets 1,3,1,3 javax.swing.plaf.InsetsUIResource [UI] MenuBar.shadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI] MenuBar.underlineSelectionBackground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties index f31817e11..37482bdb4 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties @@ -242,10 +242,13 @@ Menu.icon.disabledArrowColor = #ABABAB #---- MenuBar ---- MenuBar.selectionInsets = 1,3,1,3 +MenuBar.selectionEmbeddedInsets = 2,3,2,3 MenuBar.selectionArc = 8 MenuBar.borderColor = #44f MenuBar.hoverBackground = #fdd +MenuBar.selectionBackground = #f00 +MenuBar.selectionForeground = #0f0 MenuBar.underlineSelectionBackground = #0f0 MenuBar.underlineSelectionColor = #ff0 diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt index 22cf9d7f8..613bdb839 100644 --- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt +++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt @@ -463,7 +463,9 @@ MenuBar.highlight MenuBar.hoverBackground MenuBar.itemMargins MenuBar.selectionArc +MenuBar.selectionBackground MenuBar.selectionEmbeddedInsets +MenuBar.selectionForeground MenuBar.selectionInsets MenuBar.shadow MenuBar.underlineSelectionBackground