blob: a996015df608262971759d06713598dbc40dee5a [file] [log] [blame]
/*******************************************************************************
* 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.fastview;
import javax.annotation.PostConstruct;
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.MUILabel;
import org.eclipse.e4.ui.model.application.ui.SideValue;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
import org.eclipse.e4.ui.model.application.ui.basic.MTrimBar;
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.workbench.IPresentationEngine;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.vaaclipse.api.Behaviour;
import org.eclipse.osbp.vaaclipse.presentation.widgets.TrimmedWindowContent;
import org.eclipse.osbp.vaaclipse.widgets.FastView;
import org.osgi.service.event.EventHandler;
import com.vaadin.event.MouseEvents.ClickEvent;
import com.vaadin.event.MouseEvents.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/**
* @author rushan
*
*/
public class SingleElementFastViewManager {
@Inject
UI vaadinUI;
@Inject
Behaviour behaviour;
@Inject
MUIElement minimizedElement;
@Inject
MTrimBar trimBar;
@Inject
MToolBar toolBar;
private MWindow window;
private Panel vaadinWindow;
// --------------------------------------------
// --------------------------------------------
private static final String STATE_XSIZE = "XSize"; //$NON-NLS-1$
private static final String STATE_YSIZE = "YSize"; //$NON-NLS-1$
private boolean isShowing = false;
private FastView hostPane;
@Inject
EModelService modelService;
@Inject
EPartService partService;
@Inject
protected IEventBroker eventBroker;
/**
* This is the old way to subscribe to UIEvents. You should consider using
* the new way as shown by handleTransientDataEvents() and described in the
* article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
*/
private EventHandler closeHandler = new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (!isShowing)
return;
// The only time we don't close is if I've selected my tab.
MUIElement changedElement = (MUIElement) event
.getProperty(UIEvents.EventTags.ELEMENT);
// Perspective changed, close the visible stacks
if (changedElement instanceof MPerspectiveStack) {
showStack(false);
return;
}
if (changedElement == getLeafPart(minimizedElement)) {
fixToolItemSelection(changedElement);
return;
}
showStack(false);
}
};
private void fixToolItemSelection(MUIElement element) {
// TODO: implement correctly this method
// if (trimStackTB == null || trimStackTB.isDisposed())
// return;
//
// if (isEditorStack()) {
// trimStackTB.getItem(1).setSelection(element != null);
// if (element != null)
// trimStackTB.getItem(1).setData(element);
// } else if (isPerspectiveStack()) {
// for (ToolItem item : trimStackTB.getItems()) {
// boolean result = item.getData() == null ? false : item.getData() ==
// element;
// item.setSelection(result);
// }
// } else {
// for (ToolItem item : trimStackTB.getItems()) {
// boolean result = item.getData() == null ? false : item.getData() ==
// element;
// item.setSelection(result);
// }
// }
}
private boolean isEditorStack() {
return minimizedElement instanceof MPlaceholder;
}
private boolean isPerspectiveStack() {
return minimizedElement instanceof MPerspectiveStack;
}
private MPart getLeafPart(MUIElement element) {
if (element instanceof MPlaceholder)
return getLeafPart(((MPlaceholder) element).getRef());
if (element instanceof MElementContainer<?>)
return getLeafPart(((MElementContainer<?>) element)
.getSelectedElement());
if (element instanceof MPart)
return (MPart) element;
return null;
}
private EventHandler openHandler = new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (isShowing)
return;
MPerspective currentPerspective = modelService
.getPerspectiveFor(minimizedElement);
MPerspective activePerspective = modelService
.getActivePerspective(window);
if (currentPerspective != activePerspective)
return;
MPart changedElement = (MPart) event
.getProperty(UIEvents.EventTags.ELEMENT);
// Open if shared area
if (getLeafPart(minimizedElement) == changedElement) {
showStack(true);
return;
}
MUIElement selectedElement = null;
if (minimizedElement instanceof MPlaceholder) {
selectedElement = ((MPlaceholder) minimizedElement).getRef();
} else if (minimizedElement instanceof MPartStack) {
selectedElement = ((MPartStack) minimizedElement)
.getSelectedElement();
}
if (selectedElement == null)
return;
if (selectedElement instanceof MPlaceholder)
selectedElement = ((MPlaceholder) selectedElement).getRef();
if (changedElement != selectedElement)
return;
showStack(true);
}
};
/**
* This is the old way to subscribe to UIEvents. You should consider using
* the new way as shown by handleTransientDataEvents() and described in the
* article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
*/
private EventHandler toBeRenderedHandler = new EventHandler() {
public void handleEvent(org.osgi.service.event.Event event) {
if (minimizedElement == null || trimBar == null)
return;
MUIElement changedElement = (MUIElement) event
.getProperty(UIEvents.EventTags.ELEMENT);
// if our stack is going away, so should we
if (changedElement == minimizedElement
&& !minimizedElement.isToBeRendered()) {
if (hostPane != null)
vaadinUI.removeWindow(hostPane);
hostPane = null;
return;
}
}
};
@PostConstruct
void postConstruct() {
if (window == null)
window = (MWindow) (trimBar.getParent() != null ? (MElementContainer<?>) trimBar
.getParent() : ((EObject) trimBar).eContainer());
vaadinWindow = (Panel) window.getWidget();
eventBroker.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED,
toBeRenderedHandler);
eventBroker.subscribe(UIEvents.UILifeCycle.BRINGTOTOP, openHandler);
eventBroker.subscribe(UIEvents.UILifeCycle.ACTIVATE, closeHandler);
}
void dispose() {
showStack(false);
eventBroker.unsubscribe(toBeRenderedHandler);
eventBroker.unsubscribe(openHandler);
eventBroker.unsubscribe(closeHandler);
}
/**
* This is the old way to subscribe to UIEvents. You should consider using
* the new way as shown by handleTransientDataEvents() and described in the
* article at http://wiki.eclipse.org/Eclipse4/RCP/Event_Model
*/
@PreDestroy
void removeListeners() {
eventBroker.unsubscribe(openHandler);
eventBroker.unsubscribe(closeHandler);
}
private String getLabelText(MUILabel label) {
// Use override text if available
if (label instanceof MUIElement) {
String text = getOverrideTitleToolTip((MUIElement) label);
if (text != null)
return text;
}
String string = label.getLabel();
return string == null ? "" : string; //$NON-NLS-1$
}
private String getOverrideTitleToolTip(MUIElement element) {
String result = null;
Object stringObject = element.getTransientData().get(
IPresentationEngine.OVERRIDE_TITLE_TOOL_TIP_KEY);
if (stringObject != null && stringObject instanceof String)
result = (String) stringObject;
return result;
}
private MUILabel getLabelElement(MUIElement element) {
if (element instanceof MPlaceholder)
element = ((MPlaceholder) element).getRef();
return (MUILabel) (element instanceof MUILabel ? element : null);
}
/**
* Create the popup menu that will appear when a minimized part has been
* selected by the cursor.
*/
// private void createPopupMenu() {
// trimStackMenu = new Menu(trimStackTB);
// trimStackTB.setMenu(trimStackMenu);
//
// MenuItem closeItem = new MenuItem(trimStackMenu, SWT.NONE);
// closeItem.setText(Messages.TrimStack_CloseText);
// closeItem.addListener(SWT.Selection, new Listener() {
// public void handleEvent(Event event) {
// partService.hidePart((MPart) selectedToolItem.getData());
// }
// });
// }
ClickListener layoutClickListener = new ClickListener() {
@Override
public void click(ClickEvent event) {
if (isShowing)
showStack(false);
partService.requestActivation();
}
};
public synchronized void showStack(boolean show) {
Component ctf = (Component) minimizedElement.getWidget();
if (show && !isShowing) {
hostPane = getHostPane();
VerticalLayout vl = new VerticalLayout();
vl.setSizeFull();
hostPane.setContent(vl);
ctf.setVisible(true);
TrimmedWindowContent windowContent = (TrimmedWindowContent) vaadinWindow
.getContent();
VerticalLayout clientArea = windowContent.getClientArea();
hostPane.setTrimmedWindowClientArea(clientArea);
// hostPane.setContent(ctf);
vl.addComponent(ctf);
vaadinUI.addWindow(hostPane);
vaadinWindow.addClickListener(layoutClickListener);
isShowing = true;
} else if (!show && isShowing) {
if (hostPane != null) {
vaadinUI.removeWindow(hostPane);
// capture the current shell's bounds
toolBar.getPersistedState().put(STATE_XSIZE,
Float.toString(Float.valueOf(hostPane.getWidth())));
toolBar.getPersistedState().put(STATE_YSIZE,
Float.toString(Float.valueOf(hostPane.getHeight())));
}
fixToolItemSelection(null);
vaadinWindow.removeClickListener(layoutClickListener);
partService.requestActivation();
isShowing = false;
}
}
private FastView getHostPane() {
if (hostPane != null)
return hostPane;
// Create one
hostPane = new FastView();
hostPane.setSide(trimBar.getSide().getValue());
hostPane.setClosable(false);
hostPane.setDraggable(false);
if (trimBar.getSide() == SideValue.RIGHT)
hostPane.setResizable(false);
// hostPane.setResizeLazy(true);
hostPane.setStyleName("loading-window");
// TODO: implement closing by esc
// hostPane.addListener(SWT.Traverse, new Listener() {
// public void handleEvent(Event event) {
// if (event.character == SWT.ESC) {
// partService.requestActivation();
// }
// }
// });
return hostPane;
}
}