#638 Button events

KevinKelley Sat 13 Jun 2009

Okay, I'm trying to add tooltip help on ToolBar buttons, and having problems.

First I tried adding button.onMouseHover handlers, but no joy; buttons (at least when in toolbars) don't generate events. Not surprising; lot of libraries have the toolbar generate events for its buttons.

So I added the handler on toolbar instead, and I now get the events -- but, the event data isn't good. echoing the event shows:

Event { id=mouseHover button=0 key= pos=161,14 count=0 }

So I'm thinking the button property ought to be the button index. But it's always 0, no matter where I hover.

Okay, so next I'm thinking workaround using the pos property to find the button whose bounds contains that point. Which would be fine except when I iterate the toolbar's children and look at child.bounds I get nothing -- all the buttons report {0,0,0,0} as their bounds.

This method:

Widget? childAtPoint(Widget parent, Point pt)
{
  return parent.children.find |child|
  {
    echo("pt: $pt; child: $child; child.bounds: $child.bounds")
    return child.bounds.contains(pt.x, pt.y)
  }
}

gives me this output:

hover on fan.fwt.ToolBar@ba9340
pt: 30,7; child: fan.fwt.Button@1551d7f; child.bounds: 0,0,0,0
pt: 30,7; child: fan.fwt.Button@10382a9; child.bounds: 0,0,0,0
pt: 30,7; child: fan.fwt.Button@17725c4; child.bounds: 0,0,0,0
pt: 30,7; child: fan.fwt.Button@1506dc4; child.bounds: 0,0,0,0

Any ideas?

brian Sat 13 Jun 2009

The Event.button is for the mouse button that got pressed, not the widget button.

Buttons on toolbars are a little weird in the SWT - if you look at ButtonPeer.java you can see that buttons in a toolbar aren't first class widgets, they are ToolItems. We'd have to see what people do in SWT for this.

KevinKelley Sat 13 Jun 2009

Okay, I see that... SWT doc shows a getBounds method on ToolItem, so how about this? I see in WidgetPeer.java the pos and size are managed by a PosProp and a SizeProp (from Prop.java).

And, the getter/setter for PosProp/SizeProp are doing if peer.control instanceof Control ..., so how about adding an else if instanceof ToolItem at least for the getters.

Then bounds should work at least on get ... I guess bounds.set should continue to do nothing, since layout is managed by the toolbar.

Okay, gonna try that.

KevinKelley Sat 13 Jun 2009

What do you know, it worked. With the diff below, I'm now getting correct values from toolbar.children[i].bounds, which means I'm able to tell which button an event happened in. Cool.

Still don't know how (or if it's possible) to get events directly from the buttons; but don't really need to.

diff -r f172726f9e28 src/fwt/java/Prop.java
--- a/src/fwt/java/Prop.java  Mon May 18 16:30:50 2009 -0400
+++ b/src/fwt/java/Prop.java  Fri Jun 12 21:53:04 2009 -0500
@@ -17,6 +17,7 @@
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.widgets.Widget;
 import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.ToolItem;

 /**
  * Props are used to manage a field's value and how they
@@ -175,6 +176,11 @@
         Control c = (Control)peer.control;
         val = WidgetPeer.point(c.getLocation());
       }
+      else if (peer.control instanceof ToolItem)
+      {
+        ToolItem t = (ToolItem)peer.control;
+        val = WidgetPeer.point(t.getBounds().x, t.getBounds().y);
+      }
       return val;
     }

@@ -210,6 +216,11 @@
         Control c = (Control)peer.control;
         val = WidgetPeer.size(c.getSize());
       }
+      else if (peer.control instanceof ToolItem)
+      {
+        ToolItem t = (ToolItem)peer.control;
+        val = WidgetPeer.size(t.getBounds().width, t.getBounds().height);
+      }
       return val;
     }

brian Sat 13 Jun 2009

Kevin - thanks for the patch. I pushed it into hg.

Side note: if you (or anybody else) is working with fwt in the tip note that I am making a few breaking changes as I get gfx support working browsers:

  • you can no longer subclass from Widget, you must use Canvas or Pane now
  • this morning I will be changing semanatics of Graphics.drawText to make y the baseline coordinate (as opposed to top level corner today)

brian Sat 13 Jun 2009

Actually I'm going to keep Graphics.drawText the way it is, it much more convenient to work with as a bounding box so you can do things like:

ty := (h - font.height) / 2

Chrome and Safari seem to respect this mode with textBaseline set to "top" (it appears that maybe FF seems to interpret "top" as "top of ascent", but I need to dig into it).

KevinKelley Sat 13 Jun 2009

Good; I'd noticed that and found it to be kind of convenient, not needing to worry about text baseline and leading and such for the simple case of "I just want to draw some text in a box".

Login or Signup to reply.