Bug 207711 - SWT.MeasureItem width not used for native selection or focus drawing
Summary: SWT.MeasureItem width not used for native selection or focus drawing
Status: RESOLVED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-10-28 15:54 EDT by Michael Chervil CLA
Modified: 2008-01-30 16:53 EST (History)
5 users (show)

See Also:


Attachments
SWT Snippet236 showing the bug (2.80 KB, text/plain)
2007-10-28 15:54 EDT, Michael Chervil CLA
no flags Details
Screenshot on WinXP with current SWT (10.05 KB, image/png)
2007-11-01 13:22 EDT, Michael Chervil CLA
no flags Details
Screenshot on Vista (11.09 KB, image/png)
2007-11-01 15:08 EDT, Michael Chervil CLA
no flags Details
Snippet236 on my machine (14.78 KB, image/png)
2007-11-01 15:55 EDT, Steve Northover CLA
no flags Details
Modified SWT Snippet236 showing the bug (2.02 KB, text/plain)
2007-11-01 16:08 EDT, Michael Chervil CLA
no flags Details
PR_207711 on my machine (13.85 KB, image/png)
2007-11-01 16:15 EDT, Steve Northover CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michael Chervil CLA 2007-10-28 15:54:00 EDT
Created attachment 81411 [details]
SWT Snippet236 showing the bug

Just start SWT Snippet236 (added to this report for your convenience) and select a table item. The selection width does not match the width specified in the MeasureItem event. The same goes for the width of the focus rectangle.

TableItem.getTextBound() TableItem.getBound() return the wrong width as well.

This bug is probably a duplicate of bug 157679, bug 154704 and connected with bug 168807. A resolution would help with bug 188333.
Comment 1 Matthew Hall CLA 2007-10-29 00:00:40 EDT
See also bug 168807
Comment 2 Steve Northover CLA 2007-11-01 11:25:28 EDT
I can't see the bug you are talking about (using the snippet).  The other bugs that Matthew mentions are real.  Perhaps your bug is a duplicate?
Comment 3 Michael Chervil CLA 2007-11-01 13:22:21 EDT
Created attachment 81864 [details]
Screenshot on WinXP with current SWT

