gtkcustomlayout.c 3.96 KB
Newer Older
Emmanuele Bassi's avatar
Emmanuele Bassi committed
1
/**
Matthias Clasen's avatar
Matthias Clasen committed
2
 * GtkCustomLayout:
Emmanuele Bassi's avatar
Emmanuele Bassi committed
3
 *
Matthias Clasen's avatar
Matthias Clasen committed
4
 * `GtkCustomLayout` uses closures for size negotiation.
Emmanuele Bassi's avatar
Emmanuele Bassi committed
5
 *
Matthias Clasen's avatar
Matthias Clasen committed
6 7 8 9
 * 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.
Emmanuele Bassi's avatar
Emmanuele Bassi committed
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
 */

#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);

36
  return GTK_LAYOUT_MANAGER_CLASS (gtk_custom_layout_parent_class)->get_request_mode (manager, widget);
Emmanuele Bassi's avatar
Emmanuele Bassi committed
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
}

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)
{
}

/**
96 97
 * gtk_custom_layout_new:
 * @request_mode: (nullable) (scope call): a function to retrieve
Matthias Clasen's avatar
Matthias Clasen committed
98
 *   the `GtkSizeRequestMode` of the widget using the layout; the
Emmanuele Bassi's avatar
Emmanuele Bassi committed
99
 *   default request mode is %GTK_SIZE_REQUEST_CONSTANT_SIZE
100 101
 * @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
Emmanuele Bassi's avatar
Emmanuele Bassi committed
102 103 104 105
 *   the layout manager
 *
 * Creates a new legacy layout manager.
 *
Matthias Clasen's avatar
Matthias Clasen committed
106
 * Legacy layout managers map to the old `GtkWidget` size negotiation
Emmanuele Bassi's avatar
Emmanuele Bassi committed
107 108 109
 * virtual functions, and are meant to be used during the transition
 * from layout containers to layout manager delegates.
 *
Matthias Clasen's avatar
Matthias Clasen committed
110
 * Returns: (transfer full): the newly created `GtkCustomLayout`
Emmanuele Bassi's avatar
Emmanuele Bassi committed
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
 */
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);
}