]> git.argeo.org Git - gpl/argeo-suite.git/blob - swt/org.argeo.app.swt/src/org/argeo/app/swt/ux/SuiteSwtUtils.java
Update Argeo Build
[gpl/argeo-suite.git] / swt / org.argeo.app.swt / src / org / argeo / app / swt / ux / SuiteSwtUtils.java
1 package org.argeo.app.swt.ux;
2
3 import java.util.function.Predicate;
4
5 import javax.xml.namespace.QName;
6
7 import org.argeo.api.acr.Content;
8 import org.argeo.api.acr.QNamed;
9 import org.argeo.api.cms.ux.Cms2DSize;
10 import org.argeo.api.cms.ux.CmsEditable;
11 import org.argeo.api.cms.ux.CmsStyle;
12 import org.argeo.app.ux.SuiteStyle;
13 import org.argeo.cms.Localized;
14 import org.argeo.cms.acr.ContentUtils;
15 import org.argeo.cms.swt.CmsSwtUtils;
16 import org.argeo.cms.swt.acr.Img;
17 import org.argeo.cms.swt.dialogs.CmsFeedback;
18 import org.argeo.cms.swt.dialogs.LightweightDialog;
19 import org.argeo.cms.swt.widgets.CmsLink;
20 import org.argeo.cms.swt.widgets.EditableText;
21 import org.argeo.eclipse.ui.EclipseUiUtils;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.custom.ScrolledComposite;
24 import org.eclipse.swt.events.FocusEvent;
25 import org.eclipse.swt.events.FocusListener;
26 import org.eclipse.swt.events.MouseAdapter;
27 import org.eclipse.swt.events.MouseEvent;
28 import org.eclipse.swt.events.MouseListener;
29 import org.eclipse.swt.events.SelectionEvent;
30 import org.eclipse.swt.events.SelectionListener;
31 import org.eclipse.swt.graphics.Point;
32 import org.eclipse.swt.layout.GridData;
33 import org.eclipse.swt.layout.GridLayout;
34 import org.eclipse.swt.widgets.Composite;
35 import org.eclipse.swt.widgets.Control;
36 import org.eclipse.swt.widgets.Label;
37 import org.eclipse.swt.widgets.Text;
38
39 /** Static utilities implementing the look and feel of Argeo Suite with SWT. */
40 public class SuiteSwtUtils {
41 /** creates a title bar composite with label and optional button */
42 public static Composite addTitleBar(Composite parent, Localized title) {
43 return addTitleBar(parent, title.lead());
44 }
45
46 /** creates a title bar composite with label and optional button */
47 public static Composite addTitleBar(Composite parent, String title) {
48 Composite titleBar = new Composite(parent, SWT.NONE);
49 titleBar.setLayoutData(CmsSwtUtils.fillWidth());
50 CmsSwtUtils.style(titleBar, SuiteStyle.titleContainer);
51
52 titleBar.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(2, false)));
53 Label titleLbl = new Label(titleBar, SWT.NONE);
54 titleLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
55 CmsSwtUtils.style(titleLbl, SuiteStyle.titleLabel);
56 titleLbl.setText(title);
57
58 // if (isEditable) {
59 // Button editBtn = new Button(titleBar, SWT.PUSH);
60 // editBtn.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
61 // CmsSwtUtils.style(editBtn, SuiteStyle.inlineButton);
62 // editBtn.setText("Edit");
63 // }
64 return titleBar;
65 }
66
67 public static Label addFormLabel(Composite parent, String label) {
68 Label lbl = new Label(parent, SWT.WRAP);
69 lbl.setText(label);
70 lbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
71 CmsSwtUtils.style(lbl, SuiteStyle.simpleLabel);
72 return lbl;
73 }
74
75 public static Label addFormLabel(Composite parent, Localized msg) {
76 return addFormLabel(parent, msg.lead());
77 }
78
79 public static Text addFormTextField(Composite parent, String text, String message, int style) {
80 Text txt = new Text(parent, style);
81 if (text != null)
82 txt.setText(text);
83 if (message != null)
84 txt.setMessage(message);
85 txt.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));
86 CmsSwtUtils.style(txt, SuiteStyle.simpleInput);
87 return txt;
88 }
89
90 public static Text addFormTextField(Composite parent, String text, String message) {
91 return addFormTextField(parent, text, message, SWT.NONE);
92 }
93
94 // public static Text addFormInputField(Composite parent, String placeholder) {
95 // Text txt = new Text(parent, SWT.BORDER);
96 //
97 // GridData gridData = CmsSwtUtils.fillWidth();
98 // txt.setLayoutData(gridData);
99 //
100 // if (placeholder != null)
101 // txt.setText(placeholder);
102 //
103 // CmsSwtUtils.style(txt, SuiteStyle.simpleInput);
104 // return txt;
105 // }
106
107 public static Composite addLineComposite(Composite parent, int columns) {
108 Composite lineComposite = new Composite(parent, SWT.NONE);
109 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
110 lineComposite.setLayoutData(gd);
111 lineComposite.setLayout(new GridLayout(columns, false));
112 CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
113 return lineComposite;
114 }
115
116 /** creates a single horizontal-block composite for key:value display */
117 public static Text addFormLine(Composite parent, Localized label, String text) {
118 return addFormLine(parent, label.lead(), text);
119 }
120
121 /** creates a single horizontal-block composite for key:value display */
122 public static Text addFormLine(Composite parent, String label, String text) {
123 Composite lineComposite = addLineComposite(parent, 2);
124 CmsSwtUtils.style(lineComposite, SuiteStyle.formLine);
125 addFormLabel(lineComposite, label);
126 Text txt = addFormTextField(lineComposite, text, null);
127 txt.setEditable(false);
128 txt.setLayoutData(CmsSwtUtils.fillWidth());
129 return txt;
130 }
131
132 // public static Text addFormInput(Composite parent, String label, String placeholder) {
133 // Composite lineComposite = addLineComposite(parent, 2);
134 // addFormLabel(lineComposite, label);
135 // Text txt = addFormInputField(lineComposite, placeholder);
136 // txt.setLayoutData(CmsSwtUtils.fillWidth());
137 // return txt;
138 // }
139
140 /**
141 * creates a single horizontal-block composite for key:value display, with
142 * offset value
143 */
144 public static Text addFormLine(Composite parent, String label, String text, Integer offset) {
145 Composite lineComposite = addLineComposite(parent, 3);
146 Label offsetLbl = new Label(lineComposite, SWT.NONE);
147 GridData gridData = new GridData();
148 gridData.widthHint = offset;
149 offsetLbl.setLayoutData(gridData);
150 addFormLabel(lineComposite, label);
151 Text txt = addFormTextField(lineComposite, text, null);
152 txt.setLayoutData(CmsSwtUtils.fillWidth());
153 return txt;
154 }
155
156 /** creates a single vertical-block composite for key:value display */
157 public static Text addFormColumn(Composite parent, Localized label, String text) {
158 return addFormColumn(parent, label.lead(), text);
159 }
160
161 /** creates a single vertical-block composite for key:value display */
162 public static Text addFormColumn(Composite parent, String label, String text) {
163 // Composite columnComposite = new Composite(parent, SWT.NONE);
164 // columnComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
165 // false));
166 // columnComposite.setLayout(new GridLayout(1, false));
167 addFormLabel(parent, label);
168 Text txt = addFormTextField(parent, text, null);
169 txt.setEditable(false);
170 txt.setLayoutData(CmsSwtUtils.fillWidth());
171 return txt;
172 }
173
174 public static Label createBoldLabel(Composite parent, Localized localized) {
175 Label label = new Label(parent, SWT.LEAD);
176 label.setText(localized.lead());
177 label.setFont(EclipseUiUtils.getBoldFont(parent));
178 label.setLayoutData(new GridData(SWT.LEAD, SWT.CENTER, false, false));
179 return label;
180 }
181
182 /*
183 * CONTENT
184 */
185 public static String toLink(Content content) {
186 return content != null ? "#" + ContentUtils.cleanPathForUrl(content.getPath()) : null;
187 }
188
189 public static Text addFormLine(Composite parent, Localized label, Content content, QNamed property,
190 CmsEditable cmsEditable) {
191 return addFormLine(parent, label.lead(), content, property.qName(), cmsEditable);
192 }
193
194 public static EditableText addTextLine(Composite parent, int style, Localized msg, Content content, QNamed attr,
195 CmsEditable cmsEditable, boolean line, Predicate<String> validator) {
196 Composite parentToUse = line ? SuiteSwtUtils.addLineComposite(parent, 2) : parent;
197 SuiteSwtUtils.addFormLabel(parentToUse, msg.lead());
198 EditableText text = createFormText(parentToUse, style, msg, content, attr, cmsEditable, validator);
199 return text;
200 }
201
202 public static EditableText createFormText(Composite parent, int style, Localized msg, Content content, QNamed attr,
203 CmsEditable cmsEditable, Predicate<String> validator) {
204 EditableText text = new EditableText(parent, style | SWT.FLAT | (cmsEditable.isEditing() ? 0 : SWT.READ_ONLY));
205 text.setMessage("-");
206 text.setLayoutData(CmsSwtUtils.fillWidth());
207 text.setStyle(SuiteStyle.simpleInput);
208 String txt = content.attr(attr);
209 if (txt == null)
210 txt = "";
211 text.setText(txt);
212 if (cmsEditable.isEditing())
213 text.setMouseListener(new MouseAdapter() {
214
215 private static final long serialVersionUID = 1L;
216
217 @Override
218 public void mouseDoubleClick(MouseEvent e) {
219 String currentTxt = text.getText();
220 text.startEditing();
221 text.setText(currentTxt);
222
223 Runnable save = () -> {
224 String editedTxt = text.getText();
225 if (validator != null) {
226 if (!validator.test(editedTxt)) {
227 text.stopEditing();
228 text.setText(currentTxt);
229 CmsFeedback.show(editedTxt + " is not properly formatted");
230 return;
231 // throw new IllegalArgumentException(editedTxt + " is not properly formatted");
232 }
233 }
234 content.put(attr, editedTxt);
235 text.stopEditing();
236 text.setText(editedTxt);
237 text.getParent().layout(new Control[] { text.getControl() });
238 };
239 ((Text) text.getControl()).addSelectionListener(new SelectionListener() {
240
241 private static final long serialVersionUID = 1L;
242
243 @Override
244 public void widgetSelected(SelectionEvent e) {
245 }
246
247 @Override
248 public void widgetDefaultSelected(SelectionEvent e) {
249 save.run();
250 }
251 });
252 ((Text) text.getControl()).addFocusListener(new FocusListener() {
253
254 private static final long serialVersionUID = 333838002411959302L;
255
256 @Override
257 public void focusLost(FocusEvent event) {
258 save.run();
259 }
260
261 @Override
262 public void focusGained(FocusEvent event) {
263 }
264 });
265
266 }
267
268 });
269 return text;
270 }
271
272 public static Text addFormLine(Composite parent, String label, Content content, QName property,
273 CmsEditable cmsEditable) {
274 Composite lineComposite = SuiteSwtUtils.addLineComposite(parent, 2);
275 SuiteSwtUtils.addFormLabel(lineComposite, label);
276 String text = content.attr(property);
277 Text txt = SuiteSwtUtils.addFormTextField(lineComposite, text, null, SWT.WRAP);
278 if (cmsEditable != null && cmsEditable.isEditing()) {
279 txt.addModifyListener((e) -> {
280 content.put(property, txt.getText());
281 });
282 } else {
283 txt.setEditable(false);
284 }
285 txt.setLayoutData(CmsSwtUtils.fillWidth());
286 return txt;
287 }
288
289 public static Text addFormColumn(Composite parent, Localized label, Content content, QNamed property,
290 CmsEditable cmsEditable) {
291 return addFormColumn(parent, label.lead(), content, property.qName(), cmsEditable);
292 }
293
294 public static Text addFormColumn(Composite parent, String label, Content content, QName property,
295 CmsEditable cmsEditable) {
296 SuiteSwtUtils.addFormLabel(parent, label);
297 String text = content.attr(property);
298 Text txt = SuiteSwtUtils.addFormTextField(parent, text, null, 0);
299 if (cmsEditable != null && cmsEditable.isEditing()) {
300 txt.addModifyListener((e) -> {
301 content.put(property, txt.getText());
302 });
303 } else {
304 txt.setEditable(false);
305 }
306 txt.setLayoutData(CmsSwtUtils.fillWidth());
307 return txt;
308 }
309
310 /*
311 * LINKS
312 */
313
314 /** Add a link to an internal content. */
315 public static Control addLink(Composite parent, String label, Content node, CmsStyle style) {
316 String target = toLink(node);
317 CmsLink link = new CmsLink(label, target, style);
318 return link.createUi(parent);
319 }
320
321 public static Control addExternalLink(Composite parent, String label, String url, String plainCssAnchorClass,
322 boolean newWindow) {
323 Label lbl = new Label(parent, SWT.NONE);
324 CmsSwtUtils.markup(lbl);
325 StringBuilder txt = new StringBuilder();
326 txt.append("<a");
327 if (plainCssAnchorClass != null)
328 txt.append(" class='" + plainCssAnchorClass + "'");
329 txt.append(" href='").append(url).append("'");
330 if (newWindow) {
331 txt.append(" target='blank_'");
332 }
333 txt.append(">");
334 txt.append(label);
335 txt.append("</a>");
336 lbl.setText(txt.toString());
337 return lbl;
338 }
339
340 /*
341 * IMAGES
342 */
343
344 public static Img addPicture(Composite parent, Content file) {
345 return addPicture(parent, file, null);
346 }
347
348 public static Img addPicture(Composite parent, Content file, Integer maxWidth) {
349 return addPicture(parent, file, maxWidth, null);
350 }
351
352 public static Img addPicture(Composite parent, Content file, Integer maxWidth, Content link) {
353 // TODO optimise
354 // Integer width;
355 // Integer height;
356 // if (file.hasContentClass(EntityType.box)) {
357 // width = file.get(SvgAttrs.width, Integer.class).get();
358 // height = file.get(SvgAttrs.height, Integer.class).get();
359 // } else {
360 // try (InputStream in = file.open(InputStream.class)) {
361 // ImageData imageData = new ImageData(in);
362 // width = imageData.width;
363 // height = imageData.height;
364 // } catch (IOException e) {
365 // throw new RuntimeException(e);
366 // }
367 // }
368 //
369 // if (maxWidth != null && width > maxWidth) {
370 // Double ratio = maxWidth.doubleValue() / width.doubleValue();
371 // width = maxWidth;
372 // height = (int) Math.rint(ratio * height);
373 // }
374 // Label img = new Label(parent, SWT.NONE);
375 // CmsSwtUtils.markup(img);
376 // StringBuffer txt = new StringBuffer();
377 // String target = toLink(link);
378 // if (target != null)
379 // txt.append("<a href='").append(target).append("'>");
380 // txt.append(CmsUiUtils.img(fileNode, width.toString(), height.toString()));
381 // if (target != null)
382 // txt.append("</a>");
383 // img.setText(txt.toString());
384 // if (parent.getLayout() instanceof GridLayout) {
385 // GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false);
386 // gd.widthHint = width.intValue();
387 // gd.heightHint = height.intValue();
388 // img.setLayoutData(gd);
389 // }
390
391 Img img = new Img(parent, 0, file, new Cms2DSize(maxWidth != null ? maxWidth : 0, 0));
392 if (link != null)
393 img.setLink(link);
394
395 // String target = toLink(link);
396 if (link == null)
397 img.addMouseListener(new MouseListener() {
398 private static final long serialVersionUID = -1362242049325206168L;
399
400 @Override
401 public void mouseUp(MouseEvent e) {
402 }
403
404 @Override
405 public void mouseDown(MouseEvent e) {
406 }
407
408 @Override
409 public void mouseDoubleClick(MouseEvent e) {
410 LightweightDialog dialog = new LightweightDialog(img.getShell()) {
411
412 @Override
413 protected Control createDialogArea(Composite parent) {
414 parent.setLayout(new GridLayout());
415 ScrolledComposite scroll = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
416 scroll.setLayoutData(CmsSwtUtils.fillAll());
417 scroll.setLayout(CmsSwtUtils.noSpaceGridLayout());
418 scroll.setExpandHorizontal(true);
419 scroll.setExpandVertical(true);
420 // scroll.setAlwaysShowScrollBars(true);
421
422 Composite c = new Composite(scroll, SWT.NONE);
423 scroll.setContent(c);
424 c.setLayout(new GridLayout());
425 c.setLayoutData(CmsSwtUtils.fillAll());
426 Img bigImg = new Img(c, 0, file);
427 // Label bigImg = new Label(c, SWT.NONE);
428 // CmsSwtUtils.markup(bigImg);
429 // bigImg.setText(CmsUiUtils.img(fileNode, Jcr.get(content, EntityNames.SVG_WIDTH),
430 // Jcr.get(content, EntityNames.SVG_HEIGHT)));
431 bigImg.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
432 return bigImg;
433 }
434
435 @Override
436 protected Point getInitialSize() {
437 Point shellSize = img.getShell().getSize();
438 return new Point(shellSize.x - 100, shellSize.y - 100);
439 }
440
441 };
442 dialog.open();
443 }
444 });
445 img.initControl();
446 return img;
447 }
448
449 /** singleton */
450 private SuiteSwtUtils() {
451 }
452
453 }