Bug 228376 - Owner draw: measure does not contain 'is selected' information
Summary: Owner draw: measure does not contain 'is selected' information
Status: RESOLVED FIXED
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: 3.7   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks: 228397 292198
  Show dependency tree
 
Reported: 2008-04-23 07:12 EDT by Martin Aeschlimann CLA
Modified: 2011-04-28 10:53 EDT (History)
7 users (show)

See Also:


Attachments
example code (8.36 KB, text/plain)
2008-04-23 07:12 EDT, Martin Aeschlimann CLA
no flags Details
Patch for Win32 (6.97 KB, patch)
2010-10-07 19:17 EDT, Scott Kovatch CLA
no flags Details | Diff
Patch for Mac/Cocoa (6.30 KB, patch)
2010-10-07 19:37 EDT, Scott Kovatch CLA
no flags Details | Diff
Patch for GTK (2.35 KB, patch)
2010-10-21 11:28 EDT, Felipe Heidrich CLA
no flags Details | Diff
Patch for motif (3.38 KB, patch)
2010-10-21 11:51 EDT, Felipe Heidrich CLA
no flags Details | Diff
new patch for Tree on win32 (4.46 KB, patch)
2010-10-21 15:50 EDT, Felipe Heidrich CLA
no flags Details | Diff
Modified example code (7.50 KB, text/plain)
2010-10-22 12:42 EDT, Scott Kovatch CLA
no flags Details
Second modified example (8.12 KB, text/plain)
2010-10-22 12:43 EDT, Scott Kovatch CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2008-04-23 07:12:30 EDT
Created attachment 97201 [details]
example code

20080422-0800

Not sure if it is a bug or intended:

in the measure event (SWT.MeasureItem), it's currently not possible to find out if the element is selected:
   SWT.SELECTED is never set in event.detail.

It would be nice to have this information so we don't need to do extra work in paint
(want to prepare the text layout once in measure (needed for the width) and just apply it in paint)

