Sun, 19 Oct 2025 21:20:08 +0200
update toolkit
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2017 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include "graphics.h" #include "container.h" #include "../common/object.h" #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 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); #if GTK_CHECK_VERSION(4, 0, 0) 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); #else int w = args->width > 0 ? args->width : 100; int h = args->height > 0 ? args->height : 100; gtk_widget_set_size_request(widget, w, h); #endif UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; 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; } #if GTK_MAJOR_VERSION <= 3 static gboolean widget_button_pressed( GtkWidget *widget, GdkEvent *event, gpointer userdata) { UiEventData *eventdata = userdata; UiMouseEvent me; me.x = (int)event->button.x; me.y = (int)event->button.y; int exec = 0; if(event->button.type == GDK_BUTTON_PRESS) { exec = 1; me.type = UI_PRESS; } else if(event->button.type == GDK_2BUTTON_PRESS) { exec = 1; me.type = UI_PRESS2; } if(exec) { UiEvent e; e.obj = eventdata->obj; e.window = eventdata->obj->window; e.document = eventdata->obj->ctx->document; e.eventdata = &me; e.intval = 0; eventdata->callback(&e, eventdata->userdata); } return TRUE; } #endif void ui_drawingarea_getsize(UIWIDGET drawingarea, int *width, int *height) { #if GTK_MAJOR_VERSION >= 4 *width = gtk_widget_get_width(drawingarea); *height = gtk_widget_get_height(drawingarea); #elif GTK_MAJOR_VERSION == 3 *width = gtk_widget_get_allocated_width(drawingarea); *height = gtk_widget_get_allocated_height(drawingarea); #else *width = drawingarea->allocation.width; *height = drawingarea->allocation.height; #endif } void ui_drawingarea_redraw(UIWIDGET drawingarea) { gtk_widget_queue_draw(drawingarea); } void ui_drawingarea_mousehandler(UiObject *obj, UIWIDGET widget, ui_callback f, void *u) { #if GTK_MAJOR_VERSION >= 4 // TODO #else gtk_widget_set_events(widget, GDK_BUTTON_PRESS_MASK); if(f) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; event->callback = f; event->userdata = u; event->customdata = NULL; event->value = 0; g_signal_connect(G_OBJECT(widget), "button-press-event", G_CALLBACK(widget_button_pressed), event); } else { // TODO: warning } #endif } // text layout UiTextLayout* ui_text(UiGraphics *g) { UiTextLayout *layout = malloc(sizeof(UiTextLayout)); PangoContext *pc = ui_get_pango_context(g); layout->layout = pango_layout_new(pc); return layout; } void ui_text_setstring(UiTextLayout *layout, char *str) { pango_layout_set_text(layout->layout, str, -1); } void ui_text_setstringl(UiTextLayout *layout, char *str, int len) { pango_layout_set_text(layout->layout, str, len); } 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); pango_layout_set_font_description(layout->layout, fontDesc); pango_font_description_free(fontDesc); } void ui_text_getsize(UiTextLayout *layout, int *width, int *height) { pango_layout_get_size(layout->layout, width, height); *width = *width / PANGO_SCALE; *height = *height / PANGO_SCALE; } void ui_text_setwidth(UiTextLayout *layout, int width) { pango_layout_set_width(layout->layout, width * PANGO_SCALE); pango_layout_set_ellipsize(layout->layout, PANGO_ELLIPSIZE_END); //pango_layout_set_wrap(layout->layout, PANGO_WRAP_WORD_CHAR); } void ui_text_free(UiTextLayout *text) { g_object_unref(text->layout); free(text); }