(In reply to comment #2)
> I can't see the bug you are talking about (using the snippet).  

Really? Very strange. I just retried with the most current SWT from CVS and still can see it. Attached is a screenshot where you can see both the wrong selection and focus rectangle. Using WinXP SP2. Please reconsider.

> Perhaps your bug is a duplicate?

Possible. It depends on your definition of duplicate. None of the bugs I mentioned  say anything about selection or focus drawing.
Comment 4 Steve Northover CLA 2007-11-01 14:09:31 EDT
On my machine, the focus draws properly.  What theme are you using?
Comment 5 Michael Chervil CLA 2007-11-01 15:08:28 EDT
Created attachment 81870 [details]
Screenshot  on Vista

I tried with Luna (that was the attached screenshot), Royale, classic and a custom theme. I use a localized Windows, but I wouldn't expect this to be the cause of the different behaviours.

Just to assure you that I am not the only one seeing this, look at bug 188333 comment #50.

On (my) Vista it looks a tiny bit off as well, as the second screenshot shows (no WPF tried) No problems on GTK or Carbon.
Comment 6 Steve Northover CLA 2007-11-01 15:55:27 EDT
Created attachment 81877 [details]
Snippet236 on my machine
Comment 7 Steve Northover CLA 2007-11-01 15:56:48 EDT
Are we running the same code?  I'm running unmodified Snippet236 and SWT from HEAD.
Comment 8 Michael Chervil CLA 2007-11-01 16:08:12 EDT
Created attachment 81878 [details]
Modified SWT Snippet236 showing the bug

(In reply to comment #7)
> Are we running the same code?  I'm running unmodified Snippet236 and SWT from
> HEAD.

Damn, no we are not. I DID modify the Snippet, and apparently forgot about it as soon as I did it. I changed the style bits of the Table to SWT.NONE.

Sorry for this stupid mistake.

I ran the modified Snippet on Carbon an GTK. The problem appears on Carbon as well, GTK does a full selection in any case, so there is no problem.
Comment 9 Steve Northover CLA 2007-11-01 16:12:46 EDT
Ok, here is the code I am running (your code):


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class PR_207701 {
	public static void main(String [] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		Table table = new Table(shell, SWT.NONE);
		table.setLinesVisible(true);
		for(int i = 0; i < 10; i++) {
			new TableItem(table, SWT.NONE);			
		}
		final TextLayout textLayout = new TextLayout(display);
		textLayout.setText("SWT: Standard Widget Toolkit");
		Font font1 = new Font(display, "Tahoma", 14, SWT.BOLD);
		Font font2 = new Font(display, "Tahoma", 10, SWT.NORMAL);
		Font font3 = new Font(display, "Tahoma", 14, SWT.ITALIC);
		TextStyle style1 = new TextStyle(font1, display.getSystemColor(SWT.COLOR_BLUE), null);
		TextStyle style2 = new TextStyle(font2, display.getSystemColor(SWT.COLOR_MAGENTA), null);
		TextStyle style3 = new TextStyle(font3, display.getSystemColor(SWT.COLOR_RED), null);
		textLayout.setStyle(style1, 0, 0); textLayout.setStyle(style1, 5, 12);
		textLayout.setStyle(style2, 1, 1); textLayout.setStyle(style2, 14, 19);
		textLayout.setStyle(style3, 2, 2); textLayout.setStyle(style3, 21, 27);

		/*
		 * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly.
		 * Therefore, it is critical for performance that these methods be as
		 * efficient as possible.
		 */
		table.addListener(SWT.PaintItem, new Listener() {
			public void handleEvent(Event event) {
				textLayout.draw(event.gc, event.x, event.y);
			}
		});
		final Rectangle textLayoutBounds = textLayout.getBounds();
		table.addListener(SWT.MeasureItem, new Listener() {
			public void handleEvent(Event e) {
				e.width = textLayoutBounds.width + 2;
				e.height = textLayoutBounds.height + 2;
			}
		});
		shell.setSize(400, 200);
		shell.open();
		while(!shell.isDisposed()) {
			if(!display.readAndDispatch()) display.sleep();
		}
		font1.dispose();
		font2.dispose();
		font3.dispose();
		textLayout.dispose();
		display.dispose();
	}
}
Comment 10 Steve Northover CLA 2007-11-01 16:15:13 EDT
Created attachment 81880 [details]
PR_207711 on my machine
Comment 11 Steve Northover CLA 2007-11-01 16:16:46 EDT
Ok, what exactly is the problem?  I'm just trying to understand (there is nothing personal going on).
Comment 12 Michael Chervil CLA 2007-11-01 16:21:14 EDT
(In reply to comment #11)
> Ok, what exactly is the problem?  I'm just trying to understand (there is
> nothing personal going on).

The selection width does not match the width specified during the MeasureItem event. The same goes for the width of the focus rectangle.

Also, during the Paint event TableItem.getTextBound() and TableItem.getBound() return the wrong (unmodified) width as well.

So: there is no way to have native selection and focus drawing when using owner draw and a Table with SWT.NONE.
Comment 13 Steve Northover CLA 2007-11-01 16:47:07 EDT
The SWT.MeasureItem is measuring the item, not the selection.  The value you return for the width is used to compute the scroll bars.  What you are seeing being drawn is the native selection.  Since you have not set any text, it is a small rectangle (and looks strange).

The getTextBounds() and getImageBounds() methods return the bounds of text or images that would be drawn if there was no custom draw.  They do not take into account the width you returned in SWT.MeasureItem.

>So: there is no way to have native selection and focus drawing when
>using owner draw and a Table with SWT.NONE.

I don't see that there is (right now).  The operating system draws the selection based on the image and text.  If you draw outside of that, then it has no way of knowing where you have drawn.  If you attempt to draw the selection yourself, it will look wrong on Vista and GTK because selection is a gradient, not a single color.

It's possible that we could allow you to set the width and height in the SWT.EraseItem event and use that as the selection.  This would be new API.
Comment 14 Matthew Hall CLA 2007-11-01 17:18:07 EDT
(In reply to comment #12)
> The selection width does not match the width specified during the MeasureItem
> event. The same goes for the width of the focus rectangle.

Steve, I think what Michael's saying is that he wants the selection background and focus rectangle to be *drawn* at the size calculated in MeasureItem, rather than at the default, native size as is the case currently.

In my code i've manage to sidestep the clickable region (bug 168807) and background coloring issues by using SWT.FULL_SELECTION.  However the focus rectangle remains at the native location which is usually incorrect.

This seems like a logical thing for SWT to do for you.  SWT alone has access to the native system toolkit in order to correctly draw a selection state.  Plus it can always be overridden by a SWT.EraseItem listener if it clears those flags.

> Also, during the Paint event TableItem.getTextBound() and TableItem.getBound()
> return the wrong (unmodified) width as well.

Michael: Custom draw allows you to either completely take over drawing, or to decorate what is natively drawn by the operating system.  In order to make the second case possible the behavior of these methods had to remain the same.  This way your listener can know exactly where the natively drawn components begin and end.

You are expected in your PaintItem listener to take the event.[x,y,width,height] rectangle as the *native* rectangle and use the same calculations as in MeasureItem to determine where to draw your stuff.

> So: there is no way to have native selection and focus drawing when using owner
> draw and a Table with SWT.NONE.

Actually, there is.  You have to tell SWT in the SWT.EraseItem listener that you are taking responsibility for painting the selection background and the focus rectangle:

public void handleEvent(Event e) {
  e.detail &= ~(SWT.SELECTED | SWT.FOCUSED);
}

Then, in the SWT.PaintItem listener, you have to draw the proper background and focus rectangle depending on the state passed in on the Event.detail field:

public void handleEvent(Event e) {
  if ((e.detail & SWT.SELECTED) == SWT.SELECTED) {
    // draw selection background
  }
  // draw foreground
  if ((e.detail & SWT.FOCUSED) == SWT.FOCUSED) {
    // draw focus rectangle
  }
}
Comment 15 Michael Chervil CLA 2007-11-01 17:29:48 EDT
Thanks for the explanations.

(In reply to comment #13)
> This would be new API.

I don't understand the drawback of reusing the width of the Measure event for this: The maximal item width stays the desired column width as it is now, and the information for selection and focus drawing (and the hittest region of bug 168807) could be modified by setting the width as well. 

(In reply to comment #14)
> Actually, there is.  You have to tell SWT in the SWT.EraseItem listener that
> you are taking responsibility for painting the selection background and the
> focus rectangle:

Actually I am aware of that, that's why I wrote 'native' selection drawing. Steve described it better than I can:

> If you attempt to draw the selection yourself, it will look wrong on Vista 
> and GTK because selection is a gradient, not a single color.

Comment 16 Steve Northover CLA 2007-11-01 18:29:45 EDT
>Steve, I think what Michael's saying is that he wants the selection
>background and focus rectangle to be *drawn* at the size calculated in
>MeasureItem, rather than at the default, native size as is the case
>currently.

Isn't that (almost) the same as full selection?  If we did this, it wouldn't allow you to decorate (ie. leave the icon and text alone and draw an icon to the right of the text).  Also on XP, the selection is only drawn around the text.  Can SWT.MeasureItem be used to capture this and the selection??

The only thing I can think of is that you modify/provide a recangle in SWT.Erase and the selection is drawn using that.  It seems a bit hacky but it will work.  If you don't change the rectangle, then the native selection is drawn.  If you do change the rectangle, then the native selection is drawn in the new rectangle you provide, where you want it.

Finally, another answer might be to give API to draw a tree selection and then you draw it yourself.

We need to move all this discussion to another bug report (one that is still open) that captures the issue.  How about the hittest one?
Comment 17 Matthew Hall CLA 2007-11-01 19:04:17 EDT
> We need to move all this discussion to another bug report (one that is still
> open) that captures the issue.  How about the hittest one?

I will paste my responses there.
Comment 18 Martin Aeschlimann CLA 2008-01-30 10:57:34 EST
(In reply to comment #17)
> > We need to move all this discussion to another bug report (one that is still
> > open) that captures the issue.  How about the hittest one?
> 
> I will paste my responses there.
> 

Is that bug 168807 ?

Comment 19 Steve Northover CLA 2008-01-30 16:53:56 EST
Yes.