1 package org
.argeo
.cms
.swt
.widgets
;
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
.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
;
23 /** Manages {@link SwtSection} in a tab-like structure. */
24 public class SwtTabbedArea
extends Composite
{
25 private static final long serialVersionUID
= 8659669229482033444L;
27 private Composite headers
;
28 private Composite body
;
30 private List
<SwtSection
> sections
= new ArrayList
<>();
32 private ProvidedContent previousNode
;
33 private SwtUiProvider previousUiProvider
;
34 private SwtUiProvider currentUiProvider
;
36 private String tabStyle
;
37 private String tabSelectedStyle
;
38 private String bodyStyle
;
39 private Image closeIcon
;
41 private StackLayout stackLayout
;
43 private boolean singleTab
= false;
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
.getNode())));
91 Content node
= section
.getContent();
93 // FIXME find a standard way to display titles
94 String titleStr
= node
.getName().getLocalPart();
96 // TODO internationalize
97 title
.setText(titleStr
);
99 ToolBar toolBar
= new ToolBar(sectionHeader
, SWT
.NONE
);
100 ToolItem closeItem
= new ToolItem(toolBar
, SWT
.FLAT
);
101 if (closeIcon
!= null)
102 closeItem
.setImage(closeIcon
);
104 closeItem
.setText("X");
105 CmsSwtUtils
.style(closeItem
, selected ? tabSelectedStyle
: tabStyle
);
106 closeItem
.addSelectionListener((Selected
) (e
) -> closeTab(section
));
112 public void view(SwtUiProvider uiProvider
, Content context
) {
113 if (body
.isDisposed())
115 int index
= tabIndex(context
);
118 previousNode
= (ProvidedContent
) context
;
119 previousUiProvider
= uiProvider
;
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
;
128 previousUiProvider
= currentUiProvider
;
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
);
137 index
= tabIndex(context
);
142 public void open(SwtUiProvider uiProvider
, Content context
) {
144 throw new UnsupportedOperationException("Open is not supported in single tab mode.");
146 if (previousNode
!= null
147 && previousNode
.getSessionLocalId().equals(((ProvidedContent
) context
).getSessionLocalId())) {
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);
166 public void showTab(int index
) {
167 SwtSection sectionToShow
= sections
.get(index
);
168 // sectionToShow.moveAbove(null);
169 stackLayout
.topControl
= sectionToShow
;
174 protected void build(SwtSection section
, SwtUiProvider uiProvider
, Content context
) {
175 for (Control child
: section
.getChildren())
177 CmsSwtUtils
.style(section
, bodyStyle
);
178 section
.setContent(context
);
179 uiProvider
.createUiPart(section
, context
);
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()))
192 public void closeTab(SwtSection section
) {
193 int currentIndex
= sections
.indexOf(section
);
194 int nextIndex
= currentIndex
== 0 ?
0 : currentIndex
- 1;
195 sections
.remove(section
);
197 if (sections
.size() == 0) {
207 public void closeAllTabs() {
208 for (SwtSection section
: sections
) {
217 protected void emptyState() {
218 new SwtSection(body
, SWT
.NONE
, null);
222 public Composite
getCurrent() {
223 return getCurrentSection();
226 protected SwtSection
getCurrentSection() {
227 return (SwtSection
) stackLayout
.topControl
;
230 public Content
getCurrentContext() {
231 SwtSection section
= getCurrentSection();
232 if (section
!= null) {
233 return section
.getNode();
239 public void setTabStyle(String tabStyle
) {
240 this.tabStyle
= tabStyle
;
243 public void setTabSelectedStyle(String tabSelectedStyle
) {
244 this.tabSelectedStyle
= tabSelectedStyle
;
247 public void setBodyStyle(String bodyStyle
) {
248 this.bodyStyle
= bodyStyle
;
251 public void setCloseIcon(Image closeIcon
) {
252 this.closeIcon
= closeIcon
;
255 public void setSingleTab(boolean singleTab
) {
256 this.singleTab
= singleTab
;