X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=rcp%2Forg.argeo.minidesktop%2Fsrc%2Forg%2Fargeo%2Fminidesktop%2FMiniDesktopManager.java;fp=rcp%2Forg.argeo.minidesktop%2Fsrc%2Forg%2Fargeo%2Fminidesktop%2FMiniDesktopManager.java;h=a1f6d333e2e33c0de3b6820fdf044b147a3dbb45;hb=637bb618df290885daac173b5ce0c6a33667bb99;hp=0000000000000000000000000000000000000000;hpb=528ac382d093fe9000f3e9422fdf6b22779840e2;p=gpl%2Fargeo-slc.git diff --git a/rcp/org.argeo.minidesktop/src/org/argeo/minidesktop/MiniDesktopManager.java b/rcp/org.argeo.minidesktop/src/org/argeo/minidesktop/MiniDesktopManager.java new file mode 100644 index 000000000..a1f6d333e --- /dev/null +++ b/rcp/org.argeo.minidesktop/src/org/argeo/minidesktop/MiniDesktopManager.java @@ -0,0 +1,309 @@ +package org.argeo.minidesktop; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CTabFolder; +import org.eclipse.swt.custom.CTabItem; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +/** A very minimalistic desktop manager based on Java and Eclipse SWT. */ +public class MiniDesktopManager { + private Display display; + + private Shell rootShell; + private Shell toolBarShell; + private CTabFolder tabFolder; + private int maxTabTitleLength = 16; + + private final boolean fullscreen; + private final boolean stacking; + + public MiniDesktopManager(boolean fullscreen, boolean stacking) { + this.fullscreen = fullscreen; + this.stacking = stacking; + } + + public void init() { + display = Display.getCurrent(); + if (display != null) + throw new IllegalStateException("Already a display " + display); + display = new Display(); + + int toolBarSize = 48; + + if (isFullscreen()) { + rootShell = new Shell(display, SWT.NO_TRIM); + rootShell.setFullScreen(true); + Rectangle bounds = display.getBounds(); + rootShell.setSize(bounds.width, bounds.height); + } else { + rootShell = new Shell(display, SWT.SHELL_TRIM); + Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480); + rootShell.setSize(shellArea.width, shellArea.height); + } + + rootShell.setLayout(noSpaceGridLayout(new GridLayout(2, false))); + Composite toolBarArea = new Composite(rootShell, SWT.NONE); + toolBarArea.setLayoutData(new GridData(toolBarSize, rootShell.getSize().y)); + + ToolBar toolBar; + if (isFullscreen()) { + toolBarShell = new Shell(rootShell, SWT.NO_TRIM | SWT.ON_TOP); + toolBar = new ToolBar(toolBarShell, SWT.VERTICAL | SWT.FLAT | SWT.BORDER); + createDock(toolBar); + toolBarShell.pack(); + toolBarArea.setLayoutData(new GridData(toolBar.getSize().x, toolBar.getSize().y)); + } else { + toolBar = new ToolBar(toolBarArea, SWT.VERTICAL | SWT.FLAT | SWT.BORDER); + createDock(toolBar); + toolBarArea.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false)); + } + + if (isStacking()) { + tabFolder = new CTabFolder(rootShell, SWT.MULTI); + tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + // background + Control background = createBackground(tabFolder); + CTabItem noCloseItem = new CTabItem(tabFolder, SWT.NONE); + noCloseItem.setText("Home"); + noCloseItem.setControl(background); + } else { + createBackground(rootShell); + } + + rootShell.open(); + // rootShell.layout(true, true); + + if (toolBarShell != null) { + toolBarShell.setLocation(new Point(0, 0)); + toolBarShell.open(); + } + } + + protected void createDock(ToolBar toolBar) { + // Terminal + addToolItem(toolBar, display.getSystemImage(SWT.ICON_INFORMATION), "Terminal", () -> { + String url = System.getProperty("user.home"); + AppContext appContext = createAppParent(); + new MiniTerminal(appContext.getAppParent(), url) { + + @Override + protected void exitCalled() { + if (appContext.shell != null) + appContext.shell.dispose(); + if (appContext.tabItem != null) + appContext.tabItem.dispose(); + } + }; + String title; + try { + title = System.getProperty("user.name") + "@" + InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + title = System.getProperty("user.name") + "@localhost"; + } + if (appContext.shell != null) + appContext.shell.setText(title); + if (appContext.tabItem != null) { + appContext.tabItem.setText(tabTitle(title)); + appContext.tabItem.setToolTipText(title); + } + openApp(appContext); + }); + + // Web browser + addToolItem(toolBar, display.getSystemImage(SWT.ICON_QUESTION), "Browser", () -> { + String url = "https://duckduckgo.com/"; + AppContext appContext = createAppParent(); + new MiniBrowser(appContext.getAppParent(), url, false, false) { + @Override + protected void titleChanged(String title) { + if (appContext.shell != null) + appContext.shell.setText(title); + if (appContext.tabItem != null) { + appContext.tabItem.setText(tabTitle(title)); + appContext.tabItem.setToolTipText(title); + } + } + }; + openApp(appContext); + }); + + // File explorer + addToolItem(toolBar, display.getSystemImage(SWT.ICON_WARNING), "Explorer", () -> { + String url = System.getProperty("user.home"); + AppContext appContext = createAppParent(); + new MiniExplorer(appContext.getAppParent(), url) { + + @Override + protected void pathChanged(Path path) { + if (appContext.shell != null) + appContext.shell.setText(path.toString()); + if (appContext.tabItem != null) { + appContext.tabItem.setText(path.getFileName().toString()); + appContext.tabItem.setToolTipText(path.toString()); + } + } + }; + openApp(appContext); + }); + + // Exit + addToolItem(toolBar, display.getSystemImage(SWT.ICON_ERROR), "Exit", () -> rootShell.dispose()); + + toolBar.pack(); + } + + protected String tabTitle(String title) { + return title.length() > maxTabTitleLength ? title.substring(0, maxTabTitleLength) : title; + } + + protected void addToolItem(ToolBar toolBar, Image icon, String name, Runnable action) { + ToolItem searchI = new ToolItem(toolBar, SWT.PUSH); + searchI.setImage(icon); + searchI.setToolTipText(name); + searchI.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + action.run(); + } + + }); + } + + protected AppContext createAppParent() { + if (isStacking()) { + Composite appParent = new Composite(tabFolder, SWT.NONE); + appParent.setLayout(noSpaceGridLayout(new GridLayout())); + CTabItem item = new CTabItem(tabFolder, SWT.CLOSE); + item.setControl(appParent); + return new AppContext(item); + } else { + Shell shell = new Shell(rootShell, SWT.SHELL_TRIM); + return new AppContext(shell); + } + } + + protected void openApp(AppContext appContext) { + if (appContext.shell != null) { + Shell shell = (Shell) appContext.shell; + shell.open(); + shell.setSize(new Point(800, 480)); + } + if (appContext.tabItem != null) { + tabFolder.setSelection(appContext.tabItem); + } + } + + protected Control createBackground(Composite parent) { + Composite backgroundArea = new Composite(parent, SWT.NONE); + backgroundArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + initBackground(backgroundArea); + return backgroundArea; + } + + protected void initBackground(Composite backgroundArea) { + } + + public void run() { + while (!rootShell.isDisposed()) { + if (!display.readAndDispatch()) + display.sleep(); + } + } + + public void dispose() { + if (!rootShell.isDisposed()) + rootShell.dispose(); + } + + protected boolean isFullscreen() { + return fullscreen; + } + + protected boolean isStacking() { + return stacking; + } + + protected Image getIconForExt(String ext) { + Program program = Program.findProgram(ext); + if (program == null) + return display.getSystemImage(SWT.ICON_INFORMATION); + + ImageData iconData = program.getImageData(); + if (iconData == null) { + return display.getSystemImage(SWT.ICON_INFORMATION); + } else { + return new Image(display, iconData); + } + + } + + private static GridLayout noSpaceGridLayout(GridLayout layout) { + layout.horizontalSpacing = 0; + layout.verticalSpacing = 0; + layout.marginWidth = 0; + layout.marginHeight = 0; + return layout; + } + + public static void main(String[] args) { + List options = Arrays.asList(args); + if (options.contains("--help")) { + System.out.println("Usage: java " + MiniDesktopManager.class.getName().replace('.', '/') + " [OPTION]"); + System.out.println("A minimalistic desktop manager based on Java and Eclipse SWT."); + System.out.println(" --fullscreen : take control of the whole screen (default is to run in a window)"); + System.out.println(" --stacking : open apps as tabs (default is to create new windows)"); + System.out.println(" --help : print this help and exit"); + System.exit(1); + } + boolean fullscreen = options.contains("--fullscreen"); + boolean stacking = options.contains("--stacking"); + + MiniDesktopManager desktopManager = new MiniDesktopManager(fullscreen, stacking); + desktopManager.init(); + desktopManager.run(); + desktopManager.dispose(); + System.exit(0); + } + + class AppContext { + private Shell shell; + private CTabItem tabItem; + + public AppContext(Shell shell) { + this.shell = shell; + } + + public AppContext(CTabItem tabItem) { + this.tabItem = tabItem; + } + + Composite getAppParent() { + if (shell != null) + return shell; + if (tabItem != null) + return (Composite) tabItem.getControl(); + throw new IllegalStateException(); + } + } +}