天天看點

GTK 圖像的多層顯示以及拖動矩形的重畫

   我需要在一張圖像中選擇一個區域,并在滑鼠的拖動中不斷重畫,按理來說,用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;

  gtk_init (&argc, &argv);

  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;

}

繼續閱讀