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
|
/* Copyright 2014 Endless Mobile, Inc. */
#include "config.h"
#include "eoscustomcontainer.h"
#include <gtk/gtk.h>
/**
* SECTION:custom-container
* @short_description: For gjs container implementations
* @title: Custom Container
*
* This container allows for implementing a custom size allocate routine in
* gjs. This container implements the bare minimum of virtual functions from
* GtkContainer, add, remove and forall. Add and remove simply append to and
* remove from an internal list, and forall iterates over that list. Forall
* cannot be implemented in gjs, it's not supported by gobject-introspection,
* so this is needed for custom gjs containers. This class will not
* size_allocate any children or ever queue_resize, so that is up to
* subclasses in gjs.
*
* Here's an example gjs program which allocates a GtkFrame the top right
* quarter of it's allocation.
* |[
* const TestContainer = Lang.Class({
* Name: 'TestContainer',
* Extends: Endless.CustomContainer,
*
* _init: function() {
* this.parent();
*
* this._frame = new Gtk.Frame();
* this.add(this._frame);
* },
*
* vfunc_size_allocate: function (alloc) {
* this.parent(alloc);
* alloc.width = alloc.width / 2;
* alloc.height = alloc.height / 2;
* this._frame.size_allocate(alloc);
* }
* });
* ]|
*/
typedef struct {
GList *children;
} EosCustomContainerPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (EosCustomContainer, eos_custom_container, GTK_TYPE_CONTAINER)
static void
eos_custom_container_add (GtkContainer *container,
GtkWidget *child)
{
EosCustomContainer *self = EOS_CUSTOM_CONTAINER (container);
EosCustomContainerPrivate *priv = eos_custom_container_get_instance_private (self);
priv->children = g_list_prepend (priv->children, child);
gtk_widget_set_parent (child, GTK_WIDGET (container));
}
static void
eos_custom_container_remove (GtkContainer *container,
GtkWidget *child)
{
EosCustomContainer *self = EOS_CUSTOM_CONTAINER (container);
EosCustomContainerPrivate *priv = eos_custom_container_get_instance_private (self);
priv->children = g_list_remove (priv->children, child);
gtk_widget_unparent (child);
}
static void
eos_custom_container_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
EosCustomContainer *self = EOS_CUSTOM_CONTAINER (container);
EosCustomContainerPrivate *priv = eos_custom_container_get_instance_private (self);
g_list_foreach (priv->children, (GFunc)callback, callback_data);
}
static void
eos_custom_container_class_init (EosCustomContainerClass *klass)
{
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
container_class->add = eos_custom_container_add;
container_class->remove = eos_custom_container_remove;
container_class->forall = eos_custom_container_forall;
}
static void
eos_custom_container_init (EosCustomContainer *self)
{
GtkWidget *widget = GTK_WIDGET (self);
gtk_widget_set_has_window (widget, FALSE);
}
/**
* eos_custom_container_new:
*
* Creates a new custom container.
*
* Returns: the custom container.
*/
GtkWidget *
eos_custom_container_new (void)
{
return g_object_new (EOS_TYPE_CUSTOM_CONTAINER, NULL);
}
|