/******************************************************************************* * Copyright (c) 2011 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are made available under the terms * of the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ package org.eclipse.tcf.te.ui.forms; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.PlatformObject; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.GC; 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.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.events.IExpansionListener; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; /** * Custom form toolkit for using form elements within * dialog and wizard pages, or other containers. */ public class CustomFormToolkit extends PlatformObject { // The reference of the wrapped toolkit private final FormToolkit toolkit; /** * Constructor. * * @param toolkit The {@link FormToolkit} instance to wrap. Must not be null. */ public CustomFormToolkit(FormToolkit toolkit) { super(); Assert.isNotNull(toolkit); this.toolkit = toolkit; } /** * Returns the wrapped {@link FormToolkit} instance. * * @return The wrapped {@link FormToolkit} instance. */ public final FormToolkit getFormToolkit() { return toolkit; } /** * Dispose the form toolkit wrapper. */ public void dispose() { toolkit.dispose(); } /* (non-Javadoc) * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) */ @Override public Object getAdapter(Class adapter) { if (FormToolkit.class.isAssignableFrom(adapter)) return getFormToolkit(); return super.getAdapter(adapter); } /** * Returns the number of pixels corresponding to the height of the given * number of characters. *

* This methods uses the static {@link Dialog#convertHeightInCharsToPixels(org.eclipse.swt.graphics.FontMetrics, int)} * method for calculation. *

* @param chars The number of characters * @return The corresponding height in pixels */ protected int convertHeightInCharsToPixels(Control control, int chars) { int height = 0; if (control != null && !control.isDisposed()) { GC gc = new GC(control); gc.setFont(JFaceResources.getDialogFont()); height = Dialog.convertHeightInCharsToPixels(gc.getFontMetrics(), chars); gc.dispose(); } return height; } /** * Creates a new scrollable form container within the given parent. If * overwriteBackground is set, the parent background color * and background image is applied to the created scrollable form. * * @param parent The parent composite. Must not be null. * @param title The form title or null if none. * @param overwriteBackground If true, the parent background color and image are applied to the scrollable form. * * @return The scrollable form instance. */ public ScrolledForm createScrolledForm(Composite parent, String title, boolean overwriteBackground) { Assert.isNotNull(parent); // Create the scrolled form which is the scrollable container for the expandable composite final ScrolledForm scrollableForm = getFormToolkit().createScrolledForm(parent); // Overwrite background color and image if requested if (overwriteBackground) { scrollableForm.setBackground(parent.getBackground()); scrollableForm.setBackgroundImage(parent.getBackgroundImage()); } // If a title is given, set and decorate the header if (title != null && scrollableForm.getForm() != null) { scrollableForm.getForm().setText(title); getFormToolkit().decorateFormHeading(scrollableForm.getForm()); } return scrollableForm; } /** * Creates an expandable composite within the given parent scrollable form using the given title. * If overwriteBackground is set, the parent background color and background image * is applied to the created expandable composite. * * @param scrolledForm The parent scrolled form. Must not be null. * @param title The expandable composite title. Must not be null. * @param entriesToShow The number of entries to show within the expanded area. Must be greater than 0. * @param expanded The initial expanded state of the expandable composite. * @param overwriteBackground If true, the parent background color and image are applied to the expandable composite. * * @return The expandable composite. */ public final ExpandableComposite createExpandableComposite(final ScrolledForm scrolledForm, String title, final int entriesToShow, boolean expanded, boolean overwriteBackground) { Assert.isNotNull(scrolledForm); Assert.isNotNull(title); Assert.isTrue(entriesToShow > 0); // Create the expandable composite within the scrollable container final ExpandableComposite expandable = getFormToolkit().createExpandableComposite(scrolledForm.getBody(), ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT); expandable.setText(title); // Overwrite background color and image if requested if (overwriteBackground) { expandable.setBackground(scrolledForm.getBackground()); expandable.setBackgroundImage(scrolledForm.getBackgroundImage()); } expandable.setLayout(new GridLayout()); expandable.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Create an associate an expansion listener to the expandable form expandable.addExpansionListener(new IExpansionListener() { boolean notExpanded = true; /* (non-Javadoc) * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanged(org.eclipse.ui.forms.events.ExpansionEvent) */ @Override public void expansionStateChanged(ExpansionEvent e) { // Always set the scrolled form to re-flow. Otherwise it wouldn't // re-arrange the controls following this expandable composite on // collapse. scrolledForm.reflow(true); // Get the shell from the scrolled form. Shell shell = scrolledForm.getShell(); if (shell != null && !shell.isDisposed() && e.getState() && notExpanded) { // And recalculate the bounds on expand shell.setRedraw(false); Rectangle shellBounds = shell.getBounds(); // Assume at minimum 4 controls within the expandable area. shellBounds.height += convertHeightInCharsToPixels(expandable, Math.max(4, entriesToShow)) + IDialogConstants.VERTICAL_SPACING; shell.setBounds(shellBounds); shell.setRedraw(true); notExpanded = false; } } /* (non-Javadoc) * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanging(org.eclipse.ui.forms.events.ExpansionEvent) */ @Override public void expansionStateChanging(ExpansionEvent e) { } }); // Create the client area the caller can use as parent for the control Composite client = getFormToolkit().createComposite(expandable); client.setLayout(new GridLayout()); // Overwrite background color and image if requested if (overwriteBackground) { client.setBackground(scrolledForm.getBackground()); client.setBackgroundImage(scrolledForm.getBackgroundImage()); } // Set the initial expansion state expandable.setExpanded(expanded); // And associated the client expandable.setClient(client); return expandable; } /** * Creates an expandable section within the given parent scrollable form using the given title. * If overwriteBackground is set, the parent background color and background image * is applied to the created section. * * @param parent The parent scrolled form. Must not be null. * @param title The expandable composite title. Must not be null. * @param entriesToShow The number of entries to show within the expanded area. Must be greater than 0. * @param expanded The initial expanded state of the section. * @param overwriteBackground If true, the parent background color and image are applied to the section. * * @return The section. */ public final Section createSection(final ScrolledForm scrolledForm, String title, final int entriesToShow, boolean expanded, boolean overwriteBackground) { Assert.isNotNull(scrolledForm); Assert.isNotNull(title); Assert.isTrue(entriesToShow > 0); // Create the section within the scrollable container final Section section = getFormToolkit().createSection(scrolledForm.getBody(), ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT); section.setText(title); // Overwrite background color and image if requested if (overwriteBackground) { section.setBackground(scrolledForm.getBackground()); section.setBackgroundImage(scrolledForm.getBackgroundImage()); } section.setLayout(new GridLayout()); section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Create an associate an expansion listener to the expandable form section.addExpansionListener(new IExpansionListener() { boolean notExpanded = true; /* (non-Javadoc) * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanged(org.eclipse.ui.forms.events.ExpansionEvent) */ @Override public void expansionStateChanged(ExpansionEvent e) { // Always set the scrolled form to re-flow. Otherwise it wouldn't // re-arrange the controls following this expandable composite on // collapse. scrolledForm.reflow(true); // Get the shell from the scrolled form. Shell shell = scrolledForm.getShell(); if (shell != null && !shell.isDisposed() && e.getState() && notExpanded) { // And recalculate the bounds on expand shell.setRedraw(false); Rectangle shellBounds = shell.getBounds(); // Assume at minimum 4 controls within the expandable area. shellBounds.height += convertHeightInCharsToPixels(section, Math.max(4, entriesToShow)) + IDialogConstants.VERTICAL_SPACING; shell.setBounds(shellBounds); shell.setRedraw(true); notExpanded = false; } } /* (non-Javadoc) * @see org.eclipse.ui.forms.events.IExpansionListener#expansionStateChanging(org.eclipse.ui.forms.events.ExpansionEvent) */ @Override public void expansionStateChanging(ExpansionEvent e) { } }); // Create the client area the caller can use as parent for the control Composite client = getFormToolkit().createComposite(section); client.setLayout(new GridLayout()); // Overwrite background color and image if requested if (overwriteBackground) { client.setBackground(scrolledForm.getBackground()); client.setBackgroundImage(scrolledForm.getBackgroundImage()); } // Set the initial expansion state section.setExpanded(expanded); // And associated the client section.setClient(client); return section; } /** * Creates an non-expandable section within the given parent scrollable form using the given title. * If overwriteBackground is set, the parent background color and background image * is applied to the created section. * * @param scrolledForm The parent scrolled form. Must not be null. * @param title The expandable composite title. Must not be null. * @param overwriteBackground If true, the parent background color and image are applied to the section. * * @return The section. */ public final Section createSection(final ScrolledForm scrolledForm, String title, boolean overwriteBackground) { Assert.isNotNull(scrolledForm); Assert.isNotNull(title); // Create the section within the scrollable container final Section section = getFormToolkit().createSection(scrolledForm.getBody(), ExpandableComposite.TITLE_BAR | ExpandableComposite.CLIENT_INDENT); section.setText(title); // Overwrite background color and image if requested if (overwriteBackground) { section.setBackground(scrolledForm.getBackground()); section.setBackgroundImage(scrolledForm.getBackgroundImage()); } // Configure the layout section.setLayout(new GridLayout()); section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Create the client area the caller can use as parent for the control Composite client = getFormToolkit().createComposite(section); client.setLayout(new GridLayout()); // Overwrite background color and image if requested if (overwriteBackground) { client.setBackground(section.getBackground()); client.setBackgroundImage(section.getBackgroundImage()); } // And associated the client section.setClient(client); return section; } /** * Creates an non-expandable section within the given parent composite using the given title. * If overwriteBackground is set, the parent background color and background image * is applied to the created section. * * @param parent The parent composite. Must not be null. * @param title The expandable composite title. Must not be null. * @param overwriteBackground If true, the parent background color and image are applied to the section. * * @return The section. */ public final Section createSection(final Composite parent, String title, boolean overwriteBackground) { Assert.isNotNull(parent); Assert.isNotNull(title); // Create the section within the scrollable container final Section section = getFormToolkit().createSection(parent, ExpandableComposite.TITLE_BAR | ExpandableComposite.CLIENT_INDENT); section.setText(title); // Overwrite background color and image if requested if (overwriteBackground) { section.setBackground(parent.getBackground()); section.setBackgroundImage(parent.getBackgroundImage()); } // Configure the layout section.setLayout(new GridLayout()); section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Create the client area the caller can use as parent for the control Composite client = getFormToolkit().createComposite(section); client.setLayout(new GridLayout()); // Overwrite background color and image if requested if (overwriteBackground) { client.setBackground(section.getBackground()); client.setBackgroundImage(section.getBackgroundImage()); } // And associated the client section.setClient(client); return section; } /** * Creates a composite with a highlighted note entry and a message text. * This is designed to take up the full width of the page. * * @param parent The parent composite. Must not be null. * @param title The note title. Must not be null. * @param message The note message Must not be null. * @param widthHint The note message width hint in pixel or SWT.DEFAULT. * @param overwriteBackground If true, the parent background color and image are applied to the note composite. * * @return The note composite. */ public final Composite createNoteComposite(Composite parent, String title, String message, int widthHint, boolean overwriteBackground) { Assert.isNotNull(parent); Assert.isNotNull(title); Assert.isNotNull(message); Composite composite = getFormToolkit().createComposite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL)); composite.setFont(parent.getFont()); Label noteLabel = getFormToolkit().createLabel(composite, title, SWT.BOLD); noteLabel.setFont(JFaceResources.getFontRegistry().getBold(JFaceResources.DIALOG_FONT)); noteLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); Label messageLabel = getFormToolkit().createLabel(composite, message); GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); layoutData.widthHint = widthHint; messageLabel.setLayoutData(layoutData); messageLabel.setFont(parent.getFont()); // Overwrite background color and image if requested if (overwriteBackground) { composite.setBackground(parent.getBackground()); composite.setBackgroundImage(parent.getBackgroundImage()); noteLabel.setBackground(parent.getBackground()); noteLabel.setBackgroundImage(parent.getBackgroundImage()); messageLabel.setBackground(parent.getBackground()); messageLabel.setBackgroundImage(parent.getBackgroundImage()); } return composite; } }