1/*
2 * Copyright © 2019 Zander Brown
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19#include <glib/gi18n-lib.h>
20
21#include "type-info.h"
22
23#include "gtkpopover.h"
24
25struct _GtkInspectorTypePopover
26{
27 GtkPopover parent_instance;
28};
29
30typedef struct _GtkInspectorTypePopoverPrivate GtkInspectorTypePopoverPrivate;
31
32struct _GtkInspectorTypePopoverPrivate
33{
34 GType type;
35
36 GtkWidget *parents;
37 GtkWidget *interfaces;
38};
39
40enum
41{
42 PROP_0,
43 PROP_TYPE
44};
45
46G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorTypePopover, gtk_inspector_type_popover,
47 GTK_TYPE_POPOVER)
48
49static void
50add_row (GtkWidget *box,
51 const char *name)
52{
53 GtkWidget *row;
54 GtkWidget *label;
55
56 row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
57 first_property_name: "selectable", FALSE,
58 "activatable", FALSE,
59 NULL);
60
61 label = g_object_new (GTK_TYPE_LABEL,
62 first_property_name: "margin-start", 6,
63 "margin-end", 6,
64 "margin-top", 6,
65 "margin-bottom", 6,
66 "label", name,
67 "selectable", TRUE,
68 "xalign", 0.0,
69 NULL);
70
71 gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), child: label);
72 gtk_list_box_insert (GTK_LIST_BOX (box), child: row, position: -1);
73}
74
75void
76gtk_inspector_type_popover_set_gtype (GtkInspectorTypePopover *self,
77 GType gtype)
78{
79 GtkInspectorTypePopoverPrivate *priv;
80 GHashTable *implements;
81 GHashTableIter iter;
82 const char *name;
83 GType *interfaces;
84 GType tmp;
85 int i;
86 GtkWidget *child;
87
88 g_return_if_fail (GTK_IS_INSPECTOR_TYPE_POPOVER (self));
89
90 priv = gtk_inspector_type_popover_get_instance_private (self);
91
92 if (priv->type == gtype)
93 return;
94
95 priv->type = gtype;
96
97 while ((child = gtk_widget_get_first_child (widget: priv->parents)))
98 gtk_list_box_remove (GTK_LIST_BOX (priv->parents), child);
99 while ((child = gtk_widget_get_first_child (widget: priv->interfaces)))
100 gtk_list_box_remove (GTK_LIST_BOX (priv->interfaces), child);
101
102 implements = g_hash_table_new (hash_func: g_str_hash, key_equal_func: g_str_equal);
103
104 tmp = gtype;
105
106 do
107 {
108 add_row (box: priv->parents, name: g_type_name (type: tmp));
109
110 interfaces = g_type_interfaces (type: tmp, NULL);
111
112 for (i = 0; interfaces[i]; i++)
113 g_hash_table_add (hash_table: implements, key: (char *) g_type_name (type: interfaces[i]));
114
115 g_free (mem: interfaces);
116 }
117 while ((tmp = g_type_parent (type: tmp)));
118
119 g_hash_table_iter_init (iter: &iter, hash_table: implements);
120
121 while (g_hash_table_iter_next (iter: &iter, key: (gpointer *) &name, NULL))
122 add_row (box: priv->interfaces, name);
123
124 g_hash_table_unref (hash_table: implements);
125}
126
127static void
128gtk_inspector_type_popover_init (GtkInspectorTypePopover *self)
129{
130 GtkInspectorTypePopoverPrivate *priv;
131 GtkWidget *label;
132
133 gtk_widget_init_template (GTK_WIDGET (self));
134
135 priv = gtk_inspector_type_popover_get_instance_private (self);
136
137 priv->type = G_TYPE_NONE;
138
139 label = g_object_new (GTK_TYPE_LABEL,
140 first_property_name: "margin-start", 12,
141 "margin-end", 12,
142 "margin-top", 12,
143 "margin-bottom", 12,
144 "label", "None",
145 NULL);
146
147 gtk_list_box_set_placeholder (GTK_LIST_BOX (priv->parents), placeholder: label);
148
149 label = g_object_new (GTK_TYPE_LABEL,
150 first_property_name: "margin-start", 12,
151 "margin-end", 12,
152 "margin-top", 12,
153 "margin-bottom", 12,
154 "label", "None",
155 NULL);
156
157 gtk_list_box_set_placeholder (GTK_LIST_BOX (priv->interfaces), placeholder: label);
158}
159
160static void
161gtk_inspector_type_popover_get_property (GObject *object,
162 guint param_id,
163 GValue *value,
164 GParamSpec *pspec)
165{
166 GtkInspectorTypePopover *self = GTK_INSPECTOR_TYPE_POPOVER (ptr: object);
167 GtkInspectorTypePopoverPrivate *priv = gtk_inspector_type_popover_get_instance_private (self);
168
169 switch (param_id)
170 {
171 case PROP_TYPE:
172 g_value_set_gtype (value, v_gtype: priv->type);
173 break;
174
175 default:
176 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
177 break;
178 }
179}
180
181static void
182gtk_inspector_type_popover_set_property (GObject *object,
183 guint param_id,
184 const GValue *value,
185 GParamSpec *pspec)
186{
187 GtkInspectorTypePopover *self = GTK_INSPECTOR_TYPE_POPOVER (ptr: object);
188
189 switch (param_id)
190 {
191 case PROP_TYPE:
192 gtk_inspector_type_popover_set_gtype (self, gtype: g_value_get_gtype (value));
193 break;
194
195 default:
196 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
197 break;
198 }
199}
200
201static void
202gtk_inspector_type_popover_class_init (GtkInspectorTypePopoverClass *klass)
203{
204 GObjectClass *object_class = G_OBJECT_CLASS (klass);
205 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
206
207 object_class->get_property = gtk_inspector_type_popover_get_property;
208 object_class->set_property = gtk_inspector_type_popover_set_property;
209
210 g_object_class_install_property (oclass: object_class, property_id: PROP_TYPE,
211 pspec: g_param_spec_gtype (name: "type", nick: "Type", blurb: "Type",
212 G_TYPE_NONE, flags: G_PARAM_READWRITE));
213
214 gtk_widget_class_set_template_from_resource (widget_class, resource_name: "/org/gtk/libgtk/inspector/type-info.ui");
215 gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorTypePopover, parents);
216 gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorTypePopover, interfaces);
217}
218

source code of gtk/gtk/inspector/type-info.c