| /******************************************************************************* |
| * 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 javax.annotation.PostConstruct; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| |
| import org.eclipse.e4.core.contexts.ContextInjectionFactory; |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.di.annotations.CanExecute; |
| import org.eclipse.e4.core.services.contributions.IContributionFactory; |
| 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.menu.MDirectMenuItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MHandledItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MItem; |
| import org.eclipse.e4.ui.model.application.ui.menu.MMenu; |
| import org.eclipse.e4.ui.model.application.ui.menu.MMenuItem; |
| //import org.eclipse.e4.ui.model.application.ui.menu.MOpaqueMenuItem; |
| import org.eclipse.e4.ui.workbench.UIEvents; |
| import org.eclipse.osbp.vaaclipse.presentation.utils.Commons; |
| 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.MenuBar; |
| import com.vaadin.ui.MenuBar.Command; |
| import com.vaadin.ui.MenuBar.MenuItem; |
| |
| @SuppressWarnings("restriction") |
| public class MenuItemRenderer extends ItemRenderer { |
| |
| @Inject |
| IContributionFactory contributionFactory; |
| |
| @Inject |
| IEventBroker eventBroker; |
| |
| 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 MMenuItem)) |
| return; |
| |
| MMenuItem itemModel = (MMenuItem) event |
| .getProperty(UIEvents.EventTags.ELEMENT); |
| |
| MenuItem ici = (MenuItem) itemModel.getWidget(); |
| if (ici == null) { |
| return; |
| } |
| |
| String attName = (String) event |
| .getProperty(UIEvents.EventTags.ATTNAME); |
| String newValue = (String) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| if (UIEvents.UILabel.LABEL.equals(attName)) { |
| ici.setText(newValue); |
| } else if (UIEvents.UILabel.ICONURI.equals(attName)) { |
| Resource icon = ResourceHelper.createResource(newValue); |
| ici.setIcon(icon); |
| } else if (UIEvents.UILabel.TOOLTIP.equals(attName)) { |
| ici.setDescription(newValue); |
| } |
| } |
| }; |
| |
| private EventHandler enabledUpdater = new EventHandler() { |
| public void handleEvent(Event event) { |
| // Ensure that this event is for a MMenuItem |
| if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MMenuItem)) |
| return; |
| |
| MMenuItem itemModel = (MMenuItem) event |
| .getProperty(UIEvents.EventTags.ELEMENT); |
| MenuItem ici = (MenuItem) itemModel.getWidget(); |
| if (ici != null) { |
| Boolean newValue = (Boolean) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| ici.setEnabled(newValue); |
| } |
| } |
| }; |
| |
| private EventHandler selectedUpdater = new EventHandler() { |
| public void handleEvent(Event event) { |
| // Ensure that this event is for a MMenuItem |
| if (!(event.getProperty(UIEvents.EventTags.ELEMENT) instanceof MMenuItem)) |
| return; |
| |
| MMenuItem itemModel = (MMenuItem) event |
| .getProperty(UIEvents.EventTags.ELEMENT); |
| MenuItem ici = (MenuItem) itemModel.getWidget(); |
| if (ici != null) { |
| Boolean newValue = (Boolean) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| ici.setChecked(newValue); |
| } |
| } |
| }; |
| |
| @PostConstruct |
| public void postConstruct() { |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_ALL, itemUpdater); |
| eventBroker.subscribe(UIEvents.Item.TOPIC_ENABLED, enabledUpdater); |
| eventBroker.subscribe(UIEvents.Item.TOPIC_SELECTED, selectedUpdater); |
| eventBroker.subscribe(UIEvents.ElementContainer.TOPIC_CHILDREN, |
| childrenMoveUpdater); |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_LABEL, |
| localizeLabel); |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_LOCALIZED_TOOLTIP, |
| localizeTooltip); |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_LABEL, localizeLabel); |
| eventBroker.subscribe(UIEvents.UILabel.TOPIC_TOOLTIP, localizeTooltip); |
| } |
| |
| @PreDestroy |
| public void preDestroy() { |
| eventBroker.unsubscribe(itemUpdater); |
| eventBroker.unsubscribe(enabledUpdater); |
| eventBroker.unsubscribe(selectedUpdater); |
| eventBroker.unsubscribe(childrenMoveUpdater); |
| eventBroker.unsubscribe(localizeLabel); |
| eventBroker.unsubscribe(localizeTooltip); |
| } |
| |
| 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 MMenu)) |
| return; |
| |
| MElementContainer<MUIElement> menu = (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 : menu.getChildren()) { |
| removeChildGui(item, menu); |
| } |
| |
| for (MUIElement item : menu.getChildren()) { |
| createWidget(item, menu); |
| } |
| } |
| } |
| }; |
| |
| @Override |
| public void createWidget(MUIElement element, |
| MElementContainer<MUIElement> parent) { |
| |
| if (!element.isToBeRendered()) |
| return; |
| |
| if (element instanceof MMenuItem) { |
| MMenuItem model = (MMenuItem) element; |
| |
| // -------------------- |
| // Prepare the text |
| String text = prepareText(model); |
| text = text.replaceAll("&", ""); |
| |
| // Prepare the icon |
| Resource icon = model.getIconURI() != null ? ResourceHelper |
| .createResource(model.getIconURI()) : null; |
| |
| // Prepare the command |
| Command command = null; |
| if (model instanceof MDirectMenuItem) { |
| final MDirectMenuItem item = (MDirectMenuItem) model; |
| item.setObject(contributionFactory.create( |
| item.getContributionURI(), getContext(item))); |
| |
| command = createEventHandler(item); |
| } else if (model instanceof MHandledMenuItem) { |
| final MHandledMenuItem item = (MHandledMenuItem) model; |
| command = createParametrizedCommandEventHandler(item); |
| } |
| |
| MUIElement nextRenderableAndVisible = findNextRendarableAndVisible( |
| element, parent); |
| MenuItem item = null; |
| if (nextRenderableAndVisible == null) |
| item = ((MenuItem) parent.getWidget()).addItem(text, icon, |
| command); |
| else |
| item = ((MenuItem) parent.getWidget()).addItemBefore(text, |
| icon, command, |
| (MenuItem) nextRenderableAndVisible.getWidget()); |
| // ----------------- |
| |
| element.setWidget(item); |
| |
| updateItemEnablement(model); |
| item.setEnabled(model.isEnabled()); |
| |
| // set the check mode |
| switch (model.getType()) { |
| case CHECK: |
| item.setCheckable(true); |
| item.setChecked(model.isSelected()); |
| break; |
| default: |
| item.setCheckable(false); |
| break; |
| } |
| |
| registerEnablementUpdaters(model); |
| } |
| } |
| |
| protected void updateItemEnablement(MItem item) { |
| if (!(item.getWidget() instanceof MenuItem)) |
| return; |
| |
| MenuItem widget = (MenuItem) item.getWidget(); |
| if (widget == null) |
| return; |
| |
| item.setEnabled(canExecute(item)); |
| } |
| |
| public boolean canExecute(MItem item) { |
| if (item instanceof MHandledItem) |
| return canExecute((MHandledItem) item); |
| else if (item instanceof MDirectMenuItem) |
| return canExecute((MDirectMenuItem) item); |
| else |
| return false; |
| } |
| |
| private boolean canExecute(MDirectMenuItem item) { |
| final IEclipseContext eclipseContext = getContext(item); |
| eclipseContext.set(MItem.class, item); |
| setupContext(eclipseContext, item); |
| return (Boolean) ContextInjectionFactory.invoke(item, CanExecute.class, |
| eclipseContext, true); |
| } |
| |
| @Override |
| public void hookControllerLogic(MUIElement me) { |
| // the listener already attached (when created - vaadin API issue) |
| } |
| |
| @Override |
| protected void setupContext(IEclipseContext context, MItem item) { |
| context.set(MMenuItem.class, (MMenuItem) item); |
| |
| if (item instanceof MDirectMenuItem) |
| context.set(MDirectMenuItem.class, (MDirectMenuItem) item); |
| else if (item instanceof MHandledMenuItem) |
| context.set(MHandledMenuItem.class, (MHandledMenuItem) item); |
| // TODO luna - check this |
| // else if (item instanceof MOpaqueMenuItem) |
| // context.set(MOpaqueMenuItem.class, (MOpaqueMenuItem) item); |
| } |
| |
| @Override |
| public void setVisible(MUIElement changedElement, boolean visible) { |
| ((MenuItem) changedElement.getWidget()).setVisible(visible); |
| } |
| |
| @Override |
| public void removeChildGui(MUIElement element, |
| MElementContainer<MUIElement> parent) { |
| MenuItem childItem = (MenuItem) element.getWidget(); |
| |
| if (parent.getWidget() instanceof MenuBar) { |
| MenuBar bar = (MenuBar) parent.getWidget(); |
| bar.removeItem(childItem); |
| } else if (parent.getWidget() instanceof MenuItem) { |
| MenuItem parentItem = (MenuItem) parent.getWidget(); |
| parentItem.removeChild(childItem); |
| } |
| } |
| |
| private EventHandler localizeLabel = new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| Object element = event.getProperty(UIEvents.EventTags.ELEMENT); |
| |
| if (!(element instanceof MMenuItem)) |
| return; |
| |
| MMenuItem item = (MMenuItem) element; |
| final MenuItem menuItem = (MenuItem) item.getWidget(); |
| |
| String newValue = (String) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| |
| String label = Commons.trim(newValue); |
| if (menuItem != null) { |
| menuItem.setText(label); |
| } |
| } |
| }; |
| |
| private EventHandler localizeTooltip = new EventHandler() { |
| @Override |
| public void handleEvent(Event event) { |
| Object element = event.getProperty(UIEvents.EventTags.ELEMENT); |
| |
| if (!(element instanceof MMenuItem)) |
| return; |
| |
| MMenuItem item = (MMenuItem) element; |
| final MenuItem menuItem = (MenuItem) item.getWidget(); |
| |
| String newValue = (String) event |
| .getProperty(UIEvents.EventTags.NEW_VALUE); |
| |
| if (menuItem != null) { |
| menuItem.setDescription(newValue); |
| } |
| } |
| }; |
| } |