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
.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
;
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());
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
);
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
);
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");
67 public static Label
addFormLabel(Composite parent
, String label
) {
68 Label lbl
= new Label(parent
, SWT
.WRAP
);
70 lbl
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, false, false));
71 CmsSwtUtils
.style(lbl
, SuiteStyle
.simpleLabel
);
75 public static Label
addFormLabel(Composite parent
, Localized msg
) {
76 return addFormLabel(parent
, msg
.lead());
79 public static Text
addFormTextField(Composite parent
, String text
, String message
, int style
) {
80 Text txt
= new Text(parent
, style
);
84 txt
.setMessage(message
);
85 txt
.setLayoutData(new GridData(SWT
.FILL
, SWT
.CENTER
, true, true));
86 CmsSwtUtils
.style(txt
, SuiteStyle
.simpleInput
);
90 public static Text
addFormTextField(Composite parent
, String text
, String message
) {
91 return addFormTextField(parent
, text
, message
, SWT
.NONE
);
94 // public static Text addFormInputField(Composite parent, String placeholder) {
95 // Text txt = new Text(parent, SWT.BORDER);
97 // GridData gridData = CmsSwtUtils.fillWidth();
98 // txt.setLayoutData(gridData);
100 // if (placeholder != null)
101 // txt.setText(placeholder);
103 // CmsSwtUtils.style(txt, SuiteStyle.simpleInput);
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
;
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
);
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());
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());
141 * creates a single horizontal-block composite for key:value display, with
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());
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
);
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,
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());
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));
185 public static String
toLink(Content content
) {
186 return content
!= null ?
"#" + ContentUtils
.cleanPathForUrl(content
.getPath()) : null;
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
);
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
);
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
);
212 if (cmsEditable
.isEditing())
213 text
.setMouseListener(new MouseAdapter() {
215 private static final long serialVersionUID
= 1L;
218 public void mouseDoubleClick(MouseEvent e
) {
219 String currentTxt
= text
.getText();
221 text
.setText(currentTxt
);
223 Runnable save
= () -> {
224 String editedTxt
= text
.getText();
225 if (validator
!= null) {
226 if (!validator
.test(editedTxt
)) {
228 text
.setText(currentTxt
);
229 CmsFeedback
.show(editedTxt
+ " is not properly formatted");
231 // throw new IllegalArgumentException(editedTxt + " is not properly formatted");
234 content
.put(attr
, editedTxt
);
236 text
.setText(editedTxt
);
237 text
.getParent().layout(new Control
[] { text
.getControl() });
239 ((Text
) text
.getControl()).addSelectionListener(new SelectionListener() {
241 private static final long serialVersionUID
= 1L;
244 public void widgetSelected(SelectionEvent e
) {
248 public void widgetDefaultSelected(SelectionEvent e
) {
252 ((Text
) text
.getControl()).addFocusListener(new FocusListener() {
254 private static final long serialVersionUID
= 333838002411959302L;
257 public void focusLost(FocusEvent event
) {
262 public void focusGained(FocusEvent event
) {
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());
283 txt
.setEditable(false);
285 txt
.setLayoutData(CmsSwtUtils
.fillWidth());
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
);
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().trim());
304 txt
.setEditable(false);
306 txt
.setLayoutData(CmsSwtUtils
.fillWidth());
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
);
321 public static Control
addExternalLink(Composite parent
, String label
, String url
, String plainCssAnchorClass
,
323 Label lbl
= new Label(parent
, SWT
.NONE
);
324 CmsSwtUtils
.markup(lbl
);
325 StringBuilder txt
= new StringBuilder();
327 if (plainCssAnchorClass
!= null)
328 txt
.append(" class='" + plainCssAnchorClass
+ "'");
329 txt
.append(" href='").append(url
).append("'");
331 txt
.append(" target='blank_'");
336 lbl
.setText(txt
.toString());
344 public static Img
addPicture(Composite parent
, Content file
) {
345 return addPicture(parent
, file
, null);
348 public static Img
addPicture(Composite parent
, Content file
, Integer maxWidth
) {
349 return addPicture(parent
, file
, maxWidth
, null);
352 public static Img
addPicture(Composite parent
, Content file
, Integer maxWidth
, Content link
) {
356 // if (file.hasContentClass(EntityType.box)) {
357 // width = file.get(SvgAttrs.width, Integer.class).get();
358 // height = file.get(SvgAttrs.height, Integer.class).get();
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);
369 // if (maxWidth != null && width > maxWidth) {
370 // Double ratio = maxWidth.doubleValue() / width.doubleValue();
372 // height = (int) Math.rint(ratio * height);
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);
391 Img img
= new Img(parent
, 0, file
, new Cms2DSize(maxWidth
!= null ? maxWidth
: 0, 0));
395 // String target = toLink(link);
397 img
.addMouseListener(new MouseListener() {
398 private static final long serialVersionUID
= -1362242049325206168L;
401 public void mouseUp(MouseEvent e
) {
405 public void mouseDown(MouseEvent e
) {
409 public void mouseDoubleClick(MouseEvent e
) {
410 LightweightDialog dialog
= new LightweightDialog(img
.getShell()) {
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);
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));
436 protected Point
getInitialSize() {
437 Point shellSize
= img
.getShell().getSize();
438 return new Point(shellSize
.x
- 100, shellSize
.y
- 100);
450 private SuiteSwtUtils() {