See the example snippet. Sorry for not realizing this earlier.
Comment 1 Steve Northover CLA 2008-04-23 09:34:24 EDT
This was intended (but I can't think of a reason why this information should not be included).  Probably won't get to this for 3.4, unless critical.

The measure event was originally indended to configure the scroll bars and column widths for pack().  Then is was extended to be used for hittesting, hover and selection drawing.  Note that it is sent on hover but erase and paint may not be sent later.  This happens when the mouse moves out of the hover rectangle before the operating system hover conditions are satisfied.  Is this a problem?
Comment 2 Martin Aeschlimann CLA 2008-04-23 10:21:43 EDT
Our implementation of the StyledCellLabelProvider now constructs the text layout for selected items two times:
- Once in measure to compute the width
- Once in paint, same as before but without colors

If we knew the selection state in 'measure', we could do it right the first time.
But that's only for the selected items. So its not critical. But nice to have.
Comment 3 Markus Keller CLA 2010-06-22 13:48:14 EDT
This would still be nice to have. It doesn't sound hard to fix, and it would save us unnecessary TextLayout#setStyle(..) and subsequent computeRuns(..) for each selected item.

(In reply to comment #1)
> Note that it [measure event] is sent on hover but erase and paint
> may not be sent later.  This happens when the mouse moves out of the hover
> rectangle before the operating system hover conditions are satisfied.  Is this
> a problem?

No, as long as measure is always sent before erase and paint (bug 228695), that's no problem.
Comment 4 Markus Keller CLA 2010-10-07 13:11:32 EDT
Any chance to get this fixed for 3.7?
Comment 5 Scott Kovatch CLA 2010-10-07 19:17:09 EDT
Created attachment 180463 [details]
Patch for Win32
Comment 6 Scott Kovatch CLA 2010-10-07 19:37:32 EDT
Created attachment 180464 [details]
Patch for Mac/Cocoa
Comment 7 Scott Kovatch CLA 2010-10-07 20:16:59 EDT
Cocoa and Win32 changes attached. I don't have a GTK install handy, but the changes will be much smaller.
Comment 8 Felipe Heidrich CLA 2010-10-18 11:58:47 EDT
--- IMO about the code

I verifed the code in Win32, it looks good.

Usually send(Measure/Erase/Paint)ItemEvent does all the work internally to compute the detail field. We could change Tree#sendMeasureItemEvent() to follow the same design by calling isItemSelected (item.handle, gc.handle, 0) in the method. But the current code is fine as it reuses the is select state in two places.

I guess the only change I'd suggest is to change in the new parameter in sendMeasureItemEvent () from isSelected to detail, this way it will require less code change in the future if we need to grow more information on the event.


--- IMO about the idea

If we add the selection status to the detail field for MeasureItem event now we will open the door for people to ask the detail field to include all other status (as detail field during MeasureItem would be inconsistent if compared to PaintItem, EraseItem events).



Martin, can you change your code from:
boolean isSelected= (event.detail & SWT.SELECTED) != 0; // doesn't work at the moment: see bug.
to:
Table table = item.getParent();
boolean isSelected= table.isSelected(indexOf(item));

That is basically what Scott's patch is doing for Table anyway...
Comment 9 Markus Keller CLA 2010-10-18 13:07:43 EDT
(In reply to comment #8)
> If we add the selection status to the detail field for MeasureItem event now we
> will open the door for people to ask the detail field to include all other
> status (as detail field during MeasureItem would be inconsistent if compared to
> PaintItem, EraseItem events).

Don't worry, people will ask even if you don't open the door ;-). Anyway, the API can always be documented (bug 81334).


> Martin, can you change your code [..] to [..] table.isSelected([..]) ?

The owner draw framework in JFace does not know about the concrete type of the control. We could handle Table as a special case, but most of our owner-draw controls are actually Trees. But Tree doesn't have an isSelected(..) API and using TreeItem[] getSelection() sounds expensive.
Comment 10 Felipe Heidrich CLA 2010-10-19 09:28:13 EDT
Silenio, this is a request for new API. Please advise.

Personally I'm not against adding this API, see comment 8 and 9.
Comment 11 Silenio Quarti CLA 2010-10-20 17:19:32 EDT
The new API is fine. We just need an implementation for the other platforms (GTK and Motif) to be able to close this.
Comment 12 Felipe Heidrich CLA 2010-10-21 11:28:24 EDT
Created attachment 181414 [details]
Patch for GTK
Comment 13 Scott Kovatch CLA 2010-10-21 11:33:14 EDT
(In reply to comment #12)
> Created an attachment (id=181414) [details]
> Patch for GTK

Cool! I can shut down my ubuntu image for a while.
Comment 14 Felipe Heidrich CLA 2010-10-21 11:51:15 EDT
Created attachment 181417 [details]
Patch for motif
Comment 15 Felipe Heidrich CLA 2010-10-21 15:30:11 EDT
I have released the code for:
Table and Tree on GTK
Table and Tree on Motif
Table on Windows

I was about to release Tree on Windows but my testing showed me that it does not work on all the cases.

Change the snippet in the first comment to use a tree, select all items in the tree and just move the mouse over them. Note MeasureItem will report all items as not selected (you will need to add println to the testcase).

It seems to me that isItemSelected() is not supposed to be called outside the custom draw phase. 

Scott, did you have change to test your patch (tree on windows) ?

I'll try to fix it.
Comment 16 Felipe Heidrich CLA 2010-10-21 15:50:30 EDT
Created attachment 181444 [details]
new patch for Tree on win32

It worked for me. I'll test, verify, and release tomorrow when I get back to the office.
Comment 17 Scott Kovatch CLA 2010-10-21 16:53:05 EDT
(In reply to comment #15)
> It seems to me that isItemSelected() is not supposed to be called outside the
> custom draw phase. 
> 
> Scott, did you have change to test your patch (tree on windows) ?

My test was as you described -- changing the example to use a Tree instead of a Table, but I didn't try the test case you mentioned. I was trying to reuse isItemSelected but it looks like that wasn't a good idea.

Silenio and I talked briefly about setting other bits in the detail field, but it looks like we're going to go with just the SELECTED bit now. I'll check in the cocoa change shortly.
Comment 18 Scott Kovatch CLA 2010-10-21 17:04:04 EDT
Actually, is the point of this change to notify the listener that the item is about to be drawn with the selection or that the item itself is selected? In other words, should we be checking "isSelected && ((style & SWT.HIDE_SELECTION) == 0 || hasFocus" before setting the SELECTED bit?
Comment 19 Felipe Heidrich CLA 2010-10-22 10:32:29 EDT
Tree fixed for win32.

Scott, please release cocoa and close the bug.

SELECTED in MeasureItem has to mean exactly the same it means in EraseItem and PaintItem.

Isn't the current code correct ?
Comment 20 Scott Kovatch CLA 2010-10-22 12:02:53 EDT
(In reply to comment #19)
> Tree fixed for win32.
> 
> Scott, please release cocoa and close the bug.
> 
> SELECTED in MeasureItem has to mean exactly the same it means in EraseItem and
> PaintItem.

On Cocoa, the code just before we send a PaintItem or EraseItem message is:

if (isSelected && ((style & SWT.HIDE_SELECTION) == 0 || hasFocus)) event.detail |= SWT.SELECTED;

> Isn't the current code correct ?

If I leave that check out and modify the current test case so that the table/tree is created with HIDE_SELECTION the selected item draws with a different text color when the window isn't active and it doesn't look right. So, I think on Cocoa, anyway, we need that extra line. I'll check it all in.

It will take me a few minutes to check on windows 7, but it looks like we may need to do something similar there.
Comment 21 Scott Kovatch CLA 2010-10-22 12:07:31 EDT
(In reply to comment #20)
 
> It will take me a few minutes to check on windows 7, but it looks like we may
> need to do something similar there.

Yes, I'm seeing the same bug on Windows. With HIDE_SELECTION set the text draws black when the window isn't active.
Comment 22 Felipe Heidrich CLA 2010-10-22 12:21:21 EDT
(In reply to comment #21)
> Yes, I'm seeing the same bug on Windows. With HIDE_SELECTION set the text draws
> black when the window isn't active.

Okay, release all the code you have once you are done testing.

I'll see what you did and do the same for GTK and Motif, okay ?

To help me test, please add your snippet to this bug. Thanks.
Comment 23 Scott Kovatch CLA 2010-10-22 12:42:55 EDT
Created attachment 181518 [details]
Modified example code

Same as the example, except it uses a Tree and sets SWT.HIDE_SELECTION on creation.
Comment 24 Scott Kovatch CLA 2010-10-22 12:43:40 EDT
Created attachment 181519 [details]
Second modified example

Table with HIDE_SELECTION
Comment 25 Scott Kovatch CLA 2010-10-22 12:44:10 EDT
Changes for Cocoa are now checked in.
Comment 26 Felipe Heidrich CLA 2010-10-25 11:40:40 EDT
Awesome, the fix for table used be:
event.detail = isSelected (indexOf (item)) ? SWT.SELECTED : 0;

Turns out the correct fix is:
boolean drawSelected = false;
if (OS.IsWindowEnabled (handle)) {
	LVITEM lvItem = new LVITEM ();
	lvItem.mask = OS.LVIF_STATE;
	lvItem.stateMask = OS.LVIS_SELECTED;
	lvItem.iItem = (int)/*64*/row;
	int /*long*/ result = OS.SendMessage (handle, OS.LVM_GETITEM, 0, lvItem);
	boolean selected = (result != 0 && (lvItem.state & OS.LVIS_SELECTED) != 0);
	if (selected && (column == 0 || (style & SWT.FULL_SELECTION) != 0)) {
		if (OS.GetFocus () == handle || display.getHighContrast ()) {
			drawSelected = true;
		} else {
			drawSelected = (style & SWT.HIDE_SELECTION) == 0;
		}
	}
}
if (drawSelected) event.detail |= SWT.SELECTED;

I'll release Table, then fix Tree, then check GTK and Motif...
Comment 27 Dani Megert CLA 2010-10-25 11:46:48 EDT
Felipe, did you add the security flag on purpose?
Comment 28 Scott Kovatch CLA 2010-10-25 11:51:02 EDT
It's too easy to check that box. I've done that a couple of times myself.
Comment 29 Felipe Heidrich CLA 2010-10-25 11:55:28 EDT
Thanks Scott, I didn't notice it at all
Comment 30 Markus Keller CLA 2011-04-01 09:21:01 EDT
Is this still on the plan for 3.7?
Comment 31 Felipe Heidrich CLA 2011-04-04 11:12:21 EDT
(In reply to comment #30)
> Is this still on the plan for 3.7?

All the code has being released (not sure why I left this problem open, I think there was something I wanted to test...)

Is the problem fixed on your end ?
Comment 32 Markus Keller CLA 2011-04-04 19:22:44 EDT
> Is the problem fixed on your end ?

Yes, looks good. I just removed the workarounds (bug 292198) and tested Tree and Table on Win7, GTK, Cocoa.
Comment 33 Felipe Heidrich CLA 2011-04-05 10:57:23 EDT
(In reply to comment #32)
> > Is the problem fixed on your end ?
> Yes, looks good. I just removed the workarounds (bug 292198) and tested Tree
> and Table on Win7, GTK, Cocoa.

thank you Markus, closing this bug as fixed.