]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/PageDescComposite.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / diagram / PageDescComposite.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.diagram;\r
13 \r
14 import java.text.DecimalFormat;\r
15 import java.text.ParseException;\r
16 \r
17 import org.eclipse.jface.layout.GridDataFactory;\r
18 import org.eclipse.jface.layout.GridLayoutFactory;\r
19 import org.eclipse.swt.SWT;\r
20 import org.eclipse.swt.events.PaintEvent;\r
21 import org.eclipse.swt.events.PaintListener;\r
22 import org.eclipse.swt.graphics.GC;\r
23 import org.eclipse.swt.graphics.Point;\r
24 import org.eclipse.swt.layout.GridData;\r
25 import org.eclipse.swt.widgets.Button;\r
26 import org.eclipse.swt.widgets.Canvas;\r
27 import org.eclipse.swt.widgets.Combo;\r
28 import org.eclipse.swt.widgets.Composite;\r
29 import org.eclipse.swt.widgets.Event;\r
30 import org.eclipse.swt.widgets.Label;\r
31 import org.eclipse.swt.widgets.Listener;\r
32 import org.eclipse.swt.widgets.Text;\r
33 import org.simantics.utils.page.PageDesc;\r
34 import org.simantics.utils.page.PageOrientation;\r
35 import org.simantics.modeling.ui.preferences.DiagramPreferencePage;\r
36 import org.simantics.utils.page.MarginUtils.Margin;\r
37 import org.simantics.utils.page.MarginUtils.Margins;\r
38 \r
39 /**\r
40  * A composite control for configuring a {@link PageDesc} instance.\r
41  * \r
42  * <p>\r
43  * A PageDesc contains information about page size, orientation and margins.\r
44  * \r
45  * This code is copied from {@link DiagramPreferencePage}. To remove\r
46  * duplication, this code should be employed in DiagramPreferencePage.\r
47  * \r
48  * @author Tuukka Lehtonen (extracted here by Marko Luukkainen)\r
49  */\r
50 public class PageDescComposite extends Composite {\r
51 \r
52     PageDesc desc = PageDesc.DEFAULT;\r
53     PageDesc previousDesc;\r
54 \r
55     Button portrait;\r
56     Button landscape;\r
57     Combo combo;\r
58 \r
59     Text topMargin;\r
60     Text leftMargin;\r
61     Text rightMargin;\r
62     Text bottomMargin;\r
63 \r
64     Canvas pageCanvas;\r
65 \r
66     Listener marginListener = new Listener() {\r
67         @Override\r
68         public void handleEvent(Event event) {\r
69             if (event.type == SWT.Modify) {\r
70                 Text txt = (Text) event.widget;\r
71                 String s = txt.getText();\r
72                 double value = 0;\r
73                 boolean invalid = false;\r
74                 try {\r
75                     value = DecimalFormat.getInstance().parse(s).doubleValue();\r
76                 } catch (ParseException e) {\r
77                     invalid = true;\r
78                 }\r
79                 if (invalid) {\r
80                     txt.setBackground(txt.getDisplay().getSystemColor(SWT.COLOR_RED));\r
81                 } else {\r
82                     txt.setBackground(null);\r
83                     int mask = txt == topMargin ? Margins.TOP : txt == leftMargin ? Margins.LEFT\r
84                             : txt == rightMargin ? Margins.RIGHT : txt == bottomMargin ? Margins.BOTTOM : 0;\r
85                     Margin m = new Margin(0, 0, value);\r
86                     desc = desc.withMargins(desc.getMargins().withSide(mask, m));\r
87                     applyValuesToWidgets(false);\r
88                 }\r
89             } else if (event.type == SWT.FocusIn) {\r
90                 Text txt = (Text) event.widget;\r
91                 txt.selectAll();\r
92             }\r
93         }\r
94     };\r
95 \r
96     int[] marginEvents = { SWT.Modify, SWT.FocusIn };\r
97 \r
98     private void addMarginListeners() {\r
99         for (int et : marginEvents) {\r
100             topMargin.addListener(et, marginListener);\r
101             leftMargin.addListener(et, marginListener);\r
102             rightMargin.addListener(et, marginListener);\r
103             bottomMargin.addListener(et, marginListener);\r
104         }\r
105     }\r
106 \r
107     private void removeMarginListeners() {\r
108         for (int et : marginEvents) {\r
109             topMargin.removeListener(et, marginListener);\r
110             leftMargin.removeListener(et, marginListener);\r
111             rightMargin.removeListener(et, marginListener);\r
112             bottomMargin.removeListener(et, marginListener);\r
113         }\r
114     }\r
115 \r
116     public PageDescComposite(Composite parent, int style) {\r
117         super(parent,style);\r
118         createChoosers(this);\r
119     }\r
120 \r
121     public void setPageDesc(PageDesc desc) {\r
122         if (desc == null)\r
123             throw new NullPointerException("null page desc");\r
124         this.desc = desc;\r
125         applyValuesToWidgets();\r
126     }\r
127 \r
128     public PageDesc getPageDesc() {\r
129         return desc;\r
130     }\r
131 \r
132     protected void createChoosers(Composite parent) {\r
133         //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));\r
134         GridLayoutFactory.fillDefaults().numColumns(3).equalWidth(false).extendedMargins(12, 12, 12, 12).spacing(5, 4).applyTo(parent);\r
135         Label label = new Label(parent, 0);\r
136         label.setText("Size:");\r
137         combo = new Combo(parent, 0);\r
138         combo.addListener(SWT.Selection, new Listener() {\r
139             @Override\r
140             public void handleEvent(Event event) {\r
141                 PageDesc pd = (PageDesc) combo.getData(combo.getItem(combo.getSelectionIndex()));\r
142                 if (pd != null) {\r
143                     desc = desc.withSizeFrom(pd).withText(pd.getText());\r
144                     applyValuesToWidgets();\r
145                 }\r
146             }\r
147         });\r
148 \r
149         Composite marginComposite = new Composite(parent, 0);\r
150         //marginComposite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));\r
151         GridDataFactory.fillDefaults().grab(true, true).grab(true, true).align(SWT.CENTER, SWT.CENTER).span(1, 2).applyTo(marginComposite);\r
152         GridLayoutFactory.fillDefaults().numColumns(3).margins(5, 5).spacing(3, 3).applyTo(marginComposite);\r
153         label = new Label(marginComposite, 0);\r
154         label.setText("Margins (mm)");\r
155 \r
156         GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);\r
157         label = new Label(marginComposite, 0);\r
158         GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.TOP).span(3, 1).applyTo(label);\r
159         new Label(marginComposite, 0);\r
160         topMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);\r
161         GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(topMargin);\r
162         new Label(marginComposite, 0);\r
163         leftMargin = new Text(marginComposite, SWT.BORDER | SWT.RIGHT);\r
164         GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(leftMargin);\r
165         pageCanvas = new Canvas(marginComposite, 0);\r
166         GridDataFactory.swtDefaults().hint(SWT.DEFAULT, SWT.DEFAULT).grab(true, true).applyTo(pageCanvas);\r
167         pageCanvas.addPaintListener(new PaintListener() {\r
168             @Override\r
169             public void paintControl(PaintEvent e) {\r
170                 GC gc = e.gc;\r
171                 Point size = pageCanvas.getSize();\r
172 \r
173                 double w = desc.getOrientedWidth();\r
174                 double h = desc.getOrientedHeight();\r
175 \r
176                 Margins margins = desc.getMargins();\r
177                 int top = (int) Math.round(size.y * margins.top.diagramAbsolute / h);\r
178                 int bottom = (int) Math.round(size.y * margins.bottom.diagramAbsolute / h);\r
179                 int left = (int) Math.round(size.x * margins.left.diagramAbsolute / w);\r
180                 int right = (int) Math.round(size.x * margins.right.diagramAbsolute / w);\r
181 \r
182                 gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));\r
183                 gc.fillRectangle(0, 0, size.x, size.y);\r
184 \r
185                 if ((top+bottom) < size.y && (left+right) < size.x) {\r
186                     gc.drawLine(left, 0, left, size.y-1);\r
187                     gc.drawLine(size.x-1-right, 0, size.x-1-right, size.y-1);\r
188                     gc.drawLine(0, top, size.x-1, top);\r
189                     gc.drawLine(0, size.y-1-bottom, size.x-1, size.y-1-bottom);\r
190 \r
191                     gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));\r
192                     gc.fillRectangle(left+1, top+1, size.x-2-right-left, size.y-2-top-bottom);\r
193                 }\r
194             }\r
195         });\r
196         rightMargin = new Text(marginComposite, SWT.BORDER | SWT.LEFT);\r
197         GridDataFactory.swtDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(rightMargin);\r
198         new Label(marginComposite, 0);\r
199         bottomMargin = new Text(marginComposite, SWT.BORDER | SWT.CENTER);\r
200         GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).grab(true, false).applyTo(bottomMargin);\r
201         new Label(marginComposite, 0);\r
202 \r
203         addMarginListeners();\r
204 \r
205         label = new Label(parent, 0);\r
206         label.setText("Orientation:");\r
207         Composite comp = new Composite(parent, 0);\r
208         GridDataFactory.fillDefaults().span(1, 1).align(SWT.LEFT, SWT.CENTER).applyTo(comp);\r
209         GridLayoutFactory.fillDefaults().numColumns(1).applyTo(comp);\r
210         portrait = new Button(comp, SWT.RADIO);\r
211         landscape = new Button(comp, SWT.RADIO);\r
212         portrait.setText("Portrait");\r
213         landscape.setText("Landscape");\r
214 \r
215         Listener orientationListener = new Listener() {\r
216             @Override\r
217             public void handleEvent(Event event) {\r
218                 if (portrait.getSelection())\r
219                     desc = desc.withOrientation(PageOrientation.Portrait);\r
220                 else\r
221                     desc = desc.withOrientation(PageOrientation.Landscape);\r
222 \r
223                 applyValuesToWidgets();\r
224             }\r
225         };\r
226         portrait.addListener(SWT.Selection, orientationListener);\r
227         landscape.addListener(SWT.Selection, orientationListener);\r
228 \r
229         PageDesc[] pds = PageDesc.getPredefinedDescriptions();\r
230         for (int i = 0; i < pds.length; ++i) {\r
231             PageDesc pd = pds[i];\r
232             combo.add(pd.getText());\r
233             combo.setData(pd.getText(), pd);\r
234         }\r
235 \r
236         applyValuesToWidgets();\r
237     }\r
238 \r
239 \r
240 \r
241     private void applyValuesToWidgets() {\r
242         applyValuesToWidgets(true);\r
243     }\r
244 \r
245     private void applyValuesToWidgets(boolean applyMargins) {\r
246         switch (desc.getOrientation()) {\r
247             case Portrait:\r
248                 portrait.setSelection(true);\r
249                 landscape.setSelection(false);\r
250                 break;\r
251             case Landscape:\r
252                 portrait.setSelection(false);\r
253                 landscape.setSelection(true);\r
254                 break;\r
255         }\r
256         String name = desc.getText();\r
257         int selectedIndex = combo.getSelectionIndex();\r
258         for (int i = 0; i < combo.getItemCount(); ++i) {\r
259             String item = combo.getItem(i);\r
260             if (name.equals(item)) {\r
261                 if (selectedIndex != i) {\r
262                     combo.select(i);\r
263                 }\r
264                 break;\r
265             }\r
266         }\r
267 \r
268         if (applyMargins) {\r
269             boolean marginEnabled = !desc.isInfinite();\r
270             topMargin.setEnabled(marginEnabled);\r
271             leftMargin.setEnabled(marginEnabled);\r
272             rightMargin.setEnabled(marginEnabled);\r
273             bottomMargin.setEnabled(marginEnabled);\r
274 \r
275             if (marginEnabled) {\r
276                 removeMarginListeners();\r
277                 Margins margins = desc.getMargins();\r
278                 topMargin.setText(DecimalFormat.getNumberInstance().format(margins.top.diagramAbsolute));\r
279                 leftMargin.setText(DecimalFormat.getNumberInstance().format(margins.left.diagramAbsolute));\r
280                 rightMargin.setText(DecimalFormat.getNumberInstance().format(margins.right.diagramAbsolute));\r
281                 bottomMargin.setText(DecimalFormat.getNumberInstance().format(margins.bottom.diagramAbsolute));\r
282                 addMarginListeners();\r
283             }\r
284         }\r
285 \r
286         layout(desc);\r
287     }\r
288 \r
289     void layout(PageDesc desc) {\r
290         double max = Math.max(desc.getOrientedWidth(), desc.getOrientedHeight());\r
291         double min = Math.min(desc.getOrientedWidth(), desc.getOrientedHeight());\r
292         double ratio = min / max;\r
293         int larger = 100;\r
294         int smaller = (int) Math.round(ratio*larger);\r
295 \r
296         boolean vertical = desc.getOrientedWidth() < desc.getOrientedHeight();\r
297 \r
298         GridData gd = (GridData) pageCanvas.getLayoutData();\r
299         gd.widthHint = vertical ? smaller : larger;\r
300         gd.heightHint = vertical ? larger : smaller;\r
301 \r
302         this.getParent().layout(true, true);\r
303         pageCanvas.redraw();\r
304     }\r
305 }\r