/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.scenegraph.g2d.nodes; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import org.simantics.scenegraph.g2d.G2DNode; import org.simantics.scenegraph.utils.TextUtil; /** * @author Tuukka Lehtonen */ public class MessageNotificationNode extends G2DNode { private static final long serialVersionUID = -7518450802171689793L; private static final Stroke PROGRESS_STROKE = new BasicStroke(1f); private Rectangle2D bounds; private Font font; private double margin; private double progress; private String message; @SyncField({"bounds", "font", "margin", "progress", "message"}) public void init(Rectangle2D bounds, Font font, double margin, double progress, String message) { this.bounds = bounds; this.font = font; this.margin = margin; this.progress = progress; this.message = message; } @Override public void render(Graphics2D g2d) { double x = bounds.getX(); double y = bounds.getY(); double width = bounds.getWidth(); double height = bounds.getHeight(); double rx = 20; double ry = 20; RoundRectangle2D rr = new RoundRectangle2D.Double(x, y, width, height, rx, ry); Composite oc = g2d.getComposite(); // Base { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); g2d.setPaint(Color.BLACK); g2d.fill(rr); } // Message { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setComposite(AlphaComposite.Src); g2d.setFont(font); FontMetrics fm = g2d.getFontMetrics(font); String[] lines = TextUtil.wordWrap(message, fm, (int) (width - 2*margin)); g2d.setColor(Color.WHITE); float fh = fm.getHeight() + 1; float tx = (float)(x + margin); float ty = (float)(y + fm.getMaxAscent() + margin); for (int i = 0; i < lines.length; ++i) { if ((ty + fm.getMaxDescent() + margin) > rr.getMaxY()) break; g2d.drawString(lines[i], tx, ty); ty += fh; } } // Progress { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); float c = (float) (0.15f + 0.75f*Math.sin(progress*Math.PI)); if(c >= 0 && c <= 1.0f) g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, c)); g2d.setStroke(PROGRESS_STROKE); g2d.draw(new Rectangle2D.Double(x + margin, y + height - margin/2 - 2, (width - 2*margin), margin/2)); g2d.fill(new Rectangle2D.Double(x + margin + 2, y + height - margin/2, (width - 2*margin - 4)*progress, margin/2 - 3)); } g2d.setComposite(oc); } @Override public String toString() { return super.toString() + "[bounds=" + bounds + ", font=" + font + ", margin=" + margin + ", progress=" + progress + ", message=" + message + "]"; } @Override public Rectangle2D getBoundsInLocal() { return bounds; } }