From: Mathieu Baudier Date: Sun, 19 Apr 2020 05:46:24 +0000 (+0200) Subject: First working mini desktop manager. X-Git-Tag: argeo-slc-2.1.17~41 X-Git-Url: http://git.argeo.org/?a=commitdiff_plain;h=af32dbee6269d2d1ff7516c61aca7bb5fb6d7d35;p=gpl%2Fargeo-slc.git First working mini desktop manager. --- diff --git a/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/CmsDesktopManager.java b/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/CmsDesktopManager.java deleted file mode 100644 index 737fdef0c..000000000 --- a/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/CmsDesktopManager.java +++ /dev/null @@ -1,132 +0,0 @@ -package org.argeo.cms.desktop; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -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.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.ToolBar; -import org.eclipse.swt.widgets.ToolItem; - -public class CmsDesktopManager { - private Display display; - - private Shell rootShell; - private Shell toolBarShell; - - 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.setMaximized(true); - rootShell.setFullScreen(true); - Rectangle bounds = display.getBounds(); - - rootShell.setSize(bounds.width, bounds.height); -// Point realSize = rootShell.getSize(); -// rootShell.setBounds(bounds); -// Rectangle realBounds = rootShell.getBounds(); - } else { - rootShell = new Shell(display, SWT.SHELL_TRIM); - Rectangle shellArea = rootShell.computeTrim(200, 200, 800, 480); - rootShell.setSize(shellArea.width, shellArea.height); - } - - rootShell.setLayout(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)); - } - - Composite backgroundArea = new Composite(rootShell, SWT.NONE); - backgroundArea.setLayout(new GridLayout(6, true)); - DesktopLayer desktopLayer = new DesktopLayer(); - desktopLayer.init(backgroundArea); - rootShell.open(); - // rootShell.layout(true, true); - - if (toolBarShell != null) { - toolBarShell.setLocation(new Point(0, 0)); - toolBarShell.open(); - } - } - - protected void createDock(ToolBar toolBar) { - - // toolBar.setLocation(clientArea.x, clientArea.y); - - ToolItem closeI = new ToolItem(toolBar, SWT.PUSH); - closeI.setImage(display.getSystemImage(SWT.ICON_ERROR)); - closeI.setToolTipText("Close"); - closeI.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - rootShell.dispose(); - } - - }); - - ToolItem searchI = new ToolItem(toolBar, SWT.PUSH); - searchI.setImage(display.getSystemImage(SWT.ICON_QUESTION)); - searchI.setToolTipText("Search"); - searchI.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - // rootShell.dispose(); - } - - }); - // toolBar.setSize(48, toolBar.getSize().y); - toolBar.pack(); - } - - public void run() { - while (!rootShell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - } - - public void dispose() { - if (!rootShell.isDisposed()) - rootShell.dispose(); - } - - protected boolean isFullScreen() { - return true; - } - - public static void main(String[] args) { - CmsDesktopManager desktopManager = new CmsDesktopManager(); - desktopManager.init(); - // Runtime.getRuntime().addShutdownHook(new Thread(() -> - // desktopManager.dispose(), "Dispose desktop manager")); - desktopManager.run(); - desktopManager.dispose(); - } - -} diff --git a/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/DesktopLayer.java b/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/DesktopLayer.java deleted file mode 100644 index 0565e7320..000000000 --- a/rcp/org.argeo.cms.desktop/src/org/argeo/cms/desktop/DesktopLayer.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.argeo.cms.desktop; - -import java.io.IOException; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.apache.commons.io.FilenameUtils; -import org.eclipse.swt.SWT; -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.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.program.Program; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; - -public class DesktopLayer { - // TODO make it configurable - private Path desktopDir = Paths.get(System.getProperty("user.home"), "tmp"); - - public void init(Composite parentShell) { -// Decorations shell = new Decorations(parentShell, SWT.CLOSE); -// shell.setLayoutData(new GridData(GridData.FILL_BOTH)); - createUi(parentShell, desktopDir); - // shell.open(); - } - - public Control createUi(Composite parent, Path context) { - // parent.setLayout(new FillLayout()); - try { - DirectoryStream ds = Files.newDirectoryStream(context); - ds.forEach((path) -> createIcon(parent, path)); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return parent; - - } - - protected void createIcon(Composite parent, Path path) { - String ext = FilenameUtils.getExtension(path.getFileName().toString()); - Program program = Program.findProgram(ext); - if (program == null) { - createDefaultIcon(parent, path); - return; - } - - Display display = parent.getDisplay(); - ImageData iconData = program.getImageData(); - - Image iconImage; - if (iconData == null) { - iconImage = display.getSystemImage(SWT.ICON_INFORMATION); - iconData = iconImage.getImageData(); - } else { - iconImage = new Image(display, iconData); - } - - Composite icon = new Composite(parent, SWT.NONE); - icon.setLayoutData(new GridData(48, 72)); - icon.setLayout(new GridLayout()); - // Button - Button iconB = new Button(icon, SWT.FLAT); - iconB.setImage(iconImage); - // iconB.setLayoutData(new GridData(iconData.width, iconData.height)); - iconB.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - iconB.addSelectionListener(new SelectionAdapter() { - - @Override - public void widgetSelected(SelectionEvent e) { - program.execute(path.toString()); - } - - }); - // Label - Label iconL = new Label(icon, SWT.WRAP); - iconL.setText(path.getFileName().toString()); - iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); - } - - protected void createDefaultIcon(Composite parent, Path path) { - Composite icon = new Composite(parent, SWT.NONE); - icon.setLayout(new GridLayout()); - Label iconL = new Label(icon, SWT.NONE); - iconL.setText(path.getFileName().toString()); - iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); - } -} diff --git a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniBrowser.java b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniBrowser.java index 4b41207fc..d0ac4ee36 100644 --- a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniBrowser.java +++ b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniBrowser.java @@ -1,8 +1,5 @@ package org.argeo.swt.desktop; -import java.util.Observable; -import java.util.function.BiFunction; - import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.LocationAdapter; @@ -20,99 +17,87 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; /** A minimalistic web browser based on {@link Browser}. */ -public class MiniBrowser implements BiFunction { - @Override - public Control apply(Composite parent, MiniBrowser.Context context) { - parent.setLayout(new GridLayout()); - Control toolBar = createToolBar(parent, context); +public class MiniBrowser { + private Browser browser; + private Text addressT; + + public MiniBrowser(Composite composite, String url) { + createUi(composite); + setUrl(url); + } + + public Control createUi(Composite parent) { + parent.setLayout(noSpaceGridLayout(new GridLayout())); + Control toolBar = createToolBar(parent); toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - Control body = createBody(parent, context); + Control body = createBody(parent); body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); return body; } - public Control createToolBar(Composite parent, MiniBrowser.Context context) { + public Control createToolBar(Composite parent) { Composite toolBar = new Composite(parent, SWT.NONE); toolBar.setLayout(new FillLayout()); - Text addressT = new Text(toolBar, SWT.SINGLE | SWT.BORDER); + addressT = new Text(toolBar, SWT.SINGLE); addressT.addSelectionListener(new SelectionAdapter() { @Override public void widgetDefaultSelected(SelectionEvent e) { - String url = addressT.getText().trim(); - context.setUrl(url); + setUrl(addressT.getText().trim()); } }); - context.addObserver((o, v) -> addressT.setText(((Context) o).getUrl().toString())); return toolBar; } - public Control createBody(Composite parent, MiniBrowser.Context context) { - Browser browser = new Browser(parent, SWT.NONE); + public Control createBody(Composite parent) { + browser = new Browser(parent, SWT.NONE); browser.addLocationListener(new LocationAdapter() { - @Override - public void changing(LocationEvent event) { -// if (event.top && !context.getUrl().equals(event.location)) -// context.setUrl(event.location); - } - @Override public void changed(LocationEvent event) { - if (event.top && !context.getUrl().equals(event.location)) - context.setUrl(event.location); + addressT.setText(event.location); } }); - browser.addTitleListener(e -> context.setTitle(e.title)); - context.addObserver((o, v) -> { - String url = ((Context) o).getUrl(); - if (url != null && !url.equals(browser.getUrl())) - browser.setUrl(url.toString()); - }); + browser.addTitleListener(e -> titleChanged(e.title)); return browser; } - /** The observable context of this web browser. */ - public static class Context extends Observable { - private String url; - private String title = ""; - - public void setUrl(String url) { - this.url = url; - System.out.println(url); - setChanged(); - notifyObservers(url); - } - - public String getUrl() { - return url; - } + void setUrl(String url) { + if (browser != null && url != null && !url.equals(browser.getUrl())) + browser.setUrl(url.toString()); + } - public String getTitle() { - return title; - } + /** Called when URL changed; to be overridden, does nothing by default. */ + protected void urlChanged(String url) { + } - public void setTitle(String title) { - this.title = title; - setChanged(); - notifyObservers(title); - } + /** Called when title changed; to be overridden, does nothing by default. */ + protected void titleChanged(String title) { + } + 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) { Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent(); Shell shell = new Shell(display, SWT.SHELL_TRIM); - MiniBrowser miniBrowser = new MiniBrowser(); - MiniBrowser.Context context = new MiniBrowser.Context(); - miniBrowser.apply(shell, context); - context.addObserver((o, v) -> shell.setText(((Context) o).getTitle())); - String url = args.length > 0 ? args[0] : "http://www.argeo.org"; - context.setUrl(url); + String url = args.length > 0 ? args[0] : "https://duckduckgo.com/"; + new MiniBrowser(shell, url) { + @Override + protected void titleChanged(String title) { + shell.setText(title); + } + }; shell.open(); shell.setSize(new Point(800, 480)); + while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); diff --git a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopLayer.java b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopLayer.java new file mode 100644 index 000000000..f53e6a3c7 --- /dev/null +++ b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopLayer.java @@ -0,0 +1,83 @@ +package org.argeo.swt.desktop; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.swt.SWT; +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.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; + +/** Implementation of an active desktop with icons. */ +public class MiniDesktopLayer { + public void init(Composite parent, Path context) { + parent.setLayout(new RowLayout()); + try { + DirectoryStream ds = Files.newDirectoryStream(context); + ds.forEach((path) -> createIcon(parent, path)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void createIcon(Composite parent, Path path) { + String fileName = path.getFileName().toString(); + String ext = fileName.substring(fileName.lastIndexOf('.') + 1); + Program program = Program.findProgram(ext); + if (program == null) { + createDefaultIcon(parent, path); + return; + } + + Display display = parent.getDisplay(); + ImageData iconData = program.getImageData(); + + Image iconImage; + if (iconData == null) { + iconImage = null; + } else { + iconImage = new Image(display, iconData); + } + + Composite icon = new Composite(parent, SWT.BORDER); + icon.setLayoutData(new RowData(48, 72)); + icon.setLayout(new GridLayout()); + // Button + Button iconB = new Button(icon, SWT.FLAT); + iconB.setImage(iconImage); + // iconB.setLayoutData(new GridData(iconData.width, iconData.height)); + iconB.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); + iconB.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + program.execute(path.toString()); + } + + }); + // Label + Label iconL = new Label(icon, SWT.WRAP); + iconL.setText(path.getFileName().toString()); + iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); + } + + protected void createDefaultIcon(Composite parent, Path path) { + Composite icon = new Composite(parent, SWT.NONE); + icon.setLayout(new GridLayout()); + Label iconL = new Label(icon, SWT.NONE); + iconL.setText(path.getFileName().toString()); + iconL.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + } +} diff --git a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopManager.java b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopManager.java new file mode 100644 index 000000000..0973f70a5 --- /dev/null +++ b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniDesktopManager.java @@ -0,0 +1,313 @@ +package org.argeo.swt.desktop; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.file.Path; +import java.nio.file.Paths; +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) { + @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) { + MiniDesktopLayer desktopLayer = new MiniDesktopLayer(); + desktopLayer.init(backgroundArea, Paths.get(System.getProperty("user.dir"))); + } + + 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(); + } + } +} diff --git a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniExplorer.java b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniExplorer.java index b88dbff31..6f6a782fb 100644 --- a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniExplorer.java +++ b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniExplorer.java @@ -24,20 +24,24 @@ import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; public class MiniExplorer { - private Path url; + private Path path; private Text addressT; private Table browser; private boolean showHidden = false; - public MiniExplorer(Composite parent, int style) { - parent.setLayout(new GridLayout()); + public MiniExplorer(Composite parent, String url) { + this(parent); + setUrl(url); + } + + public MiniExplorer(Composite parent) { + parent.setLayout(noSpaceGridLayout(new GridLayout())); Composite toolBar = new Composite(parent, SWT.NONE); toolBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); toolBar.setLayout(new FillLayout()); - addressT = new Text(toolBar, SWT.SINGLE | SWT.BORDER); - // addressT.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + addressT = new Text(toolBar, SWT.SINGLE); addressT.addSelectionListener(new SelectionAdapter() { @Override @@ -45,20 +49,25 @@ public class MiniExplorer { setUrl(addressT.getText().trim()); } }); - browser = createTable(parent, this.url); + browser = createTable(parent, this.path); } - public void setUrl(Path url) { - this.url = url; + public void setPath(Path url) { + this.path = url; if (addressT != null) addressT.setText(url.toString()); if (browser != null) { Composite parent = browser.getParent(); browser.dispose(); - browser = createTable(parent, this.url); + browser = createTable(parent, this.path); parent.layout(true, true); } + pathChanged(url); + } + + protected void pathChanged(Path path) { + } protected Table createTable(Composite parent, Path path) { @@ -72,7 +81,7 @@ public class MiniExplorer { TableItem item = table.getItem(pt); Path path = (Path) item.getData(); if (Files.isDirectory(path)) { - setUrl(path); + setPath(path); } else { Program.launch(path.toString()); } @@ -88,14 +97,14 @@ public class MiniExplorer { try { // directories - DirectoryStream ds = Files.newDirectoryStream(url, p -> Files.isDirectory(p) && isShown(p)); + DirectoryStream ds = Files.newDirectoryStream(path, p -> Files.isDirectory(p) && isShown(p)); ds.forEach(p -> { TableItem ti = new TableItem(table, SWT.NONE); ti.setText(p.getFileName().toString() + "/"); ti.setData(p); }); // files - ds = Files.newDirectoryStream(url, p -> !Files.isDirectory(p) && isShown(p)); + ds = Files.newDirectoryStream(path, p -> !Files.isDirectory(p) && isShown(p)); ds.forEach(p -> { TableItem ti = new TableItem(table, SWT.NONE); ti.setText(p.getFileName().toString()); @@ -120,16 +129,30 @@ public class MiniExplorer { } public void setUrl(String url) { - setUrl(Paths.get(url)); + setPath(Paths.get(url)); + } + + 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) { Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent(); Shell shell = new Shell(display, SWT.SHELL_TRIM); - MiniExplorer miniBrowser = new MiniExplorer(shell, SWT.NONE); String url = args.length > 0 ? args[0] : System.getProperty("user.home"); - miniBrowser.setUrl(url); + new MiniExplorer(shell, url) { + + @Override + protected void pathChanged(Path path) { + shell.setText(path.toString()); + } + + }; shell.open(); shell.setSize(new Point(800, 480)); diff --git a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniTerminal.java b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniTerminal.java index cacf55aaa..0c43e3bf0 100644 --- a/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniTerminal.java +++ b/rcp/org.argeo.eclipse.ui.rcp/src/org/argeo/swt/desktop/MiniTerminal.java @@ -61,7 +61,12 @@ public class MiniTerminal implements KeyListener, PaintListener { private Thread readOut; - public MiniTerminal(Composite parent, int style) { + public MiniTerminal(Composite parent, String url) { + this(parent); + setPath(url); + } + + public MiniTerminal(Composite parent) { charset = StandardCharsets.UTF_8; Display display = parent.getDisplay(); @@ -199,7 +204,7 @@ public class MiniTerminal implements KeyListener, PaintListener { // exit else if (args.get(0).equals("exit")) { println("logout"); - area.getShell().dispose(); + exitCalled(); return; } @@ -210,7 +215,7 @@ public class MiniTerminal implements KeyListener, PaintListener { process = pb.start(); stdIn = process.getOutputStream(); - readOut = new Thread("MinitTerminal read out") { + readOut = new Thread("MiniTerminal read out") { @Override public void run() { running = true; @@ -300,6 +305,10 @@ public class MiniTerminal implements KeyListener, PaintListener { // area.setCaret(caret); } + protected void exitCalled() { + + } + public void setPath(String path) { this.currentDir = Paths.get(path); } @@ -312,9 +321,15 @@ public class MiniTerminal implements KeyListener, PaintListener { Display display = Display.getCurrent() == null ? new Display() : Display.getCurrent(); Shell shell = new Shell(display, SWT.SHELL_TRIM); - MiniTerminal miniBrowser = new MiniTerminal(shell, SWT.NONE); String url = args.length > 0 ? args[0] : System.getProperty("user.home"); - miniBrowser.setPath(url); + new MiniTerminal(shell, url) { + + @Override + protected void exitCalled() { + shell.dispose(); + System.exit(0); + } + }; shell.open(); shell.setSize(new Point(800, 480));