add new drawingarea (GTK)

Tue, 14 Oct 2025 12:48:55 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 14 Oct 2025 12:48:55 +0200
changeset 848
5a4b72489111
parent 847
50de0f36973f
child 849
63623ef950e5

add new drawingarea (GTK)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/draw_cairo.c file | annotate | diff | comparison | revisions
ui/gtk/draw_cairo.h file | annotate | diff | comparison | revisions
ui/gtk/graphics.c file | annotate | diff | comparison | revisions
ui/gtk/graphics.h file | annotate | diff | comparison | revisions
ui/ui/graphics.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Tue Oct 14 10:41:21 2025 +0200
+++ b/application/main.c	Tue Oct 14 12:48:55 2025 +0200
@@ -584,6 +584,13 @@
     return FALSE;
 }
 
+static void draw(UiEvent *event, UiGraphics *g, void *userdata) {
+    ui_draw_line(g, 0, 0, g->width, g->height);
+    ui_draw_line(g, g->width, 0, 0, g->height);
+    
+    ui_draw_rect(g, (g->width/2)-80, (g->height/2)-40, 160, 80, FALSE);
+}
+
 void application_startup(UiEvent *event, void *data) {
     // global list
     UiContext *global = ui_global_context();
@@ -789,6 +796,9 @@
                 }
             }
         }
+        ui_tab(obj, "Tab 12") {
+            ui_drawingarea(obj, .fill = TRUE, .draw = draw);
+        }
     }
     
     /*
--- a/ui/gtk/draw_cairo.c	Tue Oct 14 10:41:21 2025 +0200
+++ b/ui/gtk/draw_cairo.c	Tue Oct 14 12:48:55 2025 +0200
@@ -35,29 +35,29 @@
 
 
 #if GTK_MAJOR_VERSION >= 3
-static void ui_drawingarea_draw(
-        GtkDrawingArea *area,
-        cairo_t *cr,
-        int width,
-        int height,
-        gpointer data)
-{
+void ui_drawingarea_draw(UiDrawingArea *drawingarea, cairo_t *cr, int width, int height) {
     UiCairoGraphics g;
     g.g.width = width;
     g.g.height = height;
-    g.widget = GTK_WIDGET(area);
+    g.widget = drawingarea->widget;;
     g.cr = cr;
     
-    UiDrawEvent *event = data;
-    UiEvent ev;
-    ev.obj = event->obj;
-    ev.window = event->obj->window;
-    ev.document = event->obj->ctx->document;
+    UiEvent event;
+    event.obj = drawingarea->obj;
+    event.window = event.obj->window;
+    event.document = event.obj->ctx->document;
+    event.eventdata = NULL;
+    event.eventdatatype = 0;
+    event.intval = 0;
+    event.set = 0;
     
-    event->callback(&ev, &g.g, event->userdata);
+    if(drawingarea->draw) {
+        drawingarea->draw(&event, &g.g, drawingarea->drawdata);
+    }
 }
 #endif
 
+/*
 #if UI_GTK3
 gboolean ui_drawingarea_expose(GtkWidget *w, cairo_t *cr, void *data) {
     int width = gtk_widget_get_allocated_width(w);
@@ -85,9 +85,11 @@
     return FALSE;
 }
 #endif
+*/
 
 // function from graphics.h
 
+/*
 void ui_connect_draw_handler(GtkWidget *widget, UiDrawEvent *event) {
 #if GTK_MAJOR_VERSION >= 4
     gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(widget), ui_drawingarea_draw, event, NULL);
@@ -103,7 +105,7 @@
             event);
 #endif
 }
-
+*/
 
 PangoContext *ui_get_pango_context(UiGraphics *g) {
     UiCairoGraphics *gr = (UiCairoGraphics*)g;
@@ -130,7 +132,7 @@
     cairo_stroke(gr->cr);
 }
 
-void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, int fill) {
+void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, UiBool fill) {
     UiCairoGraphics *gr = (UiCairoGraphics*)g;
     cairo_set_line_width(gr->cr, 1);
     cairo_rectangle(gr->cr, x + 0.5, y + 0.5 , w, h);
--- a/ui/gtk/draw_cairo.h	Tue Oct 14 10:41:21 2025 +0200
+++ b/ui/gtk/draw_cairo.h	Tue Oct 14 12:48:55 2025 +0200
@@ -41,7 +41,7 @@
     cairo_t    *cr;
 } UiCairoGraphics;
 
-// ui_canvas_expose
+void ui_drawingarea_draw(UiDrawingArea *drawingarea, cairo_t *cr, int width, int height);
 
 #ifdef	__cplusplus
 }
