On 26.03.2011 15:20, chris wrote:

> Just wanted to point to some sort of discrepancy with Fl::event_inside(const 
> Fl_Widget*) I recently noticed.
>
> I was using it from within a handle() of a class derived from Fl_Window and 
> found, that it didn't work as expected.
>
> Either there is some discrepancy between the coordinate system 
> Fl::event_inside() uses with the Fl::event_x()/y() coordinate system uses.
>
> Or it is simply never meant to be used for container type widgets, which 
> means the documentation should be made clearer in this aspect.

You are right that the docs should be improved, but the method
works as intended. Let me explain:

First of all, if you only want to use a "container type" widget,
then you should probably use Fl_Group instead of Fl_Window for
the included containers. Using subwindows is useful if you want
to include an Fl_Gl_Window or some other type of window, but
usually not as a simple container widget. If you derive the
"Subwin" class in your demo code, then you can see that it works
as you expected.

The function is intended to tell you, whether an event occurred
in a specific widget *within* the window the event was delivered
to. All events are primarily delivered to a specific window, and
if you derive a class from Fl_Window, then you don't need to check
whether this event was in the window that got the event - because
that has been checked before. The x() and y() coordinates of windows
are those relative to the window's parent (for main windows, this
would be the desktop or root window), and you accounted for this
in your own event_inside() method. This would indeed work, but
as said before, it is not useful to check if an event is inside the
window that got the event, because this is always true (to be precise:
this *may* be false for FL_DRAW, FL_DRAG and maybe DND events, but
this is a special case).

So, yes, I changed the docs to make it clear that
Fl::event_inside(const Fl_Widget *) must not be called for the
window that handles the event. Thanks for the report.

This is now in the subversion repository (r 8538), but not yet
in the online docs.

> I have made a small source example for this case:

Thanks for the demo source. It was very helpful to understand the
issue. Some more notes to the code:

> --- snip ---

> class SubWin : public Fl_Window
                         ^^^^^^^^^

Try Fl_Group here and in the following statements instead of
Fl_Window.

> {
> public:
>    SubWin( int x_, int y_, int w_, int h_ ) :
>      Fl_Window( x_, y_, w_, h_ )
        ^^^^^^^^^
        Fl_Group

>    {

         box(FL_FLAT_BOX); // add a box type to make the group visible.

>    }
>    virtual int handle( int e_ )
>    {
>      switch ( e_ )
>      {
>        case FL_PUSH:
>          printf( "FL_PUSH %p: x=%d y=%d Fl::event_x()=%d Fl::event_y()=%d\n",
>                  this, x(), y(), Fl::event_x(), Fl::event_y() );
>          if ( Fl::event_inside( this ) )
>          {
>            // doesn't work if you push in the top/left areas of the subwins
>            // because Fl_event_x/y() counts coordinates relative to subwin,
>            // wheras Fl::event_inside() uses coordinates relative to parent 
> window.
>            printf( "Fl::event_inside(): pushed inside %s canvas (%p)\n", 
> colorname(color()), this );
>          }
>          if ( /*Fl::*/event_inside( this ) )
>          {
>            // works as expected
>            printf( "event_inside(): pushed inside %s canvas (%p)\n", 
> colorname(color()), this );
>          }
>          break;

In a real handle() method you would probably want to return 1 here.

>        case FL_RELEASE:
>          printf("\n");
>          break;
>      }
>      return Fl_Window::handle( e_ );
               ^^^^^^^^^^
               Fl_Group

>    }
> };
>
> int main( int argc_, const char *argv_[] )
> {
>    Fl_Window win( 640, 480, "event_inside TEST" );
>    SubWin subwin( 100, 100, 300, 200 );
>    subwin.color( FL_GREEN );
>    SubWin subwin2( 30, 30, 100, 100 );

      SubWin subwin2( 130, 130, 100, 100 ); // adjust coordinates

>    subwin2.color( FL_RED );
>    subwin2.end();

      subwin.end(); // don't forget this
      win.end();    // ... and this

>    win.show();
>    return Fl::run();
> }
> --- snip ---

Although the missing end() statements don't matter here, you
should always use them, otherwise strange widget placements
might happen.

You probably wouldn't call the class "Subwin" if you derived it
from Fl_Group, but that also doesn't matter here.

Albrecht
_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to