Do you know how to create a custom widget in GTK 3? I tried a subclass of GtkDrawingArea in C for hours. Gnome.org provides only a brief guide to the subclass of G_OBJECT. My problem is that G_Object / GTK cannot see my custom StrokerNodalContainer as a subclass of GtkWidget when casting using GTK_WIDGET , even my hard definition of struct contains the following line:
GtkDrawingArea parent_instance;
It says:
invalid cast from 'StrokerNodalContainer' to 'GtkWidget'
Here is the complete code if you suspect that something else might be wrong. This is minimal, so I see no reason why the external code is being violated.
Stroker-nodalcontainer.h
#ifndef __STROKER_NODALCONTAINER_H__ #define __STROKER_NODALCONTAINER_H__ #ifndef NO_INCLUDE_WITHIN_HEADERS #include <gtk/gtk.h> #endif #define STROKER_TYPE_NODAL_CONTAINER (stroker_nodal_container_get_type ()) #define STROKER_NODAL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainer)) #define STROKER_NODAL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainerClass)) #define STROKER_IS_NODAL_CONTAINER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STROKER_TYPE_NODAL_CONTAINER)) #define STROKER_IS_NODAL_CONTAINER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STROKER_TYPE_NODAL_CONTAINER)) #define STROKER_NODAL_CONTAINER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STROKER_TYPE_NODAL_CONTAINER, StrokerNodalContainerClass)) typedef struct _StrokerNodalContainer StrokerNodalContainer; typedef struct _StrokerNodalContainerClass StrokerNodalContainerClass; struct _StrokerNodalContainer { GtkDrawingArea parent_instance; }; struct _StrokerNodalContainerClass { GtkDrawingAreaClass parent_class; }; GType stroker_nodal_container_get_type(void); //StrokerNodalContainer* stroker_nodalcontainer_new(void); #endif /* __STROKER_NODALCONTAINER_H__ */
Stroker-nodalcontainer.c
#include <gtk/gtk.h> #include "stroker-nodalcontainer.h" G_DEFINE_TYPE( StrokerNodalContainer, stroker_nodal_container, G_TYPE_OBJECT ) static void stroker_nodal_container_class_init( StrokerNodalContainerClass* klass ) {} static void stroker_nodal_container_init( StrokerNodalContainer* self ) { GdkRGBA c; GtkWidget *widget; gdk_rgba_parse(&c, "blue"); widget = GTK_WIDGET(self); gtk_widget_override_background_color( widget, GTK_STATE_FLAG_NORMAL, &c ); }
main.c
#include <stdlib.h> #include <stdio.h> #include <gtk/gtk.h> #include <cairo/cairo.h> #include "stroker-nodalcontainer.h" int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *nodalWidget; gtk_init( &argc, &argv ); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Stroker"); g_signal_connect( window, "destroy", G_CALLBACK (gtk_main_quit), NULL ); gtk_container_set_border_width( GTK_CONTAINER(window), 10 ); gtk_widget_show (window); nodalWidget = g_object_new(STROKER_TYPE_NODAL_CONTAINER,NULL); gtk_container_add( GTK_CONTAINER(window), nodalWidget ); gtk_widget_show (nodalWidget); gtk_main(); return EXIT_SUCCESS; }
Thanks for the help!