--- a/ui/gtk/graphics.c	Tue Oct 14 10:41:21 2025 +0200
+++ b/ui/gtk/graphics.c	Tue Oct 14 12:48:55 2025 +0200
@@ -33,22 +33,83 @@
 #include "container.h"
 #include "../common/object.h"
 
-UIWIDGET ui_drawingarea(UiObject *obj, ui_drawfunc f, void *userdata) {
-    GtkWidget *widget = gtk_drawing_area_new();
+#if GTK_CHECK_VERSION(3, 0, 0)
+#include "draw_cairo.h"
+#endif
+
+static void destroy_drawingarea(GtkWidget *widget, UiDrawingArea *drawingarea) {
+    free(drawingarea);
+}
+
+static void drawingarea_draw(UiDrawingArea *drawingarea, cairo_t *cr, int width, int height) {
+    UiEvent event;
+    event.obj = drawingarea->obj;
+    event.window = event.obj->window;
+    event.document = event.obj->ctx->document;
+    event.eventdata = NULL;
+    event.eventdatatype = 0;
+    event.intval = 0;
+    event.set = 0;
+    
     
-    if(f) {
-        UiDrawEvent *event = malloc(sizeof(UiDrawEvent));
-        event->obj = obj;
-        event->callback = f;
-        event->userdata = userdata;
-        ui_connect_draw_handler(widget, event);
-    }
+}
+
+#if GTK_CHECK_VERSION(4, 0, 0)
+static void drawfunc(
+        GtkDrawingArea *area,
+        cairo_t *cr,
+        int width,
+        int  height,
+        gpointer userdata)
+{
+    ui_drawingarea_draw(userdata, cr, width, height);
+}
+#elif GTK_CHECK_VERSION(3, 0, 0)
+gboolean draw_callback(GtkWidget *widget, cairo_t *cr, UiDrawingArea *drawingarea) {
+    int width = gtk_widget_get_allocated_width(widget);
+    int height = gtk_widget_get_allocated_height(widget);
+    ui_drawingarea_draw(drawingarea, cr, width, height);
+    return FALSE;
+}
+#endif
+
+UIWIDGET ui_drawingarea_create(UiObject *obj, UiDrawingAreaArgs *args) {
+    GtkWidget *widget = gtk_drawing_area_new();
+    ui_set_name_and_style(widget, args->name, args->style_class);
+    
+    gtk_drawing_area_set_content_width(GTK_DRAWING_AREA(widget), args->width > 0 ? args->width : 100);
+    gtk_drawing_area_set_content_height(GTK_DRAWING_AREA(widget), args->height > 0 ? args->height : 100);
     
     UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
-    //UiLayout layout = UI_ARGS2LAYOUT(args);
-    UiLayout layout = {0};
+    UiLayout layout = UI_ARGS2LAYOUT(args);
     ct->add(ct, widget, &layout);
     
+    UiDrawingArea *drawingarea = malloc(sizeof(UiDrawingArea));
+    drawingarea->obj = obj;
+    drawingarea->widget = widget;
+    drawingarea->draw = args->draw;
+    drawingarea->drawdata = args->drawdata;
+    drawingarea->onclick = args->onclick;
+    drawingarea->onclickdata = args->onclickdata;
+    drawingarea->onmotion = args->onmotion;
+    drawingarea->onmotiondata = args->onmotiondata;
+    
+#if GTK_CHECK_VERSION(4, 0, 0)
+    gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(widget), drawfunc, drawingarea, NULL);
+#elif GTK_CHECK_VERSION(3, 0, 0)
+    g_signal_connect(
+            widget,
+            "draw",
+            G_CALLBACK(draw_callback),
+            NULL);
+#endif
+    
+    g_signal_connect(
+                widget,
+                "destroy",
+                G_CALLBACK(destroy_drawingarea),
+                drawingarea);
+    
     return widget;
 }
 
@@ -144,7 +205,7 @@
     pango_layout_set_text(layout->layout, str, len);
 }
 
