/*******************************************************************************
* Copyright (c) 2011 Kai Toedter and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html.
*
* Contributors:
* Kai Toedter - initial API and implementation
******************************************************************************/
package com.toedter.e4.ui.workbench.renderers.swt;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.e4.core.services.events.IEventBroker;
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.workbench.UIEvents;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
import com.toedter.e4.ui.workbench.generic.GenericRenderer;
import com.toedter.e4.ui.workbench.swt.SWTPresentationEngine;
import com.toedter.e4.ui.workbench.swt.layouts.SimpleTrimLayout;
@SuppressWarnings("restriction")
public class SashRenderer extends GenericRenderer {
@Inject
private IEventBroker eventBroker;
private EventHandler sashOrientationHandler;
private EventHandler sashWeightHandler;
@Override
public void createWidget(MUIElement element, MElementContainer<MUIElement> parent) {
if (!(element instanceof MPartSashContainer)) {
return;
}
final MPartSashContainer partSashContainer = (MPartSashContainer) element;
SashForm sashForm = new SashForm((Composite) parent.getWidget(), SWT.NONE);
if (parent.getWidget() instanceof Shell) {
sashForm.setLayoutData(SimpleTrimLayout.CENTER);
}
if (partSashContainer.isHorizontal()) {
sashForm.setOrientation(SWT.HORIZONTAL);
} else {
sashForm.setOrientation(SWT.VERTICAL);
}
element.setWidget(sashForm);
}
@Override
public void processContents(final MElementContainer<MUIElement> element) {
if (((MUIElement) element instanceof MPartSashContainer)) {
if (element.getChildren().size() == 2) {
SashForm sashForm = (SashForm) element.getWidget();
Shell limbo = SWTPresentationEngine.getLimboShell();
int visibleChildrenCount = 0;
for (int i = 0; i < 2; i++) {
MUIElement childElement = element.getChildren().get(i);
Control childControl = (Control) childElement.getWidget();
if (!childElement.isVisible()) {
Control[] children = sashForm.getChildren();
for (Control child : children) {
if (child == childElement.getWidget()
|| (child == ((Control) childElement.getWidget()).getParent())) {
child.setParent(limbo);
}
}
} else {
visibleChildrenCount++;
// do always 2 re-parentings to make sure that the
// original order is restored
if (childControl.getParent().getParent() == limbo
|| childControl.getParent().getParent() == sashForm) {
childControl.getParent().setParent(limbo);
childControl.getParent().setParent(sashForm);
} else if (childControl.getParent() == limbo || childControl.getParent() == sashForm) {
childControl.setParent(limbo);
childControl.setParent(sashForm);
}
}
}
sashForm.setVisible(visibleChildrenCount != 0);
sashForm.layout();
element.setVisible(visibleChildrenCount != 0);
} else {
System.err.println("A sash has to have 2 children");
}
}
}
@Override
public void hookControllerLogic(final MUIElement element) {
sashOrientationHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
// Ensure that this event is for a MPartSashContainer
MUIElement element = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
if (element.getRenderer() != SashRenderer.this) {
return;
}
forceLayout((MElementContainer<MUIElement>) element);
}
};
eventBroker.subscribe(UIEvents.GenericTile.TOPIC_HORIZONTAL, sashOrientationHandler);
sashWeightHandler = new EventHandler() {
@Override
public void handleEvent(Event event) {
// Ensure that this event is for a MPartSashContainer
MUIElement element = (MUIElement) event.getProperty(UIEvents.EventTags.ELEMENT);
MElementContainer<MUIElement> parent = element.getParent();
if (parent.getRenderer() != SashRenderer.this) {
return;
}
forceLayout(parent);
}
};
eventBroker.subscribe(UIEvents.UIElement.TOPIC_CONTAINERDATA, sashWeightHandler);
final SashForm sashForm = (SashForm) element.getWidget();
System.out.println("SashRenderer.hookControllerLogic()");
Control[] children = sashForm.getChildren();
children[0].addControlListener(new ControlListener() {
@Override
public void controlResized(ControlEvent e) {
int[] weights = sashForm.getWeights();
String weightsString = "";
boolean first = true;
for (int i = 0; i < weights.length; i++) {
if (!first) {
weightsString += ",";
}
weightsString += weights[i];
first = false;
}
element.setContainerData(weightsString);
}
@Override
public void controlMoved(ControlEvent e) {
}
});
String weightString = element.getContainerData();
if (weightString != null) {
String[] results = weightString.split(",");
int[] weights = new int[results.length];
for (int i = 0; i < results.length; i++) {
weights[i] = Integer.parseInt(results[i]);
}
sashForm.setWeights(weights);
}
}
@PreDestroy
void preDestroy() {
eventBroker.unsubscribe(sashOrientationHandler);
eventBroker.unsubscribe(sashWeightHandler);
}
protected void forceLayout(MElementContainer<MUIElement> pscModel) {
// layout the containing Composite
while (!(pscModel.getWidget() instanceof Control)) {
pscModel = pscModel.getParent();
}
Control ctrl = (Control) pscModel.getWidget();
if (ctrl instanceof Shell) {
((Shell) ctrl).layout(null, SWT.ALL | SWT.CHANGED | SWT.DEFER);
} else {
ctrl.getParent().layout(null, SWT.ALL | SWT.CHANGED | SWT.DEFER);
}
}
@Override
public void setVisible(MUIElement element, boolean visible) {
System.out.println("SWT SashRenderer.setVisible()");
SashForm sashForm = (SashForm) element.getWidget();
sashForm.setVisible(visible);
}
}