Learning_GTK4_tree/gtk/gtkcustomlayout.c

128 lines
4.0 KiB
C
Raw Normal View History

2023-12-12 11:36:42 +01:00
/**
* GtkCustomLayout:
*
* `GtkCustomLayout` uses closures for size negotiation.
*
* A `GtkCustomLayout `uses closures matching to the old `GtkWidget`
* virtual functions for size negotiation, as a convenience API to
* ease the porting towards the corresponding `GtkLayoutManager
* virtual functions.
*/
#include "config.h"
#include "gtkcustomlayout.h"
struct _GtkCustomLayout
{
GtkLayoutManager parent_instance;
GtkCustomRequestModeFunc request_mode_func;
GtkCustomMeasureFunc measure_func;
GtkCustomAllocateFunc allocate_func;
};
G_DEFINE_TYPE (GtkCustomLayout, gtk_custom_layout, GTK_TYPE_LAYOUT_MANAGER)
static GtkSizeRequestMode
gtk_custom_layout_get_request_mode (GtkLayoutManager *manager,
GtkWidget *widget)
{
GtkCustomLayout *self = GTK_CUSTOM_LAYOUT (manager);
if (self->request_mode_func != NULL)
return self->request_mode_func (widget);
return GTK_LAYOUT_MANAGER_CLASS (gtk_custom_layout_parent_class)->get_request_mode (manager, widget);
}
static void
gtk_custom_layout_measure (GtkLayoutManager *manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkCustomLayout *self = GTK_CUSTOM_LAYOUT (manager);
int min = 0, nat = 0;
int min_baseline = -1, nat_baseline = -1;
self->measure_func (widget, orientation, for_size,
&min, &nat,
&min_baseline, &nat_baseline);
if (minimum != NULL)
*minimum = min;
if (natural != NULL)
*natural = nat;
if (minimum_baseline != NULL)
*minimum_baseline = min_baseline;
if (natural_baseline != NULL)
*natural_baseline = nat_baseline;
}
static void
gtk_custom_layout_allocate (GtkLayoutManager *manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkCustomLayout *self = GTK_CUSTOM_LAYOUT (manager);
self->allocate_func (widget, width, height, baseline);
}
static void
gtk_custom_layout_class_init (GtkCustomLayoutClass *klass)
{
GtkLayoutManagerClass *layout_class = GTK_LAYOUT_MANAGER_CLASS (klass);
layout_class->get_request_mode = gtk_custom_layout_get_request_mode;
layout_class->measure = gtk_custom_layout_measure;
layout_class->allocate = gtk_custom_layout_allocate;
}
static void
gtk_custom_layout_init (GtkCustomLayout *self)
{
}
/**
* gtk_custom_layout_new:
* @request_mode: (nullable) (scope call): a function to retrieve
* the `GtkSizeRequestMode` of the widget using the layout; the
* default request mode is %GTK_SIZE_REQUEST_CONSTANT_SIZE
* @measure: (not nullable) (scope call): a function to measure the widget using the layout manager
* @allocate: (not nullable) (scope call): a function to allocate the children of the widget using
* the layout manager
*
* Creates a new legacy layout manager.
*
* Legacy layout managers map to the old `GtkWidget` size negotiation
* virtual functions, and are meant to be used during the transition
* from layout containers to layout manager delegates.
*
* Returns: (transfer full): the newly created `GtkCustomLayout`
*/
GtkLayoutManager *
gtk_custom_layout_new (GtkCustomRequestModeFunc request_mode,
GtkCustomMeasureFunc measure,
GtkCustomAllocateFunc allocate)
{
GtkCustomLayout *self = g_object_new (GTK_TYPE_CUSTOM_LAYOUT, NULL);
g_return_val_if_fail (measure != NULL, NULL);
g_return_val_if_fail (allocate != NULL, NULL);
self->request_mode_func = request_mode;
self->measure_func = measure;
self->allocate_func = allocate;
return GTK_LAYOUT_MANAGER (self);
}