001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.intro.impl.swt;
011:
012: import org.eclipse.swt.SWT;
013: import org.eclipse.swt.graphics.Color;
014: import org.eclipse.swt.graphics.Point;
015: import org.eclipse.swt.graphics.Rectangle;
016: import org.eclipse.swt.layout.GridData;
017: import org.eclipse.swt.layout.GridLayout;
018: import org.eclipse.swt.widgets.Composite;
019: import org.eclipse.swt.widgets.Control;
020: import org.eclipse.swt.widgets.Label;
021: import org.eclipse.swt.widgets.Layout;
022: import org.eclipse.ui.forms.IFormColors;
023: import org.eclipse.ui.forms.events.HyperlinkAdapter;
024: import org.eclipse.ui.forms.events.HyperlinkEvent;
025: import org.eclipse.ui.forms.widgets.Form;
026: import org.eclipse.ui.forms.widgets.FormToolkit;
027: import org.eclipse.ui.forms.widgets.ImageHyperlink;
028: import org.eclipse.ui.forms.widgets.ScrolledPageBook;
029: import org.eclipse.ui.internal.intro.impl.IIntroConstants;
030: import org.eclipse.ui.internal.intro.impl.Messages;
031: import org.eclipse.ui.internal.intro.impl.model.AbstractBaseIntroElement;
032: import org.eclipse.ui.internal.intro.impl.model.AbstractIntroElement;
033: import org.eclipse.ui.internal.intro.impl.model.IntroContentProvider;
034: import org.eclipse.ui.internal.intro.impl.model.IntroGroup;
035: import org.eclipse.ui.internal.intro.impl.model.IntroHomePage;
036: import org.eclipse.ui.internal.intro.impl.model.IntroLink;
037: import org.eclipse.ui.internal.intro.impl.model.IntroModelRoot;
038: import org.eclipse.ui.internal.intro.impl.model.url.IntroURLParser;
039: import org.eclipse.ui.internal.intro.impl.util.DialogUtil;
040: import org.eclipse.ui.internal.intro.impl.util.ImageUtil;
041: import org.eclipse.ui.internal.intro.impl.util.StringUtil;
042: import org.eclipse.ui.internal.intro.impl.util.Util;
043: import org.eclipse.ui.intro.config.IIntroContentProviderSite;
044:
045: /**
046: * A Composite that represents the Root Page. It is swapped in the main page
047: * book in the FormIntroPartImplementation class.
048: */
049: public class RootPageForm implements IIntroConstants {
050:
051: private FormToolkit toolkit;
052: private IntroHomePage rootPage;
053: private Form parentForm;
054: protected Label descriptionLabel;
055: private PageStyleManager rootPageStyleManager;
056: private IIntroContentProviderSite site;
057: private PageWidgetFactory factory;
058:
059: class PageComposite extends Composite {
060:
061: public PageComposite(Composite parent, int style) {
062: super (parent, style);
063: }
064:
065: // Do not allow composite to take wHint as-is - layout manager
066: // can reject the hint and compute larger width.
067: public Point computeSize(int wHint, int hHint, boolean changed) {
068: return ((RootPageLayout) getLayout()).computeSize(this ,
069: wHint, hHint, changed);
070: }
071: }
072:
073: class RootPageLayout extends Layout {
074:
075: // gap between link composite and description label.
076: private int VERTICAL_SPACING = 20;
077:
078: private int LABEL_MARGIN_WIDTH = 5;
079:
080: /*
081: * Custom layout for Root Page Composite.
082: */
083: protected Point computeSize(Composite composite, int wHint,
084: int hHint, boolean flushCache) {
085: int innerWHint = wHint;
086: if (wHint != SWT.DEFAULT)
087: innerWHint -= LABEL_MARGIN_WIDTH + LABEL_MARGIN_WIDTH;
088: Control[] children = composite.getChildren();
089: Point s1 = children[0]
090: .computeSize(SWT.DEFAULT, SWT.DEFAULT);
091: Point s2 = children[1].computeSize(innerWHint, SWT.DEFAULT);
092: s2.x += LABEL_MARGIN_WIDTH;
093: int height = 2 * (s2.y + VERTICAL_SPACING + s1.y / 2);
094: Point size = new Point(Math.max(s1.x, s2.x), height + 5);
095: return size;
096: }
097:
098: /*
099: * (non-Javadoc)
100: *
101: * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite,
102: * boolean)
103: */
104: protected void layout(Composite composite, boolean flushCache) {
105: Control[] children = composite.getChildren();
106: Rectangle carea = composite.getClientArea();
107: Control content = children[0];
108: Control label = children[1];
109: Point contentSize = content.computeSize(SWT.DEFAULT,
110: SWT.DEFAULT);
111: Point labelSize = label.computeSize(carea.width - 2
112: - LABEL_MARGIN_WIDTH * 2, SWT.DEFAULT);
113: content.setBounds(carea.width / 2 - contentSize.x / 2,
114: carea.height / 2 - contentSize.y / 2,
115: contentSize.x, contentSize.y);
116: label.setBounds(LABEL_MARGIN_WIDTH, content.getLocation().y
117: + contentSize.y + VERTICAL_SPACING, carea.width
118: - LABEL_MARGIN_WIDTH * 2, labelSize.y);
119: }
120: }
121:
122: private HyperlinkAdapter hyperlinkAdapter = new HyperlinkAdapter() {
123:
124: public void linkActivated(HyperlinkEvent e) {
125: ImageHyperlink imageLink = (ImageHyperlink) e.getSource();
126: IntroLink introLink = (IntroLink) imageLink
127: .getData(INTRO_LINK);
128: IntroURLParser parser = new IntroURLParser(introLink
129: .getUrl());
130: if (parser.hasIntroUrl()) {
131: // execute the action embedded in the IntroURL
132: parser.getIntroURL().execute();
133: return;
134: } else if (parser.hasProtocol()) {
135: Util.openBrowser(introLink.getUrl());
136: return;
137: }
138: DialogUtil.displayInfoMessage(imageLink.getShell(),
139: Messages.HyperlinkAdapter_urlIs
140: + introLink.getUrl());
141: }
142:
143: public void linkEntered(HyperlinkEvent e) {
144: ImageHyperlink imageLink = (ImageHyperlink) e.getSource();
145: IntroLink introLink = (IntroLink) imageLink
146: .getData(INTRO_LINK);
147: updateDescription(introLink.getText());
148: }
149:
150: public void linkExited(HyperlinkEvent e) {
151: // empty text on exit.
152: updateDescription(""); //$NON-NLS-1$
153: }
154:
155: private void updateDescription(String text) {
156: if (text == null)
157: text = ""; //$NON-NLS-1$
158: descriptionLabel.setText(text);
159: descriptionLabel.getParent().layout();
160: }
161: };
162:
163: /**
164: *
165: */
166: public RootPageForm(FormToolkit toolkit, IntroModelRoot modelRoot,
167: Form parentForm) {
168: this .toolkit = toolkit;
169: this .rootPage = modelRoot.getHomePage();
170: this .parentForm = parentForm;
171: }
172:
173: /**
174: * Create the form for the root page. Number of columns there is equal to
175: * the number of links.
176: *
177: * @param pageBook
178: */
179: public void createPartControl(ScrolledPageBook mainPageBook,
180: SharedStyleManager shardStyleManager) {
181: // first, create the root page style manager from shared style manager.
182: rootPageStyleManager = new PageStyleManager(rootPage,
183: shardStyleManager.getProperties());
184:
185: // Set title of Main form from root page title.
186: parentForm.setText(rootPage.getTitle());
187:
188: // Composite for full root page. It has custom layout, and two
189: // children: the content composite and the description label.
190: Composite rootPageComposite = new PageComposite(mainPageBook
191: .getContainer(), SWT.NULL);
192: toolkit.adapt(rootPageComposite);
193:
194: mainPageBook.registerPage(rootPage.getId(), rootPageComposite);
195: rootPageComposite.setLayout(new RootPageLayout());
196: // Util.highlight(pageComposite, SWT.COLOR_DARK_CYAN);
197:
198: // create the contents composite in the center of the root page.
199: createRootPageContent(rootPageComposite);
200:
201: // create description label for links description.
202: descriptionLabel = createHoverLabel(rootPageComposite);
203:
204: // Clear memory. No need for style manager any more.
205: rootPageStyleManager = null;
206: }
207:
208: /**
209: * Creates content of the root page.
210: */
211: private void createRootPageContent(Composite rootPageComposite) {
212: // setup page composite/layout
213: Composite contentComposite = toolkit
214: .createComposite(rootPageComposite);
215: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
216: contentComposite.setLayoutData(gd);
217: AbstractIntroElement[] children = (AbstractIntroElement[]) rootPage
218: .getChildrenOfType(AbstractIntroElement.GROUP
219: | AbstractIntroElement.LINK
220: | AbstractIntroElement.CONTENT_PROVIDER);
221: int numChildren = children.length;
222: GridLayout layout = new GridLayout();
223: // separate links a bit more.
224: layout.horizontalSpacing = rootPageStyleManager
225: .getPageHorizantalSpacing();
226: layout.verticalSpacing = rootPageStyleManager
227: .getPageVerticalSpacing();
228: // set number of columns.
229: int numColumns = rootPageStyleManager.getPageNumberOfColumns();
230: numColumns = numColumns == 0 ? numChildren : numColumns;
231: layout.numColumns = numColumns;
232: layout.horizontalSpacing = rootPageStyleManager
233: .getPageHorizantalSpacing();
234: layout.verticalSpacing = rootPageStyleManager
235: .getPageVerticalSpacing();
236: contentComposite.setLayout(layout);
237: for (int i = 0; i < children.length; i++) {
238: if (((AbstractBaseIntroElement) children[i]).isFiltered())
239: continue;
240: if (children[i].getType() == AbstractIntroElement.GROUP)
241: createGroupContent(contentComposite,
242: (IntroGroup) children[i]);
243: else if (children[i].getType() == AbstractIntroElement.LINK)
244: createImageHyperlink(contentComposite,
245: (IntroLink) children[i]);
246: else if (children[i].getType() == AbstractIntroElement.CONTENT_PROVIDER)
247: createContentProvider(contentComposite,
248: (IntroContentProvider) children[i]);
249: }
250: }
251:
252: /**
253: * Creates content of the root page.
254: */
255: private void createGroupContent(Composite parent, IntroGroup group) {
256: AbstractIntroElement[] children = (AbstractIntroElement[]) group
257: .getChildrenOfType(AbstractIntroElement.GROUP
258: | AbstractIntroElement.LINK
259: | AbstractIntroElement.CONTENT_PROVIDER);
260: int numChildren = children.length;
261: // setup page composite/layout
262: Composite contentComposite = toolkit.createComposite(parent);
263: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
264: gd.horizontalSpan = rootPageStyleManager.getColSpan(group);
265: gd.verticalSpan = rootPageStyleManager.getRowSpan(group);
266: contentComposite.setLayoutData(gd);
267: GridLayout layout = new GridLayout();
268: // separate links a bit more.
269: layout.horizontalSpacing = 20;
270: // set number of columns.
271: int numColumns = rootPageStyleManager.getNumberOfColumns(group);
272: numColumns = numColumns < 1 ? numChildren : numColumns;
273: layout.numColumns = numColumns;
274: layout.verticalSpacing = rootPageStyleManager
275: .getVerticalSpacing(group);
276: layout.horizontalSpacing = rootPageStyleManager
277: .getHorizantalSpacing(group);
278: contentComposite.setLayout(layout);
279: for (int i = 0; i < children.length; i++) {
280: if (((AbstractBaseIntroElement) children[i]).isFiltered())
281: continue;
282: if (children[i].getType() == AbstractIntroElement.GROUP)
283: createGroupContent(contentComposite,
284: (IntroGroup) children[i]);
285: else if (children[i].getType() == AbstractIntroElement.LINK)
286: createImageHyperlink(contentComposite,
287: (IntroLink) children[i]);
288: else if (children[i].getType() == AbstractIntroElement.CONTENT_PROVIDER)
289: createContentProvider(contentComposite,
290: (IntroContentProvider) children[i]);
291: }
292: }
293:
294: /**
295: * Creates an Image Hyperlink from an IntroLink. Model object is cached in
296: * link.
297: *
298: * @param body
299: * @param link
300: */
301: private void createImageHyperlink(Composite parent, IntroLink link) {
302: // create the container composite that will hold the imageHyperLink and
303: // the label for the description.
304: Composite container = toolkit.createComposite(parent);
305: // Util.highlight(container, SWT.COLOR_CYAN);
306: GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
307: gd.horizontalSpan = rootPageStyleManager.getColSpan(link);
308: gd.verticalSpan = rootPageStyleManager.getRowSpan(link);
309: container.setLayoutData(gd);
310:
311: GridLayout layout = new GridLayout();
312: layout.marginWidth = 0;
313: layout.marginHeight = 0;
314: container.setLayout(layout);
315: ImageHyperlink imageLink = toolkit.createImageHyperlink(
316: container, SWT.NULL);
317: imageLink.setImage(rootPageStyleManager.getImage(link,
318: "link-icon", //$NON-NLS-1$
319: ImageUtil.DEFAULT_ROOT_LINK));
320: imageLink.setHoverImage(rootPageStyleManager.getImage(link,
321: "hover-icon", null)); //$NON-NLS-1$
322: // each link is centered in cell.
323: gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
324: imageLink.setLayoutData(gd);
325: // cache the intro link model object for description and URL.
326: imageLink.setData(INTRO_LINK, link);
327: imageLink.addHyperlinkListener(hyperlinkAdapter);
328:
329: // description label.
330: Label linkLabel = toolkit.createLabel(container, link
331: .getLabel());
332: gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
333: linkLabel.setFont(PageStyleManager.getBannerFont());
334: linkLabel.setLayoutData(gd);
335: }
336:
337: /**
338: * Creates a label to display the link description when you hover over a
339: * hyperlink.
340: *
341: * @param body
342: */
343: private Label createHoverLabel(Composite body) {
344: Label label = toolkit.createLabel(body, "", SWT.WRAP); //$NON-NLS-1$
345: String key = StringUtil.concat(rootPage.getId(),
346: ".", "hover-text.fg") //$NON-NLS-1$ //$NON-NLS-2$
347: .toString();
348: Color fg = rootPageStyleManager.getColor(toolkit, key);
349: if (fg == null)
350: fg = toolkit.getColors().getColor(IFormColors.TITLE);
351: label.setForeground(fg);
352: label.setAlignment(SWT.CENTER);
353: label.setFont(PageStyleManager.getBannerFont());
354: return label;
355: }
356:
357: private void createContentProvider(Composite parent,
358: IntroContentProvider providerElement) {
359: if (factory == null) {
360: factory = new PageWidgetFactory(toolkit,
361: rootPageStyleManager);
362: factory.setContentProviderSite(site);
363: }
364: factory.createContentProvider(parent, providerElement);
365: }
366:
367: public void setContentProviderSite(IIntroContentProviderSite site) {
368: this.site = site;
369: }
370: }
|