Problem moving widgets in GNOME 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 works for the most part.  But I am limited to what seems
like the widget's original area ... as far as "dragging range" is
concerned.  If I move beyond it, the widget / canvas item does not get a
"motion notify" event any longer.

I mean, if I move outside the bounds of the item's original position and
size, the item no longer receives "event" signals.  Specifically, events
are only sent when the mouse moves over the area equal to the overlap of
the widget's current position w/ it's original ... swapped x/y.  The
attached code should make it clear.  The box / button widget is the
problem one.  I've placed a GnomeCanvasRectangle around the original
position for refernece.

Try dragging it to the right about 1/2 way (click slighly above / below
the button).  Then try dragging again, from "inside" the orig boundary
again.  You'll see no messages are sent until you're outside.

I suspect something regarding x/y coordinates is being corrupted but
can't see exactly why.  If anyone has some input, or a suggestion as to
wher I might look, I'd appreciate it.

Attached is some sample code.

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;

    printf("item_x = %2.2f\n",x);
    printf("item_y = %2.2f\n",y);

 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);

    printf("item_x = %2.2f\n",x);
    printf("item_y = %2.2f\n",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;

    printf("x = %2.2f\n",x);
    printf("y = %2.2f\n",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;

    printf("new_x = %2.2f\n",item_x);
    printf("new_y = %2.2f\n",item_y);

    /*     gtk_fixed_move(GTK_FIXED(item), item->parent, new_x - x,
new_y -y ); */
       gnome_canvas_item_move (item, new_x - x , new_y - y);
       gnome_canvas_item_request_update (item);
   x = new_x;
   y = new_y;

    printf("x = %2.2f\n",x);
    printf("y = %2.2f\n",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 *ebox,*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);

  /* ebox = gtk_event_box_new(); */
  /* gtk_box_pack_start(GTK_BOX(box), ebox, 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", GTK_WIDGET(box),
         "x", 100.0,
         "y", 100.0,
         "width", 100.0,
         "height", 40.0,
         "anchor", GTK_ANCHOR_CENTER,
         "size_pixels", FALSE,
         NULL));


 setup_item (gnome_canvas_item_new (root,
        gnome_canvas_rect_get_type (),
        "x1", 50.0,
        "y1", 80.0,
        "x2", 150.0,
        "y2", 120.0,
        "outline_color", "red",
        "width_pixels", 1,
        NULL));

  gnome_app_set_contents(GNOME_APP(app), canvas);

  gtk_widget_show(button);
  gtk_widget_show(box);
  /* gtk_widget_show(ebox); */
  /*  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]