]> git.argeo.org Git - lgpl/argeo-commons.git/blob - swt/org.argeo.swt.minidesktop/src/org/argeo/minidesktop/MiniDesktopManager.java
Make MAC address UUID more robust
[lgpl/argeo-commons.git] / swt / org.argeo.swt.minidesktop / src / org / argeo / minidesktop / MiniDesktopManager.java
1 package org.argeo.minidesktop;
2
3 import java.lang.management.ManagementFactory;
4 import java.net.InetAddress;
5 import java.net.UnknownHostException;
6 import java.nio.file.Path;
7 import java.util.Arrays;
8 import java.util.List;
9
10 import org.eclipse.swt.SWT;
11 import org.eclipse.swt.custom.CTabFolder;
12 import org.eclipse.swt.custom.CTabItem;
13 import org.eclipse.swt.events.SelectionAdapter;
14 import org.eclipse.swt.events.SelectionEvent;
15 import org.eclipse.swt.graphics.Color;
16 import org.eclipse.swt.graphics.Image;
17 import org.eclipse.swt.graphics.Point;
18 import org.eclipse.swt.graphics.Rectangle;
19 import org.eclipse.swt.layout.GridData;
20 import org.eclipse.swt.layout.GridLayout;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Control;
23 import org.eclipse.swt.widgets.Display;
24 import org.eclipse.swt.widgets.Shell;
25 import org.eclipse.swt.widgets.ToolBar;
26 import org.eclipse.swt.widgets.ToolItem;
27
28 /** A very minimalistic desktop manager based on Java and Eclipse SWT. */
29 public class MiniDesktopManager {
30 private Display display;
31
32 private Shell rootShell;
33 private Shell toolBarShell;
34 private CTabFolder tabFolder;
35 private int maxTabTitleLength = 16;
36
37 private final boolean fullscreen;
38 private final boolean stacking;
39
40 private MiniDesktopImages images;
41
42 public MiniDesktopManager(boolean fullscreen, boolean stacking) {
43 this.fullscreen = fullscreen;
44 this.stacking = stacking;
45 }
46
47 public MiniDesktopManager() {
48 this(false, false);
49 }
50
51 public void start() {
52 init();
53 }
54
55 public void stop() {
56 dispose();
57 if (display != null) {
58 display.dispose();
59 display = null;
60 }
61 }
62
63 public void init() {
64 Display.setAppName("Mini SWT Desktop");
65 display = Display.getCurrent();
66 if (display != null)
67 throw new IllegalStateException("Already a display " + display);
68 display = Display.getDefault();
69
70 display.syncExec(() -> {
71 if (display.getTouchEnabled()) {
72 System.out.println("Touch enabled.");
73 }
74
75 images = new MiniDesktopImages(display);
76
77 int toolBarSize = 48;
78
79 if (isFullscreen()) {
80 rootShell = new Shell(display, SWT.NO_TRIM);
81 rootShell.setFullScreen(true);
82 Rectangle bounds = display.getBounds();
83 rootShell.setLocation(0, 0);
84 rootShell.setSize(bounds.width, bounds.height);
85 } else {
86 rootShell = new Shell(display, SWT.CLOSE | SWT.RESIZE);
87 Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480);
88 rootShell.setSize(shellArea.width, shellArea.height);
89 rootShell.setText(Display.getAppName());
90 rootShell.setImage(images.terminalIcon);
91 }
92
93 rootShell.setLayout(noSpaceGridLayout(new GridLayout(2, false)));
94 Composite toolBarArea = new Composite(rootShell, SWT.NONE);
95 toolBarArea.setLayoutData(new GridData(toolBarSize, rootShell.getSize().y));
96
97 ToolBar toolBar;
98 if (isFullscreen()) {
99 toolBarShell = new Shell(rootShell, SWT.NO_TRIM | SWT.ON_TOP);
100 toolBar = new ToolBar(toolBarShell, SWT.VERTICAL | SWT.FLAT | SWT.BORDER);
101 createDock(toolBar);
102 toolBarShell.pack();
103 toolBarArea.setLayoutData(new GridData(toolBar.getSize().x, toolBar.getSize().y));
104 } else {
105 toolBar = new ToolBar(toolBarArea, SWT.VERTICAL | SWT.FLAT | SWT.BORDER);
106 createDock(toolBar);
107 toolBarArea.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
108 }
109
110 if (isStacking()) {
111 tabFolder = new CTabFolder(rootShell, SWT.MULTI | SWT.BORDER | SWT.BOTTOM);
112 tabFolder.setLayout(noSpaceGridLayout(new GridLayout()));
113 tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
114
115 Color selectionBackground = display.getSystemColor(SWT.COLOR_LIST_SELECTION);
116 tabFolder.setSelectionBackground(selectionBackground);
117
118 // background
119 Control background = createBackground(tabFolder);
120 CTabItem homeTabItem = new CTabItem(tabFolder, SWT.NONE);
121 homeTabItem.setText("Home");
122 homeTabItem.setImage(images.homeIcon);
123 homeTabItem.setControl(background);
124 tabFolder.setFocus();
125 } else {
126 createBackground(rootShell);
127 }
128
129 rootShell.open();
130 // rootShell.layout(true, true);
131
132 if (toolBarShell != null) {
133 int toolBarShellY = (display.getBounds().height - toolBar.getSize().y) / 2;
134 toolBarShell.setLocation(0, toolBarShellY);
135 toolBarShell.open();
136 }
137
138 long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime();
139 System.out.println("SWT Mini Desktop Manager available in " + jvmUptime + " ms.");
140 });
141 }
142
143 protected void createDock(ToolBar toolBar) {
144 // Terminal
145 addToolItem(toolBar, images.terminalIcon, "Terminal", () -> {
146 String url = System.getProperty("user.home");
147 AppContext appContext = createAppParent(images.terminalIcon);
148 new MiniTerminal(appContext.getAppParent(), url) {
149
150 @Override
151 protected void exitCalled() {
152 if (appContext.shell != null)
153 appContext.shell.dispose();
154 if (appContext.tabItem != null)
155 appContext.tabItem.dispose();
156 }
157 };
158 String title;
159 try {
160 title = System.getProperty("user.name") + "@" + InetAddress.getLocalHost().getHostName();
161 } catch (UnknownHostException e) {
162 title = System.getProperty("user.name") + "@localhost";
163 }
164 if (appContext.shell != null)
165 appContext.shell.setText(title);
166 if (appContext.tabItem != null) {
167 appContext.tabItem.setText(tabTitle(title));
168 appContext.tabItem.setToolTipText(title);
169 }
170 openApp(appContext);
171 });
172
173 // Web browser
174 addToolItem(toolBar, images.browserIcon, "Browser", () -> {
175 String url = "https://start.duckduckgo.com/";
176 AppContext appContext = createAppParent(images.browserIcon);
177 new MiniBrowser(appContext.getAppParent(), url, false, false) {
178 @Override
179 public void titleChanged(String title) {
180 if (appContext.shell != null)
181 appContext.shell.setText(title);
182 if (appContext.tabItem != null) {
183 appContext.tabItem.setText(tabTitle(title));
184 appContext.tabItem.setToolTipText(title);
185 }
186 }
187 };
188 openApp(appContext);
189 });
190
191 // File explorer
192 addToolItem(toolBar, images.explorerIcon, "Explorer", () -> {
193 String url = System.getProperty("user.home");
194 AppContext appContext = createAppParent(images.explorerIcon);
195 new MiniExplorer(appContext.getAppParent(), url) {
196
197 @Override
198 protected void pathChanged(Path path) {
199 if (appContext.shell != null)
200 appContext.shell.setText(path.toString());
201 if (appContext.tabItem != null) {
202 appContext.tabItem.setText(path.getFileName().toString());
203 appContext.tabItem.setToolTipText(path.toString());
204 }
205 }
206 };
207 openApp(appContext);
208 });
209
210 // Separator
211 new ToolItem(toolBar, SWT.SEPARATOR);
212
213 // Exit
214 addToolItem(toolBar, images.exitIcon, "Exit", () -> rootShell.dispose());
215
216 toolBar.pack();
217 }
218
219 protected String tabTitle(String title) {
220 return title.length() > maxTabTitleLength ? title.substring(0, maxTabTitleLength) : title;
221 }
222
223 protected void addToolItem(ToolBar toolBar, Image icon, String name, Runnable action) {
224 ToolItem searchI = new ToolItem(toolBar, SWT.PUSH);
225 searchI.setImage(icon);
226 searchI.setToolTipText(name);
227 searchI.addSelectionListener(new SelectionAdapter() {
228
229 @Override
230 public void widgetSelected(SelectionEvent e) {
231 action.run();
232 }
233
234 });
235 }
236
237 protected AppContext createAppParent(Image icon) {
238 if (isStacking()) {
239 Composite appParent = new Composite(tabFolder, SWT.CLOSE);
240 appParent.setLayout(noSpaceGridLayout(new GridLayout()));
241 CTabItem item = new CTabItem(tabFolder, SWT.CLOSE);
242 item.setImage(icon);
243 item.setControl(appParent);
244 return new AppContext(item);
245 } else {
246 Shell shell = isFullscreen() ? new Shell(rootShell, SWT.SHELL_TRIM)
247 : new Shell(rootShell.getDisplay(), SWT.SHELL_TRIM);
248 shell.setImage(icon);
249 return new AppContext(shell);
250 }
251 }
252
253 protected void openApp(AppContext appContext) {
254 if (appContext.shell != null) {
255 Shell shell = (Shell) appContext.shell;
256 shell.open();
257 shell.setSize(new Point(800, 480));
258 }
259 if (appContext.tabItem != null) {
260 tabFolder.setFocus();
261 tabFolder.setSelection(appContext.tabItem);
262 }
263 }
264
265 protected Control createBackground(Composite parent) {
266 Composite backgroundArea = new Composite(parent, SWT.NONE);
267 backgroundArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
268 initBackground(backgroundArea);
269 return backgroundArea;
270 }
271
272 protected void initBackground(Composite backgroundArea) {
273 MiniHomePart homePart = new MiniHomePart() {
274
275 @Override
276 protected void fillAppsToolBar(ToolBar toolBar) {
277 createDock(toolBar);
278 }
279 };
280 homePart.createUiPart(backgroundArea, null);
281 }
282
283 public void run() {
284 while (!rootShell.isDisposed()) {
285 if (!display.readAndDispatch())
286 display.sleep();
287 }
288 }
289
290 public void dispose() {
291 if (!rootShell.isDisposed())
292 rootShell.dispose();
293 }
294
295 protected boolean isFullscreen() {
296 return fullscreen;
297 }
298
299 protected boolean isStacking() {
300 return stacking;
301 }
302
303 protected Image getIconForExt(String ext) {
304 // Program program = Program.findProgram(ext);
305 // if (program == null)
306 return display.getSystemImage(SWT.ICON_INFORMATION);
307
308 // ImageData iconData = program.getImageData();
309 // if (iconData == null) {
310 // return display.getSystemImage(SWT.ICON_INFORMATION);
311 // } else {
312 // return new Image(display, iconData);
313 // }
314
315 }
316
317 private static GridLayout noSpaceGridLayout(GridLayout layout) {
318 layout.horizontalSpacing = 0;
319 layout.verticalSpacing = 0;
320 layout.marginWidth = 0;
321 layout.marginHeight = 0;
322 return layout;
323 }
324
325 public static void main(String[] args) {
326 List<String> options = Arrays.asList(args);
327 if (options.contains("--help")) {
328 System.out.println("Usage: java " + MiniDesktopManager.class.getName().replace('.', '/') + " [OPTION]");
329 System.out.println("A minimalistic desktop manager based on Java and Eclipse SWT.");
330 System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)");
331 System.out.println(" --stacking : open apps as tabs (default is to create new windows)");
332 System.out.println(" --help : print this help and exit");
333 System.exit(1);
334 }
335 boolean fullscreen = options.contains("--fullscreen");
336 boolean stacking = options.contains("--stacking");
337
338 MiniDesktopManager desktopManager = new MiniDesktopManager(fullscreen, stacking);
339 desktopManager.init();
340 desktopManager.run();
341 desktopManager.dispose();
342 System.exit(0);
343 }
344
345 class AppContext {
346 private Shell shell;
347 private CTabItem tabItem;
348
349 public AppContext(Shell shell) {
350 this.shell = shell;
351 }
352
353 public AppContext(CTabItem tabItem) {
354 this.tabItem = tabItem;
355 }
356
357 Composite getAppParent() {
358 if (shell != null)
359 return shell;
360 if (tabItem != null)
361 return (Composite) tabItem.getControl();
362 throw new IllegalStateException();
363 }
364 }
365 }