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.swt.SWT;
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.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.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.xmind.ui.internal.ToolkitImages;
import org.xmind.ui.resources.ColorUtils;
import org.xmind.ui.resources.FontUtils;
import org.xmind.ui.util.UITimer;
/**
* @author Shawn Liu
* @since 3.6.50
*/
public class Promotion extends Dialog {
private static final int MARGIN = 5;
private static int STAY_DURATION = 5000;
private static List<Promotion> promotionList = new ArrayList<Promotion>();
private String infoText;
private IAction action;
private boolean isCenter;
private UITimer timer;
private int duration = STAY_DURATION;
private ResourceManager resources;
private boolean isClosed = false;
public Promotion(Shell parent, String infoText, IAction action,
boolean isCenter) {
super(parent);
this.infoText = infoText;
this.action = action;
this.isCenter = isCenter;
setShellStyle(SWT.NO_TRIM | SWT.TOOL);
setBlockOnOpen(false);
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
resources = new LocalResourceManager(JFaceResources.getResources(),
newShell);
}
@Override
protected Point getInitialLocation(Point initialSize) {
Point size = getInitialSize();
Rectangle bounds = getParentShell().getBounds();
int x = isCenter ? bounds.x + (bounds.width - size.x) / 2
: bounds.x + bounds.width - size.x - MARGIN;
int y = bounds.y + bounds.height - size.y - MARGIN;
if (promotionList.size() != 0) {
Dialog topDialog = promotionList.get(promotionList.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("#e1e1e1"))); //$NON-NLS-1$
GridData gridData = new GridData(GridData.FILL_BOTH);
gridData.widthHint = 446;
gridData.heightHint = 170;
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(2, false);
gridLayout.marginWidth = 1;
gridLayout.marginHeight = 1;
gridLayout.horizontalSpacing = 0;
composite.setLayout(gridLayout);
createImageSection(composite);
createContentSection(composite);
return composite;
}
private void createImageSection(Composite parent) {
Image image = null;
if (action != null) {
ImageDescriptor imageDesc = action.getImageDescriptor();
if (imageDesc != null) {
image = (Image) resources.get(imageDesc);
}
}
//get default image
Shell sourceShell = getParentShell();
if (image == null && sourceShell != null && !sourceShell.isDisposed()) {
image = findBrandingImage(sourceShell.getImage(),
sourceShell.getImages());
}
if (image != null) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#f7f7f7"))); //$NON-NLS-1$
GridData gridData = new GridData(SWT.LEFT, SWT.FILL, false, true);
composite.setLayoutData(gridData);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.horizontalSpacing = 0;
composite.setLayout(layout);
Composite composite2 = new Composite(composite, SWT.NONE);
composite2.setBackground(composite.getBackground());
GridData gridData2 = new GridData(SWT.FILL, SWT.FILL, true, true);
gridData2.widthHint = 174;
composite2.setLayoutData(gridData2);
GridLayout layout2 = new GridLayout(1, false);
layout2.marginWidth = 0;
layout2.marginHeight = 0;
composite2.setLayout(layout2);
Label iconLabel = new Label(composite2, SWT.CENTER);
iconLabel.setBackground(composite2.getBackground());
GridData gridData3 = new GridData(SWT.CENTER, SWT.CENTER, true,
true);
iconLabel.setLayoutData(gridData3);
iconLabel.setImage(image);
//create separator
createSeperator(composite);
} else {
((GridLayout) parent.getLayout()).numColumns = 1;
}
}
private void createSeperator(Composite parent) {
Composite seperator = new Composite(parent, SWT.NONE);
seperator.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#e1e1e1"))); //$NON-NLS-1$
GridData gridData = new GridData(SWT.CENTER, SWT.FILL, false, true);
gridData.widthHint = 1;
seperator.setLayoutData(gridData);
seperator.setLayout(new GridLayout());
}
private void createContentSection(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
GridData gridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.verticalSpacing = 5;
composite.setLayout(gridLayout);
createCloseButton(composite);
createInfoSection(composite);
createActionButton(composite);
}
private void createCloseButton(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(parent.getBackground());
GridData layoutData = new GridData(SWT.RIGHT, SWT.TOP, false, false);
composite.setLayoutData(layoutData);
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.marginTop = 14;
layout.marginRight = 14;
composite.setLayout(layout);
final Label close = new Label(composite, SWT.RIGHT);
close.setBackground(composite.getBackground());
close.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
final Image focusedImage = (Image) resources
.get(ToolkitImages.get("close.png", true)); //$NON-NLS-1$
final Image noFocusedImage = (Image) resources
.get(ToolkitImages.get("close.png", false)); //$NON-NLS-1$
close.setImage(noFocusedImage);
composite.setCursor(
parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
close.setCursor(parent.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
MouseTrackListener mouseTrackListener = new MouseTrackListener() {
public void mouseHover(MouseEvent e) {
}
public void mouseExit(MouseEvent e) {
close.setImage(noFocusedImage);
}
public void mouseEnter(MouseEvent e) {
close.setImage(focusedImage);
}
};
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) {
}
};
composite.addMouseListener(mouseListener);
close.addMouseListener(mouseListener);
}
private void createInfoSection(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(
(Color) resources.get(ColorUtils.toDescriptor("#ffffff"))); //$NON-NLS-1$
GridData gridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gridData);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginWidth = 20;
gridLayout.marginHeight = 0;
composite.setLayout(gridLayout);
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("#4a4a4a"))); //$NON-NLS-1$
link.setFont((Font) resources.get(FontDescriptor.createFrom(
FontUtils.relativeHeight(link.getFont().getFontData(), 3))));
link.setText(content);
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();
}
});
}
});
}
private void createActionButton(Composite parent) {
boolean hasAction = action != null;
if (hasAction) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setBackground(parent.getBackground());
GridData layoutData = new GridData(SWT.CENTER, SWT.BOTTOM, false,
false);
composite.setLayoutData(layoutData);
GridLayout layout = new GridLayout(1, false);
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.marginBottom = 13;
composite.setLayout(layout);
Hyperlink hyperlink = new Hyperlink(composite, SWT.NONE);
hyperlink.setLayoutData(
new GridData(SWT.CENTER, SWT.CENTER, false, false));
hyperlink.setBackground(composite.getBackground());
hyperlink.setForeground(
(Color) resources.get(ColorUtils.toDescriptor("#4a90e2"))); //$NON-NLS-1$
hyperlink
.setFont(
(Font) resources
.get(FontDescriptor.createFrom(
FontUtils.bold(
FontUtils.relativeHeight(
hyperlink.getFont()
.getFontData(),
3),
true))));
hyperlink.setUnderlined(true);
hyperlink.setText(action.getText());
hyperlink.addHyperlinkListener(new IHyperlinkListener() {
public void linkExited(HyperlinkEvent e) {
}
public void linkEntered(HyperlinkEvent e) {
}
public void linkActivated(HyperlinkEvent e) {
close();
action.run();
}
});
}
}
private Image findBrandingImage(Image mainImage, Image[] images) {
Image best = null;
int scale = -1;
Rectangle r;
int s;
if (mainImage != null) {
r = mainImage.getBounds();
s = Math.abs(r.width - 48) * Math.abs(r.height - 48);
if (scale < 0 || s < scale) {
best = mainImage;
scale = s;
}
}
for (Image img : images) {
r = img.getBounds();
s = Math.abs(r.width - 48) * Math.abs(r.height - 48);
if (scale < 0 || s < scale) {
best = img;
scale = s;
}
}
return best;
}
/**
* @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.cancel();
timer = null;
}
});
}
timer.run();
promotionList.add(this);
return code;
}
@Override
public boolean close() {
return closePromotion();
}
private synchronized boolean closePromotion() {
if (isClosed)
return false;
isClosed = true;
movePromotionLocation(promotionList.indexOf(this));
promotionList.remove(this);
return super.close();
}
private void movePromotionLocation(int index) {
if (promotionList.size() - 1 > index && -1 < index) {
for (int i = index + 1; i < promotionList.size(); i++) {
Promotion prom = promotionList.get(i);
prom.getShell()
.setLocation(new Point(prom.getShell().getBounds().x,
prom.getShell().getBounds().y
+ prom.getInitialSize().y));
}
}
}
}