LINUX.ORG.RU

История изменений

Исправление Darth_Revan, (текущая версия) :

Если напрягает gtkmm, то вот на C:

#include <gtk/gtk.h>

static gboolean
on_widget_draw (GtkWidget *widget,
                cairo_t   *cr)
{
    GdkWindow       *gdk_surface;
    cairo_t         *cr2;
    cairo_surface_t *surface;
    cairo_region_t  *region;

    const int w = gtk_widget_get_allocated_width (widget);
    const int h = gtk_widget_get_allocated_height (widget);
    const double radius = 30;

    gdk_surface  = gtk_widget_get_window (widget);
    surface = gdk_window_create_similar_surface (gdk_surface,
                                                 CAIRO_CONTENT_COLOR_ALPHA,
                                                 w,
                                                 h);

    cr2 = cairo_create (surface);
    cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);

    cairo_set_source_rgba (cr2, 0.0, 0.0, 0.0, 0.0);
    cairo_paint (cr2);

    cairo_rectangle (cr2, 0, 0, w, h - radius);
    cairo_set_source_rgb (cr2, 1.0, 0.0, 0.0);
    cairo_fill (cr2);

    cairo_arc (cr2, w - radius, h - radius, radius, 0.0,        G_PI * 0.5);
    cairo_arc (cr2, radius,     h - radius, radius, G_PI * 0.5, G_PI);
    cairo_set_source_rgb (cr2, 1.0, 0.0, 0.0);
    cairo_fill (cr2);

    cairo_set_source_rgb (cr2, 0.0, 0.0, 0.0);
    cairo_set_line_width (cr2, 1.0);
    cairo_stroke (cr2);

    if (cr != NULL) {
        cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
        cairo_set_source_surface (cr, surface, 0.0, 0.0);
        cairo_paint (cr);
    }

    region = gdk_cairo_region_create_from_surface (surface);
    gtk_widget_shape_combine_region (widget, region);
    gtk_widget_input_shape_combine_region (widget, region);

    cairo_region_destroy (region);
    cairo_destroy (cr2);
    cairo_surface_destroy (surface);

    return FALSE;
}

static void
on_widget_realize (GtkWidget *widget)
{
    on_widget_draw (widget, NULL);
}

static void
on_application_activate (GtkApplication *application)
{
    GtkWidget *window = gtk_application_window_new (application);

    g_signal_connect (window, "draw",    G_CALLBACK (on_widget_draw),    NULL);
    g_signal_connect (window, "realize", G_CALLBACK (on_widget_realize), NULL);

    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    gtk_widget_set_app_paintable (window, TRUE);
    gtk_window_present (GTK_WINDOW (window));
}

int
main (int   argc,
      char *argv[])
{
    GtkApplication *app = gtk_application_new (NULL, G_APPLICATION_NON_UNIQUE);

    g_signal_connect (app,
                      "activate",
                      G_CALLBACK (on_application_activate),
                      NULL);

    return g_application_run (G_APPLICATION (app), argc, argv);
}

Исходная версия Darth_Revan, :

Если напрягает gtkmm, то вот на C:

#include <gtk/gtk.h>

static gboolean
on_widget_draw (GtkWidget *widget,
                cairo_t   *cr)
{
    GdkWindow       *gdk_surface;
    cairo_t         *cr2;
    cairo_surface_t *surface;
    cairo_region_t  *region;

    const double radius = 30;
    const int w = gtk_widget_get_allocated_width (widget);
    const int h = gtk_widget_get_allocated_height (widget);

    gdk_surface  = gtk_widget_get_window (widget);
    surface = gdk_window_create_similar_surface (gdk_surface,
                                                 CAIRO_CONTENT_COLOR_ALPHA,
                                                 w,
                                                 h);

    cr2 = cairo_create (surface);
    cairo_set_operator (cr2, CAIRO_OPERATOR_SOURCE);

    cairo_set_source_rgba (cr2, 0.0, 0.0, 0.0, 0.0);
    cairo_paint (cr2);

    cairo_rectangle (cr2, 0, 0, w, h - radius);
    cairo_set_source_rgb (cr2, 1.0, 0.0, 0.0);
    cairo_fill (cr2);

    cairo_arc (cr2, w - radius, h - radius, radius, 0.0,        G_PI * 0.5);
    cairo_arc (cr2, radius,     h - radius, radius, G_PI * 0.5, G_PI);
    cairo_set_source_rgb (cr2, 1.0, 0.0, 0.0);
    cairo_fill (cr2);

    cairo_set_source_rgb (cr2, 0.0, 0.0, 0.0);
    cairo_set_line_width (cr2, 1.0);
    cairo_stroke (cr2);

    if (cr != NULL) {
        cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
        cairo_set_source_surface (cr, surface, 0.0, 0.0);
        cairo_paint (cr);
    }

    region = gdk_cairo_region_create_from_surface (surface);
    gtk_widget_shape_combine_region (widget, region);
    gtk_widget_input_shape_combine_region (widget, region);

    cairo_region_destroy (region);
    cairo_destroy (cr2);
    cairo_surface_destroy (surface);

    return FALSE;
}

static void
on_widget_realize (GtkWidget *widget)
{
    on_widget_draw (widget, NULL);
}

static void
on_application_activate (GtkApplication *application)
{
    GtkWidget *window = gtk_application_window_new (application);

    g_signal_connect (window, "draw",    G_CALLBACK (on_widget_draw),    NULL);
    g_signal_connect (window, "realize", G_CALLBACK (on_widget_realize), NULL);

    gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
    gtk_widget_set_app_paintable (window, TRUE);
    gtk_window_present (GTK_WINDOW (window));
}

int
main (int   argc,
      char *argv[])
{
    int ret;
    GtkApplication *app = gtk_application_new (NULL, G_APPLICATION_NON_UNIQUE);
    g_signal_connect (app,
                      "activate",
                      G_CALLBACK (on_application_activate),
                      NULL);

    ret = g_application_run (G_APPLICATION (app), argc, argv);
    g_object_unref (app);

    return ret;
}