package com.yoursway.swt.animations.humaneMessage;
import static com.yoursway.swt.additions.YsSwtGeometry.centeredRectange;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import com.yoursway.swt.overlay.TemporaryCanvasOverlay;
public class HumaneMessageBox {
private final Display display;
private Point gap;
private Font font;
private TemporaryCanvasOverlay overlay;
private Image image;
private Rectangle overlayBounds;
private boolean rendered = false;
private boolean disposed = false;
private PaintListener paintListener;
private Canvas canvas;
public HumaneMessageBox(Display display) {
this.display = display;
}
public synchronized void show(final String message) {
if (disposed)
return;
gap = new Point(25, 10);
font = new Font(display, "Gill Sans", 54, 0);
Shell shell = display.getActiveShell();
Rectangle clientArea = shell.getClientArea();
GC gc = new GC(shell);
gc.setFont(font);
Point extent = gc.textExtent(message);
int maxWidth = clientArea.width * 2 / 3;
int width = extent.x + 2 * gap.x;
if (width > maxWidth)
width = maxWidth;
int height = extent.y + 2 * gap.y;
Rectangle messageArea = centeredRectange(clientArea, width, height);
overlay = new TemporaryCanvasOverlay(shell, messageArea);
overlayBounds = overlay.getBounds();
image = new Image(display, overlayBounds.width, overlayBounds.height);
canvas = overlay.getCanvas();
paintListener = new PaintListener() {
public void paintControl(PaintEvent e) {
paintMessage(message);
overlay.renderOffscreenImage(image);
}
};
canvas.addPaintListener(paintListener);
Listener dismissListener = new Listener() {
public void handleEvent(Event event) {
dismiss();
display.removeFilter(SWT.MouseMove, this);
display.removeFilter(SWT.MouseDown, this);
display.removeFilter(SWT.KeyDown, this);
}
};
display.addFilter(SWT.MouseMove, dismissListener);
display.addFilter(SWT.MouseDown, dismissListener);
display.addFilter(SWT.KeyDown, dismissListener);
}
void paintMessage(final String message) {
GC gc = new GC(image);
overlay.drawOverlayBackgroundOnto(gc, image.getBounds());
Color background = display.getSystemColor(SWT.COLOR_DARK_BLUE);
gc.setBackground(background);
gc.setAlpha(160);
gc.fillRoundRectangle(0, 0, overlayBounds.width, overlayBounds.height, 30, 30);
gc.setAlpha(255);
gc.setFont(font);
gc.setForeground(new Color(display, 255, 255, 255));
gc.drawText(message, gap.x, gap.y, true);
gc.dispose();
rendered = true;
}
public synchronized void dismiss() {
if (disposed)
return;
if (!rendered) {
if (overlay != null)
overlay.dispose();
} else {
canvas.removePaintListener(paintListener);
overlay.disposeWithFadeout(image, 370);
}
disposed = true;
}
public synchronized void dismissQuickly(Runnable runnable) {
if (disposed) {
runnable.run();
return;
}
if (!rendered) {
if (overlay != null)
overlay.dispose();
runnable.run();
} else {
canvas.removePaintListener(paintListener);
overlay.disposeWithFadeout(image, 100);
display.timerExec(150, runnable);
}
disposed = true;
}
}