Bug 29994 - Image background Composite / Transparent widget backgrounds
Summary: Image background Composite / Transparent widget backgrounds
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 2.0   Edit
Hardware: All All
: P4 enhancement with 12 votes (vote)
Target Milestone: 3.2 M4   Edit
Assignee: Steve Northover CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 75895 82523 (view as bug list)
Depends on:
Blocks: 81961 126553
  Show dependency tree
 
Reported: 2003-01-22 11:34 EST by Brian Farn CLA
Modified: 2014-01-02 13:19 EST (History)
19 users (show)

See Also:


Attachments
comment 23-snippet (2.41 KB, text/plain)
2005-12-14 13:10 EST, Michael Chervil CLA
no flags Details
comment 23-image (299 bytes, image/png)
2005-12-14 13:10 EST, Michael Chervil CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Brian Farn CLA 2003-01-22 11:34:58 EST
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.
Comment 1 Steve Northover CLA 2003-01-22 11:40:28 EST
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.
Comment 2 Grant Gayed CLA 2004-10-08 10:42:38 EDT
*** Bug 75895 has been marked as a duplicate of this bug. ***
Comment 3 Veronika Irvine CLA 2005-03-08 10:42:48 EST
*** Bug 82523 has been marked as a duplicate of this bug. ***
Comment 4 Dejan Glozic CLA 2005-05-13 15:29:08 EDT
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.
Comment 5 Slash CLA 2005-08-12 14:17:27 EDT
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...

Comment 6 Steve Northover CLA 2005-08-12 18:44:45 EDT
Yes we are looking into it for 3.2.  Hang in there.
Comment 7 Steve Northover CLA 2005-12-12 18:57:27 EST
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 ***
Comment 8 Chris Gross CLA 2005-12-13 16:48:22 EST
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.
Comment 9 Steve Northover CLA 2005-12-13 16:55:00 EST
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.
Comment 10 Bryan Hunt CLA 2005-12-13 17:03:18 EST
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.
Comment 11 Steve Northover CLA 2005-12-13 17:08:01 EST
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.
Comment 12 Chris Gross CLA 2005-12-13 17:09:47 EST
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.  
Comment 13 Dejan Glozic CLA 2005-12-13 17:14:09 EST
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.
Comment 14 Chris Gross CLA 2005-12-13 17:20:01 EST
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.?
Comment 15 Bryan Hunt CLA 2005-12-13 17:22:37 EST
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);
Comment 16 Aaron Siri CLA 2005-12-13 17:25:01 EST
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.
Comment 17 Dejan Glozic CLA 2005-12-13 17:25:49 EST
(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.
Comment 18 Chris Gross CLA 2005-12-13 17:28:45 EST
Thanks Dejan
Comment 19 Dejan Glozic CLA 2005-12-13 17:29:05 EST
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.)
Comment 20 Billy Biggs CLA 2005-12-13 17:35:34 EST
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.
Comment 21 Steve Northover CLA 2005-12-13 17:48:00 EST
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()).
Comment 23 Michael Chervil CLA 2005-12-14 13:09:29 EST
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.
Comment 24 Michael Chervil CLA 2005-12-14 13:10:23 EST
Created attachment 31767 [details]
comment 23-snippet
Comment 25 Michael Chervil CLA 2005-12-14 13:10:52 EST
Created attachment 31768 [details]
comment 23-image
Comment 26 Steve Northover CLA 2005-12-14 13:57:22 EST
Please enter new bug reports with issues that you find.
Comment 27 Randy Hudson CLA 2005-12-15 14:44:42 EST
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.
Comment 28 Dejan Glozic CLA 2005-12-15 14:53:44 EST
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.
Comment 29 Randy Hudson CLA 2005-12-15 15:19:17 EST
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.
Comment 30 Steve Northover CLA 2005-12-15 16:07:27 EST
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.
Comment 31 Steve Northover CLA 2005-12-15 16:09:25 EST
I do feel your pain and understand your concerns, however, we are doing the best we can.
Comment 32 Susan McCourt CLA 2006-02-24 18:17:46 EST
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?
Comment 33 Steve Northover CLA 2006-02-24 18:57:49 EST
Yes, I must update the spec.  Do you have a real need for this method at this time in the Eclipse release cycle?
Comment 34 Susan McCourt CLA 2006-02-24 19:48:23 EST
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.  
Comment 35 open source CLA 2014-01-02 13:19:21 EST
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.