package org.gwtoolbox.commons.ui.client.notification.tray;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import org.gwtoolbox.commons.ui.client.animation.Animator;
import org.gwtoolbox.commons.ui.client.event.EventUtils;
import org.gwtoolbox.commons.ui.client.event.Handler;
import org.gwtoolbox.commons.ui.client.notification.Notification;
/**
* @author Uri Boness
*/
public class TrayNotificationBox extends Widget {
private int autoHideTimeout;
private boolean closing;
private boolean showing;
private boolean shown;
private final static double opacity = 0.95;
private final static Animator animator = new Animator(500);
public TrayNotificationBox(String title, String message) {
this(Notification.builder().title(title).body(message).build());
}
public TrayNotificationBox(String title, String message, int autoHideTimeout) {
this(Notification.builder().title(title).body(message).autoCloseDelay(autoHideTimeout).build());
}
public TrayNotificationBox(Notification notification) {
this.autoHideTimeout = notification.autoCloseDelay();
String imageStyle = notification.imageStyle();
boolean hasImage = imageStyle != null;
DivElement box = DOM.createDiv().cast();
box.setClassName("gtx-tray-notification-box");
if (!hasImage) {
box.addClassName("gtx-no-image");
}
if (notification.boxStyle() != null) {
box.addClassName(notification.boxStyle());
}
AnchorElement btn = DOM.createAnchor().cast();
btn.setClassName("gtx-tray-notification-btn");
EventUtils.addOnClickHandler(btn, new Handler<Event>() {
@Override
public void handle(Event event) {
close();
}
});
box.appendChild(btn);
if (hasImage) {
DivElement img = DOM.createDiv().cast();
img.setClassName("gtx-tray-notification-img");
img.addClassName(imageStyle);
box.appendChild(img);
}
DivElement titleDiv = DOM.createDiv().cast();
titleDiv.setClassName("gtx-tray-notification-title");
titleDiv.setInnerText(notification.title());
box.appendChild(titleDiv);
DivElement body = DOM.createDiv().cast();
body.setClassName("gtx-tray-notification-body");
body.setInnerHTML(notification.body());
box.appendChild(body);
// starting transparent and fading in.
box.getStyle().setOpacity(0);
setElement(box);
shown = false;
}
protected void onLoad() {
show();
}
protected void close() {
if (closing) {
return;
}
closing = true;
animator.start(new Animator.Callback() {
public void update(double progress) {
getElement().getStyle().setOpacity(opacity - opacity * progress);
}
public void finished() {
final int height = getOffsetHeight() - 2;
animator.start(new Animator.Callback() {
public void update(double progress) {
int newHeight = (int) (height * (1 - progress));
GWT.log("height: " + newHeight);
getElement().getStyle().setHeight(newHeight, Style.Unit.PX);
}
public void finished() {
removeFromParent();
}
});
}
});
}
protected void show() {
if (showing || shown) {
return;
}
showing = true;
animator.start(new Animator.Callback() {
public void update(double progress) {
getElement().getStyle().setOpacity(progress * opacity);
}
public void finished() {
startCloseTimeout();
showing = false;
shown = true;
}
});
}
protected void startCloseTimeout() {
if (autoHideTimeout >= 0) {
new Timer() {
public void run() {
if (isAttached()) {
close();
}
}
}.schedule(autoHideTimeout);
}
}
}