Re: moving a widget on a canvas



Lauris Kaplinski wrote:

> On Sun, 28 May 2000, Thomas Morris wrote:
>
> > Hi,
> > I've been experimenting with the Gnome Canvas a bit creating canvas
> > items from widgets and haven't had any
> > problems except when I try to drag a widget from one location on the
> > canvas to another.  When I click on the widget
> > and begin to drag him he starts jittering up and down and sideways as if
> > he is fighting back. Its a cool effect but its not
> > exactly what I want to use for a finished app. The code I used to
> > implement the movement is basically what I found in
> > Havoc's book and a few other emails in the archives.  Here is the
> > movement code that I use.  I really appreciate any help
> > or clues as to where my problem lies.
> >
> > gnome_canvas_w2c_d (GNOME_CANVAS (dwidget->home_canvas),
> >        event->button.x, event->button.y, &cx, &cy);
> >
> >  switch (event->type)
> >  {
> >  case GDK_BUTTON_PRESS:
> >   switch (event->button.button)
> >   {
> >   case 1:
> >    /* grab the widget */
> >    x = event->button.x;
> >    y = event->button.y;
> >    cursor = gdk_cursor_new (GDK_FLEUR);
> >    retval = gdk_pointer_grab (GTK_WIDGET (dwidget)->window,
> >          FALSE,
> >          GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
> >          NULL,
> Lauris Kaplinski wrote:
>
>> On Sun, 28 May 2000, Thomas Morris wrote:
>>
>> > Hi,
>> > I've been experimenting with the Gnome Canvas a bit creating canvas
>> > items from widgets and haven't had any
>> > problems except when I try to drag a widget from one location on the
>> > canvas to another.  When I click on the widget
>> > and begin to drag him he starts jittering up and down and sideways as
>> if
>> > he is fighting back. Its a cool effect but its not
>> > exactly what I want to use for a finished app. The code I used to
>> > implement the movement is basically what I found in
>> > Havoc's book and a few other emails in the archives.  Here is the
>> > movement code that I use.  I really appreciate any help
>> > or clues as to where my problem lies.
>> >
>> > gnome_canvas_w2c_d (GNOME_CANVAS (dwidget->home_canvas),
>> >        event->button.x, event->button.y, &cx, &cy);
>> >
>> >  switch (event->type)
>> >  {
>> >  case GDK_BUTTON_PRESS:
>> >   switch (event->button.button)
>> >   {
>> >   case 1:
>> >    /* grab the widget */
>> >    x = event->button.x;
>> >    y = event->button.y;
>> >    cursor = gdk_cursor_new (GDK_FLEUR);
>> >    retval = gdk_pointer_grab (GTK_WIDGET (dwidget)->window,
>> >          FALSE,
>> >          GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
>> >          NULL,
>> >          cursor,
>> >          event->button.time);
>>
>> Hmmm... aren't you here grabbing widget instead of corresponding canvas
>> item?
>>
>> >    if (!retval)
>> >     dragging = TRUE;
>> >    gdk_cursor_destroy (cursor);
>> >    break;
>> >   case 2:
>> >    break;
>> >   default:
>> >    break;
>> >   }
>> >   break;
>> >  case GDK_MOTION_NOTIFY:
>> >   if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
>> >    gnome_canvas_item_move (dwidget->this_item,
>> >       event->button.x - x,
>> >       event->button.y - y);
>> >    x = event->button.x;
>> >    y = event->button.y;
>> >   }
>> >   break;
>> >  case GDK_BUTTON_RELEASE:
>> >   if (gdk_pointer_is_grabbed ()) {
>> >    gdk_pointer_ungrab (event->button.time);
>> >    dwidget->xpos = event->button.x;
>> >    dwidget->ypos = event->button.y;
>> >    dbs_widget_save (dwidget);
>> >   }
>> >   dragging = FALSE;
>> >   break;
>> >  default:
>> >   break;
>> >  }
>> >
>> > best regards,
>> > Thomas Morris.
>> >
>
> >          cursor,
> >          event->button.time);
>
> Hmmm... aren't you here grabbing widget instead of corresponding canvas
> item?
>
> >    if (!retval)
> >     dragging = TRUE;
> >    gdk_cursor_destroy (cursor);
> >    break;
> >   case 2:
> >    break;
> >   default:
> >    break;
> >   }
> >   break;
> >  case GDK_MOTION_NOTIFY:
> >   if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
> >    gnome_canvas_item_move (dwidget->this_item,
> >       event->button.x - x,
> >       event->button.y - y);
> >    x = event->button.x;
> >    y = event->button.y;
> >   }
> >   break;
> >  case GDK_BUTTON_RELEASE:
> >   if (gdk_pointer_is_grabbed ()) {
> >    gdk_pointer_ungrab (event->button.time);
> >    dwidget->xpos = event->button.x;
> >    dwidget->ypos = event->button.y;
> >    dbs_widget_save (dwidget);
> >   }
> >   dragging = FALSE;
> >   break;
> >  default:
> >   break;
> >  }
> >
> > best regards,
> > Thomas Morris.
> >

