Receive tabbed area from Argeo Commons.
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 7 Feb 2021 10:21:41 +0000 (11:21 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 7 Feb 2021 10:21:41 +0000 (11:21 +0100)
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/SuiteUiUtils.java
core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java [new file with mode: 0644]

index 7b8bb3eb360c7eb4f8d56fb25e8626e96a7998ce..0ab5ab43c1b47c0db39e2ea9a69f5d4bab419077 100644 (file)
@@ -10,7 +10,7 @@ import javax.jcr.RepositoryException;
 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.cms.ui.widgets.TabbedArea;
+import org.argeo.suite.ui.widgets.TabbedArea;
 import org.argeo.util.LangUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.argeo.util.LangUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
index dc8060b3ad6d2bed0f91cf4defcb9eb7422e0f3a..c941a154d351810d5c5990b31e83ab742ced3927 100644 (file)
@@ -30,7 +30,6 @@ import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.dialogs.CmsFeedback;
 import org.argeo.cms.ui.CmsUiProvider;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.dialogs.CmsFeedback;
-import org.argeo.cms.ui.util.CmsEvent;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.specific.UiContext;
 import org.argeo.entity.EntityConstants;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.specific.UiContext;
 import org.argeo.entity.EntityConstants;
@@ -345,7 +344,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                try {
 //                     String currentLayerId = ui.getCurrentLayerId();
 //                     SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
                try {
 //                     String currentLayerId = ui.getCurrentLayerId();
 //                     SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
-                       if (isTopic(event, SuiteEvent.refreshPart)) {
+                       if (SuiteUiUtils.isTopic(event, SuiteEvent.refreshPart)) {
                                Node node = getNode(ui, event);
                                if (node == null)
                                        return;
                                Node node = getNode(ui, event);
                                if (node == null)
                                        return;
@@ -354,7 +353,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                                ui.switchToLayer(layer, node);
                                ui.getCmsView().runAs(() -> layer.view(uiProvider, ui.getCurrentWorkArea(), node));
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
                                ui.switchToLayer(layer, node);
                                ui.getCmsView().runAs(() -> layer.view(uiProvider, ui.getCurrentWorkArea(), node));
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
-                       } else if (isTopic(event, SuiteEvent.openNewPart)) {
+                       } else if (SuiteUiUtils.isTopic(event, SuiteEvent.openNewPart)) {
                                Node node = getNode(ui, event);
                                if (node == null)
                                        return;
                                Node node = getNode(ui, event);
                                if (node == null)
                                        return;
@@ -363,7 +362,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                                ui.switchToLayer(layer, node);
                                ui.getCmsView().runAs(() -> layer.open(uiProvider, ui.getCurrentWorkArea(), node));
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
                                ui.switchToLayer(layer, node);
                                ui.getCmsView().runAs(() -> layer.open(uiProvider, ui.getCurrentWorkArea(), node));
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
-                       } else if (isTopic(event, SuiteEvent.switchLayer)) {
+                       } else if (SuiteUiUtils.isTopic(event, SuiteEvent.switchLayer)) {
                                String layerId = get(event, SuiteEvent.LAYER);
                                if (layerId != null) {
 //                                     ui.switchToLayer(layerId, ui.getUserDir());
                                String layerId = get(event, SuiteEvent.LAYER);
                                if (layerId != null) {
 //                                     ui.switchToLayer(layerId, ui.getUserDir());
@@ -426,11 +425,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                return managedUis.get(get(event, CMS_VIEW_UID_PROPERTY));
        }
 
                return managedUis.get(get(event, CMS_VIEW_UID_PROPERTY));
        }
 
-       private static boolean isTopic(Event event, CmsEvent cmsEvent) {
-               return event.getTopic().equals(cmsEvent.topic());
-       }
-
-       private static String get(Event event, String key) {
+       public static String get(Event event, String key) {
                Object value = event.getProperty(key);
                if (value == null)
                        return null;
                Object value = event.getProperty(key);
                if (value == null)
                        return null;
index 3c47b96a6053a187abb123cbdc95af5bfc1c4305..79edb6416e38ffd7644037b9bbae3b68fce58ea2 100644 (file)
@@ -12,6 +12,7 @@ import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.ui.CmsEditable;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.dialogs.LightweightDialog;
 import org.argeo.cms.ui.CmsEditable;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.dialogs.LightweightDialog;
+import org.argeo.cms.ui.util.CmsEvent;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.entity.EntityNames;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.eclipse.ui.EclipseUiUtils;
 import org.argeo.entity.EntityNames;
@@ -32,6 +33,7 @@ import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Text;
+import org.osgi.service.event.Event;
 
 /** UI utilities related to the APAF project. */
 public class SuiteUiUtils {
 
 /** UI utilities related to the APAF project. */
 public class SuiteUiUtils {
@@ -318,6 +320,10 @@ public class SuiteUiUtils {
                return coworker;
        }
 
                return coworker;
        }
 
+       public static boolean isTopic(Event event, CmsEvent cmsEvent) {
+               return event.getTopic().equals(cmsEvent.topic());
+       }
+
 //     public static String createAndConfigureEntity(Shell shell, Session referenceSession, String mainMixin,
 //                     String... additionnalProps) {
 //
 //     public static String createAndConfigureEntity(Shell shell, Session referenceSession, String mainMixin,
 //                     String... additionnalProps) {
 //
diff --git a/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java b/core/org.argeo.suite.ui/src/org/argeo/suite/ui/widgets/TabbedArea.java
new file mode 100644 (file)
index 0000000..5192f84
--- /dev/null
@@ -0,0 +1,244 @@
+package org.argeo.suite.ui.widgets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+
+import org.argeo.cms.ui.CmsUiProvider;
+import org.argeo.cms.ui.util.CmsUiUtils;
+import org.argeo.cms.ui.viewers.Section;
+import org.argeo.eclipse.ui.Selected;
+import org.argeo.jcr.Jcr;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+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.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/** Manages {@link Section} in a tab-like structure. */
+public class TabbedArea extends Composite {
+       private static final long serialVersionUID = 8659669229482033444L;
+
+       private Composite headers;
+       private Composite body;
+
+       private List<Section> sections = new ArrayList<>();
+
+       private Node previousNode;
+       private CmsUiProvider previousUiProvider;
+       private CmsUiProvider currentUiProvider;
+
+       private String tabStyle;
+       private String tabSelectedStyle;
+       private String bodyStyle;
+       private Image closeIcon;
+
+       public TabbedArea(Composite parent, int style) {
+               super(parent, style);
+               CmsUiUtils.style(parent, bodyStyle);
+
+               setLayout(CmsUiUtils.noSpaceGridLayout());
+
+               // TODO manage tabs at bottom or sides
+               headers = new Composite(this, SWT.NONE);
+               headers.setLayoutData(CmsUiUtils.fillWidth());
+               // CmsUiUtils.style(headers, bodyStyle);
+               body = new Composite(this, SWT.NONE);
+               body.setLayoutData(CmsUiUtils.fillAll());
+               body.setLayout(new FormLayout());
+               emptyState();
+       }
+
+       protected void refreshTabHeaders() {
+               // TODO deal with initialisation better
+//             CmsUiUtils.style(body, bodyStyle);
+
+//             int tabCount = sections.size() > 0 ?(sections.size()>1?sections.size()+1:1)  : 1;
+               int tabCount = sections.size() > 0 ? sections.size() : 1;
+               for (Control tab : headers.getChildren())
+                       tab.dispose();
+
+//             GridLayout headersGridLayout = new GridLayout(tabCount, true);
+//             headersGridLayout.marginHeight=0;
+//             headers.setLayout(headersGridLayout);
+               headers.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
+
+               if (sections.size() == 0) {
+                       Composite emptyHeader = new Composite(headers, SWT.NONE);
+                       emptyHeader.setLayoutData(CmsUiUtils.fillAll());
+                       emptyHeader.setLayout(new GridLayout());
+                       Label lbl = new Label(emptyHeader, SWT.NONE);
+                       lbl.setText("");
+                       lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
+
+               }
+
+               Section currentSection = getCurrentSection();
+               for (Section section : sections) {
+                       boolean selected = section == currentSection;
+                       Composite sectionHeader = section.createHeader(headers);
+                       CmsUiUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
+                       int headerColumns = 2;
+                       sectionHeader.setLayout(new GridLayout(headerColumns, false));
+                       sectionHeader.setLayout(CmsUiUtils.noSpaceGridLayout(headerColumns));
+                       Button title = new Button(sectionHeader, SWT.FLAT);
+                       CmsUiUtils.style(title, selected ? tabSelectedStyle : tabStyle);
+                       title.setLayoutData(CmsUiUtils.fillWidth());
+                       title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
+                       Node node = section.getNode();
+                       title.setText(Jcr.getTitle(node));
+                       ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
+//                     CmsUiUtils.style(toolBar, selected ? tabSelectedStyle : tabStyle);
+                       ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
+                       if (closeIcon != null)
+                               closeItem.setImage(closeIcon);
+                       else
+                               closeItem.setText("X");
+                       CmsUiUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
+                       closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
+               }
+
+//             if(sections.size()>1)
+//             {
+//                     ToolBar toolBar = new ToolBar(headers, SWT.NONE);
+//                     CmsUiUtils.style(toolBar, tabStyle);
+//                     ToolItem closeAllItem = new ToolItem(toolBar, SWT.FLAT);
+//                     closeAllItem.setText("X");
+//             }
+       }
+
+       public void view(CmsUiProvider uiProvider, Node context) {
+               if (body.isDisposed())
+                       return;
+               int index = tabIndex(context);
+               if (index >= 0) {
+                       showTab(index);
+                       previousNode = context;
+                       previousUiProvider = uiProvider;
+                       return;
+               }
+               Section section = (Section) body.getChildren()[0];
+               previousNode = section.getNode();
+               if (previousNode == null) {// empty state
+                       previousNode = context;
+                       previousUiProvider = uiProvider;
+               } else {
+                       previousUiProvider = currentUiProvider;
+               }
+               currentUiProvider = uiProvider;
+               section.setNode(context);
+               section.setLayoutData(CmsUiUtils.coverAll());
+               build(section, uiProvider, context);
+               if (sections.size() == 0)
+                       sections.add(section);
+               refreshTabHeaders();
+               layout(true, true);
+       }
+
+       public void open(CmsUiProvider uiProvider, Node context) {
+//             try {
+//                     if (openingTimer > 0)
+//                             Thread.sleep(openingTimer);
+//             } catch (InterruptedException e) {
+//                     // silent
+//             }
+
+               // int index = tabIndex(context);
+               if (previousNode != null && Jcr.getIdentifier(previousNode).equals(Jcr.getIdentifier(context))) {
+                       // does nothing
+                       return;
+               }
+               if (sections.size() == 0)
+                       CmsUiUtils.clear(body);
+               Section currentSection = getCurrentSection();
+               int currentIndex = sections.indexOf(currentSection);
+               Section previousSection = new Section(body, SWT.NONE, context);
+               build(previousSection, previousUiProvider, previousNode);
+               previousSection.setLayoutData(CmsUiUtils.coverAll());
+//             sections.remove(currentSection);
+               sections.add(currentIndex + 1, previousSection);
+//             sections.add(currentSection);
+//             nextCurrentSection.moveAbove(null);
+//             if (previousNode != null) {
+//                     view(previousUiProvider, previousNode);
+//             }
+               refreshTabHeaders();
+               layout(true, true);
+       }
+       
+       public void showTab(int index) {
+               Section sectionToShow = sections.get(index);
+               sectionToShow.moveAbove(null);
+               refreshTabHeaders();
+               layout(true, true);
+       }
+
+       protected void build(Section section, CmsUiProvider uiProvider, Node context) {
+               for (Control child : section.getChildren())
+                       child.dispose();
+               CmsUiUtils.style(section, bodyStyle);
+               section.setNode(context);
+               uiProvider.createUiPart(section, context);
+
+       }
+
+       private int tabIndex(Node node) {
+               for (int i = 0; i < sections.size(); i++) {
+                       Section section = sections.get(i);
+                       if (Jcr.getIdentifier(section.getNode()).equals(Jcr.getIdentifier(node)))
+                               return i;
+               }
+               return -1;
+       }
+
+       public void closeTab(Section section) {
+               int currentIndex = sections.indexOf(section);
+               int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
+               sections.remove(section);
+               section.dispose();
+               if (sections.size() == 0) {
+                       emptyState();
+                       refreshTabHeaders();
+                       layout(true, true);
+                       return;
+               }
+               refreshTabHeaders();
+               showTab(nextIndex);
+       }
+
+       protected void emptyState() {
+               new Section(body, SWT.NONE, null);
+               refreshTabHeaders();
+       }
+
+       public Composite getCurrent() {
+               return getCurrentSection();
+       }
+
+       protected Section getCurrentSection() {
+               return (Section) body.getChildren()[0];
+       }
+
+       public void setTabStyle(String tabStyle) {
+               this.tabStyle = tabStyle;
+       }
+
+       public void setTabSelectedStyle(String tabSelectedStyle) {
+               this.tabSelectedStyle = tabSelectedStyle;
+       }
+
+       public void setBodyStyle(String bodyStyle) {
+               this.bodyStyle = bodyStyle;
+       }
+
+       public void setCloseIcon(Image closeIcon) {
+               this.closeIcon = closeIcon;
+       }
+}