Browse Source

Reduce overhead of painting balloon tooltip background

Instead of calculating the area loop over all parts (the round rect and triangle)
to fill.
jsvg
Jannis Weis 3 years ago
parent
commit
c896b888ce
No known key found for this signature in database
GPG Key ID: 7C9D8D4B558049AB
  1. 51
      core/src/main/java/com/github/weisj/darklaf/components/border/BubbleBorder.java
  2. 21
      core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.java
  3. 6
      core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkTooltipBorder.java

51
core/src/main/java/com/github/weisj/darklaf/components/border/BubbleBorder.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,
@ -270,29 +270,46 @@ public class BubbleBorder extends AbstractBorder {
return getBorderInsets(c);
}
public Area getBubbleArea(final float x, final float y, final float width, final float height, final float adj) {
public Shape[] getBubbleShapes(final float x, final float y, final float width, final float height,
final float adj) {
float w = width - 2 * adj;
float h = height - 2 * adj;
RoundRectangle2D.Float bubble = calculateBubbleRect(x + adj, y + adj, w, h);
final Shape[] shapes = new Shape[pointerSide != Alignment.CENTER ? 2 : 1];
shapes[0] = calculateBubbleRect(x + adj, y + adj, w, h);
if (pointerSide != Alignment.CENTER) {
shapes[1] = calculatePointerShape(adj, w, h, bubble);
}
return shapes;
}
private Shape calculatePointerShape(final float adj, final float w, final float h,
final RoundRectangle2D.Float bubble) {
double pSize = getPointerSize() - adj;
double pWidth = getPointerWidth() - 2 * adj;
double pointerPad = calculatePointerPad(w, h, pointerSide);
switch (pointerSide) {
case SOUTH_EAST:
case NORTH_EAST:
pointerPad += adj;
break;
case NORTH_WEST:
case SOUTH_WEST:
pointerPad -= adj;
break;
default:
break;
}
return creatPointerShape(pointerPad, pSize, pWidth, bubble);
}
public Area getBubbleArea(final float x, final float y, final float width, final float height, final float adj) {
float w = width - 2 * adj;
float h = height - 2 * adj;
RoundRectangle2D.Float bubble = calculateBubbleRect(x + adj, y + adj, w, h);
final Area area = new Area(bubble);
if (pointerSide != Alignment.CENTER) {
double pointerPad = calculatePointerPad(w, h, pointerSide);
switch (pointerSide) {
case SOUTH_EAST:
case NORTH_EAST:
pointerPad += adj;
break;
case NORTH_WEST:
case SOUTH_WEST:
pointerPad -= adj;
break;
default:
break;
}
Path2D pointer = creatPointerShape(pointerPad, pSize, pWidth, bubble);
area.add(new Area(pointer));
area.add(new Area(calculatePointerShape(adj, w, h, bubble)));
}
return area;
}

21
core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.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,
@ -22,7 +22,6 @@ package com.github.weisj.darklaf.ui.tooltip;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Area;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@ -43,7 +42,9 @@ import com.github.weisj.darklaf.util.PropertyKey;
import com.github.weisj.darklaf.util.graphics.GraphicsContext;
import com.github.weisj.darklaf.util.graphics.GraphicsUtil;
/** @author Jannis Weis */
/**
* @author Jannis Weis
*/
public class DarkToolTipUI extends BasicToolTipUI
implements PropertyChangeListener, HierarchyListener, ToolTipConstants {
@ -193,8 +194,10 @@ public class DarkToolTipUI extends BasicToolTipUI
GraphicsContext context = GraphicsUtil.setupAntialiasing(g);
g.setColor(c.getBackground());
if (!isPlain && c.getBorder() instanceof DarkTooltipBorder) {
Area area = ((DarkTooltipBorder) c.getBorder()).getBackgroundArea(c, c.getWidth(), c.getHeight());
((Graphics2D) g).fill(area);
for (Shape shape : ((DarkTooltipBorder) c.getBorder()).getBackgroundShapes(c, c.getWidth(),
c.getHeight())) {
((Graphics2D) g).fill(shape);
}
} else {
PaintUtil.fillRect(g, 0, 0, c.getWidth(), c.getHeight());
}
@ -280,9 +283,11 @@ public class DarkToolTipUI extends BasicToolTipUI
public boolean contains(final JComponent c, final int x, final int y) {
Border b = c.getBorder();
if (b instanceof DarkTooltipBorder) {
Area insideArea =
((DarkTooltipBorder) b).getBackgroundArea(toolTip, toolTip.getWidth(), toolTip.getHeight());
return insideArea.contains(x, y);
for (Shape shape : ((DarkTooltipBorder) b).getBackgroundShapes(
toolTip, toolTip.getWidth(), toolTip.getHeight())) {
if (shape.contains(x, y)) return true;
}
return false;
} else {
return super.contains(c, x, y);
}

6
core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkTooltipBorder.java

@ -60,13 +60,13 @@ public class DarkTooltipBorder implements Border, AlignableTooltipBorder {
paintShadow = UIManager.getBoolean("ToolTip.paintShadow");
}
public Area getBackgroundArea(final Component c, final int width, final int height) {
public Shape[] getBackgroundShapes(final Component c, final int width, final int height) {
if (isPlain(c)) {
return new Area(new Rectangle(0, 0, width, height));
return new Area[] {new Area(new Rectangle(0, 0, width, height))};
}
Insets ins = shadowBorder.getBorderInsets(null);
adjustInsets(ins);
return bubbleBorder.getBubbleArea(ins.left, ins.top, width - ins.left - ins.right,
return bubbleBorder.getBubbleShapes(ins.left, ins.top, width - ins.left - ins.right,
height - ins.top - ins.bottom, bubbleBorder.getThickness() / 3f);
}

Loading…
Cancel
Save