Help w/ dragging widgets around a canvas



Hi folks,

I've been trying to find a nice way to pack widgets into a canvas, and
then move them around.  I've hacked up some code from the gnome_canvas
example.  It took me a while to figure out that at least in the case of
a button, I had to draw something around it.  Makes sense, as the button
no doubt takes control of the mouse.

But something else is going wrong.

After moving the mouse around a bit ... signals stop getting sent to the
widget.  Then I can't move it any more.  This has nothing to do with
pressing the button widget.  I don't even do that.

I'm not sure if the problem is in the item_event callback, or if there
is a bug related to capturing mouse events for Gtk widgets.

Can anyone give me a hand here?  The sample code is below.

Thanks,

Dave Topper
--
Technical Director - Virginia Center for Computer Music
http://www.people.virginia.edu/~djt7p

----- snip -----

#include "testgnome.h"
#include <gdk/gdkkeysyms.h>

static gint
item_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
 static double x, y;
 double new_x, new_y;
 GdkCursor *fleur;
 static int dragging;
 double item_x, item_y;

 /* set item_[xy] to the event x,y position in the parent's
item-relative coordinates */
 item_x = event->button.x;
 item_y = event->button.y;
 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);

 switch (event->type) {
 case GDK_BUTTON_PRESS:
   printf("BUTTON_PRESS\n");
  switch (event->button.button) {
  case 1:
   if (event->button.state & GDK_SHIFT_MASK)
    gtk_object_destroy (GTK_OBJECT (item));
   else {
       printf("event->button.button 1\n");
    x = item_x;
    y = item_y;

    fleur = gdk_cursor_new (GDK_FLEUR);
    gnome_canvas_item_grab (item,
       GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
       fleur,
       event->button.time);
    gdk_cursor_destroy (fleur);
    dragging = TRUE;
   }
   break;

  case 2:
    printf("event->button.button 2\n");
    if (event->button.state & GDK_SHIFT_MASK)
   gnome_canvas_item_lower_to_bottom (item);
   else
    gnome_canvas_item_lower (item, 1);
   break;

  case 3:
    printf("event->button.button 2\n");
   if (event->button.state & GDK_SHIFT_MASK)
    gnome_canvas_item_raise_to_top (item);
   else
    gnome_canvas_item_raise (item, 1);
   break;

  default:
   break;
  }

  break;

 case GDK_MOTION_NOTIFY:
   printf("MOTION_NOTIFY\n");
  if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
   new_x = item_x;
   new_y = item_y;

   gnome_canvas_item_move (item, new_x - x, new_y - y);
   x = new_x;
   y = new_y;
  }
  break;

 case GDK_BUTTON_RELEASE:
   printf("BUTTON_RELEASE\n");
  gnome_canvas_item_ungrab (item, event->button.time);
  dragging = FALSE;
  break;

 default:
   printf("NOTHING\n");
  break;
 }

 return FALSE;
}

static void
setup_item (GnomeCanvasItem *item)
{
 gtk_signal_connect (GTK_OBJECT (item), "event",
       (GtkSignalFunc) item_event,
       NULL);
}

int
main (int argc, char *argv[]) {
  GtkWidget *canvas;
  GtkWidget *app;
  GtkWidget *box;
  GtkWidget *button;
  char app_name[32];
  char title[32];
  GnomeCanvasGroup *root;
  GtkWidget *frame;

  strcpy(app_name,"test");
  strcpy(title,"test");

  gnome_init ("testGNOME", title, argc, argv);

  app = gnome_app_new (app_name, title);
  gtk_window_set_policy (GTK_WINDOW (app), TRUE, TRUE, FALSE);

  canvas = gnome_canvas_new ();
  gtk_widget_set_usize (canvas, 500, 350);
  gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), 0, 0, 500,
350);
  root = gnome_canvas_root (GNOME_CANVAS (canvas));

  box = gtk_vbox_new(FALSE,0);
  button = gtk_button_new_with_label ("Hello world!");
  gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 10);

  frame = gtk_frame_new(NULL);
  gtk_container_add(GTK_CONTAINER(frame), box);

  setup_item(gnome_canvas_item_new (root,
       gnome_canvas_widget_get_type (),
       "widget", frame,
       "x", 100.0,
       "y", 100.0,
       "width", 100.0,
       "height", 40.0,
       "anchor", GTK_ANCHOR_NW,
       "size_pixels", FALSE,
       NULL));

  gnome_app_set_contents(GNOME_APP(app), canvas);

  gtk_widget_show(button);
  gtk_widget_show(box);
  gtk_widget_show(frame);
  gtk_widget_show(canvas);
  gtk_widget_show(app);
  gtk_main();
}






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