-void ui_text_setfont(UiTextLayout *layout, char *font, int size) {
+void ui_text_setfont(UiTextLayout *layout, const char *font, int size) {
     PangoFontDescription *fontDesc;
     fontDesc = pango_font_description_from_string(font);
     pango_font_description_set_size(fontDesc, size * PANGO_SCALE);
--- a/ui/gtk/graphics.h	Tue Oct 14 10:41:21 2025 +0200
+++ b/ui/gtk/graphics.h	Tue Oct 14 12:48:55 2025 +0200
@@ -36,18 +36,24 @@
 extern "C" {
 #endif
 
-typedef struct UiDrawEvent {
-    ui_drawfunc callback;
-    UiObject    *obj;
-    void        *userdata;
-} UiDrawEvent;
+
+typedef struct UiDrawingArea {
+    UiObject *obj;
+    GtkWidget *widget;
+    ui_drawfunc draw;
+    void *drawdata;
+    ui_callback onclick;
+    void *onclickdata;
+    ui_callback onmotion;
+    void *onmotiondata;
+} UiDrawingArea;
 
 struct UiTextLayout {
     PangoLayout *layout;
 };
 
 // implemented in draw_*.h
-void ui_connect_draw_handler(GtkWidget *widget, UiDrawEvent *event);
+//void ui_connect_draw_handler(GtkWidget *widget, UiDrawEvent *event);
 PangoContext *ui_get_pango_context(UiGraphics *g);
 
 #ifdef	__cplusplus
--- a/ui/ui/graphics.h	Tue Oct 14 10:41:21 2025 +0200
+++ b/ui/ui/graphics.h	Tue Oct 14 12:48:55 2025 +0200
@@ -45,25 +45,53 @@
     int height;
 };
 
-UIWIDGET ui_drawingarea(UiObject *obj, ui_drawfunc f, void *userdata);
-void ui_drawingarea_mousehandler(UiObject *obj, UIWIDGET widget, ui_callback f, void *u);
-void ui_drawingarea_getsize(UIWIDGET drawingarea, int *width, int *height);
-void ui_drawingarea_redraw(UIWIDGET drawingarea);
+typedef struct UiDrawingAreaArgs {
+    UiBool fill;
+    UiBool hexpand;
+    UiBool vexpand;
+    UiBool hfill;
+    UiBool vfill;
+    UiBool override_defaults;
+    int margin;
+    int margin_left;
+    int margin_right;
+    int margin_top;
+    int margin_bottom;
+    int colspan;
+    int rowspan;
+    const char *name;
+    const char *style_class;
+    
+    int width;
+    int height;
+    ui_drawfunc draw;
+    void *drawdata;
+    ui_callback onclick;
+    void *onclickdata;
+    ui_callback onmotion;
+    void *onmotiondata;
+} UiDrawingAreaArgs;
+
+#define ui_drawingarea(obj, ...) ui_drawingarea_create(obj, &(UiDrawingAreaArgs) { __VA_ARGS__ } )
+
+UIEXPORT UIWIDGET ui_drawingarea_create(UiObject *obj, UiDrawingAreaArgs *args);
+UIEXPORT void ui_drawingarea_getsize(UIWIDGET drawingarea, int *width, int *height);
+UIEXPORT void ui_drawingarea_redraw(UIWIDGET drawingarea);
 
 // text layout
-UiTextLayout* ui_text(UiGraphics *g);
-void ui_text_free(UiTextLayout *text);
-void ui_text_setstring(UiTextLayout *layout, char *str);
-void ui_text_setstringl(UiTextLayout *layout, char *str, int len);
-void ui_text_setfont(UiTextLayout *layout, char *font, int size);
-void ui_text_getsize(UiTextLayout *layout, int *width, int *height);
-void ui_text_setwidth(UiTextLayout *layout, int width);
+UIEXPORT UiTextLayout* ui_text(UiGraphics *g);
+UIEXPORT void ui_text_free(UiTextLayout *text);
+UIEXPORT void ui_text_setstring(UiTextLayout *layout, char *str);
+UIEXPORT void ui_text_setstringl(UiTextLayout *layout, char *str, int len);
+UIEXPORT void ui_text_setfont(UiTextLayout *layout, const char *font, int size);
+UIEXPORT void ui_text_getsize(UiTextLayout *layout, int *width, int *height);
+UIEXPORT void ui_text_setwidth(UiTextLayout *layout, int width);
 
 // drawing functions
-void ui_graphics_color(UiGraphics *g, int red, int green, int blue);
-void ui_draw_line(UiGraphics *g, int x1, int y1, int x2, int y2);
-void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, int fill);
-void ui_draw_text(UiGraphics *g, int x, int y, UiTextLayout *text);
+UIEXPORT void ui_graphics_color(UiGraphics *g, int red, int green, int blue);
+UIEXPORT void ui_draw_line(UiGraphics *g, int x1, int y1, int x2, int y2);
+UIEXPORT void ui_draw_rect(UiGraphics *g, int x, int y, int w, int h, UiBool fill);
+UIEXPORT void ui_draw_text(UiGraphics *g, int x, int y, UiTextLayout *text);
 
 #ifdef	__cplusplus
 }

mercurial