Lauris Kaplinski wrote:

> On Sun, 28 May 2000, Thomas Morris wrote:
>
> > Hi,
> > I've been experimenting with the Gnome Canvas a bit creating canvas
> > items from widgets and haven't had any
> > problems except when I try to drag a widget from one location on the
> > canvas to another.  When I click on the widget
> > and begin to drag him he starts jittering up and down and sideways as if
> > he is fighting back. Its a cool effect but its not
> > exactly what I want to use for a finished app. The code I used to
> > implement the movement is basically what I found in
> > Havoc's book and a few other emails in the archives.  Here is the
> > movement code that I use.  I really appreciate any help
> > or clues as to where my problem lies.
> >
> > gnome_canvas_w2c_d (GNOME_CANVAS (dwidget->home_canvas),
> >        event->button.x, event->button.y, &cx, &cy);
> >
> >  switch (event->type)
> >  {
> >  case GDK_BUTTON_PRESS:
> >   switch (event->button.button)
> >   {
> >   case 1:
> >    /* grab the widget */
> >    x = event->button.x;
> >    y = event->button.y;
> >    cursor = gdk_cursor_new (GDK_FLEUR);
> >    retval = gdk_pointer_grab (GTK_WIDGET (dwidget)->window,
> >          FALSE,
> >          GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
> >          NULL,
> >          cursor,
> >          event->button.time);
>
> Hmmm... aren't you here grabbing widget instead of corresponding canvas
> item?
>
> >    if (!retval)
> >     dragging = TRUE;
> >    gdk_cursor_destroy (cursor);
> >    break;
> >   case 2:
> >    break;
> >   default:
> >    break;
> >   }
> >   break;
> >  case GDK_MOTION_NOTIFY:
> >   if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
> >    gnome_canvas_item_move (dwidget->this_item,
> >       event->button.x - x,
> >       event->button.y - y);
> >    x = event->button.x;
> >    y = event->button.y;
> >   }
> >   break;
> >  case GDK_BUTTON_RELEASE:
> >   if (gdk_pointer_is_grabbed ()) {
> >    gdk_pointer_ungrab (event->button.time);
> >    dwidget->xpos = event->button.x;
> >    dwidget->ypos = event->button.y;
> >    dbs_widget_save (dwidget);
> >   }
> >   dragging = FALSE;
> >   break;
> >  default:
> >   break;
> >  }
> >
> > best regards,
> > Thomas Morris.
> >Lauris Kaplinski wrote:
>
>> On Sun, 28 May 2000, Thomas Morris wrote:
>>
>> > Hi,
>> > I've been experimenting with the Gnome Canvas a bit creating canvas
>> > items from widgets and haven't had any
>> > problems except when I try to drag a widget from one location on the
>> > canvas to another.  When I click on the widget
>> > and begin to drag him he starts jittering up and down and sideways as
>> if
>> > he is fighting back. Its a cool effect but its not
>> > exactly what I want to use for a finished app. The code I used to
>> > implement the movement is basically what I found in
>> > Havoc's book and a few other emails in the archives.  Here is the
>> > movement code that I use.  I really appreciate any help
>> > or clues as to where my problem lies.
>> >
>> > gnome_canvas_w2c_d (GNOME_CANVAS (dwidget->home_canvas),
>> >        event->button.x, event->button.y, &cx, &cy);
>> >
>> >  switch (event->type)
>> >  {
>> >  case GDK_BUTTON_PRESS:
>> >   switch (event->button.button)
>> >   {
>> >   case 1:
>> >    /* grab the widget */
>> >    x = event->button.x;
>> >    y = event->button.y;
>> >    cursor = gdk_cursor_new (GDK_FLEUR);
>> >    retval = gdk_pointer_grab (GTK_WIDGET (dwidget)->window,
>> >          FALSE,
>> >          GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
>> >          NULL,
>> >          cursor,
>> >          event->button.time);
>>
>> Hmmm... aren't you here grabbing widget instead of corresponding canvas
>> item?
>>
>> >    if (!retval)
>> >     dragging = TRUE;
>> >    gdk_cursor_destroy (cursor);
>> >    break;
>> >   case 2:
>> >    break;
>> >   default:
>> >    break;
>> >   }
>> >   break;
>> >  case GDK_MOTION_NOTIFY:
>> >   if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
>> >    gnome_canvas_item_move (dwidget->this_item,
>> >       event->button.x - x,
>> >       event->button.y - y);
>> >    x = event->button.x;
>> >    y = event->button.y;
>> >   }
>> >   break;
>> >  case GDK_BUTTON_RELEASE:
>> >   if (gdk_pointer_is_grabbed ()) {
>> >    gdk_pointer_ungrab (event->button.time);
>> >    dwidget->xpos = event->button.x;
>> >    dwidget->ypos = event->button.y;
>> >    dbs_widget_save (dwidget);
>> >   }
>> >   dragging = FALSE;
>> >   break;
>> >  default:
>> >   break;
>> >  }
>> >
>> > best regards,
>> > Thomas Morris.
>> >
>
Hi Lauris,
you were right I was grabbing the widget's window instead of the canvas item
however there are a few more pieces to complete the puzzle.  Federico Quitero
pointed out in an email some months ago that when using a widget on a canvas
note the widget receives all events not the canvas item. Therefore the widget
needs the event handler to catch the mouse events up to the point that
gnome_canvas_item_grab is called.  gnome_canvas_item_grab should grab the
canvas item, as you pointed out, however at this point the canvas item starts
receiving the masked events. Therefore I have had to setup an event handler
for the widget and one for the canvas item. The handler for the canvas item
is responsible for moving the canvas item and releasing the grab. So far this
is the cleanest way that I have found. Here are the code snippets that show
what I just described.  Thanks for the help.

