Bug 168807 - SWT.MeasureItem not used for selection hittest
Summary: SWT.MeasureItem not used for selection hittest
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal with 1 vote (vote)
Target Milestone: 3.4 M5   Edit
Assignee: Steve Northover CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 210809
  Show dependency tree
 
Reported: 2006-12-20 22:48 EST by Matthew Hall CLA
Modified: 2008-02-07 11:48 EST (History)
10 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthew Hall CLA 2006-12-20 22:48:27 EST
(3.3M4)

I'm having trouble selecting items in an owner-draw table using the mouse.  I can use the arrow keys to move the selection up and down through the table, however I have to click at the far left side of the table to select the item with a mouse.  Clicking anywhere outside this small area has no effect.  The example below demonstrates this behavior.

I believe this is happening because the "hot zone" rectangle (the region where clicking selects the item) is derived from the item's image and text, even if the table is in owner-draw mode.  The example code does not set any text or images on the table items, so the clickable region ends up being very small.

Perhaps when in owner-draw mode, the clickable region should be the size returned by MeasureItem.

In the meanwhile, using SWT.FULL_SELECTION style in the table gets around this behavior.

----

package swt.rocks.the.casbah;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;

/**
 * Demonstrate problem with owner draw table item selection using mouse clicks
 * @author Matthew Hall
 */
public class OwnerDrawTableTest {
  /**
   * 
   * @param args
   */
  public static void main(String[] args) {
    Display display = new Display();

    Shell shell = new Shell(display, SWT.SHELL_TRIM);
    shell.setBounds(100, 100, 400, 300);
    shell.setLayout(new FillLayout());

    Table table = new Table(shell, SWT.NONE);

    table.addListener(SWT.MeasureItem, new Listener() {
      public void handleEvent(Event event) {
        String text = (String) event.item.getData();
        Point textExtent = event.gc.textExtent(text);
        event.width = textExtent.x;
        event.height = textExtent.y;
      }
    });

    table.addListener(SWT.EraseItem, new Listener() {
      public void handleEvent(Event event) {
        event.detail &= ~SWT.FOREGROUND;
      }
    });

    table.addListener(SWT.PaintItem, new Listener() {
      public void handleEvent(Event event) {
        String text = (String) event.item.getData();
        event.gc.drawText(text, event.x, event.y);
        event.detail &= ~SWT.FOREGROUND;
      }
    });

    String[] items = new String[] {
        "aslkdjflaksjdfsal",
        "aslkjdfslkjflksfl",
        "slkdjflskjdflksjf",
        "lskdjflksjdflkdsj",
        "lskdfjlskdfjlksjf"
    };

    for (String item : items)
      new TableItem(table, SWT.LEFT).setData(item);

    shell.open();
    table.setFocus();
    table.setSelection(0);
    while (!shell.isDisposed())
      if (!display.readAndDispatch())
        display.sleep();

    display.dispose();
  }
}
Comment 1 Jed Anderson CLA 2007-10-29 13:03:19 EDT
I see this with FULL_SELECTION as well.  However, if I programmatically make an initial selection I don't see the problem.
Comment 2 Matthew Hall CLA 2007-10-29 13:26:14 EDT
Do you mean you can't click on the item to select it?  This bugzilla is not concerned with the focus rectangle--only the hit rectangle where clicking causes an item to become selected.
Comment 3 Jed Anderson CLA 2007-10-29 13:43:09 EDT
Ah, I should be more clear.  I have a tree, not a table.  It looks something like this:

Text Header
(i) Item
(i) Item             *
(i) Item

All of the items in the tree are at the top level of the tree.  The font on the Text Header item is large, but it has no icon.  All of the other items have icons.  Everything is custom measured and painted.

What I have found is that right after the tree is first created the hit test appears to use the width/height of the Text Header to determine selections.  If I click off to the side (like where the '*' is) the Text Header is selected.

However, once a selection has been made on the tree SWT/Windows seems to figure out what's going on and selections occur normally.

My workaround is to make and remove a selection right after table creation.  It happens fast enough that there isn't a flicker.
Comment 4 Steve Northover CLA 2007-10-29 22:54:47 EDT
Windows platform behavior is to select the first visible item when the tree gets focus and there is no selection.  You can see this in trees that don't use custom draw.  Could it be this behavior that you are seeing and it is somehow going wrong for custom draw?

In any case, please enter a new bug report with a description of the problem and a sample test case and put me on the CC.
Comment 5 Matthew Hall CLA 2007-11-01 19:08:51 EDT
(In reply to Bug #207711 comment #16)
> >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?

Not if the rectangle was measured and drawn per-item.

> 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).

I don't understand why this would be any different that me taking over background and focus painting but not foreground.

> Also on XP, the selection is only drawn around the
> text.  Can SWT.MeasureItem be used to capture this and the selection??

Yes, yhat detail about XP makes it infeasible to use the MeasureItem rect.

> 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.

That sounds like it would work, but it is kind of a hack.  My concern is that custom draw is already so complex, and I worry that obscure details like this will make it worse.

It makes it almost as much work as just drawing the selection and focus yourself.

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

It seems this approach might be useful in other situations where you want to paint a native-looking selection.  Then there's the question of whether selected items are painted differently in trees vs tables
Comment 6 Michael Chervil CLA 2007-11-02 05:27:01 EDT
> > 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.

This could solve both the native drawing and the hittest issue this bug is about.

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

While this sounds more intuitive, it wouldn't change the hittest region, would it?

What about an API for setting an item's rectangle used for hittest, selection and focus drawing? Probably not feasable, because the icon must stay clickable, while it shouldn't be drawn as selected on XP, as Steve pointed out.

This behaviour of XP is something that makes life hard for everyone. Lets assume we have an API to draw native selection. Owner draw code has to make a difference whether it runs on XP or not, to make certain it looks the same as natively drawn.
Comment 7 Boris Bokowski CLA 2008-01-30 17:40:01 EST
Do you plan to do something about this in 3.4?

Right now, we have owner draw support in JFace, but it only works well if you don't do anything that changes the size of the text. I.e. we support multiple colors, but not multiple fonts.

Multiple colors are being used to de-emphasize secondary information, e.g. in the Package Explorer, and the current support works well for that.

It is not looking as good when you use multiple fonts, for example to highlight matches with a bold face font as in the Quick Access dialog (Ctrl-3). In that particular case, we are lucky because we are using SWT.FULL_SELECTION, but it would be good if we could support this more generally.
Comment 8 Steve Northover CLA 2008-02-04 19:33:53 EST
Fixed > 20080204
Comment 9 Matthew Hall CLA 2008-02-05 01:24:31 EST
Hooray!  Will this be in 3.4M5?

Just to clarify, this addresses the mouse hit rect for item selection, but does not change the way selection or focus rects are painted (bug 207711), correct?
Comment 10 Steve Northover CLA 2008-02-05 10:37:18 EST
Mouse hit for selection only.  It will be in M5 ... if the fix holds.