1 package org
.argeo
.cms
.swt
;
3 import java
.net
.URLEncoder
;
4 import java
.nio
.charset
.StandardCharsets
;
5 import java
.util
.HashMap
;
7 import java
.util
.StringTokenizer
;
9 import org
.argeo
.api
.cms
.ux
.CmsIcon
;
10 import org
.argeo
.api
.cms
.ux
.CmsStyle
;
11 import org
.argeo
.api
.cms
.ux
.CmsTheme
;
12 import org
.argeo
.api
.cms
.ux
.CmsView
;
13 import org
.argeo
.eclipse
.ui
.specific
.EclipseUiSpecificUtils
;
14 import org
.eclipse
.swt
.SWT
;
15 import org
.eclipse
.swt
.events
.SelectionListener
;
16 import org
.eclipse
.swt
.graphics
.Image
;
17 import org
.eclipse
.swt
.layout
.FormAttachment
;
18 import org
.eclipse
.swt
.layout
.FormData
;
19 import org
.eclipse
.swt
.layout
.FormLayout
;
20 import org
.eclipse
.swt
.layout
.GridData
;
21 import org
.eclipse
.swt
.layout
.GridLayout
;
22 import org
.eclipse
.swt
.layout
.RowData
;
23 import org
.eclipse
.swt
.layout
.RowLayout
;
24 import org
.eclipse
.swt
.widgets
.Button
;
25 import org
.eclipse
.swt
.widgets
.Composite
;
26 import org
.eclipse
.swt
.widgets
.Control
;
27 import org
.eclipse
.swt
.widgets
.Label
;
28 import org
.eclipse
.swt
.widgets
.Layout
;
29 import org
.eclipse
.swt
.widgets
.Shell
;
30 import org
.eclipse
.swt
.widgets
.Text
;
31 import org
.eclipse
.swt
.widgets
.Widget
;
34 public class CmsSwtUtils
{
39 public static CmsSwtTheme
getCmsTheme(Composite parent
) {
40 CmsSwtTheme theme
= (CmsSwtTheme
) parent
.getData(CmsTheme
.class.getName());
43 Shell topShell
= parent
.getShell();
44 while (topShell
.getParent() != null)
45 topShell
= (Shell
) topShell
.getParent();
46 theme
= (CmsSwtTheme
) topShell
.getData(CmsTheme
.class.getName());
47 parent
.setData(CmsTheme
.class.getName(), theme
);
52 public static void registerCmsTheme(Shell shell
, CmsTheme theme
) {
54 Shell topShell
= shell
;
55 while (topShell
.getParent() != null)
56 topShell
= (Shell
) topShell
.getParent();
57 // check if already set
58 if (topShell
.getData(CmsTheme
.class.getName()) != null) {
59 CmsTheme registeredTheme
= (CmsTheme
) topShell
.getData(CmsTheme
.class.getName());
60 throw new IllegalArgumentException(
61 "Theme " + registeredTheme
.getThemeId() + " already registered in this shell");
63 topShell
.setData(CmsTheme
.class.getName(), theme
);
66 public static CmsView
getCmsView(Control parent
) {
68 Shell topShell
= parent
.getShell();
69 while (topShell
.getParent() != null)
70 topShell
= (Shell
) topShell
.getParent();
71 return (CmsView
) topShell
.getData(CmsView
.class.getName());
74 public static void registerCmsView(Shell shell
, CmsView view
) {
76 Shell topShell
= shell
;
77 while (topShell
.getParent() != null)
78 topShell
= (Shell
) topShell
.getParent();
79 // check if already set
80 if (topShell
.getData(CmsView
.class.getName()) != null) {
81 CmsView registeredView
= (CmsView
) topShell
.getData(CmsView
.class.getName());
82 throw new IllegalArgumentException("Cms view " + registeredView
+ " already registered in this shell");
84 shell
.setData(CmsView
.class.getName(), view
);
91 /** Sends an event via {@link CmsView#sendEvent(String, Map)}. */
92 public static void sendEventOnSelect(Control control
, String topic
, Map
<String
, Object
> properties
) {
93 SelectionListener listener
= (Selected
) (e
) -> {
94 getCmsView(control
.getParent()).sendEvent(topic
, properties
);
96 if (control
instanceof Button
) {
97 ((Button
) control
).addSelectionListener(listener
);
99 throw new UnsupportedOperationException("Control type " + control
.getClass() + " is not supported.");
103 * Convenience method to sends an event via
104 * {@link CmsView#sendEvent(String, Map)}.
106 public static void sendEventOnSelect(Control control
, String topic
, String key
, Object value
) {
107 Map
<String
, Object
> properties
= new HashMap
<>();
108 properties
.put(key
, value
);
109 sendEventOnSelect(control
, topic
, properties
);
115 /** Get a small icon from this theme. */
116 public static Image
getSmallIcon(CmsTheme theme
, CmsIcon icon
) {
117 return ((CmsSwtTheme
) theme
).getSmallIcon(icon
);
120 /** Get a big icon from this theme. */
121 public static Image
getBigIcon(CmsTheme theme
, CmsIcon icon
) {
122 return ((CmsSwtTheme
) theme
).getBigIcon(icon
);
128 /** Takes the most space possible, depending on parent layout. */
129 public static void fill(Control control
) {
130 Layout parentLayout
= control
.getParent().getLayout();
131 if (parentLayout
== null)
132 throw new IllegalStateException("Parent layout is not set");
133 if (parentLayout
instanceof GridLayout
) {
134 control
.setLayoutData(fillAll());
135 } else if (parentLayout
instanceof FormLayout
) {
136 control
.setLayoutData(coverAll());
138 throw new IllegalArgumentException("Unsupported parent layout " + parentLayout
.getClass().getName());
145 /** A {@link GridLayout} without any spacing and one column. */
146 public static GridLayout
noSpaceGridLayout() {
147 return noSpaceGridLayout(new GridLayout());
151 * A {@link GridLayout} without any spacing and multiple columns of unequal
154 public static GridLayout
noSpaceGridLayout(int columns
) {
155 return noSpaceGridLayout(new GridLayout(columns
, false));
158 /** @return the same layout, with spaces removed. */
159 public static GridLayout
noSpaceGridLayout(GridLayout layout
) {
160 layout
.horizontalSpacing
= 0;
161 layout
.verticalSpacing
= 0;
162 layout
.marginWidth
= 0;
163 layout
.marginHeight
= 0;
167 public static GridData
fillAll() {
168 return new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
171 public static GridData
fillWidth() {
172 return grabWidth(SWT
.FILL
, SWT
.FILL
);
175 public static GridData
grabWidth(int horizontalAlignment
, int verticalAlignment
) {
176 return new GridData(horizontalAlignment
, horizontalAlignment
, true, false);
179 public static GridData
fillHeight() {
180 return grabHeight(SWT
.FILL
, SWT
.FILL
);
183 public static GridData
grabHeight(int horizontalAlignment
, int verticalAlignment
) {
184 return new GridData(horizontalAlignment
, horizontalAlignment
, false, true);
190 /** @return the same layout, with margins removed. */
191 public static RowLayout
noMarginsRowLayout(RowLayout rowLayout
) {
192 rowLayout
.marginTop
= 0;
193 rowLayout
.marginBottom
= 0;
194 rowLayout
.marginLeft
= 0;
195 rowLayout
.marginRight
= 0;
199 public static RowLayout
noMarginsRowLayout(int type
) {
200 return noMarginsRowLayout(new RowLayout(type
));
203 public static RowData
rowData16px() {
204 return new RowData(16, 16);
210 public static FormData
coverAll() {
211 FormData fdLabel
= new FormData();
212 fdLabel
.top
= new FormAttachment(0, 0);
213 fdLabel
.left
= new FormAttachment(0, 0);
214 fdLabel
.right
= new FormAttachment(100, 0);
215 fdLabel
.bottom
= new FormAttachment(100, 0);
224 public static <T
extends Widget
> T
style(T widget
, String style
) {
226 return widget
;// does nothing
227 EclipseUiSpecificUtils
.setStyleData(widget
, style
);
228 if (widget
instanceof Control
) {
229 CmsView cmsView
= getCmsView((Control
) widget
);
231 cmsView
.applyStyles(widget
);
237 public static <T
extends Widget
> T
style(T widget
, CmsStyle style
) {
238 return style(widget
, style
.style());
241 /** Enable markups on widget */
242 public static <T
extends Widget
> T
markup(T widget
) {
243 EclipseUiSpecificUtils
.setMarkupData(widget
);
247 /** Disable markup validation. */
248 public static <T
extends Widget
> T
disableMarkupValidation(T widget
) {
249 EclipseUiSpecificUtils
.setMarkupValidationDisabledData(widget
);
254 * Apply markup and set text on {@link Label}, {@link Button}, {@link Text}.
256 * @param widget the widget to style and to use in order to display text
257 * @param txt the object to display via its <code>toString()</code> method.
258 * This argument should not be null, but if it is null and
259 * assertions are disabled "<null>" is displayed instead; if
260 * assertions are enabled the call will fail.
264 public static <T
extends Widget
> T
text(T widget
, Object txt
) {
266 String str
= txt
!= null ? txt
.toString() : "<null>";
268 if (widget
instanceof Label
)
269 ((Label
) widget
).setText(str
);
270 else if (widget
instanceof Button
)
271 ((Button
) widget
).setText(str
);
272 else if (widget
instanceof Text
)
273 ((Text
) widget
).setText(str
);
275 throw new IllegalArgumentException("Unsupported widget type " + widget
.getClass());
279 /** A {@link Label} with markup activated. */
280 public static Label
lbl(Composite parent
, Object txt
) {
281 return text(new Label(parent
, SWT
.NONE
), txt
);
284 /** A read-only {@link Text} whose content can be copy/pasted. */
285 public static Text
txt(Composite parent
, Object txt
) {
286 return text(new Text(parent
, SWT
.NONE
), txt
);
289 /** Dispose all children of a Composite */
290 public static void clear(Composite composite
) {
291 if (composite
.isDisposed())
293 for (Control child
: composite
.getChildren())
297 /** Clean reserved URL characters for use in HTTP links. */
298 public static String
cleanPathForUrl(String path
) {
299 StringTokenizer st
= new StringTokenizer(path
, "/");
300 StringBuilder sb
= new StringBuilder();
301 while (st
.hasMoreElements()) {
303 String encoded
= URLEncoder
.encode(st
.nextToken(), StandardCharsets
.UTF_8
);
304 encoded
= encoded
.replace("+", "%20");
308 return sb
.toString();
312 private CmsSwtUtils() {