1/*
2 * Copyright (c) 2020 Red Hat, Inc.
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 "list-data.h"
22
23#include "gtkcolumnview.h"
24#include "gtktogglebutton.h"
25#include "gtklabel.h"
26#include "gtkstack.h"
27#include "gtkboxlayout.h"
28#include "gtkorientable.h"
29#include "gtknoselection.h"
30#include "gtksignallistitemfactory.h"
31#include "gtklistitem.h"
32#include "window.h"
33
34
35struct _GtkInspectorListData
36{
37 GtkWidget parent_instance;
38
39 GListModel *object;
40 GtkColumnView *view;
41 GtkWidget *items_label;
42};
43
44struct _GtkInspectorListDataClass
45{
46 GtkWidgetClass parent_class;
47};
48
49G_DEFINE_TYPE (GtkInspectorListData, gtk_inspector_list_data, GTK_TYPE_WIDGET)
50
51static void
52gtk_inspector_list_data_init (GtkInspectorListData *sl)
53{
54 gtk_widget_init_template (GTK_WIDGET (sl));
55
56 gtk_orientable_set_orientation (GTK_ORIENTABLE (gtk_widget_get_layout_manager (GTK_WIDGET (sl))),
57 orientation: GTK_ORIENTATION_VERTICAL);
58}
59
60void
61gtk_inspector_list_data_set_object (GtkInspectorListData *sl,
62 GObject *object)
63{
64 GtkWidget *stack;
65 GtkStackPage *page;
66 char *text;
67 GtkNoSelection *selection;
68
69 stack = gtk_widget_get_parent (GTK_WIDGET (sl));
70 page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
71
72 gtk_column_view_set_model (self: sl->view, NULL);
73 sl->object = NULL;
74
75 if (!G_IS_LIST_MODEL (ptr: object))
76 {
77 g_object_set (object: page, first_property_name: "visible", FALSE, NULL);
78 return;
79 }
80
81 text = g_strdup_printf (format: "%u items", g_list_model_get_n_items (list: G_LIST_MODEL (ptr: object)));
82 gtk_label_set_label (GTK_LABEL (sl->items_label), str: text);
83 g_free (mem: text);
84
85 g_object_set (object: page, first_property_name: "visible", TRUE, NULL);
86
87 sl->object = G_LIST_MODEL (ptr: object);
88 selection = gtk_no_selection_new (g_object_ref (sl->object));
89 gtk_column_view_set_model (self: sl->view, model: GTK_SELECTION_MODEL (ptr: selection));
90 g_object_unref (object: selection);
91}
92
93static void
94setup_object (GtkSignalListItemFactory *factory,
95 GtkListItem *item)
96{
97 GtkWidget *label;
98
99 label = gtk_label_new (str: "");
100 gtk_label_set_xalign (GTK_LABEL (label), xalign: 0);
101 gtk_widget_add_css_class (widget: label, css_class: "cell");
102 gtk_list_item_set_child (self: item, child: label);
103}
104
105static void
106bind_object (GtkSignalListItemFactory *factory,
107 GtkListItem *item)
108{
109 GtkWidget *label;
110 gpointer obj;
111 char *text;
112
113 label = gtk_list_item_get_child (self: item);
114 obj = gtk_list_item_get_item (self: item);
115
116 text = g_strdup_printf (format: "%p", obj);
117 gtk_label_set_label (GTK_LABEL (label), str: text);
118 g_free (mem: text);
119}
120
121static void
122setup_type (GtkSignalListItemFactory *factory,
123 GtkListItem *item)
124{
125 GtkWidget *label;
126
127 label = gtk_label_new (str: "");
128 gtk_label_set_xalign (GTK_LABEL (label), xalign: 0);
129 gtk_widget_add_css_class (widget: label, css_class: "cell");
130 gtk_list_item_set_child (self: item, child: label);
131}
132
133static void
134bind_type (GtkSignalListItemFactory *factory,
135 GtkListItem *item)
136{
137 GtkWidget *label;
138 gpointer obj;
139
140 label = gtk_list_item_get_child (self: item);
141 obj = gtk_list_item_get_item (self: item);
142
143 gtk_label_set_label (GTK_LABEL (label), G_OBJECT_TYPE_NAME (obj));
144}
145
146static void
147setup_props (GtkSignalListItemFactory *factory,
148 GtkListItem *item)
149{
150 GtkWidget *button;
151
152 button = gtk_button_new_with_label (label: "Properties");
153 gtk_widget_add_css_class (widget: button, css_class: "cell");
154 gtk_widget_set_halign (widget: button, align: GTK_ALIGN_START);
155 gtk_list_item_set_child (self: item, child: button);
156}
157
158static void
159object_properties (GtkWidget *button,
160 GtkListItem *item)
161{
162 GtkInspectorWindow *iw;
163 GObject *obj;
164 guint pos;
165
166 iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_ancestor (button, GTK_TYPE_INSPECTOR_WINDOW));
167
168 obj = gtk_list_item_get_item (self: item);
169 pos = gtk_list_item_get_position (self: item);
170 gtk_inspector_window_push_object (iw, object: obj, kind: CHILD_KIND_LISTITEM, position: pos);
171}
172
173static void
174bind_props (GtkSignalListItemFactory *factory,
175 GtkListItem *item,
176 GtkInspectorListData *sl)
177{
178 g_signal_connect (gtk_list_item_get_child (item), "clicked",
179 G_CALLBACK (object_properties), item);
180}
181
182static void
183unbind_props (GtkSignalListItemFactory *factory,
184 GtkListItem *item)
185{
186 g_signal_handlers_disconnect_by_func (gtk_list_item_get_child (item), object_properties, item);
187}
188
189static void
190dispose (GObject *object)
191{
192 GtkInspectorListData *sl = GTK_INSPECTOR_LIST_DATA (ptr: object);
193 GtkWidget *child;
194
195 while ((child = gtk_widget_get_first_child (GTK_WIDGET (sl))))
196 gtk_widget_unparent (widget: child);
197
198 G_OBJECT_CLASS (gtk_inspector_list_data_parent_class)->dispose (object);
199}
200
201static void
202gtk_inspector_list_data_class_init (GtkInspectorListDataClass *klass)
203{
204 GObjectClass *object_class = G_OBJECT_CLASS (klass);
205 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
206
207 object_class->dispose = dispose;
208
209 gtk_widget_class_set_template_from_resource (widget_class, resource_name: "/org/gtk/libgtk/inspector/list-data.ui");
210 gtk_widget_class_bind_template_child (widget_class, GtkInspectorListData, view);
211 gtk_widget_class_bind_template_child (widget_class, GtkInspectorListData, items_label);
212
213 gtk_widget_class_bind_template_callback (widget_class, setup_object);
214 gtk_widget_class_bind_template_callback (widget_class, bind_object);
215 gtk_widget_class_bind_template_callback (widget_class, setup_type);
216 gtk_widget_class_bind_template_callback (widget_class, bind_type);
217 gtk_widget_class_bind_template_callback (widget_class, setup_props);
218 gtk_widget_class_bind_template_callback (widget_class, bind_props);
219 gtk_widget_class_bind_template_callback (widget_class, unbind_props);
220
221 gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
222}
223
224// vim: set et sw=2 ts=2:
225

source code of gtk/gtk/inspector/list-data.c