summaryrefslogtreecommitdiff
path: root/gtk/gtkcustomlayout.c
blob: 32d2c37a9e354ad13e2fa79837164effae43e7a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * SECTION:gtkcustomlayout
 * @Title: GtkCustomLayout
 * @Short_description: A convenience layout manager
 *
 * #GtkCustomLayout is a convenience type meant to be used as a transition
 * mechanism between #GtkWidgets implementing a layout policy, and
 * #GtkLayoutManager classes.
 *
 * 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);
}