1 package org
.argeo
.cms
.swt
.acr
;
3 import java
.util
.ArrayList
;
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
;
22 /** Manages {@link SwtSection} in a tab-like structure. */
23 public class SwtTabbedArea
extends Composite
{
24 private static final long serialVersionUID
= 8659669229482033444L;
26 private Composite headers
;
27 private Composite body
;
29 private List
<SwtSection
> sections
= new ArrayList
<>();
31 private ProvidedContent previousNode
;
32 private SwtUiProvider previousUiProvider
;
33 private SwtUiProvider currentUiProvider
;
35 private String tabStyle
;
36 private String tabSelectedStyle
;
37 private String bodyStyle
;
38 private Image closeIcon
;
40 private StackLayout stackLayout
;
42 private boolean singleTab
= false;
43 private String singleTabTitle
= null;
45 public SwtTabbedArea(Composite parent
, int style
) {
46 super(parent
, SWT
.NONE
);
47 CmsSwtUtils
.style(parent
, bodyStyle
);
49 setLayout(CmsSwtUtils
.noSpaceGridLayout());
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
);
62 protected void refreshTabHeaders() {
63 int tabCount
= sections
.size() > 0 ? sections
.size() : 1;
64 for (Control tab
: headers
.getChildren())
67 headers
.setLayout(CmsSwtUtils
.noSpaceGridLayout(new GridLayout(tabCount
, true)));
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
);
75 lbl
.setLayoutData(new GridData(SWT
.CENTER
, SWT
.CENTER
, true, false));
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();
93 // FIXME find a standard way to display titles
94 String titleStr
= node
.getName().getLocalPart();
95 if (singleTab
&& singleTabTitle
!= null)
96 titleStr
= singleTabTitle
;
98 // TODO internationalise
99 title
.setText(titleStr
);
101 ToolBar toolBar
= new ToolBar(sectionHeader
, SWT
.NONE
);
102 ToolItem closeItem
= new ToolItem(toolBar
, SWT
.FLAT
);
103 if (closeIcon
!= null)
104 closeItem
.setImage(closeIcon
);
106 closeItem
.setText("X");
107 CmsSwtUtils
.style(closeItem
, selected ? tabSelectedStyle
: tabStyle
);
108 closeItem
.addSelectionListener((Selected
) (e
) -> closeTab(section
));
114 public void view(SwtUiProvider uiProvider
, Content context
) {
115 if (body
.isDisposed())
117 int index
= tabIndex(context
);
120 previousNode
= (ProvidedContent
) context
;
121 previousUiProvider
= uiProvider
;
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
;
130 previousUiProvider
= currentUiProvider
;
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
);
139 index
= tabIndex(context
);
144 public void open(SwtUiProvider uiProvider
, Content context
) {
146 throw new UnsupportedOperationException("Open is not supported in single tab mode.");
148 if (previousNode
!= null
149 && previousNode
.getSessionLocalId().equals(((ProvidedContent
) context
).getSessionLocalId())) {
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);
168 public void showTab(int index
) {
169 SwtSection sectionToShow
= sections
.get(index
);
170 // sectionToShow.moveAbove(null);
171 stackLayout
.topControl
= sectionToShow
;
176 protected void build(SwtSection section
, SwtUiProvider uiProvider
, Content context
) {
177 for (Control child
: section
.getChildren())
179 CmsSwtUtils
.style(section
, bodyStyle
);
180 section
.setContent(context
);
181 uiProvider
.createUiPart(section
, context
);
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()))
194 public void closeTab(SwtSection section
) {
195 int currentIndex
= sections
.indexOf(section
);
196 int nextIndex
= currentIndex
== 0 ?
0 : currentIndex
- 1;
197 sections
.remove(section
);
199 if (sections
.size() == 0) {
209 public void closeAllTabs() {
210 for (SwtSection section
: sections
) {
219 protected void emptyState() {
220 new SwtSection(body
, SWT
.NONE
, null);
224 public Composite
getCurrent() {
225 return getCurrentSection();
228 protected SwtSection
getCurrentSection() {
229 return (SwtSection
) stackLayout
.topControl
;
232 public Content
getCurrentContext() {
233 SwtSection section
= getCurrentSection();
234 if (section
!= null) {
235 return section
.getContent();
241 public void setTabStyle(String tabStyle
) {
242 this.tabStyle
= tabStyle
;
245 public void setTabSelectedStyle(String tabSelectedStyle
) {
246 this.tabSelectedStyle
= tabSelectedStyle
;
249 public void setBodyStyle(String bodyStyle
) {
250 this.bodyStyle
= bodyStyle
;
253 public void setCloseIcon(Image closeIcon
) {
254 this.closeIcon
= closeIcon
;
257 public void setSingleTab(boolean singleTab
) {
258 this.singleTab
= singleTab
;
261 public void setSingleTabTitle(String singleTabTitle
) {
262 this.singleTabTitle
= singleTabTitle
;