[brasero] Fix #559103 - Never change window size because of the preview The preview widget has been refactore



commit db5f81aae2bf065a1390d6bc70fd4ef12764e24e
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date:   Thu Jun 24 20:49:52 2010 +0200

    Fix #559103  - Never change window size because of the preview
    The preview widget has been refactored so it has a constant size.
    Some glitches have been corrected in the process.
    It also removes the last translatable string with tags inside

 libbrasero-burn/brasero-cover.c |   10 +-
 libbrasero-utils/brasero-misc.c |    2 +-
 po/POTFILES.in                  |    1 +
 src/Makefile.am                 |    4 +-
 src/brasero-audio-disc.c        |    5 +-
 src/brasero-layout.c            |   14 +-
 src/brasero-player-bacon.c      |   97 +++-
 src/brasero-player-bacon.h      |    3 +-
 src/brasero-player.c            | 1319 ++++++++++++---------------------------
 src/brasero-player.h            |    7 -
 src/brasero-preview.c           |   16 +-
 src/brasero-project.c           |    4 +-
 src/brasero-song-control.c      |  653 +++++++++++++++++++
 src/brasero-song-control.h      |   78 +++
 src/brasero-split-dialog.c      |   23 +-
 src/brasero-split-dialog.h      |    4 +-
 16 files changed, 1247 insertions(+), 993 deletions(-)
