Community
Participate
Working Groups
Scenario: Display a form using an SWT widget, where the form is painted with a background image. The form contains other SWT widgets such as Composite, text labels, entry fields, and other widgets. The child widgets have transparent backgrounds which allow the background image to show through within the widget bounds. Problem: Today, a Composite widget with child widgets are able to set its background colour. Each child widget may also set its background colour to that of its parent. A subclass of a Composite or Canvas may be created with NO_BACKGROUND style that uses a PaintListener to paint an Image onto the background. 1. Child widgets of the Composite that display text do not have transparent background ability. 2. The painted image of the background Composite does not show through child Composites with NO_BACKGROUND style. A child composite that paints itself shows the desktop pixels, and not its parent pixels, even though it is parented by the background Composite. Requirements: 1. Composite that uses an Image as its background rather than a background colour. Options: alignment, stretch, maintain width/height ratio. 2. Composites also need to be transparent, since background image needs to show through child composites. The background image of the child composites need to show the background image of its parent. 3. Widgets that display text such as Label, radio buttons, check boxes, and group boxes require transparent background option. Preferably, new capability could be an extension of current Composite class, although not absolutely necessary.
This may need to be implemented as a hint on platforms that don't support rendering widgets without drawing the background. The SWT.NO_BACKGROUND flag is intended widget implementors so they can stop the operating system from drawing the background, thus reducing flicker. It's not really intended to be used as you describe.
*** Bug 75895 has been marked as a duplicate of this bug. ***
*** Bug 82523 has been marked as a duplicate of this bug. ***
Eclipse Forms have a use-case as well. We have section title that uses gradient, so whatever solid color we pick for child control background, it is partially wrong. Having a hint that works on some platforms but not on others is a step forward.
IS there any work on that bug (or lacking function) ??? I'm quite surprised by the p4, i think it would be a p3 or p2... It is a very important function to make transparent widget (ie search "transparent SWT" in google)... In the 81961 bug, it was wrote that investigation on transparent widget will begin after 3.1RC1... the 3.2 is under dev, so is that any news about that VERY important thing ??? So, we could eventualay abandon the remaining 10% AWT of application because of that issue... thanks for any work on that subject. ---- To speak about this issue, I know enabling a transparent widget for some OS and not the remaining OS is annoying but less than forbidding transparency completely. FOr which OS transparent widget is impossible ?? 2,3..15 ?? If there only few (2-3) it could be usefull to allow trnapsrency no ??? I thnk Solaris apps do not require any widget child of a composite with background Image...
Yes we are looking into it for 3.2. Hang in there.
Fixed > 20051212 See Control.setBackgroundImage() which works the same way as Control.setBackground(Color). This API will most likely remain untouched for 3.2. *** WORK IN PROGRESS *** An experimental API Composite.setBackgroundMode() has been released for M4 that allows you to set the background for those children that normally don't want their own background (using SWT.INHERIT_DEFAULT) or to force the background for all children (using SWT.INHERIT_FORCE). The idea behind SWT.INHERIT_DEFAULT is to allow you to set the background for labels, check boxes etc and leave the background alone for tables, trees etc. Currently, setBackgroundMode() only applies to newly created children. If you set it right after the composite is created and leave it alone, you will be fine. *** THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE ***
The background mode functionality seems to show the parent's background color and background image. This is a big step forward, but are there any plans to include the actual drawn area of the underlying widget? If I add a paint listener to the parent widget, anything drawn is not reflected in the children.
Eh? By definition, paint listeners only draw within the client area of the widget. If you have a particular bug of feature request, please enter it.
I'm glad to see some progress. Thanks for the work Steve! My use-case is the following: I need to draw a "transparent" rectangle around a widget such as a text box, checkbox, etc. The foreground (border) of the rectangle needs to be seen and the rectangle needs to capture mouse events. The widget below should be visible through the rectangle, but should not receive mouse events.
Ok but this bug report isn't capturing that. You can already do what you want by creating a parent composite and disabling it. The child will not draw disabled and the event will go to the parent of the disabled widget.
Take the Forms use case. The Section class (extends Composite) draws a gradient and a border. They also create a label widget and center inside the gradient to act as the title text. In 3.1, the title is opaque and Section is forced to set the background color of the label to be one of the gradient colors, so it kinda matches but the gradient does not 'bleed' through. Bug 81961 has screenshots.
Don't worry about forms :-). I worked with Steve on this and plan to rework drawing to paint into an offscreen image and set it on the Composite. After M4, Section/ExpandableComposite and Form will be reworked to use this technique for gradient painting.
I was just using Forms as an example :) I am wondering how to implement the same requirement in my own widgets. So should this be the recommended technique? I'm assuming you are going to create the image once during construction and not during the paint event.?
From comment 11, does this mean that I would have to create a rectangle widget that was a parent of the underlying widget? Something like this? Rectangle r = new Rectangle(parent, SWT.INHERIT_DEFAULT); Text t = new Text(r, SWT.NONE); My use-cae requires both the rectangle and underlying widget to have the same composite parent. I simply need the rectnagle to be on top of the widget in Z order so that it captures the events, and be transparent so you can see the widget underneath. Something like this: Rectangle r = new Rectangle(parent, SWT.INHERIT_DEFAULT); Text t = new Text(parent, SWT.NONE);
I thought that what was being asked for is what you yourself alluded to in comment #1 - true transparency. It appears that some people, including myself, were assuming this bug was asking for true transparency (no background is drawn and anything below in Z-order, background and foreground, is shown), not a background-inheritance mechanism. The bug request is a bit confusing but requirments 2 and 3 lead me to believe that true transparency was asked for. In my view it wouldn't even be a child/parent thing but rather a z-order thing (nothing prevents siblings from overlaping each other.) What was done here is good news but isn't what I'd call transparency (at least it is a bit misleading.) Again, perhaps some of us were reading more into the bug and a new bug is needed.
(In reply to comment #14) Depends on what you do. This is what I plan to do: 1) For vertical gradient, create a narrow image with the height equal to the composite client area height. 2) For horizontal gradient, create a short image with the width equal to the composite client area width. In both case, SWT is supposed to tile the background image over the entire area. I will create this image on size change event.
Thanks Dejan
I think we all agree here (including Steve) that the support in M4 is not 'transparency' but rather a way of having background images and gradients show up on children of composites with them. With this feature alone you are better off than web browsers (because HTML allows you to set background image only but in SWT you can create these images dynamically, which allows you to all kinds of interesting background effects that can be configurable, use system colors etc.)
Bryan, I don't think your use case as you describe it is implementable using the underlying widget toolkits, so you'll probably need to have some sort of hack at some point.
Bryan, You can already capture events by placing a disabled composite on top of a widget. The events will go to the parent of the disabled composite. Isn't this what you are describing? Everyone else, This is NOT transparent widgets. That would imply that when two widgets overlapped, you could see part of the widget on the bottom through the widget on the top using an alpha value. This is not what was implemented. Sorry for the confusion. So, please enter new bug reports in this area (but also be aware that were are playing with API, specifically Composite.setBackgroundMode()).
See http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet214.java?rev=HEAD&content-type=text/vnd.viewcvs-markup
There seems to be a bug with transparent images on ToolItems, if I didn't miss something. The background image doesn't show. If you only set a background color, it works. I attached a variant of your Snippet and a transparent image. I use WinXP and swt-I20051214.
Created attachment 31767 [details] comment 23-snippet
Created attachment 31768 [details] comment 23-image
Please enter new bug reports with issues that you find.
Steve, doesn't snippet 214 show the limitation of this new API? Wouldn't it make more sense to introduce a setBackgroundPainter(PaintListener/Painter) API instead of an image. Then, you could just paint the gradient directly which would be much faster, and would reduce the number of resource handles an application consumes. If a client wants to paint a String or message as the background, he/she must create a very large Image to prevent the message from being tiled. Finally, adding setBackgroundImage(Image) in 3.2 makes it less likely that a background painter API could be added in the future.
I will let Steve answer too, but I think the issue is with the native WS limitations - I think Steve is working with native background image support here and there is no equivalent background painter function to tap into.
At least on swt.win32's Control, it looks like there is a method drawBackground that performs the actual painting. Of course, there's no easy way to tell if every win32 control calls this method at some time.
The operating system paints the background of a widget using the theme manager. Some widgets, on some platforms have hooks that let you get in there and draw. Others, do not. Since we must be portable, we cannot offer an API that can't be implemented on every platform. >Of course, there's no easy way to tell if every win32 control calls this >method at some time. It doesn't. However, one easy way to tell is to put a print statement in the method, create a well known hierachy of widgets and see that this method is called for every widget in your hierarchy. Finally, this bug called 'Image background Composite'. Should a mechanism be devised to draw the background in a listener, there are many ways that the listener and this API could be resolved ("doit flag", "you draw after"). In addition, we already have the notion of background color so we would need to resolve the proposed listener API anyways.
I do feel your pain and understand your concerns, however, we are doing the best we can.
Is it safe to use Composite.setBackgroundMode? It is still marked with a warning (at least in win32 it is). Now that we are past API freeze, I'm assuming it is safe to use and will be updated with a real spec?
Yes, I must update the spec. Do you have a real need for this method at this time in the Eclipse release cycle?
It lets me remove a workaround in some of my code and prevent API additions in the future, but it's not a huge deal. I will use it if other clients (such as ui forms) are already using it. I have a class DecoratedField that allows clients to put image decorations abround a control. To do this, I create a few labels that surround a text control on a composite. If the composite has a background mode of INHERIT_DEFAULT, then I don't have to worry about keeping the colors of the child labels in sync with the parent composite. I'd like the clients to be able to access the composite and change the color of the background, and have the labels change accordingly. The workaround is that I create the labels with the parent background color and if the client dynamically changes the parent color later, then they are out of luck. Otherwise I have to provide wrapper API and force them to go through my field so that I can change all the associated labels.
Any news on this long overdue feature? :) It's marked as resolved/fixed, but that's certainly not the case, at least I haven't found any reliable way that works on all platforms.