Introduce fixed entry area.
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 15 Jul 2021 06:26:44 +0000 (08:26 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 15 Jul 2021 06:26:44 +0000 (08:26 +0200)
core/org.argeo.suite.ui/src/org/argeo/suite/ui/DefaultEditionLayer.java
core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteApp.java
core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteLayer.java
core/org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUi.java
core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java

index 68081b4e646d944b9066c855f98cdc941b48f2ff..7004ad01b1ef04e6a9926bf4e7d1aa521bf5fc52 100644 (file)
@@ -11,6 +11,7 @@ import org.argeo.cms.Localized;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.jcr.JcrException;
 import org.argeo.suite.ui.widgets.TabbedArea;
 import org.argeo.util.LangUtils;
 import org.eclipse.swt.SWT;
 import org.argeo.suite.ui.widgets.TabbedArea;
 import org.argeo.util.LangUtils;
 import org.eclipse.swt.SWT;
@@ -24,21 +25,33 @@ import org.osgi.framework.wiring.BundleWiring;
 /** An app layer based on an entry area and an editor area. */
 public class DefaultEditionLayer implements SuiteLayer {
        private CmsUiProvider entryArea;
 /** An app layer based on an entry area and an editor area. */
 public class DefaultEditionLayer implements SuiteLayer {
        private CmsUiProvider entryArea;
+       private CmsUiProvider defaultView;
        private CmsUiProvider workArea;
        private List<String> weights = new ArrayList<>();
        private boolean startMaximized = false;
        private CmsUiProvider workArea;
        private List<String> weights = new ArrayList<>();
        private boolean startMaximized = false;
+       private boolean fixedEntryArea = false;
        private boolean singleTab = false;
        private Localized title = null;
 
        @Override
        public Control createUi(Composite parent, Node context) throws RepositoryException {
        private boolean singleTab = false;
        private Localized title = null;
 
        @Override
        public Control createUi(Composite parent, Node context) throws RepositoryException {
+               // TODO Factorize more, or split into more specialised classes?
                if (entryArea != null) {
                if (entryArea != null) {
-                       SashFormEditionArea sashFormEditionArea = new SashFormEditionArea(parent, parent.getStyle());
-                       entryArea.createUi(sashFormEditionArea.getEntryArea(), context);
-                       if (this.workArea != null) {
-                               this.workArea.createUi(sashFormEditionArea.getEditorArea(), context);
+                       if (fixedEntryArea) {
+                               FixedEditionArea editionArea = new FixedEditionArea(parent, parent.getStyle());
+                               entryArea.createUi(editionArea.getEntryArea(), context);
+                               if (this.defaultView != null) {
+                                       editionArea.getTabbedArea().view(defaultView, context);
+                               }
+                               return editionArea;
+                       } else {
+                               SashFormEditionArea editionArea = new SashFormEditionArea(parent, parent.getStyle());
+                               entryArea.createUi(editionArea.getEntryArea(), context);
+                               if (this.defaultView != null) {
+                                       editionArea.getTabbedArea().view(defaultView, context);
+                               }
+                               return editionArea;
                        }
                        }
-                       return sashFormEditionArea;
                } else {
                        if (this.workArea != null) {
                                Composite area = new Composite(parent, SWT.NONE);
                } else {
                        if (this.workArea != null) {
                                Composite area = new Composite(parent, SWT.NONE);
@@ -52,15 +65,51 @@ public class DefaultEditionLayer implements SuiteLayer {
        }
 
        @Override
        }
 
        @Override
-       public void view(CmsUiProvider uiProvider, Composite workArea, Node context) {
-               TabbedArea tabbedArea;
+       public void view(CmsUiProvider uiProvider, Composite workAreaC, Node context) {
+               if (workArea != null) {
+                       try {
+                               CmsUiUtils.clear(workAreaC);
+                               workArea.createUi(workAreaC, context);
+                               workAreaC.requestLayout();
+                               return;
+                       } catch (RepositoryException e) {
+                               throw new JcrException("Cannot rebuild work area", e);
+                       }
+               }
+               
+               // tabbed area
+               TabbedArea tabbedArea = findTabbedArea(workAreaC);
+               if (tabbedArea == null)
+                       throw new IllegalArgumentException("Unsupported work area " + workAreaC.getClass().getName());
+               if (uiProvider == null) {
+                       // reset
+                       tabbedArea.closeAllTabs();
+                       if (this.defaultView != null) {
+                               tabbedArea.view(defaultView, context);
+                       }
+               } else {
+                       tabbedArea.view(uiProvider, context);
+               }
+       }
+
+       @Override
+       public Node getCurrentContext(Composite workArea) {
+               TabbedArea tabbedArea = findTabbedArea(workArea);
+               if (tabbedArea == null)
+                       return null;
+               return tabbedArea.getCurrentContext();
+       }
+
+       private TabbedArea findTabbedArea(Composite workArea) {
+               TabbedArea tabbedArea = null;
                if (workArea instanceof SashFormEditionArea) {
                        tabbedArea = ((SashFormEditionArea) workArea).getTabbedArea();
                if (workArea instanceof SashFormEditionArea) {
                        tabbedArea = ((SashFormEditionArea) workArea).getTabbedArea();
+               } else if (workArea instanceof FixedEditionArea) {
+                       tabbedArea = ((FixedEditionArea) workArea).getTabbedArea();
                } else if (workArea instanceof TabbedArea) {
                        tabbedArea = (TabbedArea) workArea;
                } else if (workArea instanceof TabbedArea) {
                        tabbedArea = (TabbedArea) workArea;
-               } else
-                       throw new IllegalArgumentException("Unsupported work area " + workArea.getClass().getName());
-               tabbedArea.view(uiProvider, context);
+               }
+               return tabbedArea;
        }
 
        @Override
        }
 
        @Override
@@ -78,6 +127,12 @@ public class DefaultEditionLayer implements SuiteLayer {
                weights = LangUtils.toStringList(properties.get(Property.weights.name()));
                startMaximized = properties.containsKey(Property.startMaximized.name())
                                && "true".equals(properties.get(Property.startMaximized.name()));
                weights = LangUtils.toStringList(properties.get(Property.weights.name()));
                startMaximized = properties.containsKey(Property.startMaximized.name())
                                && "true".equals(properties.get(Property.startMaximized.name()));
+               fixedEntryArea = properties.containsKey(Property.fixedEntryArea.name())
+                               && "true".equals(properties.get(Property.fixedEntryArea.name()));
+               if (fixedEntryArea && weights.size() != 0) {
+                       throw new IllegalArgumentException("Property " + Property.weights.name() + " should not be set if property "
+                                       + Property.fixedEntryArea.name() + " is set.");
+               }
                singleTab = properties.containsKey(Property.singleTab.name())
                                && "true".equals(properties.get(Property.singleTab.name()));
 
                singleTab = properties.containsKey(Property.singleTab.name())
                                && "true".equals(properties.get(Property.singleTab.name()));
 
@@ -116,6 +171,10 @@ public class DefaultEditionLayer implements SuiteLayer {
                this.workArea = workArea;
        }
 
                this.workArea = workArea;
        }
 
+       public void setDefaultView(CmsUiProvider defaultView) {
+               this.defaultView = defaultView;
+       }
+
        TabbedArea createTabbedArea(Composite parent, CmsTheme theme) {
                TabbedArea tabbedArea = new TabbedArea(parent, SWT.NONE);
                tabbedArea.setSingleTab(singleTab);
        TabbedArea createTabbedArea(Composite parent, CmsTheme theme) {
                TabbedArea tabbedArea = new TabbedArea(parent, SWT.NONE);
                tabbedArea.setSingleTab(singleTab);
@@ -127,26 +186,26 @@ public class DefaultEditionLayer implements SuiteLayer {
                return tabbedArea;
        }
 
                return tabbedArea;
        }
 
-       /** A work area based on an entry area and and a tabbed area. */
+//     /** A work area based on an entry area and and a tabbed area. */
        class SashFormEditionArea extends SashForm {
                private static final long serialVersionUID = 2219125778722702618L;
        class SashFormEditionArea extends SashForm {
                private static final long serialVersionUID = 2219125778722702618L;
-               private CmsTheme theme;
-               private Composite entryArea;
-               private Composite editorArea;
                private TabbedArea tabbedArea;
                private TabbedArea tabbedArea;
+               private Composite entryC;
 
                SashFormEditionArea(Composite parent, int style) {
                        super(parent, SWT.HORIZONTAL);
 
                SashFormEditionArea(Composite parent, int style) {
                        super(parent, SWT.HORIZONTAL);
-                       theme = CmsTheme.getCmsTheme(parent);
+                       CmsTheme theme = CmsTheme.getCmsTheme(parent);
 
 
+                       Composite editorC;
                        if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
                        if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
-                               editorArea = new Composite(this, SWT.BORDER);
-                               entryArea = new Composite(this, SWT.BORDER);
+                               editorC = new Composite(this, SWT.BORDER);
+                               entryC = new Composite(this, SWT.BORDER);
                        } else {
                        } else {
-                               entryArea = new Composite(this, SWT.NONE);
-                               editorArea = new Composite(this, SWT.NONE);
+                               entryC = new Composite(this, SWT.NONE);
+                               editorC = new Composite(this, SWT.NONE);
                        }
 
                        }
 
+                       // sash form specific
                        if (weights.size() != 0) {
                                int[] actualWeight = new int[weights.size()];
                                for (int i = 0; i < weights.size(); i++) {
                        if (weights.size() != 0) {
                                int[] actualWeight = new int[weights.size()];
                                for (int i = 0; i < weights.size(); i++) {
@@ -158,30 +217,69 @@ public class DefaultEditionLayer implements SuiteLayer {
                                setWeights(actualWeights);
                        }
                        if (startMaximized)
                                setWeights(actualWeights);
                        }
                        if (startMaximized)
-                               setMaximizedControl(editorArea);
-                       GridLayout editorAreaLayout = new GridLayout();
-                       editorAreaLayout.verticalSpacing = 0;
-                       editorAreaLayout.marginBottom = 0;
-                       editorAreaLayout.marginHeight = 0;
-                       editorArea.setLayout(editorAreaLayout);
-
-                       if (DefaultEditionLayer.this.workArea == null) {
-                               tabbedArea = createTabbedArea(editorArea, theme);
-                       }
+                               setMaximizedControl(editorC);
+
+                       GridLayout editorAreaLayout = CmsUiUtils.noSpaceGridLayout();
+//                     editorAreaLayout.verticalSpacing = 0;
+//                     editorAreaLayout.marginBottom = 0;
+//                     editorAreaLayout.marginHeight = 0;
+//                     editorAreaLayout.marginLeft = 0;
+//                     editorAreaLayout.marginRight = 0;
+                       editorC.setLayout(editorAreaLayout);
 
 
+                       tabbedArea = createTabbedArea(editorC, theme);
+               }
+
+               TabbedArea getTabbedArea() {
+                       return tabbedArea;
                }
 
                Composite getEntryArea() {
                }
 
                Composite getEntryArea() {
-                       return entryArea;
+                       return entryC;
+               }
+
+       }
+
+       class FixedEditionArea extends Composite {
+               private static final long serialVersionUID = -5525672639277322465L;
+               private TabbedArea tabbedArea;
+               private Composite entryC;
+
+               public FixedEditionArea(Composite parent, int style) {
+                       super(parent, style);
+                       CmsTheme theme = CmsTheme.getCmsTheme(parent);
+
+                       setLayout(CmsUiUtils.noSpaceGridLayout(2));
+
+                       Composite editorC;
+                       if (SWT.RIGHT_TO_LEFT == (style & SWT.RIGHT_TO_LEFT)) {// arabic, hebrew, etc.
+                               editorC = new Composite(this, SWT.NONE);
+                               entryC = new Composite(this, SWT.NONE);
+                       } else {
+                               entryC = new Composite(this, SWT.NONE);
+                               editorC = new Composite(this, SWT.NONE);
+                       }
+                       entryC.setLayoutData(CmsUiUtils.fillHeight());
+
+                       GridLayout editorAreaLayout = CmsUiUtils.noSpaceGridLayout();
+//                     editorAreaLayout.verticalSpacing = 0;
+//                     editorAreaLayout.marginBottom = 0;
+//                     editorAreaLayout.marginHeight = 0;
+//                     editorAreaLayout.marginLeft = 0;
+//                     editorAreaLayout.marginRight = 0;
+                       editorC.setLayout(editorAreaLayout);
+                       editorC.setLayoutData(CmsUiUtils.fillAll());
+
+                       tabbedArea = createTabbedArea(editorC, theme);
                }
 
                TabbedArea getTabbedArea() {
                        return tabbedArea;
                }
 
                }
 
                TabbedArea getTabbedArea() {
                        return tabbedArea;
                }
 
-               Composite getEditorArea() {
-                       return editorArea;
+               Composite getEntryArea() {
+                       return entryC;
                }
                }
-
        }
        }
+
 }
\ No newline at end of file
 }
\ No newline at end of file
index bdcf30c87101e488b6654ac1fec9172843c69374..dabd8afbce15714807fc6db7e477c88a39c112c0 100644 (file)
@@ -57,6 +57,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
        public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId";
        public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer";
        private final static String LOGIN = "login";
        public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId";
        public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer";
        private final static String LOGIN = "login";
+       private final static String HOME_STATE = "~";
 
        private String publicBasePath = null;
 
 
        private String publicBasePath = null;
 
@@ -335,7 +336,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                if (!state.startsWith("/")) {
                        if (parent instanceof SuiteUi) {
                                SuiteUi ui = (SuiteUi) parent;
                if (!state.startsWith("/")) {
                        if (parent instanceof SuiteUi) {
                                SuiteUi ui = (SuiteUi) parent;
-                               if (LOGIN.equals(state) || state.equals("~")) {
+                               if (LOGIN.equals(state) || state.equals(HOME_STATE)) {
                                        String appTitle = "";
                                        if (ui.getTitle() != null)
                                                appTitle = ui.getTitle().lead();
                                        String appTitle = "";
                                        if (ui.getTitle() != null)
                                                appTitle = ui.getTitle().lead();
@@ -343,20 +344,21 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                                        return;
                                }
                                String currentLayerId = ui.getCurrentLayerId();
                                        return;
                                }
                                String currentLayerId = ui.getCurrentLayerId();
-                               if (state.equals(currentLayerId))
-                                       return; // does nothing
-                               else {
-                                       Map<String, Object> properties = new HashMap<>();
-                                       properties.put(SuiteEvent.LAYER, state);
-                                       ui.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), properties);
-                               }
+//                             if (state.equals(currentLayerId))
+//                                     return; // does nothing
+//                             else {
+                               Map<String, Object> properties = new HashMap<>();
+                               properties.put(SuiteEvent.LAYER, state);
+                               properties.put(SuiteEvent.NODE_PATH, HOME_STATE);
+                               ui.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), properties);
+//                             }
                        }
                        return;
                }
                SuiteUi suiteUi = (SuiteUi) parent;
                Node node = stateToNode(suiteUi, state);
                if (node == null) {
                        }
                        return;
                }
                SuiteUi suiteUi = (SuiteUi) parent;
                Node node = stateToNode(suiteUi, state);
                if (node == null) {
-                       suiteUi.getCmsView().navigateTo("~");
+                       suiteUi.getCmsView().navigateTo(HOME_STATE);
                } else {
                        suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
                        suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
                } else {
                        suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
                        suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
@@ -441,11 +443,27 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 //                                     ui.switchToLayer(layerId, ui.getUserDir());
                                        SuiteLayer suiteLayer = findLayer(layerId);
                                        Localized layerTitle = suiteLayer.getTitle();
 //                                     ui.switchToLayer(layerId, ui.getUserDir());
                                        SuiteLayer suiteLayer = findLayer(layerId);
                                        Localized layerTitle = suiteLayer.getTitle();
-                                       ui.getCmsView().runAs(() -> ui.switchToLayer(layerId, ui.getUserDir()));
+                                       // FIXME make sure we don't rebuild the work area twice
+                                       Composite workArea = ui.getCmsView().doAs(() -> ui.switchToLayer(layerId, ui.getUserDir()));
                                        String title = null;
                                        if (layerTitle != null)
                                                title = layerTitle.lead();
                                        String title = null;
                                        if (layerTitle != null)
                                                title = layerTitle.lead();
-                                       ui.getCmsView().stateChanged(layerId, appTitle + title);
+                                       Node nodeFromState = getNode(ui, event);
+                                       if (nodeFromState != null && nodeFromState.getPath().equals(ui.getUserDir().getPath())) {
+                                               // default layer view is forced
+                                               ui.getCmsView().stateChanged(layerId, appTitle + title);
+                                               suiteLayer.view(null, workArea, nodeFromState);
+                                       } else {
+                                               Node layerCurrentContext = suiteLayer.getCurrentContext(workArea);
+                                               if (layerCurrentContext != null) {
+                                                       // layer was already showing a context so we set the state to it
+                                                       ui.getCmsView().stateChanged(nodeToState(layerCurrentContext),
+                                                                       appTitle + Jcr.getTitle(layerCurrentContext));
+                                               } else {
+                                                       // no context was shown
+                                                       ui.getCmsView().stateChanged(layerId, appTitle + title);
+                                               }
+                                       }
                                } else {
                                        Node node = getNode(ui, event);
                                        if (node != null) {
                                } else {
                                        Node node = getNode(ui, event);
                                        if (node != null) {
@@ -463,6 +481,8 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 
        private Node getNode(SuiteUi ui, Event event) {
                String nodePath = get(event, SuiteEvent.NODE_PATH);
 
        private Node getNode(SuiteUi ui, Event event) {
                String nodePath = get(event, SuiteEvent.NODE_PATH);
+               if (nodePath != null && nodePath.equals(HOME_STATE))
+                       return ui.getUserDir();
                String workspaceName = get(event, SuiteEvent.WORKSPACE);
                Session session = ui.getSession(workspaceName);
                Node node;
                String workspaceName = get(event, SuiteEvent.WORKSPACE);
                Session session = ui.getSession(workspaceName);
                Node node;
index c0816627917e536d43832795eb8a4a9c24c9ab72..d18192f0260809385f3df24e6b68244fb6488f36 100644 (file)
@@ -9,10 +9,12 @@ import org.eclipse.swt.widgets.Composite;
 /** An UI layer for the main work area. */
 public interface SuiteLayer extends CmsUiProvider {
        static enum Property {
 /** An UI layer for the main work area. */
 public interface SuiteLayer extends CmsUiProvider {
        static enum Property {
-               title, icon, weights, startMaximized, singleTab;
+               title, icon, weights, startMaximized, singleTab, fixedEntryArea;
        }
 
        void view(CmsUiProvider uiProvider, Composite workArea, Node context);
        }
 
        void view(CmsUiProvider uiProvider, Composite workArea, Node context);
+       
+       Node getCurrentContext(Composite workArea);
 
        default void open(CmsUiProvider uiProvider, Composite workArea, Node context) {
                view(uiProvider, workArea, context);
 
        default void open(CmsUiProvider uiProvider, Composite workArea, Node context) {
                view(uiProvider, workArea, context);
index ca2d9c38378321042e3997468a40bf431a3f8060..c29ff596221ee2d5eacb8dd7f8ec8a299bbf6963 100644 (file)
@@ -149,6 +149,7 @@ class SuiteUi extends Composite {
                }
                throw new IllegalArgumentException("Layer is not registered.");
        }
                }
                throw new IllegalArgumentException("Layer is not registered.");
        }
+       
 
        void addLayer(String id, SuiteLayer layer) {
                layers.put(id, layer);
 
        void addLayer(String id, SuiteLayer layer) {
                layers.put(id, layer);
index 8ce5fedb736249fd9581c885f6d740bc224641b8..c281904e989d8d4b8b67b47f4c6ce4cb99b0a468 100644 (file)
@@ -45,7 +45,7 @@ public class TabbedArea extends Composite {
        private boolean singleTab = false;
 
        public TabbedArea(Composite parent, int style) {
        private boolean singleTab = false;
 
        public TabbedArea(Composite parent, int style) {
-               super(parent, style);
+               super(parent, SWT.NONE);
                CmsUiUtils.style(parent, bodyStyle);
 
                setLayout(CmsUiUtils.noSpaceGridLayout());
                CmsUiUtils.style(parent, bodyStyle);
 
                setLayout(CmsUiUtils.noSpaceGridLayout());
@@ -200,6 +200,16 @@ public class TabbedArea extends Composite {
                refreshTabHeaders();
                showTab(nextIndex);
        }
                refreshTabHeaders();
                showTab(nextIndex);
        }
+       
+       public void closeAllTabs() {
+               for(Section section:sections) {
+                       section.dispose();                      
+               }
+               sections.clear();
+               emptyState();
+               refreshTabHeaders();
+               layout(true, true);
+       }
 
        protected void emptyState() {
                new Section(body, SWT.NONE, null);
 
        protected void emptyState() {
                new Section(body, SWT.NONE, null);
@@ -214,6 +224,15 @@ public class TabbedArea extends Composite {
                return (Section) stackLayout.topControl;
        }
 
                return (Section) stackLayout.topControl;
        }
 
+       public Node getCurrentContext() {
+               Section section = getCurrentSection();
+               if (section != null) {
+                       return section.getNode();
+               } else {
+                       return null;
+               }
+       }
+
        public void setTabStyle(String tabStyle) {
                this.tabStyle = tabStyle;
        }
        public void setTabStyle(String tabStyle) {
                this.tabStyle = tabStyle;
        }