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