1 /**
2  * Copyright (c) 2004-2007 Michael Terry
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 
19 #include "xpad-pad-group.h"
20 #include "xpad-pad.h"
21 
22 G_DEFINE_TYPE(XpadPadGroup, xpad_pad_group, G_TYPE_OBJECT)
23 
24 #define XPAD_PAD_GROUP_GET_PRIVATE(object)  (G_TYPE_INSTANCE_GET_PRIVATE ((object), XPAD_TYPE_PAD_GROUP, XpadPadGroupPrivate))
25 
26 struct XpadPadGroupPrivate
27 {
28 	GSList *pads;
29 };
30 
31 static void     xpad_pad_group_dispose           (GObject *object);
32 
33 static void     xpad_pad_group_destroy_pads      (XpadPadGroup *group);
34 
35 enum {
36 	PROP_0
37 };
38 
39 enum
40 {
41 	PAD_ADDED,
42 	PAD_REMOVED,
43 	LAST_SIGNAL
44 };
45 
46 static guint signals[LAST_SIGNAL] = { 0 };
47 
48 XpadPadGroup *
xpad_pad_group_new(void)49 xpad_pad_group_new (void)
50 {
51 	return XPAD_PAD_GROUP (g_object_new (XPAD_TYPE_PAD_GROUP, NULL));
52 }
53 
54 static void
xpad_pad_group_class_init(XpadPadGroupClass * klass)55 xpad_pad_group_class_init (XpadPadGroupClass *klass)
56 {
57 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
58 
59 	object_class->dispose = xpad_pad_group_dispose;
60 
61 	signals[PAD_ADDED] =
62 		g_signal_new ("pad_added",
63 		              G_OBJECT_CLASS_TYPE (object_class),
64 		              G_SIGNAL_RUN_FIRST,
65 		              G_STRUCT_OFFSET (XpadPadGroupClass, pad_added),
66 		              NULL, NULL,
67 		              g_cclosure_marshal_VOID__OBJECT,
68 		              G_TYPE_NONE,
69 		              1,
70 		              GTK_TYPE_WIDGET);
71 
72 	signals[PAD_REMOVED] =
73 		g_signal_new ("pad_removed",
74 		              G_OBJECT_CLASS_TYPE (object_class),
75 		              G_SIGNAL_RUN_FIRST,
76 		              G_STRUCT_OFFSET (XpadPadGroupClass, pad_added),
77 		              NULL, NULL,
78 		              g_cclosure_marshal_VOID__OBJECT,
79 		              G_TYPE_NONE,
80 		              1,
81 		              GTK_TYPE_WIDGET);
82 
83 	g_type_class_add_private (object_class, sizeof (XpadPadGroupPrivate));
84 }
85 
86 static void
xpad_pad_group_dispose(GObject * object)87 xpad_pad_group_dispose (GObject *object)
88 {
89 	XpadPadGroup *group = XPAD_PAD_GROUP (object);
90 
91 	xpad_pad_group_destroy_pads (group);
92 }
93 
94 static void
xpad_pad_group_init(XpadPadGroup * group)95 xpad_pad_group_init (XpadPadGroup *group)
96 {
97 	group->priv = XPAD_PAD_GROUP_GET_PRIVATE (group);
98 
99 	group->priv->pads = NULL;
100 }
101 
102 
103 GSList *
xpad_pad_group_get_pads(XpadPadGroup * group)104 xpad_pad_group_get_pads (XpadPadGroup *group)
105 {
106 	return g_slist_copy (group->priv->pads);
107 }
108 
109 
110 /* Subsumes a pad into this group */
111 void
xpad_pad_group_add(XpadPadGroup * group,GtkWidget * pad)112 xpad_pad_group_add (XpadPadGroup *group, GtkWidget *pad)
113 {
114 	g_object_ref(pad);
115 	g_object_ref_sink(GTK_OBJECT(pad));
116 
117 	group->priv->pads = g_slist_append (group->priv->pads, XPAD_PAD (pad));
118 	g_signal_connect_swapped (pad, "destroy", G_CALLBACK (xpad_pad_group_remove), group);
119 
120 	g_signal_emit (group, signals[PAD_ADDED], 0, pad);
121 }
122 
123 
124 /* Removes a pad from this group */
125 void
xpad_pad_group_remove(XpadPadGroup * group,GtkWidget * pad)126 xpad_pad_group_remove (XpadPadGroup *group, GtkWidget *pad)
127 {
128 	group->priv->pads = g_slist_remove (group->priv->pads, XPAD_PAD (pad));
129 
130 	g_signal_emit (group, signals[PAD_REMOVED], 0, pad);
131 
132 	g_object_unref(pad);
133 }
134 
135 
136 /* Deletes all the current pads in the group */
137 static void
xpad_pad_group_destroy_pads(XpadPadGroup * group)138 xpad_pad_group_destroy_pads (XpadPadGroup *group)
139 {
140 	g_slist_foreach (group->priv->pads, (GFunc) gtk_widget_destroy, NULL);
141 	g_slist_free (group->priv->pads);
142 	group->priv->pads = NULL;
143 }
144 
145 
146 gint
xpad_pad_group_num_visible_pads(XpadPadGroup * group)147 xpad_pad_group_num_visible_pads (XpadPadGroup *group)
148 {
149 	gint num = 0;
150 	if (group)
151 	{
152 		GSList *i;
153 		for (i = group->priv->pads; i; i = i->next)
154 		{
155 			if (GTK_WIDGET_VISIBLE(GTK_WIDGET(i->data)))
156 				num ++;
157 		}
158 	}
159 	return num;
160 }
161 
162 
163 void
xpad_pad_group_close_all(XpadPadGroup * group)164 xpad_pad_group_close_all (XpadPadGroup *group)
165 {
166 	if (group)
167 		g_slist_foreach (group->priv->pads, (GFunc) xpad_pad_close, NULL);
168 }
169 
170 
171 void
xpad_pad_group_show_all(XpadPadGroup * group)172 xpad_pad_group_show_all (XpadPadGroup *group)
173 {
174 	if (group)
175 		g_slist_foreach (group->priv->pads, (GFunc) gtk_widget_show, NULL);
176 }
177 
178