Доброго всем дня!
Есть маленькая программка с одним окошком, на котором есть тулбар с двумя кнопками, Drawing Area и статусбар. Нужно, чтобы при нажатии на кнопку тулбара "Refresh", на Drawing Area при помощи Cairo рисовалась простейшая геометрическая фигура (в данном случае, квадрат) и фон заливался другим цветом. Реализовал рисование через expose_event, все компилируется без ошибок, но нифига не рисует. Долго пытался понять, в чем дело и в итоге обнаружил, что expose_event не посылается виджету Drawing Area ни во время первого старта приложения, ни принудительно при нажатии на кнопку "Refresh" (посредством gdk_window_process_all_updates). Т.е. даже если написать в expose_event gtk_main_quit(), ничего не происходит.
Если кто разбирается в Cairo и может помочь, буду безмерно благодарен! Код приведен ниже, если чего, прошу не пинать ногами и не посылать учить матчасть, программирую под линуксом неделю.
Код компилется вот так: gcc pe.c -o pe `pkg-config --cflags --libs gtk+-3.0`
Собственно, сабж:
#include <gtk/gtk.h>
#include <cairo.h>
static void destroy (GtkWidget *window, gpointer data)
{
gtk_main_quit ();
}
static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
cairo_t *cr;
cr = gdk_cairo_create (gtk_widget_get_parent_window(widget));
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_set_line_width (cr, 2);
cairo_rectangle (cr, 50, 50, 50, 50);
cairo_stroke_preserve (cr);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_fill (cr);
cairo_destroy (cr);
return FALSE;
}
static void force_expose_event (GtkWidget *widget, gpointer data)
{
gdk_window_process_all_updates ();
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
GtkWidget *window, *table, *toolbar, *drawing_area, *statusbar;
GtkToolItem *btn_refresh, *btn_quit;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Cairo Test");
gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
table = gtk_table_new (8, 8, FALSE);
gtk_container_add (GTK_CONTAINER (window), table);
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE);
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH);
btn_refresh = gtk_tool_button_new_from_stock (GTK_STOCK_REFRESH);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), btn_refresh, 0);
g_signal_connect (G_OBJECT (btn_refresh), "clicked", G_CALLBACK (force_expose_event), NULL);
btn_quit = gtk_tool_button_new_from_stock (GTK_STOCK_QUIT);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), btn_quit, 1);
g_signal_connect (G_OBJECT (btn_quit), "clicked", G_CALLBACK (gtk_main_quit), NULL);
gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (toolbar), 0, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (GTK_WIDGET (drawing_area), 800, 480);
GdkColor white;
gdk_color_parse ("white", &white);
gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &white);
gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (drawing_area), 0, 3, 2, 3, GTK_FILL, GTK_FILL, 10, 10);
g_signal_connect (G_OBJECT (drawing_area), "expose_event", G_CALLBACK (on_expose_event), NULL);
statusbar = gtk_statusbar_new ();
gtk_table_attach(GTK_TABLE (table), GTK_WIDGET (statusbar), 0, 3, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
ps
По поводу матчасти - если у кого есть хорошие мануалы по Cairo и(или) рисованию при помощи средств GTK+, дайте пожалуйста ссылочку!