While trying out the possibilities of the GtkLayoutManager, I tried to use the “create_layout_child” function. According to the documentation, you should create your own instance of GtkLayoutManager for this purpose. “Create_layout_child” should then be overwritten as a virtual function. It will then be called automatically. Accordingly, I’ve created a derived class from GtkLayoutManager. It’s all working now too, but the “create_layout_child” function isn’t called, so I can’t use it. Does anyone have an idea or hint on how to implement this feature?
My layout manager looks like this.
#include"layout_mywidget.h"
struct _LayoutMywidget
{
GtkLayoutManager parent_instance;
};
struct _LayoutMywidgetClass
{
GtkLayoutManagerClass parent_class;
};
G_DEFINE_TYPE (LayoutMywidget, layout_mywidget, GTK_TYPE_LAYOUT_MANAGER)
static GtkLayoutChild *
layout_mywidget_create_layout_child (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkWidget *child)
{
//Function is not called. Why?
g_print("layout_child\n");
}
/* Container */
static void layout_mywidget_measure (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
/* Already set in widget.ui */
};
/*Position of the children*/
static void layout_mywidget_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkRequisition label_req;
GtkRequisition entry_req;
GtkRequisition button_req;
GtkWidget *child;
for(child = gtk_widget_get_first_child(widget);
child != NULL;
child = gtk_widget_get_next_sibling (child))
{
if(strcmp(gtk_widget_get_name(child),"GtkEntry") == 0)
{
gtk_widget_get_preferred_size(child, &entry_req,NULL);
gtk_widget_size_allocate(child,
&(const GtkAllocation){10,60,200,entry_req.height},-1);
}
else if (strcmp(gtk_widget_get_name(child),"GtkLabel") == 0)
{
gtk_widget_get_preferred_size(child, &label_req,NULL);
gtk_widget_size_allocate(child,
&(const GtkAllocation){width/2-(label_req.width/2),20,
label_req.width,label_req.height},-1);
}
else if (strcmp(gtk_widget_get_name(child),"GtkButton") == 0)
{
gtk_widget_get_preferred_size(child, &button_req,NULL);
gtk_widget_size_allocate(child,
&(const GtkAllocation){220,60,button_req.width,
button_req.height},-1);
}
}
};
/* The default implementation of this virtual function, which means that the widget
* will only ever get -1 passed as the for_size value to its Gtk.WidgetClass.measure
* implementation. You can overwrite that */
static GtkSizeRequestMode
layout_mywidget_get_request_mode (GtkLayoutManager *layout_manager,
GtkWidget *widget)
{
return GTK_SIZE_REQUEST_CONSTANT_SIZE;
};
static void layout_mywidget_class_init (LayoutMywidgetClass *class)
{
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (class);
layout_class->get_request_mode = layout_mywidget_get_request_mode;
layout_class->measure = layout_mywidget_measure;
layout_class->allocate = layout_mywidget_allocate;
//Function is not called. Why ?
layout_class->create_layout_child = layout_mywidget_create_layout_child;
};
static void layout_mywidget_init(LayoutMywidget *self)
{
};
GtkLayoutManager *layout_mywidget_new(void)
{
return g_object_new(LAYOUT_TYPE_MYWIDGET,NULL);
};