Multi-layers and events.
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 8 Oct 2020 08:25:56 +0000 (10:25 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 8 Oct 2020 08:25:56 +0000 (10:25 +0200)
org.argeo.suite.ui.rap/OSGI-INF/cmsWebApp.xml
org.argeo.suite.ui/OSGI-INF/cmsApp.xml
org.argeo.suite.ui/OSGI-INF/leadPane.xml
org.argeo.suite.ui/config/cmsApp.properties
org.argeo.suite.ui/src/org/argeo/suite/ui/ArgeoSuiteApp.java
org.argeo.suite.ui/src/org/argeo/suite/ui/ArgeoSuiteUi.java
org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultLeadPane.java
org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java [new file with mode: 0644]

index 1d13e203d15c596e6a210793b9d4354bd5fb055d..4dfdcff3a3946705b87a762044e589c912cd414d 100644 (file)
@@ -2,5 +2,6 @@
 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="init" deactivate="destroy" name="Argeo Suite Web App">
    <implementation class="org.argeo.cms.web.CmsWebApp"/>
    <property name="contextName" type="String" value="argeo"/>
-   <reference bind="setCmsApp" cardinality="1..1" interface="org.argeo.cms.ui.CmsApp" name="CmsApp" policy="dynamic" target="(contextName=argeo)" unbind="unsetCmsApp"/>
+   <reference bind="setCmsApp" cardinality="1..1" interface="org.argeo.cms.ui.CmsApp" name="CmsApp" policy="dynamic" target="(service.pid=argeo.suite.ui.app)" unbind="unsetCmsApp"/>
+   <reference bind="setEventAdmin" cardinality="1..1" interface="org.osgi.service.event.EventAdmin" name="EventAdmin" policy="static"/>
 </scr:component>
index 3d77a7d6736385e76d260740442e3cbe10b9db9e..5a26f52d0b488d2856f68349ee12d502e09f5884 100644 (file)
@@ -3,6 +3,7 @@
    <implementation class="org.argeo.suite.ui.ArgeoSuiteApp"/>
    <service>
       <provide interface="org.argeo.cms.ui.CmsApp"/>
+      <provide interface="org.osgi.service.event.EventHandler"/>
    </service>
    <reference bind="addUiProvider" cardinality="0..n" interface="org.argeo.cms.ui.CmsUiProvider" name="CmsUiProvider" policy="dynamic" unbind="removeUiProvider"/>
    <reference bind="addTheme" cardinality="1..n" interface="org.argeo.cms.ui.CmsTheme" name="CmsTheme" policy="dynamic" unbind="removeTheme"/>
index a4b9ca03401fd197af043a5dec5f9bd4d622236f..997c5b36555a3559a4b250c9901f2dea5f428888 100644 (file)
@@ -3,7 +3,7 @@
    <implementation class="org.argeo.suite.ui.DefaultLeadPane"/>
    <service>
       <provide interface="org.argeo.cms.ui.CmsUiProvider"/>
-      <provide interface="org.osgi.service.cm.ManagedService"/>
    </service>
    <properties entry="config/leadPane.properties"/>
+   <reference bind="setEventAdmin" cardinality="1..1" interface="org.osgi.service.event.EventAdmin" name="EventAdmin" policy="static"/>
 </scr:component>
index 641bba6195caad03703fce399a42a49ce5e8f97e..1dec00e2915e6dffec677e1e2010362254023ba1 100644 (file)
@@ -1,2 +1,3 @@
 service.pid=argeo.suite.ui.app
-contextName=argeo
+
+event.topics=argeo/suite/*
\ No newline at end of file
index da86e5b6c336bd13bb3a2693ff8e976407634d87..3f1a8cebbc8bbf4eb1b362e518b58918292854fe 100644 (file)
@@ -1,9 +1,10 @@
 package org.argeo.suite.ui;
 
-import java.util.ArrayList;
+import static org.argeo.cms.ui.CmsView.CMS_VIEW_UID_PROPERTY;
+
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
@@ -25,9 +26,11 @@ import org.argeo.jcr.JcrUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventHandler;
 
 /** The Argeo Suite App. */
-public class ArgeoSuiteApp extends AbstractCmsApp {
+public class ArgeoSuiteApp extends AbstractCmsApp implements EventHandler {
        private final static Log log = LogFactory.getLog(ArgeoSuiteApp.class);
 
        public final static String PID_PREFIX = "argeo.suite.ui.";
@@ -43,7 +46,7 @@ public class ArgeoSuiteApp extends AbstractCmsApp {
        private SortedMap<RankingKey, CmsUiProvider> uiProviders = Collections.synchronizedSortedMap(new TreeMap<>());
 
        // TODO make more optimal or via CmsSession/CmsView
-       private List<ArgeoSuiteUi> knownUis = new ArrayList<>();
+       private Map<String, ArgeoSuiteUi> managedUis = new HashMap<>();
 
 //     private CmsUiProvider headerPart = null;
 
@@ -53,7 +56,7 @@ public class ArgeoSuiteApp extends AbstractCmsApp {
        }
 
        public void destroy(Map<String, String> properties) {
-               for (ArgeoSuiteUi ui : knownUis)
+               for (ArgeoSuiteUi ui : managedUis.values())
                        if (!ui.isDisposed())
                                ui.dispose();
                if (log.isDebugEnabled())
@@ -71,11 +74,18 @@ public class ArgeoSuiteApp extends AbstractCmsApp {
        @Override
        public Composite initUi(Composite parent) {
                String uiName = parent.getData(UI_NAME_PROPERTY) != null ? parent.getData(UI_NAME_PROPERTY).toString() : null;
+               CmsView cmsView = CmsView.getCmsView(parent);
                CmsTheme theme = getTheme(uiName);
                if (theme != null)
                        CmsTheme.registerCmsTheme(parent.getShell(), theme);
                ArgeoSuiteUi argeoSuiteUi = new ArgeoSuiteUi(parent, SWT.NONE);
-               knownUis.add(argeoSuiteUi);
+               String uid = cmsView.getUid();
+               managedUis.put(uid, argeoSuiteUi);
+               argeoSuiteUi.addDisposeListener((e) -> {
+                       managedUis.remove(uid);
+                       if (log.isDebugEnabled())
+                               log.debug("Suite UI " + uid + " has been disposed.");
+               });
                refreshUi(argeoSuiteUi, null);
                return argeoSuiteUi;
        }
@@ -215,6 +225,23 @@ public class ArgeoSuiteApp extends AbstractCmsApp {
 
        }
 
+       @Override
+       public void handleEvent(Event event) {
+               if (event.getTopic().equals(SuiteEvent.switchLayer.topic())) {
+                       String layer = get(event, SuiteEvent.LAYER_PARAM);
+                       managedUis.get(get(event, CMS_VIEW_UID_PROPERTY)).switchToLayer(layer);
+               }
+
+       }
+
+       private static String get(Event event, String key) {
+               Object value = event.getProperty(key);
+               if (value == null)
+                       throw new IllegalArgumentException("Property " + key + " must be set");
+               return value.toString();
+
+       }
+
 //     public void setHeaderPart(CmsUiProvider headerPart) {
 //             this.headerPart = headerPart;
 //             if (log.isDebugEnabled())
index 73dc2f4e4be0d2eeaf6485d5ba720cd7bd475da6..e30360c092dbb3d21c565f2227eae6f6a6648183 100644 (file)
@@ -2,6 +2,9 @@ package org.argeo.suite.ui;
 
 import static org.argeo.suite.ui.SuiteIcon.dashboard;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.jcr.Session;
 
 import org.argeo.cms.ui.CmsTheme;
@@ -11,6 +14,7 @@ import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.CTabFolder;
 import org.eclipse.swt.custom.CTabItem;
 import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.layout.FormLayout;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
@@ -24,18 +28,15 @@ public class ArgeoSuiteUi extends Composite {
        private Composite header;
        private Composite belowHeader;
        private Composite leadPane;
-
-       private SashForm dynamicArea;
-       private Composite entryArea;
-       private Composite editorArea;
-       private CTabFolder editorTabFolder;
-
-       private Composite defaultBody;
+       private Composite dynamicArea;
 
        private CmsTheme theme;
-       
+
        private Session session;
 
+       private Map<String, WorkLayer> layers = new HashMap<>();
+       private String currentLayer = "dashboard";
+
        public ArgeoSuiteUi(Composite parent, int style) {
                super(parent, style);
                theme = CmsTheme.getCmsTheme(parent);
@@ -50,48 +51,42 @@ public class ArgeoSuiteUi extends Composite {
                belowHeader.setLayout(CmsUiUtils.noSpaceGridLayout(2));
 
                if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
-                       dynamicArea = new SashForm(belowHeader, SWT.HORIZONTAL);
+                       dynamicArea = new Composite(belowHeader, SWT.NONE);
                        leadPane = new Composite(belowHeader, SWT.NONE);
                } else {
                        leadPane = new Composite(belowHeader, SWT.NONE);
-                       dynamicArea = new SashForm(belowHeader, SWT.HORIZONTAL);
+                       dynamicArea = new Composite(belowHeader, SWT.NONE);
                }
                leadPane.setLayoutData(CmsUiUtils.fillHeight());
                CmsUiUtils.style(leadPane, SuiteStyle.leadPane);
                dynamicArea.setLayoutData(CmsUiUtils.fillAll());
 
-               if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
-                       editorArea = new Composite(dynamicArea, SWT.BORDER);
-                       entryArea = new Composite(dynamicArea, SWT.BORDER);
-               } else {
-                       entryArea = new Composite(dynamicArea, SWT.NONE);
-                       editorArea = new Composite(dynamicArea, SWT.NONE);
-               }
-               int[] weights = new int[] { 2000, 8000 };
-               dynamicArea.setWeights(weights);
-               editorArea.setLayout(new GridLayout());
-
-               editorTabFolder = new CTabFolder(editorArea, SWT.NONE);
-               editorTabFolder.setLayoutData(CmsUiUtils.fillAll());
-
-               // TODO make it dynamic
-               Composite buttons = new Composite(editorTabFolder, SWT.NONE);
-               buttons.setLayout(CmsUiUtils.noSpaceGridLayout());
-               ToolBar toolBar = new ToolBar(buttons, SWT.NONE);
-               toolBar.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
-               ToolItem deleteItem = new ToolItem(toolBar, SWT.PUSH);
-               deleteItem.setImage(SuiteIcon.delete.getSmallIcon(theme));
-               deleteItem.setEnabled(false);
-               editorTabFolder.setTopRight(buttons);
-
-               CTabItem defaultTab = new CTabItem(editorTabFolder, SWT.NONE);
-               // defaultTab.setText("Home");
-               defaultTab.setImage(dashboard.getSmallIcon(theme));
-               defaultBody = new Composite(editorTabFolder, SWT.NONE);
-               defaultTab.setControl(defaultBody);
-               editorTabFolder.setSelection(defaultTab);
-
-               // editorArea.setSingle(true);
+               dynamicArea.setLayout(new FormLayout());
+
+               layers.put("dashboard", new WorkLayer(dynamicArea, style));
+               layers.put("documents", new WorkLayer(dynamicArea, style));
+               layers.put("locations", new WorkLayer(dynamicArea, style));
+               layers.put("people", new WorkLayer(dynamicArea, style));
+       }
+
+       Composite getCurrentLayer() {
+               return layers.get(currentLayer).getArea();
+       }
+
+       Composite getLayer(String id) {
+               if (!layers.containsKey(id))
+                       throw new IllegalArgumentException("No layer " + id + " is available.");
+               return layers.get(id).getArea();
+       }
+
+       Composite switchToLayer(String layer) {
+               Composite current = getCurrentLayer();
+               if (currentLayer.equals(layer))
+                       return current;
+               Composite toShow = getLayer(layer);
+               getDisplay().syncExec(() -> toShow.moveAbove(current));
+               currentLayer = layer;
+               return toShow;
        }
 
        /*
@@ -106,24 +101,16 @@ public class ArgeoSuiteUi extends Composite {
                return leadPane;
        }
 
-       SashForm getDynamicArea() {
-               return dynamicArea;
+       Composite getBelowHeader() {
+               return belowHeader;
        }
 
        Composite getEntryArea() {
-               return entryArea;
-       }
-
-       CTabFolder getEditorTabFolder() {
-               return editorTabFolder;
+               return layers.get(currentLayer).getEntryArea();
        }
 
        Composite getDefaultBody() {
-               return defaultBody;
-       }
-
-       Composite getBelowHeader() {
-               return belowHeader;
+               return layers.get(currentLayer).getDefaultBody();
        }
 
        Session getSession() {
@@ -134,5 +121,67 @@ public class ArgeoSuiteUi extends Composite {
                this.session = session;
        }
 
-       
+       class WorkLayer {
+               private SashForm area;
+               private Composite entryArea;
+               private Composite editorArea;
+               private CTabFolder editorTabFolder;
+
+               private Composite defaultBody;
+
+               WorkLayer(Composite parent, int style) {
+                       area = new SashForm(parent, SWT.HORIZONTAL);
+                       area.setLayoutData(CmsUiUtils.coversAll());
+
+                       if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
+                               editorArea = new Composite(area, SWT.BORDER);
+                               entryArea = new Composite(area, SWT.BORDER);
+                       } else {
+                               entryArea = new Composite(area, SWT.NONE);
+                               editorArea = new Composite(area, SWT.NONE);
+                       }
+                       int[] weights = new int[] { 2000, 8000 };
+                       area.setWeights(weights);
+                       editorArea.setLayout(new GridLayout());
+
+                       editorTabFolder = new CTabFolder(editorArea, SWT.NONE);
+                       editorTabFolder.setLayoutData(CmsUiUtils.fillAll());
+
+                       // TODO make it dynamic
+                       Composite buttons = new Composite(editorTabFolder, SWT.NONE);
+                       buttons.setLayout(CmsUiUtils.noSpaceGridLayout());
+                       ToolBar toolBar = new ToolBar(buttons, SWT.NONE);
+                       toolBar.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
+                       ToolItem deleteItem = new ToolItem(toolBar, SWT.PUSH);
+                       deleteItem.setImage(SuiteIcon.delete.getSmallIcon(theme));
+                       deleteItem.setEnabled(false);
+                       editorTabFolder.setTopRight(buttons);
+
+                       CTabItem defaultTab = new CTabItem(editorTabFolder, SWT.NONE);
+                       // defaultTab.setText("Home");
+                       defaultTab.setImage(dashboard.getSmallIcon(theme));
+                       defaultBody = new Composite(editorTabFolder, SWT.NONE);
+                       defaultTab.setControl(defaultBody);
+                       editorTabFolder.setSelection(defaultTab);
+
+               }
+
+               Composite getArea() {
+                       return area;
+               }
+
+               Composite getEntryArea() {
+                       return entryArea;
+               }
+
+               CTabFolder getEditorTabFolder() {
+                       return editorTabFolder;
+               }
+
+               Composite getDefaultBody() {
+                       return defaultBody;
+               }
+
+       }
+
 }
index cbc0a7846636223bf9862fc40b941a8dacd15a6d..48e6149d6af6aba132523a1b28e4cacf0356f890 100644 (file)
@@ -1,27 +1,33 @@
 package org.argeo.suite.ui;
 
-import java.util.Dictionary;
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.Localized;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.util.CmsIcon;
 import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.eclipse.ui.Selected;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
 
 /** Side pane listing various perspectives. */
-public class DefaultLeadPane implements CmsUiProvider, ManagedService {
+public class DefaultLeadPane implements CmsUiProvider {
+       private final static Log log = LogFactory.getLog(DefaultLeadPane.class);
+       private EventAdmin eventAdmin;
+
        @Override
        public Control createUi(Composite parent, Node node) throws RepositoryException {
                CmsView cmsView = CmsView.getCmsView(parent);
@@ -32,31 +38,31 @@ public class DefaultLeadPane implements CmsUiProvider, ManagedService {
                layout.marginRight = 10;
                parent.setLayout(layout);
 
-               Button dashboardB = createButton(parent, SuiteMsg.dashboard, SuiteIcon.dashboard);
+               Button dashboardB = createButton(parent, SuiteMsg.dashboard.name(), SuiteMsg.dashboard, SuiteIcon.dashboard);
                if (!cmsView.isAnonymous()) {
-                       createButton(parent, SuiteMsg.documents, SuiteIcon.documents);
-                       createButton(parent, SuiteMsg.people, SuiteIcon.people);
-                       createButton(parent, SuiteMsg.locations, SuiteIcon.location);
+                       createButton(parent, SuiteMsg.documents.name(), SuiteMsg.documents, SuiteIcon.documents);
+                       createButton(parent, SuiteMsg.people.name(), SuiteMsg.people, SuiteIcon.people);
+                       createButton(parent, SuiteMsg.locations.name(), SuiteMsg.locations, SuiteIcon.location);
                }
                return dashboardB;
        }
 
-       protected Button createButton(Composite parent, Localized msg, CmsIcon icon) {
+       protected Button createButton(Composite parent, String layer, Localized msg, CmsIcon icon) {
                CmsTheme theme = CmsTheme.getCmsTheme(parent);
-               Button button = new Button(parent, SWT.FLAT);
+               Button button = new Button(parent, SWT.PUSH);
                CmsUiUtils.style(button, SuiteStyle.leadPane);
                button.setToolTipText(msg.lead());
                button.setImage(icon.getBigIcon(theme));
+               CmsUiUtils.sendEventOnSelect(button, SuiteEvent.switchLayer.topic(), SuiteEvent.LAYER_PARAM, layer);
                return button;
        }
 
-       @Override
-       public void updated(Dictionary<String, ?> properties) throws ConfigurationException {
-               // TODO Auto-generated method stub
+       public void init(Map<String, String> properties) {
 
        }
 
-       public void init(Map<String, String> properties) {
-
+       public void setEventAdmin(EventAdmin eventAdmin) {
+               this.eventAdmin = eventAdmin;
        }
+
 }
diff --git a/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java b/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteEvent.java
new file mode 100644 (file)
index 0000000..7d9bca7
--- /dev/null
@@ -0,0 +1,17 @@
+package org.argeo.suite.ui;
+
+/** Events specific to Argeo Suite. */
+public enum SuiteEvent {
+       switchLayer;
+
+       public final static String LAYER_PARAM = "layer";
+
+       String topic() {
+               return getTopicBase() + "/" + name();
+       }
+
+       String getTopicBase() {
+               return "argeo/suite/ui";
+       }
+
+}