GTK 图像的多层显示以及拖动矩形的重画

来源:互联网 发布:网络出版的商业价值 编辑:程序博客网 时间:2024/05/21 22:32

   我需要在一张图像中选择一个区域,并在鼠标的拖动中不断重画,按理来说,用gtk_draw_focus()画了聚集矩形之后,只要在原来的地方重画一次,是可以将上次的擦除的,但不知怎么就是擦不干净,于是用了另外一种方法,添加一个gtk_event_box,将将背景设为透明,画框框都在它里面完成,这样在需要擦除时,只要重画event_box的一部分矩形即可,而并不影响下面的图像。

#include <gtk/gtk.h>

GtkWidget *eventbox;
gboolean bleftdown = FALSE;

gint xdown = 0;
gint ydown = 0;
gint oldx =0;
gint oldy = 0;


void Sort(gint *a, gint *b)
{
    int c;

    if(*a > *b)
    {
    c  = *a; *a = *b; *b = c;
    }
}

void RrawRect(GtkWidget* widget,unsigned long R,
                           unsigned long G, unsigned long B,gint x1, gint y1, gint x2, gint y2)
{
    GdkGC *gc;
    GdkColormap *cmap;
    GdkColor color;

    Sort(&x1, &x2);
    Sort(&y1, &y2);

    cmap = gdk_colormap_get_system();
    gc   = gdk_gc_new(widget->window);

    color.red=R;// 0x00;
    color.green = G;// 0xFFFF;
    color.blue = B;//0x0;

    if (gdk_color_alloc(cmap, &color) == 0)
    {
         g_error("can't allocate color/n");
    }
    gdk_gc_set_rgb_fg_color(gc, &color);
    gdk_draw_rectangle(widget->window,gc,FALSE,x1, y1, x2-x1, y2-y1);
    gdk_gc_destroy(gc);
}

void    Redraw(gint x1, gint y1, gint x2, gint y2)
{
  GdkRectangle rect;

   Sort(&x1, &x2);
   Sort(&y1, &y2);

  rect.x = x1;
  rect.y = y1;
  rect.width = x2- x1+1;
  rect.height =y2 -y1+1;
  gtk_widget_draw(eventbox, &rect);
}

gboolean    button_release_event_callback(GtkWidget  *widget,
                                           GdkEventButton *event,gpointer    user_data)
{
      if(event->button == 1 ) // left button
      {
            if (bleftdown && event->type == GDK_BUTTON_RELEASE)
            {
                    bleftdown =  FALSE;
                    RrawRect(eventbox, 0x0000, 0x0000, 0xFFFF, xdown, ydown,event->x , event->y);
           }
      }

      return FALSE;
}

gboolean    button_press_event_callback  (GtkWidget    *widget,
                                            GdkEventButton *event, gpointer    user_data)
{
    printf("button press/n");
    if(event->button == 1 ) // left button
    {
        if (event->type == GDK_BUTTON_PRESS)
        {
            Redraw(xdown, ydown, oldx, oldy);
            bleftdown =  TRUE;
            xdown = event->x;
            ydown = event->y;
        }
   }

    return FALSE;
}

gboolean    motion_notify_event_callback(GtkWidget      *widget,
                                            GdkEventMotion *event, gpointer     user_data)
{
   // GtkStyle*  style;

    if (bleftdown)
    {
      //style = gtk_style_new();

      Redraw(xdown, ydown, oldx, oldy);
     //gtk_draw_focus(style, eventbox->window, xdown, ydown,oldwidth, oldheight);
      RrawRect(eventbox, 0x0000, 0xFFFF, 0x0000, xdown, ydown,event->x , event->y);

      oldx = event->x;
      oldy = event->y;
    }

    return FALSE;
}


gint close_application( GtkWidget *widget,
                        GdkEvent  *event,
                        gpointer   data )
{
    gtk_main_quit();
    return(FALSE);
}

int main (int argc, char *argv[])
{
 GtkWidget *win;
 GtkWidget *fixed;
 GtkWidget *image;
 GdkPixbuf *pixbuf;
 GdkPixbuf *pixbuf2;

  /* Initialize GTK+ */
  gtk_init (&argc, &argv);

  /* Create the main window */
  win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_container_set_border_width (GTK_CONTAINER (win), 8);
  gtk_widget_set_usize(win, 500, 400);
  gtk_window_set_title (GTK_WINDOW (win), "Drawing Rectangle on Image");
  gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
  gtk_widget_realize (win);

   eventbox = gtk_event_box_new ();
   gtk_container_add (GTK_CONTAINER (win), eventbox );
   gtk_widget_set_usize(eventbox, gdk_pixbuf_get_width(pixbuf)*2, gdk_pixbuf_get_height(pixbuf));
   /*  设置鼠标 */
   gdk_window_set_cursor(eventbox->window,  gdk_cursor_new( GDK_CROSS));

   fixed = gtk_fixed_new ();
   gtk_container_add (GTK_CONTAINER (eventbox), fixed );

    pixbuf = gdk_pixbuf_new_from_file ("/bg.jpg", NULL);
    image = gtk_image_new_from_pixbuf (pixbuf);
    gtk_fixed_put (GTK_FIXED (fixed), image, 0, 0);

    pixbuf2 = gdk_pixbuf_new_from_file ("/fruit.jpg", NULL);
    image = gtk_image_new_from_pixbuf (pixbuf2);
    /*  叠加在原来的地方  */
    gtk_fixed_put (GTK_FIXED (fixed), image, 10, 10);


    g_signal_connect (G_OBJECT (win), "delete_event",
                      G_CALLBACK (close_application), NULL);

    gtk_widget_add_events (eventbox, GDK_POINTER_MOTION_MASK
             | GDK_BUTTON_PRESS_MASK
             | GDK_BUTTON_RELEASE_MASK
             );

  g_signal_connect (eventbox, "button-press-event", G_CALLBACK(button_press_event_callback), NULL);
  g_signal_connect (eventbox , "button-release-event", G_CALLBACK(button_release_event_callback), NULL);
  g_signal_connect (eventbox , "motion_notify_event", G_CALLBACK(motion_notify_event_callback), NULL);

  gtk_widget_show_all(win);
  gtk_main ();

  return 0;
}