mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
2006-06-21 Matthew Allum <mallum@openedhand.com>
* clutter/Makefile.am: Make sure clutter.h included. * clutter/clutter-stage.c: (clutter_stage_realize), (clutter_stage_get_actor_at_pos): Select for motion events on X window. Return highest rather than lowest found actor for actor_at_pos. * examples/Makefile.am: Remove test-text, remane test video. * examples/README: Add info about the included examples. * examples/test-video.c: * examples/video-player.c: Redo test-video a little nicer and rename. * examples/video-cube.c: Fix so it at least 'works' again. * examples/test.c: Clean up a little.
This commit is contained in:
parent
177add8768
commit
d61ee2240b
20
ChangeLog
20
ChangeLog
@ -1,3 +1,23 @@
|
|||||||
|
2006-06-21 Matthew Allum <mallum@openedhand.com>
|
||||||
|
|
||||||
|
* clutter/Makefile.am:
|
||||||
|
Make sure clutter.h included.
|
||||||
|
* clutter/clutter-stage.c: (clutter_stage_realize),
|
||||||
|
(clutter_stage_get_actor_at_pos):
|
||||||
|
Select for motion events on X window.
|
||||||
|
Return highest rather than lowest found actor for actor_at_pos.
|
||||||
|
* examples/Makefile.am:
|
||||||
|
Remove test-text, remane test video.
|
||||||
|
* examples/README:
|
||||||
|
Add info about the included examples.
|
||||||
|
* examples/test-video.c:
|
||||||
|
* examples/video-player.c:
|
||||||
|
Redo test-video a little nicer and rename.
|
||||||
|
* examples/video-cube.c:
|
||||||
|
Fix so it at least 'works' again.
|
||||||
|
* examples/test.c:
|
||||||
|
Clean up a little.
|
||||||
|
|
||||||
2006-06-21 Ross Burton <ross@openedhand.com>
|
2006-06-21 Ross Burton <ross@openedhand.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
|
@ -5,22 +5,22 @@ GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
|
|||||||
|
|
||||||
BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
|
BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
|
||||||
|
|
||||||
source_h = \
|
source_h = clutter.h \
|
||||||
$(srcdir)/clutter-keysyms.h \
|
clutter-keysyms.h \
|
||||||
$(srcdir)/clutter-util.h \
|
clutter-util.h \
|
||||||
$(srcdir)/clutter-media.h \
|
clutter-media.h \
|
||||||
$(srcdir)/clutter-event.h \
|
clutter-event.h \
|
||||||
$(srcdir)/clutter-color.h \
|
clutter-color.h \
|
||||||
$(srcdir)/clutter-timeline.h \
|
clutter-timeline.h \
|
||||||
$(srcdir)/clutter-actor.h \
|
clutter-actor.h \
|
||||||
$(srcdir)/clutter-group.h \
|
clutter-group.h \
|
||||||
$(srcdir)/clutter-stage.h \
|
clutter-stage.h \
|
||||||
$(srcdir)/clutter-rectangle.h \
|
clutter-rectangle.h \
|
||||||
$(srcdir)/clutter-texture.h \
|
clutter-texture.h \
|
||||||
$(srcdir)/clutter-clone-texture.h \
|
clutter-clone-texture.h \
|
||||||
$(srcdir)/clutter-video-texture.h \
|
clutter-video-texture.h \
|
||||||
$(srcdir)/clutter-label.h \
|
clutter-label.h \
|
||||||
$(srcdir)/clutter-main.h
|
clutter-main.h
|
||||||
|
|
||||||
clutter-marshal.h: clutter-marshal.list
|
clutter-marshal.h: clutter-marshal.list
|
||||||
( $(GLIB_GENMARSHAL) --prefix=clutter_marshal \
|
( $(GLIB_GENMARSHAL) --prefix=clutter_marshal \
|
||||||
|
@ -403,6 +403,8 @@ clutter_stage_realize (ClutterActor *actor)
|
|||||||
priv->xwin,
|
priv->xwin,
|
||||||
StructureNotifyMask
|
StructureNotifyMask
|
||||||
|ExposureMask
|
|ExposureMask
|
||||||
|
/* FIXME: we may want to eplicity enable MotionMask */
|
||||||
|
|PointerMotionMask
|
||||||
|KeyPressMask
|
|KeyPressMask
|
||||||
|KeyReleaseMask
|
|KeyReleaseMask
|
||||||
|ButtonPressMask
|
|ButtonPressMask
|
||||||
@ -1058,7 +1060,8 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
|
|||||||
g_print ("Hit at %i\n", buff[i * 4 + 3]);
|
g_print ("Hit at %i\n", buff[i * 4 + 3]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage), buff[3]);
|
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage),
|
||||||
|
buff[(hits-1) * 4 + 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_gl_viewport (stage);
|
sync_gl_viewport (stage);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
noinst_PROGRAMS = test test-video video-cube test-text super-oh
|
noinst_PROGRAMS = test video-player video-cube super-oh
|
||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)/
|
INCLUDES = -I$(top_srcdir)/
|
||||||
|
|
||||||
@ -10,9 +10,9 @@ test_LDFLAGS = \
|
|||||||
$(GCONF_LIBS) \
|
$(GCONF_LIBS) \
|
||||||
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
||||||
|
|
||||||
test_video_SOURCES = test-video.c
|
video_player_SOURCES = video-player.c
|
||||||
test_video_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
video_player_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||||
test_video_LDFLAGS = \
|
video_player_LDFLAGS = \
|
||||||
$(CLUTTER_LIBS) \
|
$(CLUTTER_LIBS) \
|
||||||
$(GST_LIBS) \
|
$(GST_LIBS) \
|
||||||
$(GCONF_LIBS) \
|
$(GCONF_LIBS) \
|
||||||
@ -26,14 +26,6 @@ video_cube_LDFLAGS = \
|
|||||||
$(GCONF_LIBS) \
|
$(GCONF_LIBS) \
|
||||||
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
||||||
|
|
||||||
test_text_SOURCES = test-text.c
|
|
||||||
test_text_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
|
||||||
test_text_LDFLAGS = \
|
|
||||||
$(CLUTTER_LIBS) \
|
|
||||||
$(GST_LIBS) \
|
|
||||||
$(GCONF_LIBS) \
|
|
||||||
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
|
||||||
|
|
||||||
super_oh_SOURCES = super-oh.c
|
super_oh_SOURCES = super-oh.c
|
||||||
super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
super_oh_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||||
super_oh_LDFLAGS = \
|
super_oh_LDFLAGS = \
|
||||||
@ -42,4 +34,9 @@ super_oh_LDFLAGS = \
|
|||||||
$(GCONF_LIBS) \
|
$(GCONF_LIBS) \
|
||||||
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
||||||
|
|
||||||
EXTRA_DIST = redhand.png clutter-logo-800x600.png
|
EXTRA_DIST = redhand.png \
|
||||||
|
clutter-logo-800x600.png \
|
||||||
|
media-actions-pause.png \
|
||||||
|
media-actions-start.png \
|
||||||
|
vid-panel.png \
|
||||||
|
README
|
||||||
|
37
examples/README
Normal file
37
examples/README
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
examples/
|
||||||
|
===
|
||||||
|
|
||||||
|
This directory contains a number of simple hacks come tests come
|
||||||
|
examples come clutter demos.
|
||||||
|
|
||||||
|
There are:
|
||||||
|
|
||||||
|
o test
|
||||||
|
|
||||||
|
Lots of randomness. Scratchpad to test new features.
|
||||||
|
|
||||||
|
o test.py
|
||||||
|
|
||||||
|
Like above but more randomness in python.
|
||||||
|
|
||||||
|
o super-oh
|
||||||
|
|
||||||
|
Spinning OH logos. Click to dissapear.
|
||||||
|
|
||||||
|
o video-player.
|
||||||
|
|
||||||
|
Simple fullscreen video player.
|
||||||
|
|
||||||
|
- Move mouse to see controls.
|
||||||
|
- Hit q or Esc to exit, p to toggle pause state.
|
||||||
|
- Has some useless cheesy effects built in.
|
||||||
|
- Hit e to flip the video.
|
||||||
|
|
||||||
|
o video-cube.
|
||||||
|
|
||||||
|
Pure evil. A nasty hack to do a video cube with clutter.
|
||||||
|
Could be done much nicer.
|
||||||
|
|
||||||
|
|
||||||
|
Also see http://svn.o-hand.com/repos/misc/trunk/opt for a simple
|
||||||
|
clutter based presentation program.
|
BIN
examples/media-actions-pause.png
Normal file
BIN
examples/media-actions-pause.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
BIN
examples/media-actions-start.png
Normal file
BIN
examples/media-actions-start.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.9 KiB |
@ -1,158 +0,0 @@
|
|||||||
#include <clutter/clutter.h>
|
|
||||||
|
|
||||||
ClutterActor *rect; /* um... */
|
|
||||||
|
|
||||||
|
|
||||||
void input_cb (ClutterStage *stage,
|
|
||||||
ClutterEvent *event,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterVideoTexture *vtex = CLUTTER_VIDEO_TEXTURE(user_data);
|
|
||||||
static gint paused = 0;
|
|
||||||
|
|
||||||
if (event->type == CLUTTER_KEY_RELEASE)
|
|
||||||
{
|
|
||||||
if (paused)
|
|
||||||
{
|
|
||||||
clutter_media_set_playing (CLUTTER_MEDIA(vtex), TRUE);
|
|
||||||
paused = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
clutter_media_set_playing (CLUTTER_MEDIA(vtex), FALSE);
|
|
||||||
paused = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
size_change (ClutterTexture *texture,
|
|
||||||
gint width,
|
|
||||||
gint height,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterActor *stage;
|
|
||||||
ClutterGeometry stage_geom;
|
|
||||||
gint vid_width, vid_height, new_y, new_height;
|
|
||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
|
||||||
|
|
||||||
clutter_actor_get_geometry (stage, &stage_geom);
|
|
||||||
|
|
||||||
clutter_texture_get_base_size (texture, &vid_width, &vid_height);
|
|
||||||
|
|
||||||
printf("*** vid : %ix%i stage %ix%i ***\n",
|
|
||||||
vid_width, vid_height, stage_geom.width, stage_geom.height);
|
|
||||||
|
|
||||||
|
|
||||||
new_height = ( vid_height * stage_geom.width ) / vid_width;
|
|
||||||
new_y = (stage_geom.height - new_height) / 2;
|
|
||||||
|
|
||||||
clutter_actor_set_position (CLUTTER_ACTOR (texture), 0, new_y);
|
|
||||||
|
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture),
|
|
||||||
stage_geom.width,
|
|
||||||
new_height);
|
|
||||||
|
|
||||||
// clutter_actor_set_opacity (CLUTTER_ACTOR (texture), 50);
|
|
||||||
|
|
||||||
printf("*** Pos set to +%i+%i , %ix%i ***\n",
|
|
||||||
0, new_y, stage_geom.width, new_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
tick (GObject *object,
|
|
||||||
GParamSpec *pspec,
|
|
||||||
ClutterLabel *label)
|
|
||||||
{
|
|
||||||
ClutterVideoTexture *vtex;
|
|
||||||
gint w, h, position, duration;
|
|
||||||
gchar buf[256];
|
|
||||||
|
|
||||||
vtex = CLUTTER_VIDEO_TEXTURE(object);
|
|
||||||
|
|
||||||
position = clutter_media_get_position (CLUTTER_MEDIA(vtex));
|
|
||||||
duration = clutter_media_get_duration (CLUTTER_MEDIA(vtex));
|
|
||||||
|
|
||||||
g_snprintf(buf, 256, "%i / %i", position, duration);
|
|
||||||
|
|
||||||
clutter_label_set_text (label, buf);
|
|
||||||
|
|
||||||
clutter_texture_get_base_size (CLUTTER_TEXTURE(label), &w, &h);
|
|
||||||
clutter_actor_set_size(rect, w+10, h+10);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char *argv[])
|
|
||||||
{
|
|
||||||
ClutterActor *label, *vtexture, *ctexture;
|
|
||||||
ClutterActor *stage;
|
|
||||||
ClutterColor rect_color = { 0xde, 0xde, 0xdf, 0xaa };
|
|
||||||
ClutterColor stage_color = { 0x00, 0x00, 0x00, 0x00 };
|
|
||||||
GError *err = NULL;
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
g_error("%s <video file>", argv[0]);
|
|
||||||
|
|
||||||
clutter_init (&argc, &argv);
|
|
||||||
|
|
||||||
vtexture = clutter_video_texture_new ();
|
|
||||||
|
|
||||||
clutter_media_set_filename(CLUTTER_MEDIA(vtexture), argv[1]);
|
|
||||||
|
|
||||||
stage = clutter_stage_get_default ();
|
|
||||||
|
|
||||||
/* Broken..
|
|
||||||
g_object_set(vtexture, "repeat-x", TRUE, NULL);
|
|
||||||
g_object_set(vtexture, "repeat-y", TRUE, NULL);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (vtexture == NULL || err != NULL)
|
|
||||||
{
|
|
||||||
g_error("failed to create vtexture, err: %s", err->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
label = clutter_label_new_with_text ("Sans Bold 24", "Loading...");
|
|
||||||
|
|
||||||
clutter_actor_set_position(label, 10, 10);
|
|
||||||
|
|
||||||
rect = clutter_rectangle_new_with_color (&rect_color);
|
|
||||||
clutter_actor_set_size(rect, 0, 0);
|
|
||||||
clutter_actor_set_position(rect, 5, 5);
|
|
||||||
|
|
||||||
ctexture = clutter_clone_texture_new (CLUTTER_TEXTURE(vtexture));
|
|
||||||
clutter_actor_set_opacity (CLUTTER_ACTOR (ctexture), 100);
|
|
||||||
|
|
||||||
clutter_actor_set_size (ctexture, 640, 50);
|
|
||||||
clutter_actor_set_position (ctexture, 0, 430);
|
|
||||||
|
|
||||||
clutter_group_add_many (CLUTTER_GROUP (stage),
|
|
||||||
vtexture, rect, label, ctexture, NULL);
|
|
||||||
|
|
||||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
|
||||||
|
|
||||||
g_signal_connect (stage, "input-event",
|
|
||||||
G_CALLBACK (input_cb),
|
|
||||||
vtexture);
|
|
||||||
|
|
||||||
clutter_group_show_all (CLUTTER_GROUP (stage));
|
|
||||||
|
|
||||||
clutter_media_set_playing (CLUTTER_MEDIA(vtexture), TRUE);
|
|
||||||
|
|
||||||
g_signal_connect (CLUTTER_MEDIA(vtexture),
|
|
||||||
"notify::position",
|
|
||||||
G_CALLBACK (tick),
|
|
||||||
label);
|
|
||||||
|
|
||||||
g_object_set (G_OBJECT(vtexture), "sync-size", FALSE, NULL);
|
|
||||||
|
|
||||||
g_signal_connect (CLUTTER_TEXTURE(vtexture),
|
|
||||||
"size-change",
|
|
||||||
G_CALLBACK (size_change), NULL);
|
|
||||||
|
|
||||||
clutter_main();
|
|
||||||
|
|
||||||
g_object_unref (stage);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -91,6 +91,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
para = clutter_label_new_with_text ("Sans 24", PARA_TEXT);
|
para = clutter_label_new_with_text ("Sans 24", PARA_TEXT);
|
||||||
clutter_actor_set_position(para, 10, 10);
|
clutter_actor_set_position(para, 10, 10);
|
||||||
|
clutter_label_set_text_extents (CLUTTER_LABEL(para), 200, 0);
|
||||||
|
|
||||||
clutter_group_add (CLUTTER_GROUP (stage), texture);
|
clutter_group_add (CLUTTER_GROUP (stage), texture);
|
||||||
clutter_group_add (CLUTTER_GROUP (stage), label);
|
clutter_group_add (CLUTTER_GROUP (stage), label);
|
||||||
|
BIN
examples/vid-panel.png
Normal file
BIN
examples/vid-panel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
@ -228,7 +228,7 @@ int
|
|||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ClutterActor *label, *texture, *vtexture;
|
ClutterActor *label, *texture, *vtexture;
|
||||||
ClutterActor *stage = clutter_stage_get_default ();
|
ClutterActor *stage;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GError *err = NULL;
|
GError *err = NULL;
|
||||||
|
|
||||||
@ -237,6 +237,8 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
clutter_init (&argc, &argv);
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
|
pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
|
||||||
|
|
||||||
if (!pixbuf)
|
if (!pixbuf)
|
||||||
@ -254,7 +256,6 @@ main (int argc, char *argv[])
|
|||||||
g_error("failed to create vtexture, err: %s", err->message);
|
g_error("failed to create vtexture, err: %s", err->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
clutter_media_set_filename (CLUTTER_MEDIA(vtexture), argv[1]);
|
clutter_media_set_filename (CLUTTER_MEDIA(vtexture), argv[1]);
|
||||||
|
|
||||||
clutter_group_add (CLUTTER_GROUP (stage), texture);
|
clutter_group_add (CLUTTER_GROUP (stage), texture);
|
||||||
|
383
examples/video-player.c
Normal file
383
examples/video-player.c
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#define SEEK_H 20
|
||||||
|
#define SEEK_W 690
|
||||||
|
|
||||||
|
typedef struct VideoApp
|
||||||
|
{
|
||||||
|
ClutterActor *vtexture;
|
||||||
|
|
||||||
|
ClutterActor *control, *control_bg, *control_play, *control_pause,
|
||||||
|
*control_seek1, *control_seek2, *control_seekbar, *control_label;
|
||||||
|
gboolean controls_showing, paused;
|
||||||
|
guint controls_timeout;
|
||||||
|
ClutterTimeline *controls_tl, *effect1_tl;
|
||||||
|
}
|
||||||
|
VideoApp;
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_controls (VideoApp *app, gboolean vis);
|
||||||
|
|
||||||
|
void
|
||||||
|
control_tl_cb (ClutterTimeline *timeline,
|
||||||
|
gint frame_num,
|
||||||
|
VideoApp *app)
|
||||||
|
{
|
||||||
|
guint8 opacity;
|
||||||
|
|
||||||
|
clutter_group_show_all (CLUTTER_GROUP (app->control));
|
||||||
|
clutter_actor_hide (app->paused ? app->control_pause : app->control_play);
|
||||||
|
clutter_actor_show (app->paused ? app->control_play : app->control_pause);
|
||||||
|
|
||||||
|
opacity = ( frame_num * 0xde ) / clutter_timeline_get_n_frames(timeline);
|
||||||
|
|
||||||
|
if (!app->controls_showing)
|
||||||
|
opacity = 0xde - opacity;
|
||||||
|
|
||||||
|
clutter_actor_set_opacity (app->control, opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
control_tl_complete_cb (ClutterTimeline *timeline,
|
||||||
|
VideoApp *app)
|
||||||
|
{
|
||||||
|
if (!app->controls_showing)
|
||||||
|
clutter_group_hide_all (CLUTTER_GROUP (app->control));
|
||||||
|
|
||||||
|
app->controls_timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
controls_timeout_cb (VideoApp *app)
|
||||||
|
{
|
||||||
|
show_controls (app, FALSE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
show_controls (VideoApp *app, gboolean vis)
|
||||||
|
{
|
||||||
|
if (clutter_timeline_is_playing (app->controls_tl))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (vis == TRUE && app->controls_showing == FALSE)
|
||||||
|
{
|
||||||
|
app->controls_showing = TRUE;
|
||||||
|
clutter_timeline_start (app->controls_tl);
|
||||||
|
|
||||||
|
app->controls_timeout = g_timeout_add (5 * 1000,
|
||||||
|
(GSourceFunc)controls_timeout_cb,
|
||||||
|
app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vis == TRUE && app->controls_showing == TRUE)
|
||||||
|
{
|
||||||
|
if (app->controls_timeout)
|
||||||
|
{
|
||||||
|
g_source_remove (app->controls_timeout);
|
||||||
|
|
||||||
|
app->controls_timeout
|
||||||
|
= g_timeout_add (5 * 1000,
|
||||||
|
(GSourceFunc)controls_timeout_cb,
|
||||||
|
app);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vis == FALSE && app->controls_showing == TRUE)
|
||||||
|
{
|
||||||
|
app->controls_showing = FALSE;
|
||||||
|
clutter_timeline_start (app->controls_tl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toggle_pause_state (VideoApp *app)
|
||||||
|
{
|
||||||
|
if (app->paused)
|
||||||
|
{
|
||||||
|
clutter_media_set_playing (CLUTTER_MEDIA(app->vtexture),
|
||||||
|
TRUE);
|
||||||
|
app->paused = FALSE;
|
||||||
|
clutter_actor_hide (app->control_play);
|
||||||
|
clutter_actor_show (app->control_pause);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_media_set_playing (CLUTTER_MEDIA(app->vtexture),
|
||||||
|
FALSE);
|
||||||
|
app->paused = TRUE;
|
||||||
|
clutter_actor_hide (app->control_pause);
|
||||||
|
clutter_actor_show (app->control_play);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
input_cb (ClutterStage *stage,
|
||||||
|
ClutterEvent *event,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
VideoApp *app = (VideoApp*)user_data;
|
||||||
|
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case CLUTTER_MOTION:
|
||||||
|
show_controls (app, TRUE);
|
||||||
|
break;
|
||||||
|
case CLUTTER_BUTTON_PRESS:
|
||||||
|
if (app->controls_showing)
|
||||||
|
{
|
||||||
|
ClutterActor *actor;
|
||||||
|
ClutterButtonEvent *bev = (ClutterButtonEvent *) event;
|
||||||
|
|
||||||
|
actor
|
||||||
|
= clutter_stage_get_actor_at_pos
|
||||||
|
(CLUTTER_STAGE(clutter_stage_get_default()),
|
||||||
|
bev->x, bev->y);
|
||||||
|
|
||||||
|
if (actor == app->control_pause || actor == app->control_play)
|
||||||
|
{
|
||||||
|
toggle_pause_state (app);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor == app->control_seek1
|
||||||
|
|| actor == app->control_seek2
|
||||||
|
|| actor == app->control_seekbar)
|
||||||
|
{
|
||||||
|
gint x, y, dist, pos;
|
||||||
|
|
||||||
|
clutter_actor_get_abs_position (app->control_seekbar, &x, &y);
|
||||||
|
|
||||||
|
dist = bev->x - x;
|
||||||
|
|
||||||
|
CLAMP(dist, 0, SEEK_W);
|
||||||
|
|
||||||
|
pos = (dist * clutter_media_get_duration
|
||||||
|
(CLUTTER_MEDIA(app->vtexture))) / SEEK_W;
|
||||||
|
|
||||||
|
clutter_media_set_position (CLUTTER_MEDIA(app->vtexture),
|
||||||
|
pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLUTTER_KEY_RELEASE:
|
||||||
|
{
|
||||||
|
ClutterKeyEvent* kev = (ClutterKeyEvent *) event;
|
||||||
|
|
||||||
|
switch (clutter_key_event_symbol (kev))
|
||||||
|
{
|
||||||
|
case CLUTTER_q:
|
||||||
|
case CLUTTER_Escape:
|
||||||
|
clutter_main_quit ();
|
||||||
|
break;
|
||||||
|
case CLUTTER_e:
|
||||||
|
if (!clutter_timeline_is_playing (app->effect1_tl))
|
||||||
|
clutter_timeline_start (app->effect1_tl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
toggle_pause_state (app);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
size_change (ClutterTexture *texture,
|
||||||
|
gint width,
|
||||||
|
gint height,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterGeometry stage_geom;
|
||||||
|
gint vid_width, vid_height, new_y, new_height;
|
||||||
|
|
||||||
|
clutter_texture_get_base_size (texture, &vid_width, &vid_height);
|
||||||
|
|
||||||
|
new_height = ( vid_height * CLUTTER_STAGE_WIDTH() ) / vid_width;
|
||||||
|
new_y = ( CLUTTER_STAGE_HEIGHT() - new_height) / 2;
|
||||||
|
|
||||||
|
clutter_actor_set_position (CLUTTER_ACTOR (texture), 0, new_y);
|
||||||
|
|
||||||
|
clutter_actor_set_size (CLUTTER_ACTOR (texture),
|
||||||
|
CLUTTER_STAGE_WIDTH(),
|
||||||
|
new_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tick (GObject *object,
|
||||||
|
GParamSpec *pspec,
|
||||||
|
VideoApp *app)
|
||||||
|
{
|
||||||
|
ClutterVideoTexture *vtex;
|
||||||
|
gint w, h, position, duration, seek_w;
|
||||||
|
gchar buf[256];
|
||||||
|
|
||||||
|
vtex = CLUTTER_VIDEO_TEXTURE(object);
|
||||||
|
|
||||||
|
position = clutter_media_get_position (CLUTTER_MEDIA(vtex));
|
||||||
|
duration = clutter_media_get_duration (CLUTTER_MEDIA(vtex));
|
||||||
|
|
||||||
|
if (duration == 0 || position == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
clutter_actor_set_size (app->control_seekbar,
|
||||||
|
(position * SEEK_W) / duration,
|
||||||
|
SEEK_H);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
effect1_tl_cb (ClutterTimeline *timeline,
|
||||||
|
gint frame_num,
|
||||||
|
VideoApp *app)
|
||||||
|
{
|
||||||
|
clutter_actor_rotate_y (app->vtexture,
|
||||||
|
frame_num * 12,
|
||||||
|
CLUTTER_STAGE_WIDTH()/2,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
VideoApp *app = NULL;
|
||||||
|
ClutterActor *stage;
|
||||||
|
ClutterColor stage_color = { 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
ClutterColor control_color1 = { 73, 74, 77, 0xee };
|
||||||
|
ClutterColor control_color2 = { 0xcc, 0xcc, 0xcc, 0xff };
|
||||||
|
GdkPixbuf *pixb;
|
||||||
|
gint x,y;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
g_error("%s <video file>", argv[0]);
|
||||||
|
|
||||||
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
g_object_set (stage, "fullscreen", TRUE, NULL);
|
||||||
|
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||||
|
|
||||||
|
app = g_new0(VideoApp, 1);
|
||||||
|
|
||||||
|
app->vtexture = clutter_video_texture_new ();
|
||||||
|
|
||||||
|
if (app->vtexture == NULL)
|
||||||
|
{
|
||||||
|
g_error("failed to create vtexture");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dont let the underlying pixbuf dictate size */
|
||||||
|
g_object_set (G_OBJECT(app->vtexture), "sync-size", FALSE, NULL);
|
||||||
|
|
||||||
|
/* Handle it ourselves so can scale up for fullscreen better */
|
||||||
|
g_signal_connect (CLUTTER_TEXTURE(app->vtexture),
|
||||||
|
"size-change",
|
||||||
|
G_CALLBACK (size_change), NULL);
|
||||||
|
|
||||||
|
/* Load up out video texture */
|
||||||
|
clutter_media_set_filename(CLUTTER_MEDIA(app->vtexture), argv[1]);
|
||||||
|
|
||||||
|
/* Create the control UI */
|
||||||
|
app->control = clutter_group_new ();
|
||||||
|
|
||||||
|
pixb = gdk_pixbuf_new_from_file ("vid-panel.png", NULL);
|
||||||
|
|
||||||
|
if (pixb == NULL)
|
||||||
|
g_error("Unable to load vid-panel.png");
|
||||||
|
|
||||||
|
app->control_bg = clutter_texture_new_from_pixbuf (pixb);
|
||||||
|
|
||||||
|
pixb = gdk_pixbuf_new_from_file("media-actions-start.png", NULL);
|
||||||
|
|
||||||
|
if (pixb == NULL)
|
||||||
|
g_error("Unable to load media-actions-start.png");
|
||||||
|
|
||||||
|
app->control_play = clutter_texture_new_from_pixbuf (pixb);
|
||||||
|
|
||||||
|
pixb = gdk_pixbuf_new_from_file("media-actions-pause.png", NULL);
|
||||||
|
|
||||||
|
if (pixb == NULL)
|
||||||
|
g_error("Unable to load media-actions-pause.png");
|
||||||
|
|
||||||
|
app->control_pause = clutter_texture_new_from_pixbuf (pixb);
|
||||||
|
|
||||||
|
app->control_seek1 = clutter_rectangle_new_with_color (&control_color1);
|
||||||
|
app->control_seek2 = clutter_rectangle_new_with_color (&control_color2);
|
||||||
|
app->control_seekbar = clutter_rectangle_new_with_color (&control_color1);
|
||||||
|
clutter_actor_set_opacity (app->control_seekbar, 0x99);
|
||||||
|
|
||||||
|
app->control_label
|
||||||
|
= clutter_label_new_with_text("Sans Bold 24",
|
||||||
|
g_path_get_basename(argv[1]));
|
||||||
|
clutter_label_set_color (CLUTTER_LABEL(app->control_label), &control_color1);
|
||||||
|
|
||||||
|
clutter_group_add_many (CLUTTER_GROUP (app->control),
|
||||||
|
app->control_bg,
|
||||||
|
app->control_play,
|
||||||
|
app->control_pause,
|
||||||
|
app->control_seek1,
|
||||||
|
app->control_seek2,
|
||||||
|
app->control_seekbar,
|
||||||
|
app->control_label,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
x = (CLUTTER_STAGE_WIDTH() - clutter_actor_get_width(app->control))/2;
|
||||||
|
y = CLUTTER_STAGE_HEIGHT() - (CLUTTER_STAGE_HEIGHT()/3);
|
||||||
|
|
||||||
|
clutter_actor_set_position (app->control, x, y);
|
||||||
|
clutter_actor_set_opacity (app->control, 0xee);
|
||||||
|
|
||||||
|
clutter_actor_set_position (app->control_play, 30, 30);
|
||||||
|
clutter_actor_set_position (app->control_pause, 30, 30);
|
||||||
|
|
||||||
|
clutter_actor_set_size (app->control_seek1, SEEK_W+10, SEEK_H+10);
|
||||||
|
clutter_actor_set_position (app->control_seek1, 200, 100);
|
||||||
|
clutter_actor_set_size (app->control_seek2, SEEK_W, SEEK_H);
|
||||||
|
clutter_actor_set_position (app->control_seek2, 205, 105);
|
||||||
|
clutter_actor_set_size (app->control_seekbar, 0, SEEK_H);
|
||||||
|
clutter_actor_set_position (app->control_seekbar, 205, 105);
|
||||||
|
|
||||||
|
clutter_actor_set_position (app->control_label, 200, 40);
|
||||||
|
|
||||||
|
/* Add control UI to stage */
|
||||||
|
clutter_group_add_many (CLUTTER_GROUP (stage),
|
||||||
|
app->vtexture, app->control, NULL);
|
||||||
|
|
||||||
|
/* hook up a time line for fading controls */
|
||||||
|
app->controls_tl = clutter_timeline_new (10, 30);
|
||||||
|
g_signal_connect (app->controls_tl, "new-frame",
|
||||||
|
G_CALLBACK (control_tl_cb), app);
|
||||||
|
g_signal_connect (app->controls_tl, "completed",
|
||||||
|
G_CALLBACK (control_tl_complete_cb), app);
|
||||||
|
|
||||||
|
|
||||||
|
app->effect1_tl = clutter_timeline_new (30, 90);
|
||||||
|
g_signal_connect (app->effect1_tl, "new-frame",
|
||||||
|
G_CALLBACK (effect1_tl_cb), app);
|
||||||
|
|
||||||
|
/* Hook up other events */
|
||||||
|
g_signal_connect (stage, "input-event",
|
||||||
|
G_CALLBACK (input_cb),
|
||||||
|
app);
|
||||||
|
|
||||||
|
g_signal_connect (CLUTTER_MEDIA(app->vtexture),
|
||||||
|
"notify::position",
|
||||||
|
G_CALLBACK (tick),
|
||||||
|
app);
|
||||||
|
|
||||||
|
clutter_media_set_playing (CLUTTER_MEDIA(app->vtexture), TRUE);
|
||||||
|
|
||||||
|
clutter_group_show_all (CLUTTER_GROUP (stage));
|
||||||
|
|
||||||
|
clutter_main();
|
||||||
|
|
||||||
|
g_object_unref (stage);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user