5192f84559610871bcab7886a0ab80388e0b68eb
[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                 // CmsUiUtils.style(headers, bodyStyle);
53                 body = new Composite(this, SWT.NONE);
54                 body.setLayoutData(CmsUiUtils.fillAll());
55                 body.setLayout(new FormLayout());
56                 emptyState();
57         }
58
59         protected void refreshTabHeaders() {
60                 // TODO deal with initialisation better
61 //              CmsUiUtils.style(body, bodyStyle);
62
63 //              int tabCount = sections.size() > 0 ?(sections.size()>1?sections.size()+1:1)  : 1;
64                 int tabCount = sections.size() > 0 ? sections.size() : 1;
65                 for (Control tab : headers.getChildren())
66                         tab.dispose();
67
68 //              GridLayout headersGridLayout = new GridLayout(tabCount, true);
69 //              headersGridLayout.marginHeight=0;
70 //              headers.setLayout(headersGridLayout);
71                 headers.setLayout(CmsUiUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
72
73                 if (sections.size() == 0) {
74                         Composite emptyHeader = new Composite(headers, SWT.NONE);
75                         emptyHeader.setLayoutData(CmsUiUtils.fillAll());
76                         emptyHeader.setLayout(new GridLayout());
77                         Label lbl = new Label(emptyHeader, SWT.NONE);
78                         lbl.setText("");
79                         lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
80
81                 }
82
83                 Section currentSection = getCurrentSection();
84                 for (Section section : sections) {
85                         boolean selected = section == currentSection;
86                         Composite sectionHeader = section.createHeader(headers);
87                         CmsUiUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
88                         int headerColumns = 2;
89                         sectionHeader.setLayout(new GridLayout(headerColumns, false));
90                         sectionHeader.setLayout(CmsUiUtils.noSpaceGridLayout(headerColumns));
91                         Button title = new Button(sectionHeader, SWT.FLAT);
92                         CmsUiUtils.style(title, selected ? tabSelectedStyle : tabStyle);
93                         title.setLayoutData(CmsUiUtils.fillWidth());
94                         title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
95                         Node node = section.getNode();
96                         title.setText(Jcr.getTitle(node));
97                         ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
98 //                      CmsUiUtils.style(toolBar, selected ? tabSelectedStyle : tabStyle);
99                         ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
100                         if (closeIcon != null)
101                                 closeItem.setImage(closeIcon);
102                         else
103                                 closeItem.setText("X");
104                         CmsUiUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
105                         closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
106                 }
107
108 //              if(sections.size()>1)
109 //              {
110 //                      ToolBar toolBar = new ToolBar(headers, SWT.NONE);
111 //                      CmsUiUtils.style(toolBar, tabStyle);
112 //                      ToolItem closeAllItem = new ToolItem(toolBar, SWT.FLAT);
113 //                      closeAllItem.setText("X");
114 //              }
115         }
116
117         public void view(CmsUiProvider uiProvider, Node context) {
118                 if (body.isDisposed())
119                         return;
120                 int index = tabIndex(context);
121                 if (index >= 0) {
122                         showTab(index);
123                         previousNode = context;
124                         previousUiProvider = uiProvider;
125                         return;
126                 }
127                 Section section = (Section) body.getChildren()[0];
128                 previousNode = section.getNode();
129                 if (previousNode == null) {// empty state
130                         previousNode = context;
131                         previousUiProvider = uiProvider;
132                 } else {
133                         previousUiProvider = currentUiProvider;
134                 }
135                 currentUiProvider = uiProvider;
136                 section.setNode(context);
137                 section.setLayoutData(CmsUiUtils.coverAll());
138                 build(section, uiProvider, context);
139                 if (sections.size() == 0)
140                         sections.add(section);
141                 refreshTabHeaders();
142                 layout(true, true);
143         }
144
145         public void open(CmsUiProvider uiProvider, Node context) {
146 //              try {
147 //                      if (openingTimer > 0)
148 //                              Thread.sleep(openingTimer);
149 //              } catch (InterruptedException e) {
150 //                      // silent
151 //              }
152
153                 // int index = tabIndex(context);
154                 if (previousNode != null && Jcr.getIdentifier(previousNode).equals(Jcr.getIdentifier(context))) {
155                         // does nothing
156                         return;
157                 }
158                 if (sections.size() == 0)
159                         CmsUiUtils.clear(body);
160                 Section currentSection = getCurrentSection();
161                 int currentIndex = sections.indexOf(currentSection);
162                 Section previousSection = new Section(body, SWT.NONE, context);
163                 build(previousSection, previousUiProvider, previousNode);
164                 previousSection.setLayoutData(CmsUiUtils.coverAll());
165 //              sections.remove(currentSection);
166                 sections.add(currentIndex + 1, previousSection);
167 //              sections.add(currentSection);
168 //              nextCurrentSection.moveAbove(null);
169 //              if (previousNode != null) {
170 //                      view(previousUiProvider, previousNode);
171 //              }
172                 refreshTabHeaders();
173                 layout(true, true);
174         }
175         
176         public void showTab(int index) {
177                 Section sectionToShow = sections.get(index);
178                 sectionToShow.moveAbove(null);
179                 refreshTabHeaders();
180                 layout(true, true);
181         }
182
183         protected void build(Section section, CmsUiProvider uiProvider, Node context) {
184                 for (Control child : section.getChildren())
185                         child.dispose();
186                 CmsUiUtils.style(section, bodyStyle);
187                 section.setNode(context);
188                 uiProvider.createUiPart(section, context);
189
190         }
191
192         private int tabIndex(Node node) {
193                 for (int i = 0; i < sections.size(); i++) {
194                         Section section = sections.get(i);
195                         if (Jcr.getIdentifier(section.getNode()).equals(Jcr.getIdentifier(node)))
196                                 return i;
197                 }
198                 return -1;
199         }
200
201         public void closeTab(Section section) {
202                 int currentIndex = sections.indexOf(section);
203                 int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
204                 sections.remove(section);
205                 section.dispose();
206                 if (sections.size() == 0) {
207                         emptyState();
208                         refreshTabHeaders();
209                         layout(true, true);
210                         return;
211                 }
212                 refreshTabHeaders();
213                 showTab(nextIndex);
214         }
215
216         protected void emptyState() {
217                 new Section(body, SWT.NONE, null);
218                 refreshTabHeaders();
219         }
220
221         public Composite getCurrent() {
222                 return getCurrentSection();
223         }
224
225         protected Section getCurrentSection() {
226                 return (Section) body.getChildren()[0];
227         }
228
229         public void setTabStyle(String tabStyle) {
230                 this.tabStyle = tabStyle;
231         }
232
233         public void setTabSelectedStyle(String tabSelectedStyle) {
234                 this.tabSelectedStyle = tabSelectedStyle;
235         }
236
237         public void setBodyStyle(String bodyStyle) {
238                 this.bodyStyle = bodyStyle;
239         }
240
241         public void setCloseIcon(Image closeIcon) {
242                 this.closeIcon = closeIcon;
243         }
244 }