/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.modeling.ui.diagram; import java.text.DecimalFormat; import java.text.ParseException; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.simantics.utils.page.PageDesc; import org.simantics.utils.page.PageOrientation; import org.simantics.modeling.ui.preferences.DiagramPreferencePage; import org.simantics.utils.page.MarginUtils.Margin; import org.simantics.utils.page.MarginUtils.Margins; /** * A composite control for configuring a {@link PageDesc} instance. * *

* A PageDesc contains information about page size, orientation and margins. * * This code is copied from {@link DiagramPreferencePage}. To remove * duplication, this code should be employed in DiagramPreferencePage. * * @author Tuukka Lehtonen (extracted here by Marko Luukkainen) */ public class PageDescComposite extends Composite { PageDesc desc = PageDesc.DEFAULT; PageDesc previousDesc; Button portrait; Button landscape; Combo combo; Text topMargin; Text leftMargin; Text rightMargin; Text bottomMargin; Canvas pageCanvas; Listener marginListener = new Listener() { @Override public void handleEvent(Event event) { if (event.type == SWT.Modify) { Text txt = (Text) event.widget; String s = txt.getText(); double value = 0; boolean invalid = false; try { value = DecimalFormat.getInstance().parse(s).doubleValue(); } catch (ParseException e) { invalid = true; } if (invalid) { txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_RED)); } else { txt.setBackground(null); int mask = txt == topMargin ? Margins.TOP : txt == leftMargin ? Margins.LEFT : txt == rightMargin ? Margins.RIGHT : txt == bottomMargin ? Margins.BOTTOM : 0; Margin m = new Margin(0, 0, value); desc = desc.withMargins(desc.getMargins().withSide(mask, m)); applyValuesToWidgets(false); } } else if (event.type == SWT.FocusIn) { Text txt = (Text) event.widget; txt.selectAll(); } } }; int[] marginEvents = { SWT.Modify, SWT.FocusIn }; private void addMarginListeners() { for (int et : marginEvents) { topMargin.addListener(et, marginListener); leftMargin.addListener(et, marginListener); rightMargin.addListener(et, marginListener); bottomMargin.addListener(et, marginListener); } } private void removeMarginListeners() { for (int et : marginEvents) { topMargin.removeListener(et, marginListener); leftMargin.removeListener(et, marginListener); rightMargin.removeListener(et, marginListener); bottomMargin.removeListener(et, marginListener); } } public PageDescComposite(Composite parent, int style) { super(parent,style); createChoosers(this); } public void setPageDesc(PageDesc desc) { if (desc == null) throw new NullPointerException("null page desc"); //$NON-NLS-1$ this.desc = desc; applyValuesToWidgets(); } public PageDesc getPageDesc() { return desc; } protected void createChoosers(Composite parent) { //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE)); GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(parent); Label label = new Label(parent, 0); label.setText(Messages.PageDescComposite_Size); combo = new Combo(parent, 0); combo.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { PageDesc pd = (PageDesc) combo.getData(combo.getItem(combo.getSelectionIndex())); if (pd != null) { desc = desc.withSizeFrom(pd).withText(pd.getText()); applyValuesToWidgets(); } } }); Composite marginComposite = new Composite(parent, 0); //marginComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED)); GridDataFactory.fillDefaults().grab(true, true).grab(true, true).align(SWT.CENTER, SWT.CENTER).span(1, 2).applyTo(marginComposite); GridLayoutFactory.fillDefaults().numColumns(3).margins(5, 5).spacing(3, 3).applyTo(marginComposite); label = new Label(marginComposite, 0); label.setText(Messages.PageDescComposite_MarginsMM); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label); label = new Label(marginComposite, 0); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label); new Label(marginComposite, 0); topMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER); GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(topMargin); new Label(marginComposite, 0); leftMargin = new Text(marginComposite, SWT.BORDER | SWT.RIGHT); GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(leftMargin); pageCanvas = new Canvas(marginComposite, 0); GridDataFactory.swtDefaults().hint(SWT.DEFAULT, SWT.DEFAULT).grab(true, true).applyTo(pageCanvas); pageCanvas.addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { GC gc = e.gc; Point size = pageCanvas.getSize(); double w = desc.getOrientedWidth(); double h = desc.getOrientedHeight(); Margins margins = desc.getMargins(); int top = (int) Math.round(size.y * margins.top.diagramAbsolute / h); int bottom = (int) Math.round(size.y * margins.bottom.diagramAbsolute / h); int left = (int) Math.round(size.x * margins.left.diagramAbsolute / w); int right = (int) Math.round(size.x * margins.right.diagramAbsolute / w); gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY)); gc.fillRectangle(0, 0, size.x, size.y); if ((top+bottom) < size.y && (left+right) < size.x) { gc.drawLine(left, 0, left, size.y-1); gc.drawLine(size.x-1-right, 0, size.x-1-right, size.y-1); gc.drawLine(0, top, size.x-1, top); gc.drawLine(0, size.y-1-bottom, size.x-1, size.y-1-bottom); gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE)); gc.fillRectangle(left+1, top+1, size.x-2-right-left, size.y-2-top-bottom); } } }); rightMargin = new Text(marginComposite, SWT.BORDER | SWT.LEFT); GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(rightMargin); new Label(marginComposite, 0); bottomMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER); GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(bottomMargin); new Label(marginComposite, 0); addMarginListeners(); label = new Label(parent, 0); label.setText(Messages.PageDescComposite_Orientation); Composite comp = new Composite(parent, 0); GridDataFactory.fillDefaults().span(1, 1).align(SWT.LEFT, SWT.CENTER).applyTo(comp); GridLayoutFactory.fillDefaults().numColumns(1).applyTo(comp); portrait = new Button(comp, SWT.RADIO); landscape = new Button(comp, SWT.RADIO); portrait.setText(Messages.PageDescComposite_Portrait); landscape.setText(Messages.PageDescComposite_Landscape); Listener orientationListener = new Listener() { @Override public void handleEvent(Event event) { if (portrait.getSelection()) desc = desc.withOrientation(PageOrientation.Portrait); else desc = desc.withOrientation(PageOrientation.Landscape); applyValuesToWidgets(); } }; portrait.addListener(SWT.Selection, orientationListener); landscape.addListener(SWT.Selection, orientationListener); PageDesc[] pds = PageDesc.getPredefinedDescriptions(); for (int i = 0; i < pds.length; ++i) { PageDesc pd = pds[i]; combo.add(pd.getText()); combo.setData(pd.getText(), pd); } applyValuesToWidgets(); } private void applyValuesToWidgets() { applyValuesToWidgets(true); } private void applyValuesToWidgets(boolean applyMargins) { switch (desc.getOrientation()) { case Portrait: portrait.setSelection(true); landscape.setSelection(false); break; case Landscape: portrait.setSelection(false); landscape.setSelection(true); break; } String name = desc.getText(); int selectedIndex = combo.getSelectionIndex(); for (int i = 0; i < combo.getItemCount(); ++i) { String item = combo.getItem(i); if (name.equals(item)) { if (selectedIndex != i) { combo.select(i); } break; } } if (applyMargins) { boolean marginEnabled = !desc.isInfinite(); topMargin.setEnabled(marginEnabled); leftMargin.setEnabled(marginEnabled); rightMargin.setEnabled(marginEnabled); bottomMargin.setEnabled(marginEnabled); if (marginEnabled) { removeMarginListeners(); Margins margins = desc.getMargins(); topMargin.setText(DecimalFormat.getNumberInstance().format(margins.top.diagramAbsolute)); leftMargin.setText(DecimalFormat.getNumberInstance().format(margins.left.diagramAbsolute)); rightMargin.setText(DecimalFormat.getNumberInstance().format(margins.right.diagramAbsolute)); bottomMargin.setText(DecimalFormat.getNumberInstance().format(margins.bottom.diagramAbsolute)); addMarginListeners(); } } layout(desc); } void layout(PageDesc desc) { double max = Math.max(desc.getOrientedWidth(), desc.getOrientedHeight()); double min = Math.min(desc.getOrientedWidth(), desc.getOrientedHeight()); double ratio = min / max; int larger = 100; int smaller = (int) Math.round(ratio*larger); boolean vertical = desc.getOrientedWidth() < desc.getOrientedHeight(); GridData gd = (GridData) pageCanvas.getLayoutData(); gd.widthHint = vertical ? smaller : larger; gd.heightHint = vertical ? larger : smaller; this.getParent().layout(true, true); pageCanvas.redraw(); } }