/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.diagram.ui; import java.awt.geom.Point2D; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MenuEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchPartSite; import org.simantics.g2d.diagram.DiagramHints; /** * This is a SWTPopupMenu implementation with workaround for SWT popup menus that do not work when overlaid top of AWT widgets in Linux/GTK * * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=392101 * * * @author Marko Luukkainen * */ public class SWTPopupMenuParticipantAwt extends SWTPopupMenuParticipant { Shell shell; Menu menu; public SWTPopupMenuParticipantAwt(IWorkbenchPartSite site, Control control, Display display, String menuId) { super(site, control, display, menuId); } @Override protected void runDispose() { if (shell != null) { shell.dispose(); shell = null; } super.runDispose(); } @Override protected void createControl() { if(shell == null) { shell = new Shell(control.getShell(),SWT.NO_TRIM|SWT.NO_FOCUS|SWT.ON_TOP); shell.setSize(4, 4); shell.setVisible(false); } menuManager = createPopupMenu(); if (menuManager != null) { menu = menuManager.createContextMenu(shell); menu.addMenuListener(menuListener); shell.setMenu(menu); if (site != null) { site.registerContextMenu(menuManager.getId(), menuManager, wbsp); } } } @Override protected void menuHidden(MenuEvent e) { if (shell != null) shell.setVisible(false); super.menuHidden(e); } /** * @param newValue * @thread canvas-thread (AWT) */ protected void showPopup(Point2D newValue) { final Point2D cp = (Point2D) newValue; setHint(DiagramHints.POPUP_MENU_CONTROL_POSITION, cp); setHint(DiagramHints.POPUP_MENU_CANVAS_POSITION, trUtil.controlToCanvas(cp, null)); display.asyncExec(new Runnable() { @Override public void run() { if (control == null || control.isDisposed()) return; final Point p = control.toDisplay((int) cp.getX(), (int) cp.getY()); shell.getDisplay().asyncExec(new Runnable() { public void run() { shell.setLocation(p.x-1, p.y-1); shell.setActive(); shell.setVisible(true); }}); shell.getDisplay().asyncExec(new Runnable() { public void run() { menuManager.getMenu().setLocation(p); menuManager.getMenu().setVisible(true); }}); } }); } }