| /******************************************************************************* |
| * 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 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Rushan R. Gilmullin - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.osbp.vaaclipse.presentation.renderers; |
| |
| import java.util.ArrayList; |
| |
| 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.core.services.events.IEventBroker; |
| import org.eclipse.e4.ui.internal.workbench.ContributionsAnalyzer; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| 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.menu.MDirectToolItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MHandledToolItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBar; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBarContribution; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement; |
| import org.eclipse.e4.ui.model.application.ui.menu.MToolBarSeparator; |
| import org.eclipse.e4.ui.workbench.UIEvents; |
| import org.eclipse.e4.ui.workbench.modeling.EModelService; |
| import org.eclipse.osbp.vaaclipse.presentation.utils.GuiUtils; |
| import org.eclipse.osbp.vaaclipse.publicapi.resources.ResourceHelper; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventHandler; |
| |
| import com.vaadin.server.Resource; |
| import com.vaadin.ui.AbstractLayout; |
| import com.vaadin.ui.AbstractOrderedLayout; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.HorizontalLayout; |
| import com.vaadin.ui.VerticalLayout; |
| |
| @SuppressWarnings("restriction") |
| public class ToolBarRenderer extends BasicMenuToolbarTrimbarRenderer { |
| @Inject |
| private MApplication application; |
| @Inject |
| private EModelService modelService; |
| @Inject |
| IEventBroker eventBroker; |
| |
| @PostConstruct |
| public void init() { |
| context.set(ToolBarRenderer.class, this); |
| } |
| |
| @PreDestroy |
| public void contextDisposed() { |
| |
| } |
| |
| @Override |
| public void createWidget(MUIElement element, |
| MElementContainer<MUIElement> parent) { |
| if (!(element instanceof MToolBar)) { |
| return; |
| } |
| |
| MToolBar toolbarModel = (MToolBar) element; |
| processContribution(toolbarModel); |
| |
| AbstractLayout toolBarWidget; |
| |
| if ((MElementContainer<?>) toolbarModel.getParent() instanceof MTrimBar) { |
| MTrimBar parentTrimBar = (MTrimBar) (MElementContainer<?>) toolbarModel |
| .getParent(); |
| int orientation = parentTrimBar.getSide().getValue(); |
| |
| if (orientation == SideValue.TOP_VALUE |
| || orientation == SideValue.BOTTOM_VALUE) { |
| toolBarWidget = new HorizontalLayout() { |
| @Override |
| public void addComponent(Component c) { |
| if (!c.getStyleName().contains("horizontalseparator")) |
| c.addStyleName("horizontaltoolbarlement"); |
| super.addComponent(c); |
| } |
| |
| @Override |
| public void addComponent(Component c, int index) { |
| if (!c.getStyleName().contains("horizontalseparator")) |
| c.addStyleName("horizontaltoolbarlement"); |
| super.addComponent(c, index); |
| } |
| }; |
| toolBarWidget.addStyleName("horizontaltoolbar"); |
| } else { |
| toolBarWidget = new VerticalLayout() { |
| @Override |
| public void addComponent(Component c) { |
| if (!c.getStyleName().contains("verticalseparator")) |
| c.addStyleName("verticaltoolbarlement"); |
| super.addComponent(c); |
| } |
| |
| @Override |
| public void addComponent(Component c, int index) { |
| if (!c.getStyleName().contains("verticalseparator")) |
| c.addStyleName("verticaltoolbarlement"); |
| super.addComponent(c, index); |
| } |
| }; |
| toolBarWidget.addStyleName("verticaltoolbar"); |
| } |
| |
| Component separator = GuiUtils.createSeparator(toolbarModel); |
| if (separator != null) |
| toolBarWidget.addComponent(separator); |
| } else { |
| toolBarWidget = new HorizontalLayout(); |
| Component separator = GuiUtils.createSeparator(toolbarModel); |
| if (separator != null) |
| toolBarWidget.addComponent(separator); |
| } |
| toolBarWidget.setSizeUndefined(); |
| toolBarWidget.addStyleName("toolbar"); |
| |
| for (String css : toolbarModel.getTags()) { |
| toolBarWidget.addStyleName(css); |
| } |
| |
| element.setWidget(toolBarWidget); |
| } |
| |
| /** |
| * @param element |
| */ |
| private void processContribution(MToolBar toolbarModel) { |
| final ArrayList<MToolBarContribution> toContribute = new ArrayList<MToolBarContribution>(); |
| ContributionsAnalyzer.XXXgatherToolBarContributions(toolbarModel, |
| application.getToolBarContributions(), |
| toolbarModel.getElementId(), toContribute); |
| generateContributions(toolbarModel, toContribute); |
| } |
| |
| /** |
| * @param toolbarModel |
| * @param toContribute |
| */ |
| private void generateContributions(MToolBar toolbarModel, |
| ArrayList<MToolBarContribution> toContribute) { |
| |
| AbstractLayout manager = (AbstractLayout) toolbarModel.getWidget(); |
| boolean done = toContribute.size() == 0; |
| while (!done) { |
| ArrayList<MToolBarContribution> curList = new ArrayList<MToolBarContribution>( |
| toContribute); |
| int retryCount = toContribute.size(); |
| toContribute.clear(); |
| |
| for (final MToolBarContribution contribution : curList) { |
| if (!processAddition(toolbarModel, manager, contribution)) { |
| toContribute.add(contribution); |
| } |
| } |
| // 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); |
| } |
| } |
| |
| /** |
| * @param toolbarModel |
| * @param manager |
| * @param contribution |
| * @param existingSeparatorNames |
| * @return <code>true</code> if the contribution was successfuly processed |
| */ |
| private boolean processAddition(final MToolBar toolbarModel, |
| final AbstractLayout manager, MToolBarContribution contribution) { |
| final ToolBarContributionRecord record = new ToolBarContributionRecord( |
| toolbarModel, contribution, this); |
| if (!record.mergeIntoModel()) { |
| return false; |
| } |
| if (record.anyVisibleWhen()) { |
| final IEclipseContext parentContext = modelService |
| .getContainingContext(toolbarModel); |
| parentContext.runAndTrack(new RunAndTrack() { |
| @Override |
| public boolean changed(IEclipseContext context) { |
| if (toolbarModel.getWidget() == null) { |
| return false; |
| } |
| |
| record.updateVisibility(parentContext.getActiveLeaf()); |
| |
| return true; |
| } |
| }); |
| } |
| |
| return true; |
| } |
| |
| @Override |
| public void processContents(final MElementContainer<MUIElement> container) { |
| MToolBar toolBar = (MToolBar) (MElementContainer<?>) container; |
| AbstractLayout toolBarWidget = (AbstractLayout) container.getWidget(); |
| if (toolBarWidget != null) { |
| for (MUIElement element : container.getChildren()) { |
| if (element instanceof MHandledToolItem |
| || element instanceof MDirectToolItem) { |
| toolBarWidget.addComponent((Component) element.getWidget()); |
| } else if (element instanceof MToolBarSeparator) { |
| toolBarWidget.addComponent(GuiUtils |
| .createSeparator(toolBar)); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void addChildGui(MUIElement child, |
| MElementContainer<MUIElement> element) { |
| if (!(child instanceof MToolBarElement && (MElementContainer<?>) element instanceof MToolBar)) |
| return; |
| |
| MToolBar toolBar = (MToolBar) (MElementContainer<?>) element; |
| |
| AbstractOrderedLayout toolbarWidget = (AbstractOrderedLayout) element |
| .getWidget(); |
| Component childWidget = (Component) child.getWidget(); |
| if (toolbarWidget == null || childWidget == null) |
| return; |
| int index = indexOf(child, element)/* + 1 */; // +1 becouse the first |
| // element is toolbar |
| // drag handler |
| // (separator) |
| // if (element instanceof MToolBarSeparator) { |
| // toolbarWidget |
| // .addComponent(GuiUtils.createSeparator(toolBar), index); |
| // } else { |
| toolbarWidget.addComponent(childWidget, index); |
| // } |
| |
| toolbarWidget.requestRepaint(); |
| } |
| |
| @Override |
| public void setVisible(MUIElement changedElement, boolean visible) { |
| ((AbstractOrderedLayout) changedElement.getWidget()) |
| .setVisible(visible); |
| } |
| |
| @PostConstruct |
| public void postConstruct() { |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_ALL, itemUpdater); |
| eventBroker.subscribe(UIEvents.Menu.TOPIC_ENABLED, itemUpdater); |
| eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, |
| childrenMoveUpdater); |
| } |
| |
| @PreDestroy |
| public void preDestroy() { |
| eventBroker.unsubscribe(itemUpdater); |
| eventBroker.unsubscribe(childrenMoveUpdater); |
| } |
| |
| private EventHandler itemUpdater = new EventHandler() { |
| public void handleEvent(Event event) { |
| // Ensure that this event is for a MMenuItem |
| if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBar)) |
| return; |
| |
| MToolBar model = (MToolBar) event |
| .getProperty(UIEvents.EventTags.ELEMENT); |
| AbstractOrderedLayout ici = (AbstractOrderedLayout) model |
| .getWidget(); |
| if (ici == null) { |
| return; |
| } |
| |
| String attName = (String) event |
| .getProperty(UIEvents.EventTags.ATTNAME); |
| Object newValue = event.getProperty(UIEvents.EventTags.NEW_VALUE); |
| if (UIEvents.UILabel.ICONURI.equals(attName)) { |
| Resource icon = ResourceHelper |
| .createResource((String) newValue); |
| ici.setIcon(icon); |
| } else if (UIEvents.UILabel.TOOLTIP.equals(attName)) { |
| ici.setDescription((String) newValue); |
| } else if (UIEvents.Item.ENABLED.equals(attName)) { |
| ici.setEnabled((boolean) newValue); |
| } |
| } |
| }; |
| |
| private EventHandler childrenMoveUpdater = new EventHandler() { |
| @SuppressWarnings("unchecked") |
| public void handleEvent(Event event) { |
| // Ensure that this event is for a MMenuItem |
| if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MToolBar)) |
| return; |
| |
| MElementContainer<MUIElement> toolbar = (MElementContainer<MUIElement>) event |
| .getProperty(UIEvents.EventTags.ELEMENT); |
| |
| String type = (String) event.getProperty(UIEvents.EventTags.TYPE); |
| |
| // on move, we unrender an render the UI again |
| // |
| if (UIEvents.EventTypes.MOVE.equals(type)) { |
| for (MUIElement item : toolbar.getChildren()) { |
| removeChildGui(item, toolbar); |
| } |
| |
| for (MUIElement item : toolbar.getChildren()) { |
| addChildGui(item, toolbar); |
| } |
| } |
| } |
| }; |
| } |