GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Wed Sep 03, 2014 7:10 am

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: put moving crosshairs on a GDK image
PostPosted: Sun Nov 25, 2007 2:41 am 
Offline
Familiar Face

Joined: Sat Nov 17, 2007 3:05 pm
Posts: 5
I want to create an effect where guidelines follow a the pointer cursor
around on a GTK image - I don't even know the basics of drawing, like
how to get the GDK drawable. I think what I need to know is how to find
the drawable for the image, how to write lines onto that, and how to
restore what was originally where the lines were... can anyone point me
to the appropriate functions?

To rephrase what I'm trying to do - I want to have a pair of
1-pixel-thick lines, one horizontal, one vertical, that extend from
edge to edge of the GTK image, and cross at the point where the mouse
cursor is. And move around when the cursor moves. And the image doesn't
change, so whatever is "underneath" the lines has to get restored.

Thanks


Top
 Profile  
 
 Post subject: An answer
PostPosted: Wed Dec 05, 2007 3:31 am 
Offline
Familiar Face

Joined: Sat Nov 17, 2007 3:05 pm
Posts: 5
I happened to see a mail list conversation about drawing rubberbanding
lines that gave me enough examples to start to answer my own question,
and code that does what I want is below. Here's what I think I
learned, corrections welcome, and a question:

1. You can draw shapes with the gdk drawing functions, such as
gdk_draw_line, by writing on the widget's "window" member.
1a (?The window this draws on is a gdk window, not a gtk window.?)

2. GTK only notifies your event box of mouse movements if you say:
gtk_widget_add_events(eventbox, GDK_POINTER_MOTION_MASK)

If there's a alternate/better way to go about this, I'd be happy to hear.

Note that you have to have a readable graphic file named
/home/levin/ex.jpg for this program. If you don't, either edit the
program to reflect a valid name on your system or update to a
distribution that includes a readable jpg file with that name.

Code:
#include <gtk/gtk.h>


/* compile with
gcc lines.c  -Wall -o runme `pkg-config --cflags --libs gtk+-2.0`
*/

static gboolean cross_pointer (GtkWidget      *widget,
                GdkEventMotion *event,
                gpointer        user_data)  ;

int main(int argc, char *argv[]) {

  GError *openError = NULL ;
  GtkWidget *window, *box, *image, *eventbox ;
  GdkPixbuf *bigPicture ;

  gtk_init(&argc, &argv) ;
 
  bigPicture = gdk_pixbuf_new_from_file( "/home/levin/ex.jpg", &openError) ;
  image = gtk_image_new_from_pixbuf( bigPicture ) ;
 
 
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
  g_signal_connect (G_OBJECT (window), "destroy",
          G_CALLBACK (gtk_main_quit), NULL);

  /* put the image in an event box.  The window associated with the
     event box has to enable GDK_POINTER_MOTION_MASK.  For user data,
     send the image so that the cross_pointer function can restore
     from image when mouse moves away
  */
  eventbox = gtk_event_box_new() ;
  g_signal_connect (G_OBJECT (eventbox), "motion_notify_event",
          G_CALLBACK (cross_pointer),  image) ;
  gtk_widget_add_events(eventbox, GDK_POINTER_MOTION_MASK ) ;
   

  gtk_container_add(GTK_CONTAINER ( eventbox ), image ) ;
  box = gtk_vbox_new (FALSE, 5 );
 
  gtk_box_pack_start( GTK_BOX(box), eventbox, FALSE, FALSE, 0);
  gtk_container_add( GTK_CONTAINER (window), box);
 
  gtk_widget_show_all(window) ;
 
  gtk_main() ;
  return 0 ;
}

static gboolean cross_pointer (GtkWidget      *widget,
                GdkEventMotion *event,
                gpointer        image)
{
  static gint h, w, X, Y ;  /* h&w: height & width of event box;
                X,Y mouse pointer coordinates */
  static gboolean initialized = FALSE ;

  if( initialized ) {
    /*
      Line have previouslybeen drawn; X & Y are set.  Redraw from the image IF
      it's not the same as the new line.  Usually, the motion is only
      in the x or y direction, so one of the lines, she is still valid
    */
    if((gint)event->x != X) {
      /* we moved horiz - get rid of old horiz line */
      gtk_widget_queue_draw_area( image, X, 0, 1, h+1) ;

     
    }
    if((gint)event->y != Y ) {
       /* we move vertically - remove the old vertical line */
      gtk_widget_queue_draw_area( image, 0, Y, w+1, 1) ;
    }
  }
  else {
    w = widget->allocation.width-1 ;
    h = widget->allocation.height-1 ;  /* get size of box */
    initialized = TRUE ;
  }
  X = (gint) event->x ;
  Y = (gint) event->y ;  /* where the mouse is */

  /* first draw horiz line */
  gdk_draw_line( GTK_WIDGET (image)->window,
       GTK_WIDGET (image)->style->white_gc,
       0, Y, w, Y ) ;
  /* and then draw vert line */
  gdk_draw_line( GTK_WIDGET (image)->window,
       GTK_WIDGET (image)->style->white_gc,
       X, 0, X, h ) ;
  return TRUE ;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group