Add GtkBinLayout

Like GtkBin, but lets you lay out multiple children instead of just one.
This commit is contained in:
Emmanuele Bassi 2019-03-04 15:03:34 +00:00
parent 8cf06befc0
commit d6dfa41f10
4 changed files with 139 additions and 0 deletions

View File

@ -45,6 +45,7 @@
#include <gtk/gtkaspectframe.h>
#include <gtk/gtkassistant.h>
#include <gtk/gtkbin.h>
#include <gtk/gtkbinlayout.h>
#include <gtk/gtkbindings.h>
#include <gtk/gtkborder.h>
#include <gtk/gtkboxlayout.h>

115
gtk/gtkbinlayout.c Normal file
View File

@ -0,0 +1,115 @@
/* gtkbinlayout.c: Layout manager for bin-like widgets
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL 2.1+
*/
/**
* SECTION:gtkbinlayout
* @Title: GtkBinLayout
* @Short_description: A layout manager for bin-like widgets
* @Include: gtk/gtk.h
*
* GtkBinLayout is a #GtkLayoutManager subclass useful for create "bins" of
* widgets. GtkBinLayout will stack each child of a widget on top of each
* other, using the #GtkWidget:hexpand, #GtkWidget:vexpand, #GtkWidget:halign,
* and #GtkWidget:valign properties of each child to determine where they
* should be positioned.
*/
#include "config.h"
#include "gtkbinlayout.h"
#include "gtkwidgetprivate.h"
struct _GtkBinLayout
{
GtkLayoutManager parent_instance;
};
G_DEFINE_TYPE (GtkBinLayout, gtk_bin_layout, GTK_TYPE_LAYOUT_MANAGER)
static void
gtk_bin_layout_measure (GtkLayoutManager *layout_manager,
GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkWidget *child;
child = _gtk_widget_get_first_child (widget);
while (child != NULL)
{
GtkWidget *next = _gtk_widget_get_next_sibling (child);
if (gtk_widget_get_visible (child))
{
int child_min = 0;
int child_nat = 0;
gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
*minimum = MAX (*minimum, child_min);
*natural = MAX (*natural, child_nat);
}
child = next;
}
}
static void
gtk_bin_layout_allocate (GtkLayoutManager *layout_manager,
GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkWidget *child;
child = _gtk_widget_get_first_child (widget);
while (child != NULL)
{
GtkWidget *next = _gtk_widget_get_next_sibling (child);
if (child && gtk_widget_get_visible (child))
gtk_widget_size_allocate (child,
&(GtkAllocation) {
0, 0,
width, height
}, baseline);
child = next;
}
}
static void
gtk_bin_layout_class_init (GtkBinLayoutClass *klass)
{
GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass);
layout_manager_class->measure = gtk_bin_layout_measure;
layout_manager_class->allocate = gtk_bin_layout_allocate;
}
static void
gtk_bin_layout_init (GtkBinLayout *self)
{
}
/**
* gtk_bin_layout_new:
*
* Creates a new #GtkBinLayout instance.
*
* Returns: the newly created #GtkBinLayout
*/
GtkLayoutManager *
gtk_bin_layout_new (void)
{
return g_object_new (GTK_TYPE_BIN_LAYOUT, NULL);
}

21
gtk/gtkbinlayout.h Normal file
View File

@ -0,0 +1,21 @@
/* gtkbinlayout.h: Layout manager for bin-like widgets
*
* Copyright 2019 GNOME Foundation
*
* SPDX-License-Identifier: LGPL 2.1+
*/
#pragma once
#include <gtk/gtklayoutmanager.h>
G_BEGIN_DECLS
#define GTK_TYPE_BIN_LAYOUT (gtk_bin_layout_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkBinLayout, gtk_bin_layout, GTK, BIN_LAYOUT, GtkLayoutManager)
GDK_AVAILABLE_IN_ALL
GtkLayoutManager * gtk_bin_layout_new (void);
G_END_DECLS

View File

@ -164,6 +164,7 @@ gtk_public_sources = files([
'gtkaspectframe.c',
'gtkassistant.c',
'gtkbin.c',
'gtkbinlayout.c',
'gtkbindings.c',
'gtkborder.c',
'gtkboxlayout.c',
@ -420,6 +421,7 @@ gtk_public_headers = files([
'gtkaspectframe.h',
'gtkassistant.h',
'gtkbin.h',
'gtkbinlayout.h',
'gtkbindings.h',
'gtkborder.h',
'gtkbox.h',