diff --git a/src/main/java/com/weis/darklaf/ui/colorchooser/ColorWheelPanel.java b/src/main/java/com/weis/darklaf/ui/colorchooser/ColorWheelPanel.java index dcb26328..89c20ab7 100644 --- a/src/main/java/com/weis/darklaf/ui/colorchooser/ColorWheelPanel.java +++ b/src/main/java/com/weis/darklaf/ui/colorchooser/ColorWheelPanel.java @@ -35,9 +35,9 @@ import java.awt.*; * @author Konstantin Bulenkov */ public class ColorWheelPanel extends JPanel { - private final ColorWheel myColorWheel; - private final SlideComponent myBrightnessComponent; - private SlideComponent myOpacityComponent = null; + private final ColorWheel colorWheel; + private final SlideComponent brightnessSlider; + private SlideComponent opacitySlider = null; private boolean enableOpacity; public ColorWheelPanel(final ColorListener colorListener, final boolean enableOpacity, @@ -47,30 +47,31 @@ public class ColorWheelPanel extends JPanel { this.enableOpacity = enableOpacity; - myColorWheel = new ColorWheel(); - add(myColorWheel, BorderLayout.CENTER); + colorWheel = new ColorWheel(); + add(colorWheel, BorderLayout.CENTER); - myColorWheel.addListener(colorListener); - - myBrightnessComponent = new SlideComponent("Brightness", true); - myBrightnessComponent.setToolTipText("Brightness"); - myBrightnessComponent.addListener(value -> { - myColorWheel.setBrightness(1 - (value / 255f)); - myColorWheel.repaint(); + brightnessSlider = new SlideComponent("Brightness", true, false); + brightnessSlider.addListener(value -> { + colorWheel.setBrightness(1 - (value / 255f)); + colorWheel.repaint(); }); - add(myBrightnessComponent, BorderLayout.EAST); + add(brightnessSlider, BorderLayout.EAST); + colorWheel.addListener(colorListener); + colorWheel.addListener(brightnessSlider); + if (enableOpacity) { - myOpacityComponent = new SlideComponent("Opacity", false); - myOpacityComponent.setUnits(opacityInPercent ? SlideComponent.Unit.PERCENT : SlideComponent.Unit.LEVEL); - myOpacityComponent.setToolTipText("Opacity"); - myOpacityComponent.addListener(integer -> { - myColorWheel.setOpacity(integer); - myColorWheel.repaint(); + opacitySlider = new SlideComponent("Opacity", false, true); + opacitySlider.setUnits(opacityInPercent ? SlideComponent.Unit.PERCENT : SlideComponent.Unit.LEVEL); + opacitySlider.addListener(integer -> { + colorWheel.setOpacity(integer); + colorWheel.repaint(); }); - add(myOpacityComponent, BorderLayout.SOUTH); + add(opacitySlider, BorderLayout.SOUTH); + colorWheel.addListener(opacitySlider); + } } @@ -78,16 +79,16 @@ public class ColorWheelPanel extends JPanel { float[] hsb = new float[3]; Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb); - myBrightnessComponent.setValue(255 - (int) (hsb[2] * 255)); - myBrightnessComponent.repaint(); + brightnessSlider.setValue(255 - (int) (hsb[2] * 255)); + brightnessSlider.repaint(); - myColorWheel.dropImage(); - if (myOpacityComponent != null && source instanceof AbstractColorChooserPanel) { - myOpacityComponent.setValue(color.getAlpha()); - myOpacityComponent.repaint(); + colorWheel.dropImage(); + if (opacitySlider != null && source instanceof AbstractColorChooserPanel) { + opacitySlider.setValue(color.getAlpha()); + opacitySlider.repaint(); } - myColorWheel.setColor(color, source, hsb[0], hsb[1], hsb[2]); + colorWheel.setColor(color, source, hsb[0], hsb[1], hsb[2]); } public boolean isColorTransparencySelectionEnabled() { @@ -97,8 +98,8 @@ public class ColorWheelPanel extends JPanel { public void setColorTransparencySelectionEnabled(final boolean b) { if (b != enableOpacity) { enableOpacity = b; - myOpacityComponent.setEnabled(b); - myOpacityComponent.setVisible(b); + opacitySlider.setEnabled(b); + opacitySlider.setVisible(b); } } } diff --git a/src/main/java/com/weis/darklaf/ui/colorchooser/SlideComponent.java b/src/main/java/com/weis/darklaf/ui/colorchooser/SlideComponent.java index 08c55090..db7340eb 100644 --- a/src/main/java/com/weis/darklaf/ui/colorchooser/SlideComponent.java +++ b/src/main/java/com/weis/darklaf/ui/colorchooser/SlideComponent.java @@ -25,7 +25,9 @@ package com.weis.darklaf.ui.colorchooser; import com.weis.darklaf.components.alignment.Alignment; +import com.weis.darklaf.components.tooltip.ToolTipContext; import com.weis.darklaf.util.ColorUtil; +import com.weis.darklaf.util.DarkUIUtil; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -44,19 +46,29 @@ import java.util.function.Consumer; * @author Konstantin Bulenkov * @author Jannis Weis */ -class SlideComponent extends JComponent { +class SlideComponent extends JComponent implements ColorListener { private static final int OFFSET = 11; - private final boolean myVertical; - private final String myTitle; - private final List> myListeners = new ArrayList<>(); - private int myPointerValue = 0; - private int myValue = 0; - private Unit myUnit = Unit.LEVEL; - private JToolTip tooltip; - - SlideComponent(final String title, final boolean vertical) { - myTitle = title; - myVertical = vertical; + private final ToolTipContext toolTipContext = new ToolTipContext(this); + private final boolean vertical; + private boolean isOpacity; + private final String title; + private final List> listeners = new ArrayList<>(); + private int pointerValue = 0; + private int value = 0; + private Unit unitType = Unit.LEVEL; + private Color color; + + SlideComponent(final String title, final boolean vertical, final boolean isOpacity) { + this.title = title; + this.vertical = vertical; + this.isOpacity = isOpacity; + this.color = Color.WHITE; + + toolTipContext.setAlignInside(false) + .setAlignment(vertical ? Alignment.WEST : Alignment.NORTH) + .setHideOnExit(false) + .setToolTipRectSupplier(e -> getKnobRect()) + .setInsets(new Insets(3, 0, 3, 0)); addMouseMotionListener(new MouseAdapter() { @Override @@ -67,25 +79,22 @@ class SlideComponent extends JComponent { addMouseListener(new MouseAdapter() { @Override - public void mouseExited(final MouseEvent e) { - var p = e.getPoint(); - p = SwingUtilities.convertPoint(e.getComponent(), p, SlideComponent.this); - if (tooltip != null && !contains(p)) { - tooltip.setVisible(false); - } + public void mousePressed(final MouseEvent e) { + processMouse(e); } }); + addMouseWheelListener(event -> { int units = event.getUnitsToScroll(); if (units == 0) return; - int pointerValue = myPointerValue + units; + int pointerValue = this.pointerValue + units; pointerValue = Math.max(pointerValue, OFFSET); - int size = myVertical ? getHeight() : getWidth(); + int size = this.vertical ? getHeight() : getWidth(); pointerValue = Math.min(pointerValue, (size - 12)); - myPointerValue = pointerValue; - myValue = pointerValueToValue(myPointerValue); + this.pointerValue = pointerValue; + value = pointerValueToValue(this.pointerValue); repaint(); fireValueChanged(); @@ -104,14 +113,14 @@ class SlideComponent extends JComponent { } private void processMouse(final MouseEvent e) { - int pointerValue = myVertical ? e.getY() : e.getX(); + int pointerValue = vertical ? e.getY() : e.getX(); pointerValue = Math.max(pointerValue, OFFSET); - int size = myVertical ? getHeight() : getWidth(); + int size = vertical ? getHeight() : getWidth(); pointerValue = Math.min(pointerValue, (size - 12)); - myPointerValue = pointerValue; + this.pointerValue = pointerValue; - myValue = pointerValueToValue(myPointerValue); + value = pointerValueToValue(this.pointerValue); repaint(); fireValueChanged(); @@ -119,49 +128,54 @@ class SlideComponent extends JComponent { private int pointerValueToValue(int pointerValue) { pointerValue -= OFFSET; - final int size = myVertical ? getHeight() : getWidth(); + final int size = vertical ? getHeight() : getWidth(); double proportion = (size - 23) / 255f; return (int) Math.round((pointerValue / proportion)); } private void fireValueChanged() { - for (Consumer listener : myListeners) { - listener.accept(myValue); + var p = MouseInfo.getPointerInfo().getLocation(); + SwingUtilities.convertPointFromScreen(p, this); + ToolTipManager.sharedInstance().mouseMoved(new MouseEvent(this, MouseEvent.MOUSE_MOVED, 0, + 0, p.x, p.y, 0, false, 0)); + for (Consumer listener : listeners) { + listener.accept(value); } } public int getValue() { - return myValue; + return value; } public void setValue(final int value) { if (value < 0 || value > 255) { throw new IllegalArgumentException("Value " + value + " not in range [0,255]"); } - myPointerValue = valueToPointerValue(value); - myValue = value; + pointerValue = valueToPointerValue(value); + this.value = value; } private int valueToPointerValue(final int value) { - final int size = myVertical ? getHeight() : getWidth(); + final int size = vertical ? getHeight() : getWidth(); float proportion = (size - 23) / 255f; return OFFSET + (int) (value * proportion); } void setUnits(final Unit unit) { - myUnit = unit; + unitType = unit; } public void addListener(final Consumer listener) { - myListeners.add(listener); + listeners.add(listener); } @Override protected void paintComponent(final Graphics g) { final Graphics2D g2d = (Graphics2D) g; - - if (myVertical) { - g2d.setPaint(new GradientPaint(0f, 0f, Color.WHITE, 0f, getHeight(), Color.BLACK)); + Color endColor = isOpacity ? DarkUIUtil.TRANSPARENT_COLOR : Color.BLACK; + Color beginColor = color; + if (vertical) { + g2d.setPaint(new GradientPaint(0f, 0f, beginColor, 0f, getHeight(), endColor)); g.fillRect(7, 10, 12, getHeight() - 20); g.setColor(UIManager.getColor("ColorChooser.sliderBorderColor")); @@ -170,7 +184,7 @@ class SlideComponent extends JComponent { g.fillRect(7 + 12 - 1, 10, 1, getHeight() - 20); g.fillRect(7, 10 + getHeight() - 20 - 1, 12, 1); } else { - g2d.setPaint(new GradientPaint(0f, 0f, Color.WHITE, getWidth(), 0f, Color.BLACK)); + g2d.setPaint(new GradientPaint(0f, 0f, endColor, getWidth(), 0f, beginColor)); g.fillRect(10, 7, getWidth() - 20, 12); g.setColor(UIManager.getColor("ColorChooser.sliderBorderColor")); @@ -180,7 +194,17 @@ class SlideComponent extends JComponent { g.fillRect(10 + getWidth() - 20 - 1, 7, 1, 12); } - drawKnob(g2d, myVertical ? 7 : myPointerValue, myVertical ? myPointerValue : 7, myVertical); + drawKnob(g2d, vertical ? 7 : pointerValue, vertical ? pointerValue : 7, vertical); + } + + @NotNull + @Contract(" -> new") + private Rectangle getKnobRect() { + if (vertical) { + return new Rectangle(1, pointerValue - 6, 12, 12); + } else { + return new Rectangle(pointerValue - 6, 1, 12, 12); + } } private static void drawKnob(@NotNull final Graphics2D g2d, int x, int y, final boolean vertical) { @@ -225,49 +249,35 @@ class SlideComponent extends JComponent { @Override public Dimension getPreferredSize() { - return myVertical ? new Dimension(22, 100) - : new Dimension(100, 22); + return vertical ? new Dimension(22, 100) + : new Dimension(100, 22); } @Override public Dimension getMinimumSize() { - return myVertical ? new Dimension(22, 50) - : new Dimension(50, 22); + return vertical ? new Dimension(22, 50) + : new Dimension(50, 22); } @Override public String getToolTipText(final MouseEvent event) { - return myTitle + ": " + Unit.formatValue(myValue, myUnit); + return title + ": " + Unit.formatValue(value, unitType); } @Override public Point getToolTipLocation(final MouseEvent e) { - if (tooltip == null) { - createToolTip(); - tooltip.setTipText(getToolTipText(e)); - } - final Point point = myVertical ? new Point(0, myPointerValue) : new Point(myPointerValue, 0); - if (myVertical) { - point.x -= tooltip.getPreferredSize().width - 7; - point.y -= (tooltip.getPreferredSize().height) / 2 - 4; - } else { - point.x -= tooltip.getPreferredSize().width / 2; - point.y -= tooltip.getPreferredSize().height - 7; - } - return point; + return toolTipContext.getToolTipLocation(e); } @Override public JToolTip createToolTip() { - tooltip = super.createToolTip(); - if (myVertical) { - tooltip.setPreferredSize(new Dimension(130, 39)); - } else { - tooltip.setPreferredSize(new Dimension(120, 46)); - } - tooltip.putClientProperty("JToolTip.insets", new Insets(3, 0, 3, 0)); - tooltip.putClientProperty("JToolTip.pointerLocation", myVertical ? Alignment.EAST : Alignment.SOUTH); - return tooltip; + return toolTipContext.getToolTip(); + } + + @Override + public void colorChanged(final Color color, final Object source) { + this.color = ColorUtil.removeAlpha(color); + repaint(); } enum Unit { diff --git a/src/main/java/com/weis/darklaf/ui/colorchooser/SwatchPanel.java b/src/main/java/com/weis/darklaf/ui/colorchooser/SwatchPanel.java index 465bfe15..dabc6913 100644 --- a/src/main/java/com/weis/darklaf/ui/colorchooser/SwatchPanel.java +++ b/src/main/java/com/weis/darklaf/ui/colorchooser/SwatchPanel.java @@ -1,6 +1,7 @@ package com.weis.darklaf.ui.colorchooser; import com.weis.darklaf.components.alignment.Alignment; +import com.weis.darklaf.components.tooltip.ToolTipContext; import com.weis.darklaf.util.DarkUIUtil; import com.weis.darklaf.util.GraphicsUtil; import org.jetbrains.annotations.Contract; @@ -13,7 +14,6 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** @@ -21,6 +21,11 @@ import java.awt.event.MouseEvent; */ abstract class SwatchPanel extends JPanel { + private final ToolTipContext toolTipContext = new ToolTipContext(this) + .setAlignment(Alignment.CENTER) + .setToolTipRectSupplier(this::getSwatchBounds) + .setHideOnExit(true); + protected Color[] colors; protected Dimension swatchSize; protected Dimension numSwatches; @@ -28,7 +33,6 @@ abstract class SwatchPanel extends JPanel { private int selRow; private int selCol; - private JToolTip tooltip; public SwatchPanel() { initValues(); @@ -38,16 +42,6 @@ abstract class SwatchPanel extends JPanel { setBackground(UIManager.getColor("ColorChooser.swatchGridColor")); setFocusable(true); setInheritsPopupMenu(true); - addMouseListener(new MouseAdapter() { - @Override - public void mouseExited(final MouseEvent e) { - var p = e.getPoint(); - p = SwingUtilities.convertPoint(e.getComponent(), p, SwatchPanel.this); - if (tooltip != null && !contains(p)) { - tooltip.setVisible(false); - } - } - }); addFocusListener(new FocusAdapter() { public void focusGained(final FocusEvent e) { repaint(); @@ -179,26 +173,20 @@ abstract class SwatchPanel extends JPanel { @Override public Point getToolTipLocation(final MouseEvent e) { - if (tooltip == null) { - createToolTip(); - tooltip.setTipText(getToolTipText(e)); - } + return toolTipContext.getToolTipLocation(e); + } + + @NotNull + protected Rectangle getSwatchBounds(@NotNull final MouseEvent e) { var p = getCoordinatesForLocation(e.getX(), e.getY()); int x = getXForColumn(p.x); int y = getYForRow(p.y); - x += swatchSize.width / 2; - y += swatchSize.height / 2; - x -= tooltip.getPreferredSize().width / 2; - return new Point(x, y); + return new Rectangle(x, y, swatchSize.width, swatchSize.height); } @Override public JToolTip createToolTip() { - tooltip = super.createToolTip(); -// tooltip.putClientProperty("JToolTip.pointerWidth", 10); -// tooltip.putClientProperty("JToolTip.pointerHeight", 7); - tooltip.putClientProperty("JToolTip.pointerLocation", Alignment.NORTH); - return tooltip; + return toolTipContext.getToolTip(); } public Point getCoordinatesForLocation(final int x, final int y) {