public static void initializeStyling(Display display, IEclipseContext appContext) { String cssTheme = (String) appContext.get(E4Application.THEME_ID); String cssURI = (String) appContext.get(E4Workbench.CSS_URI_ARG); if (cssTheme != null) { String cssResourcesURI = (String) appContext.get(E4Workbench.CSS_RESOURCE_URI_ARG); Bundle bundle = WorkbenchSWTActivator.getDefault().getBundle(); BundleContext context = bundle.getBundleContext(); ServiceReference ref = context.getServiceReference(IThemeManager.class.getName()); IThemeManager mgr = (IThemeManager) context.getService(ref); final IThemeEngine engine = mgr.getEngineForDisplay(display); // Store the app context IContributionFactory contribution = (IContributionFactory) appContext.get(IContributionFactory.class.getName()); IEclipseContext cssContext = EclipseContextFactory.create(); cssContext.set(IContributionFactory.class.getName(), contribution); display.setData("org.eclipse.e4.ui.css.context", cssContext); // $NON-NLS-1$ // Create the OSGi resource locator if (cssResourcesURI != null) { // TODO: Should this be set through an extension as well? engine.registerResourceLocator(new OSGiResourceLocator(cssResourcesURI)); } engine.restore(cssTheme); // TODO Should we create an empty default theme? appContext.set(IThemeEngine.class.getName(), engine); appContext.set( IStylingEngine.SERVICE_NAME, new IStylingEngine() { public void setClassname(Object widget, String classname) { WidgetElement.setCSSClass((Widget) widget, classname); engine.applyStyles((Widget) widget, true); } public void setId(Object widget, String id) { WidgetElement.setID((Widget) widget, id); engine.applyStyles((Widget) widget, true); } public void style(Object widget) { engine.applyStyles((Widget) widget, true); } public CSSStyleDeclaration getStyle(Object widget) { return engine.getStyle((Widget) widget); } public void setClassnameAndId(Object widget, String classname, String id) { WidgetElement.setCSSClass((Widget) widget, classname); WidgetElement.setID((Widget) widget, id); engine.applyStyles((Widget) widget, true); } }); } else if (cssURI != null) { String cssResourcesURI = (String) appContext.get(E4Workbench.CSS_RESOURCE_URI_ARG); final CSSSWTEngineImpl engine = new CSSSWTEngineImpl(display, true); WidgetElement.setEngine(display, engine); if (cssResourcesURI != null) { engine .getResourcesLocatorManager() .registerResourceLocator(new OSGiResourceLocator(cssResourcesURI.toString())); } // FIXME: is this needed? display.setData("org.eclipse.e4.ui.css.context", appContext); // $NON-NLS-1$ appContext.set( IStylingEngine.SERVICE_NAME, new IStylingEngine() { public void setClassname(Object widget, String classname) { WidgetElement.setCSSClass((Widget) widget, classname); engine.applyStyles((Widget) widget, true); } public void setId(Object widget, String id) { WidgetElement.setID((Widget) widget, id); engine.applyStyles((Widget) widget, true); } public void style(Object widget) { engine.applyStyles((Widget) widget, true); } public CSSStyleDeclaration getStyle(Object widget) { Element e = engine.getCSSElementContext(widget).getElement(); if (e == null) { return null; } return engine.getViewCSS().getComputedStyle(e, null); } public void setClassnameAndId(Object widget, String classname, String id) { WidgetElement.setCSSClass((Widget) widget, classname); WidgetElement.setID((Widget) widget, id); engine.applyStyles((Widget) widget, true); } }); URL url; InputStream stream = null; try { url = FileLocator.resolve(new URL(cssURI)); stream = url.openStream(); engine.parseStyleSheet(stream); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } Shell[] shells = display.getShells(); for (Shell s : shells) { try { s.setRedraw(false); s.reskin(SWT.ALL); engine.applyStyles(s, true); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { s.setRedraw(true); } } } CSSRenderingUtils cssUtils = ContextInjectionFactory.make(CSSRenderingUtils.class, appContext); appContext.set(CSSRenderingUtils.class, cssUtils); }
private void drag(Event dragEvent) { DNDEvent event = new DNDEvent(); event.widget = this; event.x = dragEvent.x; event.y = dragEvent.y; event.time = OS.GetMessageTime(); event.doit = true; notifyListeners(DND.DragStart, event); if (!event.doit || transferAgents == null || transferAgents.length == 0) return; int[] pdwEffect = new int[1]; int operations = opToOs(getStyle()); Display display = control.getDisplay(); String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$ Object oldValue = display.getData(key); display.setData(key, Boolean.TRUE); ImageList imagelist = null; Image image = event.image; hwndDrag = 0; topControl = null; if (image != null) { imagelist = new ImageList(SWT.NONE); imagelist.add(image); topControl = control.getShell(); /* * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT. * The fix is to create a transparent window that covers the shell client * area and use it during the drag to prevent the image from being inverted. * On XP if the shell is RTL, the image is not displayed. */ int offsetX = event.offsetX; hwndDrag = topControl.handle; if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) { offsetX = image.getBounds().width - offsetX; RECT rect = new RECT(); OS.GetClientRect(topControl.handle, rect); hwndDrag = OS.CreateWindowEx( OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT, WindowClass, null, OS.WS_CHILD | OS.WS_CLIPSIBLINGS, 0, 0, rect.right - rect.left, rect.bottom - rect.top, topControl.handle, 0, OS.GetModuleHandle(null), null); OS.ShowWindow(hwndDrag, OS.SW_SHOW); } OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY); /* * Feature in Windows. When ImageList_DragEnter() is called, * it takes a snapshot of the screen If a drag is started * when another window is in front, then the snapshot will * contain part of the other window, causing pixel corruption. * The fix is to force all paints to be delivered before * calling ImageList_DragEnter(). */ if (OS.IsWinCE) { OS.UpdateWindow(topControl.handle); } else { int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; OS.RedrawWindow(topControl.handle, null, 0, flags); } POINT pt = new POINT(); pt.x = dragEvent.x; pt.y = dragEvent.y; OS.MapWindowPoints(control.handle, 0, pt, 1); RECT rect = new RECT(); OS.GetWindowRect(hwndDrag, rect); OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top); } int result = COM.DRAGDROP_S_CANCEL; try { result = COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect); } finally { // ensure that we don't leave transparent window around if (hwndDrag != 0) { OS.ImageList_DragLeave(hwndDrag); OS.ImageList_EndDrag(); imagelist.dispose(); if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag); hwndDrag = 0; topControl = null; } display.setData(key, oldValue); } int operation = osToOp(pdwEffect[0]); if (dataEffect == DND.DROP_MOVE) { operation = (operation == DND.DROP_NONE || operation == DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE; } else { if (dataEffect != DND.DROP_NONE) { operation = dataEffect; } } event = new DNDEvent(); event.widget = this; event.time = OS.GetMessageTime(); event.doit = (result == COM.DRAGDROP_S_DROP); event.detail = operation; notifyListeners(DND.DragEnd, event); dataEffect = DND.DROP_NONE; }