summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2013-09-03 22:03:19 +0200
committerStefan Sauer <ensonic@users.sf.net>2013-09-03 22:03:19 +0200
commita560b5c94f7f7945dbbd03935c89738e62371e04 (patch)
tree68efebf16b413cbe5313d6e22ad21bed9729127b
parent48d1ac3edca17cb6aba823be5a10b4a041b7b877 (diff)
preview: extract preview area as separate widget
-rw-r--r--src/Makefile.am3
-rw-r--r--src/mi-info.vala89
-rw-r--r--src/mi-preview.vala125
3 files changed, 149 insertions, 68 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fe7489e..e370d7b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,7 +15,8 @@ VALAFLAGS = \
gst_mi_SOURCES = \
mi.vala \
mi-app.vala \
- mi-info.vala
+ mi-info.vala \
+ mi-preview.vala
gst_mi_LDADD = \
$(MI_LIBS) -lgstinterfaces-0.10 -lgstpbutils-0.10
diff --git a/src/mi-info.vala b/src/mi-info.vala
index 8291b95..a304042 100644
--- a/src/mi-info.vala
+++ b/src/mi-info.vala
@@ -57,8 +57,7 @@ public class MediaInfo.Info : Box
private Notebook video_streams; // depending on screen resolution
private Notebook audio_streams;
private Notebook subtitle_streams;
- private AspectFrame drawing_frame;
- private DrawingArea drawing_area;
+ private Preview preview;
private ScrolledWindow info_area;
// gstreamer objects
private Discoverer dc;
@@ -67,7 +66,6 @@ public class MediaInfo.Info : Box
private uint num_video_streams;
private uint num_audio_streams;
private uint num_subtitle_streams;
- private float video_ratio = 1.0f;
private ArrayList<Gdk.Point?> video_resolutions = null;
// stream data
private Gdk.Pixbuf album_art = null;
@@ -168,19 +166,9 @@ public class MediaInfo.Info : Box
}
// add widgets
- drawing_frame = new AspectFrame (null, 0.5f, 0.5f, 1.25f, false);
- drawing_frame.set_size_request (160, 128);
- drawing_frame.set_shadow_type (Gtk.ShadowType.NONE);
-
- pack_start (drawing_frame, true, true, 0);
-
- drawing_area = new DrawingArea ();
- drawing_area.set_size_request (160, 128);
- drawing_area.draw.connect (on_drawing_area_draw);
- drawing_area.size_allocate.connect (on_drawing_area_size_allocate);
- drawing_area.realize.connect (on_drawing_area_realize);
- drawing_area.unrealize.connect (on_drawing_area_unrealize);
- drawing_frame.add (drawing_area);
+ preview = new Preview ();
+ preview.draw.connect (on_preview_draw);
+ pack_start (preview, false, false, 0);
info_area = new ScrolledWindow (null, null);
info_area.set_policy (PolicyType.NEVER, PolicyType.ALWAYS);
@@ -324,7 +312,6 @@ public class MediaInfo.Info : Box
// stop previous playback
pb.set_state (State.READY);
album_art = null;
- drawing_area.queue_draw();
try {
FileInfo finfo = file.query_info ("standard::*", FileQueryInfoFlags.NONE, null);
@@ -736,19 +723,12 @@ public class MediaInfo.Info : Box
if (have_video) {
Gdk.Point res = video_resolutions[0];
- video_ratio = (float)(res.x) / (float)(res.y);
- debug ("video_ratio from video: %f", video_ratio);
+ preview.set_content_size(res.x, res.y);
} else if (album_art != null) {
- int sw=album_art.get_width ();
- int sh=album_art.get_height ();
- video_ratio = (float)sw / (float)sh;
- debug ("video_ratio from album art: %f", video_ratio);
+ preview.set_static_content(album_art);
} else {
- video_ratio = 1.0f;
- debug ("video_ratio --- : %f", video_ratio);
+ preview.reset();
}
- drawing_frame.set (0.5f, 0.5f, video_ratio, false);
- drawing_area.queue_resize();
//l = info.get_container_streams ();
@@ -759,7 +739,8 @@ public class MediaInfo.Info : Box
// signal handlers
- private void on_drawing_area_size_allocate (Widget widget, Gtk.Allocation frame)
+ /*
+ private void on_size_allocate (Widget widget, Gtk.Allocation box)
{
Gtk.Allocation alloc;
get_allocation (out alloc);
@@ -768,57 +749,29 @@ public class MediaInfo.Info : Box
Gtk.Requisition requisition;
info_area.get_child ().get_preferred_size (null, out requisition);
debug ("info_area: %d x %d", requisition.width, requisition.height);
- debug ("video_area: %d x %d", frame.width, frame.height);
+ int frame_height = (int)(box.width / video_ratio);
+ debug ("video_area: %d x %d", box.width, frame_height);
- int max_h = alloc.height - frame.height;
+ int max_h = alloc.height - frame_height;
info_area.set_min_content_height (int.min (requisition.height, max_h));
}
+ */
- private bool on_drawing_area_draw (Widget widget, Cairo.Context cr)
+ private bool on_preview_draw (Widget widget, Cairo.Context cr)
{
- // redraw if not playing and if there is no video
if (pb.current_state < State.PAUSED || !have_video) {
widget.set_double_buffered (true);
-
- Gtk.Allocation frame;
- widget.get_allocation (out frame);
- int w = frame.width;
- int h = frame.height;
- //debug ("on_drawing_area_draw:video_ratio: %d x %d : %f", w, h, video_ratio);
-
- if (album_art != null) {
- Gdk.Pixbuf pb = album_art.scale_simple (w, h, Gdk.InterpType.BILINEAR);
- Gdk.cairo_set_source_pixbuf (cr, pb, 0, 0);
- } else {
- cr.set_source_rgb (0, 0, 0);
- }
- cr.rectangle (0, 0, w, h);
- cr.fill ();
} else {
widget.set_double_buffered (false);
}
return false;
}
-
- private void on_drawing_area_realize (Widget widget)
- {
- widget.get_window ().ensure_native ();
- widget.set_double_buffered (false);
- }
-
- private void on_drawing_area_unrealize (Widget widget)
- {
- pb.set_state (State.NULL);
- }
private void on_element_sync_message (Gst.Bus bus, Message message)
{
if (Gst.Video.is_video_overlay_prepare_window_handle_message (message)) {
Gst.Video.Overlay overlay = message.src as Gst.Video.Overlay;
- overlay.set_window_handle ((uint *)Gdk.X11Window.get_xid (drawing_area.get_window()));
- drawing_frame.set (0.5f, 0.5f, video_ratio, false);
- debug ("on_element_sync_message:video_ratio: %f", video_ratio);
- drawing_area.queue_resize();
+ overlay.set_window_handle ((uint *)Gdk.X11Window.get_xid (preview.get_window ()));
/* playbin does this in 1.0
if (message.src.get_class ().find_property ("force-aspect-ratio") != null) {
@@ -833,7 +786,12 @@ public class MediaInfo.Info : Box
* - we can use:
* - pad.get_stream_id() on playbin
* - sinfo.get_stream_id() on discoverer
- *
+ * - gather all stream-ids and build {audio,video,subtitle}_stream_map with
+ * stream-id as a key and value initially set to -1
+ * - have cur_{audio,video,subtile} = 0
+ * - listen for playbin.pad_added and set the stream_id to cur_*
+ * - ideally playbin will have api to switch to a stream-by-id
+ * - or we sort the discoverer streams by stream-info too
*/
private void on_video_stream_switched (Notebook nb, Widget page, uint page_num)
{
@@ -841,10 +799,7 @@ public class MediaInfo.Info : Box
debug ("Switching video to: %u", page_num);
((GLib.Object)pb).set_property ("current-video", (int)page_num);
Gdk.Point res = video_resolutions[(int)page_num];
- video_ratio = (float)(res.x) / (float)(res.y);
- drawing_frame.set (0.5f, 0.5f, video_ratio, false);
- drawing_area.queue_resize();
- debug ("on_video_stream_switched:video_ratio: %f", video_ratio);
+ preview.set_content_size(res.x, res.y);
}
}
diff --git a/src/mi-preview.vala b/src/mi-preview.vala
new file mode 100644
index 0000000..48ce6af
--- /dev/null
+++ b/src/mi-preview.vala
@@ -0,0 +1,125 @@
+/* GStreamer media browser
+ * Copyright (C) 2010-2013 Stefan Sauer <ensonic@user.sf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Steet,
+ * Boston, MA 02110-1301, USA.
+ */
+
+using Gtk;
+
+public class MediaInfo.Preview : DrawingArea {
+ private Gdk.Pixbuf content = null;
+ private int width = 0;
+ private int height = 0;
+ private float ratio = 0.0f;
+ private int alloc_width;
+ private int alloc_height;
+
+ construct {
+ set_has_window (true);
+ }
+
+ public void reset () {
+ content = null;
+ ratio = 0.0f;
+ debug ("no content: 0.0");
+ queue_resize ();
+ }
+
+ public void set_static_content (Gdk.Pixbuf? content) {
+ this.content = content;
+ if (content != null) {
+ width = content.get_width ();
+ height = content.get_height ();
+ ratio = (float)width / (float)height;
+ debug ("ratio from album art: %f", ratio);
+ queue_resize ();
+ }
+ }
+
+ public void set_content_size (uint width, uint height) {
+ if (height != 0) {
+ ratio = (float)width / (float)height;
+ } else {
+ ratio = 0.0f;
+ }
+ debug ("ratio from video: %f", ratio);
+ queue_resize ();
+ }
+
+ // vmethods
+
+ public override SizeRequestMode get_request_mode () {
+ return SizeRequestMode.HEIGHT_FOR_WIDTH;
+ }
+
+ public override void get_preferred_width (out int minimal_width, out int natural_width) {
+ if (ratio != 0.0) {
+ minimal_width = natural_width = (int)(alloc_height * ratio);
+ } else {
+ minimal_width = natural_width = 0;
+ }
+ debug ("width w,h: %d,%d", natural_width, alloc_height);
+ }
+
+ public override void get_preferred_height (out int minimal_height, out int natural_height) {
+ if (ratio != 0.0) {
+ minimal_height = natural_height = (int)(alloc_width / ratio);
+ } else {
+ minimal_height = natural_height = 0;
+ }
+ debug ("height w,h: %d,%d", alloc_width, natural_height);
+ }
+
+ public override void get_preferred_width_for_height (int height, out int minimal_width, out int natural_width) {
+ if (ratio != 0.0) {
+ minimal_width = natural_width = (int)(height * ratio);
+ } else {
+ minimal_width = natural_width = 0;
+ }
+ debug ("width_for_height w,h: %d,%d", natural_width, height);
+ }
+
+ public override void get_preferred_height_for_width (int width, out int minimal_height, out int natural_height) {
+ if (ratio != 0.0) {
+ minimal_height = natural_height = (int)(width / ratio);
+ } else {
+ minimal_height = natural_height = 0;
+ }
+ debug ("height_for_width w,h: %d,%d", width, natural_height);
+ }
+
+ public override void size_allocate (Gtk.Allocation alloc) {
+ base.size_allocate (alloc);
+
+ alloc_width = alloc.width;
+ alloc_height = alloc.height;
+ debug ("alloc w,h: %d,%d", alloc_width, alloc_height);
+ }
+
+ public override bool draw (Cairo.Context cr) {
+ if (content != null) {
+ Gdk.Pixbuf pb = content.scale_simple (alloc_width, alloc_height, Gdk.InterpType.BILINEAR);
+ Gdk.cairo_set_source_pixbuf (cr, pb, 0, 0);
+ } else {
+ cr.set_source_rgb (0, 0, 0);
+ }
+ cr.rectangle (0, 0, alloc_width, alloc_height);
+ cr.fill ();
+ debug ("draw w,h: %d,%d", alloc_width, alloc_height);
+ return false;
+ }
+}
+