1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 2013-2014 Red Hat, Inc.
3 *
4 * Authors:
5 * - Bastien Nocera <bnocera@redhat.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /*
22 * Modified by the GTK+ Team and others 2013-2014. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26 */
27
28 #include "config.h"
29
30 #include <gtk/gtk.h>
31 #include <glib/gi18n-lib.h>
32 #include "totem-selection-toolbar.h"
33 #include "griloresources.h"
34
35 /*
36 * SECTION:totemselectiontoolbar
37 * @Short_description: An toolbar with oft-used buttons.
38 * @Title: TotemSelectionToolbar
39 *
40 * #TotemSelectionToolbar is a toolbar that contains oft-used buttons such as toggles
41 * for select mode, and find mode, or a new button. The widget will also be
42 * styled properly when in specific mode.
43 */
44
45 struct _TotemSelectionToolbarPrivate {
46 /* Template widgets */
47 GtkWidget *add_to_fav;
48 GtkWidget *play;
49 GtkWidget *shuffle;
50 GtkWidget *delete;
51
52 /* Delete button */
53 gboolean show_delete_button;
54 gboolean delete_sensitive;
55
56 /* Selection mode */
57 guint n_selected;
58 };
59
60 G_DEFINE_TYPE_WITH_CODE (TotemSelectionToolbar, totem_selection_toolbar, GTK_TYPE_ACTION_BAR,
61 G_ADD_PRIVATE (TotemSelectionToolbar));
62
63 enum {
64 PROP_0,
65 PROP_SHOW_DELETE_BUTTON,
66 PROP_N_SELECTED,
67 PROP_DELETE_BUTTON_SENSITIVE
68 };
69
70 static void
change_class(GtkWidget * widget,const char * class,gboolean add)71 change_class (GtkWidget *widget,
72 const char *class,
73 gboolean add)
74 {
75 GtkStyleContext *style;
76
77 style = gtk_widget_get_style_context (widget);
78 if (add)
79 gtk_style_context_add_class (style, class);
80 else
81 gtk_style_context_remove_class (style, class);
82 }
83
84 static void
update_toolbar_state(TotemSelectionToolbar * bar)85 update_toolbar_state (TotemSelectionToolbar *bar)
86 {
87 TotemSelectionToolbarPrivate *priv = bar->priv;
88 gboolean sensitive;
89
90 if (priv->n_selected == 0)
91 {
92 sensitive = FALSE;
93 change_class (GTK_WIDGET (priv->delete), "destructive-action", FALSE);
94 }
95 else
96 {
97 sensitive = TRUE;
98 change_class (GTK_WIDGET (priv->delete), "destructive-action", TRUE);
99 }
100
101 gtk_widget_set_sensitive (priv->add_to_fav, sensitive);
102 gtk_widget_set_sensitive (priv->play, sensitive);
103 gtk_widget_set_sensitive (priv->shuffle, sensitive);
104 }
105
106 static void
add_to_fav_clicked_cb(GtkButton * button,TotemSelectionToolbar * bar)107 add_to_fav_clicked_cb (GtkButton *button,
108 TotemSelectionToolbar *bar)
109 {
110 g_signal_emit_by_name (G_OBJECT (bar), "add-to-favourites-clicked", NULL);
111 }
112
113 static void
delete_clicked_cb(GtkButton * button,TotemSelectionToolbar * bar)114 delete_clicked_cb (GtkButton *button,
115 TotemSelectionToolbar *bar)
116 {
117 g_signal_emit_by_name (G_OBJECT (bar), "delete-clicked", NULL);
118 }
119
120 static void
play_clicked_cb(GtkButton * button,TotemSelectionToolbar * bar)121 play_clicked_cb (GtkButton *button,
122 TotemSelectionToolbar *bar)
123 {
124 g_signal_emit_by_name (G_OBJECT (bar), "play-clicked", NULL);
125 }
126
127 static void
shuffle_clicked_cb(GtkButton * button,TotemSelectionToolbar * bar)128 shuffle_clicked_cb (GtkButton *button,
129 TotemSelectionToolbar *bar)
130 {
131 g_signal_emit_by_name (G_OBJECT (bar), "shuffle-clicked", NULL);
132 }
133
134 static void
totem_selection_toolbar_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)135 totem_selection_toolbar_set_property (GObject *object,
136 guint prop_id,
137 const GValue *value,
138 GParamSpec *pspec)
139 {
140 TotemSelectionToolbar *bar = TOTEM_SELECTION_TOOLBAR (object);
141
142 switch (prop_id)
143 {
144 case PROP_N_SELECTED:
145 totem_selection_toolbar_set_n_selected (bar, g_value_get_uint (value));
146 break;
147
148 case PROP_SHOW_DELETE_BUTTON:
149 totem_selection_toolbar_set_show_delete_button (bar, g_value_get_boolean (value));
150 break;
151
152 case PROP_DELETE_BUTTON_SENSITIVE:
153 totem_selection_toolbar_set_delete_button_sensitive (bar, g_value_get_boolean (value));
154 break;
155
156 default:
157 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
158 break;
159 }
160 }
161
162 static void
totem_selection_toolbar_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)163 totem_selection_toolbar_get_property (GObject *object,
164 guint prop_id,
165 GValue *value,
166 GParamSpec *pspec)
167 {
168 TotemSelectionToolbar *bar = TOTEM_SELECTION_TOOLBAR (object);
169 TotemSelectionToolbarPrivate *priv = bar->priv;
170
171 switch (prop_id)
172 {
173 case PROP_N_SELECTED:
174 g_value_set_uint (value, totem_selection_toolbar_get_n_selected (bar));
175 break;
176
177 case PROP_SHOW_DELETE_BUTTON:
178 g_value_set_boolean (value, priv->show_delete_button);
179 break;
180
181 case PROP_DELETE_BUTTON_SENSITIVE:
182 g_value_set_boolean (value, priv->delete_sensitive);
183 break;
184
185 default:
186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187 break;
188 }
189 }
190
191 static void
totem_selection_toolbar_class_init(TotemSelectionToolbarClass * klass)192 totem_selection_toolbar_class_init (TotemSelectionToolbarClass *klass)
193 {
194 GObjectClass *object_class = G_OBJECT_CLASS (klass);
195 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
196
197 object_class->set_property = totem_selection_toolbar_set_property;
198 object_class->get_property = totem_selection_toolbar_get_property;
199
200 g_object_class_install_property (object_class,
201 PROP_N_SELECTED,
202 g_param_spec_uint ("n-selected",
203 "Number of Selected Items",
204 "The number of selected items",
205 0,
206 G_MAXUINT,
207 0,
208 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
209
210 g_object_class_install_property (object_class,
211 PROP_SHOW_DELETE_BUTTON,
212 g_param_spec_boolean ("show-delete-button",
213 "Show Delete Button",
214 "Whether the delete button is visible",
215 TRUE,
216 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
217
218 g_object_class_install_property (object_class,
219 PROP_DELETE_BUTTON_SENSITIVE,
220 g_param_spec_boolean ("delete-button-sensitive",
221 "Delete Button Sensitive",
222 "Whether the delete button is sensitive",
223 FALSE,
224 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
225
226 g_signal_new ("add-to-favourites-clicked",
227 G_OBJECT_CLASS_TYPE (klass),
228 0,
229 0,
230 NULL, NULL,
231 g_cclosure_marshal_generic,
232 G_TYPE_NONE, 0, G_TYPE_NONE);
233
234 g_signal_new ("delete-clicked",
235 G_OBJECT_CLASS_TYPE (klass),
236 0,
237 0,
238 NULL, NULL,
239 g_cclosure_marshal_generic,
240 G_TYPE_NONE, 0, G_TYPE_NONE);
241
242 g_signal_new ("play-clicked",
243 G_OBJECT_CLASS_TYPE (klass),
244 0,
245 0,
246 NULL, NULL,
247 g_cclosure_marshal_generic,
248 G_TYPE_NONE, 0, G_TYPE_NONE);
249
250 g_signal_new ("shuffle-clicked",
251 G_OBJECT_CLASS_TYPE (klass),
252 0,
253 0,
254 NULL, NULL,
255 g_cclosure_marshal_generic,
256 G_TYPE_NONE, 0, G_TYPE_NONE);
257
258 gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/totem/grilo/totemselectiontoolbar.ui");
259 gtk_widget_class_bind_template_child_private (widget_class, TotemSelectionToolbar, add_to_fav);
260 gtk_widget_class_bind_template_child_private (widget_class, TotemSelectionToolbar, delete);
261 gtk_widget_class_bind_template_child_private (widget_class, TotemSelectionToolbar, play);
262 gtk_widget_class_bind_template_child_private (widget_class, TotemSelectionToolbar, shuffle);
263 }
264
265 static void
totem_selection_toolbar_init(TotemSelectionToolbar * bar)266 totem_selection_toolbar_init (TotemSelectionToolbar *bar)
267 {
268 bar->priv = totem_selection_toolbar_get_instance_private (bar);
269
270 gtk_widget_init_template (GTK_WIDGET (bar));
271
272 gtk_widget_hide (bar->priv->add_to_fav);
273
274 /* So that the default FALSE actually gets applied */
275 bar->priv->delete_sensitive = TRUE;
276
277 g_signal_connect (bar->priv->add_to_fav, "clicked",
278 G_CALLBACK (add_to_fav_clicked_cb), bar);
279 g_signal_connect (bar->priv->delete, "clicked",
280 G_CALLBACK (delete_clicked_cb), bar);
281 g_signal_connect (bar->priv->play, "clicked",
282 G_CALLBACK (play_clicked_cb), bar);
283 g_signal_connect (bar->priv->shuffle, "clicked",
284 G_CALLBACK (shuffle_clicked_cb), bar);
285 };
286
287 /**
288 * totem_selection_toolbar_new:
289 *
290 * Creates a #TotemSelectionToolbar.
291 *
292 * Return value: a new #TotemSelectionToolbar
293 *
294 * Since: 3.10
295 **/
296 GtkWidget *
totem_selection_toolbar_new(void)297 totem_selection_toolbar_new (void)
298 {
299 return GTK_WIDGET (g_object_new (TOTEM_TYPE_SELECTION_TOOLBAR, NULL));
300 }
301
302 void
totem_selection_toolbar_set_n_selected(TotemSelectionToolbar * bar,guint n_selected)303 totem_selection_toolbar_set_n_selected (TotemSelectionToolbar *bar,
304 guint n_selected)
305 {
306 g_return_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar));
307
308 if (bar->priv->n_selected == n_selected)
309 return;
310
311 bar->priv->n_selected = n_selected;
312
313 update_toolbar_state (bar);
314 g_object_notify (G_OBJECT (bar), "n-selected");
315 }
316
317 guint
totem_selection_toolbar_get_n_selected(TotemSelectionToolbar * bar)318 totem_selection_toolbar_get_n_selected (TotemSelectionToolbar *bar)
319 {
320 g_return_val_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar), 0);
321
322 return bar->priv->n_selected;
323 }
324
325 void
totem_selection_toolbar_set_show_delete_button(TotemSelectionToolbar * bar,gboolean show_delete_button)326 totem_selection_toolbar_set_show_delete_button (TotemSelectionToolbar *bar,
327 gboolean show_delete_button)
328 {
329 g_return_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar));
330
331 if (bar->priv->show_delete_button == show_delete_button)
332 return;
333
334 bar->priv->show_delete_button = show_delete_button;
335 gtk_widget_set_visible (bar->priv->delete, bar->priv->show_delete_button);
336
337 g_object_notify (G_OBJECT (bar), "show-delete-button");
338 }
339
340 gboolean
totem_selection_toolbar_get_show_delete_button(TotemSelectionToolbar * bar)341 totem_selection_toolbar_get_show_delete_button (TotemSelectionToolbar *bar)
342 {
343 g_return_val_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar), 0);
344
345 return bar->priv->show_delete_button;
346 }
347
348 void
totem_selection_toolbar_set_delete_button_sensitive(TotemSelectionToolbar * bar,gboolean sensitive)349 totem_selection_toolbar_set_delete_button_sensitive (TotemSelectionToolbar *bar,
350 gboolean sensitive)
351 {
352 g_return_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar));
353
354 if (bar->priv->delete_sensitive == sensitive)
355 return;
356
357 bar->priv->delete_sensitive = sensitive;
358 gtk_widget_set_sensitive (bar->priv->delete, sensitive);
359
360 g_object_notify (G_OBJECT (bar), "delete-button-sensitive");
361 }
362
363 gboolean
totem_selection_toolbar_get_delete_button_sensitive(TotemSelectionToolbar * bar)364 totem_selection_toolbar_get_delete_button_sensitive (TotemSelectionToolbar *bar)
365 {
366 g_return_val_if_fail (TOTEM_IS_SELECTION_TOOLBAR (bar), 0);
367
368 return bar->priv->delete_sensitive;
369 }
370