/******************************************************************************* * Copyright (c) 2010, 2015 IBM Corporation 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: * IBM Corporation - initial API and implementation ******************************************************************************/ package org.eclipse.e4.ui.workbench.addons.dndaddon; import org.eclipse.e4.ui.model.application.ui.MUIElement; 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.MPartSashContainerElement; import org.eclipse.e4.ui.model.application.ui.basic.MPartStack; import org.eclipse.e4.ui.workbench.IPresentationEngine; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; public class DetachedDropAgent extends DropAgent { DnDManager manager; private EModelService modelService; private Rectangle curRect; public DetachedDropAgent(DnDManager manager) { super(manager); this.manager = manager; modelService = manager.getModelService(); } @Override public boolean canDrop(MUIElement dragElement, DnDInfo info) { if (info.curElement != null) { return false; } if (dragElement instanceof MPart || dragElement instanceof MPlaceholder || dragElement instanceof MPartStack) { return true; } return false; } @Override public boolean drop(MUIElement dragElement, DnDInfo info) { // Ensure that the stack is restored first if minimizdd if (dragElement.getTags().contains(IPresentationEngine.MINIMIZED)) { dragElement.getTags().remove(IPresentationEngine.MINIMIZED); } if (dragElement.getCurSharedRef() != null) { dragElement = dragElement.getCurSharedRef(); } Rectangle rectangle = getRectangle(dragElement, info); modelService.detach((MPartSashContainerElement) dragElement, rectangle.x, rectangle.y, rectangle.width, rectangle.height); // Fully re-activate the part since its location has changed reactivatePart(dragElement); return true; } @Override public Rectangle getRectangle(MUIElement dragElement, DnDInfo info) { if (dragElement.getCurSharedRef() != null) { dragElement = dragElement.getCurSharedRef(); } if (dragElement instanceof MPartStack) { Control ctrl = (Control) dragElement.getWidget(); curRect = ctrl.getBounds(); } else { // Adjust the rectangle to account for the stack inside the new window MUIElement parentME = dragElement.getParent(); Control ctrl = (Control) parentME.getWidget(); curRect = ctrl.getBounds(); // Try to take the window's trim into account curRect.width += 10; curRect.height += 22; } Point cp = Display.getCurrent().getCursorLocation(); curRect.x = cp.x - 15; curRect.y = cp.y - 15; return curRect; } @Override public boolean track(MUIElement dragElement, DnDInfo info) { if (info.curElement != null) { return false; } manager.frameRect(getRectangle(dragElement, info)); return true; } @Override public void dragEnter(MUIElement dragElement, DnDInfo info) { super.dragEnter(dragElement, info); dndManager.setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_HAND)); } @Override public void dragLeave(MUIElement dragElement, DnDInfo info) { manager.clearOverlay(); dndManager.setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_NO)); super.dragLeave(dragElement, info); } }