예제 #1
0
static void
gth_media_viewer_page_real_view (GthViewerPage *base,
				 GthFileData   *file_data)
{
	GthMediaViewerPage *self;
	char               *uri;

	self = (GthMediaViewerPage*) base;
	g_return_if_fail (file_data != NULL);

	if (! gstreamer_init ())
		return;

	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));

	if ((self->priv->file_data != NULL)
	    && g_file_equal (file_data->file, self->priv->file_data->file)
	    && (gth_file_data_get_mtime (file_data) == gth_file_data_get_mtime (self->priv->file_data)))
	{
		return;
	}

	/**/

	_g_object_unref (self->priv->file_data);
	self->priv->file_data = gth_file_data_dup (file_data);

	self->priv->duration = 0;

	_g_object_unref (self->priv->icon);
	self->priv->icon = NULL;

	_gth_media_viewer_page_update_caption (self);

	/**/

	gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), TRUE);
	g_signal_handlers_block_by_func(GET_WIDGET ("adjustment_position"), position_value_changed_cb, self);
	gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("adjustment_position")), 0.0);
	g_signal_handlers_unblock_by_func(GET_WIDGET ("adjustment_position"), position_value_changed_cb, self);
	reset_player_state (self);

	if (self->priv->playbin == NULL)
		return;

	gst_element_set_state (self->priv->playbin, GST_STATE_NULL);
	uri = g_file_get_uri (self->priv->file_data->file);
	g_object_set (G_OBJECT (self->priv->playbin), "uri", uri, NULL);

	gdk_threads_add_idle (set_to_paused, self);

	g_free (uri);
}
static void
gth_file_tool_adjust_contrast_destroy_options (GthFileTool *base)
{
	GthFileToolAdjustContrast *self;
	GtkWidget                 *window;
	GtkWidget                 *viewer_page;

	self = (GthFileToolAdjustContrast *) base;

	if (self->priv->apply_event != 0) {
		g_source_remove (self->priv->apply_event);
		self->priv->apply_event = 0;
	}

	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
	gth_image_viewer_page_reset_viewer_tool (GTH_IMAGE_VIEWER_PAGE (viewer_page));
	gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (viewer_page));

	_g_clear_object (&self->priv->builder);

	_cairo_clear_surface (&self->priv->preview);
	_cairo_clear_surface (&self->priv->destination);
	self->priv->method = GTH_FILTER_GRID_NO_FILTER;
	self->priv->last_applied_method = GTH_FILTER_GRID_NO_FILTER;
}
예제 #3
0
static void
bus_message_cb (GstBus     *bus,
                GstMessage *message,
                gpointer    user_data)
{
	GthMediaViewerPage *self = user_data;

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;

		old_state = new_state = GST_STATE_NULL;
		gst_message_parse_state_changed (message, &old_state, &new_state, &pending_state);

		self->priv->paused = (new_state == GST_STATE_PAUSED);

		if (old_state == new_state)
			break;
		if (GST_MESSAGE_SRC (message) != GST_OBJECT (self->priv->playbin))
			break;

		update_current_position_bar (self, TRUE);

		if ((old_state == GST_STATE_READY) && (new_state == GST_STATE_PAUSED)) {
			update_stream_info (self);
			gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
		}
		if ((old_state == GST_STATE_READY) || (new_state == GST_STATE_PAUSED))
			update_volume_from_playbin (self);
		if ((old_state == GST_STATE_PLAYING) || (new_state == GST_STATE_PLAYING))
			update_play_button (self, new_state);
		break;
	}

	case GST_MESSAGE_DURATION: {
		GstFormat format;

		format = GST_FORMAT_TIME;
		gst_message_parse_duration (message, &format, &self->priv->duration);
		update_current_position_bar (self, TRUE);
		break;
	}

	case GST_MESSAGE_EOS:
		reset_player_state (self);
		break;

	case GST_MESSAGE_BUFFERING: {
		int percent = 0;
		gst_message_parse_buffering (message, &percent);
		g_print ("Buffering (%%%u percent done)", percent);
		break;
	}

	default:
		break;
	}
}
예제 #4
0
static void
update_play_button (GthMediaViewerPage *self,
		    GstState            new_state)
{
	if (! self->priv->playing && (new_state == GST_STATE_PLAYING)) {
		self->priv->playing = TRUE;
		gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("button_play_image")), GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_widget_set_tooltip_text (GET_WIDGET ("button_play_image"), _("Pause"));

		if (self->priv->update_progress_id == 0)
			self->priv->update_progress_id = gdk_threads_add_timeout (PROGRESS_DELAY, update_progress_cb, self);
	}
	else if (self->priv->playing && (new_state != GST_STATE_PLAYING)) {
		self->priv->playing = FALSE;
		gtk_image_set_from_stock (GTK_IMAGE (GET_WIDGET ("button_play_image")), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_widget_set_tooltip_text (GET_WIDGET ("button_play_image"), _("Play"));

		if (self->priv->update_progress_id != 0) {
			 g_source_remove (self->priv->update_progress_id);
			 self->priv->update_progress_id = 0;
		}
	}

	gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
}
예제 #5
0
static void
resize_task_completed_cb (GthTask  *task,
			  GError   *error,
			  gpointer  user_data)
{
	GthFileToolResize *self = user_data;
	GtkWidget         *window;
	GtkWidget         *viewer_page;

	self->priv->resize_task = NULL;

	if (self->priv->closing) {
		g_object_unref (task);
		gth_image_viewer_page_tool_reset_image (GTH_IMAGE_VIEWER_PAGE_TOOL (self));
		return;
	}

	if (error != NULL) {
		if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
			update_image_size (self);
		g_object_unref (task);
		return;
	}

	_cairo_clear_surface (&self->priv->new_image);
	self->priv->new_image = gth_image_task_get_destination_surface (GTH_IMAGE_TASK (task));
	if (self->priv->new_image == NULL) {
		g_object_unref (task);
		return;
	}

	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
	gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->new_image, FALSE);

	if (self->priv->apply_to_original) {
		gth_image_history_add_surface (gth_image_viewer_page_get_history (GTH_IMAGE_VIEWER_PAGE (viewer_page)),
					       self->priv->new_image,
					       -1,
					       TRUE);
		gth_viewer_page_focus (GTH_VIEWER_PAGE (viewer_page));
		gth_file_tool_hide_options (GTH_FILE_TOOL (self));
	}
	else {
		update_dimensione_info_label (self,
					      "new_dimensions_label",
					      self->priv->new_width,
					      self->priv->new_height,
					      TRUE);
		update_dimensione_info_label (self,
					      "scale_factor_label",
					      (double) self->priv->new_width / self->priv->original_width,
					      (double) self->priv->new_height / self->priv->original_height,
					      FALSE);
	}

	g_object_unref (task);
}
예제 #6
0
static void
gth_file_tool_save_as_activate (GthFileTool *tool)
{
    GtkWidget *window;
    GtkWidget *viewer_page;

    window = gth_file_tool_get_window (tool);
    viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
    gth_viewer_page_save_as (GTH_VIEWER_PAGE (viewer_page), NULL, NULL);
}
예제 #7
0
static void
gth_file_tool_save_as_update_sensitivity (GthFileTool *base)
{
    GtkWidget *window;
    gboolean   can_save;

    window = gth_file_tool_get_window (base);

    can_save = gth_viewer_page_can_save (GTH_VIEWER_PAGE (gth_browser_get_viewer_page (GTH_BROWSER (window))));
    can_save = can_save && (gth_browser_get_current_file (GTH_BROWSER (window)) != NULL);
    gtk_widget_set_sensitive (GTK_WIDGET (base), can_save);
}
예제 #8
0
static void
gth_media_viewer_page_real_view (GthViewerPage *base,
				 GthFileData   *file_data)
{
	GthMediaViewerPage *self;
	char               *uri;

	self = (GthMediaViewerPage*) base;
	g_return_if_fail (file_data != NULL);

	if (! gstreamer_init ())
		return;

	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));

	if ((self->priv->file_data != NULL)
	    && g_file_equal (file_data->file, self->priv->file_data->file)
	    && (gth_file_data_get_mtime (file_data) == gth_file_data_get_mtime (self->priv->file_data)))
	{
		return;
	}

	/**/

	_g_object_unref (self->priv->file_data);
	self->priv->file_data = gth_file_data_dup (file_data);

	self->priv->duration = 0;
	self->priv->has_audio = FALSE;
	self->priv->has_video = FALSE;

	_g_object_unref (self->priv->icon);
	self->priv->icon = NULL;

	_gth_media_viewer_page_update_caption (self);

	/**/

	g_signal_handlers_block_by_func(GET_WIDGET ("position_adjustment"), position_value_changed_cb, self);
	gtk_adjustment_set_value (GTK_ADJUSTMENT (GET_WIDGET ("position_adjustment")), 0.0);
	g_signal_handlers_unblock_by_func(GET_WIDGET ("position_adjustment"), position_value_changed_cb, self);
	reset_player_state (self);

	create_playbin (self);
	if (self->priv->playbin == NULL)
		return;

	uri = g_file_get_uri (self->priv->file_data->file);
	_gth_media_viewer_page_set_uri (self, uri, self->priv->visible ? GST_STATE_PLAYING : GST_STATE_PAUSED);

	g_free (uri);
}
void
gth_browser_activate_save_as (GSimpleAction *action,
			      GVariant      *parameter,
			      gpointer       user_data)
{
	GthBrowser *browser = user_data;
	GtkWidget  *viewer_page;

	viewer_page = gth_browser_get_viewer_page (browser);
	if (viewer_page == NULL)
		return;

	gth_viewer_page_save_as (GTH_VIEWER_PAGE (viewer_page), NULL, NULL);
}
예제 #10
0
static void
gth_media_viewer_page_real_show (GthViewerPage *base)
{
	GthMediaViewerPage *self = GTH_MEDIA_VIEWER_PAGE (base);

	self->priv->visible = TRUE;
	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));

	create_playbin (self);
	if (self->priv->file_data != NULL) {
		char *uri;

		uri = g_file_get_uri (self->priv->file_data->file);
		_gth_media_viewer_page_set_uri (self, uri, GST_STATE_PLAYING);

		g_free (uri);
	}
}
예제 #11
0
static void
gth_media_viewer_page_real_show (GthViewerPage *base)
{
	GthMediaViewerPage *self;
	GError             *error = NULL;
	GstBus             *bus;
	char               *uri;

	self = (GthMediaViewerPage*) base;

	if (self->priv->merge_id != 0)
		return;

	self->priv->merge_id = gtk_ui_manager_add_ui_from_string (gth_browser_get_ui_manager (self->priv->browser), media_viewer_ui_info, -1, &error);
	if (self->priv->merge_id == 0) {
		g_warning ("ui building failed: %s", error->message);
		g_error_free (error);
	}

	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));

	if (self->priv->playbin != NULL)
		return;

	self->priv->playbin = gst_element_factory_make ("playbin", "playbin");
	g_signal_connect (self->priv->playbin, "notify::volume", G_CALLBACK (playbin_notify_volume_cb), self);

	bus = gst_pipeline_get_bus (GST_PIPELINE (self->priv->playbin));
	gst_bus_enable_sync_message_emission (bus);
	gst_bus_set_sync_handler (bus, (GstBusSyncHandler) set_playbin_window, self);
	gst_bus_add_signal_watch (bus);
	g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), self);

	if (self->priv->file_data == NULL)
		return;

	uri = g_file_get_uri (self->priv->file_data->file);
	g_object_set (G_OBJECT (self->priv->playbin), "uri", uri, NULL);
	gst_element_set_state (self->priv->playbin, GST_STATE_PAUSED);

	g_free (uri);
}
예제 #12
0
static void
update_play_button (GthMediaViewerPage *self,
		    GstState            new_state)
{
	if (! self->priv->playing && (new_state == GST_STATE_PLAYING)) {
		set_playing_state (self, TRUE);
		gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_button_image")), "media-playback-pause-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_widget_set_tooltip_text (GET_WIDGET ("play_button_image"), _("Pause"));

		if (self->priv->update_progress_id == 0)
			self->priv->update_progress_id = gdk_threads_add_timeout (PROGRESS_DELAY, update_progress_cb, self);

		update_playback_info (self);
	}
	else if (self->priv->playing && (new_state != GST_STATE_PLAYING)) {
		GtkWidget *play_button = GET_WIDGET ("play_button_image");
		gboolean   rtl;

		rtl = gtk_widget_get_direction (play_button) == GTK_TEXT_DIR_RTL;

		set_playing_state (self, FALSE);
		gtk_image_set_from_icon_name (GTK_IMAGE (play_button),
					      rtl ? "media-playback-start-rtl-symbolic" : "media-playback-start-symbolic",
					      GTK_ICON_SIZE_LARGE_TOOLBAR);
		gtk_widget_set_tooltip_text (GET_WIDGET ("play_button_image"), _("Play"));

		if (self->priv->update_progress_id != 0) {
			 g_source_remove (self->priv->update_progress_id);
			 self->priv->update_progress_id = 0;
		}

		update_playback_info (self);
	}

	gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
}
예제 #13
0
static void
gth_media_viewer_page_real_activate (GthViewerPage *base,
				     GthBrowser    *browser)
{
	GthMediaViewerPage *self;

	if (! gstreamer_init ())
		return;

	self = (GthMediaViewerPage*) base;

	self->priv->browser = browser;

	self->priv->actions = gtk_action_group_new ("Video Viewer Actions");
	gtk_action_group_set_translation_domain (self->priv->actions, NULL);
	gtk_action_group_add_actions (self->priv->actions,
				      media_viewer_action_entries,
				      G_N_ELEMENTS (media_viewer_action_entries),
				      self);
	gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), self->priv->actions, 0);

	self->priv->area_box = gtk_vbox_new (FALSE, 0);

	/* video area */

	self->priv->area = gtk_drawing_area_new ();
	gtk_widget_set_double_buffered (self->priv->area, FALSE);
	gtk_widget_add_events (self->priv->area, (gtk_widget_get_events (self->priv->area)
						  | GDK_EXPOSURE_MASK
						  | GDK_BUTTON_PRESS_MASK
						  | GDK_BUTTON_RELEASE_MASK
						  | GDK_POINTER_MOTION_MASK
						  | GDK_POINTER_MOTION_HINT_MASK
						  | GDK_BUTTON_MOTION_MASK));
	GTK_WIDGET_SET_FLAGS (self->priv->area, GTK_CAN_FOCUS);
	gtk_widget_show (self->priv->area);
	gtk_box_pack_start (GTK_BOX (self->priv->area_box), self->priv->area, TRUE, TRUE, 0);

	g_signal_connect (G_OBJECT (self->priv->area),
			  "realize",
			  G_CALLBACK (video_area_realize_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "unrealize",
			  G_CALLBACK (video_area_unrealize_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "expose_event",
			  G_CALLBACK (video_area_expose_event_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "button_press_event",
			  G_CALLBACK (video_area_button_press_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "scroll_event",
			  G_CALLBACK (video_area_scroll_event_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "key_press_event",
			  G_CALLBACK (video_area_key_press_cb),
			  self);

	/* mediabar */

	self->priv->builder = _gtk_builder_new_from_file ("mediabar.ui", "gstreamer_tools");
	self->priv->mediabar = GET_WIDGET ("mediabar");
	gtk_widget_show (self->priv->mediabar);
	gtk_box_pack_start (GTK_BOX (self->priv->area_box), self->priv->mediabar, FALSE, FALSE, 0);

	g_signal_connect (GET_WIDGET ("adjustment_volume"), "value-changed", G_CALLBACK (volume_value_changed_cb), self);
	g_signal_connect (GET_WIDGET ("adjustment_position"), "value-changed", G_CALLBACK (position_value_changed_cb), self);
	g_signal_connect (GET_WIDGET ("hscale_volume"), "format-value", G_CALLBACK (hscale_volume_format_value_cb), self);
	g_signal_connect (GET_WIDGET ("hscale_position"), "change-value", G_CALLBACK (hscale_position_change_value_cb), self);
	g_signal_connect (GET_WIDGET ("hscale_position"), "button-release-event", G_CALLBACK (hscale_position_button_release_event_cb), self);
	g_signal_connect (GET_WIDGET ("button_play"), "clicked", G_CALLBACK (button_play_clicked_cb), self);
	g_signal_connect (GET_WIDGET ("togglebutton_volume"), "toggled", G_CALLBACK (togglebutton_volume_toggled_cb), self);
	g_signal_connect (GET_WIDGET ("button_play_slower"), "clicked", G_CALLBACK (button_play_slower_clicked_cb), self);
	g_signal_connect (GET_WIDGET ("button_play_faster"), "clicked", G_CALLBACK (button_play_faster_clicked_cb), self);

	gtk_widget_show (self->priv->area_box);
	gth_browser_set_viewer_widget (browser, self->priv->area_box);

	gtk_widget_realize (self->priv->area);
	gdk_window_ensure_native (gtk_widget_get_window (self->priv->area));
	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
}
예제 #14
0
static void
bus_message_cb (GstBus     *bus,
                GstMessage *message,
                gpointer    user_data)
{
	GthMediaViewerPage *self = user_data;

	if (GST_MESSAGE_SRC (message) != GST_OBJECT (self->priv->playbin))
		return;

	switch (GST_MESSAGE_TYPE (message)) {
	case GST_MESSAGE_STATE_CHANGED: {
		GstState old_state;
		GstState new_state;
		GstState pending_state;

		old_state = new_state = GST_STATE_NULL;
		gst_message_parse_state_changed (message, &old_state, &new_state, &pending_state);
		if (old_state == new_state)
			break;

		self->priv->paused = (new_state == GST_STATE_PAUSED);
		update_current_position_bar (self);

		if ((old_state == GST_STATE_NULL) && (new_state == GST_STATE_READY) && (pending_state != GST_STATE_PAUSED)) {
			update_stream_info (self);
			gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
			gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, TRUE);
		}
		if ((old_state == GST_STATE_READY) && (new_state == GST_STATE_PAUSED)) {
			update_stream_info (self);
			gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (self));
			gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, TRUE);
		}
		if ((old_state == GST_STATE_READY) || (new_state == GST_STATE_PAUSED))
			update_volume_from_playbin (self);
		if ((old_state == GST_STATE_PLAYING) || (new_state == GST_STATE_PLAYING))
			update_play_button (self, new_state);
		break;
	}

	case GST_MESSAGE_DURATION_CHANGED:
		self->priv->duration = 0;
		update_current_position_bar (self);
		break;

	case GST_MESSAGE_EOS:
		reset_player_state (self);
		break;

	case GST_MESSAGE_BUFFERING: {
		int percent = 0;
		gst_message_parse_buffering (message, &percent);
		gst_element_set_state (self->priv->playbin, (percent == 100) ? GST_STATE_PLAYING : GST_STATE_PAUSED);
		break;
	}

	case GST_MESSAGE_ERROR:
		gth_viewer_page_file_loaded (GTH_VIEWER_PAGE (self), self->priv->file_data, FALSE);
		break;

	default:
		break;
	}
}
예제 #15
0
static void
gth_media_viewer_page_real_activate (GthViewerPage *base,
				     GthBrowser    *browser)
{
	GthMediaViewerPage *self;
	gboolean            rtl;

	if (! gstreamer_init ())
		return;

	self = (GthMediaViewerPage*) base;

	self->priv->browser = browser;
	g_action_map_add_action_entries (G_ACTION_MAP (browser),
					 actions,
					 G_N_ELEMENTS (actions),
					 browser);
	self->priv->screenshot_button =
			gth_browser_add_header_bar_button (browser,
							   GTH_BROWSER_HEADER_SECTION_VIEWER_VIEW,
							   "camera-photo-symbolic",
							   _("Take a screenshot"),
							   "win.video-screenshot",
							   NULL);

	rtl = gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL;

	/* video area */

	self->priv->area = gtk_drawing_area_new ();

	/* do not use the rgba visual on the drawing area */
	{
	        GdkVisual *visual;
	        visual = gdk_screen_get_system_visual (gtk_widget_get_screen (GTK_WIDGET (self->priv->area)));
        	if (visual != NULL)
                	gtk_widget_set_visual (GTK_WIDGET (self->priv->area), visual);
	}

	gtk_widget_set_double_buffered (self->priv->area, FALSE);
	gtk_widget_add_events (self->priv->area, (gtk_widget_get_events (self->priv->area)
						  | GDK_EXPOSURE_MASK
						  | GDK_BUTTON_PRESS_MASK
						  | GDK_BUTTON_RELEASE_MASK
						  | GDK_POINTER_MOTION_MASK
						  | GDK_POINTER_MOTION_HINT_MASK
						  | GDK_BUTTON_MOTION_MASK
						  | GDK_SCROLL_MASK));
	gtk_widget_set_can_focus (self->priv->area, TRUE);
	gtk_widget_show (self->priv->area);

	g_signal_connect (G_OBJECT (self->priv->area),
			  "realize",
			  G_CALLBACK (video_area_realize_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "unrealize",
			  G_CALLBACK (video_area_unrealize_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "draw",
			  G_CALLBACK (video_area_draw_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "button_press_event",
			  G_CALLBACK (video_area_button_press_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "popup-menu",
			  G_CALLBACK (video_area_popup_menu_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "scroll_event",
			  G_CALLBACK (video_area_scroll_event_cb),
			  self);
	g_signal_connect (G_OBJECT (self->priv->area),
			  "key_press_event",
			  G_CALLBACK (video_area_key_press_cb),
			  self);

	/* mediabar */

	self->priv->builder = _gtk_builder_new_from_file ("mediabar.ui", "gstreamer_tools");
	self->priv->mediabar = GET_WIDGET ("mediabar");
	gtk_widget_set_halign (self->priv->mediabar, GTK_ALIGN_FILL);
	gtk_widget_set_valign (self->priv->mediabar, GTK_ALIGN_END);

	gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_slower_image")),
				      rtl ? "media-seek-backward-rtl-symbolic" : "media-seek-backward-symbolic",
				      GTK_ICON_SIZE_MENU);
	gtk_image_set_from_icon_name (GTK_IMAGE (GET_WIDGET ("play_faster_image")),
				      rtl ? "media-seek-forward-rtl-symbolic" : "media-seek-forward-symbolic",
				      GTK_ICON_SIZE_MENU);

	g_signal_connect (GET_WIDGET ("volume_adjustment"),
			  "value-changed",
			  G_CALLBACK (volume_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("position_adjustment"),
			  "value-changed",
			  G_CALLBACK (position_value_changed_cb),
			  self);
	g_signal_connect (GET_WIDGET ("play_button"),
			  "clicked",
			  G_CALLBACK (play_button_clicked_cb),
			  self);
	g_signal_connect (GET_WIDGET ("play_slower_button"),
			  "clicked",
			  G_CALLBACK (play_slower_button_clicked_cb),
			  self);
	g_signal_connect (GET_WIDGET ("play_faster_button"),
			  "clicked",
			  G_CALLBACK (play_faster_button_clicked_cb),
			  self);

	self->priv->mediabar_revealer = gtk_revealer_new ();
	gtk_revealer_set_transition_type (GTK_REVEALER (self->priv->mediabar_revealer), GTK_REVEALER_TRANSITION_TYPE_SLIDE_UP);
	gtk_widget_set_halign (self->priv->mediabar_revealer, GTK_ALIGN_FILL);
	gtk_widget_set_valign (self->priv->mediabar_revealer, GTK_ALIGN_END);
	gtk_widget_show (self->priv->mediabar_revealer);
	gtk_container_add (GTK_CONTAINER (self->priv->mediabar_revealer), self->priv->mediabar);

	self->priv->area_box = gtk_overlay_new ();
	gtk_container_add (GTK_CONTAINER (self->priv->area_box), self->priv->area);
	gtk_overlay_add_overlay (GTK_OVERLAY (self->priv->area_box), self->priv->mediabar_revealer);
	gtk_widget_show (self->priv->area_box);
	gth_browser_set_viewer_widget (browser, self->priv->area_box);

	gtk_widget_realize (self->priv->area);
	gth_browser_register_viewer_control (self->priv->browser, self->priv->mediabar);

	gth_viewer_page_focus (GTH_VIEWER_PAGE (self));
}