1 /*
2  * Copyright (C) 2020 Purism SPC
3  *
4  * SPDX-License-Identifier: LGPL-2.1+
5  *
6  * Based on
7  * glade-gtk-header-bar.c - GladeWidgetAdaptor for GtkHeaderBar
8  */
9 
10 #include <config.h>
11 #include <glib/gi18n-lib.h>
12 
13 #include "glade-hdy-flap.h"
14 
15 #include <gladeui/glade.h>
16 #include "glade-hdy-utils.h"
17 
18 static void
selection_changed_cb(GladeProject * project,GladeWidget * gwidget)19 selection_changed_cb (GladeProject *project,
20                       GladeWidget  *gwidget)
21 {
22   GList *list;
23   GtkWidget *sel_widget;
24   GtkContainer *container = GTK_CONTAINER (glade_widget_get_object (gwidget));
25 
26   if ((list = glade_project_selection_get (project)) != NULL &&
27       g_list_length (list) == 1) {
28     sel_widget = list->data;
29 
30     if (GTK_IS_WIDGET (sel_widget) &&
31         gtk_widget_is_ancestor (sel_widget, GTK_WIDGET (container))) {
32       GtkWidget *content = hdy_flap_get_content (HDY_FLAP (container));
33       GtkWidget *flap = hdy_flap_get_flap (HDY_FLAP (container));
34       GtkWidget *separator = hdy_flap_get_separator (HDY_FLAP (container));
35       gboolean folded = hdy_flap_get_folded (HDY_FLAP (container));
36 
37       if (folded &&
38           (sel_widget == content ||
39            gtk_widget_is_ancestor (sel_widget, content)))
40         hdy_flap_set_reveal_flap (HDY_FLAP (container), FALSE);
41 
42       if ((sel_widget == flap ||
43            gtk_widget_is_ancestor (sel_widget, flap)))
44         hdy_flap_set_reveal_flap (HDY_FLAP (container), TRUE);
45 
46       if ((sel_widget == separator ||
47            gtk_widget_is_ancestor (sel_widget, separator)))
48         hdy_flap_set_reveal_flap (HDY_FLAP (container), TRUE);
49     }
50   }
51 }
52 
53 static void
project_changed_cb(GladeWidget * gwidget,GParamSpec * pspec,gpointer userdata)54 project_changed_cb (GladeWidget *gwidget,
55                     GParamSpec  *pspec,
56                     gpointer     userdata)
57 {
58   GladeProject *project = glade_widget_get_project (gwidget);
59   GladeProject *old_project = g_object_get_data (G_OBJECT (gwidget),
60                                                  "project-ptr");
61 
62   if (old_project)
63     g_signal_handlers_disconnect_by_func (G_OBJECT (old_project),
64                                           G_CALLBACK (selection_changed_cb),
65                                           gwidget);
66 
67   if (project)
68     g_signal_connect (G_OBJECT (project),
69                       "selection-changed",
70                       G_CALLBACK (selection_changed_cb),
71                       gwidget);
72 
73   g_object_set_data (G_OBJECT (gwidget), "project-ptr", project);
74 }
75 
76 void
glade_hdy_flap_post_create(GladeWidgetAdaptor * adaptor,GObject * container,GladeCreateReason reason)77 glade_hdy_flap_post_create (GladeWidgetAdaptor *adaptor,
78                             GObject            *container,
79                             GladeCreateReason   reason)
80 {
81   GladeWidget *gwidget = glade_widget_get_from_gobject (container);
82   GtkWidget *child;
83   GtkWidget *content;
84 
85   if (!hdy_flap_get_flap (HDY_FLAP (container))) {
86     child = glade_placeholder_new ();
87     g_object_set_data (G_OBJECT (child), "special-child-type", "flap");
88     hdy_flap_set_flap (HDY_FLAP (container), child);
89   }
90 
91   if (!hdy_flap_get_separator (HDY_FLAP (container))) {
92     child = glade_placeholder_new ();
93     g_object_set_data (G_OBJECT (child), "special-child-type", "separator");
94     hdy_flap_set_separator (HDY_FLAP (container), child);
95   }
96 
97   content = hdy_flap_get_content (HDY_FLAP (container));
98   if (!content) {
99     child = glade_placeholder_new ();
100     g_object_set_data (G_OBJECT (child), "special-child-type", "content");
101     hdy_flap_set_content (HDY_FLAP (container), child);
102   } else {
103     g_object_set_data (G_OBJECT (content), "special-child-type", "content");
104   }
105 
106   g_signal_connect (G_OBJECT (gwidget),
107                     "notify::project",
108                     G_CALLBACK (project_changed_cb),
109                     NULL);
110 
111   project_changed_cb (gwidget, NULL, NULL);
112 }
113 
114 void
glade_hdy_flap_add_child(GladeWidgetAdaptor * adaptor,GObject * parent,GObject * child)115 glade_hdy_flap_add_child (GladeWidgetAdaptor *adaptor,
116                           GObject            *parent,
117                           GObject            *child)
118 {
119   gchar *special_child_type = g_object_get_data (child, "special-child-type");
120 
121   if (special_child_type && !strcmp (special_child_type, "flap")) {
122     hdy_flap_set_flap (HDY_FLAP (parent), GTK_WIDGET (child));
123 
124     return;
125   }
126 
127   if (special_child_type && !strcmp (special_child_type, "separator")) {
128     hdy_flap_set_separator (HDY_FLAP (parent), GTK_WIDGET (child));
129 
130     return;
131   }
132 
133   hdy_flap_set_content (HDY_FLAP (parent), GTK_WIDGET (child));
134 }
135 
136 void
glade_hdy_flap_remove_child(GladeWidgetAdaptor * adaptor,GObject * object,GObject * child)137 glade_hdy_flap_remove_child (GladeWidgetAdaptor *adaptor,
138                              GObject            *object,
139                              GObject            *child)
140 {
141   gchar *special_child_type = g_object_get_data (child, "special-child-type");
142   GtkWidget *replacement = glade_placeholder_new ();
143 
144   if (special_child_type && !strcmp (special_child_type, "flap")) {
145     g_object_set_data (G_OBJECT (replacement), "special-child-type", "flap");
146     hdy_flap_set_flap (HDY_FLAP (object), replacement);
147 
148     return;
149   }
150 
151   if (special_child_type && !strcmp (special_child_type, "separator")) {
152     g_object_set_data (G_OBJECT (replacement), "special-child-type", "separator");
153     hdy_flap_set_separator (HDY_FLAP (object), replacement);
154 
155     return;
156   }
157 
158   g_object_set_data (G_OBJECT (replacement), "special-child-type", "content");
159   hdy_flap_set_content (HDY_FLAP (object), replacement);
160 }
161 
162 void
glade_hdy_flap_replace_child(GladeWidgetAdaptor * adaptor,GObject * container,GObject * current,GObject * new_widget)163 glade_hdy_flap_replace_child (GladeWidgetAdaptor *adaptor,
164                               GObject            *container,
165                               GObject            *current,
166                               GObject            *new_widget)
167 {
168   gchar *special_child_type =
169     g_object_get_data (G_OBJECT (current), "special-child-type");
170 
171   if (special_child_type && !strcmp (special_child_type, "flap")) {
172     g_object_set_data (G_OBJECT (new_widget), "special-child-type", "flap");
173     hdy_flap_set_flap (HDY_FLAP (container), GTK_WIDGET (new_widget));
174 
175     return;
176   }
177 
178   if (special_child_type && !strcmp (special_child_type, "separator")) {
179     g_object_set_data (G_OBJECT (new_widget), "special-child-type", "separator");
180     hdy_flap_set_separator (HDY_FLAP (container), GTK_WIDGET (new_widget));
181 
182     return;
183   }
184 
185   g_object_set_data (G_OBJECT (new_widget), "special-child-type", "content");
186   hdy_flap_set_content (HDY_FLAP (container), GTK_WIDGET (new_widget));
187 }
188