]> git.argeo.org Git - lgpl/argeo-commons.git/blob - eclipse/org.argeo.cms.swt/src/org/argeo/cms/swt/widgets/SwtTabbedArea.java
Refactor to use ACR instead of JCR.
[lgpl/argeo-commons.git] / eclipse / org.argeo.cms.swt / src / org / argeo / cms / swt / widgets / SwtTabbedArea.java
1 package org.argeo.cms.swt.widgets;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.argeo.api.acr.Content;
7 import org.argeo.api.acr.spi.ProvidedContent;
8 import org.argeo.cms.swt.CmsSwtUtils;
9 import org.argeo.cms.swt.Selected;
10 import org.argeo.cms.swt.acr.SwtUiProvider;
11 import org.eclipse.swt.SWT;
12 import org.eclipse.swt.custom.StackLayout;
13 import org.eclipse.swt.graphics.Image;
14 import org.eclipse.swt.layout.GridData;
15 import org.eclipse.swt.layout.GridLayout;
16 import org.eclipse.swt.widgets.Button;
17 import org.eclipse.swt.widgets.Composite;
18 import org.eclipse.swt.widgets.Control;
19 import org.eclipse.swt.widgets.Label;
20 import org.eclipse.swt.widgets.ToolBar;
21 import org.eclipse.swt.widgets.ToolItem;
22
23 /** Manages {@link SwtSection} in a tab-like structure. */
24 public class SwtTabbedArea extends Composite {
25 private static final long serialVersionUID = 8659669229482033444L;
26
27 private Composite headers;
28 private Composite body;
29
30 private List<SwtSection> sections = new ArrayList<>();
31
32 private ProvidedContent previousNode;
33 private SwtUiProvider previousUiProvider;
34 private SwtUiProvider currentUiProvider;
35
36 private String tabStyle;
37 private String tabSelectedStyle;
38 private String bodyStyle;
39 private Image closeIcon;
40
41 private StackLayout stackLayout;
42
43 private boolean singleTab = false;
44
45 public SwtTabbedArea(Composite parent, int style) {
46 super(parent, SWT.NONE);
47 CmsSwtUtils.style(parent, bodyStyle);
48
49 setLayout(CmsSwtUtils.noSpaceGridLayout());
50
51 // TODO manage tabs at bottom or sides
52 headers = new Composite(this, SWT.NONE);
53 headers.setLayoutData(CmsSwtUtils.fillWidth());
54 body = new Composite(this, SWT.NONE);
55 body.setLayoutData(CmsSwtUtils.fillAll());
56 // body.setLayout(new FormLayout());
57 stackLayout = new StackLayout();
58 body.setLayout(stackLayout);
59 emptyState();
60 }
61
62 protected void refreshTabHeaders() {
63 int tabCount = sections.size() > 0 ? sections.size() : 1;
64 for (Control tab : headers.getChildren())
65 tab.dispose();
66
67 headers.setLayout(CmsSwtUtils.noSpaceGridLayout(new GridLayout(tabCount, true)));
68
69 if (sections.size() == 0) {
70 Composite emptyHeader = new Composite(headers, SWT.NONE);
71 emptyHeader.setLayoutData(CmsSwtUtils.fillAll());
72 emptyHeader.setLayout(new GridLayout());
73 Label lbl = new Label(emptyHeader, SWT.NONE);
74 lbl.setText("");
75 lbl.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
76
77 }
78
79 SwtSection currentSection = getCurrentSection();
80 for (SwtSection section : sections) {
81 boolean selected = section == currentSection;
82 Composite sectionHeader = section.createHeader(headers);
83 CmsSwtUtils.style(sectionHeader, selected ? tabSelectedStyle : tabStyle);
84 int headerColumns = singleTab ? 1 : 2;
85 sectionHeader.setLayout(new GridLayout(headerColumns, false));
86 sectionHeader.setLayout(CmsSwtUtils.noSpaceGridLayout(headerColumns));
87 Button title = new Button(sectionHeader, SWT.FLAT);
88 CmsSwtUtils.style(title, selected ? tabSelectedStyle : tabStyle);
89 title.setLayoutData(CmsSwtUtils.fillWidth());
90 title.addSelectionListener((Selected) (e) -> showTab(tabIndex(section.getNode())));
91 Content node = section.getContent();
92
93 // FIXME find a standard way to display titles
94 String titleStr = node.getName().getLocalPart();
95
96 // TODO internationalize
97 title.setText(titleStr);
98 if (!singleTab) {
99 ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
100 ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
101 if (closeIcon != null)
102 closeItem.setImage(closeIcon);
103 else
104 closeItem.setText("X");
105 CmsSwtUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
106 closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
107 }
108 }
109
110 }
111
112 public void view(SwtUiProvider uiProvider, Content context) {
113 if (body.isDisposed())
114 return;
115 int index = tabIndex(context);
116 if (index >= 0) {
117 showTab(index);
118 previousNode = (ProvidedContent) context;
119 previousUiProvider = uiProvider;
120 return;
121 }
122 SwtSection section = (SwtSection) body.getChildren()[0];
123 previousNode = (ProvidedContent) section.getNode();
124 if (previousNode == null) {// empty state
125 previousNode = (ProvidedContent) context;
126 previousUiProvider = uiProvider;
127 } else {
128 previousUiProvider = currentUiProvider;
129 }
130 currentUiProvider = uiProvider;
131 section.setContent(context);
132 // section.setLayoutData(CmsUiUtils.coverAll());
133 build(section, uiProvider, context);
134 if (sections.size() == 0)
135 sections.add(section);
136 refreshTabHeaders();
137 index = tabIndex(context);
138 showTab(index);
139 layout(true, true);
140 }
141
142 public void open(SwtUiProvider uiProvider, Content context) {
143 if (singleTab)
144 throw new UnsupportedOperationException("Open is not supported in single tab mode.");
145
146 if (previousNode != null
147 && previousNode.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId())) {
148 // does nothing
149 return;
150 }
151 if (sections.size() == 0)
152 CmsSwtUtils.clear(body);
153 SwtSection currentSection = getCurrentSection();
154 int currentIndex = sections.indexOf(currentSection);
155 SwtSection previousSection = new SwtSection(body, SWT.NONE, context);
156 build(previousSection, previousUiProvider, previousNode);
157 // previousSection.setLayoutData(CmsUiUtils.coverAll());
158 int newIndex = currentIndex + 1;
159 sections.add(currentIndex, previousSection);
160 // sections.add(newIndex, previousSection);
161 showTab(newIndex);
162 refreshTabHeaders();
163 layout(true, true);
164 }
165
166 public void showTab(int index) {
167 SwtSection sectionToShow = sections.get(index);
168 // sectionToShow.moveAbove(null);
169 stackLayout.topControl = sectionToShow;
170 refreshTabHeaders();
171 layout(true, true);
172 }
173
174 protected void build(SwtSection section, SwtUiProvider uiProvider, Content context) {
175 for (Control child : section.getChildren())
176 child.dispose();
177 CmsSwtUtils.style(section, bodyStyle);
178 section.setContent(context);
179 uiProvider.createUiPart(section, context);
180
181 }
182
183 private int tabIndex(Content context) {
184 for (int i = 0; i < sections.size(); i++) {
185 SwtSection section = sections.get(i);
186 if (section.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId()))
187 return i;
188 }
189 return -1;
190 }
191
192 public void closeTab(SwtSection section) {
193 int currentIndex = sections.indexOf(section);
194 int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
195 sections.remove(section);
196 section.dispose();
197 if (sections.size() == 0) {
198 emptyState();
199 refreshTabHeaders();
200 layout(true, true);
201 return;
202 }
203 refreshTabHeaders();
204 showTab(nextIndex);
205 }
206
207 public void closeAllTabs() {
208 for (SwtSection section : sections) {
209 section.dispose();
210 }
211 sections.clear();
212 emptyState();
213 refreshTabHeaders();
214 layout(true, true);
215 }
216
217 protected void emptyState() {
218 new SwtSection(body, SWT.NONE, null);
219 refreshTabHeaders();
220 }
221
222 public Composite getCurrent() {
223 return getCurrentSection();
224 }
225
226 protected SwtSection getCurrentSection() {
227 return (SwtSection) stackLayout.topControl;
228 }
229
230 public Content getCurrentContext() {
231 SwtSection section = getCurrentSection();
232 if (section != null) {
233 return section.getNode();
234 } else {
235 return null;
236 }
237 }
238
239 public void setTabStyle(String tabStyle) {
240 this.tabStyle = tabStyle;
241 }
242
243 public void setTabSelectedStyle(String tabSelectedStyle) {
244 this.tabSelectedStyle = tabSelectedStyle;
245 }
246
247 public void setBodyStyle(String bodyStyle) {
248 this.bodyStyle = bodyStyle;
249 }
250
251 public void setCloseIcon(Image closeIcon) {
252 this.closeIcon = closeIcon;
253 }
254
255 public void setSingleTab(boolean singleTab) {
256 this.singleTab = singleTab;
257 }
258
259 }