package mage.client.components; import com.google.common.base.Function; import com.google.common.collect.MapMaker; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.util.Map; import java.util.Objects; import javax.swing.JPanel; import mage.client.util.ImageCaches; import org.jdesktop.swingx.graphics.GraphicsUtilities; import org.jdesktop.swingx.graphics.ShadowRenderer; /** * Mage round pane with transparency. Used for tooltips. * * @author nantuko */ public class MageRoundPane extends JPanel { private int X_OFFSET = 30; private int Y_OFFSET = 30; private final Color defaultBackgroundColor = new Color(141, 130, 112, 200); private Color backgroundColor = defaultBackgroundColor; private static final int alpha = 0; private static final Map<ShadowKey, BufferedImage> SHADOW_IMAGE_CACHE; private static final Map<Key, BufferedImage> IMAGE_CACHE; static { SHADOW_IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap((Function<ShadowKey, BufferedImage>) key -> createShadowImage(key))); IMAGE_CACHE = ImageCaches.register(new MapMaker().softValues().makeComputingMap((Function<Key, BufferedImage>) key -> createImage(key))); } private final static class ShadowKey { final int width; final int height; public ShadowKey(int width, int height) { this.width = width; this.height = height; } @Override public int hashCode() { int hash = 7; hash = 97 * hash + this.width; hash = 97 * hash + this.height; return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final ShadowKey other = (ShadowKey) obj; if (this.width != other.width) { return false; } if (this.height != other.height) { return false; } return true; } } private final static class Key { final int width; final int height; final int xOffset; final int yOffset; final Color backgroundColor; public Key(int width, int height, int xOffset, int yOffset, Color backgroundColor) { this.width = width; this.height = height; this.xOffset = xOffset; this.yOffset = yOffset; this.backgroundColor = backgroundColor; } @Override public int hashCode() { int hash = 5; hash = 59 * hash + this.width; hash = 59 * hash + this.height; hash = 59 * hash + this.xOffset; hash = 59 * hash + this.yOffset; hash = 59 * hash + Objects.hashCode(this.backgroundColor); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Key other = (Key) obj; if (this.width != other.width) { return false; } if (this.height != other.height) { return false; } if (this.xOffset != other.xOffset) { return false; } if (this.yOffset != other.yOffset) { return false; } if (!Objects.equals(this.backgroundColor, other.backgroundColor)) { return false; } return true; } } @Override protected void paintComponent(Graphics g) { g.drawImage(IMAGE_CACHE.get(new Key(getWidth(), getHeight(), X_OFFSET, Y_OFFSET, backgroundColor)), 0, 0, null); } private static BufferedImage createImage(Key key) { int x = key.xOffset; int y = key.yOffset; int w = key.width - 2 * key.xOffset; int h = key.height - 2 * key.yOffset; int arc = 10; BufferedImage image = GraphicsUtilities.createCompatibleTranslucentImage(key.width, key.height); Graphics2D g2 = image.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); BufferedImage shadow = SHADOW_IMAGE_CACHE.get(new ShadowKey(w, h)); { int xOffset = (shadow.getWidth() - w) / 2; int yOffset = (shadow.getHeight() - h) / 2; g2.drawImage(shadow, x - xOffset, y - yOffset, null); } ////////////////////////////////////////////////////////////////// // fill content /** * Add white translucent substrate */ /*if (alpha != 0) { g2.setColor(new Color(255, 255, 255, alpha)); g2.fillRoundRect(x, y, w, h, arc, arc); }*/ g2.setColor(key.backgroundColor); g2.fillRoundRect(x, y, w, h, arc, arc); ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// // draw border g2.setStroke(new BasicStroke(1.5f)); g2.setColor(Color.BLACK); g2.drawRoundRect(x, y, w, h, arc, arc); // //////////////////////////////////////////////////////////////// g2.dispose(); return image; } public void setXOffset(int x_offset) { X_OFFSET = x_offset; } public void setYOffset(int y_offset) { Y_OFFSET = y_offset; } private static BufferedImage createShadowImage(ShadowKey key) { int w = key.width; int h = key.height; int arc = 10; int shadowSize = 50; BufferedImage base = GraphicsUtilities.createCompatibleTranslucentImage(w, h); Graphics2D g2 = base.createGraphics(); g2.setColor(Color.WHITE); g2.fillRoundRect(0, 0, w, h, arc, arc); g2.dispose(); ShadowRenderer renderer = new ShadowRenderer(shadowSize, 0.5f, Color.GRAY); return renderer.createShadow(base); } public void showDialog(boolean bShow) { setVisible(bShow); } public void resetBackgroundColor() { this.backgroundColor = defaultBackgroundColor; } public void setBackgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; } /** * Default UID. */ private static final long serialVersionUID = 1L; }