package net.jeeeyul.eclipse.themes;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import net.jeeeyul.eclipse.themes.css.internal.CSSClasses;
import net.jeeeyul.eclipse.themes.internal.Debug;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MStackElement;
import org.eclipse.e4.ui.services.IStylingEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.UIEvents.ElementContainer;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.xtext.xbase.lib.Functions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
public class EmptyPartStackProcessor {
@Inject
IEventBroker broker;
@Inject
IStylingEngine engine;
@Inject
EModelService modelService;
private EventHandler widgetAssignListener = new EventHandler() {
@Override
public void handleEvent(Event event) {
if (!UIEvents.isSET(event)) {
return;
}
Object e = event.getProperty("ChangedElement");
if (e instanceof MPartStack) {
MPartStack ps = (MPartStack) e;
applyEmptyTag(ps);
}
}
};
private EventHandler modelChildrenListener = new EventHandler() {
@Override
public void handleEvent(Event event) {
if (UIEvents.isADD(event) || UIEvents.isREMOVE(event)) {
Object parent = event.getProperty("ChangedElement");
if (parent instanceof MPartStack) {
MPartStack stack = (MPartStack) parent;
applyTagsAndClasses(stack);
}
}
}
};
private EventHandler toggleViewVisibilityListener = new EventHandler() {
@Override
public void handleEvent(Event event) {
Object sender = event.getProperty("ChangedElement");
if (sender instanceof MPlaceholder) {
MPlaceholder placeholder = (MPlaceholder) sender;
Object parent = placeholder.getParent();
if (parent instanceof MPartStack) {
applyTagsAndClasses((MPartStack) parent);
}
}
}
};
private void applyEmptyTag(MPartStack stack) {
boolean hasEmptyTag = stack.getTags().contains("empty");
boolean hasChild = hasVisibleChild(stack);
if (hasChild == false && hasEmptyTag == false) {
stack.getTags().add("empty");
}
else if (hasEmptyTag && hasChild) {
stack.getTags().remove("empty");
}
}
private void applyTagsAndClasses(MPartStack stack) {
Widget widget = (Widget) stack.getWidget();
if (widget == null || widget.isDisposed()) {
return;
}
CSSClasses styleClasses = CSSClasses.getStyleClasses(widget);
boolean hasEmptyTag = stack.getTags().contains("empty");
boolean hasChild = hasVisibleChild(stack);
if (hasChild == false && hasEmptyTag == false) {
stack.getTags().add("empty");
styleClasses.add("empty");
engine.setClassname(widget, styleClasses.toString());
Debug.println("New Empty Part Stack Found!");
}
else if (hasEmptyTag && hasChild) {
stack.getTags().remove("empty");
styleClasses.remove("empty");
engine.setClassname(widget, styleClasses.toString());
Debug.println("Empty Part Stack about to have a new child");
}
}
@PreDestroy
public void dispose() {
broker.unsubscribe(widgetAssignListener);
broker.unsubscribe(modelChildrenListener);
Debug.println("Empty Part Stack Processor is stopped.");
}
@Execute
public void execute(MApplication app) {
Debug.println("Empty Part Stack Processor is started");
// Initial PartStack Rendering. (for e4 App)
broker.subscribe(UIEvents.UIElement.TOPIC_WIDGET, widgetAssignListener);
// Catches editor opening and closing
broker.subscribe(ElementContainer.TOPIC_CHILDREN, modelChildrenListener);
// Catches view closing.
broker.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED, toggleViewVisibilityListener);
}
private boolean hasVisibleChild(MPartStack stack) {
boolean hasChild = IterableExtensions.exists(stack.getChildren(), new Functions.Function1<MStackElement, Boolean>() {
@Override
public Boolean apply(MStackElement e) {
return e.isToBeRendered();
}
});
return hasChild;
}
}