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