/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.gef.ui.properties; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.viewers.ISelection; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; 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.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.part.IPageSite; import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.ui.forms.WidgetFactory; public abstract class PropertyPagePart implements IPropertyPagePart { private static final int DEFAULT_SECTION_WIDTH = 200; private static class SectionRec { IPropertySectionPart section; Section control; public SectionRec(IPropertySectionPart section) { this.section = section; } } private IPropertyPartContainer container; private IGraphicalEditor editor; private WidgetFactory widgetFactory; private List<SectionRec> sections = new ArrayList<SectionRec>(); private ScrolledForm form; public void init(IPropertyPartContainer container, IGraphicalEditor editor) { this.container = container; this.editor = editor; for (SectionRec rec : sections) { rec.section.init(this, editor); } } public IPageSite getContainerSite() { return container.getContainerSite(); } public void updateSectionTitle(IPropertySectionPart section) { SectionRec rec = findRecord(section); if (rec != null) { updateSectionTitle(rec); } } private SectionRec findRecord(IPropertySectionPart section) { for (SectionRec rec : sections) { if (rec.section == section) return rec; } return null; } public IGraphicalEditor getContributedEditor() { return editor; } protected void addSection(IPropertySectionPart section) { Assert.isNotNull(section); SectionRec rec = new SectionRec(section); sections.add(rec); section.init(container, editor); if (form != null && !form.isDisposed()) { createSectionControl(form.getBody(), rec); } } public List<IPropertySectionPart> getSections() { List<IPropertySectionPart> list = new ArrayList<IPropertySectionPart>( sections.size()); for (SectionRec rec : sections) { list.add(rec.section); } return list; } public void createControl(Composite parent) { this.widgetFactory = new WidgetFactory(parent.getDisplay()); form = widgetFactory.createScrolledForm(parent); form.setMinWidth(DEFAULT_SECTION_WIDTH); // TODO this not working??? form.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if (widgetFactory != null) { widgetFactory.dispose(); widgetFactory = null; } } }); createSectionControls(form, form.getBody()); form.reflow(true); } protected void createSectionControls(final ScrolledForm form, final Composite parent) { GridLayout layout = new GridLayout(1, true); parent.setLayout(layout); for (SectionRec rec : sections) { createSectionControl(parent, rec); } form.addControlListener(new ControlListener() { public void controlResized(ControlEvent e) { Rectangle area = form.getClientArea(); GridLayout layout = (GridLayout) parent.getLayout(); int newNumColumns = area.width / DEFAULT_SECTION_WIDTH; boolean change = newNumColumns != layout.numColumns && newNumColumns >= 0 && newNumColumns <= parent.getChildren().length; if (change) { layout.numColumns = newNumColumns; parent.layout(); } } public void controlMoved(ControlEvent e) { } }); } private void createSectionControl(Composite parent, SectionRec rec) { rec.control = widgetFactory.createSection(parent, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED | SWT.BORDER); Composite client = widgetFactory.createComposite(rec.control, SWT.NO_FOCUS | SWT.WRAP); rec.control.setClient(client); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.verticalAlignment = GridData.BEGINNING; data.widthHint = DEFAULT_SECTION_WIDTH; rec.control.setLayoutData(data); rec.section.createControl(client); updateSectionTitle(rec); } private void updateSectionTitle(SectionRec rec) { if (rec.control == null || rec.control.isDisposed()) return; String title = rec.section.getTitle(); if (title == null) { title = ""; //$NON-NLS-1$ } rec.control.setText(title); } public Control getControl() { return form; } public abstract String getTitle(); public void dispose() { for (SectionRec rec : sections) { rec.section.dispose(); } if (form != null) { form.dispose(); form = null; } } public void setSelection(ISelection selection) { for (SectionRec rec : sections) { rec.section.setSelection(selection); } } public IPropertyPartContainer getContainer() { return container; } public void refresh() { for (SectionRec rec : sections) { rec.section.refresh(); } if (form != null && !form.isDisposed()) { form.reflow(true); } } public void setFocus() { if (sections.isEmpty()) { form.setFocus(); } else { sections.get(0).section.setFocus(); } } }