Remove old comments.
[gpl/argeo-suite.git] / core / org.argeo.suite.ui / src / org / argeo / suite / ui / widgets / TabbedArea.java
1 package org.argeo.suite.ui.widgets;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.jcr.Node;
7
8 import org.argeo.cms.ui.CmsUiProvider;
9 import org.argeo.cms.ui.util.CmsUiUtils;
10 import org.argeo.cms.ui.viewers.Section;
11 import org.argeo.eclipse.ui.Selected;
12 import org.argeo.jcr.Jcr;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.graphics.Image;
15 import org.eclipse.swt.layout.FormLayout;
16 import org.eclipse.swt.layout.GridData;
17 import org.eclipse.swt.layout.GridLayout;
18 import org.eclipse.swt.widgets.Button;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Label;
22 import org.eclipse.swt.widgets.ToolBar;
23 import org.eclipse.swt.widgets.ToolItem;
24
25 /** Manages {@link Section} in a tab-like structure. */
26 public class TabbedArea extends Composite {
27         private static final long serialVersionUID = 8659669229482033444L;
28
29         private Composite headers;
30         private Composite body;
31
32         private List<Section> sections = new ArrayList<>();
33
34         private Node previousNode;
35         private CmsUiProvider previousUiProvider;
36         private CmsUiProvider currentUiProvider;
37
38         private String tabStyle;
39         private String tabSelectedStyle;
40         private String bodyStyle;
41         private Image closeIcon;
42
43         public TabbedArea(Composite parent, int style) {
44                 super(parent, style);
45                 CmsUiUtils.style(parent, bodyStyle);
46
47                 setLayout(CmsUiUtils.noSpaceGridLayout());
48
49                 // TODO manage tabs at bottom or sides
50                 headers = new Composite(this, SWT.NONE);
51                 headers.setLayoutData(CmsUiUtils.fillWidth());
52                 body = new Composite(this, SWT.NONE);
53                 body.setLayoutData(CmsUiUtils.fillAll());
54                 body.setLayout(new FormLayout());
55                 emptyState();
56         }
57
58         protected void refreshTabHeaders() {
59                 int tabCount = sections.size() > 0 ? sections.size() : 1;
60                 for (Control tab : headers.getChildren())
61                         tab.dispose();
62
63                 headers.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
64
65                 if (sections.size() == 0) {
66                         Composite emptyHeader = new Composite(headers, SWT.NONE);
67                         emptyHeader.setLayoutData(CmsUiUtils.fillAll());
68                         emptyHeader.setLayout(new GridLayout());
69                         Label lbl = new Label(emptyHeader, SWT.NONE);
70                         lbl.setText("");
71                         lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
72
73                 }
74
75                 Section currentSection = getCurrentSection();
76                 for (Section section : sections) {
77                         boolean selected = section == currentSection;
78                         Composite sectionHeader = section.createHeader(headers);
79                         CmsUiUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
80                         int headerColumns = 2;
81                         sectionHeader.setLayout(new GridLayout(headerColumns, false));
82                         sectionHeader.setLayout(CmsUiUtils.noSpaceGridLayout(headerColumns));
83                         Button title = new Button(sectionHeader, SWT.FLAT);
84                         CmsUiUtils.style(title, selected ? tabSelectedStyle : tabStyle);
85                         title.setLayoutData(CmsUiUtils.fillWidth());
86                         title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
87                         Node node = section.getNode();
88                         title.setText(Jcr.getTitle(node));
89                         ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
90                         ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
91                         if (closeIcon != null)
92                                 closeItem.setImage(closeIcon);
93                         else
94                                 closeItem.setText("X");
95                         CmsUiUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
96                         closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
97                 }
98
99         }
100
101         public void view(CmsUiProvider uiProvider, Node context) {
102                 if (body.isDisposed())
103                         return;
104                 int index = tabIndex(context);
105                 if (index >= 0) {
106                         showTab(index);
107                         previousNode = context;
108                         previousUiProvider = uiProvider;
109                         return;
110                 }
111                 Section section = (Section) body.getChildren()[0];
112                 previousNode = section.getNode();
113                 if (previousNode == null) {// empty state
114                         previousNode = context;
115                         previousUiProvider = uiProvider;
116                 } else {
117                         previousUiProvider = currentUiProvider;
118                 }
119                 currentUiProvider = uiProvider;
120                 section.setNode(context);
121                 section.setLayoutData(CmsUiUtils.coverAll());
122                 build(section, uiProvider, context);
123                 if (sections.size() == 0)
124                         sections.add(section);
125                 refreshTabHeaders();
126                 layout(true, true);
127         }
128
129         public void open(CmsUiProvider uiProvider, Node context) {
130                 if (previousNode != null && Jcr.getIdentifier(previousNode).equals(Jcr.getIdentifier(context))) {
131                         // does nothing
132                         return;
133                 }
134                 if (sections.size() == 0)
135                         CmsUiUtils.clear(body);
136                 Section currentSection = getCurrentSection();
137                 int currentIndex = sections.indexOf(currentSection);
138                 Section previousSection = new Section(body, SWT.NONE, context);
139                 build(previousSection, previousUiProvider, previousNode);
140                 previousSection.setLayoutData(CmsUiUtils.coverAll());
141                 sections.add(currentIndex + 1, previousSection);
142                 refreshTabHeaders();
143                 layout(true, true);
144         }
145         
146         public void showTab(int index) {
147                 Section sectionToShow = sections.get(index);
148                 sectionToShow.moveAbove(null);
149                 refreshTabHeaders();
150                 layout(true, true);
151         }
152
153         protected void build(Section section, CmsUiProvider uiProvider, Node context) {
154                 for (Control child : section.getChildren())
155                         child.dispose();
156                 CmsUiUtils.style(section, bodyStyle);
157                 section.setNode(context);
158                 uiProvider.createUiPart(section, context);
159
160         }
161
162         private int tabIndex(Node node) {
163                 for (int i = 0; i < sections.size(); i++) {
164                         Section section = sections.get(i);
165                         if (Jcr.getIdentifier(section.getNode()).equals(Jcr.getIdentifier(node)))
166                                 return i;
167                 }
168                 return -1;
169         }
170
171         public void closeTab(Section section) {
172                 int currentIndex = sections.indexOf(section);
173                 int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
174                 sections.remove(section);
175                 section.dispose();
176                 if (sections.size() == 0) {
177                         emptyState();
178                         refreshTabHeaders();
179                         layout(true, true);
180                         return;
181                 }
182                 refreshTabHeaders();
183                 showTab(nextIndex);
184         }
185
186         protected void emptyState() {
187                 new Section(body, SWT.NONE, null);
188                 refreshTabHeaders();
189         }
190
191         public Composite getCurrent() {
192                 return getCurrentSection();
193         }
194
195         protected Section getCurrentSection() {
196                 return (Section) body.getChildren()[0];
197         }
198
199         public void setTabStyle(String tabStyle) {
200                 this.tabStyle = tabStyle;
201         }
202
203         public void setTabSelectedStyle(String tabSelectedStyle) {
204                 this.tabSelectedStyle = tabSelectedStyle;
205         }
206
207         public void setBodyStyle(String bodyStyle) {
208                 this.bodyStyle = bodyStyle;
209         }
210
211         public void setCloseIcon(Image closeIcon) {
212                 this.closeIcon = closeIcon;
213         }
214 }