---
diff --git a/libbrasero-burn/brasero-cover.c b/libbrasero-burn/brasero-cover.c
index 754e715..4800d0d 100644
--- a/libbrasero-burn/brasero-cover.c
+++ b/libbrasero-burn/brasero-cover.c
@@ -133,18 +133,20 @@ brasero_jacket_edit_set_audio_tracks_back (BraseroJacketView *back,
 		info = brasero_track_tag_lookup_string (BRASERO_TRACK (track),
 							BRASERO_TRACK_STREAM_ARTIST_TAG);
 		if (info) {
+			gchar *string;
+
 			/* Reminder: if this string happens to be used
 			 * somewhere else in brasero we'll need a
 			 * context with C_() macro */
-			/* Translators: "by" is followed by the name of an artist.
+			/* Translators: %s is the name of the artist.
 			 * This text is the one written on the cover of a disc.
 			 * Before it there is the name of the song.
 			 * I had to break it because it is in a GtkTextBuffer
 			 * and every word has a different tag. */
-			BRASERO_JACKET_EDIT_INSERT_TAGGED_TEXT (buffer, _("by"), "Artist", &start);
-			BRASERO_JACKET_EDIT_INSERT_TAGGED_TEXT (buffer, " ", "Artist", &start);
-			BRASERO_JACKET_EDIT_INSERT_TAGGED_TEXT (buffer, info, "Artist", &start);
+			string = g_strdup_printf (_("by %s"), info);
+			BRASERO_JACKET_EDIT_INSERT_TAGGED_TEXT (buffer, string, "Artist", &start);
 			BRASERO_JACKET_EDIT_INSERT_TAGGED_TEXT (buffer, " ", "Artist", &start);
+			g_free (string);
 		}
 
 		info = brasero_track_tag_lookup_string (BRASERO_TRACK (track),
diff --git a/libbrasero-utils/brasero-misc.c b/libbrasero-utils/brasero-misc.c
index 7242f8d..01ebc20 100644
--- a/libbrasero-utils/brasero-misc.c
+++ b/libbrasero-utils/brasero-misc.c
@@ -341,7 +341,7 @@ brasero_utils_pack_properties_list (const gchar *title, GSList *list)
 		label = gtk_label_new (title);
 		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 		gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-		gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
 		gtk_widget_show (label);
 
 		gtk_box_pack_start (GTK_BOX (vbox), vbox_main, TRUE, TRUE, 0);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5683357..d41245f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -71,6 +71,7 @@ src/brasero-plugin-option.c
 src/brasero-search-entry.c
 src/brasero-search-beagle.c
 src/brasero-song-properties.c
+src/brasero-song-control.c
 src/brasero-utils.c
 src/brasero-data-disc.c
 src/brasero-file-chooser.c
diff --git a/src/Makefile.am b/src/Makefile.am
index e168c4b..424a21d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -120,7 +120,9 @@ brasero_SOURCES = \
 	brasero-search-engine.h        \
 	brasero-search-engine.c        \
 	brasero-drive-settings.h        \
-	brasero-drive-settings.c
+	brasero-drive-settings.c	\
+	brasero-song-control.h        \
+	brasero-song-control.c
 
 if BUILD_PLAYLIST
 brasero_SOURCES += \
diff --git a/src/brasero-audio-disc.c b/src/brasero-audio-disc.c
index 2bee380..9775573 100644
--- a/src/brasero-audio-disc.c
+++ b/src/brasero-audio-disc.c
@@ -1315,7 +1315,10 @@ brasero_audio_disc_split (BraseroAudioDisc *disc)
 	gtk_window_set_position (GTK_WINDOW (toplevel), GTK_WIN_POS_CENTER_ON_PARENT);
 
 	uri = brasero_track_stream_get_source (BRASERO_TRACK_STREAM (track), TRUE);
-	brasero_split_dialog_set_uri (BRASERO_SPLIT_DIALOG (dialog), uri);
+	brasero_split_dialog_set_uri (BRASERO_SPLIT_DIALOG (dialog),
+	                              uri,
+	                              brasero_track_tag_lookup_string (track, BRASERO_TRACK_STREAM_TITLE_TAG),
+	                              brasero_track_tag_lookup_string (track, BRASERO_TRACK_STREAM_ARTIST_TAG));
 	g_free (uri);
 
 	brasero_split_dialog_set_boundaries (BRASERO_SPLIT_DIALOG (dialog),
diff --git a/src/brasero-layout.c b/src/brasero-layout.c
index b4abc15..bc70fd9 100644
--- a/src/brasero-layout.c
+++ b/src/brasero-layout.c
@@ -26,12 +26,12 @@
  * 	Boston, MA  02110-1301, USA.
  */
 
-#include <string.h>
-
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
 
+#include <string.h>
+
 #include <glib.h>
 #include <glib/gi18n-lib.h>
 
@@ -383,8 +383,9 @@ static void
 brasero_layout_set_side_pane_visible (BraseroLayout *layout,
 				      gboolean visible)
 {
-	GtkWidget *parent;
+	BraseroLayoutObject *source;
 	gboolean preview_in_project;
+	GtkWidget *parent;
 	GList *children;
 
 	children = gtk_container_get_children (GTK_CONTAINER (layout->priv->main_box));
@@ -392,6 +393,7 @@ brasero_layout_set_side_pane_visible (BraseroLayout *layout,
 	g_list_free (children);
 
 	parent = gtk_widget_get_parent (layout->priv->main_box);
+	source = brasero_layout_item_get_object (layout->priv->active_item);
 
 	if (!visible) {
 		/* No side pane should be visible */
@@ -412,10 +414,10 @@ brasero_layout_set_side_pane_visible (BraseroLayout *layout,
 
 		brasero_project_set_source (BRASERO_PROJECT (layout->priv->project), NULL);
 		gtk_widget_hide (parent);
+
+		brasero_uri_container_uri_selected (BRASERO_URI_CONTAINER (source));
 	}
 	else {
-		BraseroLayoutObject *source;
-
 		/* The side pane should be visible */
 		if (preview_in_project) {
 			/* we need to unparent the preview widget
@@ -429,7 +431,6 @@ brasero_layout_set_side_pane_visible (BraseroLayout *layout,
 		}
 
 		/* Now tell the project which source it gets URIs from */
-		source = brasero_layout_item_get_object (layout->priv->active_item);
 		if (!BRASERO_IS_URI_CONTAINER (source)) {
 			brasero_project_set_source (BRASERO_PROJECT (layout->priv->project),
 						    NULL);
@@ -921,7 +922,6 @@ brasero_layout_close_button_clicked_cb (GtkWidget *button,
 
 	action = gtk_action_group_get_action (layout->priv->action_group,
 					      BRASERO_LAYOUT_NONE_ID);
-
 	if (!action)
 		return;
 
diff --git a/src/brasero-player-bacon.c b/src/brasero-player-bacon.c
index f77495d..4a8c344 100644
--- a/src/brasero-player-bacon.c
+++ b/src/brasero-player-bacon.c
@@ -112,6 +112,21 @@ brasero_player_bacon_get_property (GObject *obj,
 }
 
 static void
+brasero_player_bacon_unrealize (GtkWidget *widget)
+{
+	BraseroPlayerBacon *bacon;
+
+	bacon = BRASERO_PLAYER_BACON (widget);
+
+	/* Stop the pipeline as otherwise it would try to write video to a destroyed window */
+	gst_element_set_state (bacon->priv->pipe, GST_STATE_READY);
+	bacon->priv->xid = 0;
+
+	if (GTK_WIDGET_CLASS (brasero_player_bacon_parent_class)->unrealize)
+		GTK_WIDGET_CLASS (brasero_player_bacon_parent_class)->unrealize (widget);
+}
+
+static void
 brasero_player_bacon_realize (GtkWidget *widget)
 {
 	GdkWindow *window;
@@ -119,21 +134,34 @@ brasero_player_bacon_realize (GtkWidget *widget)
 	GtkAllocation allocation;
 	GdkWindowAttr attributes;
 	BraseroPlayerBacon *bacon;
+	gfloat screen_width, screen_height, ratio;
 
 	bacon = BRASERO_PLAYER_BACON (widget);
 
 	attributes.window_type = GDK_WINDOW_CHILD;
 
 	gtk_widget_get_allocation (widget, &allocation);
-	attributes.x = 0;
-	attributes.y = 0;
-	attributes.width = allocation.width;
-	attributes.height = allocation.height;
+
+	screen_width = allocation.width;
+	screen_height = allocation.height;
+	
+	if ((gfloat) screen_width / PLAYER_BACON_WIDTH > 
+	    (gfloat) screen_height / PLAYER_BACON_HEIGHT)
+		ratio = (gfloat) screen_height / PLAYER_BACON_HEIGHT;
+	else
+		ratio = (gfloat) screen_width / PLAYER_BACON_WIDTH;
+
+	attributes.x = allocation.x + (allocation.width - (gint) screen_width) / 2;
+	attributes.y = allocation.y + (allocation.height - (gint) screen_height) / 2;
+	attributes.width = screen_width;
+	attributes.height = screen_height;
 	attributes.wclass = GDK_INPUT_OUTPUT;
 	attributes.visual = gtk_widget_get_visual (widget);
 	attributes.colormap = gtk_widget_get_colormap (widget);
 	attributes.event_mask = gtk_widget_get_events (widget);
-	attributes.event_mask |= GDK_EXPOSURE_MASK|GDK_BUTTON_PRESS_MASK;
+	attributes.event_mask |= GDK_EXPOSURE_MASK|
+				 GDK_BUTTON_PRESS_MASK|
+				 GDK_BUTTON_RELEASE_MASK;
 	attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_COLORMAP;
 
 	gtk_widget_set_window (widget, gdk_window_new (gtk_widget_get_parent_window (widget),
@@ -166,9 +194,8 @@ brasero_player_bacon_expose (GtkWidget *widget, GdkEventExpose *event)
 
 	if (bacon->priv->xoverlay
 	&&  GST_IS_X_OVERLAY (bacon->priv->xoverlay)
-	&&  bacon->priv->state >= GST_STATE_PAUSED) {
+	&&  bacon->priv->state >= GST_STATE_PAUSED)
 		gst_x_overlay_expose (bacon->priv->xoverlay);
-	}
 	else if (window)
 		gdk_window_clear (window);
 
@@ -242,9 +269,8 @@ brasero_player_bacon_bus_messages_handler (GstBus *bus,
 	if (!structure)
 		return GST_BUS_PASS;
 
-	if (!gst_structure_has_name (structure, "prepare-xwindow-id")) {
+	if (!gst_structure_has_name (structure, "prepare-xwindow-id"))
 		return GST_BUS_PASS;
-	}
 
 	/* NOTE: apparently GDK does not like to be asked to retrieve the XID
 	 * in a thread so we do it in the callback of the expose event. */
@@ -322,14 +348,15 @@ brasero_player_bacon_set_boundaries (BraseroPlayerBacon *bacon, gint64 start, gi
 }
 
 void
-brasero_player_bacon_set_volume (BraseroPlayerBacon *bacon, gdouble volume)
+brasero_player_bacon_set_volume (BraseroPlayerBacon *bacon,
+                                 gdouble volume)
 {
 	if (!bacon->priv->pipe)
 		return;
 
-	volume = CLAMP (volume, 0, 100) / 100.0;
+	volume = CLAMP (volume, 0, 1.0);
 	g_object_set (bacon->priv->pipe,
-		      "volume", volume * 100,
+		      "volume", volume,
 		      NULL);
 }
 
@@ -345,7 +372,7 @@ brasero_player_bacon_get_volume (BraseroPlayerBacon *bacon)
 		      "volume", &volume,
 		      NULL);
 
-	return volume / 5.0;
+	return volume;
 }
 
 static gboolean
@@ -435,18 +462,45 @@ brasero_player_bacon_stop (BraseroPlayerBacon *bacon)
 }
 
 gboolean
-brasero_player_bacon_set_pos (BraseroPlayerBacon *bacon,
-			      gdouble pos)
+brasero_player_bacon_forward (BraseroPlayerBacon *bacon,
+                              gint64 pos)
 {
-	gint64 duration;
-	GstFormat format = GST_FORMAT_TIME;
+	if (!bacon->priv->pipe)
+		return FALSE;
 
+	return gst_element_seek (bacon->priv->pipe,
+				 1.0,
+				 GST_FORMAT_TIME,
+				 GST_SEEK_FLAG_FLUSH,
+				 GST_SEEK_TYPE_CUR,
+				 pos,
+				 GST_SEEK_TYPE_NONE,
+				 0);
+}
+
+gboolean
+brasero_player_bacon_backward (BraseroPlayerBacon *bacon,
+                               gint64 pos)
+{
 	if (!bacon->priv->pipe)
 		return FALSE;
 
-	gst_element_query_duration (bacon->priv->pipe,
-				    &format,
-				    &duration);
+	return gst_element_seek (bacon->priv->pipe,
+				 1.0,
+				 GST_FORMAT_TIME,
+				 GST_SEEK_FLAG_FLUSH,
+				 GST_SEEK_TYPE_SET,
+				 - pos,
+				 GST_SEEK_TYPE_NONE,
+				 0);
+}
+
+gboolean
+brasero_player_bacon_set_pos (BraseroPlayerBacon *bacon,
+			      gdouble pos)
+{
+	if (!bacon->priv->pipe)
+		return FALSE;
 
 	return gst_element_seek (bacon->priv->pipe,
 				 1.0,
@@ -532,7 +586,7 @@ brasero_player_bacon_setup_pipe (BraseroPlayerBacon *bacon)
 	                           BRASERO_SETTING_PLAYER_VOLUME,
 	                           &value);
 	volume = GPOINTER_TO_INT (value);
-	volume = CLAMP (volume, 0, 500);
+	volume = CLAMP (volume, 0, 100);
 	g_object_set (bacon->priv->pipe,
 		      "volume", (gdouble) volume / 100.0,
 		      NULL);
@@ -621,6 +675,7 @@ brasero_player_bacon_class_init (BraseroPlayerBaconClass *klass)
 
 	widget_class->expose_event = brasero_player_bacon_expose;
 	widget_class->realize = brasero_player_bacon_realize;
+	widget_class->unrealize = brasero_player_bacon_unrealize;
 	widget_class->size_request = brasero_player_bacon_size_request;
 	widget_class->size_allocate = brasero_player_bacon_size_allocate;
 
diff --git a/src/brasero-player-bacon.h b/src/brasero-player-bacon.h
index 38aa145..966b028 100644
--- a/src/brasero-player-bacon.h
+++ b/src/brasero-player-bacon.h
@@ -79,7 +79,8 @@ gboolean brasero_player_bacon_stop (BraseroPlayerBacon *bacon);
 gboolean brasero_player_bacon_set_pos (BraseroPlayerBacon *bacon, gdouble pos);
 gboolean brasero_player_bacon_get_pos (BraseroPlayerBacon *bacon, gint64 *pos);
 gdouble  brasero_player_bacon_get_volume (BraseroPlayerBacon *bacon);
-
+gboolean brasero_player_bacon_forward (BraseroPlayerBacon *bacon, gint64 value);
+gboolean brasero_player_bacon_backward (BraseroPlayerBacon *bacon, gint64 value);
 G_END_DECLS
 
 #endif /* PLAYER_BACON_H */
diff --git a/src/brasero-player.c b/src/brasero-player.c
index aaac67b..cdf5c54 100644
--- a/src/brasero-player.c
+++ b/src/brasero-player.c
@@ -53,34 +53,25 @@
 G_DEFINE_TYPE (BraseroPlayer, brasero_player, GTK_TYPE_ALIGNMENT);
 
 struct BraseroPlayerPrivate {
-	GtkWidget *hbox;
-	GtkWidget *vbox;
-
 	GtkWidget *notebook;
+
 	GtkWidget *bacon;
-	GtkWidget *controls;
+
+	GtkWidget *spinner;
+
+	GtkWidget *play_image;
 
 	gint image_width;
 	gint image_height;
 	GdkPixbuf *pixbuf;
 
-
 	GtkWidget *image_display;
-	GtkWidget *image_event;
-	GtkWidget *image_zoom_in;
-	GtkWidget *image_zoom_out;
+
+	GtkWidget *zoom_in;
+	GtkWidget *zoom_out;
 
 	gint video_width;
 	gint video_height;
-	GtkWidget *video_zoom_in;
-	GtkWidget *video_zoom_out;
-
-	GtkWidget *button;
-	GtkWidget *progress;
-
-	GtkWidget *header;
-	GtkWidget *size;
-	guint update_scale_id;
 
 	BraseroPlayerBaconState state;
 
@@ -90,6 +81,8 @@ struct BraseroPlayerPrivate {
 	gint64 start;
 	gint64 end;
 	gint64 length;
+
+	int is_video:1;
 };
 
 typedef enum {
@@ -103,41 +96,11 @@ static guint brasero_player_signals [LAST_SIGNAL] = { 0 };
 static GObjectClass *parent_class = NULL;
 
 static void
-brasero_player_destroy_controls (BraseroPlayer *player)
-{
-	if (!player->priv->controls)
-		return;
-
-	gtk_box_set_child_packing (GTK_BOX (player->priv->hbox),
-				   gtk_widget_get_parent (player->priv->notebook),
-				   FALSE,
-				   FALSE,
-				   0,
-				   GTK_PACK_START);
-
-	gtk_widget_destroy (player->priv->controls);
-	player->priv->controls = NULL;
-	player->priv->progress = NULL;
-	player->priv->header = NULL;
-	player->priv->button = NULL;
-	player->priv->size = NULL;
-	player->priv->video_zoom_in = NULL;
-	player->priv->video_zoom_out = NULL;
-	player->priv->image_zoom_in = NULL;
-	player->priv->image_zoom_out = NULL;
-}
-
-static void
 brasero_player_no_multimedia_stream (BraseroPlayer *player)
 {
-	if (player->priv->update_scale_id) {
-		g_source_remove (player->priv->update_scale_id);
-		player->priv->update_scale_id = 0;
-	}
-
-	gtk_alignment_set_padding (GTK_ALIGNMENT (player), 0, 0, 0, 0);
-	
-	gtk_widget_hide (player->priv->notebook);
+	gtk_spinner_stop (GTK_SPINNER (player->priv->spinner));
+	gtk_widget_set_has_tooltip (GTK_WIDGET (player), FALSE);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 2);
 
 	player->priv->length = 0;
 	player->priv->start = 0;
@@ -147,475 +110,35 @@ brasero_player_no_multimedia_stream (BraseroPlayer *player)
 static void
 brasero_player_video_zoom_out (BraseroPlayer *player)
 {
-	GtkWidget *parent;
-	gint width, height;
-	GtkAllocation player_allocation, bacon_allocation;
-
-	gtk_widget_set_sensitive (GTK_WIDGET (player->priv->video_zoom_in), TRUE);
-
-	gtk_widget_get_allocation (GTK_WIDGET (player->priv->bacon), &bacon_allocation);
-	width = bacon_allocation.width;
-	height = bacon_allocation.height;
-
-	width -= PLAYER_BACON_WIDTH / 3;
-	height -= PLAYER_BACON_HEIGHT / 3;
-
-	gtk_widget_get_allocation (GTK_WIDGET (player), &player_allocation);
-	parent = gtk_widget_get_parent (player->priv->controls);
-	if (width < player_allocation.width / 2 &&
-	    gtk_widget_get_parent (player->priv->controls) == player->priv->vbox) {
-		g_object_ref (player->priv->controls);
-		gtk_container_remove (GTK_CONTAINER (player->priv->vbox),
-				      player->priv->controls);
-
-		gtk_box_pack_start (GTK_BOX (player->priv->hbox),
-				    player->priv->controls,
-				    TRUE,
-				    TRUE,
-				    0);
-		g_object_unref (player->priv->controls);
-
-		gtk_box_set_child_packing (GTK_BOX (player->priv->hbox),
-					   gtk_widget_get_parent (player->priv->notebook),
-					   FALSE,
-					   FALSE,
-					   0,
-					   GTK_PACK_START);
-	}
+	player->priv->video_width -= PLAYER_BACON_WIDTH / 3;
+	player->priv->video_height -= PLAYER_BACON_HEIGHT / 3;
 
-	if (width <= PLAYER_BACON_WIDTH ||
-	    height <= PLAYER_BACON_HEIGHT) {
-		width = PLAYER_BACON_WIDTH;
-		height = PLAYER_BACON_HEIGHT;
-		gtk_widget_set_sensitive (GTK_WIDGET (player->priv->video_zoom_out), FALSE);
+	if (player->priv->video_width <= PLAYER_BACON_WIDTH ||
+	    player->priv->video_height <= PLAYER_BACON_HEIGHT) {
+		player->priv->video_width = PLAYER_BACON_WIDTH;
+		player->priv->video_height = PLAYER_BACON_HEIGHT;
 	}
 
-	player->priv->video_width = width;
-	player->priv->video_height = height;
-
 	gtk_widget_set_size_request (GTK_WIDGET (player->priv->bacon),
-				     width,
-				     height);
-}
-
-static void
-brasero_player_video_zoom_out_button_cb (GtkButton *button,
-					 BraseroPlayer *player)
-{
-	brasero_player_video_zoom_out (player);
+				     player->priv->video_width,
+				     player->priv->video_height);
 }
 
 static void
 brasero_player_video_zoom_in (BraseroPlayer *player)
 {
-	GtkAllocation player_allocation, bacon_allocation;
-	gint width, height;
-
-	gtk_widget_set_sensitive (GTK_WIDGET (player->priv->video_zoom_out), TRUE);
-
-	gtk_widget_get_allocation (player->priv->bacon, &bacon_allocation);
-	width = bacon_allocation.width;
-	height = bacon_allocation.height;
-
-	width += PLAYER_BACON_WIDTH / 3;
-	height += PLAYER_BACON_HEIGHT / 3;
-
-	gtk_widget_get_allocation (GTK_WIDGET (player), &player_allocation);
-	if (width >= (player_allocation.width / 2) &&
-	    gtk_widget_get_parent (player->priv->controls) == player->priv->hbox) {
-		g_object_ref (player->priv->controls);
-		gtk_container_remove (GTK_CONTAINER (player->priv->hbox),
-				      player->priv->controls);
-
-		gtk_box_pack_start (GTK_BOX (player->priv->vbox),
-				    player->priv->controls,
-				    TRUE,
-				    TRUE,
-				    0);
-		g_object_unref (player->priv->controls);
-
-		gtk_box_set_child_packing (GTK_BOX (player->priv->hbox),
-					   gtk_widget_get_parent (player->priv->notebook),
-					   TRUE,
-					   TRUE,
-					   0,
-					   GTK_PACK_START);
-	}
+	player->priv->video_width += PLAYER_BACON_WIDTH / 3;
+	player->priv->video_height += PLAYER_BACON_HEIGHT / 3;
 
-	if (width >= PLAYER_BACON_WIDTH * 3 ||
-	    height >= PLAYER_BACON_HEIGHT * 3) {
-		width = PLAYER_BACON_WIDTH * 3;
-		height = PLAYER_BACON_HEIGHT * 3;
-		gtk_widget_set_sensitive (GTK_WIDGET (player->priv->video_zoom_in), FALSE);
+	if (player->priv->video_width >= PLAYER_BACON_WIDTH * 3 ||
+	    player->priv->video_height >= PLAYER_BACON_HEIGHT * 3) {
+		player->priv->video_width = PLAYER_BACON_WIDTH * 3;
+		player->priv->video_height = PLAYER_BACON_HEIGHT * 3;
 	}
 
-	player->priv->video_width = width;
-	player->priv->video_height = height;
-
 	gtk_widget_set_size_request (GTK_WIDGET (player->priv->bacon),
-				     width,
-				     height);
-}
-
-static void
-brasero_player_video_zoom_in_button_cb (GtkButton *button,
-					BraseroPlayer *player)
-{
-	brasero_player_video_zoom_in (player);
-}
-
-static gboolean
-brasero_player_video_scroll (BraseroPlayerBacon *bacon,
-			     GdkEventScroll *event,
-			     BraseroPlayer *player)
-{
-	if (event->direction == GDK_SCROLL_UP)
-		brasero_player_video_zoom_in (player);
-	else
-		brasero_player_video_zoom_out (player);
-
-	return TRUE;
-}
-
-static void
-brasero_player_update_position (BraseroPlayer *player)
-{
-	gdouble value;
-	GtkAdjustment *adjustment;
-	gchar *pos_string, *len_string, *result;
-
-	if (!player->priv->progress || !player->priv->size)
-		return;
-
-	adjustment = gtk_range_get_adjustment (GTK_RANGE (player->priv->progress));
-	len_string = brasero_units_get_time_string (player->priv->end - player->priv->start, FALSE, FALSE);
-
-	value = gtk_range_get_value (GTK_RANGE (player->priv->progress));
-	pos_string = brasero_units_get_time_string (value, FALSE, FALSE);
-
-	/**
-	 * Translators: this is the position being played in the stream. The 
-	 * first %s is the position and the second %s is the whole length of
-	 * the stream. I chose to make that translatable in case some languages
-	 * don't allow the "/" */
-	result = g_strdup_printf (_("%s / %s"), pos_string, len_string);
-	g_free (len_string);
-	g_free (pos_string);
-
-	gtk_label_set_text (GTK_LABEL (player->priv->size), result);
-	g_free (result);
-}
-
-static void
-brasero_player_range_value_changed (GtkRange *range,
-				    BraseroPlayer *player)
-{
-	if (player->priv->state >= BACON_STATE_PAUSED && !player->priv->update_scale_id) {
-		gdouble pos;
-
-		/* user changed the value tell the player/pipeline */
-		pos = gtk_range_get_value (GTK_RANGE (player->priv->progress));
-		brasero_player_bacon_set_pos (BRASERO_PLAYER_BACON (player->priv->bacon), (gint64) pos + player->priv->start);
-	}
-
-	brasero_player_update_position (player);
-}
-
-static void
-brasero_player_set_length (BraseroPlayer *player)
-{
-	if (player->priv->progress && player->priv->end - player->priv->start != 0)
-		gtk_range_set_range (GTK_RANGE (player->priv->progress),
-				     0.0,
-				     (gdouble) player->priv->end - player->priv->start);
-
-	brasero_player_update_position (player);
-}
-
-static gboolean
-brasero_player_update_progress_cb (BraseroPlayer *player)
-{
-	gint64 pos;
-
-	if (brasero_player_bacon_get_pos (BRASERO_PLAYER_BACON (player->priv->bacon), &pos) == TRUE) {
-		gtk_range_set_value (GTK_RANGE (player->priv->progress), (gdouble) pos - player->priv->start);
-
-		/* This is done on purpose with videos it wouldn't redraw automatically 
-		 * I don't know why */
-		gtk_widget_queue_draw (GTK_WIDGET (player->priv->progress));
-	}
-
-	return TRUE;
-}
-
-static gboolean
-brasero_player_range_button_pressed_cb (GtkWidget *widget,
-					GdkEvent *event,
-					BraseroPlayer *player)
-{
-	/* stop the automatic update of progress bar position */
-	if (player->priv->update_scale_id) {
-		g_source_remove (player->priv->update_scale_id);
-		player->priv->update_scale_id = 0;
-	}
-
-	return FALSE;
-}
-
-static gboolean
-brasero_player_range_button_released_cb (GtkWidget *widget,
-					 GdkEvent *event,
-					 BraseroPlayer *player)
-{
-	/* restart the automatic update of progress bar */
-	if (player->priv->state == BACON_STATE_PLAYING && !player->priv->update_scale_id)
-		player->priv->update_scale_id = g_timeout_add (500,
-							       (GSourceFunc) brasero_player_update_progress_cb,
-							       player);
-
-	return FALSE;
-}
-
-static void
-brasero_player_button_clicked_cb (GtkButton *button,
-				  BraseroPlayer *player)
-{
-	if (player->priv->state == BACON_STATE_READY) {
-		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 2);
-		brasero_player_bacon_set_uri (BRASERO_PLAYER_BACON (player->priv->bacon), player->priv->uri);
-		brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
-	}
-	else if (player->priv->state == BACON_STATE_PAUSED)
-		brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
-	else if (player->priv->state == BACON_STATE_PLAYING)
-		brasero_player_bacon_stop (BRASERO_PLAYER_BACON (player->priv->bacon));
-}
-
-static void
-brasero_player_volume_changed_cb (GtkScaleButton *button,
-				  gdouble volume,
-				  BraseroPlayer *player)
-{
-	brasero_player_bacon_set_volume (BRASERO_PLAYER_BACON (player->priv->bacon),
-					 volume);
-}
-
-static void
-brasero_player_create_controls_stream (BraseroPlayer *player,
-				       gboolean video)
-{
-	GtkAllocation allocation;
-	GtkWidget *box = NULL;
-	GtkWidget *header_box;
-	GtkWidget *alignment;
-	GtkWidget *volume;
-	GtkWidget *image;
-	
-	if (player->priv->controls)
-		brasero_player_destroy_controls (player);
-
-	player->priv->controls = gtk_vbox_new (FALSE, 4);
-
-	/* first line title */
-	header_box = gtk_hbox_new (FALSE, 12);
-	gtk_box_pack_start (GTK_BOX (player->priv->controls),
-			    header_box,
-			    FALSE,
-			    FALSE,
-			    0);
-	
-	player->priv->header = gtk_label_new (_("No file"));
-	gtk_label_set_use_markup (GTK_LABEL (player->priv->header), TRUE);
-	gtk_label_set_justify (GTK_LABEL (player->priv->header), GTK_JUSTIFY_LEFT);
-	gtk_misc_set_alignment (GTK_MISC (player->priv->header), 0.0, 0.5);
-	gtk_box_pack_start (GTK_BOX (header_box),
-			    player->priv->header,
-			    TRUE,
-			    TRUE,
-			    0);
-
-	player->priv->size = gtk_label_new (NULL);
-	gtk_widget_get_allocation (GTK_WIDGET (player), &allocation);
-	if (allocation.width > allocation.height) {
-		gtk_label_set_justify (GTK_LABEL (player->priv->size), GTK_JUSTIFY_RIGHT);
-		gtk_misc_set_alignment (GTK_MISC (player->priv->size), 1.0, 0.0);
-
-		gtk_box_pack_start (GTK_BOX (header_box),
-				    player->priv->size,
-				    FALSE,
-				    FALSE,
-				    0);
-	}
-	else {
-		gtk_label_set_justify (GTK_LABEL (player->priv->size), GTK_JUSTIFY_LEFT);
-		gtk_misc_set_alignment (GTK_MISC (player->priv->size), 0.0, 0.0);
-
-		gtk_box_pack_start (GTK_BOX (player->priv->controls),
-				    player->priv->size,
-				    FALSE,
-				    FALSE,
-				    0);
-	}
-	
-	/* second line : play, progress, volume button */
-	box = gtk_hbox_new (FALSE, 12);
-	gtk_box_pack_start (GTK_BOX (player->priv->controls),
-			    box,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
-	player->priv->button = gtk_toggle_button_new ();
-	gtk_widget_set_tooltip_text (player->priv->button, _("Start and stop playing"));
-	gtk_container_add (GTK_CONTAINER (alignment), player->priv->button);
-	gtk_box_pack_start (GTK_BOX (box),
-			    alignment,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
-	gtk_container_add (GTK_CONTAINER (player->priv->button), image);
-	g_signal_connect (G_OBJECT (player->priv->button), "clicked",
-			  G_CALLBACK (brasero_player_button_clicked_cb),
-			  player);
-
-	player->priv->progress = gtk_hscale_new_with_range (0, 1, 500000000);
-	gtk_scale_set_digits (GTK_SCALE (player->priv->progress), 0);
-	gtk_scale_set_draw_value (GTK_SCALE (player->priv->progress), FALSE);
-	gtk_widget_set_size_request (player->priv->progress, 80, -1);
-	gtk_range_set_update_policy (GTK_RANGE (player->priv->progress), GTK_UPDATE_CONTINUOUS);
-	gtk_box_pack_start (GTK_BOX (box),
-			  player->priv->progress,
-			  TRUE,
-			  TRUE,
-			  0);
-
-	g_signal_connect (G_OBJECT (player->priv->progress),
-			  "button-press-event",
-			  G_CALLBACK (brasero_player_range_button_pressed_cb), player);
-	g_signal_connect (G_OBJECT (player->priv->progress),
-			  "button-release-event",
-			  G_CALLBACK (brasero_player_range_button_released_cb), player);
-	g_signal_connect (G_OBJECT (player->priv->progress),
-			  "value-changed",
-			  G_CALLBACK (brasero_player_range_value_changed),
-			  player);
-
-	volume = gtk_volume_button_new ();
-	gtk_widget_show (volume);
-	gtk_box_pack_start (GTK_BOX (box),
-			    volume,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	if (player->priv->bacon)
-		gtk_scale_button_set_value (GTK_SCALE_BUTTON (volume),
-					    brasero_player_bacon_get_volume (BRASERO_PLAYER_BACON (player->priv->bacon)));
-
-	g_signal_connect (volume,
-			  "value-changed",
-			  G_CALLBACK (brasero_player_volume_changed_cb),
-			  player);
-
-	/* zoom in/out, only if video */
-	if (video) {
-		GtkWidget *image;
-		GtkWidget *zoom;
-		GtkWidget *hbox;
-
-		box = gtk_hbox_new (FALSE, 12);
-		gtk_box_pack_start (GTK_BOX (player->priv->controls),
-				    box,
-				    FALSE,
-				    FALSE,
-				    0);
-
-		hbox = gtk_hbox_new (FALSE, 0);
-		alignment = gtk_alignment_new (1.0, 0.0, 0.0, 0.0);
-
-		gtk_container_add (GTK_CONTAINER (alignment), hbox);
-		gtk_box_pack_start (GTK_BOX (box),
-				    alignment,
-				    TRUE,
-				    TRUE,
-				    0);
-		
-		image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_BUTTON);
-		zoom = gtk_button_new ();
-		gtk_button_set_image (GTK_BUTTON (zoom), image);
-		gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
-		gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
-		g_signal_connect (zoom,
-				  "clicked",
-				  G_CALLBACK (brasero_player_video_zoom_out_button_cb),
-				  player);
-		gtk_box_pack_start (GTK_BOX (hbox),
-				    zoom,
-				    FALSE,
-				    FALSE,
-				    0);
-		player->priv->video_zoom_out = zoom;
-
-		image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_BUTTON);
-		zoom = gtk_button_new ();
-		gtk_button_set_image (GTK_BUTTON (zoom), image);
-		gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
-		gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
-		g_signal_connect (zoom,
-				  "clicked",
-				  G_CALLBACK (brasero_player_video_zoom_in_button_cb),
-				  player);
-		gtk_box_pack_start (GTK_BOX (hbox),
-				    zoom,
-				    FALSE,
-				    FALSE,
-				    0);
-		player->priv->video_zoom_in = zoom;
-
-		if (player->priv->video_height <= PLAYER_BACON_HEIGHT
-		||  player->priv->video_width  <= PLAYER_BACON_WIDTH)
-			gtk_widget_set_sensitive (player->priv->video_zoom_out, FALSE);
-		else
-			gtk_widget_set_sensitive (player->priv->video_zoom_out, TRUE);
-
-		if (player->priv->video_height >= PLAYER_BACON_HEIGHT * 3
-		||  player->priv->video_width  >= PLAYER_BACON_WIDTH * 3)
-			gtk_widget_set_sensitive (player->priv->video_zoom_in, FALSE);
-		else
-			gtk_widget_set_sensitive (player->priv->video_zoom_in, TRUE);
-
-		if (player->priv->video_width >= (allocation.width / 2)) {
-			gtk_box_pack_start (GTK_BOX (player->priv->vbox),
-					    player->priv->controls,
-					    TRUE,
-					    TRUE,
-					    0);
-			gtk_box_set_child_packing (GTK_BOX (player->priv->hbox),
-						   gtk_widget_get_parent (player->priv->notebook),
-						   TRUE,
-						   TRUE,
-						   0,
-						   GTK_PACK_START);
-		}
-		else if (player->priv->video_width < (allocation.width / 2))
-			gtk_box_pack_start (GTK_BOX (player->priv->hbox),
-					    player->priv->controls,
-					    TRUE,
-					    TRUE,
-					    0);
-	}
-	else
-		gtk_box_pack_end (GTK_BOX (player->priv->hbox),
-				  player->priv->controls,
-				  TRUE,
-				  TRUE,
-				  0);
-
-	gtk_widget_show_all (player->priv->controls);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (player), 12, 0, 0, 0);
+				     player->priv->video_width,
+				     player->priv->video_height);
 }
 
 static gboolean
@@ -657,26 +180,17 @@ brasero_player_scale_image (BraseroPlayer *player)
 static void
 brasero_player_image_zoom_in (BraseroPlayer *player)
 {
-	gtk_widget_set_sensitive (player->priv->image_zoom_out, TRUE);
-
 	player->priv->image_width += PLAYER_BACON_WIDTH / 3;
 	player->priv->image_height += PLAYER_BACON_HEIGHT / 3;
 
 	if (player->priv->image_width >= PLAYER_BACON_WIDTH * 3 ||
 	    player->priv->image_height >= PLAYER_BACON_HEIGHT * 3) {
-		gtk_widget_set_sensitive (player->priv->image_zoom_in, FALSE);
 		player->priv->image_width = PLAYER_BACON_WIDTH * 3;
 		player->priv->image_height = PLAYER_BACON_HEIGHT * 3;
 	}
 
-	brasero_player_scale_image (player);
-}
-
-static void
-brasero_player_image_zoom_in_button_cb (GtkButton *button,
-					BraseroPlayer *player)
-{
-	brasero_player_image_zoom_in (player);
+	if (player->priv->pixbuf)
+		brasero_player_scale_image (player);
 }
 
 static void
@@ -684,10 +198,14 @@ brasero_player_image_zoom_out (BraseroPlayer *player)
 {
 	gint min_height, min_width;
 
-	gtk_widget_set_sensitive (player->priv->image_zoom_in, TRUE);
-
-	min_width = MIN (PLAYER_BACON_WIDTH, gdk_pixbuf_get_width (player->priv->pixbuf));
-	min_height = MIN (PLAYER_BACON_HEIGHT, gdk_pixbuf_get_height (player->priv->pixbuf));
+	if (player->priv->pixbuf) {
+		min_width = MIN (PLAYER_BACON_WIDTH, gdk_pixbuf_get_width (player->priv->pixbuf));
+		min_height = MIN (PLAYER_BACON_HEIGHT, gdk_pixbuf_get_height (player->priv->pixbuf));
+	}
+	else {
+		min_width = PLAYER_BACON_WIDTH;
+		min_height = PLAYER_BACON_HEIGHT;
+	}
 
 	player->priv->image_width -= PLAYER_BACON_WIDTH / 3;
 	player->priv->image_height -= PLAYER_BACON_HEIGHT / 3;
@@ -695,127 +213,161 @@ brasero_player_image_zoom_out (BraseroPlayer *player)
 	/* the image itself */
 	if (player->priv->image_width <= min_width ||
 	    player->priv->image_height <= min_height) {
-		gtk_widget_set_sensitive (player->priv->image_zoom_out, FALSE);
 		player->priv->image_width = min_width;
 		player->priv->image_height = min_height;
 	}
 
-	brasero_player_scale_image (player);
+	if (player->priv->pixbuf)
+		brasero_player_scale_image (player);
+}
+
+static void
+brasero_player_zoom_in_cb (GtkButton *button,
+                           BraseroPlayer *player)
+{
+	brasero_player_image_zoom_in (player);
+	brasero_player_video_zoom_in (player);
 }
 
 static void
-brasero_player_image_zoom_out_button_cb (GtkButton *button,
-					 BraseroPlayer *player)
+brasero_player_zoom_out_cb (GtkButton *button,
+                            BraseroPlayer *player)
 {
 	brasero_player_image_zoom_out (player);
+	brasero_player_video_zoom_out (player);
+}
+
+static gboolean
+brasero_bacon_scroll (BraseroPlayerBacon *bacon,
+                      GdkEventScroll *event,
+                      BraseroPlayer *player)
+{
+	switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (player->priv->notebook))) {
+	case 1:
+	case 4:
+		if (event->direction == GDK_SCROLL_UP)
+			brasero_player_bacon_forward (bacon, GST_SECOND);
+		else
+			brasero_player_bacon_backward (bacon, GST_SECOND);
+		break;
+
+	case 0:
+	case 2:
+	case 3:
+	default:
+		if (event->direction == GDK_SCROLL_UP) {
+			brasero_player_image_zoom_in (player);
+			brasero_player_video_zoom_in (player);
+		}
+		else {
+			brasero_player_image_zoom_out (player);
+			brasero_player_video_zoom_out (player);
+		}
+		break;
+	}
+
+	return TRUE;
 }
 
 static gboolean
-brasero_player_image_scroll (BraseroPlayerBacon *bacon,
-			     GdkEventScroll *event,
-			     BraseroPlayer *player)
+brasero_bacon_button_release (BraseroPlayerBacon *bacon,
+                              GdkEventButton *event,
+                              BraseroPlayer *player)
 {
-	if (event->direction == GDK_SCROLL_UP)
-		brasero_player_image_zoom_in (player);
-	else
-		brasero_player_image_zoom_out (player);
+	if (event->button != 1)
+		return FALSE;
+
+	if (player->priv->state == BACON_STATE_READY) {
+		/* This will probably never happen as we display a play button */
+		gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 1);
+		brasero_player_bacon_set_uri (BRASERO_PLAYER_BACON (player->priv->bacon), player->priv->uri);
+		brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
+	}
+	else if (player->priv->state == BACON_STATE_PAUSED) {
+		gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 1);
+		brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
+	}
+	else if (player->priv->state == BACON_STATE_PLAYING) {
+		gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_DIALOG);
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 4);
+		brasero_player_bacon_stop (BRASERO_PLAYER_BACON (player->priv->bacon));
+	}
 
 	return TRUE;
 }
 
-static void
-brasero_player_create_controls_image (BraseroPlayer *player)
+static gboolean
+brasero_player_button_release (GtkWidget *widget,
+                               GdkEventButton *event,
+                               BraseroPlayer *player)
 {
-	GtkWidget *box, *zoom;
-	GtkWidget *image;
-	GtkAllocation allocation;
+	if (event->button != 1)
+		return FALSE;
 
-	if (player->priv->image_display)
-		gtk_widget_set_sensitive (player->priv->image_display, TRUE);
+	if (gtk_notebook_get_current_page (GTK_NOTEBOOK (player->priv->notebook)) == 4) {
+		if (player->priv->state == BACON_STATE_READY) {
+			gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_DIALOG);
+			if (player->priv->is_video)
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 1);
 
-	player->priv->controls = gtk_vbox_new (FALSE, 4);
+			brasero_player_bacon_set_uri (BRASERO_PLAYER_BACON (player->priv->bacon), player->priv->uri);
+			brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
+		}
+		else if (player->priv->state == BACON_STATE_PAUSED) {
+			gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_DIALOG);
+			if (player->priv->is_video)
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 1);
 
-	gtk_widget_get_allocation (GTK_WIDGET (player), &allocation);
-	if (allocation.width > allocation.height)
-		gtk_box_pack_end (GTK_BOX (player->priv->hbox),
-				  player->priv->controls,
-				  TRUE,
-				  TRUE,
-				  0);
-	else
-		gtk_box_pack_end (GTK_BOX (player->priv->vbox),
-				  player->priv->controls,
-				  TRUE,
-				  TRUE,
-				  0);
-
-	player->priv->header = gtk_label_new (NULL);
-	gtk_misc_set_alignment (GTK_MISC (player->priv->header), 0.0, 0.5);
-	gtk_box_pack_start (GTK_BOX (player->priv->controls),
-			    player->priv->header,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	player->priv->size = gtk_label_new (NULL);
-	gtk_misc_set_alignment (GTK_MISC (player->priv->size), 0.0, 0.5);
-	gtk_box_pack_start (GTK_BOX (player->priv->controls),
-			    player->priv->size,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	box = gtk_hbox_new (FALSE, 0);
-	gtk_box_pack_start (GTK_BOX (player->priv->controls),
-			    box,
-			    FALSE,
-			    FALSE,
-			    0);
+			brasero_player_bacon_play (BRASERO_PLAYER_BACON (player->priv->bacon));
+		}
+		else if (player->priv->state == BACON_STATE_PLAYING) {
+			gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+			brasero_player_bacon_stop (BRASERO_PLAYER_BACON (player->priv->bacon));
+		}
+	}
 
-	image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_BUTTON);
-	zoom = gtk_button_new ();
-	gtk_button_set_image (GTK_BUTTON (zoom), image);
-	gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
-	gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
-	g_signal_connect (zoom,
-			  "clicked",
-			  G_CALLBACK (brasero_player_image_zoom_out_button_cb),
-			  player);
-	gtk_box_pack_start (GTK_BOX (box),
-			    zoom,
-			    FALSE,
-			    FALSE,
-			    0);
-	player->priv->image_zoom_out = zoom;
+	return TRUE;
+}
 
-	image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_BUTTON);
-	zoom = gtk_button_new ();
-	gtk_button_set_image (GTK_BUTTON (zoom), image);
-	gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
-	gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
-	g_signal_connect (zoom,
-			  "clicked",
-			  G_CALLBACK (brasero_player_image_zoom_in_button_cb),
-			  player);
-	gtk_box_pack_start (GTK_BOX (box),
-			    zoom,
-			    FALSE,
-			    FALSE,
-			    0);
-	player->priv->image_zoom_in = zoom;
-
-	gtk_widget_show_all (player->priv->controls);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (player), 12, 0, 0, 0);
+static gboolean
+brasero_player_scroll (GtkWidget *widget,
+                       GdkEventScroll *event,
+                       BraseroPlayer *player)
+{
+	switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (player->priv->notebook))) {
+	case 1:
+	case 4:
+		if (event->direction == GDK_SCROLL_UP)
+			brasero_player_bacon_forward (BRASERO_PLAYER_BACON (player->priv->bacon), GST_SECOND);
+		else
+			brasero_player_bacon_backward (BRASERO_PLAYER_BACON (player->priv->bacon), GST_SECOND);
+		break;
+
+	case 0:
+	case 2:
+	case 3:
+	default:
+		if (event->direction == GDK_SCROLL_UP) {
+			brasero_player_image_zoom_in (player);
+			brasero_player_video_zoom_in (player);
+		}
+		else {
+			brasero_player_image_zoom_out (player);
+			brasero_player_video_zoom_out (player);
+		}
+		break;
+	}
+
+	return TRUE;
 }
 
 static void
 brasero_player_image (BraseroPlayer *player)
 {
 	GError *error = NULL;
-	gint width, height;
-	gchar *string;
 	gchar *path;
-	gchar *name;
 
 	if (player->priv->pixbuf) {
 		g_object_unref (player->priv->pixbuf);
@@ -834,89 +386,68 @@ brasero_player_image (BraseroPlayer *player)
 		}
 
 		brasero_player_no_multimedia_stream (player);
-
 		g_free (path);
 		return;
 	}
-
-	height = gdk_pixbuf_get_height (player->priv->pixbuf);
-	width = gdk_pixbuf_get_width (player->priv->pixbuf);
-
+	
 	brasero_player_scale_image (player);
 
-	/* display information about the image */
-	brasero_player_create_controls_image (player);
-
-	if (player->priv->image_height <= MIN (PLAYER_BACON_HEIGHT, gdk_pixbuf_get_height (player->priv->pixbuf))
-	||  player->priv->image_width  <= MIN (PLAYER_BACON_WIDTH, gdk_pixbuf_get_width (player->priv->pixbuf)))
-		gtk_widget_set_sensitive (player->priv->image_zoom_out, FALSE);
-	else
-		gtk_widget_set_sensitive (player->priv->image_zoom_out, TRUE);
-
-	if (player->priv->image_height >= PLAYER_BACON_HEIGHT * 3
-	||  player->priv->image_width  >= PLAYER_BACON_WIDTH * 3)
-		gtk_widget_set_sensitive (player->priv->image_zoom_in, FALSE);
-	else
-		gtk_widget_set_sensitive (player->priv->image_zoom_in, TRUE);
-
-	BRASERO_GET_BASENAME_FOR_DISPLAY (path, name);
-	g_free (path);
-
-	string = g_strdup_printf ("<span weight=\"bold\">%s</span>\t %s",
-				  _("Name:"),
-				  name);
-	g_free (name);
-
-	gtk_label_set_markup (GTK_LABEL (player->priv->header), string);
-	g_free (string);
-
-	string = g_strdup_printf (_("<span weight=\"bold\">Size:</span>\t<i><span size=\"smaller\"> %i \303\227 %i pixels</span></i>"), width, height);
-	gtk_label_set_markup (GTK_LABEL (player->priv->size), string);
-	g_free (string);
-
-	gtk_widget_hide (player->priv->bacon);
-	gtk_widget_show (player->priv->image_event);
 	gtk_widget_show (player->priv->notebook);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (player), 12, 0, 0, 0);
-
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 0);
 	g_signal_emit (player,
 		       brasero_player_signals [READY_SIGNAL],
 		       0);
 }
 
 static void
-brasero_player_update_info_real (BraseroPlayer *player,
-				 const gchar *artist,
-				 const gchar *title)
+brasero_player_update_tooltip (BraseroPlayer *player,
+                               GFileInfo *info)
 {
-	gchar *header;
-
-	brasero_player_set_length (player);
-	if (artist && title) {
-		header = g_markup_printf_escaped (_("<span weight=\"bold\">%s</span>\nby <span size=\"smaller\"><i>%s</i></span>"),
-						  title,
-						  artist);
-		gtk_label_set_ellipsize (GTK_LABEL (player->priv->header),
-					 PANGO_ELLIPSIZE_END);
-
-	}
-	else if (title) {
-		header = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>\n", title);
-		gtk_label_set_ellipsize (GTK_LABEL (player->priv->header),
-					 PANGO_ELLIPSIZE_END);
-	}
+	gchar *string;
+	gchar *len_string;
+	const gchar *title;
+	const gchar *artist;
+
+	/* Update the tooltip */
+	len_string = brasero_units_get_time_string (g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN), TRUE, FALSE);
+	title = g_file_info_get_attribute_string (info, BRASERO_IO_TITLE);
+	artist = g_file_info_get_attribute_string (info, BRASERO_IO_ARTIST);
+	if (artist) {
+		gchar *artist_string;
+
+		/* Translators: %s is the name of the artist */
+		artist_string = g_strdup_printf (_("by %s"), artist);
+		string = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>"
+		                                  "\n<i><span size=\"smaller\">%s</span></i>"
+		                                  "\n%s",
+		                                  title,
+		                                  artist_string,
+		                                  len_string);
+		g_free (artist_string);
+	}
+	else if (title)
+		string = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>"
+		                                  "\n%s",
+		                                  title,
+		                                  len_string);
 	else {
 		gchar *name;
-
-	    	BRASERO_GET_BASENAME_FOR_DISPLAY (player->priv->uri, name);
-		header = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>\n", name);
+		gchar *unescaped_uri;
+
+		unescaped_uri = g_uri_unescape_string (player->priv->uri, NULL);
+		name = g_path_get_basename (unescaped_uri);
+		g_free (unescaped_uri);
+		string = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>"
+		                                  "\n%s",
+		                                  name,
+		                                  len_string);
 		g_free (name);
-		gtk_label_set_ellipsize (GTK_LABEL (player->priv->header),
-					 PANGO_ELLIPSIZE_END);
 	}
 
-	gtk_label_set_markup (GTK_LABEL (player->priv->header), header);
-	g_free (header);
+	g_free (len_string);
+
+	gtk_widget_set_tooltip_markup (GTK_WIDGET (player), string);
+	g_free (string);
 }
 
 static void
@@ -929,15 +460,14 @@ brasero_player_metadata_completed (GObject *obj,
 	BraseroPlayer *player = BRASERO_PLAYER (obj);
 	const gchar *mime;
 
+	gtk_spinner_stop (GTK_SPINNER (player->priv->spinner));
+
 	if (player->priv->pixbuf) {
 		gtk_image_set_from_pixbuf (GTK_IMAGE (player->priv->image_display), NULL);
 		g_object_unref (player->priv->pixbuf);
 		player->priv->pixbuf = NULL;
 	}
 
-	if (player->priv->controls)
-		brasero_player_destroy_controls (player);
-
 	if (error) {
 		brasero_player_no_multimedia_stream (player);
 		g_signal_emit (player,
@@ -958,17 +488,12 @@ brasero_player_metadata_completed (GObject *obj,
 			return;
 		}
 
-		/* video */
-		brasero_player_create_controls_stream (player, TRUE);
-		gtk_range_set_value (GTK_RANGE (player->priv->progress), 0.0);
-		if (g_file_info_get_attribute_boolean (info,BRASERO_IO_IS_SEEKABLE))
-			gtk_widget_set_sensitive (player->priv->progress, TRUE);
-		else
-			gtk_widget_set_sensitive (player->priv->progress, FALSE);
+		/* video: display play button first */
+		player->priv->is_video = TRUE;
+		gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 4);
 
-		gtk_widget_show (player->priv->bacon);
-		gtk_widget_hide (player->priv->image_event);
-		gtk_widget_show (player->priv->notebook);
+		brasero_player_update_tooltip (player, info);
 	}
 	else if (g_file_info_get_attribute_boolean (info, BRASERO_IO_HAS_AUDIO)) {
 		if (g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN) <= 0) {
@@ -979,17 +504,21 @@ brasero_player_metadata_completed (GObject *obj,
 			return;
 		}
 
-		/* audio */
-		brasero_player_create_controls_stream (player, FALSE);
-		gtk_widget_hide (player->priv->notebook);
-		gtk_range_set_value (GTK_RANGE (player->priv->progress), 0.0);
+		/* Audio */
+		player->priv->is_video = FALSE;
+		gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 4);
 
-		if (g_file_info_get_attribute_boolean (info, BRASERO_IO_IS_SEEKABLE))
-			gtk_widget_set_sensitive (player->priv->progress, TRUE);
-		else
-			gtk_widget_set_sensitive (player->priv->progress, FALSE);
+		brasero_player_update_tooltip (player, info);
 	}
 	else if (mime && !strncmp ("image/", mime, 6)) {
+		gchar *size_string;
+		gchar *string;
+		gchar *path;
+		gchar *name;
+		gint height;
+		gint width;
+
 		/* Only do that if the image is < 20 M otherwise that's crap
 		 * FIXME: maybe a sort of error message here? or use thumbnail? */
 		if (g_file_info_get_size (info) > 100000000LL) {
@@ -997,10 +526,28 @@ brasero_player_metadata_completed (GObject *obj,
 			g_signal_emit (player,
 				       brasero_player_signals [ERROR_SIGNAL],
 				       0);
+			return;
 		}
-		else
-			brasero_player_image (player);
 
+		brasero_player_image (player);
+
+		path = g_filename_from_uri (player->priv->uri, NULL, NULL);
+		BRASERO_GET_BASENAME_FOR_DISPLAY (path, name);
+		g_free (path);
+
+		height = gdk_pixbuf_get_height (player->priv->pixbuf);
+		width = gdk_pixbuf_get_width (player->priv->pixbuf);
+		size_string = g_strdup_printf (_("%i \303\227 %i pixels"), width, height);
+
+		string = g_strdup_printf ("<span weight=\"bold\">%s</span>\n"
+		                          "<i><span size=\"smaller\">%s</span></i>",
+		                          name,
+		                          size_string);
+		g_free (name);
+		g_free (size_string);
+
+		gtk_widget_set_tooltip_markup (GTK_WIDGET (player), string);
+		g_free (string);
 		return;
 	}
 	else {
@@ -1016,11 +563,6 @@ brasero_player_metadata_completed (GObject *obj,
 
 	player->priv->length = g_file_info_get_attribute_uint64 (info, BRASERO_IO_LEN);
 
-	/* only reached for audio/video */
-	brasero_player_update_info_real (player,
-					 g_file_info_get_attribute_string (info, BRASERO_IO_ARTIST),
-					 g_file_info_get_attribute_string (info, BRASERO_IO_TITLE));
-
 	player->priv->state = BACON_STATE_READY;
 	g_signal_emit (player,
 		       brasero_player_signals [READY_SIGNAL],
@@ -1043,12 +585,6 @@ brasero_player_retrieve_metadata (BraseroPlayer *player)
 				  NULL);
 }
 
-const gchar *
-brasero_player_get_uri (BraseroPlayer *player)
-{
-	return player->priv->uri;
-}
-
 void
 brasero_player_set_boundaries (BraseroPlayer *player, 
 			       gint64 start,
@@ -1064,11 +600,6 @@ brasero_player_set_boundaries (BraseroPlayer *player,
 	else
 		player->priv->end = end;
 
-	if (player->priv->progress) {
-		brasero_player_set_length (player);
-		gtk_range_set_value (GTK_RANGE (player->priv->progress), 0);
-	}
-
 	if (player->priv->bacon)
 		brasero_player_bacon_set_boundaries (BRASERO_PLAYER_BACON (player->priv->bacon),
 						     player->priv->start,
@@ -1079,26 +610,19 @@ void
 brasero_player_set_uri (BraseroPlayer *player,
 			const gchar *uri)
 {
-	gchar *name;
-
 	/* avoid reloading everything if it's the same uri */
-	if (uri && player->priv->uri
-	&& !strcmp (uri, player->priv->uri)) {
+	if (!g_strcmp0 (uri, player->priv->uri)) {
 		/* if it's not loaded yet just return */
-		if (!player->priv->controls)
-			return;
-
-		if (player->priv->progress) {
-			brasero_player_bacon_set_uri (BRASERO_PLAYER_BACON (player->priv->bacon), uri);
-			brasero_player_set_boundaries (player, -1, -1);
-
-			/* the existence of progress is the surest way to know
-			 * if that uri was successfully loaded */
+		/* the existence of progress is the surest way to know
+		 * if that uri was successfully loaded */
+		if (uri)
 			g_signal_emit (player,
 				       brasero_player_signals [READY_SIGNAL],
 				       0);
-		}
-
+		else
+			g_signal_emit (player,
+				       brasero_player_signals [ERROR_SIGNAL],
+				       0);
 		return;
 	}
 
@@ -1115,55 +639,14 @@ brasero_player_set_uri (BraseroPlayer *player,
 
 	/* That stops the pipeline from playing */
 	brasero_player_bacon_set_uri (BRASERO_PLAYER_BACON (player->priv->bacon), NULL);
-
 	if (!uri) {
 		brasero_player_no_multimedia_stream (player);
-		brasero_player_destroy_controls (player);
 		return;
 	}
 
-	if (player->priv->controls) {
-		if (player->priv->header) {
-			gchar *song_uri;
-
-			BRASERO_GET_BASENAME_FOR_DISPLAY (uri, name);
-			song_uri = g_markup_printf_escaped (_("<span weight=\"bold\">Loading information</span>\nabout <span size=\"smaller\"><i>%s</i></span>"),
-							  name);
-			g_free (name);
-
-			gtk_label_set_markup (GTK_LABEL (player->priv->header), song_uri);
-			g_free (song_uri);
-		}
-
-		/* grey out the rest of the control while it's loading */
-		if (player->priv->progress) {
-			gtk_widget_set_sensitive (player->priv->progress, FALSE);
-			gtk_range_set_value (GTK_RANGE (player->priv->progress), 0);
-		}
-
-		if (player->priv->size)
-			gtk_label_set_text (GTK_LABEL (player->priv->size), NULL);
-
-		if (player->priv->button) {
-			gtk_widget_set_sensitive (player->priv->button, FALSE);
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (player->priv->button), FALSE);
-		}
-		
-		if (player->priv->image_zoom_in)
-			gtk_widget_set_sensitive (player->priv->image_zoom_in, FALSE);
-
-		if (player->priv->image_zoom_out)
-			gtk_widget_set_sensitive (player->priv->image_zoom_out, FALSE);
-
-		if (player->priv->video_zoom_in)
-			gtk_widget_set_sensitive (player->priv->video_zoom_in, FALSE);
-
-		if (player->priv->video_zoom_out)
-			gtk_widget_set_sensitive (player->priv->video_zoom_out, FALSE);
-
-		if (player->priv->image_display)
-			gtk_widget_set_sensitive (player->priv->image_display, FALSE);
-	}
+	gtk_widget_set_has_tooltip (GTK_WIDGET (player), FALSE);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (player->priv->notebook), 3);
+	gtk_spinner_start (GTK_SPINNER (player->priv->spinner));
 
 	brasero_player_retrieve_metadata (player);
 }
@@ -1171,17 +654,10 @@ brasero_player_set_uri (BraseroPlayer *player,
 static void
 brasero_player_eof_cb (BraseroPlayerBacon *bacon, BraseroPlayer *player)
 {
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (player->priv->button), FALSE);
-
-	if (player->priv->update_scale_id) {
-		g_source_remove (player->priv->update_scale_id);
-		player->priv->update_scale_id = 0;
-	}
-
-	gtk_range_set_value (GTK_RANGE (player->priv->progress), 0.0);
 	brasero_player_bacon_stop (BRASERO_PLAYER_BACON (player->priv->bacon));
 	brasero_player_bacon_set_pos (BRASERO_PLAYER_BACON (player->priv->bacon), player->priv->start);
 	player->priv->state = BACON_STATE_PAUSED;
+	gtk_image_set_from_stock (GTK_IMAGE (player->priv->play_image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
 }
 
 static void
@@ -1197,31 +673,6 @@ brasero_player_state_changed_cb (BraseroPlayerBacon *bacon,
 		brasero_player_no_multimedia_stream (player);
 		break;
 
-	case BACON_STATE_PAUSED:
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (player->priv->button), FALSE);	
-		if (player->priv->update_scale_id) {
-			g_source_remove (player->priv->update_scale_id);
-			player->priv->update_scale_id = 0;
-		}
-		break;
-
-	case BACON_STATE_PLAYING:
-		if (player->priv->state == BACON_STATE_READY) {
-			gdouble pos;
-
-			pos = gtk_range_get_value (GTK_RANGE (player->priv->progress));
-			brasero_player_bacon_set_pos (BRASERO_PLAYER_BACON (player->priv->bacon), pos + player->priv->start);
-
-			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (player->priv->button), TRUE);
-
-			if (!player->priv->update_scale_id)
-			player->priv->update_scale_id = g_timeout_add (500,
-								       (GSourceFunc) brasero_player_update_progress_cb,
-								       player);
-		}
-
-		break;
-
 	default:
 		break;
 	}
@@ -1229,77 +680,6 @@ brasero_player_state_changed_cb (BraseroPlayerBacon *bacon,
 	player->priv->state = state;
 }
 
-gint64
-brasero_player_get_length (BraseroPlayer *self)
-{
-	if (!self->priv->bacon)
-		return -1;
-
-	return self->priv->end - self->priv->start;
-}
-
-gint64
-brasero_player_get_pos (BraseroPlayer *self)
-{
-	gdouble pos;
-
-	if (!self->priv->bacon)
-		return -1;
-
-	pos = gtk_range_get_value (GTK_RANGE (self->priv->progress));
-
-	return pos;
-}
-
-static void
-brasero_player_size_allocate (GtkWidget *widget,
-			      GtkAllocation *allocation)
-{
-	BraseroPlayer *player;
-	GtkWidget *parent;
-
-	player = BRASERO_PLAYER (widget);
-	if (!player->priv->controls) {
-		GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
-		return;
-	}
-
-	if (!player->priv->pixbuf) {
-		GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
-		return;
-	}
-
-	parent = gtk_widget_get_parent (player->priv->controls);
-
-	g_object_ref (player->priv->controls);
-
-	if (allocation->width > allocation->height) {
-		if (parent != player->priv->hbox) {
-			gtk_container_remove (GTK_CONTAINER (player->priv->vbox), player->priv->controls);
-			gtk_box_pack_end (GTK_BOX (player->priv->hbox),
-					  player->priv->controls,
-					  TRUE,
-					  TRUE,
-					  0);
-		}
-	}
-	else {
-		if (parent != player->priv->vbox) {
-			gtk_container_remove (GTK_CONTAINER (player->priv->hbox), player->priv->controls);
-			gtk_box_pack_end (GTK_BOX (player->priv->vbox),
-					  player->priv->controls,
-					  TRUE,
-					  TRUE,
-					  0);
-		}
-	}
-
-	g_object_unref (player->priv->controls);
-	gtk_widget_show (player->priv->controls);
-
-	GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
-}
-
 static void
 brasero_player_destroy (GtkObject *obj)
 {
@@ -1317,19 +697,14 @@ brasero_player_destroy (GtkObject *obj)
 	                           BRASERO_SETTING_VIDEO_SIZE_WIDTH,
 	                           GINT_TO_POINTER (player->priv->video_width));
 	brasero_setting_set_value (brasero_setting_get_default (),
-	                           BRASERO_SETTING_VIDEO_SIZE_WIDTH,
-	                           GINT_TO_POINTER (player->priv->video_width));
+	                           BRASERO_SETTING_VIDEO_SIZE_HEIGHT,
+	                           GINT_TO_POINTER (player->priv->video_height));
 
 	if (player->priv->pixbuf) {
 		g_object_unref (player->priv->pixbuf);
 		player->priv->pixbuf = NULL;
 	}
 
-	if (player->priv->update_scale_id) {
-		g_source_remove (player->priv->update_scale_id);
-		player->priv->update_scale_id = 0;
-	}
-
 	if (player->priv->uri) {
 		g_free (player->priv->uri);
 		player->priv->uri = NULL;
@@ -1361,15 +736,12 @@ brasero_player_class_init (BraseroPlayerClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
 	GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
-	GtkWidgetClass *gtk_widget_class = GTK_WIDGET_CLASS (klass);
 
 	parent_class = g_type_class_peek_parent (klass);
 	object_class->finalize = brasero_player_finalize;
 
 	gtk_object_class->destroy = brasero_player_destroy;
 
-	gtk_widget_class->size_allocate = brasero_player_size_allocate;
-
 	brasero_player_signals [ERROR_SIGNAL] = 
 			g_signal_new ("error",
 				      G_TYPE_FROM_CLASS (klass),
@@ -1389,62 +761,74 @@ brasero_player_class_init (BraseroPlayerClass *klass)
 }
 
 static void
+brasero_player_volume_changed_cb (GtkScaleButton *button,
+				  gdouble volume,
+				  BraseroPlayer *player)
+{
+	brasero_player_bacon_set_volume (BRASERO_PLAYER_BACON (player->priv->bacon), volume);
+}
+
+static void
 brasero_player_init (BraseroPlayer *obj)
 {
-	GtkWidget *alignment;
+	GtkWidget *volume;
+	GtkWidget *image;
+	GtkWidget *label;
 	GtkWidget *event;
+	GtkWidget *zoom;
+	GtkWidget *hbox;
+	GtkWidget *vbox;
 	gpointer value;
+	gchar *string;
 
 	obj->priv = g_new0 (BraseroPlayerPrivate, 1);
 
-	obj->priv->vbox = gtk_vbox_new (FALSE, 0);
-	gtk_widget_show (obj->priv->vbox);
-	gtk_container_set_border_width (GTK_CONTAINER (obj->priv->vbox), 0);
-	gtk_container_add (GTK_CONTAINER (obj), obj->priv->vbox);
-
-	obj->priv->hbox = gtk_hbox_new (FALSE, 0);
-	gtk_widget_show (obj->priv->hbox);
-	gtk_box_pack_start (GTK_BOX (obj->priv->vbox),
-			    obj->priv->hbox,
-			    TRUE,
-			    TRUE,
-			    0);
-
-	alignment = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
-	gtk_widget_show (alignment);
-	gtk_box_pack_start (GTK_BOX (obj->priv->hbox),
-			    alignment,
-			    FALSE,
-			    FALSE,
-			    0);
-
-	obj->priv->notebook = gtk_notebook_new ();
-	gtk_container_set_border_width (GTK_CONTAINER (obj->priv->notebook), 6);
-	gtk_container_add (GTK_CONTAINER (alignment), obj->priv->notebook);
-	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (obj->priv->notebook), FALSE);
-	gtk_notebook_set_show_border (GTK_NOTEBOOK (obj->priv->notebook), FALSE);
+	gtk_alignment_set (GTK_ALIGNMENT (obj), 0.5, 0.5, 0.0, 0.0);
 
+	vbox = gtk_vbox_new (FALSE, 2);
+	gtk_widget_show (vbox);
+	gtk_container_add (GTK_CONTAINER (obj), vbox);
+	
+	/* The notebook and all views */
 	event = gtk_event_box_new ();
-	obj->priv->image_event = event;
+	gtk_box_pack_start (GTK_BOX (vbox), event, FALSE, FALSE, 0);
 	gtk_event_box_set_above_child (GTK_EVENT_BOX (event), TRUE);
 	gtk_event_box_set_visible_window (GTK_EVENT_BOX (event), FALSE);
-	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
-				  event,
-				  NULL);
+	g_signal_connect (event,
+			  "button-release-event",
+			  G_CALLBACK (brasero_player_button_release),
+			  obj);
 	g_signal_connect (event,
 			  "scroll-event",
-			  G_CALLBACK (brasero_player_image_scroll),
+			  G_CALLBACK (brasero_player_scroll),
 			  obj);
 	gtk_widget_show (event);
 
+	obj->priv->notebook = gtk_notebook_new ();
+	gtk_widget_show (obj->priv->notebook);
+	gtk_container_add (GTK_CONTAINER (event), obj->priv->notebook);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (obj->priv->notebook), FALSE);
+
+	/* Images */
 	obj->priv->image_display = gtk_image_new ();
 	gtk_widget_show (obj->priv->image_display);
-	gtk_misc_set_alignment (GTK_MISC (obj->priv->image_display), 1.0, 0.0);
-	gtk_container_add (GTK_CONTAINER (event), obj->priv->image_display);
+	gtk_misc_set_alignment (GTK_MISC (obj->priv->image_display), 0.5, 0.5);
+	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
+				  obj->priv->image_display,
+				  NULL);
 
+	/* Video */
 	obj->priv->bacon = brasero_player_bacon_new ();
 	gtk_widget_show (obj->priv->bacon);
 	g_signal_connect (obj->priv->bacon,
+			  "button-release-event",
+			  G_CALLBACK (brasero_bacon_button_release),
+			  obj);
+	g_signal_connect (obj->priv->bacon,
+			  "scroll-event",
+			  G_CALLBACK (brasero_bacon_scroll),
+			  obj);
+	g_signal_connect (obj->priv->bacon,
 			  "state-change",
 			  G_CALLBACK (brasero_player_state_changed_cb),
 			  obj);
@@ -1452,15 +836,39 @@ brasero_player_init (BraseroPlayer *obj)
 			  "eof",
 			  G_CALLBACK (brasero_player_eof_cb),
 			  obj);
-	g_signal_connect (obj->priv->bacon,
-			  "scroll-event",
-			  G_CALLBACK (brasero_player_video_scroll),
-			  obj);
 
 	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
 				  obj->priv->bacon,
 				  NULL);
 
+	/* No Preview view */
+	string = g_strdup_printf ("<span color='grey'><big><b>%s</b></big></span>", _("No preview"));
+	label = gtk_label_new (string);
+	g_free (string);
+
+	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+	gtk_widget_show (label);
+	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
+	                          label,
+	                          NULL);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (obj->priv->notebook), 2);
+
+	/* Loading view */
+	obj->priv->spinner = gtk_spinner_new ();
+	gtk_widget_show (obj->priv->spinner);
+	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
+	                          obj->priv->spinner,
+	                          NULL);
+
+	/* Music */
+	image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_DIALOG);
+	gtk_widget_show (image);
+	gtk_notebook_append_page (GTK_NOTEBOOK (obj->priv->notebook),
+	                          image,
+	                          NULL);
+	obj->priv->play_image = image;
+
+	/* Set the saved sizes */
 	brasero_setting_get_value (brasero_setting_get_default (),
 	                           BRASERO_SETTING_IMAGE_SIZE_WIDTH,
 	                           &value);
@@ -1500,6 +908,63 @@ brasero_player_init (BraseroPlayer *obj)
 	gtk_widget_set_size_request (obj->priv->bacon,
 				     obj->priv->video_width,
 				     obj->priv->video_height);
+
+	/* A few controls */
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+	image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_BUTTON);
+	zoom = gtk_button_new ();
+	gtk_widget_show (zoom);
+	gtk_widget_show (image);
+	gtk_button_set_image (GTK_BUTTON (zoom), image);
+	gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
+	gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
+	g_signal_connect (zoom,
+			  "clicked",
+			  G_CALLBACK (brasero_player_zoom_out_cb),
+			  obj);
+	gtk_box_pack_start (GTK_BOX (hbox),
+	                    zoom,
+	                    FALSE,
+	                    FALSE,
+	                    0);
+	obj->priv->zoom_out = zoom;
+
+	image = gtk_image_new_from_stock (GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_BUTTON);
+	zoom = gtk_button_new ();
+	gtk_widget_show (zoom);
+	gtk_widget_show (image);
+	gtk_button_set_image (GTK_BUTTON (zoom), image);
+	gtk_button_set_relief (GTK_BUTTON (zoom), GTK_RELIEF_NONE);
+	gtk_button_set_focus_on_click (GTK_BUTTON (zoom), FALSE);
+	g_signal_connect (zoom,
+			  "clicked",
+			  G_CALLBACK (brasero_player_zoom_in_cb),
+			  obj);
+	gtk_box_pack_start (GTK_BOX (hbox),
+	                    zoom,
+	                    FALSE,
+	                    FALSE,
+	                    0);
+	obj->priv->zoom_in = zoom;
+
+	volume = gtk_volume_button_new ();
+	gtk_widget_show (volume);
+	gtk_box_pack_end (GTK_BOX (hbox),
+			  volume,
+			  FALSE,
+			  FALSE,
+			  0);
+
+	gtk_scale_button_set_value (GTK_SCALE_BUTTON (volume),
+				    brasero_player_bacon_get_volume (BRASERO_PLAYER_BACON (obj->priv->bacon)));
+
+	g_signal_connect (volume,
+			  "value-changed",
+			  G_CALLBACK (brasero_player_volume_changed_cb),
+			  obj);
 }
 
 GtkWidget *
diff --git a/src/brasero-player.h b/src/brasero-player.h
index 85ad8b9..f976d9a 100644
--- a/src/brasero-player.h
+++ b/src/brasero-player.h
@@ -69,13 +69,6 @@ brasero_player_set_boundaries (BraseroPlayer *player,
 			       gint64 start,
 			       gint64 end);
 
-const gchar *
-brasero_player_get_uri (BraseroPlayer *player);
-gint64
-brasero_player_get_pos (BraseroPlayer *player);
-gint64
-brasero_player_get_length (BraseroPlayer *player);
-
 G_END_DECLS
 
 #endif
diff --git a/src/brasero-preview.c b/src/brasero-preview.c
index 534f36e..baa50eb 100644
--- a/src/brasero-preview.c
+++ b/src/brasero-preview.c
@@ -40,7 +40,6 @@ typedef struct _BraseroPreviewPrivate BraseroPreviewPrivate;
 struct _BraseroPreviewPrivate
 {
 	GtkWidget *player;
-	GtkWidget *frame;
 
 	guint set_uri_id;
 
@@ -89,7 +88,7 @@ brasero_preview_source_selection_changed_cb (BraseroURIContainer *source,
 	/* Should we always hide ? */
 	uri = brasero_uri_container_get_selected_uri (source);
 	if (!uri)
-		gtk_widget_hide (priv->frame);
+		gtk_widget_hide (priv->player);
 
 	/* clean the potentially previous uri information */
 	priv->end = -1;
@@ -127,7 +126,7 @@ brasero_preview_hide (BraseroPreview *self)
 	BraseroPreviewPrivate *priv;
 
 	priv = BRASERO_PREVIEW_PRIVATE (self);
-	gtk_widget_hide (priv->frame);
+	gtk_widget_hide (priv->player);
 }
 
 void
@@ -147,7 +146,7 @@ brasero_preview_player_error_cb (BraseroPlayer *player,
 	BraseroPreviewPrivate *priv;
 
 	priv = BRASERO_PREVIEW_PRIVATE (self);
-	gtk_widget_hide (priv->frame);
+	gtk_widget_hide (priv->player);
 }
 
 static void
@@ -157,7 +156,7 @@ brasero_preview_player_ready_cb (BraseroPlayer *player,
 	BraseroPreviewPrivate *priv;
 
 	priv = BRASERO_PREVIEW_PRIVATE (self);
-	gtk_widget_show (priv->frame);
+	gtk_widget_show (priv->player);
 }
 
 static void
@@ -167,13 +166,10 @@ brasero_preview_init (BraseroPreview *object)
 
 	priv = BRASERO_PREVIEW_PRIVATE (object);
 
-	priv->frame = gtk_frame_new (_("Preview"));
-	gtk_container_add (GTK_CONTAINER (object), priv->frame);
-
 	priv->player = brasero_player_new ();
 	gtk_container_set_border_width (GTK_CONTAINER (priv->player), 4);
-	gtk_widget_show_all (priv->player);
-	gtk_container_add (GTK_CONTAINER (priv->frame), priv->player);
+
+	gtk_container_add (GTK_CONTAINER (object), priv->player);
 	g_signal_connect (priv->player,
 			  "error",
 			  G_CALLBACK (brasero_preview_player_error_cb),
diff --git a/src/brasero-project.c b/src/brasero-project.c
index 75a3e73..37a75f6 100644
--- a/src/brasero-project.c
+++ b/src/brasero-project.c
@@ -2148,7 +2148,7 @@ brasero_project_update_preview (GtkFileChooser *chooser,
 {
 	gchar *uri;
 
-	gtk_file_chooser_set_preview_widget_active (chooser, FALSE);
+	gtk_file_chooser_set_preview_widget_active (chooser, TRUE);
 
 	uri = gtk_file_chooser_get_preview_uri (chooser);
 	brasero_player_set_uri (player, uri);
@@ -2255,7 +2255,7 @@ brasero_project_add_uris_cb (GtkAction *action,
 	player = brasero_player_new ();
 
 	gtk_widget_show (player);
-	gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (project->priv->chooser), FALSE);
+	gtk_file_chooser_set_preview_widget_active (GTK_FILE_CHOOSER (project->priv->chooser), TRUE);
 	gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (project->priv->chooser), FALSE);
 	gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (project->priv->chooser), player);
 
diff --git a/src/brasero-song-control.c b/src/brasero-song-control.c
new file mode 100644
index 0000000..eb60d37
--- /dev/null
+++ b/src/brasero-song-control.c
@@ -0,0 +1,653 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2010 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+
+#include <gst/gst.h>
+
+#include "brasero-song-control.h"
+#include "brasero-units.h"
+#include "brasero-misc.h"
+#include "brasero-setting.h"
+
+typedef struct _BraseroSongControlPrivate BraseroSongControlPrivate;
+struct _BraseroSongControlPrivate
+{
+	GstElement *pipe;
+	GstState state;
+
+	gchar *uri;
+
+	gint update_scale_id;
+
+	GtkWidget *progress;
+	GtkWidget *button;
+	GtkWidget *header;
+	GtkWidget *size;
+
+	gsize start;
+	gsize end;
+};
+
+#define BRASERO_SONG_CONTROL_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_SONG_CONTROL, BraseroSongControlPrivate))
+
+G_DEFINE_TYPE (BraseroSongControl, brasero_song_control, GTK_TYPE_ALIGNMENT);
+
+gint64
+brasero_song_control_get_length (BraseroSongControl *self)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (self);
+	if (!priv->uri)
+		return -1;
+
+	return priv->end - priv->start;
+}
+
+gint64
+brasero_song_control_get_pos (BraseroSongControl *self)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (self);
+	return gtk_range_get_value (GTK_RANGE (priv->progress));
+}
+
+static void
+brasero_song_control_update_position (BraseroSongControl *player)
+{
+	gdouble value;
+	GtkAdjustment *adjustment;
+	BraseroSongControlPrivate *priv;
+	gchar *pos_string, *len_string, *result;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	adjustment = gtk_range_get_adjustment (GTK_RANGE (priv->progress));
+	len_string = brasero_units_get_time_string (priv->end - priv->start, FALSE, FALSE);
+
+	value = gtk_range_get_value (GTK_RANGE (priv->progress));
+	pos_string = brasero_units_get_time_string (value, FALSE, FALSE);
+
+	/**
+	 * Translators: this is the position being played in a stream. The 
+	 * first %s is the position and the second %s is the whole length of
+	 * the stream. I chose to make that translatable in case some languages
+	 * don't allow the "/" */
+	result = g_strdup_printf (_("%s / %s"), pos_string, len_string);
+	g_free (len_string);
+	g_free (pos_string);
+
+	gtk_label_set_text (GTK_LABEL (priv->size), result);
+	g_free (result);
+}
+
+static gboolean
+brasero_song_control_set_pos (BraseroSongControl *player,
+                              gint64 pos)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+	return gst_element_seek (priv->pipe,
+				 1.0,
+				 GST_FORMAT_TIME,
+				 GST_SEEK_FLAG_FLUSH,
+				 GST_SEEK_TYPE_SET,
+				 (gint64) pos,
+				 priv->end ? GST_SEEK_TYPE_SET:GST_SEEK_TYPE_NONE,
+				 priv->end);
+}
+
+static void
+brasero_song_control_range_value_changed (GtkRange *range,
+                                          BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	if (priv->state >= GST_STATE_PAUSED && !priv->update_scale_id) {
+		gdouble pos;
+
+		/* user changed the value tell the player/pipeline */
+		pos = gtk_range_get_value (GTK_RANGE (priv->progress));
+		brasero_song_control_set_pos (BRASERO_SONG_CONTROL (player), (gint64) pos + priv->start);
+	}
+
+	brasero_song_control_update_position (player);
+}
+
+static void
+brasero_song_control_set_length (BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+	if (priv->end - priv->start != 0)
+		gtk_range_set_range (GTK_RANGE (priv->progress),
+				     0.0,
+				     (gdouble) priv->end - priv->start);
+
+	brasero_song_control_update_position (player);
+}
+
+static gboolean
+brasero_song_control_update_progress_cb (BraseroSongControl *player)
+{
+	gint64 pos;
+	gboolean result;
+	BraseroSongControlPrivate *priv;
+	GstFormat format = GST_FORMAT_TIME;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+	result = gst_element_query_position (priv->pipe,
+					     &format,
+					     &pos);
+
+	if (pos >= 0) {
+		gtk_range_set_value (GTK_RANGE (priv->progress), (gsize) (pos - priv->start));
+		gtk_widget_queue_draw (GTK_WIDGET (priv->progress));
+	}
+
+	return TRUE;
+}
+
+static gboolean
+brasero_song_control_range_button_pressed_cb (GtkWidget *widget,
+                                              GdkEvent *event,
+                                              BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	/* stop the automatic update of progress bar position */
+	if (priv->update_scale_id) {
+		g_source_remove (priv->update_scale_id);
+		priv->update_scale_id = 0;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+brasero_song_control_range_button_released_cb (GtkWidget *widget,
+                                               GdkEvent *event,
+                                               BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	/* restart the automatic update of progress bar */
+	if (priv->state == GST_STATE_PLAYING && !priv->update_scale_id)
+		priv->update_scale_id = g_timeout_add (500,
+		                                       (GSourceFunc) brasero_song_control_update_progress_cb,
+		                                       player);
+
+	return FALSE;
+}
+
+static void
+brasero_song_control_button_clicked_cb (GtkButton *button,
+                                        BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	if (priv->state == GST_STATE_READY)
+		gst_element_set_state (priv->pipe, GST_STATE_PLAYING);
+	else if (priv->state == GST_STATE_PAUSED)
+		gst_element_set_state (priv->pipe, GST_STATE_PLAYING);
+	else if (priv->state == GST_STATE_PLAYING)
+		gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
+}
+
+static void
+brasero_song_control_volume_changed_cb (GtkScaleButton *button,
+                                        gdouble volume,
+                                        BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+	g_object_set (priv->pipe,
+		      "volume", volume,
+		      NULL);
+}
+
+const gchar *
+brasero_song_control_get_uri (BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+	return priv->uri;
+}
+
+void
+brasero_song_control_set_info (BraseroSongControl *player,
+                               const gchar *title,
+                               const gchar *artist)
+{
+	gchar *header = NULL;
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	brasero_song_control_set_length (player);
+
+	if (artist) {
+		gchar *artist_string;
+		gchar *artist_markup;
+		gchar *title_string;
+
+		artist_markup = g_markup_printf_escaped ("<span size=\"smaller\"><i>%s</i></span>", artist);
+
+		/* Translators: %s is the name of an artist. */
+		artist_string = g_strdup_printf (_("by %s"), artist_markup);
+		g_free (artist_markup);
+
+		title_string = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", title);
+		header = g_strdup_printf ("%s\n%s", title_string, artist_string);
+		g_free (artist_string);
+		g_free (title_string);
+
+		gtk_label_set_ellipsize (GTK_LABEL (priv->header),
+					 PANGO_ELLIPSIZE_END);
+
+	}
+	else if (title) {
+		header = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>", title);
+		gtk_label_set_ellipsize (GTK_LABEL (priv->header),
+					 PANGO_ELLIPSIZE_END);
+	}
+	else {
+		gchar *name;
+
+	    	BRASERO_GET_BASENAME_FOR_DISPLAY (priv->uri, name);
+		header = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>\n", name);
+		g_free (name);
+
+		gtk_label_set_ellipsize (GTK_LABEL (priv->header),
+					 PANGO_ELLIPSIZE_END);
+	}
+
+	gtk_label_set_markup (GTK_LABEL (priv->header), header);
+	g_free (header);
+}
+
+void
+brasero_song_control_set_boundaries (BraseroSongControl *player, 
+                                     gsize start,
+                                     gsize end)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	priv->start = start;
+	priv->end = end;
+
+	brasero_song_control_set_length (player);
+	gtk_range_set_value (GTK_RANGE (priv->progress), 0);
+
+	brasero_song_control_set_pos (player, start);
+}
+
+void
+brasero_song_control_set_uri (BraseroSongControl *player,
+                              const gchar *uri)
+{
+	BraseroSongControlPrivate *priv;
+
+	g_return_if_fail (uri != NULL);
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	/* avoid reloading everything if it's the same uri */
+	if (!g_strcmp0 (uri, priv->uri))
+		return;
+
+	if (priv->uri)
+		g_free (priv->uri);
+
+	priv->uri = g_strdup (uri);
+
+	priv->start = 0;
+	priv->end = 0;
+
+	gst_element_set_state (priv->pipe, GST_STATE_NULL);
+	priv->state = GST_STATE_NULL;
+
+	g_object_set (G_OBJECT (priv->pipe),
+		      "uri", uri,
+		      NULL);
+
+	gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
+}
+
+static gboolean
+brasero_song_control_bus_messages (GstBus *bus,
+				   GstMessage *msg,
+				   BraseroSongControl *player)
+{
+	BraseroSongControlPrivate *priv;
+	GstStateChangeReturn result;
+	GError *error = NULL;
+	GstState state;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (player);
+
+	switch (GST_MESSAGE_TYPE (msg)) {
+	case GST_MESSAGE_EOS:
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE);
+
+		if (priv->update_scale_id) {
+			g_source_remove (priv->update_scale_id);
+			priv->update_scale_id = 0;
+		}
+
+		gtk_range_set_value (GTK_RANGE (priv->progress), 0.0);
+		gst_element_set_state (priv->pipe, GST_STATE_PAUSED);
+		brasero_song_control_set_pos (player, priv->start);
+		break;
+
+	case GST_MESSAGE_ERROR:
+		gst_message_parse_error (msg, &error, NULL);
+		g_warning ("%s", error->message);
+		g_error_free (error);
+
+		gtk_widget_set_sensitive (priv->button, FALSE);
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE);
+
+		gtk_widget_set_sensitive (priv->progress, FALSE);
+		gtk_range_set_value (GTK_RANGE (priv->progress), 0.0);
+		break;
+
+	case GST_MESSAGE_STATE_CHANGED:
+		result = gst_element_get_state (GST_ELEMENT (priv->pipe),
+						&state,
+						NULL,
+						500);
+
+		if (result != GST_STATE_CHANGE_SUCCESS)
+			break;
+
+		if (priv->state == state || state < GST_STATE_READY)
+			break;
+
+		if (state == GST_STATE_PLAYING) {
+			if (priv->state == GST_STATE_READY) {
+				gdouble pos;
+
+				pos = gtk_range_get_value (GTK_RANGE (priv->progress));
+				brasero_song_control_set_pos (player, priv->start + pos);
+
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), TRUE);
+			}
+
+			if (!priv->update_scale_id)
+				priv->update_scale_id = g_timeout_add (500,
+								       (GSourceFunc) brasero_song_control_update_progress_cb,
+								       player);
+		}
+		else if (state == GST_STATE_PAUSED) {
+			if (priv->state != GST_STATE_PLAYING) {
+				gdouble pos;
+
+				pos = gtk_range_get_value (GTK_RANGE (priv->progress));
+				brasero_song_control_set_pos (player, priv->start + pos);
+			}
+
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->button), FALSE);	
+			if (priv->update_scale_id) {
+				g_source_remove (priv->update_scale_id);
+				priv->update_scale_id = 0;
+			}
+		}
+
+		priv->state = state;
+		break;
+
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+
+static void
+brasero_song_control_destroy (GtkObject *obj)
+{
+	BraseroSongControlPrivate *priv;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (obj);
+
+	if (priv->update_scale_id) {
+		g_source_remove (priv->update_scale_id);
+		priv->update_scale_id = 0;
+	}
+
+	if (priv->pipe) {
+		gdouble volume;
+
+		g_object_get (priv->pipe,
+			      "volume", &volume,
+			      NULL);
+		brasero_setting_set_value (brasero_setting_get_default (),
+		                           BRASERO_SETTING_PLAYER_VOLUME,
+		                           GINT_TO_POINTER ((gint) (volume * 100.0)));
+
+		gst_element_set_state (priv->pipe, GST_STATE_NULL);
+		gst_object_unref (GST_OBJECT (priv->pipe));
+		priv->pipe = NULL;
+	}
+
+	if (priv->uri) {
+		g_free (priv->uri);
+		priv->uri = NULL;
+	}
+
+	GTK_OBJECT_CLASS (brasero_song_control_parent_class)->destroy (obj);
+}
+
+static void
+brasero_song_control_init (BraseroSongControl *object)
+{
+	BraseroSongControlPrivate *priv;
+	GtkWidget *alignment;
+	GtkWidget *volume;
+	gint volume_value;
+	GtkWidget *image;
+	GtkWidget *vbox;
+	GtkWidget *hbox;
+	gpointer value;
+	GstBus *bus;
+
+	priv = BRASERO_SONG_CONTROL_PRIVATE (object);
+
+	/* Pipeline */
+	priv->pipe = gst_element_factory_make ("playbin2", NULL);
+	if (priv->pipe) {
+		GstElement *audio_sink;
+
+		audio_sink = gst_element_factory_make ("gconfaudiosink", NULL);
+		if (audio_sink)
+			g_object_set (G_OBJECT (priv->pipe),
+				      "audio-sink", audio_sink,
+				      NULL);
+	}
+	else
+		g_warning ("Pipe creation error : can't create pipe.\n");
+
+	bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipe));
+	gst_bus_add_watch (bus,
+			   (GstBusFunc) brasero_song_control_bus_messages,
+			   object);
+	gst_object_unref (bus);
+
+	/* Widget itself */
+	vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (vbox);
+	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);
+	gtk_container_add (GTK_CONTAINER (object), vbox);
+
+	/* first line title */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (vbox),
+			    hbox,
+			    FALSE,
+			    FALSE,
+			    0);
+
+	priv->header = gtk_label_new (_("No file"));
+	gtk_widget_show (priv->header);
+	gtk_label_set_use_markup (GTK_LABEL (priv->header), TRUE);
+	gtk_label_set_justify (GTK_LABEL (priv->header), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment (GTK_MISC (priv->header), 0.0, 0.5);
+	gtk_box_pack_start (GTK_BOX (hbox),
+			    priv->header,
+			    TRUE,
+			    TRUE,
+			    0);
+
+	priv->size = gtk_label_new (NULL);
+	gtk_widget_show (priv->size);
+	gtk_label_set_justify (GTK_LABEL (priv->size), GTK_JUSTIFY_LEFT);
+	gtk_misc_set_alignment (GTK_MISC (priv->size), 0.0, 0.0);
+	gtk_box_pack_end (GTK_BOX (hbox),
+	                  priv->size,
+	                  FALSE,
+	                  FALSE,
+	                  0);
+	
+	/* second line : play, progress, volume button */
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_widget_show (hbox);
+	gtk_box_pack_start (GTK_BOX (vbox),
+			    hbox,
+			    FALSE,
+			    FALSE,
+			    0);
+
+	alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
+	gtk_widget_show (alignment);
+
+	priv->button = gtk_toggle_button_new ();
+	gtk_widget_show (priv->button);
+	gtk_widget_set_tooltip_text (priv->button, _("Start and stop playing"));
+	gtk_container_add (GTK_CONTAINER (alignment), priv->button);
+	gtk_box_pack_start (GTK_BOX (hbox),
+			    alignment,
+			    FALSE,
+			    FALSE,
+			    0);
+
+	image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
+	gtk_widget_show (image);
+	gtk_container_add (GTK_CONTAINER (priv->button), image);
+	g_signal_connect (G_OBJECT (priv->button), "clicked",
+			  G_CALLBACK (brasero_song_control_button_clicked_cb),
+			  object);
+
+	priv->progress = gtk_hscale_new_with_range (0, 1, 500000000);
+	gtk_widget_show (priv->progress);
+	gtk_scale_set_digits (GTK_SCALE (priv->progress), 0);
+	gtk_scale_set_draw_value (GTK_SCALE (priv->progress), FALSE);
+	gtk_widget_set_size_request (priv->progress, 80, -1);
+	gtk_range_set_update_policy (GTK_RANGE (priv->progress), GTK_UPDATE_CONTINUOUS);
+	gtk_box_pack_start (GTK_BOX (hbox),
+	                    priv->progress,
+	                    TRUE,
+	                    TRUE,
+	                    0);
+
+	g_signal_connect (G_OBJECT (priv->progress),
+			  "button-press-event",
+			  G_CALLBACK (brasero_song_control_range_button_pressed_cb), object);
+	g_signal_connect (G_OBJECT (priv->progress),
+			  "button-release-event",
+			  G_CALLBACK (brasero_song_control_range_button_released_cb), object);
+	g_signal_connect (G_OBJECT (priv->progress),
+			  "value-changed",
+			  G_CALLBACK (brasero_song_control_range_value_changed),
+			  object);
+
+	/* Set saved volume */
+	brasero_setting_get_value (brasero_setting_get_default (),
+	                           BRASERO_SETTING_PLAYER_VOLUME,
+	                           &value);
+	volume_value = GPOINTER_TO_INT (value);
+	volume_value = CLAMP (volume_value, 0, 100);
+	g_object_set (priv->pipe,
+		      "volume", (gdouble) volume_value / 100.0,
+		      NULL);
+
+	volume = gtk_volume_button_new ();
+	gtk_widget_show (volume);
+	gtk_box_pack_start (GTK_BOX (hbox),
+			    volume,
+			    FALSE,
+			    FALSE,
+			    0);
+
+	gtk_scale_button_set_value (GTK_SCALE_BUTTON (volume), (gdouble) volume_value / 100.0);
+	g_signal_connect (volume,
+			  "value-changed",
+			  G_CALLBACK (brasero_song_control_volume_changed_cb),
+			  object);
+
+	gtk_alignment_set_padding (GTK_ALIGNMENT (object), 12, 0, 0, 0);
+}
+
+static void
+brasero_song_control_finalize (GObject *object)
+{
+	G_OBJECT_CLASS (brasero_song_control_parent_class)->finalize (object);
+}
+
+static void
+brasero_song_control_class_init (BraseroSongControlClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtkObjectClass* gtk_object_class = GTK_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (BraseroSongControlPrivate));
+
+	object_class->finalize = brasero_song_control_finalize;
+	gtk_object_class->destroy = brasero_song_control_destroy;
+}
+
+GtkWidget *
+brasero_song_control_new (void)
+{
+	return g_object_new (BRASERO_TYPE_SONG_CONTROL, NULL);
+}
diff --git a/src/brasero-song-control.h b/src/brasero-song-control.h
new file mode 100644
index 0000000..4cadfaa
--- /dev/null
+++ b/src/brasero-song-control.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * brasero
+ * Copyright (C) Philippe Rouquier 2010 <bonfire-app wanadoo fr>
+ * 
+ * brasero is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * brasero is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BRASERO_SONG_CONTROL_H_
+#define _BRASERO_SONG_CONTROL_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define BRASERO_TYPE_SONG_CONTROL             (brasero_song_control_get_type ())
+#define BRASERO_SONG_CONTROL(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), BRASERO_TYPE_SONG_CONTROL, BraseroSongControl))
+#define BRASERO_SONG_CONTROL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), BRASERO_TYPE_SONG_CONTROL, BraseroSongControlClass))
+#define BRASERO_IS_SONG_CONTROL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BRASERO_TYPE_SONG_CONTROL))
+#define BRASERO_IS_SONG_CONTROL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), BRASERO_TYPE_SONG_CONTROL))
+#define BRASERO_SONG_CONTROL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), BRASERO_TYPE_SONG_CONTROL, BraseroSongControlClass))
+
+typedef struct _BraseroSongControlClass BraseroSongControlClass;
+typedef struct _BraseroSongControl BraseroSongControl;
+
+struct _BraseroSongControlClass
+{
+	GtkAlignmentClass parent_class;
+};
+
+struct _BraseroSongControl
+{
+	GtkAlignment parent_instance;
+};
+
+GType brasero_song_control_get_type (void) G_GNUC_CONST;
+
+GtkWidget *
+brasero_song_control_new (void);
+
+void
+brasero_song_control_set_uri (BraseroSongControl *player,
+                              const gchar *uri);
+
+void
+brasero_song_control_set_info (BraseroSongControl *player,
+                               const gchar *title,
+                               const gchar *artist);
+
+void
+brasero_song_control_set_boundaries (BraseroSongControl *player, 
+                                     gsize start,
+                                     gsize end);
+
+gint64
+brasero_song_control_get_pos (BraseroSongControl *control);
+
+gint64
+brasero_song_control_get_length (BraseroSongControl *control);
+
+const gchar *
+brasero_song_control_get_uri (BraseroSongControl *control);
+
+G_END_DECLS
+
+#endif /* _BRASERO_SONG_CONTROL_H_ */
diff --git a/src/brasero-split-dialog.c b/src/brasero-split-dialog.c
index fa1c3ae..b7924c7 100644
--- a/src/brasero-split-dialog.c
+++ b/src/brasero-split-dialog.c
@@ -38,7 +38,7 @@
 #include "brasero-track-stream.h"
 
 #include "brasero-split-dialog.h"
-#include "brasero-player.h"
+#include "brasero-song-control.h"
 #include "brasero-utils.h"
 
 enum {
@@ -85,12 +85,15 @@ G_DEFINE_TYPE (BraseroSplitDialog, brasero_split_dialog, GTK_TYPE_DIALOG);
 
 void
 brasero_split_dialog_set_uri (BraseroSplitDialog *self,
-			      const gchar *uri)
+			      const gchar *uri,
+                              const gchar *title,
+                              const gchar *artist)
 {
 	BraseroSplitDialogPrivate *priv;
 
 	priv = BRASERO_SPLIT_DIALOG_PRIVATE (self);
-	brasero_player_set_uri (BRASERO_PLAYER (priv->player), uri);
+	brasero_song_control_set_uri (BRASERO_SONG_CONTROL (priv->player), uri);
+	brasero_song_control_set_info (BRASERO_SONG_CONTROL (priv->player), title, artist);
 }
 
 void
@@ -114,9 +117,9 @@ brasero_split_dialog_set_boundaries (BraseroSplitDialog *self,
 	priv->start = start;
 	priv->end = end;
 
-	brasero_player_set_boundaries (BRASERO_PLAYER (priv->player),
-				       priv->start,
-				       priv->end);
+	brasero_song_control_set_boundaries (BRASERO_SONG_CONTROL (priv->player),
+	                                     priv->start,
+	                                     priv->end);
 }
 
 GSList *
@@ -211,7 +214,7 @@ brasero_split_dialog_cut (BraseroSplitDialog *self,
 
 		/* nothing in the tree yet */
 		if (priv->end <= 0)
-			end = brasero_player_get_length (BRASERO_PLAYER (priv->player));
+			end = brasero_song_control_get_length (BRASERO_SONG_CONTROL (priv->player));
 		else
 			end = priv->end;
 
@@ -733,7 +736,7 @@ brasero_split_dialog_cut_clicked_cb (GtkButton *button,
 		gint64 pos;
 
 		/* this one is before since it doesn't wipe all slices */
-		pos = brasero_player_get_pos (BRASERO_PLAYER (priv->player));
+		pos = brasero_song_control_get_pos (BRASERO_SONG_CONTROL (priv->player));
 		brasero_split_dialog_cut (self, pos + priv->start, TRUE);
 		return;
 	}
@@ -798,7 +801,7 @@ brasero_split_dialog_cut_clicked_cb (GtkButton *button,
 			  G_CALLBACK (brasero_split_dialog_metadata_finished_cb),
 			  self);
 	brasero_metadata_get_info_async (priv->metadata,
-					 brasero_player_get_uri (BRASERO_PLAYER (priv->player)),
+					 brasero_song_control_get_uri (BRASERO_SONG_CONTROL (priv->player)),
 					 BRASERO_METADATA_FLAG_SILENCES);
 
 	/* stop anything from playing and grey out things */
@@ -1103,7 +1106,7 @@ brasero_split_dialog_init (BraseroSplitDialog *object)
 	gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
 	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
 
-	priv->player = brasero_player_new ();
+	priv->player = brasero_song_control_new ();
 	gtk_widget_show (priv->player);
 	gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->player, NULL);
 
diff --git a/src/brasero-split-dialog.h b/src/brasero-split-dialog.h
index e1993e7..f1108d6 100644
--- a/src/brasero-split-dialog.h
+++ b/src/brasero-split-dialog.h
@@ -62,7 +62,9 @@ brasero_split_dialog_new (void);
 
 void
 brasero_split_dialog_set_uri (BraseroSplitDialog *dialog,
-			      const gchar *uri);
+			      const gchar *uri,
+                              const gchar *title,
+                              const gchar *artist);
 void
 brasero_split_dialog_set_boundaries (BraseroSplitDialog *dialog,
 				     gint64 start,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]