]> git.argeo.org Git - lgpl/argeo-commons.git/blob - CmsSwtUtils.java
5d964090b9abbd908ff1fc3f007c85afe11a76f8
[lgpl/argeo-commons.git] / CmsSwtUtils.java
1 package org.argeo.cms.swt;
2
3 import java.net.URLEncoder;
4 import java.nio.charset.StandardCharsets;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.StringTokenizer;
8
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;
32
33 /** SWT utilities. */
34 public class CmsSwtUtils {
35 /*
36 * THEME AND VIEW
37 */
38
39 public static CmsSwtTheme getCmsTheme(Composite parent) {
40 CmsSwtTheme theme = (CmsSwtTheme) parent.getData(CmsTheme.class.getName());
41 if (theme == null) {
42 // find parent shell
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);
48 }
49 return theme;
50 }
51
52 public static void registerCmsTheme(Shell shell, CmsTheme theme) {
53 // find parent shell
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");
62 }
63 topShell.setData(CmsTheme.class.getName(), theme);
64 }
65
66 public static CmsView getCmsView(Control parent) {
67 // find parent shell
68 Shell topShell = parent.getShell();
69 while (topShell.getParent() != null)
70 topShell = (Shell) topShell.getParent();
71 return (CmsView) topShell.getData(CmsView.class.getName());
72 }
73
74 public static void registerCmsView(Shell shell, CmsView view) {
75 // find parent shell
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");
83 }
84 shell.setData(CmsView.class.getName(), view);
85 }
86
87 /*
88 * EVENTS
89 */
90
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);
95 };
96 if (control instanceof Button) {
97 ((Button) control).addSelectionListener(listener);
98 } else
99 throw new UnsupportedOperationException("Control type " + control.getClass() + " is not supported.");
100 }
101
102 /**
103 * Convenience method to sends an event via
104 * {@link CmsView#sendEvent(String, Map)}.
105 */
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);
110 }
111
112 /*
113 * ICONS
114 */
115 /** Get a small icon from this theme. */
116 public static Image getSmallIcon(CmsTheme theme, CmsIcon icon) {
117 return ((CmsSwtTheme) theme).getSmallIcon(icon);
118 }
119
120 /** Get a big icon from this theme. */
121 public static Image getBigIcon(CmsTheme theme, CmsIcon icon) {
122 return ((CmsSwtTheme) theme).getBigIcon(icon);
123 }
124
125 /*
126 * LAYOUT INDEPENDENT
127 */
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());
137 } else {
138 throw new IllegalArgumentException("Unsupported parent layout " + parentLayout.getClass().getName());
139 }
140 }
141
142 /*
143 * GRID LAYOUT
144 */
145 /** A {@link GridLayout} without any spacing and one column. */
146 public static GridLayout noSpaceGridLayout() {
147 return noSpaceGridLayout(new GridLayout());
148 }
149
150 /**
151 * A {@link GridLayout} without any spacing and multiple columns of unequal
152 * width.
153 */
154 public static GridLayout noSpaceGridLayout(int columns) {
155 return noSpaceGridLayout(new GridLayout(columns, false));
156 }
157
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;
164 return layout;
165 }
166
167 public static GridData fillAll() {
168 return new GridData(SWT.FILL, SWT.FILL, true, true);
169 }
170
171 public static GridData fillWidth() {
172 return grabWidth(SWT.FILL, SWT.FILL);
173 }
174
175 public static GridData grabWidth(int horizontalAlignment, int verticalAlignment) {
176 return new GridData(horizontalAlignment, horizontalAlignment, true, false);
177 }
178
179 public static GridData fillHeight() {
180 return grabHeight(SWT.FILL, SWT.FILL);
181 }
182
183 public static GridData grabHeight(int horizontalAlignment, int verticalAlignment) {
184 return new GridData(horizontalAlignment, horizontalAlignment, false, true);
185 }
186
187 /*
188 * ROW LAYOUT
189 */
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;
196 return rowLayout;
197 }
198
199 public static RowLayout noMarginsRowLayout(int type) {
200 return noMarginsRowLayout(new RowLayout(type));
201 }
202
203 public static RowData rowData16px() {
204 return new RowData(16, 16);
205 }
206
207 /*
208 * FORM LAYOUT
209 */
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);
216 return fdLabel;
217 }
218
219 /*
220 * STYLING
221 */
222
223 /** Style widget */
224 public static <T extends Widget> T style(T widget, String style) {
225 if (style == null)
226 return widget;// does nothing
227 EclipseUiSpecificUtils.setStyleData(widget, style);
228 if (widget instanceof Control) {
229 CmsView cmsView = getCmsView((Control) widget);
230 if (cmsView != null)
231 cmsView.applyStyles(widget);
232 }
233 return widget;
234 }
235
236 /** Style widget */
237 public static <T extends Widget> T style(T widget, CmsStyle style) {
238 return style(widget, style.style());
239 }
240
241 /** Enable markups on widget */
242 public static <T extends Widget> T markup(T widget) {
243 EclipseUiSpecificUtils.setMarkupData(widget);
244 return widget;
245 }
246
247 /** Disable markup validation. */
248 public static <T extends Widget> T disableMarkupValidation(T widget) {
249 EclipseUiSpecificUtils.setMarkupValidationDisabledData(widget);
250 return widget;
251 }
252
253 /**
254 * Apply markup and set text on {@link Label}, {@link Button}, {@link Text}.
255 *
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.
261 *
262 * @see markup
263 */
264 public static <T extends Widget> T text(T widget, Object txt) {
265 assert txt != null;
266 String str = txt != null ? txt.toString() : "<null>";
267 markup(widget);
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);
274 else
275 throw new IllegalArgumentException("Unsupported widget type " + widget.getClass());
276 return widget;
277 }
278
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);
282 }
283
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);
287 }
288
289 /** Dispose all children of a Composite */
290 public static void clear(Composite composite) {
291 if (composite.isDisposed())
292 return;
293 for (Control child : composite.getChildren())
294 child.dispose();
295 }
296
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()) {
302 sb.append('/');
303 String encoded = URLEncoder.encode(st.nextToken(), StandardCharsets.UTF_8);
304 encoded = encoded.replace("+", "%20");
305 sb.append(encoded);
306
307 }
308 return sb.toString();
309 }
310
311 /** Singleton. */
312 private CmsSwtUtils() {
313 }
314
315 }