Hi all,
i use gtk+-3.62 on a debian system and currently i'm playing around with the new GtkOverlay widget, especially to stack a partly transparent drawing area above a widget. Given that i stacked a drawingarea within the overlay container on top of a button and everything works as described in the reference.
Now i would like to go a step further. My plan is to propagate gdk events down to the stacked widgets, so that they respond with the correlated signals and execute the usual visual action (like the one if a button is clicked).
My first approach for testing purpose was to connect the 'button-press-event" of the topmost widget in the overlay-container to a handler that simply returns 'FALSE' to propagate the event further (like described in the docs). Unfortunately this approach don't propagate the events down to the bottommost widget.
To visualize the described behavior i appended a little program. My aim related to this program is, that if i click on the 'Edit' button (see the picture below), the button should respond with the usual visual behavior and the "clicked" handler should also be called.
I would be very thankful if anybody can help me to achieve my objective.
With best regards and thanks for your help
Attachment:
Selection_001.png [ 2.7 KiB | Viewed 255 times ]
Code:
#include <gtk/gtk.h>
#include <glib.h>
typedef struct _ui {
GtkWidget *window;
GtkWidget *overlay;
GtkWidget *button;
GtkWidget *event_box;
GtkWidget *box;
GtkWidget *drawing_area;
} Ui;
void window_destroy_cb(GtkWidget *object, gpointer data) {
gtk_main_quit();
}
gboolean event_box_button_press_event_cb(GtkWidget *widget,
GdkEventButton *event,
gpointer data) {
g_printf("DrawingArea/EventBox: clicked\n");
return FALSE;
}
void button_clicked_cb(GtkWidget *widget, gpointer data) {
g_printf("Button: clicked\n");
}
gboolean drawing_area_draw_cb(GtkWidget *widget, cairo_t *cr,
gpointer data) {
guint width, height;
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
cairo_set_source_rgba(cr, 1, 0, 0, 0.2);
cairo_paint(cr);
cairo_set_source_rgba(cr, 0, 0, 0, 1);
cairo_set_line_width(cr, 3);
cairo_move_to(cr, 0, 0);
cairo_line_to(cr, width, 0);
cairo_rel_line_to(cr, 0, height);
cairo_rel_line_to(cr, -width, 0);
cairo_rel_line_to(cr, 0, -height);
cairo_stroke(cr);
}
void init_widgets(Ui *ui) {
ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_wmclass(GTK_WINDOW(ui->window),
"MyGtkTraining",
"MyGtkTraining");
gtk_container_set_border_width(GTK_CONTAINER(ui->window), 10);
gtk_window_resize(GTK_WINDOW(ui->window), 450, 250);
ui->overlay = gtk_overlay_new();
ui->button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
ui->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
ui->drawing_area = gtk_drawing_area_new();
ui->event_box = gtk_event_box_new();
}
void connect_signals(Ui *ui) {
g_signal_connect(ui->window,
"destroy",
G_CALLBACK(window_destroy_cb),
NULL);
g_signal_connect(ui->drawing_area,
"draw",
G_CALLBACK(drawing_area_draw_cb),
NULL);
g_signal_connect(ui->event_box,
"button-press-event",
G_CALLBACK(event_box_button_press_event_cb),
NULL);
g_signal_connect(ui->button,
"clicked",
G_CALLBACK(button_clicked_cb),
NULL);
}
int main(int argc, char *argv[]) {
Ui ui;
GdkRGBA transparent = {0, 0, 0, 0};
gtk_init(&argc, &argv);
init_widgets(&ui);
g_object_set(ui.button,
"halign", GTK_ALIGN_CENTER,
"valign", GTK_ALIGN_CENTER,
"expand", TRUE,
NULL);
gtk_container_add(GTK_CONTAINER(ui.box), ui.button);
gtk_container_add(GTK_CONTAINER(ui.overlay), ui.box);
gtk_container_add(GTK_CONTAINER(ui.window), ui.overlay);
gtk_container_add(GTK_CONTAINER(ui.event_box), ui.drawing_area);
gtk_widget_override_background_color (ui.overlay, 0, &transparent);
gtk_widget_override_background_color (ui.event_box, 0, &transparent);
gtk_overlay_add_overlay(GTK_OVERLAY(ui.overlay), ui.event_box);
connect_signals(&ui);
gtk_widget_show_all(ui.window);
gtk_main();
return 0;
}