From 24323293f10d5b00bb90e188f8c22a83b98aa239 Mon Sep 17 00:00:00 2001 From: weisj Date: Thu, 19 Mar 2020 12:28:03 +0100 Subject: [PATCH] Added option to disable border on specific side of buttons. This allows for button groups that visually are one long buttons (e.g. they act as radio buttons). Extended ButtonDemo to show new border mechanic. Fixed ToggleButtons not showing the pressed background. --- .../darklaf/ui/button/DarkButtonBorder.java | 137 +++++++++++++----- .../weisj/darklaf/ui/button/DarkButtonUI.java | 90 ++++++++---- .../darklaf/ui/button/DarkToggleButtonUI.java | 24 ++- .../ui/filechooser/DarkFileChooserUI.java | 7 + core/src/test/java/ui/button/ButtonDemo.java | 16 ++ .../github/weisj/darklaf/util/Alignment.java | 45 ++++-- .../weisj/darklaf/util/AlignmentExt.java | 105 ++++++++++++++ 7 files changed, 343 insertions(+), 81 deletions(-) create mode 100644 utils/src/main/java/com/github/weisj/darklaf/util/AlignmentExt.java 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 8a69c09e..b7fecff6 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 @@ -23,6 +23,7 @@ */ package com.github.weisj.darklaf.ui.button; +import com.github.weisj.darklaf.util.AlignmentExt; import com.github.weisj.darklaf.util.DarkUIUtil; import com.github.weisj.darklaf.util.GraphicsContext; @@ -87,6 +88,51 @@ public class DarkButtonBorder implements Border, UIResource { if (labelInsets == null) labelInsets = new Insets(0, 0, 0, 0); } + public static boolean showDropShadow(final JComponent c) { + return showDropShadow(getCornerFlag(c)); + } + + public static boolean showDropShadow(final AlignmentExt a) { + return a == null + || a == AlignmentExt.SOUTH + || a == AlignmentExt.SOUTH_EAST + || a == AlignmentExt.SOUTH_WEST + || a == AlignmentExt.LEFT + || a == AlignmentExt.RIGHT + || a == AlignmentExt.BOTTOM + || a == AlignmentExt.MIDDLE_HORIZONTAL; + } + + protected int getArc(final Component c) { + if (DarkButtonUI.isNoArc(c)) return 0; + boolean square = DarkButtonUI.isSquare(c); + boolean alt = DarkButtonUI.chooseAlternativeArc(c); + return square ? alt ? arc : squareArc : alt ? squareArc : arc; + } + + protected int getFocusArc(final Component c) { + if (DarkButtonUI.isNoArc(c)) return minimumArc; + boolean square = DarkButtonUI.isSquare(c); + boolean alt = DarkButtonUI.chooseAlternativeArc(c); + return square ? alt ? focusArc : squareFocusArc : alt ? squareFocusArc : focusArc; + } + + public static AlignmentExt getCornerFlag(final Component component) { + if (component instanceof JComponent) { + Object align = ((JComponent) component).getClientProperty(DarkButtonUI.KEY_CORNER); + return align instanceof AlignmentExt ? (AlignmentExt) align : null; + } + return null; + } + + protected int getShadowSize() { + return shadowSize; + } + + protected int getBorderSize() { + return borderSize; + } + @Override public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { @@ -99,50 +145,56 @@ public class DarkButtonBorder implements Border, UIResource { int arc = getArc(c); int focusArc = getFocusArc(c); GraphicsContext config = new GraphicsContext(g); + AlignmentExt corner = getCornerFlag(c); - if (c.isEnabled()) { - paintShadow(g2, width, height, arc); - } - - int shadowHeight = getShadowSize(); + boolean paintShadow = showDropShadow(corner); + int shadowHeight = paintShadow ? getShadowSize() : 0; int borderSize = getBorderSize(); + Insets insetMask = new Insets(borderSize, borderSize, borderSize, borderSize); + Insets focusIns = new Insets(0, 0, 0, 0); + if (corner != null) { + focusIns = corner.maskInsets(focusIns, -borderSize - focusArc); + insetMask = corner.maskInsets(insetMask, -arc); + } + + int bx = insetMask.left; + int by = insetMask.top; + int bw = width - insetMask.left - insetMask.right; + int bh = height - insetMask.top - insetMask.bottom; + int fx = focusIns.left; + int fy = focusIns.top; + int fw = width - focusIns.left - focusIns.right; + int fh = height - focusIns.top - focusIns.bottom; + + if (c.isEnabled() && paintShadow) { + paintShadow((Graphics2D) g, bx, by, bw, bh, arc); + } - if (c.hasFocus()) { - DarkUIUtil.paintFocusBorder(g2, width, height - shadowHeight, focusArc, borderSize); + if (paintFocus(c)) { + g.translate(fx, fy); + DarkUIUtil.paintFocusBorder(g2, fw, fh - shadowHeight, focusArc, borderSize); + g.translate(-fx, -fy); } g2.setColor(getBorderColor(c)); - DarkUIUtil.paintLineBorder(g2, borderSize, borderSize, width - 2 * borderSize, - height - 2 * borderSize - shadowHeight, arc); + DarkUIUtil.paintLineBorder(g2, bx, by, bw, bh - shadowHeight, arc); config.restore(); } - protected int getArc(final Component c) { - if (DarkButtonUI.isNoArc(c)) return 0; - boolean square = DarkButtonUI.isSquare(c); - boolean alt = DarkButtonUI.chooseAlternativeArc(c); - return square ? alt ? arc : squareArc : alt ? squareArc : arc; - } - - protected int getFocusArc(final Component c) { - if (DarkButtonUI.isNoArc(c)) return minimumArc; - boolean square = DarkButtonUI.isSquare(c); - boolean alt = DarkButtonUI.chooseAlternativeArc(c); - return square ? alt ? focusArc : squareFocusArc : alt ? squareFocusArc : focusArc; + protected boolean paintFocus(final Component c) { + if (c instanceof AbstractButton) { + return ((AbstractButton) c).isFocusPainted() && c.hasFocus(); + } + return c.hasFocus(); } - private void paintShadow(final Graphics2D g2, final int width, final int height, final int arc) { + private void paintShadow(final Graphics2D g2, final int x, final int y, + final int width, final int height, final int arc) { GraphicsContext context = new GraphicsContext(g2); - int borderSize = getBorderSize(); int shadowSize = getShadowSize(); - Area shadowShape = new Area(new RoundRectangle2D.Double(borderSize, borderSize, - width - 2 * borderSize, height - 2 * borderSize, - arc, arc)); - Area innerArea = new Area(new RoundRectangle2D.Double(borderSize, borderSize, - width - 2 * borderSize, - height - 2 * borderSize - shadowSize, - arc, arc)); + Area shadowShape = new Area(new RoundRectangle2D.Double(x, y, width, height, arc, arc)); + Area innerArea = new Area(new RoundRectangle2D.Double(x, y, width, height - shadowSize, arc, arc)); shadowShape.subtract(innerArea); g2.setComposite(DarkUIUtil.SHADOW_COMPOSITE); g2.setColor(shadowColor); @@ -150,16 +202,12 @@ public class DarkButtonBorder implements Border, UIResource { context.restore(); } - protected int getShadowSize() { - return shadowSize; - } - - protected int getBorderSize() { - return borderSize; + public boolean isBorderOpaque() { + return false; } protected Color getBorderColor(final Component c) { - if (c.hasFocus()) { + if (paintFocus(c)) { return focusBorderColor; } else if (c instanceof JButton && ((JButton) c).isDefaultButton() && c.isEnabled()) { return defaultBorderColor; @@ -184,10 +232,19 @@ public class DarkButtonBorder implements Border, UIResource { : thinInsets : square ? squareInsets : insets; - return new InsetsUIResource(pad.top, pad.left, pad.bottom + shadow, pad.right); + return maskInsets(new InsetsUIResource(pad.top, pad.left, pad.bottom, pad.right), c, shadow); } - public boolean isBorderOpaque() { - return false; + protected Insets maskInsets(final Insets ins, final Component c, final int shadow) { + ins.bottom += shadow; + AlignmentExt alignment = getCornerFlag(c); + if (alignment == null) return ins; + Insets insetMask = new Insets(borderSize, borderSize, borderSize + shadow, borderSize); + insetMask = alignment.maskInsetsInverted(insetMask); + ins.top -= insetMask.top; + ins.bottom -= insetMask.bottom; + ins.left -= insetMask.left; + ins.right -= insetMask.right; + return ins; } } 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 7a66dd1e..25c12f99 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 @@ -55,6 +55,7 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene public static final String KEY_SQUARE = KEY_PREFIX + "square"; public static final String KEY_THIN = KEY_PREFIX + "thin"; public static final String KEY_NO_SHADOW_OVERWRITE = KEY_PREFIX + "noShadowOverwrite"; + public static final String KEY_CORNER = KEY_PREFIX + "cornerFlag"; public static final String VARIANT_ONLY_LABEL = "onlyLabel"; public static final String VARIANT_FULL_SHADOW = "fullShadow"; public static final String VARIANT_SHADOW = "shadow"; @@ -198,6 +199,17 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene if (!isShadowVariant(b)) { i = new Insets(i.top, borderSize, i.bottom, borderSize); } + + AlignmentExt corner = DarkButtonBorder.getCornerFlag(c); + Insets insetMask = new Insets(borderSize, borderSize, borderSize, borderSize); + if (corner != null) { + insetMask = corner.maskInsetsInverted(insetMask, 0); + } + i.left -= insetMask.left; + i.right -= insetMask.right; + i.top -= insetMask.top; + i.bottom -= insetMask.bottom; + viewRect.x = i.left; viewRect.y = i.top; viewRect.width = width - (i.right + i.left); @@ -348,33 +360,59 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene Insets margin = b.getMargin(); if (margin instanceof UIResource) margin = new Insets(0, 0, 0, 0); if (isShadowVariant(c)) { - if (b.isEnabled() && b.getModel().isRollover()) { - GraphicsUtil.setupAAPainting(g2); - g.setColor(getShadowColor(b)); - if (isFullShadow(c)) { - g.fillRect(margin.left, margin.top, - width - margin.left - margin.right, - height - margin.top - margin.bottom); - } else if (doConvertToShadow(b)) { - int size = Math.min(width - margin.left - margin.right, - height - margin.left - margin.right); - g.fillRoundRect((width - size) / 2, (height - size) / 2, size, size, arc, arc); - } else { - g.fillRoundRect(margin.left, margin.top, - width - margin.left - margin.right, - height - margin.top - margin.bottom, - arc, arc); - } - } + paintShadowBackground(g, c, g2, b, arc, width, height, margin); } else { - g2.setColor(getBackgroundColor(c)); - if (isSquare(c) && !chooseAlternativeArc(c)) { - g2.fillRect(borderSize, borderSize, width - 2 * borderSize, - height - 2 * borderSize - shadowHeight); - } else { - DarkUIUtil.fillRoundRect((Graphics2D) g, borderSize, borderSize, width - 2 * borderSize, - height - 2 * borderSize - shadowHeight, arc); - } + paintDefaultBackground((Graphics2D) g, c, g2, arc, width, height); + } + } + } + + protected void paintDefaultBackground(final Graphics2D g, final JComponent c, final Graphics2D g2, + final int arc, final int width, final int height) { + g2.setColor(getBackgroundColor(c)); + int shadow = DarkButtonBorder.showDropShadow(c) ? shadowHeight : 0; + int effectiveArc = isSquare(c) && !chooseAlternativeArc(c) ? 0 : arc; + Rectangle bgRect = getEffectiveRect(width, height, c, -(effectiveArc + 1)); + if (effectiveArc == 0) { + g2.fillRect(bgRect.x, bgRect.y, bgRect.width, bgRect.height - shadow); + } else { + DarkUIUtil.fillRoundRect(g, bgRect.x, bgRect.y, bgRect.width, bgRect.height - shadow, effectiveArc); + } + } + + protected Rectangle getEffectiveRect(final int width, final int height, final JComponent c, final int adjustment) { + AlignmentExt corner = DarkButtonBorder.getCornerFlag(c); + Insets insetMask = new Insets(borderSize, borderSize, borderSize, borderSize); + if (corner != null) { + insetMask = corner.maskInsets(insetMask, adjustment); + } + + int bx = insetMask.left; + int by = insetMask.top; + int bw = width - insetMask.left - insetMask.right; + int bh = height - insetMask.top - insetMask.bottom; + return new Rectangle(bx, by, bw, bh); + } + + protected void paintShadowBackground(final Graphics g, final JComponent c, final Graphics2D g2, + final AbstractButton b, final int arc, + final int width, final int height, final Insets margin) { + if (b.isEnabled() && b.getModel().isRollover()) { + GraphicsUtil.setupAAPainting(g2); + g.setColor(getShadowColor(b)); + if (isFullShadow(c)) { + g.fillRect(margin.left, margin.top, + width - margin.left - margin.right, + height - margin.top - margin.bottom); + } else if (doConvertToShadow(b)) { + int size = Math.min(width - margin.left - margin.right, + height - margin.left - margin.right); + g.fillRoundRect((width - size) / 2, (height - size) / 2, size, size, arc, arc); + } else { + g.fillRoundRect(margin.left, margin.top, + width - margin.left - margin.right, + height - margin.top - margin.bottom, + arc, arc); } } } diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkToggleButtonUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkToggleButtonUI.java index 7fef5fb0..1bd80fdd 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkToggleButtonUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/button/DarkToggleButtonUI.java @@ -116,14 +116,28 @@ public class DarkToggleButtonUI extends DarkButtonUI { } protected Color getBackgroundColor(final JComponent c) { - if (c instanceof JToggleButton && c.isEnabled()) { - if (((JToggleButton) c).isSelected()) { - return background; + AbstractButton b = (AbstractButton) c; + boolean rollOver = (b.isRolloverEnabled() || doConvertToShadow(b)) && (((JButton) c).getModel().isRollover()); + boolean clicked = b.getModel().isArmed(); + if (c.isEnabled()) { + if (clicked) { + return clickBackground; + } else if (rollOver) { + return hoverBackground; } else { - return backgroundInactive; + if (c instanceof JToggleButton && c.isEnabled()) { + if (((JToggleButton) c).isSelected()) { + return background; + } else { + return backgroundInactive; + } + } else { + return super.getBackgroundColor(c); + } } + } else { + return inactiveBackground; } - return super.getBackgroundColor(c); } @Override diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java index 34b4e35c..70427a27 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java @@ -26,6 +26,7 @@ package com.github.weisj.darklaf.ui.filechooser; import com.github.weisj.darklaf.components.tooltip.TooltipAwareButton; import com.github.weisj.darklaf.components.tooltip.TooltipAwareToggleButton; import com.github.weisj.darklaf.ui.button.DarkButtonUI; +import com.github.weisj.darklaf.util.AlignmentExt; import sun.swing.FilePane; import javax.accessibility.AccessibleContext; @@ -107,6 +108,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge { upFolderButton.putClientProperty(DarkButtonUI.KEY_SQUARE, true); upFolderButton.putClientProperty(DarkButtonUI.KEY_ALT_ARC, true); upFolderButton.setText(null); + upFolderButton.setFocusPainted(false); upFolderButton.setIcon(upFolderIcon); upFolderButton.setToolTipText(upFolderToolTipText); upFolderButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, @@ -125,6 +127,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge { JButton b = new TooltipAwareButton(homeFolderIcon); b.putClientProperty(DarkButtonUI.KEY_NO_SHADOW_OVERWRITE, true); b.setToolTipText(toolTipText); + b.setFocusPainted(false); b.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, homeFolderAccessibleName); b.setAlignmentX(JComponent.LEFT_ALIGNMENT); @@ -160,10 +163,12 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge { // List Button listViewButton = new TooltipAwareToggleButton(listViewIcon); + listViewButton.setFocusPainted(false); listViewButton.putClientProperty(DarkButtonUI.KEY_NO_SHADOW_OVERWRITE, true); listViewButton.putClientProperty(DarkButtonUI.KEY_SQUARE, true); listViewButton.putClientProperty(DarkButtonUI.KEY_ALT_ARC, true); listViewButton.putClientProperty(DarkButtonUI.KEY_SQUARE, Boolean.TRUE); + listViewButton.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.LEFT); listViewButton.setToolTipText(listViewButtonToolTipText); listViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, listViewButtonAccessibleName); @@ -177,9 +182,11 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge { // Details Button detailsViewButton = new TooltipAwareToggleButton(detailsViewIcon); + detailsViewButton.setFocusPainted(false); detailsViewButton.putClientProperty(DarkButtonUI.KEY_NO_SHADOW_OVERWRITE, true); detailsViewButton.putClientProperty(DarkButtonUI.KEY_SQUARE, true); detailsViewButton.putClientProperty(DarkButtonUI.KEY_ALT_ARC, true); + detailsViewButton.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.RIGHT); detailsViewButton.setToolTipText(detailsViewButtonToolTipText); detailsViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, detailsViewButtonAccessibleName); detailsViewButton.setAlignmentX(JComponent.LEFT_ALIGNMENT); diff --git a/core/src/test/java/ui/button/ButtonDemo.java b/core/src/test/java/ui/button/ButtonDemo.java index fbe58d29..ba241865 100644 --- a/core/src/test/java/ui/button/ButtonDemo.java +++ b/core/src/test/java/ui/button/ButtonDemo.java @@ -25,6 +25,7 @@ package ui.button; import com.github.weisj.darklaf.icons.IconLoader; import com.github.weisj.darklaf.ui.button.DarkButtonUI; +import com.github.weisj.darklaf.util.AlignmentExt; import ui.ComponentDemo; import ui.DemoPanel; import ui.QuickColorChooser; @@ -95,6 +96,21 @@ public class ButtonDemo implements ComponentDemo { setSelectedItem(DarkButtonUI.VARIANT_NONE); addItemListener(e -> button.putClientProperty(DarkButtonUI.KEY_VARIANT, e.getItem())); }}); + controlPanel.add(new JLabel(DarkButtonUI.KEY_CORNER + ":")); + controlPanel.add(new JComboBox() {{ + addItem("None"); + for (AlignmentExt a : AlignmentExt.values()) { + addItem(a.name()); + } + setSelectedItem("None"); + addItemListener(e -> { + if ("None".equals(e.getItem())) { + button.putClientProperty(DarkButtonUI.KEY_CORNER, null); + } else { + button.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.valueOf(e.getItem().toString())); + } + }); + }}); controlPanel.add(new JCheckBox("Icon Only") {{ setSelected(false); addActionListener(e -> button.setText(isSelected() ? null : "Test Button")); diff --git a/utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java b/utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java index 5e562b43..3688ec1a 100644 --- a/utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java +++ b/utils/src/main/java/com/github/weisj/darklaf/util/Alignment.java @@ -235,32 +235,57 @@ public enum Alignment { } } - public Insets maskInsets(final Insets insets) { + return maskInsets(insets, 0); + } + + + public Insets maskInsets(final Insets insets, final int maskValue) { + return maskInsets(insets.top, insets.left, insets.bottom, insets.right, maskValue); + } + + public Insets maskInsets(final int top, final int left, final int bottom, final int right, final int mask) { switch (this) { case NORTH: - return new Insets(insets.top, 0, 0, 0); + return new Insets(top, mask, mask, mask); case NORTH_EAST: - return new Insets(insets.top, 0, 0, insets.right); + return new Insets(top, mask, mask, right); case EAST: - return new Insets(0, 0, 0, insets.right); + return new Insets(mask, mask, mask, right); case SOUTH_EAST: - return new Insets(0, 0, insets.bottom, insets.right); + return new Insets(mask, mask, bottom, right); case SOUTH: - return new Insets(0, 0, insets.bottom, 0); + return new Insets(mask, mask, bottom, mask); case SOUTH_WEST: - return new Insets(0, insets.left, insets.bottom, 0); + return new Insets(mask, left, bottom, mask); case WEST: - return new Insets(0, insets.left, 0, 0); + return new Insets(mask, left, mask, mask); case NORTH_WEST: - return new Insets(insets.top, insets.left, 0, 0); + return new Insets(top, left, mask, mask); case CENTER: - return new Insets(0, 0, 0, 0); + return new Insets(mask, mask, mask, mask); default: throw new IllegalArgumentException(); } } + public Insets maskInsetsInverted(final Insets insets) { + return maskInsetsInverted(insets, 0); + } + + public Insets maskInsetsInverted(final Insets insets, final int mask) { + return maskInsetsInverted(insets.top, insets.left, insets.bottom, insets.right, mask); + } + + public Insets maskInsetsInverted(final int top, final int left, final int bottom, final int right, final int mask) { + Insets masking = maskInsets(0, 0, 0, 0, 1); + Insets maskVal = maskInsets(mask, mask, mask, mask, 0); + return new Insets(top * masking.top + maskVal.top, + left * masking.left + maskVal.left, + bottom * masking.bottom + maskVal.bottom, + right * masking.right + maskVal.right); + } + /** * Align Rectangle inside other rectangle with respect to the alignment. * diff --git a/utils/src/main/java/com/github/weisj/darklaf/util/AlignmentExt.java b/utils/src/main/java/com/github/weisj/darklaf/util/AlignmentExt.java new file mode 100644 index 00000000..51ebd1c4 --- /dev/null +++ b/utils/src/main/java/com/github/weisj/darklaf/util/AlignmentExt.java @@ -0,0 +1,105 @@ +/* + * MIT License + * + * Copyright (c) 2020 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, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.github.weisj.darklaf.util; + +import java.awt.*; + +public enum AlignmentExt { + NORTH(Alignment.NORTH), + SOUTH(Alignment.SOUTH_WEST), + EAST(Alignment.EAST), + WEST(Alignment.WEST), + NORTH_EAST(Alignment.NORTH_EAST), + NORTH_WEST(Alignment.NORTH_WEST), + SOUTH_EAST(Alignment.SOUTH_EAST), + SOUTH_WEST(Alignment.SOUTH_WEST), + CENTER(Alignment.CENTER), + LEFT(null), + MIDDLE_HORIZONTAL(null), + RIGHT(null), + TOP(null), + MIDDLE_VERTICAL(null), + BOTTOM(null); + + private Alignment parent; + + AlignmentExt(final Alignment parent) { + this.parent = parent; + } + + public Insets maskInsets(final Insets insets) { + return maskInsets(insets, 0); + } + + + public Insets maskInsets(final Insets insets, final int maskValue) { + return maskInsets(insets.top, insets.left, insets.bottom, insets.right, maskValue); + } + + public Insets maskInsets(final int top, final int left, final int bottom, final int right, final int mask) { + switch (this) { + case NORTH: + case NORTH_EAST: + case EAST: + case SOUTH_EAST: + case SOUTH: + case SOUTH_WEST: + case WEST: + case NORTH_WEST: + case CENTER: + return parent.maskInsets(top, left, bottom, right, mask); + case LEFT: + return new Insets(top, left, bottom, mask); + case MIDDLE_HORIZONTAL: + return new Insets(top, mask, bottom, mask); + case RIGHT: + return new Insets(top, mask, bottom, right); + case TOP: + return new Insets(top, left, mask, right); + case MIDDLE_VERTICAL: + return new Insets(mask, left, mask, right); + case BOTTOM: + return new Insets(mask, left, bottom, right); + default: + throw new IllegalArgumentException(); + } + } + + public Insets maskInsetsInverted(final Insets insets) { + return maskInsetsInverted(insets, 0); + } + + public Insets maskInsetsInverted(final Insets insets, final int mask) { + return maskInsetsInverted(insets.top, insets.left, insets.bottom, insets.right, mask); + } + + public Insets maskInsetsInverted(final int top, final int left, final int bottom, final int right, final int mask) { + Insets masking = maskInsets(0, 0, 0, 0, 1); + Insets maskVal = maskInsets(mask, mask, mask, mask, 0); + return new Insets(top * masking.top + maskVal.top, + left * masking.left + maskVal.left, + bottom * masking.bottom + maskVal.bottom, + right * masking.right + maskVal.right); + } +}