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;
44 public SwtTabbedArea(Composite parent
, int style
) {
45 super(parent
, SWT
.NONE
);
46 CmsSwtUtils
.style(parent
, bodyStyle
);
48 setLayout(CmsSwtUtils
.noSpaceGridLayout());
50 // TODO manage tabs at bottom or sides
51 headers
= new Composite(this, SWT
.NONE
);
52 headers
.setLayoutData(CmsSwtUtils
.fillWidth());
53 body
= new Composite(this, SWT
.NONE
);
54 body
.setLayoutData(CmsSwtUtils
.fillAll());
55 // body.setLayout(new FormLayout());
56 stackLayout
= new StackLayout();
57 body
.setLayout(stackLayout
);
61 protected void refreshTabHeaders() {
62 int tabCount
= sections
.size() > 0 ? sections
.size() : 1;
63 for (Control tab
: headers
.getChildren())
66 headers
.setLayout(CmsSwtUtils
.noSpaceGridLayout(new GridLayout(tabCount
, true)));
68 if (sections
.size() == 0) {
69 Composite emptyHeader
= new Composite(headers
, SWT
.NONE
);
70 emptyHeader
.setLayoutData(CmsSwtUtils
.fillAll());
71 emptyHeader
.setLayout(new GridLayout());
72 Label lbl
= new Label(emptyHeader
, SWT
.NONE
);
74 lbl
.setLayoutData(new GridData(SWT
.CENTER
, SWT
.CENTER
, true, false));
78 SwtSection currentSection
= getCurrentSection();
79 for (SwtSection section
: sections
) {
80 boolean selected
= section
== currentSection
;
81 Composite sectionHeader
= section
.createHeader(headers
);
82 CmsSwtUtils
.style(sectionHeader
, selected ? tabSelectedStyle
: tabStyle
);
83 int headerColumns
= singleTab ?
1 : 2;
84 sectionHeader
.setLayout(new GridLayout(headerColumns
, false));
85 sectionHeader
.setLayout(CmsSwtUtils
.noSpaceGridLayout(headerColumns
));
86 Button title
= new Button(sectionHeader
, SWT
.FLAT
);
87 CmsSwtUtils
.style(title
, selected ? tabSelectedStyle
: tabStyle
);
88 title
.setLayoutData(CmsSwtUtils
.fillWidth());
89 title
.addSelectionListener((Selected
) (e
) -> showTab(tabIndex(section
.getNode())));
90 Content node
= section
.getContent();
92 // FIXME find a standard way to display titles
93 String titleStr
= node
.getName().getLocalPart();
95 // TODO internationalize
96 title
.setText(titleStr
);
98 ToolBar toolBar
= new ToolBar(sectionHeader
, SWT
.NONE
);
99 ToolItem closeItem
= new ToolItem(toolBar
, SWT
.FLAT
);
100 if (closeIcon
!= null)
101 closeItem
.setImage(closeIcon
);
103 closeItem
.setText("X");
104 CmsSwtUtils
.style(closeItem
, selected ? tabSelectedStyle
: tabStyle
);
105 closeItem
.addSelectionListener((Selected
) (e
) -> closeTab(section
));
111 public void view(SwtUiProvider uiProvider
, Content context
) {
112 if (body
.isDisposed())
114 int index
= tabIndex(context
);
117 previousNode
= (ProvidedContent
) context
;
118 previousUiProvider
= uiProvider
;
121 SwtSection section
= (SwtSection
) body
.getChildren()[0];
122 previousNode
= (ProvidedContent
) section
.getNode();
123 if (previousNode
== null) {// empty state
124 previousNode
= (ProvidedContent
) context
;
125 previousUiProvider
= uiProvider
;
127 previousUiProvider
= currentUiProvider
;
129 currentUiProvider
= uiProvider
;
130 section
.setContent(context
);
131 // section.setLayoutData(CmsUiUtils.coverAll());
132 build(section
, uiProvider
, context
);
133 if (sections
.size() == 0)
134 sections
.add(section
);
136 index
= tabIndex(context
);
141 public void open(SwtUiProvider uiProvider
, Content context
) {
143 throw new UnsupportedOperationException("Open is not supported in single tab mode.");
145 if (previousNode
!= null
146 && previousNode
.getSessionLocalId().equals(((ProvidedContent
) context
).getSessionLocalId())) {
150 if (sections
.size() == 0)
151 CmsSwtUtils
.clear(body
);
152 SwtSection currentSection
= getCurrentSection();
153 int currentIndex
= sections
.indexOf(currentSection
);
154 SwtSection previousSection
= new SwtSection(body
, SWT
.NONE
, context
);
155 build(previousSection
, previousUiProvider
, previousNode
);
156 // previousSection.setLayoutData(CmsUiUtils.coverAll());
157 int newIndex
= currentIndex
+ 1;
158 sections
.add(currentIndex
, previousSection
);
159 // sections.add(newIndex, previousSection);
165 public void showTab(int index
) {
166 SwtSection sectionToShow
= sections
.get(index
);
167 // sectionToShow.moveAbove(null);
168 stackLayout
.topControl
= sectionToShow
;
173 protected void build(SwtSection section
, SwtUiProvider uiProvider
, Content context
) {
174 for (Control child
: section
.getChildren())
176 CmsSwtUtils
.style(section
, bodyStyle
);
177 section
.setContent(context
);
178 uiProvider
.createUiPart(section
, context
);
182 private int tabIndex(Content context
) {
183 for (int i
= 0; i
< sections
.size(); i
++) {
184 SwtSection section
= sections
.get(i
);
185 if (section
.getSessionLocalId().equals(((ProvidedContent
) context
).getSessionLocalId()))
191 public void closeTab(SwtSection section
) {
192 int currentIndex
= sections
.indexOf(section
);
193 int nextIndex
= currentIndex
== 0 ?
0 : currentIndex
- 1;
194 sections
.remove(section
);
196 if (sections
.size() == 0) {
206 public void closeAllTabs() {
207 for (SwtSection section
: sections
) {
216 protected void emptyState() {
217 new SwtSection(body
, SWT
.NONE
, null);
221 public Composite
getCurrent() {
222 return getCurrentSection();
225 protected SwtSection
getCurrentSection() {
226 return (SwtSection
) stackLayout
.topControl
;
229 public Content
getCurrentContext() {
230 SwtSection section
= getCurrentSection();
231 if (section
!= null) {
232 return section
.getNode();
238 public void setTabStyle(String tabStyle
) {
239 this.tabStyle
= tabStyle
;
242 public void setTabSelectedStyle(String tabSelectedStyle
) {
243 this.tabSelectedStyle
= tabSelectedStyle
;
246 public void setBodyStyle(String bodyStyle
) {
247 this.bodyStyle
= bodyStyle
;
250 public void setCloseIcon(Image closeIcon
) {
251 this.closeIcon
= closeIcon
;
254 public void setSingleTab(boolean singleTab
) {
255 this.singleTab
= singleTab
;