[代码实例][gtk+]画布

来源:互联网 发布:淘宝店铺扣24分后果 编辑:程序博客网 时间:2024/06/06 07:02
#include <gtk/gtk.h>/* Surface to store current scribbles */static cairo_surface_t * surface = NULL;static void activate(GtkApplication * app, gpointer user_data);static void close_window(void);static gboolean motion_notify_event_cb (GtkWidget * widget, GdkEventMotion * event, gpointer data);static gboolean button_press_event_cb(GtkWidget * widget, GdkEventButton * event, gpointer data);static void draw_brush(GtkWidget * widget, gdouble x, gdouble y);static gboolean draw_cb(GtkWidget * widget, cairo_t * cr, gpointer data);static gboolean configure_event_cb(GtkWidget *widget, GdkEventConfigure * event, gpointer data);static void clear_surface(void);int main(int argc, char * argv[]){    GtkApplication * app;    int status;    app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);    g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);    status = g_application_run(G_APPLICATION(app), argc, argv);    g_object_unref(app);    return status;}static void activate(GtkApplication * app, gpointer user_data){    GtkWidget * window;    GtkWidget * frame;    GtkWidget * drawing_area;    window = gtk_application_window_new(app);    gtk_window_set_title(GTK_WINDOW (window), "Drawing Area");    g_signal_connect(window, "destroy", G_CALLBACK(close_window), NULL);    gtk_container_set_border_width(GTK_CONTAINER(window), 8);    frame = gtk_frame_new(NULL);    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);    gtk_container_add(GTK_CONTAINER (window), frame);    drawing_area = gtk_drawing_area_new();    /* set a minimum size */    gtk_widget_set_size_request(drawing_area, 100, 100);    gtk_container_add(GTK_CONTAINER(frame), drawing_area);    /* Signals used to handle the backing surface */    g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_cb), NULL);    g_signal_connect(drawing_area, "configure-event", G_CALLBACK(configure_event_cb), NULL);    /* Event signals */    g_signal_connect(drawing_area, "motion-notify-event", G_CALLBACK(motion_notify_event_cb), NULL);    g_signal_connect (drawing_area, "button-press-event", G_CALLBACK(button_press_event_cb), NULL);    /* Ask to receive events the drawing area doesn't normally     * subscribe to. In particular, we need to ask for the     * button press and motion notify events that want to handle.     */    gtk_widget_set_events(drawing_area,        gtk_widget_get_events (drawing_area) | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);    gtk_widget_show_all (window);}static void close_window(void){    if(surface)        cairo_surface_destroy(surface);    gtk_main_quit();}/* Handle motion events by continuing to draw if button 1 is * still held down. The ::motion-notify signal handler receives * a GdkEventMotion struct which contains this information. */static gboolean motion_notify_event_cb (GtkWidget * widget, GdkEventMotion * event, gpointer data){    /* paranoia check, in case we haven't gotten a configure event */    if(surface == NULL)        return FALSE;    if(event->state & GDK_BUTTON1_MASK)        draw_brush(widget, event->x, event->y);    /* We've handled it, stop processing */    return TRUE;}/* Handle button press events by either drawing a rectangle * or clearing the surface, depending on which button was pressed. * The ::button-press signal handler receives a GdkEventButton * struct which contains this information. */static gboolean button_press_event_cb(GtkWidget * widget, GdkEventButton * event, gpointer data){    /* paranoia check, in case we haven't gotten a configure event */    if(surface == NULL)        return FALSE;    if(event->button == GDK_BUTTON_PRIMARY)    {        draw_brush(widget, event->x, event->y);    }    else if(event->button == GDK_BUTTON_SECONDARY)    {        clear_surface();        gtk_widget_queue_draw(widget);    }    /* We've handled the event, stop processing */    return TRUE;}/* Draw a rectangle on the surface at the given position */static void draw_brush(GtkWidget * widget, gdouble x, gdouble y){    cairo_t *cr;    /* Paint to the surface, where we store our state */    cr = cairo_create(surface);    cairo_rectangle(cr, x - 3, y - 3, 6, 6);    cairo_fill(cr);    cairo_destroy(cr);    /* Now invalidate the affected region of the drawing area. */    gtk_widget_queue_draw_area(widget, x - 3, y - 3, 6, 6);}/* Redraw the screen from the surface. Note that the ::draw * signal receives a ready-to-be-used cairo_t that is already * clipped to only draw the exposed areas of the widget */static gboolean draw_cb(GtkWidget * widget, cairo_t * cr, gpointer data){    cairo_set_source_surface(cr, surface, 0, 0);    cairo_paint(cr);  return FALSE;}/* Create a new surface of the appropriate size to store our scribbles */static gboolean configure_event_cb(GtkWidget *widget, GdkEventConfigure * event, gpointer data){    if (surface)        cairo_surface_destroy(surface);    surface = gdk_window_create_similar_surface(        gtk_widget_get_window(widget),        CAIRO_CONTENT_COLOR,        gtk_widget_get_allocated_width(widget),        gtk_widget_get_allocated_height(widget));    /* Initialize the surface to white */    clear_surface ();    /* We've handled the configure event, no need for further processing. */    return TRUE;}static void clear_surface(void){    cairo_t *cr;    cr = cairo_create (surface);    cairo_set_source_rgb (cr, 1, 1, 1);    cairo_paint (cr);    cairo_destroy (cr);}

makefile:

main: main.c    gcc main.c -o main `pkg-config --cflags --libs gtk+-3.0`
0 0
原创粉丝点击