Java tutorial
/******************************************************************************* * Copyright (c) 2012 Rushan R. Gilmullin 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: * Rushan R. Gilmullin - initial API and implementation *******************************************************************************/ package org.semanticsoft.vaaclipse.presentation.renderers; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.contexts.RunAndTrack; import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.MCoreExpression; 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.SideValue; import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar; import org.eclipse.e4.ui.model.application.ui.basic.MTrimElement; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; import org.eclipse.e4.ui.model.application.ui.menu.MTrimContribution; import org.eclipse.e4.ui.services.internal.events.EventBroker; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.ExpressionContext; import org.semanticsoft.vaaclipse.api.VaadinExecutorService; import org.semanticsoft.vaaclipse.presentation.widgets.TrimmedWindowContent; import com.vaadin.server.Sizeable.Unit; import com.vaadin.ui.AbstractLayout; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Component; import com.vaadin.ui.ComponentContainer; import com.vaadin.ui.CssLayout; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; @SuppressWarnings("restriction") public class TrimBarRenderer extends VaadinRenderer { @Inject MApplication app; @Inject EventBroker eventBroker; @Inject EModelService modelService; @Inject VaadinExecutorService execService; private HashMap<MTrimBar, ArrayList<ArrayList<MTrimElement>>> pendingCleanup = new HashMap<MTrimBar, ArrayList<ArrayList<MTrimElement>>>(); @PostConstruct public void subsrcribe() { } @PreDestroy public void unsubscribe() { } @Override public void createWidget(MUIElement element, MElementContainer<MUIElement> parent) { if (!(element instanceof MTrimBar)) { return; } MTrimBar mTrimBar = (MTrimBar) element; int orientation = mTrimBar.getSide().getValue(); AbstractLayout trimBar = null; if (orientation == SideValue.BOTTOM_VALUE) { trimBar = new CssLayout(); trimBar.addStyleName("horizontaltrimbar"); } else if (orientation == SideValue.TOP_VALUE) { trimBar = new CssLayout(); trimBar.addStyleName("toptrimbar"); } else if (orientation == SideValue.LEFT_VALUE || orientation == SideValue.RIGHT_VALUE) { trimBar = new VerticalLayout(); trimBar.addStyleName("verticaltrimbar"); } trimBar.setSizeUndefined(); if (orientation == SideValue.BOTTOM_VALUE || orientation == SideValue.TOP_VALUE) { trimBar.setWidth("100%"); } element.setWidget(trimBar); } @Override public void processContents(MElementContainer<MUIElement> container) { final MTrimBar trimBar = (MTrimBar) ((MElementContainer<?>) container); int orientation = trimBar.getSide().getValue(); AbstractLayout trimBarWidget = (AbstractLayout) container.getWidget(); if (orientation == SideValue.TOP_VALUE || orientation == SideValue.BOTTOM_VALUE) trimBarWidget.setHeight(-1, Unit.PIXELS); else trimBarWidget.setWidth(-1, Unit.PIXELS); boolean isFirst = true; trimBarWidget.removeAllComponents(); for (MUIElement element : container.getChildren()) { if (element.isToBeRendered()) { ComponentContainer subToolbar = (ComponentContainer) element.getWidget(); subToolbar.setVisible(element.isVisible()); if (subToolbar != null) { if (orientation == SideValue.TOP_VALUE || orientation == SideValue.BOTTOM_VALUE) subToolbar.addStyleName("horizontaltrimelement"); else subToolbar.addStyleName("verticaltrimelement"); subToolbar.setSizeUndefined(); trimBarWidget.addComponent(subToolbar); isFirst = false; } } } //--- IEclipseContext ctx = getContext(container); final ExpressionContext eContext = new ExpressionContext(ctx); //visible when support for original trimbar elements (without contributed) for (final MTrimElement child : trimBar.getChildren()) { if (child.getVisibleWhen() != null) { ctx.runAndTrack(new RunAndTrack() { @Override public boolean changed(IEclipseContext context) { if (!trimBar.isToBeRendered() || !trimBar.isVisible() || trimBar.getWidget() == null) { return false; } final boolean rc = ContributionsAnalyzer.isVisible((MCoreExpression) child.getVisibleWhen(), eContext); execService.invokeLater(new Runnable() { @Override public void run() { child.setToBeRendered(rc); } }); return true; } }); } } //contributions ArrayList<MTrimContribution> toContribute = new ArrayList<MTrimContribution>(); ContributionsAnalyzer.gatherTrimContributions(trimBar, app.getTrimContributions(), trimBar.getElementId(), toContribute, eContext); addTrimContributions(trimBar, toContribute, ctx, eContext); refreshVisibility(trimBar); } private void refreshVisibility(MTrimBar trimBar) { AbstractLayout trimBarWidget = (AbstractLayout) trimBar.getWidget(); int orientation = trimBar.getSide().getValue(); trimBarWidget.setVisible(trimBarWidget.getComponentCount() != 0); if (orientation == SideValue.TOP_VALUE) { MWindow window = modelService.getTopLevelWindowFor(trimBar); TrimmedWindowContent windowContent = (TrimmedWindowContent) ((Panel) window.getWidget()).getContent(); Component topbar = windowContent.getTopbar(); if (topbar != null) topbar.setVisible(trimBarWidget.getComponentCount() != 0); } } private void addTrimContributions(final MTrimBar trimModel, ArrayList<MTrimContribution> toContribute, IEclipseContext ctx, final ExpressionContext eContext) { HashSet<String> existingToolbarIds = new HashSet<String>(); for (MTrimElement item : trimModel.getChildren()) { String id = item.getElementId(); if (item instanceof MToolBar && id != null) { existingToolbarIds.add(id); } } boolean done = toContribute.size() == 0; while (!done) { ArrayList<MTrimContribution> curList = new ArrayList<MTrimContribution>(toContribute); int retryCount = toContribute.size(); toContribute.clear(); for (final MTrimContribution contribution : curList) { final ArrayList<MTrimElement> toRemove = new ArrayList<MTrimElement>(); if (!ContributionsAnalyzer.processAddition(trimModel, contribution, toRemove, existingToolbarIds)) { toContribute.add(contribution); } else { if (contribution.getVisibleWhen() != null) { ctx.runAndTrack(new RunAndTrack() { @Override public boolean changed(IEclipseContext context) { if (!trimModel.isToBeRendered() || !trimModel.isVisible() || trimModel.getWidget() == null) { return false; } final boolean rc = ContributionsAnalyzer.isVisible(contribution, eContext); execService.invokeLater(new Runnable() { @Override public void run() { for (MTrimElement child : toRemove) { child.setToBeRendered(rc); } } }); return true; } }); } ArrayList<ArrayList<MTrimElement>> lists = pendingCleanup.get(trimModel); if (lists == null) { lists = new ArrayList<ArrayList<MTrimElement>>(); pendingCleanup.put(trimModel, lists); } lists.add(toRemove); } } // We're done if the retryList is now empty (everything done) or // if the list hasn't changed at all (no hope) done = (toContribute.size() == 0) || (toContribute.size() == retryCount); } } @Override public void addChildGui(MUIElement child, MElementContainer<MUIElement> element) { if (!(child instanceof MTrimElement && (MElementContainer<?>) element instanceof MTrimBar)) return; MTrimBar trimBar = (MTrimBar) (MElementContainer<?>) element; final Component childWidget = (Component) child.getWidget(); childWidget.setVisible(child.isVisible()); childWidget.setSizeUndefined(); int orientation = trimBar.getSide().getValue(); if (orientation == SideValue.TOP_VALUE || orientation == SideValue.BOTTOM_VALUE) childWidget.addStyleName("horizontaltrimelement"); else childWidget.addStyleName("verticaltrimelement"); int index = indexOf(child, element); if (element.getWidget() instanceof CssLayout) { CssLayout trimWidget = (CssLayout) element.getWidget(); trimWidget.addComponent(childWidget, index); trimWidget.markAsDirty(); } else if (element.getWidget() instanceof AbstractOrderedLayout) { AbstractOrderedLayout trimWidget = (AbstractOrderedLayout) element.getWidget(); trimWidget.addComponent(childWidget, index); trimWidget.markAsDirty(); } refreshVisibility(trimBar); } @Override public void removeChildGui(MUIElement child, MElementContainer<MUIElement> element) { if (!(child instanceof MTrimElement && (MElementContainer<?>) element instanceof MTrimBar)) return; super.removeChildGui(child, element); Component trimWidget = (Component) element.getWidget(); MTrimBar trimBar = (MTrimBar) (MElementContainer<?>) element; refreshVisibility(trimBar); trimWidget.markAsDirty(); } }