1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.modeling.ui.diagram;
14 import java.text.DecimalFormat;
15 import java.text.ParseException;
17 import org.eclipse.jface.layout.GridDataFactory;
18 import org.eclipse.jface.layout.GridLayoutFactory;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.PaintEvent;
21 import org.eclipse.swt.events.PaintListener;
22 import org.eclipse.swt.graphics.GC;
23 import org.eclipse.swt.graphics.Point;
24 import org.eclipse.swt.layout.GridData;
25 import org.eclipse.swt.widgets.Button;
26 import org.eclipse.swt.widgets.Canvas;
27 import org.eclipse.swt.widgets.Combo;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Event;
30 import org.eclipse.swt.widgets.Label;
31 import org.eclipse.swt.widgets.Listener;
32 import org.eclipse.swt.widgets.Text;
33 import org.simantics.utils.page.PageDesc;
34 import org.simantics.utils.page.PageOrientation;
35 import org.simantics.modeling.ui.preferences.DiagramPreferencePage;
36 import org.simantics.utils.page.MarginUtils.Margin;
37 import org.simantics.utils.page.MarginUtils.Margins;
40 * A composite control for configuring a {@link PageDesc} instance.
43 * A PageDesc contains information about page size, orientation and margins.
45 * This code is copied from {@link DiagramPreferencePage}. To remove
46 * duplication, this code should be employed in DiagramPreferencePage.
48 * @author Tuukka Lehtonen (extracted here by Marko Luukkainen)
50 public class PageDescComposite extends Composite {
52 PageDesc desc = PageDesc.DEFAULT;
53 PageDesc previousDesc;
66 Listener marginListener = new Listener() {
68 public void handleEvent(Event event) {
69 if (event.type == SWT.Modify) {
70 Text txt = (Text) event.widget;
71 String s = txt.getText();
73 boolean invalid = false;
75 value = DecimalFormat.getInstance().parse(s).doubleValue();
76 } catch (ParseException e) {
80 txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_RED));
82 txt.setBackground(null);
83 int mask = txt == topMargin ? Margins.TOP : txt == leftMargin ? Margins.LEFT
84 : txt == rightMargin ? Margins.RIGHT : txt == bottomMargin ? Margins.BOTTOM : 0;
85 Margin m = new Margin(0, 0, value);
86 desc = desc.withMargins(desc.getMargins().withSide(mask, m));
87 applyValuesToWidgets(false);
89 } else if (event.type == SWT.FocusIn) {
90 Text txt = (Text) event.widget;
96 int[] marginEvents = { SWT.Modify, SWT.FocusIn };
98 private void addMarginListeners() {
99 for (int et : marginEvents) {
100 topMargin.addListener(et, marginListener);
101 leftMargin.addListener(et, marginListener);
102 rightMargin.addListener(et, marginListener);
103 bottomMargin.addListener(et, marginListener);
107 private void removeMarginListeners() {
108 for (int et : marginEvents) {
109 topMargin.removeListener(et, marginListener);
110 leftMargin.removeListener(et, marginListener);
111 rightMargin.removeListener(et, marginListener);
112 bottomMargin.removeListener(et, marginListener);
116 public PageDescComposite(Composite parent, int style) {
118 createChoosers(this);
121 public void setPageDesc(PageDesc desc) {
123 throw new NullPointerException("null page desc"); //$NON-NLS-1$
125 applyValuesToWidgets();
128 public PageDesc getPageDesc() {
132 protected void createChoosers(Composite parent) {
133 //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));
134 GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(parent);
135 Label label = new Label(parent, 0);
136 label.setText(Messages.PageDescComposite_Size);
137 combo = new Combo(parent, 0);
138 combo.addListener(SWT.Selection, new Listener() {
140 public void handleEvent(Event event) {
141 PageDesc pd = (PageDesc) combo.getData(combo.getItem(combo.getSelectionIndex()));
143 desc = desc.withSizeFrom(pd).withText(pd.getText());
144 applyValuesToWidgets();
149 Composite marginComposite = new Composite(parent, 0);
150 //marginComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
151 GridDataFactory.fillDefaults().grab(true, true).grab(true, true).align(SWT.CENTER, SWT.CENTER).span(1, 2).applyTo(marginComposite);
152 GridLayoutFactory.fillDefaults().numColumns(3).margins(5, 5).spacing(3, 3).applyTo(marginComposite);
153 label = new Label(marginComposite, 0);
154 label.setText(Messages.PageDescComposite_MarginsMM);
156 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);
157 label = new Label(marginComposite, 0);
158 GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);
159 new Label(marginComposite, 0);
160 topMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);
161 GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(topMargin);
162 new Label(marginComposite, 0);
163 leftMargin = new Text(marginComposite, SWT.BORDER | SWT.RIGHT);
164 GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(leftMargin);
165 pageCanvas = new Canvas(marginComposite, 0);
166 GridDataFactory.swtDefaults().hint(SWT.DEFAULT, SWT.DEFAULT).grab(true, true).applyTo(pageCanvas);
167 pageCanvas.addPaintListener(new PaintListener() {
169 public void paintControl(PaintEvent e) {
171 Point size = pageCanvas.getSize();
173 double w = desc.getOrientedWidth();
174 double h = desc.getOrientedHeight();
176 Margins margins = desc.getMargins();
177 int top = (int) Math.round(size.y * margins.top.diagramAbsolute / h);
178 int bottom = (int) Math.round(size.y * margins.bottom.diagramAbsolute / h);
179 int left = (int) Math.round(size.x * margins.left.diagramAbsolute / w);
180 int right = (int) Math.round(size.x * margins.right.diagramAbsolute / w);
182 gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));
183 gc.fillRectangle(0, 0, size.x, size.y);
185 if ((top+bottom) < size.y && (left+right) < size.x) {
186 gc.drawLine(left, 0, left, size.y-1);
187 gc.drawLine(size.x-1-right, 0, size.x-1-right, size.y-1);
188 gc.drawLine(0, top, size.x-1, top);
189 gc.drawLine(0, size.y-1-bottom, size.x-1, size.y-1-bottom);
191 gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
192 gc.fillRectangle(left+1, top+1, size.x-2-right-left, size.y-2-top-bottom);
196 rightMargin = new Text(marginComposite, SWT.BORDER | SWT.LEFT);
197 GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(rightMargin);
198 new Label(marginComposite, 0);
199 bottomMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);
200 GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(bottomMargin);
201 new Label(marginComposite, 0);
203 addMarginListeners();
205 label = new Label(parent, 0);
206 label.setText(Messages.PageDescComposite_Orientation);
207 Composite comp = new Composite(parent, 0);
208 GridDataFactory.fillDefaults().span(1, 1).align(SWT.LEFT, SWT.CENTER).applyTo(comp);
209 GridLayoutFactory.fillDefaults().numColumns(1).applyTo(comp);
210 portrait = new Button(comp, SWT.RADIO);
211 landscape = new Button(comp, SWT.RADIO);
212 portrait.setText(Messages.PageDescComposite_Portrait);
213 landscape.setText(Messages.PageDescComposite_Landscape);
215 Listener orientationListener = new Listener() {
217 public void handleEvent(Event event) {
218 if (portrait.getSelection())
219 desc = desc.withOrientation(PageOrientation.Portrait);
221 desc = desc.withOrientation(PageOrientation.Landscape);
223 applyValuesToWidgets();
226 portrait.addListener(SWT.Selection, orientationListener);
227 landscape.addListener(SWT.Selection, orientationListener);
229 PageDesc[] pds = PageDesc.getPredefinedDescriptions();
230 for (int i = 0; i < pds.length; ++i) {
231 PageDesc pd = pds[i];
232 combo.add(pd.getText());
233 combo.setData(pd.getText(), pd);
236 applyValuesToWidgets();
241 private void applyValuesToWidgets() {
242 applyValuesToWidgets(true);
245 private void applyValuesToWidgets(boolean applyMargins) {
246 switch (desc.getOrientation()) {
248 portrait.setSelection(true);
249 landscape.setSelection(false);
252 portrait.setSelection(false);
253 landscape.setSelection(true);
256 String name = desc.getText();
257 int selectedIndex = combo.getSelectionIndex();
258 for (int i = 0; i < combo.getItemCount(); ++i) {
259 String item = combo.getItem(i);
260 if (name.equals(item)) {
261 if (selectedIndex != i) {
269 boolean marginEnabled = !desc.isInfinite();
270 topMargin.setEnabled(marginEnabled);
271 leftMargin.setEnabled(marginEnabled);
272 rightMargin.setEnabled(marginEnabled);
273 bottomMargin.setEnabled(marginEnabled);
276 removeMarginListeners();
277 Margins margins = desc.getMargins();
278 topMargin.setText(DecimalFormat.getNumberInstance().format(margins.top.diagramAbsolute));
279 leftMargin.setText(DecimalFormat.getNumberInstance().format(margins.left.diagramAbsolute));
280 rightMargin.setText(DecimalFormat.getNumberInstance().format(margins.right.diagramAbsolute));
281 bottomMargin.setText(DecimalFormat.getNumberInstance().format(margins.bottom.diagramAbsolute));
282 addMarginListeners();
289 void layout(PageDesc desc) {
290 double max = Math.max(desc.getOrientedWidth(), desc.getOrientedHeight());
291 double min = Math.min(desc.getOrientedWidth(), desc.getOrientedHeight());
292 double ratio = min / max;
294 int smaller = (int) Math.round(ratio*larger);
296 boolean vertical = desc.getOrientedWidth() < desc.getOrientedHeight();
298 GridData gd = (GridData) pageCanvas.getLayoutData();
299 gd.widthHint = vertical ? smaller : larger;
300 gd.heightHint = vertical ? larger : smaller;
302 this.getParent().layout(true, true);