package org.xmind.ui.dialogs;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.xmind.ui.internal.ToolkitImages;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;
import org.xmind.ui.util.RegionUtils;
import org.xmind.ui.util.UITimer;
public class Notification extends Dialog {
private static int STAY_DURATION = 5000;
private static List<Window> group = new ArrayList<Window>();
private String infoText;
private IAction action;
private Rectangle bounds;
private boolean isCenter;
private boolean isLong;
private boolean isInfoHyperlink;
private String infoTooltip;
private UITimer timer;
private int duration = STAY_DURATION;
private Label close;
private ResourceManager resources;
private boolean noButton;
public Notification(Shell parent, String infoText, IAction action,
Rectangle bounds, boolean isCenter, boolean isLong,
boolean isInfoHyperlink, String infoTooltip) {
this(parent, infoText, action, bounds, isCenter, isLong,
isInfoHyperlink, infoTooltip, false);
}
public Notification(Shell parent, String infoText, IAction action,
Rectangle bounds, boolean isCenter, boolean isLong,
boolean isInfoHyperlink, String infoTooltip, boolean noButton) {
super(parent);
this.infoText = infoText;
this.action = action;
this.isCenter = isCenter;
this.isLong = isLong;
this.isInfoHyperlink = isInfoHyperlink;
this.infoTooltip = infoTooltip;
this.noButton = noButton;
//initial bounds
if (bounds == null) {
bounds = parent.getBounds();
}
this.bounds = new Rectangle(bounds.x, bounds.y, bounds.width,
bounds.height);
setShellStyle(SWT.NO_TRIM | SWT.TOOL);
setBlockOnOpen(false);
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
resources = new LocalResourceManager(JFaceResources.getResources(),
newShell);
newShell.setAlpha(0x95);
newShell.setBackgroundMode(SWT.INHERIT_FORCE);
}
@Override
protected void initializeBounds() {
Point size = getInitialSize();
Region region = RegionUtils
.getRoundedRectangle(new Rectangle(0, 0, size.x, size.y), 2);
getShell().setRegion(region);
Point location = getInitialLocation();
getShell().setLocation(location);
//dispose region
getShell().addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
getShell().getRegion().dispose();
}
});
}
private Point getInitialLocation() {
Point size = getInitialSize();
int x = isCenter ? bounds.x + (bounds.width - size.x) / 2
: bounds.x + bounds.width - size.x;
int y = bounds.y + bounds.height - size.y;
//if other notifications are being shown.
if (group.size() != 0) {
Window topDialog = group.get(group.size() - 1);
if (!topDialog.getShell().isDisposed()) {
y = topDialog.getShell().getBounds().y - size.y - 1;
}
}
return new Point(x, y);
}
@Override
protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#000000"))); //$NON-NLS-1$
GridData gridData = new GridData(GridData.FILL_BOTH);
gridData.widthHint = isLong ? 500 : 380;
gridData.heightHint = 64;
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(noButton ? 2 : 3, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.horizontalSpacing = 0;
composite.setLayout(gridLayout);
createImageSection(composite);
createInfoSection(composite);
if (!noButton) {
createButtonsSection(composite);
}
return composite;
}
private void createImageSection(Composite parent) {
Image image = null;
if (action != null) {
ImageDescriptor icon = action.getImageDescriptor();
if (icon != null) {
image = (Image) resources.get(icon);
}
}
//get default image
if (image == null) {
image = (Image) resources
.get(ToolkitImages.get("notification-default-small.png")); //$NON-NLS-1$
}
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(parent.getBackground());
GridData gridData = new GridData(SWT.LEFT, SWT.FILL, false, false);
gridData.widthHint = 76;
composite.setLayoutData(gridData);
composite.setLayout(new GridLayout(1, false));
Label iconLabel = new Label(composite, SWT.CENTER);
iconLabel.setBackground(composite.getBackground());
GridData gridData2 = new GridData(SWT.CENTER, SWT.CENTER, true, true);
iconLabel.setLayoutData(gridData2);
iconLabel.setImage(image);
}
private void createInfoSection(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(parent.getBackground());
GridData gridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.marginRight = 20;
composite.setLayout(gridLayout);
if (isInfoHyperlink) {
StyledLink link;
String content = infoText;
if (content.indexOf("<form>") >= 0) { //$NON-NLS-1$
link = new StyledLink(composite, SWT.NONE);
} else {
link = new StyledLink(composite, SWT.SIMPLE);
}
link.setBackground(composite.getBackground());
link.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
link.setFont(
(Font) resources.get(FontDescriptor.createFrom(FontUtils
.relativeHeight(link.getFont().getFontData(), 1))));
link.setText(content);
if (infoTooltip != null) {
link.setToolTipText(infoTooltip);
}
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true,
true);
link.setLayoutData(layoutData);
if (action == null)
link.setEnabled(false);
final IAction theAction = this.action;
link.addHyperlinkListener(new IHyperlinkListener() {
public void linkExited(HyperlinkEvent e) {
}
public void linkEntered(HyperlinkEvent e) {
}
public void linkActivated(HyperlinkEvent e) {
Display.getCurrent().asyncExec(new Runnable() {
public void run() {
if (theAction != null)
theAction.run();
}
});
}
});
} else {
Label infoLabel = null;
String content = infoText;
if (content.indexOf("<form>") >= 0) { //$NON-NLS-1$
infoLabel = new Label(composite, SWT.MULTI | SWT.WRAP);
} else {
infoLabel = new Label(composite, SWT.SIMPLE);
}
infoLabel.setBackground(composite.getBackground());
infoLabel.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
infoLabel.setFont((Font) resources
.get(FontDescriptor.createFrom(FontUtils.relativeHeight(
infoLabel.getFont().getFontData(), 1))));
infoLabel.setText(content);
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, true,
true);
infoLabel.setLayoutData(layoutData);
if (infoTooltip != null) {
infoLabel.setToolTipText(infoTooltip);
}
}
}
private void createButtonsSection(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(parent.getBackground());
GridData gridData = new GridData(SWT.RIGHT, SWT.FILL, false, true);
gridData.widthHint = 74;
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.verticalSpacing = 0;
composite.setLayout(gridLayout);
createCloseButton(composite);
createActionButton(composite);
}
private void createCloseButton(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#9b9b9b"))); //$NON-NLS-1$
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
composite.setLayoutData(layoutData);
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.marginLeft = 1;
layout.marginBottom = 1;
composite.setLayout(layout);
Composite composite2 = new Composite(composite, SWT.NONE);
composite2.setBackground(parent.getBackground());
GridData layoutData2 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite2.setLayoutData(layoutData2);
GridLayout layout2 = new GridLayout(1, false);
layout2.marginWidth = 0;
layout2.marginHeight = 0;
composite2.setLayout(layout2);
close = new Label(composite2, SWT.RIGHT);
close.setBackground(close.getParent().getBackground());
close.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
close.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
close.setFont(
(Font) resources
.get(FontDescriptor.createFrom(FontUtils.bold(
FontUtils.relativeHeight(
close.getFont().getFontData(), -1),
true))));
close.setText(Messages.Notification_closeButton_text);
composite2.setCursor(
parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
close.setCursor(parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
//add select feedback
final Color original = close.getForeground();
MouseTrackListener mouseTrackListener = new MouseTrackListener() {
public void mouseHover(MouseEvent e) {
}
public void mouseExit(MouseEvent e) {
close.setForeground(original);
}
public void mouseEnter(MouseEvent e) {
close.setForeground((Color) resources
.get(ColorUtils.toDescriptor("#3399ff"))); //$NON-NLS-1$
}
};
composite.addMouseTrackListener(mouseTrackListener);
close.addMouseTrackListener(mouseTrackListener);
MouseListener mouseListener = new MouseListener() {
public void mouseUp(MouseEvent e) {
}
public void mouseDown(MouseEvent e) {
close();
}
public void mouseDoubleClick(MouseEvent e) {
}
};
composite2.addMouseListener(mouseListener);
close.addMouseListener(mouseListener);
}
private void createActionButton(Composite parent) {
boolean hasAction = action != null;
if (hasAction) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#9b9b9b"))); //$NON-NLS-1$
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
composite.setLayoutData(layoutData);
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.marginLeft = 1;
layout.marginTop = 0;
composite.setLayout(layout);
Composite composite2 = new Composite(composite, SWT.NONE);
composite2.setBackground(parent.getBackground());
GridData layoutData2 = new GridData(SWT.FILL, SWT.FILL, true, true);
composite2.setLayoutData(layoutData2);
GridLayout layout2 = new GridLayout(1, false);
layout2.marginWidth = 0;
layout2.marginHeight = 0;
composite2.setLayout(layout2);
final Label actionButton = new Label(composite2, SWT.RIGHT);
actionButton.setBackground(parent.getBackground());
actionButton.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
actionButton.setLayoutData(
new GridData(SWT.CENTER, SWT.CENTER, true, true));
actionButton.setFont((Font) resources
.get(FontDescriptor.createFrom(FontUtils.bold(
FontUtils.relativeHeight(
actionButton.getFont().getFontData(), -1),
true))));
actionButton.setText(action.getText());
composite2.setCursor(
parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
actionButton.setCursor(
parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
//add select feedback
final Color original = actionButton.getForeground();
MouseTrackListener mouseTrackListener = new MouseTrackListener() {
public void mouseHover(MouseEvent e) {
}
public void mouseExit(MouseEvent e) {
actionButton.setForeground(original);
}
public void mouseEnter(MouseEvent e) {
actionButton.setForeground((Color) resources
.get(ColorUtils.toDescriptor("#3399ff"))); //$NON-NLS-1$
}
};
composite.addMouseTrackListener(mouseTrackListener);
actionButton.addMouseTrackListener(mouseTrackListener);
Listener mouseDownListener = new Listener() {
public void handleEvent(Event event) {
close();
action.run();
}
};
composite2.addListener(SWT.MouseDown, mouseDownListener);
actionButton.addListener(SWT.MouseDown, mouseDownListener);
}
}
/**
* @param stayDuration
* the duration this dialog will stay on the screen, in
* milliseconds
*/
public void setDuration(int stayDuration) {
this.duration = stayDuration;
}
@Override
public int open() {
int code = super.open();
if (timer == null) {
timer = new UITimer(duration, 0, 0, new SafeRunnable() {
public void run() {
close();
}
});
}
timer.run();
group.add(this);
return code;
}
@Override
public boolean close() {
boolean closed = super.close();
if (timer != null) {
timer.cancel();
timer = null;
}
group.remove(this);
return closed;
}
public void setCloseButtonListener(int eventType, Listener listener) {
if (close == null || close.isDisposed())
return;
close.addListener(eventType, listener);
close.getParent().addListener(eventType, listener);
}
}