1 package org
.argeo
.app
.swt
.ux
;
3 import java
.util
.function
.Predicate
;
5 import javax
.xml
.namespace
.QName
;
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
;
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());
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
);
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
);
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");
66 public static Label
addFormLabel(Composite parent
, String label
) {
67 Label lbl
= new Label(parent
, SWT
.WRAP
);
69 lbl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
70 CmsSwtUtils
.style(lbl
, SuiteStyle
.simpleLabel
);
74 public static Label
addFormLabel(Composite parent
, Localized msg
) {
75 return addFormLabel(parent
, msg
.lead());
78 public static Text
addFormTextField(Composite parent
, String text
, String message
, int style
) {
79 Text txt
= new Text(parent
, style
);
83 txt
.setMessage(message
);
84 txt
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, true));
85 CmsSwtUtils
.style(txt
, SuiteStyle
.simpleInput
);
89 public static Text
addFormTextField(Composite parent
, String text
, String message
) {
90 return addFormTextField(parent
, text
, message
, SWT
.NONE
);
93 // public static Text addFormInputField(Composite parent, String placeholder) {
94 // Text txt = new Text(parent, SWT.BORDER);
96 // GridData gridData = CmsSwtUtils.fillWidth();
97 // txt.setLayoutData(gridData);
99 // if (placeholder != null)
100 // txt.setText(placeholder);
102 // CmsSwtUtils.style(txt, SuiteStyle.simpleInput);
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
;
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
);
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());
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());
140 * creates a single horizontal-block composite for key:value display, with
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());
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
);
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,
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());
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));
184 public static String
toLink(Content content
) {
185 return content
!= null ?
"#" + CmsSwtUtils
.cleanPathForUrl(content
.getPath()) : null;
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
);
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
);
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
);
211 if (cmsEditable
.isEditing())
212 text
.setMouseListener(new MouseAdapter() {
214 private static final long serialVersionUID
= 1L;
217 public void mouseDoubleClick(MouseEvent e
) {
218 String currentTxt
= text
.getText();
220 text
.setText(currentTxt
);
222 Runnable save
= () -> {
223 String editedTxt
= text
.getText();
224 if (validator
!= null) {
225 if (!validator
.test(editedTxt
)) {
227 text
.setText(currentTxt
);
228 CmsFeedback
.show(editedTxt
+ " is not properly formatted");
230 // throw new IllegalArgumentException(editedTxt + " is not properly formatted");
233 content
.put(attr
, editedTxt
);
235 text
.setText(editedTxt
);
236 text
.getParent().layout(new Control
[] { text
.getControl() });
238 ((Text
) text
.getControl()).addSelectionListener(new SelectionListener() {
240 private static final long serialVersionUID
= 1L;
243 public void widgetSelected(SelectionEvent e
) {
247 public void widgetDefaultSelected(SelectionEvent e
) {
251 ((Text
) text
.getControl()).addFocusListener(new FocusListener() {
253 private static final long serialVersionUID
= 333838002411959302L;
256 public void focusLost(FocusEvent event
) {
261 public void focusGained(FocusEvent event
) {
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());
282 txt
.setEditable(false);
284 txt
.setLayoutData(CmsSwtUtils
.fillWidth());
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
);
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());
303 txt
.setEditable(false);
305 txt
.setLayoutData(CmsSwtUtils
.fillWidth());
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
);
320 public static Control
addExternalLink(Composite parent
, String label
, String url
, String plainCssAnchorClass
,
322 Label lbl
= new Label(parent
, SWT
.NONE
);
323 CmsSwtUtils
.markup(lbl
);
324 StringBuilder txt
= new StringBuilder();
326 if (plainCssAnchorClass
!= null)
327 txt
.append(" class='" + plainCssAnchorClass
+ "'");
328 txt
.append(" href='").append(url
).append("'");
330 txt
.append(" target='blank_'");
335 lbl
.setText(txt
.toString());
343 public static Img
addPicture(Composite parent
, Content file
) {
344 return addPicture(parent
, file
, null);
347 public static Img
addPicture(Composite parent
, Content file
, Integer maxWidth
) {
348 return addPicture(parent
, file
, maxWidth
, null);
351 public static Img
addPicture(Composite parent
, Content file
, Integer maxWidth
, Content link
) {
355 // if (file.hasContentClass(EntityType.box)) {
356 // width = file.get(SvgAttrs.width, Integer.class).get();
357 // height = file.get(SvgAttrs.height, Integer.class).get();
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);
368 // if (maxWidth != null && width > maxWidth) {
369 // Double ratio = maxWidth.doubleValue() / width.doubleValue();
371 // height = (int) Math.rint(ratio * height);
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);
390 Img img
= new Img(parent
, 0, file
, new Cms2DSize(maxWidth
!= null ? maxWidth
: 0, 0));
394 // String target = toLink(link);
396 img
.addMouseListener(new MouseListener() {
397 private static final long serialVersionUID
= -1362242049325206168L;
400 public void mouseUp(MouseEvent e
) {
404 public void mouseDown(MouseEvent e
) {
408 public void mouseDoubleClick(MouseEvent e
) {
409 LightweightDialog dialog
= new LightweightDialog(img
.getShell()) {
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);
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));
435 protected Point
getInitialSize() {
436 Point shellSize
= img
.getShell().getSize();
437 return new Point(shellSize
.x
- 100, shellSize
.y
- 100);
449 private SuiteSwtUtils() {