mirror of https://github.com/weisJ/darklaf.git
weisj
5 years ago
11 changed files with 431 additions and 219 deletions
@ -0,0 +1,96 @@
|
||||
package com.weis.darklaf.ui.tooltip; |
||||
|
||||
import com.weis.darklaf.components.alignment.Alignment; |
||||
import com.weis.darklaf.components.border.TextBubbleBorder; |
||||
import org.jdesktop.swingx.border.DropShadowBorder; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.border.Border; |
||||
import javax.swing.plaf.UIResource; |
||||
import java.awt.*; |
||||
import java.awt.geom.Area; |
||||
import java.awt.geom.Rectangle2D; |
||||
|
||||
public class DarkTooltipBorder implements Border, UIResource { |
||||
|
||||
private final DropShadowBorder shadowBorder = new DropShadowBorder(Color.BLACK, 10, 0.4f, 10, |
||||
false, true, |
||||
true, true); |
||||
private final TextBubbleBorder bubbleBorder; |
||||
|
||||
public DarkTooltipBorder() { |
||||
bubbleBorder = new TextBubbleBorder(UIManager.getColor("Tooltip.borderColor")); |
||||
bubbleBorder.setThickness(1); |
||||
bubbleBorder.setPointerSize(8); |
||||
bubbleBorder.setPointerWidth(12); |
||||
bubbleBorder.setPointerSide(Alignment.EAST); |
||||
} |
||||
|
||||
|
||||
public Area getBackgroundArea(final int width, final int height) { |
||||
var ins = shadowBorder.getBorderInsets(null); |
||||
return bubbleBorder.getInnerArea(ins.left, ins.top, |
||||
width - ins.left - ins.right, |
||||
height - ins.top - ins.bottom); |
||||
} |
||||
|
||||
@Override |
||||
public void paintBorder(final Component c, final Graphics g, |
||||
final int x, final int y, final int width, final int height) { |
||||
if (c instanceof JToolTip && ((JToolTip) c).getTipText() == null) return; |
||||
var ins = shadowBorder.getBorderInsets(c); |
||||
var bubbleArea = bubbleBorder.getInnerArea(x + ins.left, y + ins.top, |
||||
width - ins.left - ins.right, |
||||
height - ins.top - ins.bottom); |
||||
var oldClip = g.getClip(); |
||||
var clip = new Area(new Rectangle2D.Double(x, y, width, height)); |
||||
clip.subtract(bubbleArea); |
||||
g.setClip(clip); |
||||
|
||||
ins = bubbleBorder.getBorderInsets(c); |
||||
shadowBorder.paintBorder(c, g, x + ins.left, y + ins.top, |
||||
width - ins.left - ins.right, height - ins.top - ins.bottom); |
||||
|
||||
g.setClip(oldClip); |
||||
bubbleBorder.paintBorder(g, bubbleArea); |
||||
} |
||||
|
||||
@Override |
||||
public Insets getBorderInsets(final Component c) { |
||||
var ins = (Insets) bubbleBorder.getBorderInsets(c).clone(); |
||||
var si = shadowBorder.getBorderInsets(c); |
||||
var uIns = getUserInsets(c); |
||||
ins.left += 5 + si.left + uIns.left; |
||||
ins.top += 2 + si.top + uIns.top; |
||||
ins.right += 5 + si.right + uIns.right; |
||||
ins.bottom += 2 + si.bottom + uIns.bottom; |
||||
return ins; |
||||
} |
||||
|
||||
protected Insets getUserInsets(final Component c) { |
||||
if (c instanceof JComponent) { |
||||
var obj = ((JComponent) c).getClientProperty("JToolTip.insets"); |
||||
if (obj instanceof Insets) { |
||||
return (Insets) obj; |
||||
} |
||||
} |
||||
return new Insets(0, 0, 0, 0); |
||||
} |
||||
|
||||
@Override |
||||
public boolean isBorderOpaque() { |
||||
return false; |
||||
} |
||||
|
||||
public void setPointerLocation(final Alignment side) { |
||||
bubbleBorder.setPointerSide(side); |
||||
} |
||||
|
||||
public void setPointerWidth(final int width) { |
||||
bubbleBorder.setPointerWidth(width); |
||||
} |
||||
|
||||
public void setPointerHeight(final int height) { |
||||
bubbleBorder.setPointerSize(height); |
||||
} |
||||
} |
@ -0,0 +1,120 @@
|
||||
package com.weis.darklaf.ui.tooltip; |
||||
|
||||
import com.weis.darklaf.components.alignment.Alignment; |
||||
import com.weis.darklaf.util.DarkUIUtil; |
||||
import org.jetbrains.annotations.Contract; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import javax.swing.*; |
||||
import javax.swing.plaf.ComponentUI; |
||||
import javax.swing.plaf.basic.BasicToolTipUI; |
||||
import javax.swing.text.View; |
||||
import java.awt.*; |
||||
import java.beans.PropertyChangeEvent; |
||||
import java.beans.PropertyChangeListener; |
||||
|
||||
public class DarkTooltipUI extends BasicToolTipUI implements PropertyChangeListener { |
||||
|
||||
@NotNull |
||||
@Contract("_ -> new") |
||||
public static ComponentUI createUI(@NotNull final JComponent c) { |
||||
if (Boolean.TRUE.equals(c.getClientProperty("JComponent.plainTooltip"))) { |
||||
return BasicToolTipUI.createUI(c); |
||||
} else { |
||||
return new DarkTooltipUI(); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void installUI(final JComponent c) { |
||||
super.installUI(c); |
||||
} |
||||
|
||||
@Override |
||||
public void paint(@NotNull final Graphics g, @NotNull final JComponent c) { |
||||
if (((JToolTip) c).getTipText() == null) return; |
||||
g.setColor(c.getBackground()); |
||||
if (c.getBorder() instanceof DarkTooltipBorder) { |
||||
var area = ((DarkTooltipBorder) c.getBorder()).getBackgroundArea(c.getWidth(), c.getHeight()); |
||||
((Graphics2D) g).fill(area); |
||||
} |
||||
super.paint(g, c); |
||||
} |
||||
|
||||
@Override |
||||
protected void installDefaults(final JComponent c) { |
||||
super.installDefaults(c); |
||||
c.setOpaque(false); |
||||
} |
||||
|
||||
@Override |
||||
protected void installListeners(final JComponent c) { |
||||
super.installListeners(c); |
||||
c.addHierarchyListener(e -> { |
||||
var w = SwingUtilities.getWindowAncestor(c); |
||||
if (w != null && !c.isLightweight() && !isDecorated(w)) { |
||||
w.setBackground(DarkUIUtil.TRANSPARENT_COLOR); |
||||
} |
||||
}); |
||||
c.addPropertyChangeListener(this); |
||||
} |
||||
|
||||
protected boolean isDecorated(final Window w) { |
||||
if (w instanceof Dialog) { |
||||
return !((Dialog) w).isUndecorated(); |
||||
} |
||||
if (w instanceof Frame) { |
||||
return !((Frame) w).isUndecorated(); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public Dimension getPreferredSize(@NotNull final JComponent c) { |
||||
Font font = c.getFont(); |
||||
FontMetrics fm = c.getFontMetrics(font); |
||||
Insets insets = c.getInsets(); |
||||
|
||||
Dimension prefSize = new Dimension(insets.left + insets.right, |
||||
insets.top + insets.bottom); |
||||
String text = ((JToolTip) c).getTipText(); |
||||
|
||||
if ((text != null) && !text.equals("")) { |
||||
View v = (View) c.getClientProperty("html"); |
||||
if (v != null) { |
||||
prefSize.width += (int) v.getPreferredSpan(View.X_AXIS) + 6; |
||||
prefSize.height += (int) v.getPreferredSpan(View.Y_AXIS); |
||||
} else { |
||||
prefSize.width += fm.stringWidth(text) + 6; |
||||
prefSize.height += fm.getHeight(); |
||||
} |
||||
} |
||||
return prefSize; |
||||
} |
||||
|
||||
@Override |
||||
public void propertyChange(final PropertyChangeEvent evt) { |
||||
var key = evt.getPropertyName(); |
||||
if (evt.getSource() instanceof JToolTip) { |
||||
var tooltip = (JToolTip) evt.getSource(); |
||||
if (tooltip.getBorder() instanceof DarkTooltipBorder) { |
||||
var border = (DarkTooltipBorder) tooltip.getBorder(); |
||||
var newVal = evt.getNewValue(); |
||||
if ("JToolTip.pointerLocation".equals(key)) { |
||||
if (newVal instanceof Alignment) { |
||||
border.setPointerLocation((Alignment) newVal); |
||||
} else { |
||||
border.setPointerLocation(Alignment.CENTER); |
||||
} |
||||
} else if ("JToolTip.pointerHeight".equals(key)) { |
||||
if (newVal instanceof Integer) { |
||||
border.setPointerHeight((Integer) newVal); |
||||
} |
||||
} else if ("JToolTip.pointerWidth".equals(key)) { |
||||
if (newVal instanceof Integer) { |
||||
border.setPointerWidth((Integer) newVal); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,41 +0,0 @@
|
||||
import com.weis.darklaf.color.DarkColorModel; |
||||
import com.weis.darklaf.color.DarkColorModelCMYK; |
||||
import com.weis.darklaf.color.DarkColorModelHSB; |
||||
import com.weis.darklaf.color.DarkColorModelHSL; |
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import java.awt.*; |
||||
import java.util.Arrays; |
||||
|
||||
public class ColorModelTest { |
||||
|
||||
public static void main(final String[] args) { |
||||
var color = new Color(10, 20, 30); |
||||
|
||||
var m1 = new DarkColorModel(); |
||||
var m2 = new DarkColorModelHSB(); |
||||
var m3 = new DarkColorModelHSL(); |
||||
var m4 = new DarkColorModelCMYK(); |
||||
// test(m1);
|
||||
test(m2); |
||||
// test(m3);
|
||||
// test(m4);
|
||||
} |
||||
|
||||
private static void test(@NotNull final DarkColorModel model) { |
||||
System.out.println("Testing " + model.toString()); |
||||
for (int r = model.getMinimum(0); r < model.getMaximum(0); r++) { |
||||
for (int g = model.getMinimum(1); g < model.getMaximum(1); g++) { |
||||
for (int b = model.getMinimum(2); b < model.getMaximum(2); b++) { |
||||
var c = new int[]{r, g, b}; |
||||
var interm = model.getColorFromValues(c); |
||||
var nc = model.getValuesFromColor(interm); |
||||
if (!Arrays.equals(c, nc)) { |
||||
throw new RuntimeException( |
||||
"Not equals " + Arrays.toString(c) + " : " + interm + " : " + Arrays.toString(nc)); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue