2 * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net>
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.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <glib/gprintf.h>
23 #define G_LOG_DOMAIN "demo-gui"
31 static guint demo_gui_signals
[LAST_SIGNAL
] = { 0 };
38 typedef struct _DemoGuiPrivate
46 GtkStatusbar
*status_bar
;
47 gint position_updater_id
;
49 GtkLabel
*amount_played
;
50 GtkLabel
*amount_to_play
;
53 #define DEMO_GUI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEMO_TYPE_GUI, DemoGuiPrivate))
55 /* forward declarations */
56 static GValueArray
* build_gvalue_array (guint n_values
, ...);
58 /* Handlers for status bar and seek bar */
60 pop_status_bar (gpointer data
) {
61 GValueArray
*gvalues
= (GValueArray
*)data
;
62 GtkStatusbar
*sb
= GTK_STATUSBAR (g_value_get_object (g_value_array_get_nth (gvalues
, 0)));
63 guint msg_id
= g_value_get_uint (g_value_array_get_nth (gvalues
, 1));
65 gtk_statusbar_remove (sb
, 0, msg_id
);
70 status_bar_printf (GtkStatusbar
*sb
,
71 gchar
const *format
, ...)
75 va_start (args
, format
);
76 g_vsnprintf (msg
, 80, format
, args
);
78 guint msg_id
= gtk_statusbar_push (sb
, 0, msg
);
79 g_timeout_add (2000, pop_status_bar
,
80 build_gvalue_array (2, G_TYPE_OBJECT
, sb
, G_TYPE_UINT
, msg_id
));
83 #define PRINTF_TIME_FORMAT "u:%02u:%02u"
84 #define PRINTF_TIME_ARGS(t) \
85 (t >= 0) ? (guint) ((t) / (60 * 60)) : 99, \
86 (t >= 0) ? (guint) (((t) / (60)) % 60) : 99, \
87 (t >= 0) ? (guint) ((t) % 60) : 99
90 demo_gui_seek_bar_format (GtkScale
*scale
,
94 return g_strdup_printf ("%" PRINTF_TIME_FORMAT
, PRINTF_TIME_ARGS ((gint64
)value
));
97 gboolean
update_position (gpointer data
) {
98 DemoGui
*gui
= DEMO_GUI (data
);
99 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
100 gchar pos_str
[16], dur_str
[16];
102 gint pos
= demo_player_get_position (priv
->player
);
104 g_snprintf (pos_str
, 16, "%" PRINTF_TIME_FORMAT
, PRINTF_TIME_ARGS (pos
));
105 gint dur
= demo_player_get_duration (priv
->player
);
107 g_snprintf (dur_str
, 16, "-%" PRINTF_TIME_FORMAT
, PRINTF_TIME_ARGS (dur
- pos
));
110 g_sprintf (dur_str
, "-??:??:??");
113 gtk_range_set_range (GTK_RANGE (priv
->seek_range
), 0, (gdouble
)dur
);
114 gtk_range_set_value (GTK_RANGE (priv
->seek_range
), (gdouble
)pos
);
116 g_sprintf (pos_str
, "??:??:??");
117 g_sprintf (dur_str
, "-??:??:??");
119 gtk_label_set_text (GTK_LABEL (priv
->amount_played
), pos_str
);
120 gtk_label_set_text (GTK_LABEL (priv
->amount_to_play
), dur_str
);
122 return priv
->is_playing
;
127 demo_gui_seek_bar_change (GtkRange
*range
,
128 GtkScrollType scroll
,
132 DemoGui
*gui
= DEMO_GUI (data
);
133 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
134 gint new_second
= (gint
)value
;
136 status_bar_printf (priv
->status_bar
, "Seeking to %i second", new_second
);
137 demo_player_seek_to (priv
->player
, new_second
);
143 /* Callbacks for actions */
145 demo_gui_do_change_rate (GtkAction
*action
,
148 GValueArray
*gvalues
= (GValueArray
*)data
;
149 DemoGui
*gui
= g_value_get_object (g_value_array_get_nth (gvalues
, 0));
150 gdouble scale_amount
= g_value_get_double (g_value_array_get_nth (gvalues
, 1));
151 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
153 status_bar_printf (priv
->status_bar
, "Changing rate by %3.2lf", scale_amount
);
155 demo_player_scale_rate (priv
->player
, scale_amount
);
159 demo_gui_do_rate_entered (GtkWidget
*widget
,
162 DemoGui
*gui
= DEMO_GUI (data
);
163 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
166 sscanf (gtk_entry_get_text (GTK_ENTRY (widget
)), "%lf", &new_rate
);
168 status_bar_printf (priv
->status_bar
, "Setting rate to %3.2lf", new_rate
);
170 demo_player_set_rate (priv
->player
, new_rate
);
174 demo_gui_do_seek (GtkAction
*action
,
177 GValueArray
*gvalues
= (GValueArray
*)data
;
178 DemoGui
*gui
= g_value_get_object (g_value_array_get_nth (gvalues
, 0));
179 gint seconds
= g_value_get_int (g_value_array_get_nth (gvalues
, 1));
181 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
183 status_bar_printf (priv
->status_bar
, "Seeking %i seconds", seconds
);
185 demo_player_seek_by (priv
->player
, seconds
);
189 demo_gui_do_play (GtkAction
*action
,
192 DemoGui
*gui
= DEMO_GUI (data
);
193 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
195 if (priv
->is_playing
) {
196 g_signal_emit (gui
, demo_gui_signals
[SIGNAL_ERROR
], 0, "Already playing");
200 status_bar_printf (priv
->status_bar
, "Trying to start playing");
202 demo_player_play (priv
->player
);
206 demo_gui_do_pause (GtkAction
*action
,
209 DemoGui
*gui
= DEMO_GUI (data
);
210 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
212 if (!priv
->is_playing
) {
213 g_signal_emit (gui
, demo_gui_signals
[SIGNAL_ERROR
], 0, "Already paused");
217 status_bar_printf (priv
->status_bar
, "Trying to pause playing");
219 demo_player_pause (priv
->player
);
223 demo_gui_do_play_pause (GtkAction
*action
,
226 DemoGui
*gui
= DEMO_GUI (data
);
227 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
229 status_bar_printf (priv
->status_bar
, "Trying to toggle playing");
231 if (priv
->is_playing
)
232 demo_player_pause (priv
->player
);
234 demo_player_play (priv
->player
);
238 demo_gui_do_quit (gpointer source
,
242 g_signal_emit (DEMO_GUI (data
), demo_gui_signals
[SIGNAL_QUITING
], 0, NULL
);
246 /* Callbacks from signals */
248 demo_gui_rate_changed (DemoPlayer
*player
,
252 DemoGui
*gui
= DEMO_GUI (data
);
253 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
254 status_bar_printf (priv
->status_bar
, "Rate changed to %3.2lf", new_rate
);
257 snprintf (e
, 6, "%3.2f", new_rate
);
258 gtk_entry_set_text (GTK_ENTRY (priv
->rate_entry
), e
);
262 demo_gui_playing_started (DemoPlayer
*player
,
265 DemoGui
*gui
= DEMO_GUI (data
);
266 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
268 priv
->is_playing
= TRUE
;
269 status_bar_printf (priv
->status_bar
, "Playing started");
271 if (priv
->position_updater_id
) {
272 g_source_remove (priv
->position_updater_id
);
273 priv
->position_updater_id
= 0;
275 update_position (gui
);
276 priv
->position_updater_id
= g_timeout_add (1000, update_position
, gui
);
280 demo_gui_playing_paused (DemoPlayer
*player
,
283 DemoGui
*gui
= DEMO_GUI (data
);
284 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
286 priv
->is_playing
= FALSE
;
288 if (priv
->position_updater_id
)
289 g_source_remove (priv
->position_updater_id
);
290 priv
->position_updater_id
= 0;
291 update_position (gui
);
293 status_bar_printf (priv
->status_bar
, "Playing paused");
297 demo_gui_playing_ended (DemoPlayer
*player
,
300 DemoGui
*gui
= DEMO_GUI (data
);
301 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
302 status_bar_printf (priv
->status_bar
, "Playing ended");
306 /* method implementations */
308 demo_gui_set_player_func (DemoGui
*gui
,
311 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
313 g_signal_handlers_disconnect_by_func (G_OBJECT (priv
->player
), G_CALLBACK (demo_gui_rate_changed
), gui
);
314 g_signal_handlers_disconnect_by_func (G_OBJECT (priv
->player
), G_CALLBACK (demo_gui_playing_started
), gui
);
315 g_signal_handlers_disconnect_by_func (G_OBJECT (priv
->player
), G_CALLBACK (demo_gui_playing_paused
), gui
);
316 g_signal_handlers_disconnect_by_func (G_OBJECT (priv
->player
), G_CALLBACK (demo_gui_playing_ended
), gui
);
318 priv
->player
= player
;
319 g_signal_connect (G_OBJECT (priv
->player
), "rate-changed", G_CALLBACK (demo_gui_rate_changed
), gui
);
320 g_signal_connect (G_OBJECT (priv
->player
), "playing-started", G_CALLBACK (demo_gui_playing_started
), gui
);
321 g_signal_connect (G_OBJECT (priv
->player
), "playing-paused", G_CALLBACK (demo_gui_playing_paused
), gui
);
322 g_signal_connect (G_OBJECT (priv
->player
), "playing-ended", G_CALLBACK (demo_gui_playing_ended
), gui
);
324 if (priv
->now_playing
)
325 demo_player_load_uri (priv
->player
, priv
->now_playing
->data
);
329 demo_gui_set_playlist_func (DemoGui
*gui
,
332 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
334 priv
->now_playing
= priv
->uris
;
335 if (priv
->player
&& priv
->now_playing
)
336 demo_player_load_uri (priv
->player
, priv
->now_playing
->data
);
339 typedef struct _ActionEntry
{
345 const gchar
*tooltip
;
346 const gchar
*stock_id
;
347 GtkAccelGroup
*accel_group
;
348 GtkActionGroup
*action_group
;
354 build_gvalue_array (guint n_values
,
358 va_start (args
, n_values
);
359 GValueArray
*gva
= g_value_array_new (n_values
);
361 for (i
=0; i
<n_values
; i
++) {
362 GType type
= va_arg (args
, GType
);
363 GValue
*gval
= g_new0 (GValue
, 1);
364 if (type
== G_TYPE_INT
) {
365 gint value
= va_arg (args
, gint
);
366 g_value_set_int (g_value_init (gval
, G_TYPE_INT
), value
);
367 } else if (type
== G_TYPE_UINT
) {
368 guint value
= va_arg (args
, guint
);
369 g_value_set_uint (g_value_init (gval
, G_TYPE_UINT
), value
);
370 } else if (type
== G_TYPE_DOUBLE
) {
371 double value
= va_arg (args
, double);
372 g_value_set_double (g_value_init (gval
, G_TYPE_DOUBLE
), value
);
373 } else if (type
== G_TYPE_OBJECT
) {
374 GObject
*value
= va_arg (args
, GObject
*);
375 g_value_set_object (g_value_init (gval
, G_TYPE_OBJECT
), value
);
377 g_critical ("build_gvalue_array cannot handle type (%s)", g_type_name (type
));
381 g_value_array_append (gva
, gval
);
388 create_action (ActionEntry
*p
)
390 p
->action
= gtk_action_new (p
->name
, p
->label
, p
->tooltip
, p
->stock_id
);
392 gtk_action_group_add_action_with_accel (p
->action_group
, p
->action
, p
->accel
);
393 gtk_action_set_accel_group (p
->action
, p
->accel_group
);
394 gtk_action_connect_accelerator (p
->action
);
396 p
->button
= gtk_button_new ();
397 gtk_action_connect_proxy (p
->action
, p
->button
);
398 gtk_button_set_image (GTK_BUTTON (p
->button
), gtk_action_create_icon (p
->action
, GTK_ICON_SIZE_BUTTON
));
399 g_signal_connect (G_OBJECT (p
->action
), "activate", p
->callback
, p
->data
);
404 demo_gui_show_func (DemoGui
*gui
) {
405 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
407 gtk_init (NULL
, NULL
);
408 GtkWidget
*window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
409 g_signal_connect (G_OBJECT (window
), "destroy", G_CALLBACK (demo_gui_do_quit
), gui
);
411 GtkAccelGroup
*accel_group
= gtk_accel_group_new ();
412 gtk_window_add_accel_group (GTK_WINDOW (window
), accel_group
);
413 GtkActionGroup
*action_group
= gtk_action_group_new ("toolbar");
415 ActionEntry
*slower_lg
= &(ActionEntry
){
417 "braceleft", "slower-large",
418 "2x Slower", "half playback rate",
419 GTK_STOCK_GO_DOWN
, accel_group
, action_group
,
420 G_CALLBACK (demo_gui_do_change_rate
),
421 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_DOUBLE
, 0.5)
423 create_action (slower_lg
);
425 ActionEntry
*slower_sm
= &(ActionEntry
){
427 "bracketleft", "slower-small",
428 "_Slower", "decrease playback rate",
429 GTK_STOCK_GO_DOWN
, accel_group
, action_group
,
430 G_CALLBACK (demo_gui_do_change_rate
),
431 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_DOUBLE
, 0.943874312681694)
433 create_action (slower_sm
);
435 ActionEntry
*faster_sm
= &(ActionEntry
){
437 "bracketright", "faster-small",
438 "_Faster", "increase playback rate",
439 GTK_STOCK_GO_UP
, accel_group
, action_group
,
440 G_CALLBACK (demo_gui_do_change_rate
),
441 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_DOUBLE
, 1.0594630943593)
443 create_action (faster_sm
);
445 ActionEntry
*faster_lg
= &(ActionEntry
){
447 "braceright", "faster-large",
448 "2X Faster", "double playback rate",
449 GTK_STOCK_GO_UP
, accel_group
, action_group
,
450 G_CALLBACK (demo_gui_do_change_rate
),
451 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_DOUBLE
, 2.0)
453 create_action (faster_lg
);
455 ActionEntry
*rewind_lg
= &(ActionEntry
){
457 "<ctrl><shift>Left", "seek-rewind-large",
458 "Rewind (large)", "seek -30 seconds",
459 GTK_STOCK_MEDIA_REWIND
, accel_group
, action_group
,
460 G_CALLBACK (demo_gui_do_seek
),
461 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_INT
, -30)
463 create_action (rewind_lg
);
465 ActionEntry
*rewind_sm
= &(ActionEntry
){
467 "<ctrl>Left", "seek-rewind-small",
468 "Rewind", "seek -15 seconds",
469 GTK_STOCK_MEDIA_REWIND
, accel_group
, action_group
,
470 G_CALLBACK (demo_gui_do_seek
),
471 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_INT
, -5)
473 create_action (rewind_sm
);
475 ActionEntry
*forward_sm
= &(ActionEntry
){
477 "<ctrl>Right", "seek-forward-small",
478 "Forward", "seek +5 seconds",
479 GTK_STOCK_MEDIA_FORWARD
, accel_group
, action_group
,
480 G_CALLBACK (demo_gui_do_seek
),
481 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_INT
, 5)
483 create_action (forward_sm
);
485 ActionEntry
*forward_lg
= &(ActionEntry
){
487 "<ctrl><shift>Right", "seek-forward-large",
488 "Forward (large)", "seek +30 seconds",
489 GTK_STOCK_MEDIA_FORWARD
, accel_group
, action_group
,
490 G_CALLBACK (demo_gui_do_seek
),
491 build_gvalue_array (2, G_TYPE_OBJECT
, gui
, G_TYPE_INT
, 30)
493 create_action (forward_lg
);
495 GValue
*is_playing
= g_new0 (GValue
, 1);
496 g_value_set_boolean (g_value_init (is_playing
, G_TYPE_BOOLEAN
), TRUE
);
497 ActionEntry
*pause
= &(ActionEntry
){
500 "Pause", "Pause playback",
501 GTK_STOCK_MEDIA_PAUSE
, accel_group
, action_group
,
502 G_CALLBACK (demo_gui_do_pause
), gui
504 create_action (pause
);
506 ActionEntry
*play
= &(ActionEntry
){
509 "Play", "Start Playback",
510 GTK_STOCK_MEDIA_PLAY
, accel_group
, action_group
,
511 G_CALLBACK (demo_gui_do_play
), gui
513 create_action (play
);
514 GtkRequisition pause_size
;
515 gtk_widget_size_request (pause
->button
, &pause_size
);
516 gtk_widget_set_size_request (play
->button
, pause_size
.width
, -1);
518 ActionEntry
*play_pause
= &(ActionEntry
){
520 "space", "play-pause",
521 "Play/Pause", "Toggle playback",
522 NULL
, accel_group
, action_group
,
523 G_CALLBACK (demo_gui_do_play_pause
), gui
525 create_action (play_pause
);
527 ActionEntry
*quit
= &(ActionEntry
){
531 GTK_STOCK_MEDIA_STOP
, accel_group
, action_group
,
532 G_CALLBACK (demo_gui_do_quit
), gui
534 create_action (quit
);
536 GtkWidget
*rate_entry
= gtk_entry_new ();
537 GtkWidget
*rate_label
= gtk_label_new ("Rate:");
538 gtk_entry_set_max_length (GTK_ENTRY (rate_entry
), 5);
539 gtk_entry_set_text (GTK_ENTRY (rate_entry
), "1.0");
540 gtk_entry_set_width_chars (GTK_ENTRY (rate_entry
), 5);
541 g_signal_connect (G_OBJECT (rate_entry
), "activate", G_CALLBACK (demo_gui_do_rate_entered
), gui
);
543 GtkWidget
*menu
= gtk_menu_new ();
544 gtk_menu_set_accel_group (GTK_MENU (menu
), accel_group
);
545 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (faster_lg
->action
));
546 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (faster_sm
->action
));
547 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (slower_sm
->action
));
548 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (slower_lg
->action
));
549 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (rewind_lg
->action
));
550 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (rewind_sm
->action
));
551 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (forward_sm
->action
));
552 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (forward_lg
->action
));
553 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (play
->action
));
554 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (pause
->action
));
555 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (play_pause
->action
));
556 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), gtk_action_create_menu_item (quit
->action
));
557 GtkWidget
*menu_button
= GTK_WIDGET (gtk_menu_tool_button_new (NULL
, "More"));
558 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (menu_button
), menu
);
560 GtkWidget
*toolbox
= gtk_hbox_new (FALSE
, 0);
561 gtk_box_pack_start (GTK_BOX (toolbox
), slower_sm
->button
, FALSE
, FALSE
, 2);
562 gtk_box_pack_start (GTK_BOX (toolbox
), rate_label
, FALSE
, FALSE
, 2);
563 gtk_box_pack_start (GTK_BOX (toolbox
), rate_entry
, FALSE
, FALSE
, 2);
564 gtk_box_pack_start (GTK_BOX (toolbox
), faster_sm
->button
, FALSE
, FALSE
, 2);
565 gtk_box_pack_start (GTK_BOX (toolbox
), pause
->button
, FALSE
, FALSE
, 2);
566 gtk_box_pack_start (GTK_BOX (toolbox
), play
->button
, FALSE
, FALSE
, 2);
567 gtk_box_pack_start (GTK_BOX (toolbox
), menu_button
, FALSE
, FALSE
, 2);
569 GtkWidget
*video_window
= gtk_drawing_area_new ();
570 gtk_drawing_area_size (GTK_DRAWING_AREA (video_window
), 640, 360);
572 GtkWidget
*amount_played
= gtk_label_new ("00:00:00.00");
573 GtkWidget
*amount_to_play
= gtk_label_new ("-00:00:00.00");
574 gtk_label_set_width_chars (GTK_LABEL (amount_played
), 12);
575 gtk_label_set_width_chars (GTK_LABEL (amount_to_play
), 12);
576 gtk_misc_set_alignment (GTK_MISC (amount_played
), 1, 1);
577 gtk_misc_set_alignment (GTK_MISC (amount_to_play
), 0, 1);
578 GtkWidget
*seek_range
= gtk_hscale_new (
579 GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 5.0, 30.0, 0.00)));
580 gtk_range_set_update_policy (GTK_RANGE (seek_range
), GTK_UPDATE_DISCONTINUOUS
);
581 GtkWidget
*seek_bar
= gtk_hbox_new (FALSE
, 0);
582 gtk_box_pack_start (GTK_BOX (seek_bar
), amount_played
, FALSE
, FALSE
, 2);
583 gtk_box_pack_start (GTK_BOX (seek_bar
), seek_range
, TRUE
, TRUE
, 2);
584 gtk_box_pack_start (GTK_BOX (seek_bar
), amount_to_play
, FALSE
, FALSE
, 2);
585 g_signal_connect (G_OBJECT (seek_range
), "format-value", G_CALLBACK (demo_gui_seek_bar_format
), gui
);
586 g_signal_connect (G_OBJECT (seek_range
), "change-value", G_CALLBACK (demo_gui_seek_bar_change
), gui
);
588 GtkWidget
*status_bar
= gtk_statusbar_new ();
590 gtk_window_set_title (GTK_WINDOW (window
), "Scaletempo Demo");
591 GtkWidget
*toplevel_box
= gtk_vbox_new (FALSE
, 0);
592 gtk_container_set_border_width (GTK_CONTAINER (toplevel_box
), 3);
593 gtk_container_add (GTK_CONTAINER (window
), toplevel_box
);
594 gtk_box_pack_start (GTK_BOX (toplevel_box
), toolbox
, FALSE
, FALSE
, 2);
595 gtk_box_pack_start (GTK_BOX (toplevel_box
), video_window
, TRUE
, TRUE
, 2);
596 gtk_box_pack_start (GTK_BOX (toplevel_box
), seek_bar
, FALSE
, FALSE
, 2);
597 gtk_box_pack_start (GTK_BOX (toplevel_box
), status_bar
, FALSE
, FALSE
, 2);
599 priv
->window
= window
;
600 priv
->rate_entry
= GTK_ENTRY (rate_entry
);
601 priv
->status_bar
= GTK_STATUSBAR (status_bar
);
602 priv
->seek_range
= GTK_RANGE (seek_range
);
603 priv
->amount_played
= GTK_LABEL (amount_played
);
604 priv
->amount_to_play
= GTK_LABEL (amount_to_play
);
606 gtk_widget_show_all (window
);
607 status_bar_printf (GTK_STATUSBAR (status_bar
), "Welcome to the Scaletempo demo.");
608 gtk_widget_grab_focus (seek_range
);
611 if (!g_thread_create ((GThreadFunc
)gtk_main
, NULL
, FALSE
, &error
)) {
612 g_signal_emit (gui
, demo_gui_signals
[SIGNAL_ERROR
], 0, error
->message
);
617 /* Method wrappers */
619 demo_gui_set_player (DemoGui
*gui
,
622 g_return_if_fail (DEMO_IS_GUI (gui
));
623 g_return_if_fail (DEMO_IS_PLAYER (player
));
625 DEMO_GUI_GET_CLASS (gui
)->set_player (gui
, player
);
629 demo_gui_set_playlist (DemoGui
*gui
,
632 g_return_if_fail (DEMO_IS_GUI (gui
));
634 DEMO_GUI_GET_CLASS (gui
)->set_playlist (gui
, uris
);
638 demo_gui_show (DemoGui
*gui
)
640 g_return_if_fail (DEMO_IS_GUI (gui
));
642 DEMO_GUI_GET_CLASS (gui
)->show (gui
);
647 /* GObject overrides */
649 demo_gui_get_property (GObject
*object
,
654 //DemoGui *gui = DEMO_GUI (object);
655 switch (property_id
) {
657 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
663 demo_gui_set_property (GObject
*object
,
668 //DemoGui *gui = DEMO_GUI (object);
669 switch (property_id
) {
671 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, property_id
, pspec
);
677 /* GTypeInfo functions */
679 demo_gui_init (GTypeInstance
*instance
,
682 DemoGui
*gui
= (DemoGui
*)instance
;
684 DemoGuiPrivate
*priv
= DEMO_GUI_GET_PRIVATE (gui
);
687 priv
->now_playing
= NULL
;
688 priv
->is_playing
= FALSE
;
690 priv
->rate_entry
= NULL
;
691 priv
->position_updater_id
= 0;
692 priv
->seek_range
= NULL
;
693 priv
->amount_played
= NULL
;
694 priv
->amount_to_play
= NULL
;
698 demo_gui_class_init (gpointer klass
,
701 g_type_class_add_private (klass
, sizeof (DemoGuiPrivate
));
704 DemoGuiClass
*gui_class
= (DemoGuiClass
*)klass
;
705 gui_class
->set_player
= demo_gui_set_player_func
;
706 gui_class
->set_playlist
= demo_gui_set_playlist_func
;
707 gui_class
->show
= demo_gui_show_func
;
710 GObjectClass
*as_object_class
= G_OBJECT_CLASS (klass
);
711 as_object_class
->get_property
= demo_gui_get_property
;
712 as_object_class
->set_property
= demo_gui_set_property
;
717 GType type
= G_TYPE_FROM_CLASS (klass
);
718 demo_gui_signals
[SIGNAL_ERROR
] = g_signal_new ("error", type
,
719 G_SIGNAL_RUN_FIRST
, 0, NULL
, NULL
,
720 g_cclosure_marshal_VOID__STRING
, G_TYPE_NONE
, 1, G_TYPE_STRING
);
722 demo_gui_signals
[SIGNAL_QUITING
] = g_signal_new ("quiting", type
,
723 G_SIGNAL_RUN_FIRST
, 0, NULL
, NULL
,
724 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0, NULL
);
728 demo_gui_get_type (void)
730 static GType type
= 0;
731 if (G_UNLIKELY (type
== 0)) {
732 static const GTypeInfo info
= {
733 sizeof /* Class */ (DemoGuiClass
),
734 (GBaseInitFunc
) NULL
,
735 (GBaseFinalizeFunc
) NULL
,
736 (GClassInitFunc
) demo_gui_class_init
,
737 (GClassFinalizeFunc
) NULL
,
738 (gconstpointer
) NULL
, /* class_data */
739 sizeof /* Instance */ (DemoGui
),
741 (GInstanceInitFunc
) demo_gui_init
,
742 (const GTypeValueTable
*) NULL
744 type
= g_type_register_static (G_TYPE_OBJECT
, "DemoGui", &info
, 0);