]> git.argeo.org Git - lgpl/argeo-commons.git/blob - SwtTabbedArea.java
b65bc3b6a3a28171ff0719e69dd9c2739d1e4e0c
[lgpl/argeo-commons.git] / SwtTabbedArea.java
1 package org.argeo.cms.swt.acr;
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.eclipse.swt.SWT;
11 import org.eclipse.swt.custom.StackLayout;
12 import org.eclipse.swt.graphics.Image;
13 import org.eclipse.swt.layout.GridData;
14 import org.eclipse.swt.layout.GridLayout;
15 import org.eclipse.swt.widgets.Button;
16 import org.eclipse.swt.widgets.Composite;
17 import org.eclipse.swt.widgets.Control;
18 import org.eclipse.swt.widgets.Label;
19 import org.eclipse.swt.widgets.ToolBar;
20 import org.eclipse.swt.widgets.ToolItem;
21
22 /** Manages {@link SwtSection} in a tab-like structure. */
23 public class SwtTabbedArea extends Composite {
24 private static final long serialVersionUID = 8659669229482033444L;
25
26 private Composite headers;
27 private Composite body;
28
29 private List<SwtSection> sections = new ArrayList<>();
30
31 private ProvidedContent previousNode;
32 private SwtUiProvider previousUiProvider;
33 private SwtUiProvider currentUiProvider;
34
35 private String tabStyle;
36 private String tabSelectedStyle;
37 private String bodyStyle;
38 private Image closeIcon;
39
40 private StackLayout stackLayout;
41
42 private boolean singleTab = false;
43 private String singleTabTitle = null;
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.getContent())));
91 Content node = section.getContent();
92
93 // FIXME find a standard way to display titles
94 String titleStr = node.getName().getLocalPart();
95 if (singleTab && singleTabTitle != null)
96 titleStr = singleTabTitle;
97
98 // TODO internationalise
99 title.setText(titleStr);
100 if (!singleTab) {
101 ToolBar toolBar = new ToolBar(sectionHeader, SWT.NONE);
102 ToolItem closeItem = new ToolItem(toolBar, SWT.FLAT);
103 if (closeIcon != null)
104 closeItem.setImage(closeIcon);
105 else
106 closeItem.setText("X");
107 CmsSwtUtils.style(closeItem, selected ? tabSelectedStyle : tabStyle);
108 closeItem.addSelectionListener((Selected) (e) -> closeTab(section));
109 }
110 }
111
112 }
113
114 public void view(SwtUiProvider uiProvider, Content context) {
115 if (body.isDisposed())
116 return;
117 int index = tabIndex(context);
118 if (index >= 0) {
119 showTab(index);
120 previousNode = (ProvidedContent) context;
121 previousUiProvider = uiProvider;
122 return;
123 }
124 SwtSection section = (SwtSection) body.getChildren()[0];
125 previousNode = (ProvidedContent) section.getContent();
126 if (previousNode == null) {// empty state
127 previousNode = (ProvidedContent) context;
128 previousUiProvider = uiProvider;
129 } else {
130 previousUiProvider = currentUiProvider;
131 }
132 currentUiProvider = uiProvider;
133 section.setContent(context);
134 // section.setLayoutData(CmsUiUtils.coverAll());
135 build(section, uiProvider, context);
136 if (sections.size() == 0)
137 sections.add(section);
138 refreshTabHeaders();
139 index = tabIndex(context);
140 showTab(index);
141 layout(true, true);
142 }
143
144 public void open(SwtUiProvider uiProvider, Content context) {
145 if (singleTab)
146 throw new UnsupportedOperationException("Open is not supported in single tab mode.");
147
148 if (previousNode != null
149 && previousNode.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId())) {
150 // does nothing
151 return;
152 }
153 if (sections.size() == 0)
154 CmsSwtUtils.clear(body);
155 SwtSection currentSection = getCurrentSection();
156 int currentIndex = sections.indexOf(currentSection);
157 SwtSection previousSection = new SwtSection(body, SWT.NONE, context);
158 build(previousSection, previousUiProvider, previousNode);
159 // previousSection.setLayoutData(CmsUiUtils.coverAll());
160 int newIndex = currentIndex + 1;
161 sections.add(currentIndex, previousSection);
162 // sections.add(newIndex, previousSection);
163 showTab(newIndex);
164 refreshTabHeaders();
165 layout(true, true);
166 }
167
168 public void showTab(int index) {
169 SwtSection sectionToShow = sections.get(index);
170 // sectionToShow.moveAbove(null);
171 stackLayout.topControl = sectionToShow;
172 refreshTabHeaders();
173 layout(true, true);
174 }
175
176 protected void build(SwtSection section, SwtUiProvider uiProvider, Content context) {
177 for (Control child : section.getChildren())
178 child.dispose();
179 CmsSwtUtils.style(section, bodyStyle);
180 section.setContent(context);
181 uiProvider.createUiPart(section, context);
182
183 }
184
185 private int tabIndex(Content context) {
186 for (int i = 0; i < sections.size(); i++) {
187 SwtSection section = sections.get(i);
188 if (section.getSessionLocalId().equals(((ProvidedContent) context).getSessionLocalId()))
189 return i;
190 }
191 return -1;
192 }
193
194 public void closeTab(SwtSection section) {
195 int currentIndex = sections.indexOf(section);
196 int nextIndex = currentIndex == 0 ? 0 : currentIndex - 1;
197 sections.remove(section);
198 section.dispose();
199 if (sections.size() == 0) {
200 emptyState();
201 refreshTabHeaders();
202 layout(true, true);
203 return;
204 }
205 refreshTabHeaders();
206 showTab(nextIndex);
207 }
208
209 public void closeAllTabs() {
210 for (SwtSection section : sections) {
211 section.dispose();
212 }
213 sections.clear();
214 emptyState();
215 refreshTabHeaders();
216 layout(true, true);
217 }
218
219 protected void emptyState() {
220 new SwtSection(body, SWT.NONE, null);
221 refreshTabHeaders();
222 }
223
224 public Composite getCurrent() {
225 return getCurrentSection();
226 }
227
228 protected SwtSection getCurrentSection() {
229 return (SwtSection) stackLayout.topControl;
230 }
231
232 public Content getCurrentContext() {
233 SwtSection section = getCurrentSection();
234 if (section != null) {
235 return section.getContent();
236 } else {
237 return null;
238 }
239 }
240
241 public void setTabStyle(String tabStyle) {
242 this.tabStyle = tabStyle;
243 }
244
245 public void setTabSelectedStyle(String tabSelectedStyle) {
246 this.tabSelectedStyle = tabSelectedStyle;
247 }
248
249 public void setBodyStyle(String bodyStyle) {
250 this.bodyStyle = bodyStyle;
251 }
252
253 public void setCloseIcon(Image closeIcon) {
254 this.closeIcon = closeIcon;
255 }
256
257 public void setSingleTab(boolean singleTab) {
258 this.singleTab = singleTab;
259 }
260
261 public void setSingleTabTitle(String singleTabTitle) {
262 this.singleTabTitle = singleTabTitle;
263 }
264
265 }