GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sat Aug 27, 2016 10:14 pm

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 
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.


 Post subject: An answer
PostPosted: Wed Dec 05, 2007 3:31 am 
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.

#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 ;

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: Yahoo [Bot] and 1 guest

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:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group