package org.xmind.cathy.internal.renderer; import javax.inject.Inject; import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.e4.ui.model.application.ui.MElementContainer; import org.eclipse.e4.ui.model.application.ui.MUIElement; import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer; import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement; import org.eclipse.e4.ui.workbench.UIEvents; import org.eclipse.e4.ui.workbench.renderers.swt.SWTPartRenderer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.osgi.service.event.Event; public class XSashRenderer extends SWTPartRenderer { private static final int UNDEFINED_WEIGHT = -1; private static final int DEFAULT_WEIGHT = 5000; private int processedContent = 0; @SuppressWarnings("unchecked") @Inject @Optional private void subscribeTopicOrientationChanged( @UIEventTopic(UIEvents.GenericTile.TOPIC_HORIZONTAL) Event event) { // Ensure that this event is for a MPartSashContainer MUIElement element = (MUIElement) event .getProperty(UIEvents.EventTags.ELEMENT); if (element.getRenderer() != XSashRenderer.this) { return; } forceLayout((MElementContainer<MUIElement>) element); } @SuppressWarnings("unchecked") @Inject @Optional private void subscribeTopicSashWeightChanged( @UIEventTopic(UIEvents.UIElement.TOPIC_CONTAINERDATA) Event event) { // Ensure that this event is for a MPartSashContainer MUIElement element = (MUIElement) event .getProperty(UIEvents.EventTags.ELEMENT); if (element.getRenderer() != XSashRenderer.this) { return; } forceLayout((MElementContainer<MUIElement>) element); } /** * @param pscModel */ protected void forceLayout(MElementContainer<MUIElement> pscModel) { if (processedContent != 0) { return; } // layout the containing Composite while (!(pscModel.getWidget() instanceof Composite)) pscModel = pscModel.getParent(); Composite s = (Composite) pscModel.getWidget(); s.layout(true, true); } @Override public Object createWidget(final MUIElement element, Object parent) { MUIElement elementParent = element.getParent(); if (elementParent == null && element.getCurSharedRef() != null) elementParent = element.getCurSharedRef(); if (elementParent != null && elementParent.getRenderer() == this) { Rectangle newRect = new Rectangle(0, 0, 0, 0); // If my layout's container gets disposed 'unbind' the sash elements if (parent instanceof Composite) { ((Composite) parent).addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { element.setWidget(null); element.setRenderer(null); } }); } return newRect; } // Check to see if this is a new PSC added 'above' the previous 'root' // sash Composite sashComposite = null; MPartSashContainer psc = (MPartSashContainer) element; for (MPartSashContainerElement psce : psc.getChildren()) { if (psce instanceof MPartSashContainer && psce.getWidget() instanceof Composite) { // 'Adopt' the previous root's layout / composite sashComposite = (Composite) psce.getWidget(); bindWidget(psce, new Rectangle(0, 0, 0, 0)); } } // This is a 'root' sash container, create a composite if (sashComposite == null) sashComposite = new Composite((Composite) parent, SWT.NONE); sashComposite.setLayout(new XSashLayout(element)); return sashComposite; } @Override public void childRendered(MElementContainer<MUIElement> parentElement, MUIElement element) { super.childRendered(parentElement, element); // Ensure that the element's 'containerInfo' is initialized int weight = getWeight(element); if (weight == UNDEFINED_WEIGHT) { element.setContainerData(Integer.toString(DEFAULT_WEIGHT)); } forceLayout(parentElement); } @Override public void processContents(MElementContainer<MUIElement> container) { try { processedContent++; super.processContents(container); } finally { processedContent--; if (processedContent == 0) { forceLayout(container); } } } @Override public void hideChild(MElementContainer<MUIElement> parentElement, MUIElement child) { super.hideChild(parentElement, child); forceLayout(parentElement); } @Override public Object getUIContainer(MUIElement element) { // OK, find the 'root' of the sash container MUIElement parentElement = element.getParent(); while (parentElement.getRenderer() == this && !(parentElement.getWidget() instanceof Composite)) parentElement = parentElement.getParent(); if (parentElement.getWidget() instanceof Composite) return parentElement.getWidget(); return null; } private static int getWeight(MUIElement element) { String info = element.getContainerData(); if (info == null || info.length() == 0) { element.setContainerData(Integer.toString(10000)); info = element.getContainerData(); } try { int value = Integer.parseInt(info); return value; } catch (NumberFormatException e) { return UNDEFINED_WEIGHT; } } }