]> git.argeo.org Git - gpl/argeo-suite.git/blob - suite/ui/widgets/TabbedArea.java
Prepare next development cycle
[gpl/argeo-suite.git] / 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 }