1 /*************************************************************************/
2 /* Copyright (C) 2007-2009 sujith <m.sujith@gmail.com> */
3 /* Copyright (C) 2009-2014 matias <mati86dl@gmail.com> */
4 /* */
5 /* This program is free software: you can redistribute it and/or modify */
6 /* it under the terms of the GNU General Public License as published by */
7 /* the Free Software Foundation, either version 3 of the License, or */
8 /* (at your option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU General Public License for more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License */
16 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /*************************************************************************/
18
19 #if HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #include "pragha-toolbar.h"
24
25 #if defined(GETTEXT_PACKAGE)
26 #include <glib/gi18n-lib.h>
27 #else
28 #include <glib/gi18n.h>
29 #endif
30
31 #include <gdk/gdkkeysyms.h>
32
33 #include "pragha-simple-widgets.h"
34 #include "pragha-utils.h"
35
36 static void pragha_toolbar_finalize (GObject *object);
37
38 static void pragha_toolbar_set_remaning_mode (PraghaToolbar *toolbar, gboolean remaning_mode);
39 gboolean pragha_toolbar_get_remaning_mode (PraghaToolbar *toolbar);
40
41
42 struct _PraghaToolbar {
43 #if GTK_CHECK_VERSION (3, 12, 0)
44 GtkHeaderBar __parent__;
45 #else
46 GtkToolbar __parent__;
47 #endif
48 PraghaAlbumArt *albumart;
49
50 GtkWidget *track_progress_bar;
51
52 PraghaToolbarButton *prev_button;
53 PraghaToolbarButton *play_button;
54 PraghaToolbarButton *stop_button;
55 PraghaToolbarButton *next_button;
56 PraghaToolbarButton *unfull_button;
57 GtkWidget *vol_button;
58 GtkWidget *extra_button_box;
59
60 GtkWidget *track_length_label;
61 GtkWidget *track_time_label;
62 GtkWidget *now_playing_label;
63 GtkWidget *extention_box;
64
65 gboolean remaning_mode;
66 };
67
68 enum {
69 PROP_0,
70 PROP_VOLUME,
71 PROP_REMANING_MODE,
72 PROP_LAST
73 };
74
75 static GParamSpec *properties[PROP_LAST] = { 0 };
76
77 enum
78 {
79 PREV_ACTIVATED,
80 PLAY_ACTIVATED,
81 STOP_ACTIVATED,
82 NEXT_ACTIVATED,
83 ALBUM_ART_ACTIVATED,
84 TRACK_INFO_ACTIVATED,
85 TRACK_PROGRESS_ACTIVATED,
86 UNFULL_ACTIVATED,
87 TRACK_TIME_ACTIVATED,
88 LAST_SIGNAL
89 };
90
91 static int signals[LAST_SIGNAL] = { 0 };
92
93 #if GTK_CHECK_VERSION (3, 12, 0)
G_DEFINE_TYPE(PraghaToolbar,pragha_toolbar,GTK_TYPE_HEADER_BAR)94 G_DEFINE_TYPE(PraghaToolbar, pragha_toolbar, GTK_TYPE_HEADER_BAR)
95 #else
96 G_DEFINE_TYPE(PraghaToolbar, pragha_toolbar, GTK_TYPE_TOOLBAR)
97 #endif
98
99 void
100 pragha_toolbar_update_progress (PraghaToolbar *toolbar, gint length, gint progress)
101 {
102 gdouble fraction = 0;
103 gchar *tot_length = NULL, *cur_pos = NULL, *str_length = NULL, *str_cur_pos = NULL;
104
105 cur_pos = convert_length_str(progress);
106 str_cur_pos = g_markup_printf_escaped ("<small>%s</small>", cur_pos);
107
108 if (length == 0 || !pragha_toolbar_get_remaning_mode (toolbar)) {
109 tot_length = convert_length_str(length);
110 str_length = g_markup_printf_escaped ("<small>%s</small>", tot_length);
111 }
112 else {
113 tot_length = convert_length_str(length - progress);
114 str_length = g_markup_printf_escaped ("<small>- %s</small>", tot_length);
115 }
116
117 gtk_label_set_markup (GTK_LABEL(toolbar->track_time_label), str_cur_pos);
118 gtk_label_set_markup (GTK_LABEL(toolbar->track_length_label), str_length);
119
120 gtk_tooltip_trigger_tooltip_query(gtk_widget_get_display (toolbar->track_length_label));
121
122 if(length) {
123 fraction = (gdouble) progress / (gdouble)length;
124 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(toolbar->track_progress_bar), fraction);
125 }
126
127 g_free(cur_pos);
128 g_free(str_cur_pos);
129
130 g_free(tot_length);
131 g_free(str_length);
132 }
133
134 void
pragha_toolbar_set_title(PraghaToolbar * toolbar,PraghaMusicobject * mobj)135 pragha_toolbar_set_title (PraghaToolbar *toolbar, PraghaMusicobject *mobj)
136 {
137 gchar *str = NULL, *str_title = NULL;
138
139 const gchar *file = pragha_musicobject_get_file (mobj);
140 const gchar *title = pragha_musicobject_get_title (mobj);
141 const gchar *artist = pragha_musicobject_get_artist (mobj);
142 const gchar *album = pragha_musicobject_get_album (mobj);
143
144 if(string_is_not_empty(title))
145 str_title = g_strdup(title);
146 else
147 str_title = get_display_filename(file, FALSE);
148
149 if(string_is_not_empty(artist) && string_is_not_empty(album))
150 str = g_markup_printf_escaped (_("%s <small><span weight=\"light\">by</span></small> %s <small><span weight=\"light\">in</span></small> %s"),
151 str_title,
152 artist,
153 album);
154 else if(string_is_not_empty(artist))
155 str = g_markup_printf_escaped (_("%s <small><span weight=\"light\">by</span></small> %s"),
156 str_title,
157 artist);
158 else if(string_is_not_empty(album))
159 str = g_markup_printf_escaped (_("%s <small><span weight=\"light\">in</span></small> %s"),
160 str_title,
161 album);
162 else
163 str = g_markup_printf_escaped("%s", str_title);
164
165 gtk_label_set_markup(GTK_LABEL(toolbar->now_playing_label), str);
166
167 g_free(str_title);
168 g_free(str);
169 }
170
171 static void
pragha_toolbar_unset_song_info(PraghaToolbar * toolbar)172 pragha_toolbar_unset_song_info(PraghaToolbar *toolbar)
173 {
174 gtk_label_set_markup(GTK_LABEL(toolbar->now_playing_label), _("<b>Not playing</b>"));
175 gtk_label_set_markup(GTK_LABEL(toolbar->track_length_label), "<small>--:--</small>");
176 gtk_label_set_markup(GTK_LABEL(toolbar->track_time_label), "<small>00:00</small>");
177
178 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(toolbar->track_progress_bar), 0);
179
180 pragha_album_art_set_path(toolbar->albumart, NULL);
181 }
182
183 static void
pragha_toolbar_timer_label_event_change_mode(GtkWidget * widget,GdkEventButton * event,PraghaToolbar * toolbar)184 pragha_toolbar_timer_label_event_change_mode (GtkWidget *widget,
185 GdkEventButton *event,
186 PraghaToolbar *toolbar)
187 {
188 pragha_toolbar_set_remaning_mode (toolbar,
189 !pragha_toolbar_get_remaning_mode (toolbar));
190 }
191
192 void
pragha_toolbar_set_image_album_art(PraghaToolbar * toolbar,const gchar * uri)193 pragha_toolbar_set_image_album_art (PraghaToolbar *toolbar, const gchar *uri)
194 {
195 pragha_album_art_set_path (toolbar->albumart, uri);
196 }
197
198 /* Grab focus on current playlist when press Up or Down and move between controls with Left or Right */
199
200 /*static gboolean
201 panel_button_key_press (GtkWidget *win, GdkEventKey *event, PraghaApplication *pragha)
202 {
203 gboolean ret = FALSE;
204
205 if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down ||
206 event->keyval == GDK_KEY_Page_Up || event->keyval == GDK_KEY_Page_Down) {
207 ret = pragha_playlist_propagate_event(pragha->cplaylist, event);
208 }
209
210 return ret;
211 }*/
212
213 /*
214 * Emit signals..
215 */
216
217 static gboolean
play_button_handler(GtkButton * button,PraghaToolbar * toolbar)218 play_button_handler(GtkButton *button, PraghaToolbar *toolbar)
219 {
220 g_signal_emit (toolbar, signals[PLAY_ACTIVATED], 0);
221
222 return TRUE;
223 }
224
225 static gboolean
stop_button_handler(GtkButton * button,PraghaToolbar * toolbar)226 stop_button_handler(GtkButton *button, PraghaToolbar *toolbar)
227 {
228 g_signal_emit (toolbar, signals[STOP_ACTIVATED], 0);
229
230 return TRUE;
231 }
232
233 static gboolean
prev_button_handler(GtkButton * button,PraghaToolbar * toolbar)234 prev_button_handler(GtkButton *button, PraghaToolbar *toolbar)
235 {
236 g_signal_emit (toolbar, signals[PREV_ACTIVATED], 0);
237
238 return TRUE;
239 }
240
241 static gboolean
next_button_handler(GtkButton * button,PraghaToolbar * toolbar)242 next_button_handler(GtkButton *button, PraghaToolbar *toolbar)
243 {
244 g_signal_emit (toolbar, signals[NEXT_ACTIVATED], 0);
245
246 return TRUE;
247 }
248
249 static gboolean
unfull_button_handler(GtkButton * button,PraghaToolbar * toolbar)250 unfull_button_handler (GtkButton *button, PraghaToolbar *toolbar)
251 {
252 g_signal_emit (toolbar, signals[UNFULL_ACTIVATED], 0);
253
254 return TRUE;
255 }
256
257 static gboolean
pragha_toolbar_album_art_activated(GtkWidget * event_box,GdkEventButton * event,PraghaToolbar * toolbar)258 pragha_toolbar_album_art_activated (GtkWidget *event_box,
259 GdkEventButton *event,
260 PraghaToolbar *toolbar)
261 {
262 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
263 #if GTK_CHECK_VERSION (3, 12, 0)
264 if (!gtk_header_bar_get_show_close_button(GTK_HEADER_BAR(toolbar)))
265 #endif
266 g_signal_emit (toolbar, signals[ALBUM_ART_ACTIVATED], 0);
267
268 return FALSE;
269 }
270
271 static gboolean
pragha_toolbar_song_label_event_edit(GtkWidget * event_box,GdkEventButton * event,PraghaToolbar * toolbar)272 pragha_toolbar_song_label_event_edit (GtkWidget *event_box,
273 GdkEventButton *event,
274 PraghaToolbar *toolbar)
275 {
276 if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
277 #if GTK_CHECK_VERSION (3, 12, 0)
278 if (!gtk_header_bar_get_show_close_button(GTK_HEADER_BAR(toolbar)))
279 #endif
280 g_signal_emit (toolbar, signals[TRACK_INFO_ACTIVATED], 0);
281
282 return FALSE;
283 }
284
285 static void
pragha_toolbar_progress_bar_event_seek(GtkWidget * widget,GdkEventButton * event,PraghaToolbar * toolbar)286 pragha_toolbar_progress_bar_event_seek (GtkWidget *widget,
287 GdkEventButton *event,
288 PraghaToolbar *toolbar)
289 {
290 GtkAllocation allocation;
291 gdouble fraction = 0;
292
293 if (event->button != 1)
294 return;
295
296 gtk_widget_get_allocation(widget, &allocation);
297
298 fraction = (gdouble) event->x / allocation.width;
299
300 g_signal_emit (toolbar, signals[TRACK_PROGRESS_ACTIVATED], 0, fraction);
301 }
302
303 /*
304 * Callbacks that response to gstreamer signals.
305 */
306
307 void
pragha_toolbar_update_buffering_cb(PraghaBackend * backend,gint percent,gpointer user_data)308 pragha_toolbar_update_buffering_cb (PraghaBackend *backend, gint percent, gpointer user_data)
309 {
310 PraghaToolbar *toolbar = user_data;
311
312 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(toolbar->track_progress_bar), (gdouble)percent/100);
313 }
314
315 void
pragha_toolbar_update_playback_progress(PraghaBackend * backend,gpointer user_data)316 pragha_toolbar_update_playback_progress(PraghaBackend *backend, gpointer user_data)
317 {
318 gint length = 0, newsec = 0;
319 PraghaMusicobject *mobj = NULL;
320
321 PraghaToolbar *toolbar = user_data;
322
323 newsec = GST_TIME_AS_SECONDS(pragha_backend_get_current_position(backend));
324
325 if (newsec > 0) {
326 mobj = pragha_backend_get_musicobject (backend);
327 length = pragha_musicobject_get_length (mobj);
328
329 if (length > 0) {
330 pragha_toolbar_update_progress (toolbar, length, newsec);
331 }
332 else {
333 gint nlength = GST_TIME_AS_SECONDS(pragha_backend_get_current_length(backend));
334 pragha_musicobject_set_length (mobj, nlength);
335 }
336 }
337 }
338
339 void
pragha_toolbar_playback_state_cb(PraghaBackend * backend,GParamSpec * pspec,gpointer user_data)340 pragha_toolbar_playback_state_cb (PraghaBackend *backend, GParamSpec *pspec, gpointer user_data)
341 {
342 PraghaToolbar *toolbar = user_data;
343 PraghaBackendState state = pragha_backend_get_state (backend);
344
345 gboolean playing = (state != ST_STOPPED);
346
347 gtk_widget_set_sensitive (GTK_WIDGET(toolbar->prev_button), playing);
348
349 pragha_toolbar_button_set_icon_name (toolbar->play_button,
350 (state == ST_PLAYING) ? "media-playback-pause" : "media-playback-start");
351 gtk_widget_set_sensitive (GTK_WIDGET(toolbar->stop_button), playing);
352 gtk_widget_set_sensitive (GTK_WIDGET(toolbar->next_button), playing);
353
354 if (playing == FALSE)
355 pragha_toolbar_unset_song_info(toolbar);
356 }
357
358 void
pragha_toolbar_show_ramaning_time_cb(PraghaToolbar * toolbar,GParamSpec * pspec,gpointer user_data)359 pragha_toolbar_show_ramaning_time_cb (PraghaToolbar *toolbar, GParamSpec *pspec, gpointer user_data)
360 {
361 PraghaBackend *backend = user_data;
362 pragha_toolbar_update_playback_progress (backend, toolbar);
363 }
364
365 /*
366 * Show the unfullscreen button according to the state of the window.
367 */
368
369 gboolean
pragha_toolbar_window_state_event(GtkWidget * widget,GdkEventWindowState * event,PraghaToolbar * toolbar)370 pragha_toolbar_window_state_event (GtkWidget *widget, GdkEventWindowState *event, PraghaToolbar *toolbar)
371 {
372 if (event->type == GDK_WINDOW_STATE && (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)) {
373 gtk_widget_set_visible(GTK_WIDGET(toolbar->unfull_button), (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0);
374 }
375
376 return FALSE;
377 }
378
379 /*
380 * Public api.
381 */
382
383 #if GTK_CHECK_VERSION (3, 12, 0)
384 void
pragha_toolbar_set_style(PraghaToolbar * toolbar,gboolean system_titlebar)385 pragha_toolbar_set_style (PraghaToolbar *toolbar, gboolean system_titlebar)
386 {
387 GtkStyleContext *context;
388 context = gtk_widget_get_style_context (GTK_WIDGET(toolbar));
389
390 if (system_titlebar) {
391 gtk_style_context_remove_class (context, "header-bar");
392 gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOOLBAR);
393 gtk_style_context_add_class (context, GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
394 }
395 else {
396 gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TOOLBAR);
397 gtk_style_context_remove_class (context, GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
398 gtk_style_context_add_class (context, "header-bar");
399 }
400
401 gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(toolbar), !system_titlebar);
402 }
403 #endif
404
405 void
pragha_toolbar_add_extention_widget(PraghaToolbar * toolbar,GtkWidget * widget)406 pragha_toolbar_add_extention_widget(PraghaToolbar *toolbar, GtkWidget *widget)
407 {
408 GList *list;
409 GtkWidget *children;
410
411 list = gtk_container_get_children (GTK_CONTAINER(toolbar->extention_box));
412 if(list) {
413 children = list->data;
414 gtk_container_remove(GTK_CONTAINER(toolbar->extention_box), children);
415 gtk_widget_destroy(GTK_WIDGET(children));
416 g_list_free(list);
417 }
418 gtk_container_add(GTK_CONTAINER(toolbar->extention_box), widget);
419 }
420
421 void
pragha_toolbar_add_extra_button(PraghaToolbar * toolbar,GtkWidget * widget)422 pragha_toolbar_add_extra_button (PraghaToolbar *toolbar, GtkWidget *widget)
423 {
424 GList *list;
425 GtkWidget *children;
426
427 list = gtk_container_get_children (GTK_CONTAINER(toolbar->extra_button_box));
428 if(list) {
429 children = list->data;
430 gtk_container_remove(GTK_CONTAINER(toolbar->extra_button_box), children);
431 gtk_widget_destroy(GTK_WIDGET(children));
432 g_list_free(list);
433 }
434 gtk_container_add(GTK_CONTAINER(toolbar->extra_button_box), widget);
435 }
436
437
438 const gchar*
pragha_toolbar_get_progress_text(PraghaToolbar * toolbar)439 pragha_toolbar_get_progress_text(PraghaToolbar *toolbar)
440 {
441 return gtk_label_get_text (GTK_LABEL(toolbar->track_time_label));
442 }
443
444 const gchar*
pragha_toolbar_get_length_text(PraghaToolbar * toolbar)445 pragha_toolbar_get_length_text(PraghaToolbar *toolbar)
446 {
447 return gtk_label_get_text (GTK_LABEL(toolbar->track_length_label));
448 }
449
450 PraghaAlbumArt *
pragha_toolbar_get_album_art(PraghaToolbar * toolbar)451 pragha_toolbar_get_album_art(PraghaToolbar *toolbar)
452 {
453 return toolbar->albumart;
454 }
455
456 /*
457 * Pragha toolbar creation and destruction.
458 */
459
460 GtkWidget *
pragha_toolbar_get_song_box(PraghaToolbar * toolbar)461 pragha_toolbar_get_song_box (PraghaToolbar *toolbar)
462 {
463 PraghaPreferences *preferences;
464 PraghaAlbumArt *albumart;
465 PraghaContainer *box;
466 GtkWidget *hbox, *vbox_aling, *vbox, *top_hbox, *botton_hbox;
467 GtkWidget *album_art_frame,*title, *title_event_box, *extention_box;
468 GtkWidget *progress_bar, *progress_bar_event_box, *time_label, *time_align, *length_label, *length_align, *length_event_box;
469
470 const GBindingFlags binding_flags =
471 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL;
472
473 preferences = pragha_preferences_get();
474
475 /*
476 * Main box that allow expand.
477 */
478 box = pragha_container_new ();
479
480 /*
481 * Main box: [Album][Song info]
482 */
483 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
484 gtk_box_pack_start (GTK_BOX(box), hbox, TRUE, TRUE, 0);
485
486 album_art_frame = gtk_event_box_new ();
487 gtk_event_box_set_visible_window(GTK_EVENT_BOX(album_art_frame), FALSE);
488 g_signal_connect(G_OBJECT (album_art_frame), "button_press_event",
489 G_CALLBACK (pragha_toolbar_album_art_activated), toolbar);
490 gtk_box_pack_start (GTK_BOX(hbox), album_art_frame, FALSE, FALSE, 2);
491
492 albumart = pragha_album_art_new ();
493 g_object_bind_property (preferences, "album-art-size",
494 albumart, "size", binding_flags);
495 g_object_bind_property (preferences, "show-album-art",
496 albumart, "visible", binding_flags);
497 gtk_container_add(GTK_CONTAINER(album_art_frame), GTK_WIDGET(albumart));
498 toolbar->albumart = albumart;
499
500 /*
501 * Song info vbox
502 */
503 vbox_aling = gtk_alignment_new(0.5, 0.5, 1, 0);
504
505 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
506 gtk_container_add(GTK_CONTAINER(vbox_aling), GTK_WIDGET(vbox));
507
508 /*
509 * Top box: [Title][extentions]
510 */
511 top_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
512 gtk_box_pack_start(GTK_BOX(vbox), top_hbox, TRUE, TRUE, 0);
513
514 /* The title widget. */
515
516 title_event_box = gtk_event_box_new();
517 gtk_event_box_set_visible_window(GTK_EVENT_BOX(title_event_box), FALSE);
518
519 g_signal_connect (G_OBJECT(title_event_box), "button-press-event",
520 G_CALLBACK(pragha_toolbar_song_label_event_edit), toolbar);
521
522 title = gtk_label_new(NULL);
523 gtk_label_set_ellipsize (GTK_LABEL(title), PANGO_ELLIPSIZE_END);
524 gtk_label_set_markup(GTK_LABEL(title),_("<b>Not playing</b>"));
525 gtk_misc_set_alignment(GTK_MISC(title), 0, 0.5);
526
527 gtk_container_add (GTK_CONTAINER(title_event_box), title);
528
529 /* The extentions box. */
530
531 extention_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
532
533 /* Pack top widgets: */
534
535 gtk_box_pack_start (GTK_BOX(top_hbox),
536 GTK_WIDGET(title_event_box),
537 TRUE, TRUE, 0);
538 gtk_box_pack_start (GTK_BOX(top_hbox),
539 GTK_WIDGET(extention_box),
540 FALSE, FALSE, 0);
541
542 /*
543 * Botton box: [Time][ProgressBar][Length]
544 */
545 botton_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
546 gtk_box_pack_start(GTK_BOX(vbox), botton_hbox, FALSE, FALSE, 0);
547
548 /* Time progress widget. */
549
550 time_align = gtk_alignment_new(1, 0.5, 0, 0);
551
552 time_label = gtk_label_new(NULL);
553 gtk_label_set_markup(GTK_LABEL(time_label),"<small>00:00</small>");
554
555 gtk_container_add(GTK_CONTAINER(time_align), time_label);
556
557 /* Progress bar widget. */
558
559 progress_bar_event_box = gtk_event_box_new();
560 gtk_event_box_set_visible_window(GTK_EVENT_BOX(progress_bar_event_box), FALSE);
561
562 g_signal_connect (G_OBJECT(progress_bar_event_box), "button-press-event",
563 G_CALLBACK(pragha_toolbar_progress_bar_event_seek), toolbar);
564
565 #if GTK_CHECK_VERSION (3, 14, 0)
566 progress_bar = gtk_progress_bar_new ();
567 gtk_widget_set_valign (GTK_WIDGET(progress_bar), GTK_ALIGN_CENTER);
568 #else
569 progress_bar = GTK_WIDGET(pragha_track_progress_new ());
570 #endif
571
572 gtk_container_add (GTK_CONTAINER(progress_bar_event_box),
573 GTK_WIDGET(progress_bar));
574
575 /* Length and remaining time widget. */
576
577 length_event_box = gtk_event_box_new();
578 gtk_event_box_set_visible_window(GTK_EVENT_BOX(length_event_box), FALSE);
579 g_signal_connect (G_OBJECT(length_event_box), "button-press-event",
580 G_CALLBACK(pragha_toolbar_timer_label_event_change_mode), toolbar);
581
582 length_align = gtk_alignment_new(0, 0.5, 0, 0);
583 gtk_container_add(GTK_CONTAINER(length_event_box), length_align);
584
585 length_label = gtk_label_new(NULL);
586 gtk_label_set_markup(GTK_LABEL(length_label),"<small>--:--</small>");
587
588 gtk_container_add(GTK_CONTAINER(length_align), length_label);
589
590 /* Pack widgets. */
591
592 gtk_box_pack_start (GTK_BOX(botton_hbox),
593 GTK_WIDGET(time_align),
594 FALSE, FALSE, 3);
595 gtk_box_pack_start (GTK_BOX(botton_hbox),
596 GTK_WIDGET(progress_bar_event_box),
597 TRUE, TRUE, 0);
598 gtk_box_pack_start (GTK_BOX(botton_hbox),
599 GTK_WIDGET(length_event_box),
600 FALSE, FALSE, 3);
601
602 /* Save references. */
603
604 toolbar->track_progress_bar = progress_bar;
605 toolbar->now_playing_label = title;
606 toolbar->track_time_label = time_label;
607 toolbar->track_length_label = length_label;
608 toolbar->extention_box = extention_box;
609
610 gtk_box_pack_start(GTK_BOX(hbox), vbox_aling, TRUE, TRUE, 2);
611
612 gtk_widget_show_all(GTK_WIDGET(vbox_aling));
613 gtk_widget_show(GTK_WIDGET(album_art_frame));
614 gtk_widget_show(GTK_WIDGET(hbox));
615 gtk_widget_show(GTK_WIDGET(box));
616
617 g_object_unref(preferences);
618
619 return GTK_WIDGET(box);
620 }
621
622 #if !GTK_CHECK_VERSION (3, 12, 0)
623 static void
gtk_tool_insert_generic_item(GtkToolbar * toolbar,GtkWidget * item)624 gtk_tool_insert_generic_item(GtkToolbar *toolbar, GtkWidget *item)
625 {
626 GtkWidget *align_box;
627 GtkToolItem *boxitem;
628
629 boxitem = gtk_tool_item_new ();
630
631 align_box = gtk_alignment_new(0, 0.5, 0, 0);
632 gtk_container_add(GTK_CONTAINER(align_box), item);
633
634 gtk_container_add (GTK_CONTAINER(boxitem), align_box);
635 gtk_toolbar_insert (GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(boxitem), -1);
636 }
637 #endif
638
639 static void
vol_button_value_changed(GtkVolumeButton * button,gdouble value,PraghaToolbar * toolbar)640 vol_button_value_changed (GtkVolumeButton *button, gdouble value, PraghaToolbar *toolbar)
641 {
642 g_object_notify_by_pspec (G_OBJECT (toolbar), properties[PROP_VOLUME]);
643 }
644
645 static void
pragha_toolbar_set_volume(PraghaToolbar * toolbar,gdouble volume)646 pragha_toolbar_set_volume (PraghaToolbar *toolbar, gdouble volume)
647 {
648 gtk_scale_button_set_value (GTK_SCALE_BUTTON(toolbar->vol_button), volume);
649 }
650
651 gdouble
pragha_toolbar_get_volume(PraghaToolbar * toolbar)652 pragha_toolbar_get_volume (PraghaToolbar *toolbar)
653 {
654 return gtk_scale_button_get_value (GTK_SCALE_BUTTON(toolbar->vol_button));
655 }
656
657 static void
pragha_toolbar_set_remaning_mode(PraghaToolbar * toolbar,gboolean remaning_mode)658 pragha_toolbar_set_remaning_mode (PraghaToolbar *toolbar, gboolean remaning_mode)
659 {
660 toolbar->remaning_mode = remaning_mode;
661
662 g_object_notify_by_pspec(G_OBJECT(toolbar), properties[PROP_REMANING_MODE]);
663 }
664
665 gboolean
pragha_toolbar_get_remaning_mode(PraghaToolbar * toolbar)666 pragha_toolbar_get_remaning_mode (PraghaToolbar *toolbar)
667 {
668 return toolbar->remaning_mode;
669 }
670
671 static void
pragha_toolbar_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)672 pragha_toolbar_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
673 {
674 PraghaToolbar *toolbar = PRAGHA_TOOLBAR (object);
675
676 switch (property_id)
677 {
678 case PROP_VOLUME:
679 pragha_toolbar_set_volume (toolbar, g_value_get_double (value));
680 break;
681 case PROP_REMANING_MODE:
682 pragha_toolbar_set_remaning_mode (toolbar, g_value_get_boolean (value));
683 break;
684 default:
685 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
686 break;
687 }
688 }
689
690 static void
pragha_toolbar_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)691 pragha_toolbar_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
692 {
693 PraghaToolbar *toolbar = PRAGHA_TOOLBAR (object);
694
695 switch (property_id)
696 {
697 case PROP_VOLUME:
698 g_value_set_double (value, pragha_toolbar_get_volume (toolbar));
699 break;
700 case PROP_REMANING_MODE:
701 g_value_set_boolean (value, pragha_toolbar_get_remaning_mode (toolbar));
702 break;
703 default:
704 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
705 break;
706 }
707 }
708
709 static void
pragha_toolbar_class_init(PraghaToolbarClass * klass)710 pragha_toolbar_class_init (PraghaToolbarClass *klass)
711 {
712 GObjectClass *gobject_class;
713
714 gobject_class = G_OBJECT_CLASS (klass);
715 gobject_class->set_property = pragha_toolbar_set_property;
716 gobject_class->get_property = pragha_toolbar_get_property;
717 gobject_class->finalize = pragha_toolbar_finalize;
718
719 /*
720 * Properties:
721 */
722 properties[PROP_VOLUME] = g_param_spec_double ("volume", "Volume", "Volume showed on toolbar",
723 0.0, 1.0, 0.5,
724 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
725 properties[PROP_REMANING_MODE] = g_param_spec_boolean ("timer-remaining-mode", "TimerRemainingMode", "Show Remaining Time",
726 FALSE,
727 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
728
729 g_object_class_install_properties (gobject_class, PROP_LAST, properties);
730
731 /*
732 * Signals:
733 */
734 signals[PREV_ACTIVATED] = g_signal_new ("prev",
735 G_TYPE_FROM_CLASS (gobject_class),
736 G_SIGNAL_RUN_LAST,
737 G_STRUCT_OFFSET (PraghaToolbarClass, prev),
738 NULL, NULL,
739 g_cclosure_marshal_VOID__VOID,
740 G_TYPE_NONE, 0);
741 signals[PLAY_ACTIVATED] = g_signal_new ("play",
742 G_TYPE_FROM_CLASS (gobject_class),
743 G_SIGNAL_RUN_LAST,
744 G_STRUCT_OFFSET (PraghaToolbarClass, play),
745 NULL, NULL,
746 g_cclosure_marshal_VOID__VOID,
747 G_TYPE_NONE, 0);
748 signals[STOP_ACTIVATED] = g_signal_new ("stop",
749 G_TYPE_FROM_CLASS (gobject_class),
750 G_SIGNAL_RUN_LAST,
751 G_STRUCT_OFFSET (PraghaToolbarClass, stop),
752 NULL, NULL,
753 g_cclosure_marshal_VOID__VOID,
754 G_TYPE_NONE, 0);
755 signals[NEXT_ACTIVATED] = g_signal_new ("next",
756 G_TYPE_FROM_CLASS (gobject_class),
757 G_SIGNAL_RUN_LAST,
758 G_STRUCT_OFFSET (PraghaToolbarClass, next),
759 NULL, NULL,
760 g_cclosure_marshal_VOID__VOID,
761 G_TYPE_NONE, 0);
762 signals[ALBUM_ART_ACTIVATED] = g_signal_new ("album-art-activated",
763 G_TYPE_FROM_CLASS (gobject_class),
764 G_SIGNAL_RUN_LAST,
765 G_STRUCT_OFFSET (PraghaToolbarClass, album_art_activated),
766 NULL, NULL,
767 g_cclosure_marshal_VOID__VOID,
768 G_TYPE_NONE, 0);
769 signals[TRACK_INFO_ACTIVATED] = g_signal_new ("track-info-activated",
770 G_TYPE_FROM_CLASS (gobject_class),
771 G_SIGNAL_RUN_LAST,
772 G_STRUCT_OFFSET (PraghaToolbarClass, track_info_activated),
773 NULL, NULL,
774 g_cclosure_marshal_VOID__VOID,
775 G_TYPE_NONE, 0);
776 signals[TRACK_PROGRESS_ACTIVATED] = g_signal_new ("track-progress-activated",
777 G_TYPE_FROM_CLASS (gobject_class),
778 G_SIGNAL_RUN_LAST,
779 G_STRUCT_OFFSET (PraghaToolbarClass, track_progress_activated),
780 NULL, NULL,
781 g_cclosure_marshal_VOID__DOUBLE,
782 G_TYPE_NONE, 1, G_TYPE_DOUBLE);
783 signals[UNFULL_ACTIVATED] = g_signal_new ("unfull-activated",
784 G_TYPE_FROM_CLASS (gobject_class),
785 G_SIGNAL_RUN_LAST,
786 G_STRUCT_OFFSET (PraghaToolbarClass, unfull),
787 NULL, NULL,
788 g_cclosure_marshal_VOID__VOID,
789 G_TYPE_NONE, 0);
790 }
791
792 static void
pragha_toolbar_init(PraghaToolbar * toolbar)793 pragha_toolbar_init (PraghaToolbar *toolbar)
794 {
795 PraghaPreferences *preferences;
796 PraghaToolbarButton *prev_button, *play_button, *stop_button, *next_button;
797 PraghaToolbarButton *unfull_button;
798 PraghaToggleButton *shuffle_button, *repeat_button;
799 GtkWidget *vol_button;
800
801 const GBindingFlags binding_flags =
802 G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL;
803
804 preferences = pragha_preferences_get();
805
806 /* Setup Left control buttons */
807
808 prev_button = pragha_toolbar_button_new ("media-skip-backward");
809 gtk_widget_set_tooltip_text(GTK_WIDGET(prev_button), _("Previous Track"));
810 toolbar->prev_button = prev_button;
811
812 play_button = pragha_toolbar_button_new ("media-playback-start");
813 gtk_widget_set_tooltip_text(GTK_WIDGET(play_button), _("Play / Pause Track"));
814 toolbar->play_button = play_button;
815
816 stop_button = pragha_toolbar_button_new ("media-playback-stop");
817 gtk_widget_set_tooltip_text(GTK_WIDGET(stop_button), _("Stop playback"));
818 toolbar->stop_button = stop_button;
819
820 next_button = pragha_toolbar_button_new ("media-skip-forward");
821 gtk_widget_set_tooltip_text(GTK_WIDGET(next_button), _("Next Track"));
822 toolbar->next_button = next_button;
823
824 #if GTK_CHECK_VERSION (3, 12, 0)
825 gtk_header_bar_pack_start(GTK_HEADER_BAR(toolbar), GTK_WIDGET(prev_button));
826 gtk_header_bar_pack_start(GTK_HEADER_BAR(toolbar), GTK_WIDGET(play_button));
827 gtk_header_bar_pack_start(GTK_HEADER_BAR(toolbar), GTK_WIDGET(stop_button));
828 gtk_header_bar_pack_start(GTK_HEADER_BAR(toolbar), GTK_WIDGET(next_button));
829 #else
830 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(prev_button));
831 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(play_button));
832 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(stop_button));
833 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(next_button));
834 #endif
835
836 /* Song info Box */
837
838 #if !GTK_CHECK_VERSION (3, 12, 0)
839 GtkToolItem *boxitem = gtk_tool_item_new ();
840 gtk_tool_item_set_expand (GTK_TOOL_ITEM(boxitem), TRUE);
841 gtk_toolbar_insert (GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(boxitem), -1);
842
843 GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
844 gtk_container_add (GTK_CONTAINER(boxitem), box);
845
846 GtkWidget *playing = pragha_toolbar_get_song_box (toolbar);
847 gtk_box_pack_start (GTK_BOX(box), playing, TRUE, TRUE, 5);
848 #endif
849
850 /* Setup Right control buttons */
851
852 unfull_button = pragha_toolbar_button_new ("view-restore");
853 gtk_widget_set_tooltip_text(GTK_WIDGET(unfull_button), _("Leave Fullscreen"));
854 toolbar->unfull_button = unfull_button;
855
856 shuffle_button = pragha_toggle_button_new ("media-playlist-shuffle");
857 gtk_widget_set_tooltip_text(GTK_WIDGET(shuffle_button), _("Play songs in a random order"));
858
859 repeat_button = pragha_toggle_button_new ("media-playlist-repeat");
860 gtk_widget_set_tooltip_text(GTK_WIDGET(repeat_button), _("Repeat playback list at the end"));
861
862 vol_button = gtk_volume_button_new();
863 g_object_set(vol_button, "use-symbolic", FALSE, NULL);
864 gtk_button_set_relief(GTK_BUTTON(vol_button), GTK_RELIEF_NONE);
865 g_object_set(G_OBJECT(vol_button), "size", GTK_ICON_SIZE_LARGE_TOOLBAR, NULL);
866 toolbar->vol_button = vol_button;
867
868 toolbar->extra_button_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
869
870 #if GTK_CHECK_VERSION (3, 12, 0)
871 gtk_header_bar_pack_end(GTK_HEADER_BAR(toolbar), GTK_WIDGET(toolbar->extra_button_box));
872 gtk_header_bar_pack_end(GTK_HEADER_BAR(toolbar), GTK_WIDGET(vol_button));
873 gtk_header_bar_pack_end(GTK_HEADER_BAR(toolbar), GTK_WIDGET(repeat_button));
874 gtk_header_bar_pack_end(GTK_HEADER_BAR(toolbar), GTK_WIDGET(shuffle_button));
875 gtk_header_bar_pack_end(GTK_HEADER_BAR(toolbar), GTK_WIDGET(unfull_button));
876 #else
877 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(unfull_button));
878 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(shuffle_button));
879 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(repeat_button));
880 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(vol_button));
881 gtk_tool_insert_generic_item(GTK_TOOLBAR(toolbar), GTK_WIDGET(toolbar->extra_button_box));
882 #endif
883
884 /* Connect signals */
885
886 g_signal_connect(G_OBJECT(prev_button), "clicked",
887 G_CALLBACK(prev_button_handler), toolbar);
888 g_signal_connect(G_OBJECT(play_button), "clicked",
889 G_CALLBACK(play_button_handler), toolbar);
890 g_signal_connect(G_OBJECT(stop_button), "clicked",
891 G_CALLBACK(stop_button_handler), toolbar);
892 g_signal_connect(G_OBJECT(next_button), "clicked",
893 G_CALLBACK(next_button_handler), toolbar);
894 g_signal_connect(G_OBJECT(unfull_button), "clicked",
895 G_CALLBACK(unfull_button_handler), toolbar);
896
897 /*g_signal_connect(G_OBJECT (prev_button), "key-press-event",
898 G_CALLBACK(panel_button_key_press), toolbar);
899 g_signal_connect(G_OBJECT (play_button), "key-press-event",
900 G_CALLBACK(panel_button_key_press), toolbar);
901 g_signal_connect(G_OBJECT (stop_button), "key-press-event",
902 G_CALLBACK(panel_button_key_press), toolbar);
903 g_signal_connect(G_OBJECT (next_button), "key-press-event",
904 G_CALLBACK(panel_button_key_press), toolbar);
905 g_signal_connect(G_OBJECT (next_button), "key-press-event",
906 G_CALLBACK(panel_button_key_press), toolbar);
907 g_signal_connect(G_OBJECT (unfull_button), "key-press-event",
908 G_CALLBACK(panel_button_key_press), toolbar);
909 g_signal_connect(G_OBJECT (shuffle_button), "key-press-event",
910 G_CALLBACK(panel_button_key_press), toolbar);
911 g_signal_connect(G_OBJECT (repeat_button), "key-press-event",
912 G_CALLBACK(panel_button_key_press), toolbar);
913 g_signal_connect(G_OBJECT (vol_button), "key-press-event",
914 G_CALLBACK(panel_button_key_press), toolbar);*/
915
916 g_signal_connect (G_OBJECT (vol_button), "value-changed",
917 G_CALLBACK (vol_button_value_changed), toolbar);
918
919 g_object_bind_property(preferences, "shuffle", shuffle_button, "active", binding_flags);
920 g_object_bind_property(preferences, "repeat", repeat_button, "active", binding_flags);
921
922 /* Fix styling */
923 #if GTK_CHECK_VERSION (3, 12, 0)
924 pragha_toolbar_set_style(toolbar,
925 pragha_preferences_get_system_titlebar (preferences));
926 #endif
927
928 g_object_bind_property(preferences, "toolbar-size", prev_button, "icon-size", binding_flags);
929 g_object_bind_property(preferences, "toolbar-size", play_button, "icon-size", binding_flags);
930 g_object_bind_property(preferences, "toolbar-size", stop_button, "icon-size", binding_flags);
931 g_object_bind_property(preferences, "toolbar-size", next_button, "icon-size", binding_flags);
932 g_object_bind_property(preferences, "toolbar-size", unfull_button, "icon-size", binding_flags);
933 g_object_bind_property(preferences, "toolbar-size", shuffle_button, "icon-size", binding_flags);
934 g_object_bind_property(preferences, "toolbar-size", repeat_button, "icon-size", binding_flags);
935 g_object_bind_property(preferences, "toolbar-size", vol_button, "size", binding_flags);
936
937 gtk_widget_show(GTK_WIDGET(prev_button));
938 gtk_widget_show(GTK_WIDGET(play_button));
939 gtk_widget_show(GTK_WIDGET(stop_button));
940 gtk_widget_show(GTK_WIDGET(next_button));
941 gtk_widget_show(GTK_WIDGET(shuffle_button));
942 gtk_widget_show(GTK_WIDGET(repeat_button));
943 gtk_widget_show(GTK_WIDGET(vol_button));
944 gtk_widget_show(GTK_WIDGET(toolbar->extra_button_box));
945
946 gtk_widget_hide(GTK_WIDGET(toolbar->unfull_button));
947
948 gtk_widget_show(GTK_WIDGET(toolbar));
949
950 g_object_unref(preferences);
951 }
952
953 static void
pragha_toolbar_finalize(GObject * object)954 pragha_toolbar_finalize (GObject *object)
955 {
956 (*G_OBJECT_CLASS (pragha_toolbar_parent_class)->finalize) (object);
957 }
958
959 PraghaToolbar *
pragha_toolbar_new(void)960 pragha_toolbar_new (void)
961 {
962 return g_object_new (PRAGHA_TYPE_TOOLBAR, NULL);
963 }
964
965