area selection in a pixmap with the mouse



Hi all

Does someone has written some functions (sure of this) to  select a rectangle 
in a pixmap (like a zoom for example) when the left button of the mouse is 
pressed (and draw the area selected in inverse color, or plot a rectangle in 
dot line corresponding to the selected area)?

I have arranged something like the code hereafter, but which does not work 
satisfyingly  : 

..../...

//////////////////////////////////////////////////////////////////////////////
/* selection_event, this callback is registered after a mouse button has been
 * pressed in the drawing area, it erases the ?last? rectangle and draws
 * another to represent the area the user has selected. the callback is
 * unregistered when the user releases the mouse button
 */
void NZE_selection_event(GtkWidget *widget, 
                        GdkEventMotion *event, 
                        gpointer data)
{
  static gint x_left , y_top ;
  static gint x_right , y_bottom ;
  static int first;
  gint x, y;
  GdkGC *gc;

 static GdkPixmap *pixmap ;

 struct NZE * ps;

 ps = (struct NZE *)gtk_object_get_data(GTK_OBJECT(gNZE_Window),"pS_NZE");

  // gc f the current window
  gc = gdk_gc_new(widget->window);

 gdk_gc_set_function(gc,GDK_AND_REVERSE);

  /* create a new pixmap of a size equal to the drawing area */
  pixmap = gdk_pixmap_new(widget->window, 
                             widget->allocation.width,
                             widget->allocation.height,
                             -1);


  x = (gint) event->x;
  y = (gint) event->y;

  x_left   = (Curseur.X_down < x) ? Curseur.X_down : x;
  x_right  = (Curseur.X_down > x) ? Curseur.X_down : x;
  y_top    = (Curseur.Y_down < y) ? Curseur.Y_down : y;
  y_bottom = (Curseur.Y_down > y) ? Curseur.Y_down : y;

  gdk_draw_pixmap(
                pixmap,
                gc,
                widget->window,
                  x_left, 0,
                  x_left, 0,
                  (x_right-x_left) ,
                           widget->allocation.height);



 gdk_draw_rectangle(widget->window,
                   gc,
                   FALSE,
                    x_left, 0,
                    (x_right - x_left),
                   widget->allocation.height);

 gdk_draw_pixmap(widget->window,
                gc,
                  pixmap,
                  x_left, 0,
                  x_left, 0,
                  (x_right-x_left)-1 ,
                  widget->allocation.height);

  gdk_gc_destroy(gc);

}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* release_event, event that occurs when the user releases button on the
 * drawing area
 */
void  NZE_release_event(GtkWidget *widget, 
                        GdkEventButton *event, 
                        gpointer data)
{
  gint x_up, y_up;
  gdouble x1, x2;

  struct NZE *ps;
  ps = (struct NZE *)gtk_object_get_data(GTK_OBJECT(gNZE_Window),"pS_NZE");

  /* remove the selection callback, and this callback */
  gtk_signal_disconnect_by_func(GTK_OBJECT(widget),
                                GTK_SIGNAL_FUNC(NZE_release_event), NULL);
  gtk_signal_disconnect_by_func(GTK_OBJECT(widget),
                                GTK_SIGNAL_FUNC(NZE_selection_event), NULL);


  x_up = (gint)event->x;
  y_up = (gint)event->y;

  /* if the user pressed and released the button nearby, we'll let 'em off */
  if((abs(x_up - Curseur.X_down) < 10) 
   && (abs(y_up - Curseur.Y_down) < 10))
    return;

  // check for zero width or zero height
  if((x_up == Curseur.X_down) || (y_up == Curseur.Y_down))
    return;

// convert pixels in user coord.
 x1 = (Curseur.X_down < x_up) ?
real_x(Curseur.X_down,ps->ideb,ps->ifin,widget->allocation.width ): 
real_x(x_up,Ideb,Ifin,widget->allocation.width);

x2 = (Curseur.X_down > x_up) ? 
real_x(Curseur.X_down,ps->ideb,ps->ifin,widget->allocation.width ): 
real_x(x_up,Ideb,Ifin,widget->allocation.width);

  ps->ideb = x1;
  ps->ifin = x2;
  printf(" xdown:%d y_up:%d\n",Curseur.X_down,x_up);
  printf(" ideb:%d ifin: %d x1%f x2%f\n",ps->ideb,ps->ifin,x1,x2);

 // plot a curve 
  Dessine_NZE(ps->zone, (gpointer) ps);

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* press_event, event that occurs when the user click on the drawing area
 * left button == zoom
 */
void NZE_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
{
  if(event->button > 3) /* mouse with lotsa buttons */
    return;

 /* store the press coordinates */
  Curseur.X_down = (gint)event->x;
  Curseur.Y_down = (gint)event->y;

  /* connect the motion signal so we see a rectangle */
  gtk_signal_connect(GTK_OBJECT(widget), "motion_notify_event",
                     GTK_SIGNAL_FUNC(NZE_selection_event), NULL);

//  gdk_window_set_cursor(widget->window, cursors[event->button]);

  gtk_signal_connect(GTK_OBJECT(widget), "button_release_event",
                               GTK_SIGNAL_FUNC(NZE_release_event), NULL);
}
//////////////////////////////////////////////////////////////////////////////////


.../...




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