From c89d617612b02121f363ea026a2383ca79b3cccc Mon Sep 17 00:00:00 2001 From: Jannis Weis <31143295+weisJ@users.noreply.github.com> Date: Mon, 2 May 2022 21:12:24 +0200 Subject: [PATCH] Button: Draw focus border for borderless variant --- .../darklaf/ui/button/DarkButtonBorder.java | 23 ++++++-- .../weisj/darklaf/ui/button/DarkButtonUI.java | 53 +++++++++++-------- .../ui/splitbutton/DarkSplitButtonBorder.java | 8 +-- .../ui/splitbutton/DarkSplitButtonUI.java | 7 ++- 4 files changed, 62 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java index cfc8f6ed..e7ecbc9b 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2019-2021 Jannis Weis + * Copyright (c) 2019-2022 Jannis Weis * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, @@ -32,7 +32,9 @@ import com.github.weisj.darklaf.ui.util.DarkUIUtil; import com.github.weisj.darklaf.util.AlignmentExt; import com.github.weisj.darklaf.util.PropertyUtil; import com.github.weisj.darklaf.util.graphics.GraphicsContext; +import com.github.weisj.darklaf.util.graphics.GraphicsUtil; import com.github.weisj.swingdsl.visualpadding.VisualPaddingProvider; +import org.jetbrains.annotations.NotNull; /** @author Jannis Weis */ public class DarkButtonBorder implements Border, UIResource, VisualPaddingProvider { @@ -148,7 +150,22 @@ public class DarkButtonBorder implements Border, UIResource, VisualPaddingProvid protected void paintBorderlessBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { - + if (paintFocus(c)) { + AbstractButton b = (AbstractButton) c; + DarkButtonUI ui = DarkUIUtil.getUIOfType(b.getUI(), DarkButtonUI.class); + if (ui == null) return; + Insets margin = b.getMargin(); + if (margin instanceof UIResource) { + margin = null; + } + Rectangle r = ui.backgroundContentRect(b, width, height, margin); + + GraphicsContext context = GraphicsUtil.setupStrokePainting(g); + g.translate(x, y); + g.setColor(getBorderColor(c, true)); + PaintUtil.paintLineBorder((Graphics2D) g, r.x, r.y, r.width, r.height, getArc(c)); + context.restore(); + } } protected void paintLineBorder(final Component c, final Graphics2D g2, final int arc, final boolean focus, @@ -287,7 +304,7 @@ public class DarkButtonBorder implements Border, UIResource, VisualPaddingProvid } @Override - public Insets getVisualPaddings(final Component c) { + public @NotNull Insets getVisualPaddings(@NotNull final Component c) { return getBorderInsets(c); } } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java index b866632f..d2867f03 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2019-2021 Jannis Weis + * Copyright (c) 2019-2022 Jannis Weis * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, @@ -290,29 +290,40 @@ public class DarkButtonUI extends BasicButtonUI implements ButtonConstants { return new Rectangle(bx, by, bw, bh); } + protected Rectangle backgroundContentRect(final AbstractButton b, final int width, final int height, + final Insets m) { + Border border = b.getBorder(); + Insets ins = border != null ? border.getBorderInsets(b) : new Insets(0, 0, 0, 0); + Insets margin = m; + if (margin == null) { + margin = new Insets(0, 0, 0, 0); + } else { + // Ensure margins really only affect the size of the background around the content. + // If the button is larger than expected adjust the margin s.t. the shadow background is + // only painted in the area around the viewRect specified by the margin. + Rectangle r = iconRect.union(textRect); + margin.left = r.x - margin.left; + margin.right = width - (r.x + r.width + margin.right); + margin.top = r.y - margin.top; + margin.bottom = height - (r.y + r.height + margin.bottom); + } + + int x = Math.max(ins.left, margin.left); + int y = Math.max(ins.top, margin.top); + int w = width - x - Math.max(ins.right, margin.right); + int h = height - y - Math.max(ins.bottom, margin.bottom); + return new Rectangle(x, y, w, h); + } + protected void paintBorderlessBackground(final AbstractButton b, final Graphics2D g, final int arc, final int width, final int height, final Insets m) { - if (isRolloverBorderless(b)) { - Border border = b.getBorder(); - Insets ins = border != null ? border.getBorderInsets(b) : new Insets(0, 0, 0, 0); - Insets margin = m; - if (margin == null) { - margin = new Insets(0, 0, 0, 0); - } else { - // Ensure margins really only affect the size of the background around the content. - // If the button is larger than expected adjust the margin s.t. the shadow background is - // only painted in the area around the viewRect specified by the margin. - Rectangle r = iconRect.union(textRect); - margin.left = r.x - margin.left; - margin.right = width - (r.x + r.width + margin.right); - margin.top = r.y - margin.top; - margin.bottom = height - (r.y + r.height + margin.bottom); - } + if (isRolloverBorderless(b) || isArmedBorderless(b)) { + Rectangle backgroundRect = backgroundContentRect(b, width, height, m); - int x = Math.max(ins.left, margin.left); - int y = Math.max(ins.top, margin.top); - int w = width - x - Math.max(ins.right, margin.right); - int h = height - y - Math.max(ins.bottom, margin.bottom); + int x = backgroundRect.x; + int y = backgroundRect.y; + int w = backgroundRect.width; + int h = backgroundRect.height; GraphicsUtil.setupStrokePainting(g); if (ButtonConstants.isBorderlessRectangular(b)) { diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonBorder.java b/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonBorder.java index ccccb8c7..9ab5fb4e 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonBorder.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonBorder.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2020-2021 Jannis Weis + * Copyright (c) 2020-2022 Jannis Weis * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, @@ -59,8 +59,7 @@ public class DarkSplitButtonBorder extends DarkButtonBorder { DarkSplitButtonUI ui = DarkUIUtil.getUIOfType(((JSplitButton) c).getUI(), DarkSplitButtonUI.class); if (ui != null && ui.getDrawOutline(c)) { - boolean armed = ui.isArmedBorderless(ui.splitButton) - || (ui.useArrowButton() && ui.isArmedBorderless(ui.arrowButton)); + boolean armed = ui.isArmedBorderless(ui.splitButton); g.setColor(ui.getBorderlessOutline(armed)); } else { g.setColor(getBorderColor(c, false)); @@ -75,7 +74,8 @@ public class DarkSplitButtonBorder extends DarkButtonBorder { if (!borderless) return hasDefaultAction; if (hasDefaultAction && ButtonConstants.isBorderlessVariant(c)) { DarkSplitButtonUI ui = DarkUIUtil.getUIOfType(((JSplitButton) c).getUI(), DarkSplitButtonUI.class); - return ui != null && ui.isRolloverBorderless((AbstractButton) c); + return ui != null && + (ui.isRolloverBorderless((AbstractButton) c) || ui.isArmedBorderless((AbstractButton) c)); } return false; } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonUI.java index 3b806b27..5f8171c4 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/splitbutton/DarkSplitButtonUI.java @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright (c) 2020-2021 Jannis Weis + * Copyright (c) 2020-2022 Jannis Weis * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, @@ -188,6 +188,11 @@ public class DarkSplitButtonUI extends DarkButtonUI { return super.isRolloverBorderless(b) || (useArrowButton() && arrowButton.getModel().isRollover()); } + @Override + public boolean isArmedBorderless(final AbstractButton b) { + return super.isArmedBorderless(b) || (useArrowButton() && arrowButton.getModel().isArmed()); + } + @Override protected void paintDarklafBorderBgImpl(final AbstractButton c, final Graphics2D g, final boolean showShadow, final int shadow, final int effectiveArc, final Rectangle bgRect) {