Skip to content

Package: CollapsableGroupSWTRenderer$CollapsableGroupExpandBar

CollapsableGroupSWTRenderer$CollapsableGroupExpandBar

nameinstructionbranchcomplexitylinemethod
CollapsableGroupSWTRenderer.CollapsableGroupExpandBar(Composite, int)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
checkSubclass()
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
computeSize(int, int, boolean)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
computeSizeForBar(int, int, boolean)
M: 20 C: 42
68%
M: 7 C: 5
42%
M: 5 C: 2
29%
M: 2 C: 8
80%
M: 0 C: 1
100%
setInitialHeaderHeight(int)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
setItemComposite(Composite)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (c) 2011-2016 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * EclipseSource Munich - initial API and implementation
13: */
14: package org.eclipse.emf.ecp.view.group.swt.internal.collapsable;
15:
16: import javax.inject.Inject;
17:
18: import org.eclipse.core.databinding.observable.value.IObservableValue;
19: import org.eclipse.emf.databinding.EMFDataBindingContext;
20: import org.eclipse.emf.databinding.edit.EMFEditObservables;
21: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
22: import org.eclipse.emf.ecp.view.spi.core.swt.ContainerSWTRenderer;
23: import org.eclipse.emf.ecp.view.spi.group.model.VGroup;
24: import org.eclipse.emf.ecp.view.spi.model.VViewPackage;
25: import org.eclipse.emf.ecp.view.spi.renderer.NoPropertyDescriptorFoundExeption;
26: import org.eclipse.emf.ecp.view.spi.renderer.NoRendererFoundException;
27: import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
28: import org.eclipse.emfforms.spi.common.report.ReportService;
29: import org.eclipse.emfforms.spi.swt.core.EMFFormsRendererFactory;
30: import org.eclipse.emfforms.spi.swt.core.layout.EMFFormsSWTLayoutUtil;
31: import org.eclipse.emfforms.spi.swt.core.layout.GridDescriptionFactory;
32: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell;
33: import org.eclipse.emfforms.spi.swt.core.layout.SWTGridDescription;
34: import org.eclipse.jface.databinding.swt.ISWTObservableValue;
35: import org.eclipse.jface.databinding.swt.typed.WidgetProperties;
36: import org.eclipse.jface.layout.GridDataFactory;
37: import org.eclipse.jface.layout.GridLayoutFactory;
38: import org.eclipse.jface.resource.FontDescriptor;
39: import org.eclipse.swt.SWT;
40: import org.eclipse.swt.events.ExpandEvent;
41: import org.eclipse.swt.events.ExpandListener;
42: import org.eclipse.swt.graphics.Font;
43: import org.eclipse.swt.graphics.Point;
44: import org.eclipse.swt.layout.GridData;
45: import org.eclipse.swt.widgets.Composite;
46: import org.eclipse.swt.widgets.Control;
47: import org.eclipse.swt.widgets.ExpandBar;
48: import org.eclipse.swt.widgets.ExpandItem;
49:
50: /**
51: * A Group renderer, which is collapsable.
52: *
53: * @author Eugen Neufeld
54: * @author jfaltermeier
55: *
56: */
57: public class CollapsableGroupSWTRenderer extends ContainerSWTRenderer<VGroup> {
58:
59:         private static final int MARGIN = 5;
60:
61:         private SWTGridDescription rendererGridDescription;
62:
63:         private final EMFDataBindingContext dbc;
64:
65:         /**
66:          * Default constructor.
67:          *
68:          * @param vElement the view model element to be rendered
69:          * @param viewContext the view context
70:          * @param reportService the {@link ReportService}
71:          * @param factory the {@link EMFFormsRendererFactory}
72:          */
73:         @Inject
74:         public CollapsableGroupSWTRenderer(VGroup vElement, ViewModelContext viewContext, ReportService reportService,
75:                 EMFFormsRendererFactory factory) {
76:                 super(vElement, viewContext, reportService, factory);
77:                 dbc = new EMFDataBindingContext();
78:         }
79:
80:         @Override
81:         public SWTGridDescription getGridDescription(SWTGridDescription gridDescription) {
82:                 if (rendererGridDescription == null) {
83:                         rendererGridDescription = GridDescriptionFactory.INSTANCE.createSimpleGrid(1, 1, this);
84:                         final SWTGridCell swtGridCell = rendererGridDescription.getGrid().get(0);
85:                         swtGridCell.setVerticalFill(false);
86:                         swtGridCell.setVerticalGrab(false);
87:                 }
88:                 return rendererGridDescription;
89:         }
90:
91:         /**
92:          * {@inheritDoc}
93:          *
94:          * @see org.eclipse.emf.ecp.view.spi.core.swt.ContainerSWTRenderer#renderControl(org.eclipse.emfforms.spi.swt.core.layout.SWTGridCell,
95:          * org.eclipse.swt.widgets.Composite)
96:          */
97:         @Override
98:         protected Control renderControl(SWTGridCell gridCell, final Composite parent) throws NoRendererFoundException,
99:                 NoPropertyDescriptorFoundExeption {
100:                 final CollapsableGroupExpandBar bar = new CollapsableGroupExpandBar(parent, SWT.NONE);
101:                 bar.setBackground(parent.getBackground());
102:
103:                 // First item
104:                 final Composite composite = new Composite(bar, SWT.NONE);
105:                 GridLayoutFactory.fillDefaults().margins(MARGIN, MARGIN).applyTo(composite);
106:                 final ExpandItem item0 = new ExpandItem(bar, SWT.NONE, 0);
107:                 bar.setInitialHeaderHeight(item0.getHeaderHeight());
108:
109:                 final FontDescriptor boldDescriptor = FontDescriptor.createFrom(bar.getFont()).setStyle(SWT.BOLD);
110:                 final Font boldFont = boldDescriptor.createFont(bar.getDisplay());
111:                 bar.setFont(boldFont);
112:
113:                 final ISWTObservableValue target = WidgetProperties.text().observe(item0);
114:                 final IObservableValue modelValue = EMFEditObservables.observeValue(
115:                         AdapterFactoryEditingDomain.getEditingDomainFor(getVElement()), getVElement(),
116:                         VViewPackage.eINSTANCE.getElement_Label());
117:                 dbc.bindValue(target, modelValue);
118:
119:                 final Control containerControl = super.renderControl(gridCell, composite);
120:                 GridDataFactory.fillDefaults().grab(true, false)
121:                         .minSize(containerControl.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, SWT.DEFAULT).applyTo(containerControl);
122:                 final int height = computeHeight(composite);
123:                 item0.setHeight(height);
124:                 item0.setControl(composite);
125:                 bar.setItemComposite(composite);
126:                 bar.addExpandListener(new ExpandListener() {
127:
128:                         @Override
129:                         public void itemCollapsed(ExpandEvent e) {
130:                                 final int headerHeight = item0.getHeaderHeight();
131:                                 item0.setHeight(headerHeight);
132:                                 final Object layoutData = bar.getLayoutData();
133:                                 updateLayoutData(layoutData, headerHeight + 2 * MARGIN);
134:                                 EMFFormsSWTLayoutUtil.adjustParentSize(bar);
135:                                 getVElement().setCollapsed(true);
136:                                 postCollapsed();
137:                         }
138:
139:                         @Override
140:                         public void itemExpanded(ExpandEvent e) {
141:                                 item0.setHeight(computeHeight(composite));
142:                                 final Object layoutData = bar.getLayoutData();
143:                                 updateLayoutData(layoutData, computeHeight(composite) + item0.getHeaderHeight()
144:                                         + 2 * MARGIN);
145:                                 EMFFormsSWTLayoutUtil.adjustParentSize(bar);
146:                                 getVElement().setCollapsed(false);
147:                                 postExpanded();
148:                         }
149:
150:                         // XXX relayout upon expand/collapse will only work properly when the grid data is adjusted
151:                         // this might not be the case for non GridData layout datas
152:                         private void updateLayoutData(final Object layoutData, int height) {
153:                                 if (layoutData instanceof GridData) {
154:                                         final GridData gridData = (GridData) layoutData;
155:                                         gridData.heightHint = height;
156:                                 }
157:                         }
158:
159:                 });
160:                 item0.setExpanded(!getVElement().isCollapsed());
161:                 return bar;
162:         }
163:
164:         /**
165:          * This method gets called after the group has been expanded. Default implementation does nothing.
166:          */
167:         protected void postExpanded() {
168:                 // no op
169:         }
170:
171:         /**
172:          * This method gets called after the group has been collapsed. Default implementation does nothing.
173:          */
174:         protected void postCollapsed() {
175:                 // no op
176:         }
177:
178:         private int computeHeight(Composite composite) {
179:                 // XXX +1 because last pixel gets cut off on windows 7 64
180:                 return composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + 1;
181:         }
182:
183:         /**
184:          * {@link ExpandBar} which takes its item content size into account when computing the size.
185:          *
186:          * @author Johannes Faltermeier
187:          *
188:          */
189:         private static final class CollapsableGroupExpandBar extends ExpandBar {
190:
191:                 private Composite itemComposite;
192:                 private int headerHeight;
193:
194:                 CollapsableGroupExpandBar(Composite parent, int style) {
195:                         super(parent, style);
196:                 }
197:
198:                 /**
199:                  * @param headerHeight the header height
200:                  */
201:                 void setInitialHeaderHeight(int headerHeight) {
202:                         this.headerHeight = headerHeight;
203:                 }
204:
205:                 @Override
206:                 public Point computeSize(int wHint, int hHint, boolean changed) {
207:                         return computeSizeForBar(wHint, hHint, changed);
208:                 }
209:
210:                 @Override
211:                 protected void checkSubclass() {
212:                         /*
213:                          * we have to override expandbar because the size computation does not take the items control size into
214:                          * account. For our use case we need this to enable parent scrolled composites to set the min size
215:                          * correctely.
216:                          */
217:                 }
218:
219:                 void setItemComposite(Composite itemComposite) {
220:                         this.itemComposite = itemComposite;
221:                 }
222:
223:                 private Point computeSizeForBar(int wHint, int hHint, boolean changed) {
224:                         final Point sizeComputedByBar = super.computeSize(wHint, hHint, changed);
225:•                        if (itemComposite != null) {
226:                                 final Point itemSize = itemComposite.computeSize(wHint, hHint, changed);
227:•                                if (itemSize.x > sizeComputedByBar.x) {
228:                                         /* else might be true if the expandbar has a really long group text */
229:                                         sizeComputedByBar.x = itemSize.x;
230:                                 }
231:                                 /* workaround for SWT-Bug 430600 */
232:•                                if (getItemCount() == 1 && getItem(0).getHeaderHeight() < 0) {
233:•                                        if (itemSize.y + headerHeight > sizeComputedByBar.y && getItem(0).getExpanded()) {
234:                                                 sizeComputedByBar.y = itemSize.y + headerHeight;
235:                                         }
236:                                 }
237:                         }
238:                         sizeComputedByBar.x = sizeComputedByBar.x + 2 * MARGIN;
239:                         return sizeComputedByBar;
240:                 }
241:         }
242:
243:         @Override
244:         protected void dispose() {
245:                 if (dbc != null) {
246:                         dbc.dispose();
247:                 }
248:                 super.dispose();
249:         }
250: }