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