static gint
dwidget_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
 DbsWidget *dwidget;
 static GdkCursor *cursor;
 gboolean retval;

 dwidget = DBS_WIDGET (widget);

 switch (event->type)
 {
 case GDK_BUTTON_PRESS:
  switch (event->button.button)
  {
  case 1:
   /* grab the widget */
   item_xpos = dwidget->xpos;
   item_ypos = dwidget->ypos;
   cursor = gdk_cursor_new (GDK_FLEUR);
   retval = gnome_canvas_item_grab (dwidget->this_item,
        GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
        cursor,
        event->button.time);
   if (!retval)
    dragging = TRUE;
   gdk_cursor_destroy (cursor);
   break;
  default:
   break;
  }
  break;
 default:
  break;
 }

 return FALSE;
}

static gint
canvas_item_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer
user_data)
{
 DbsWidget *dwidget;
 static gint dif_set = FALSE;
 static double difx, dify;

 dwidget = DBS_WIDGET (user_data);

 switch (event->type)
 {
 case GDK_MOTION_NOTIFY:
  if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
   if (!dif_set) {
    difx = event->button.x - item_xpos;
    dify = event->button.y - item_ypos;
    dif_set = TRUE;

   }
   gnome_canvas_item_move (dwidget->this_item,
      event->button.x - item_xpos - difx,
      event->button.y - item_ypos - dify);
   item_xpos = event->button.x - difx;
   item_ypos = event->button.y - dify;
  }
  break;
 case GDK_BUTTON_RELEASE:
  if (gdk_pointer_is_grabbed ()) {
   gnome_canvas_item_ungrab (dwidget->this_item, event->button.time);
   dwidget->xpos = item_xpos;
   dwidget->ypos = item_ypos;
   dbs_widget_save (dwidget);
   dif_set = FALSE;
  }
  dragging = FALSE;
  break;
 default:
  break;
 }

 return FALSE;
}


Best regards,
Thomas.


begin:vcard 
n:Morris;Thomas
tel;cell:+49 177 2857370
tel;fax:+49 631 3504738
tel;home:+49 631 3504736
tel;work:+49 631 3504736
x-mozilla-html:FALSE
url:www.linuxpro.org/thomas
adr:;;;;;;
version:2.1
email;internet:Thomas@linuxpro.org
x-mozilla-cpt:;24960
fn:Thomas Morris
end:vcard


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]