package org.archstudio.bna.ui.utils; import java.util.List; import java.util.Map; import org.archstudio.bna.IBNAView; import org.archstudio.bna.ICoordinate; import org.archstudio.bna.IThing; import org.archstudio.bna.constants.DNDData; import org.archstudio.bna.constants.DNDType; import org.archstudio.bna.constants.FocusType; import org.archstudio.bna.constants.GestureType; import org.archstudio.bna.constants.KeyType; import org.archstudio.bna.constants.MouseType; import org.archstudio.bna.ui.IBNAUI; import org.archstudio.bna.ui.IUITransferProvider; import org.archstudio.bna.utils.BNAUtils; import org.archstudio.bna.utils.BNAUtils2; import org.archstudio.bna.utils.BNAUtils2.ThingsAtLocation; import org.archstudio.bna.utils.DefaultCoordinate; import org.archstudio.sysutils.Finally; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.DropTargetListener; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.dnd.TransferData; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.GestureEvent; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.MouseTrackListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import com.google.common.collect.Maps; public abstract class AbstractSWTUI extends AbstractBNAUI implements IBNAUI { class SWTMouseListener implements MouseListener { MouseEvent mouseDownEvent = null; @Override public void mouseUp(MouseEvent e) { mouseEventSWT(MouseType.UP, e); if (mouseDownEvent != null) { if (e.time - mouseDownEvent.time < 250) { mouseEventSWT(MouseType.CLICK, e); } mouseDownEvent = null; } } @Override public void mouseDown(MouseEvent e) { mouseEventSWT(MouseType.DOWN, mouseDownEvent = e); } @Override public void mouseDoubleClick(MouseEvent e) { } } class SWTMouseEventListener implements Listener { MouseType mouseType; public SWTMouseEventListener(MouseType mouseType) { this.mouseType = mouseType; } @Override public void handleEvent(Event event) { mouseEventSWT(mouseType, new MouseEvent(event)); } } class SWTGestureEventListener implements Listener { @Override public void handleEvent(Event event) { gestureEventSWT(GestureType.fromSwtEvent(event.detail), new GestureEvent(event)); } } class SWTMouseMoveListener implements MouseMoveListener { @Override public void mouseMove(MouseEvent e) { mouseEventSWT(MouseType.MOVE, e); } } class SWTMouseTrackListener implements MouseTrackListener { @Override public void mouseEnter(MouseEvent e) { mouseEventSWT(MouseType.ENTER, e); } @Override public void mouseExit(MouseEvent e) { mouseEventSWT(MouseType.EXIT, e); } @Override public void mouseHover(MouseEvent e) { } } class SWTKeyListener implements KeyListener { @Override public void keyPressed(KeyEvent e) { keyEventSWT(KeyType.PRESSED, e); } @Override public void keyReleased(KeyEvent e) { keyEventSWT(KeyType.RELEASED, e); } } class SWTFocusListener implements FocusListener { @Override public void focusGained(FocusEvent e) { focusEventSWT(FocusType.GAINED, e); } @Override public void focusLost(FocusEvent e) { focusEventSWT(FocusType.LOST, e); } } class SWTDropTargetListener implements DropTargetListener { protected void dndEvent(DNDType type, DropTargetEvent e) { try (Finally lock = BNAUtils.lock()) { DNDData data = new DNDData(); TransferData td = e.currentDataType; for (IUITransferProvider provider : transferProviders.values()) { if (provider.isSupportedType(td)) { try { provider.addData(td, data); } catch (Exception e1) { e1.printStackTrace(); } } } Point p = swtComposite.toControl(e.x, e.y); ICoordinate location = DefaultCoordinate.forLocal(new Point(p.x, p.y), view.getCoordinateMapper()); try { ThingsAtLocation thingsAtLocation = BNAUtils2.getThingsAtLocation(view, location); dndEvent2(view, type, data, location, thingsAtLocation); } catch (Exception e1) { e1.printStackTrace(); } try { List<IThing> things = view.getThingsAt(location); dndEvent1(type, data, things, location); } catch (Exception e1) { e1.printStackTrace(); } e.detail = data.getDropType().toSWTDNDDropOperation(); } catch (Exception e2) { e2.printStackTrace(); } } @SuppressWarnings("deprecation") @Override public void dragEnter(DropTargetEvent e) { dndEvent(DNDType.ENTER, e); } @Override public void dragOver(DropTargetEvent e) { dndEvent(DNDType.DRAG, e); } @Override public void dragOperationChanged(DropTargetEvent e) { dndEvent(DNDType.DRAG, e); } @SuppressWarnings("deprecation") @Override public void dragLeave(DropTargetEvent e) { dndEvent(DNDType.EXIT, e); } @Override public void dropAccept(DropTargetEvent e) { dndEvent(DNDType.DRAG, e); } @Override public void drop(DropTargetEvent e) { dndEvent(DNDType.DROP, e); } } protected Composite swtComposite; protected DropTarget swtDropTarget; protected Map<Transfer, IUITransferProvider> transferProviders = Maps.newHashMap(); public AbstractSWTUI(IBNAView view) { super(view); } protected void init(Composite swtComposite, boolean registerListeners) { super.init(swtComposite); this.swtComposite = swtComposite; this.swtDropTarget = new DropTarget(swtComposite, // DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT | DND.DROP_LINK); if (Platform.isRunning()) { IExtensionRegistry reg = Platform.getExtensionRegistry(); // The Extension Registry can be null if we're running outside of Eclipse for (IConfigurationElement configurationElement : reg .getConfigurationElementsFor("org.archstudio.bna.dndtransferprovider")) { String transferClassName = configurationElement.getAttribute("class"); if (transferClassName != null) { String bundleName = configurationElement.getDeclaringExtension().getContributor().getName(); try { Class<?> packageClass = Platform.getBundle(bundleName).loadClass(transferClassName); Transfer provider = (Transfer) packageClass.getMethod("getInstance").invoke(null); transferProviders.put(provider, (IUITransferProvider) provider); } catch (Exception e) { e.printStackTrace(); } } } } swtDropTarget.setTransfer(transferProviders.keySet().toArray(new Transfer[transferProviders.size()])); if (registerListeners) { swtComposite.addMouseListener(new SWTMouseListener()); swtComposite.addMouseMoveListener(new SWTMouseMoveListener()); swtComposite.addMouseTrackListener(new SWTMouseTrackListener()); swtComposite.addKeyListener(new SWTKeyListener()); swtComposite.addFocusListener(new SWTFocusListener()); swtComposite.addListener(SWT.MouseHorizontalWheel, new SWTMouseEventListener(MouseType.HORIZONTAL_WHEEL)); swtComposite.addListener(SWT.MouseVerticalWheel, new SWTMouseEventListener(MouseType.VERTICAL_WHEEL)); swtComposite.addListener(SWT.Gesture, new SWTGestureEventListener()); swtDropTarget.addDropListener(new SWTDropTargetListener()); // Register menu. final MenuDetectEvent[] menuDetectEvent = new MenuDetectEvent[1]; swtComposite.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { menuDetectEvent[0] = e; } }); MenuManager menuMgr = new MenuManager(); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { @Override public void menuAboutToShow(IMenuManager manager) { menuEventSWT(menuDetectEvent[0], manager); } }); Menu menu = menuMgr.createContextMenu(swtComposite); swtComposite.setMenu(menu); } } @Override public void dispose() { swtDropTarget.dispose(); } }