0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.ui.internal.forms.widgets;
0011:
0012: import java.util.Hashtable;
0013:
0014: import org.eclipse.core.runtime.Assert;
0015: import org.eclipse.core.runtime.ListenerList;
0016: import org.eclipse.jface.action.IMenuManager;
0017: import org.eclipse.jface.action.IToolBarManager;
0018: import org.eclipse.jface.action.ToolBarManager;
0019: import org.eclipse.jface.dialogs.Dialog;
0020: import org.eclipse.jface.dialogs.IMessageProvider;
0021: import org.eclipse.jface.resource.JFaceResources;
0022: import org.eclipse.swt.SWT;
0023: import org.eclipse.swt.custom.CLabel;
0024: import org.eclipse.swt.dnd.DragSourceListener;
0025: import org.eclipse.swt.dnd.DropTargetListener;
0026: import org.eclipse.swt.dnd.Transfer;
0027: import org.eclipse.swt.events.DisposeEvent;
0028: import org.eclipse.swt.events.DisposeListener;
0029: import org.eclipse.swt.events.MouseEvent;
0030: import org.eclipse.swt.events.MouseMoveListener;
0031: import org.eclipse.swt.events.MouseTrackListener;
0032: import org.eclipse.swt.graphics.Color;
0033: import org.eclipse.swt.graphics.Font;
0034: import org.eclipse.swt.graphics.FontMetrics;
0035: import org.eclipse.swt.graphics.GC;
0036: import org.eclipse.swt.graphics.Image;
0037: import org.eclipse.swt.graphics.Point;
0038: import org.eclipse.swt.graphics.Rectangle;
0039: import org.eclipse.swt.widgets.Canvas;
0040: import org.eclipse.swt.widgets.Composite;
0041: import org.eclipse.swt.widgets.Control;
0042: import org.eclipse.swt.widgets.Event;
0043: import org.eclipse.swt.widgets.Layout;
0044: import org.eclipse.swt.widgets.Listener;
0045: import org.eclipse.swt.widgets.ToolBar;
0046: import org.eclipse.ui.forms.IFormColors;
0047: import org.eclipse.ui.forms.IMessage;
0048: import org.eclipse.ui.forms.events.IHyperlinkListener;
0049: import org.eclipse.ui.forms.widgets.Hyperlink;
0050: import org.eclipse.ui.forms.widgets.ILayoutExtension;
0051: import org.eclipse.ui.forms.widgets.SizeCache;
0052: import org.eclipse.ui.internal.forms.IMessageToolTipManager;
0053: import org.eclipse.ui.internal.forms.MessageManager;
0054:
0055: /**
0056: * Form header moved out of the form class.
0057: */
0058: public class FormHeading extends Canvas {
0059: private static final int TITLE_HMARGIN = 1;
0060: private static final int SPACING = 5;
0061: private static final int VSPACING = 5;
0062: private static final int HMARGIN = 6;
0063: private static final int VMARGIN = 1;
0064: private static final int CLIENT_MARGIN = 1;
0065:
0066: private static final int SEPARATOR = 1 << 1;
0067: private static final int BOTTOM_TOOLBAR = 1 << 2;
0068: private static final int BACKGROUND_IMAGE_TILED = 1 << 3;
0069: private static final int SEPARATOR_HEIGHT = 2;
0070: private static final int MESSAGE_AREA_LIMIT = 50;
0071: static IMessage[] NULL_MESSAGE_ARRAY = new IMessage[] {};
0072:
0073: public static final String COLOR_BASE_BG = "baseBg"; //$NON-NLS-1$
0074:
0075: private Image backgroundImage;
0076:
0077: private Image gradientImage;
0078:
0079: Hashtable colors = new Hashtable();
0080:
0081: private int flags;
0082:
0083: private GradientInfo gradientInfo;
0084:
0085: private ToolBarManager toolBarManager;
0086:
0087: private SizeCache toolbarCache = new SizeCache();
0088:
0089: private SizeCache clientCache = new SizeCache();
0090:
0091: private SizeCache messageCache = new SizeCache();
0092:
0093: private TitleRegion titleRegion;
0094:
0095: private MessageRegion messageRegion;
0096:
0097: private IMessageToolTipManager messageToolTipManager = new DefaultMessageToolTipManager();
0098:
0099: private Control headClient;
0100:
0101: private class DefaultMessageToolTipManager implements
0102: IMessageToolTipManager {
0103: public void createToolTip(Control control, boolean imageLabel) {
0104: }
0105:
0106: public void update() {
0107: String details = getMessageType() == 0 ? null
0108: : MessageManager
0109: .createDetails(getChildrenMessages());
0110: if (messageRegion != null)
0111: messageRegion.updateToolTip(details);
0112: if (getMessageType() > 0
0113: && (details == null || details.length() == 0))
0114: details = getMessage();
0115: titleRegion.updateToolTip(details);
0116: }
0117: }
0118:
0119: private class GradientInfo {
0120: Color[] gradientColors;
0121:
0122: int[] percents;
0123:
0124: boolean vertical;
0125: }
0126:
0127: private class FormHeadingLayout extends Layout implements
0128: ILayoutExtension {
0129: public int computeMinimumWidth(Composite composite,
0130: boolean flushCache) {
0131: return computeSize(composite, 5, SWT.DEFAULT, flushCache).x;
0132: }
0133:
0134: public int computeMaximumWidth(Composite composite,
0135: boolean flushCache) {
0136: return computeSize(composite, SWT.DEFAULT, SWT.DEFAULT,
0137: flushCache).x;
0138: }
0139:
0140: public Point computeSize(Composite composite, int wHint,
0141: int hHint, boolean flushCache) {
0142: return layout(composite, false, 0, 0, wHint, hHint,
0143: flushCache);
0144: }
0145:
0146: protected void layout(Composite composite, boolean flushCache) {
0147: Rectangle rect = composite.getClientArea();
0148: layout(composite, true, rect.x, rect.y, rect.width,
0149: rect.height, flushCache);
0150: }
0151:
0152: private Point layout(Composite composite, boolean move, int x,
0153: int y, int width, int height, boolean flushCache) {
0154: Point tsize = null;
0155: Point msize = null;
0156: Point tbsize = null;
0157: Point clsize = null;
0158:
0159: if (flushCache) {
0160: clientCache.flush();
0161: messageCache.flush();
0162: toolbarCache.flush();
0163: }
0164: if (hasToolBar()) {
0165: ToolBar tb = toolBarManager.getControl();
0166: toolbarCache.setControl(tb);
0167: tbsize = toolbarCache.computeSize(SWT.DEFAULT,
0168: SWT.DEFAULT);
0169: }
0170: if (headClient != null) {
0171: clientCache.setControl(headClient);
0172: int cwhint = width;
0173: if (cwhint != SWT.DEFAULT) {
0174: cwhint -= HMARGIN * 2;
0175: if (tbsize != null
0176: && getToolBarAlignment() == SWT.BOTTOM)
0177: cwhint -= tbsize.x + SPACING;
0178: }
0179: clsize = clientCache.computeSize(cwhint, SWT.DEFAULT);
0180: }
0181: int totalFlexWidth = width;
0182: int flexWidth = totalFlexWidth;
0183: if (totalFlexWidth != SWT.DEFAULT) {
0184: totalFlexWidth -= TITLE_HMARGIN * 2;
0185: // complete right margin
0186: if (hasToolBar() && getToolBarAlignment() == SWT.TOP
0187: || hasMessageRegion())
0188: totalFlexWidth -= SPACING;
0189: // subtract tool bar
0190: if (hasToolBar() && getToolBarAlignment() == SWT.TOP)
0191: totalFlexWidth -= tbsize.x + SPACING;
0192: flexWidth = totalFlexWidth;
0193: if (hasMessageRegion()) {
0194: // remove message region spacing and divide by 2
0195: flexWidth -= SPACING;
0196: // flexWidth /= 2;
0197: }
0198: }
0199: /*
0200: * // compute text and message sizes tsize =
0201: * titleRegion.computeSize(flexWidth, SWT.DEFAULT); if (flexWidth !=
0202: * SWT.DEFAULT && tsize.x < flexWidth) flexWidth += flexWidth -
0203: * tsize.x;
0204: *
0205: * if (hasMessageRegion()) {
0206: * messageCache.setControl(messageRegion.getMessageControl()); msize =
0207: * messageCache.computeSize(flexWidth, SWT.DEFAULT); int maxWidth =
0208: * messageCache.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; if
0209: * (maxWidth < msize.x) { msize.x = maxWidth; // recompute title
0210: * with the reclaimed width int tflexWidth = totalFlexWidth -
0211: * SPACING - msize.x; tsize = titleRegion.computeSize(tflexWidth,
0212: * SWT.DEFAULT); } }
0213: */
0214: if (!hasMessageRegion()) {
0215: tsize = titleRegion.computeSize(flexWidth, SWT.DEFAULT);
0216: } else {
0217: // Total flexible area in the first row is flexWidth.
0218: // Try natural widths of title and
0219: Point tsizeNatural = titleRegion.computeSize(
0220: SWT.DEFAULT, SWT.DEFAULT);
0221: messageCache.setControl(messageRegion
0222: .getMessageControl());
0223: Point msizeNatural = messageCache.computeSize(
0224: SWT.DEFAULT, SWT.DEFAULT);
0225: // try to fit all
0226: tsize = tsizeNatural;
0227: msize = msizeNatural;
0228: if (flexWidth != SWT.DEFAULT) {
0229: int needed = tsizeNatural.x + msizeNatural.x;
0230: if (needed > flexWidth) {
0231: // too big - try to limit the message
0232: int mwidth = flexWidth - tsizeNatural.x;
0233: if (mwidth >= MESSAGE_AREA_LIMIT) {
0234: msize.x = mwidth;
0235: } else {
0236: // message is squeezed to the limit
0237: int flex = flexWidth - MESSAGE_AREA_LIMIT;
0238: tsize = titleRegion.computeSize(flex,
0239: SWT.DEFAULT);
0240: msize.x = MESSAGE_AREA_LIMIT;
0241: }
0242: }
0243: }
0244: }
0245:
0246: Point size = new Point(width, height);
0247: if (!move) {
0248: // compute sizes
0249: int width1 = 2 * TITLE_HMARGIN;
0250: width1 += tsize.x;
0251: if (msize != null)
0252: width1 += SPACING + msize.x;
0253: if (tbsize != null && getToolBarAlignment() == SWT.TOP)
0254: width1 += SPACING + tbsize.x;
0255: if (msize != null
0256: || (tbsize != null && getToolBarAlignment() == SWT.TOP))
0257: width1 += SPACING;
0258: size.x = width1;
0259: if (clsize != null) {
0260: int width2 = clsize.x;
0261: if (tbsize != null
0262: && getToolBarAlignment() == SWT.BOTTOM)
0263: width2 += SPACING + tbsize.x;
0264: width2 += 2 * HMARGIN;
0265: size.x = Math.max(width1, width2);
0266: }
0267: // height, first row
0268: size.y = tsize.y;
0269: if (msize != null)
0270: size.y = Math.max(msize.y, size.y);
0271: if (tbsize != null && getToolBarAlignment() == SWT.TOP)
0272: size.y = Math.max(tbsize.y, size.y);
0273: if (size.y > 0)
0274: size.y += VMARGIN * 2;
0275: // add second row
0276: int height2 = 0;
0277: if (tbsize != null
0278: && getToolBarAlignment() == SWT.BOTTOM)
0279: height2 = tbsize.y;
0280: if (clsize != null)
0281: height2 = Math.max(height2, clsize.y);
0282: if (height2 > 0)
0283: size.y += VSPACING + height2 + CLIENT_MARGIN;
0284: // add separator
0285: if (size.y > 0 && isSeparatorVisible())
0286: size.y += SEPARATOR_HEIGHT;
0287: } else {
0288: // position controls
0289: int xloc = x;
0290: int yloc = y + VMARGIN;
0291: int row1Height = tsize.y;
0292: if (hasMessageRegion())
0293: row1Height = Math.max(row1Height, msize.y);
0294: if (hasToolBar() && getToolBarAlignment() == SWT.TOP)
0295: row1Height = Math.max(row1Height, tbsize.y);
0296: titleRegion.setBounds(xloc,
0297: // yloc + row1Height / 2 - tsize.y / 2,
0298: yloc, tsize.x, tsize.y);
0299: xloc += tsize.x;
0300:
0301: if (hasMessageRegion()) {
0302: xloc += SPACING;
0303: int messageOffset = 0;
0304: if (tsize.y > 0) {
0305: // space between title area and title text
0306: int titleLeadingSpace = (tsize.y - titleRegion
0307: .getFontHeight()) / 2;
0308: // space between message control and message text
0309: int messageLeadingSpace = (msize.y - messageRegion
0310: .getFontHeight()) / 2;
0311: // how much to offset the message so baselines align
0312: messageOffset = (titleLeadingSpace + titleRegion
0313: .getFontBaselineHeight())
0314: - (messageLeadingSpace + messageRegion
0315: .getFontBaselineHeight());
0316: }
0317:
0318: messageRegion
0319: .getMessageControl()
0320: .setBounds(
0321: xloc,
0322: tsize.y > 0 ? (yloc + messageOffset)
0323: : (yloc + row1Height / 2 - msize.y / 2),
0324: msize.x, msize.y);
0325: xloc += msize.x;
0326: }
0327: if (toolBarManager != null)
0328: toolBarManager.getControl().setVisible(
0329: !toolBarManager.isEmpty());
0330: if (tbsize != null && getToolBarAlignment() == SWT.TOP) {
0331: ToolBar tbar = toolBarManager.getControl();
0332: tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN,
0333: yloc + row1Height - 1 - tbsize.y, tbsize.x,
0334: tbsize.y);
0335: }
0336: // second row
0337: xloc = HMARGIN;
0338: yloc += row1Height + VSPACING;
0339: int tw = 0;
0340:
0341: if (tbsize != null
0342: && getToolBarAlignment() == SWT.BOTTOM) {
0343: ToolBar tbar = toolBarManager.getControl();
0344: tbar.setBounds(x + width - 1 - tbsize.x - HMARGIN,
0345: yloc, tbsize.x, tbsize.y);
0346: tw = tbsize.x + SPACING;
0347: }
0348: if (headClient != null) {
0349: int carea = width - HMARGIN * 2 - tw;
0350: headClient.setBounds(xloc, yloc, carea, clsize.y);
0351: }
0352: }
0353: return size;
0354: }
0355: }
0356:
0357: private boolean hasToolBar() {
0358: return toolBarManager != null && !toolBarManager.isEmpty();
0359: }
0360:
0361: private boolean hasMessageRegion() {
0362: return messageRegion != null && !messageRegion.isEmpty();
0363: }
0364:
0365: private class MessageRegion {
0366: private String message;
0367: private int messageType;
0368: private CLabel messageLabel;
0369: private IMessage[] messages;
0370: private Hyperlink messageHyperlink;
0371: private ListenerList listeners;
0372: private Color fg;
0373: private int fontHeight = -1;
0374: private int fontBaselineHeight = -1;
0375:
0376: public MessageRegion() {
0377: }
0378:
0379: public boolean isDisposed() {
0380: Control c = getMessageControl();
0381: return c != null && c.isDisposed();
0382: }
0383:
0384: public boolean isEmpty() {
0385: Control c = getMessageControl();
0386: if (c == null)
0387: return true;
0388: return !c.getVisible();
0389: }
0390:
0391: public int getFontHeight() {
0392: if (fontHeight == -1) {
0393: Control c = getMessageControl();
0394: if (c == null)
0395: return 0;
0396: GC gc = new GC(c.getDisplay());
0397: gc.setFont(c.getFont());
0398: fontHeight = gc.getFontMetrics().getHeight();
0399: gc.dispose();
0400: }
0401: return fontHeight;
0402: }
0403:
0404: public int getFontBaselineHeight() {
0405: if (fontBaselineHeight == -1) {
0406: Control c = getMessageControl();
0407: if (c == null)
0408: return 0;
0409: GC gc = new GC(c.getDisplay());
0410: gc.setFont(c.getFont());
0411: FontMetrics fm = gc.getFontMetrics();
0412: fontBaselineHeight = fm.getHeight() - fm.getDescent();
0413: gc.dispose();
0414: }
0415: return fontBaselineHeight;
0416: }
0417:
0418: public void showMessage(String newMessage, int newType,
0419: IMessage[] messages) {
0420: Control oldControl = getMessageControl();
0421: int oldType = messageType;
0422: this .message = newMessage;
0423: this .messageType = newType;
0424: this .messages = messages;
0425: if (newMessage == null) {
0426: // clearing of the message
0427: if (oldControl != null && oldControl.getVisible())
0428: oldControl.setVisible(false);
0429: return;
0430: }
0431: ensureControlExists();
0432: if (needHyperlink()) {
0433: messageHyperlink.setText(newMessage);
0434: messageHyperlink.setHref(messages);
0435: } else {
0436: messageLabel.setText(newMessage);
0437: }
0438: if (oldType != newType)
0439: updateForeground();
0440: }
0441:
0442: public void updateToolTip(String toolTip) {
0443: Control control = getMessageControl();
0444: if (control != null)
0445: control.setToolTipText(toolTip);
0446: }
0447:
0448: public String getMessage() {
0449: return message;
0450: }
0451:
0452: public int getMessageType() {
0453: return messageType;
0454: }
0455:
0456: public IMessage[] getChildrenMessages() {
0457: return messages;
0458: }
0459:
0460: public String getDetailedMessage() {
0461: Control c = getMessageControl();
0462: if (c != null)
0463: return c.getToolTipText();
0464: return null;
0465: }
0466:
0467: public Control getMessageControl() {
0468: if (needHyperlink() && messageHyperlink != null)
0469: return messageHyperlink;
0470: return messageLabel;
0471: }
0472:
0473: public Image getMessageImage() {
0474: switch (messageType) {
0475: case IMessageProvider.INFORMATION:
0476: return JFaceResources
0477: .getImage(Dialog.DLG_IMG_MESSAGE_INFO);
0478: case IMessageProvider.WARNING:
0479: return JFaceResources
0480: .getImage(Dialog.DLG_IMG_MESSAGE_WARNING);
0481: case IMessageProvider.ERROR:
0482: return JFaceResources
0483: .getImage(Dialog.DLG_IMG_MESSAGE_ERROR);
0484: default:
0485: return null;
0486: }
0487: }
0488:
0489: public void addMessageHyperlinkListener(
0490: IHyperlinkListener listener) {
0491: if (listeners == null)
0492: listeners = new ListenerList();
0493: listeners.add(listener);
0494: ensureControlExists();
0495: if (messageHyperlink != null)
0496: messageHyperlink.addHyperlinkListener(listener);
0497: if (listeners.size() == 1)
0498: updateForeground();
0499: }
0500:
0501: private void removeMessageHyperlinkListener(
0502: IHyperlinkListener listener) {
0503: if (listeners != null) {
0504: listeners.remove(listener);
0505: if (messageHyperlink != null)
0506: messageHyperlink.removeHyperlinkListener(listener);
0507: if (listeners.isEmpty())
0508: listeners = null;
0509: ensureControlExists();
0510: if (listeners == null && !isDisposed())
0511: updateForeground();
0512: }
0513: }
0514:
0515: private void ensureControlExists() {
0516: if (needHyperlink()) {
0517: if (messageLabel != null)
0518: messageLabel.setVisible(false);
0519: if (messageHyperlink == null) {
0520: messageHyperlink = new Hyperlink(FormHeading.this ,
0521: SWT.NULL);
0522: messageHyperlink.setUnderlined(true);
0523: messageHyperlink.setText(message);
0524: messageHyperlink.setHref(messages);
0525: Object[] llist = listeners.getListeners();
0526: for (int i = 0; i < llist.length; i++)
0527: messageHyperlink
0528: .addHyperlinkListener((IHyperlinkListener) llist[i]);
0529: if (messageToolTipManager != null)
0530: messageToolTipManager.createToolTip(
0531: messageHyperlink, false);
0532: } else if (!messageHyperlink.getVisible()) {
0533: messageHyperlink.setText(message);
0534: messageHyperlink.setHref(messages);
0535: messageHyperlink.setVisible(true);
0536: }
0537: } else {
0538: // need a label
0539: if (messageHyperlink != null)
0540: messageHyperlink.setVisible(false);
0541: if (messageLabel == null) {
0542: messageLabel = new CLabel(FormHeading.this ,
0543: SWT.NULL);
0544: messageLabel.setText(message);
0545: if (messageToolTipManager != null)
0546: messageToolTipManager.createToolTip(
0547: messageLabel, false);
0548: } else if (!messageLabel.getVisible()) {
0549: messageLabel.setText(message);
0550: messageLabel.setVisible(true);
0551: }
0552: }
0553: layout(true);
0554: }
0555:
0556: private boolean needHyperlink() {
0557: return messageType > 0 && listeners != null;
0558: }
0559:
0560: public void setBackground(Color bg) {
0561: if (messageHyperlink != null)
0562: messageHyperlink.setBackground(bg);
0563: if (messageLabel != null)
0564: messageLabel.setBackground(bg);
0565: }
0566:
0567: public void setForeground(Color fg) {
0568: this .fg = fg;
0569: }
0570:
0571: private void updateForeground() {
0572: Color theFg;
0573:
0574: switch (messageType) {
0575: case IMessageProvider.ERROR:
0576: theFg = getDisplay().getSystemColor(SWT.COLOR_RED);
0577: break;
0578: case IMessageProvider.WARNING:
0579: theFg = getDisplay().getSystemColor(
0580: SWT.COLOR_DARK_YELLOW);
0581: break;
0582: default:
0583: theFg = fg;
0584: }
0585: getMessageControl().setForeground(theFg);
0586: }
0587: }
0588:
0589: /**
0590: * Creates the form content control as a child of the provided parent.
0591: *
0592: * @param parent
0593: * the parent widget
0594: */
0595: public FormHeading(Composite parent, int style) {
0596: super (parent, style);
0597: setBackgroundMode(SWT.INHERIT_DEFAULT);
0598: addListener(SWT.Paint, new Listener() {
0599: public void handleEvent(Event e) {
0600: onPaint(e.gc);
0601: }
0602: });
0603: addListener(SWT.Dispose, new Listener() {
0604: public void handleEvent(Event e) {
0605: if (gradientImage != null) {
0606: FormImages.getInstance()
0607: .markFinished(gradientImage);
0608: gradientImage = null;
0609: }
0610: }
0611: });
0612: addListener(SWT.Resize, new Listener() {
0613: public void handleEvent(Event e) {
0614: if (gradientInfo != null
0615: || (backgroundImage != null && !isBackgroundImageTiled()))
0616: updateGradientImage();
0617: }
0618: });
0619: addMouseMoveListener(new MouseMoveListener() {
0620: public void mouseMove(MouseEvent e) {
0621: updateTitleRegionHoverState(e);
0622: }
0623: });
0624: addMouseTrackListener(new MouseTrackListener() {
0625: public void mouseEnter(MouseEvent e) {
0626: updateTitleRegionHoverState(e);
0627: }
0628:
0629: public void mouseExit(MouseEvent e) {
0630: titleRegion.setHoverState(TitleRegion.STATE_NORMAL);
0631: }
0632:
0633: public void mouseHover(MouseEvent e) {
0634: }
0635: });
0636: super .setLayout(new FormHeadingLayout());
0637: titleRegion = new TitleRegion(this );
0638: }
0639:
0640: /**
0641: * Fully delegates the size computation to the internal layout manager.
0642: */
0643: public final Point computeSize(int wHint, int hHint, boolean changed) {
0644: return ((FormHeadingLayout) getLayout()).computeSize(this ,
0645: wHint, hHint, changed);
0646: }
0647:
0648: /**
0649: * Prevents from changing the custom control layout.
0650: */
0651: public final void setLayout(Layout layout) {
0652: }
0653:
0654: /**
0655: * Returns the title text that will be rendered at the top of the form.
0656: *
0657: * @return the title text
0658: */
0659: public String getText() {
0660: return titleRegion.getText();
0661: }
0662:
0663: /**
0664: * Returns the title image that will be rendered to the left of the title.
0665: *
0666: * @return the title image
0667: * @since 3.2
0668: */
0669: public Image getImage() {
0670: return titleRegion.getImage();
0671: }
0672:
0673: /**
0674: * Sets the background color of the header.
0675: */
0676: public void setBackground(Color bg) {
0677: super .setBackground(bg);
0678: internalSetBackground(bg);
0679: }
0680:
0681: private void internalSetBackground(Color bg) {
0682: titleRegion.setBackground(bg);
0683: if (messageRegion != null)
0684: messageRegion.setBackground(bg);
0685: if (toolBarManager != null)
0686: toolBarManager.getControl().setBackground(bg);
0687: putColor(COLOR_BASE_BG, bg);
0688: }
0689:
0690: /**
0691: * Sets the foreground color of the header.
0692: */
0693: public void setForeground(Color fg) {
0694: super .setForeground(fg);
0695: titleRegion.setForeground(fg);
0696: if (messageRegion != null)
0697: messageRegion.setForeground(fg);
0698: }
0699:
0700: /**
0701: * Sets the text to be rendered at the top of the form above the body as a
0702: * title.
0703: *
0704: * @param text
0705: * the title text
0706: */
0707: public void setText(String text) {
0708: titleRegion.setText(text);
0709: }
0710:
0711: public void setFont(Font font) {
0712: super .setFont(font);
0713: titleRegion.setFont(font);
0714: }
0715:
0716: /**
0717: * Sets the image to be rendered to the left of the title.
0718: *
0719: * @param image
0720: * the title image or <code>null</code> to show no image.
0721: * @since 3.2
0722: */
0723: public void setImage(Image image) {
0724: titleRegion.setImage(image);
0725: if (messageRegion != null)
0726: titleRegion.updateImage(messageRegion.getMessageImage(),
0727: true);
0728: else
0729: titleRegion.updateImage(null, true);
0730: }
0731:
0732: public void setTextBackground(Color[] gradientColors,
0733: int[] percents, boolean vertical) {
0734: if (gradientColors != null) {
0735: gradientInfo = new GradientInfo();
0736: gradientInfo.gradientColors = gradientColors;
0737: gradientInfo.percents = percents;
0738: gradientInfo.vertical = vertical;
0739: setBackground(null);
0740: updateGradientImage();
0741: } else {
0742: // reset
0743: gradientInfo = null;
0744: if (gradientImage != null) {
0745: FormImages.getInstance().markFinished(gradientImage);
0746: gradientImage = null;
0747: setBackgroundImage(null);
0748: }
0749: }
0750: }
0751:
0752: public void setHeadingBackgroundImage(Image image) {
0753: this .backgroundImage = image;
0754: if (image != null)
0755: setBackground(null);
0756: if (isBackgroundImageTiled()) {
0757: setBackgroundImage(image);
0758: } else
0759: updateGradientImage();
0760: }
0761:
0762: public Image getHeadingBackgroundImage() {
0763: return backgroundImage;
0764: }
0765:
0766: public void setBackgroundImageTiled(boolean tiled) {
0767: if (tiled)
0768: flags |= BACKGROUND_IMAGE_TILED;
0769: else
0770: flags &= ~BACKGROUND_IMAGE_TILED;
0771: setHeadingBackgroundImage(this .backgroundImage);
0772: }
0773:
0774: public boolean isBackgroundImageTiled() {
0775: return (flags & BACKGROUND_IMAGE_TILED) != 0;
0776: }
0777:
0778: public void setBackgroundImage(Image image) {
0779: super .setBackgroundImage(image);
0780: if (image != null) {
0781: internalSetBackground(null);
0782: }
0783: }
0784:
0785: /**
0786: * Returns the tool bar manager that is used to manage tool items in the
0787: * form's title area.
0788: *
0789: * @return form tool bar manager
0790: */
0791: public IToolBarManager getToolBarManager() {
0792: if (toolBarManager == null) {
0793: toolBarManager = new ToolBarManager(SWT.FLAT);
0794: ToolBar toolbar = toolBarManager.createControl(this );
0795: toolbar.setBackground(getBackground());
0796: toolbar.setForeground(getForeground());
0797: toolbar.setCursor(FormsResources.getHandCursor());
0798: addDisposeListener(new DisposeListener() {
0799: public void widgetDisposed(DisposeEvent e) {
0800: if (toolBarManager != null) {
0801: toolBarManager.dispose();
0802: toolBarManager = null;
0803: }
0804: }
0805: });
0806: }
0807: return toolBarManager;
0808: }
0809:
0810: /**
0811: * Returns the menu manager that is used to manage tool items in the form's
0812: * title area.
0813: *
0814: * @return form drop-down menu manager
0815: * @since 3.3
0816: */
0817: public IMenuManager getMenuManager() {
0818: return titleRegion.getMenuManager();
0819: }
0820:
0821: /**
0822: * Updates the local tool bar manager if used. Does nothing if local tool
0823: * bar manager has not been created yet.
0824: */
0825: public void updateToolBar() {
0826: if (toolBarManager != null)
0827: toolBarManager.update(false);
0828: }
0829:
0830: private void onPaint(GC gc) {
0831: if (!isSeparatorVisible() && getBackgroundImage() == null)
0832: return;
0833: Rectangle carea = getClientArea();
0834: Image buffer = new Image(getDisplay(), carea.width,
0835: carea.height);
0836: buffer.setBackground(getBackground());
0837: GC igc = new GC(buffer);
0838: igc.setBackground(getBackground());
0839: igc.fillRectangle(0, 0, carea.width, carea.height);
0840: if (getBackgroundImage() != null) {
0841: if (gradientInfo != null)
0842: drawBackground(igc, carea.x, carea.y, carea.width,
0843: carea.height);
0844: else {
0845: Image bgImage = getBackgroundImage();
0846: Rectangle ibounds = bgImage.getBounds();
0847: drawBackground(igc, carea.x, carea.y, ibounds.width,
0848: ibounds.height);
0849: }
0850: }
0851:
0852: if (isSeparatorVisible()) {
0853: // bg separator
0854: if (hasColor(IFormColors.H_BOTTOM_KEYLINE1))
0855: igc
0856: .setForeground(getColor(IFormColors.H_BOTTOM_KEYLINE1));
0857: else
0858: igc.setForeground(getBackground());
0859: igc.drawLine(carea.x, carea.height - 2, carea.x
0860: + carea.width - 1, carea.height - 2);
0861: if (hasColor(IFormColors.H_BOTTOM_KEYLINE2))
0862: igc
0863: .setForeground(getColor(IFormColors.H_BOTTOM_KEYLINE2));
0864: else
0865: igc.setForeground(getForeground());
0866: igc.drawLine(carea.x, carea.height - 1, carea.x
0867: + carea.width - 1, carea.height - 1);
0868: }
0869: igc.dispose();
0870: gc.drawImage(buffer, carea.x, carea.y);
0871: buffer.dispose();
0872: }
0873:
0874: private void updateTitleRegionHoverState(MouseEvent e) {
0875: Rectangle titleRect = titleRegion.getBounds();
0876: titleRect.width += titleRect.x + 15;
0877: titleRect.height += titleRect.y + 15;
0878: titleRect.x = 0;
0879: titleRect.y = 0;
0880: if (titleRect.contains(e.x, e.y))
0881: titleRegion.setHoverState(TitleRegion.STATE_HOVER_LIGHT);
0882: else
0883: titleRegion.setHoverState(TitleRegion.STATE_NORMAL);
0884: }
0885:
0886: private void updateGradientImage() {
0887: Rectangle rect = getBounds();
0888: if (gradientImage != null) {
0889: FormImages.getInstance().markFinished(gradientImage);
0890: gradientImage = null;
0891: }
0892: if (gradientInfo != null) {
0893: gradientImage = FormImages.getInstance().getGradient(
0894: getDisplay(), gradientInfo.gradientColors,
0895: gradientInfo.percents,
0896: gradientInfo.vertical ? rect.height : rect.width,
0897: gradientInfo.vertical, getColor(COLOR_BASE_BG));
0898: } else if (backgroundImage != null && !isBackgroundImageTiled()) {
0899: gradientImage = new Image(getDisplay(), Math.max(
0900: rect.width, 1), Math.max(rect.height, 1));
0901: gradientImage.setBackground(getBackground());
0902: GC gc = new GC(gradientImage);
0903: gc.drawImage(backgroundImage, 0, 0);
0904: gc.dispose();
0905: }
0906: setBackgroundImage(gradientImage);
0907: }
0908:
0909: public boolean isSeparatorVisible() {
0910: return (flags & SEPARATOR) != 0;
0911: }
0912:
0913: public void setSeparatorVisible(boolean addSeparator) {
0914: if (addSeparator)
0915: flags |= SEPARATOR;
0916: else
0917: flags &= ~SEPARATOR;
0918: }
0919:
0920: public void setToolBarAlignment(int alignment) {
0921: if (alignment == SWT.BOTTOM)
0922: flags |= BOTTOM_TOOLBAR;
0923: else
0924: flags &= ~BOTTOM_TOOLBAR;
0925: }
0926:
0927: public int getToolBarAlignment() {
0928: return (flags & BOTTOM_TOOLBAR) != 0 ? SWT.BOTTOM : SWT.TOP;
0929: }
0930:
0931: public void addMessageHyperlinkListener(IHyperlinkListener listener) {
0932: ensureMessageRegionExists();
0933: messageRegion.addMessageHyperlinkListener(listener);
0934: }
0935:
0936: public void removeMessageHyperlinkListener(
0937: IHyperlinkListener listener) {
0938: if (messageRegion != null)
0939: messageRegion.removeMessageHyperlinkListener(listener);
0940: }
0941:
0942: public String getMessage() {
0943: return messageRegion != null ? messageRegion.getMessage()
0944: : null;
0945: }
0946:
0947: public int getMessageType() {
0948: return messageRegion != null ? messageRegion.getMessageType()
0949: : 0;
0950: }
0951:
0952: public IMessage[] getChildrenMessages() {
0953: return messageRegion != null ? messageRegion
0954: .getChildrenMessages() : NULL_MESSAGE_ARRAY;
0955: }
0956:
0957: private void ensureMessageRegionExists() {
0958: // ensure message region exists
0959: if (messageRegion == null)
0960: messageRegion = new MessageRegion();
0961: }
0962:
0963: public void showMessage(String newMessage, int type,
0964: IMessage[] messages) {
0965: if (messageRegion == null) {
0966: // check the trivial case
0967: if (newMessage == null)
0968: return;
0969: } else if (messageRegion.isDisposed())
0970: return;
0971: ensureMessageRegionExists();
0972: messageRegion.showMessage(newMessage, type, messages);
0973: titleRegion.updateImage(messageRegion.getMessageImage(), false);
0974: if (messageToolTipManager != null)
0975: messageToolTipManager.update();
0976: layout();
0977: redraw();
0978: }
0979:
0980: /**
0981: * Tests if the form is in the 'busy' state.
0982: *
0983: * @return <code>true</code> if busy, <code>false</code> otherwise.
0984: */
0985:
0986: public boolean isBusy() {
0987: return titleRegion.isBusy();
0988: }
0989:
0990: /**
0991: * Sets the form's busy state. Busy form will display 'busy' animation in
0992: * the area of the title image.
0993: *
0994: * @param busy
0995: * the form's busy state
0996: */
0997:
0998: public void setBusy(boolean busy) {
0999: if (titleRegion.setBusy(busy))
1000: layout();
1001: }
1002:
1003: public Control getHeadClient() {
1004: return headClient;
1005: }
1006:
1007: public void setHeadClient(Control headClient) {
1008: if (headClient != null)
1009: Assert.isTrue(headClient.getParent() == this );
1010: this .headClient = headClient;
1011: layout();
1012: }
1013:
1014: public void putColor(String key, Color color) {
1015: if (color == null)
1016: colors.remove(key);
1017: else
1018: colors.put(key, color);
1019: }
1020:
1021: public Color getColor(String key) {
1022: return (Color) colors.get(key);
1023: }
1024:
1025: public boolean hasColor(String key) {
1026: return colors.containsKey(key);
1027: }
1028:
1029: public void addDragSupport(int operations,
1030: Transfer[] transferTypes, DragSourceListener listener) {
1031: titleRegion.addDragSupport(operations, transferTypes, listener);
1032: }
1033:
1034: public void addDropSupport(int operations,
1035: Transfer[] transferTypes, DropTargetListener listener) {
1036: titleRegion.addDropSupport(operations, transferTypes, listener);
1037: }
1038:
1039: public IMessageToolTipManager getMessageToolTipManager() {
1040: return messageToolTipManager;
1041: }
1042:
1043: public void setMessageToolTipManager(
1044: IMessageToolTipManager messageToolTipManager) {
1045: this.messageToolTipManager = messageToolTipManager;
1046: }
1047: }
|