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>
|
||||
|
||||
* Makefile.am:
|
||||
|
@ -5,22 +5,22 @@ GLIB_MKENUMS=`pkg-config --variable=glib_mkenums glib-2.0`
|
||||
|
||||
BUILT_SOURCES = $(MARSHALFILES) $(ENUMFILES)
|
||||
|
||||
source_h = \
|
||||
$(srcdir)/clutter-keysyms.h \
|
||||
$(srcdir)/clutter-util.h \
|
||||
$(srcdir)/clutter-media.h \
|
||||
$(srcdir)/clutter-event.h \
|
||||
$(srcdir)/clutter-color.h \
|
||||
$(srcdir)/clutter-timeline.h \
|
||||
$(srcdir)/clutter-actor.h \
|
||||
$(srcdir)/clutter-group.h \
|
||||
$(srcdir)/clutter-stage.h \
|
||||
$(srcdir)/clutter-rectangle.h \
|
||||
$(srcdir)/clutter-texture.h \
|
||||
$(srcdir)/clutter-clone-texture.h \
|
||||
$(srcdir)/clutter-video-texture.h \
|
||||
$(srcdir)/clutter-label.h \
|
||||
$(srcdir)/clutter-main.h
|
||||
source_h = clutter.h \
|
||||
clutter-keysyms.h \
|
||||
clutter-util.h \
|
||||
clutter-media.h \
|
||||
clutter-event.h \
|
||||
clutter-color.h \
|
||||
clutter-timeline.h \
|
||||
clutter-actor.h \
|
||||
clutter-group.h \
|
||||
clutter-stage.h \
|
||||
clutter-rectangle.h \
|
||||
clutter-texture.h \
|
||||
clutter-clone-texture.h \
|
||||
clutter-video-texture.h \
|
||||
clutter-label.h \
|
||||
clutter-main.h
|
||||
|
||||
clutter-marshal.h: clutter-marshal.list
|
||||
( $(GLIB_GENMARSHAL) --prefix=clutter_marshal \
|
||||
|
@ -403,6 +403,8 @@ clutter_stage_realize (ClutterActor *actor)
|
||||
priv->xwin,
|
||||
StructureNotifyMask
|
||||
|ExposureMask
|
||||
/* FIXME: we may want to eplicity enable MotionMask */
|
||||
|PointerMotionMask
|
||||
|KeyPressMask
|
||||
|KeyReleaseMask
|
||||
|ButtonPressMask
|
||||
@ -1058,7 +1060,8 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
|
||||
g_print ("Hit at %i\n", buff[i * 4 + 3]);
|
||||
#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);
|
||||
|
@ -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)/
|
||||
|
||||
@ -10,9 +10,9 @@ test_LDFLAGS = \
|
||||
$(GCONF_LIBS) \
|
||||
$(top_builddir)/clutter/libclutter-@CLUTTER_MAJORMINOR@.la
|
||||
|
||||
test_video_SOURCES = test-video.c
|
||||
test_video_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
test_video_LDFLAGS = \
|
||||
video_player_SOURCES = video-player.c
|
||||
video_player_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
video_player_LDFLAGS = \
|
||||
$(CLUTTER_LIBS) \
|
||||
$(GST_LIBS) \
|
||||
$(GCONF_LIBS) \
|
||||
@ -26,14 +26,6 @@ video_cube_LDFLAGS = \
|
||||
$(GCONF_LIBS) \
|
||||
$(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_CFLAGS = $(CLUTTER_CFLAGS) $(GST_CFLAGS) $(GCONF_CFLAGS)
|
||||
super_oh_LDFLAGS = \
|
||||
@ -42,4 +34,9 @@ super_oh_LDFLAGS = \
|
||||
$(GCONF_LIBS) \
|
||||
$(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;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define PARA_TEXT "This is a paragraph of text to check both" \
|
||||
#define PARA_TEXT "This is a paragraph of text to check both " \
|
||||
"word wrapping and basic clipping."
|
||||
|
||||
void
|
||||
@ -91,6 +91,7 @@ main (int argc, char *argv[])
|
||||
|
||||
para = clutter_label_new_with_text ("Sans 24", PARA_TEXT);
|
||||
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), 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,15 +228,17 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
ClutterActor *label, *texture, *vtexture;
|
||||
ClutterActor *stage = clutter_stage_get_default ();
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *err = NULL;
|
||||
ClutterActor *stage;
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *err = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
g_error("%s <video file>", argv[0]);
|
||||
|
||||
clutter_init (&argc, &argv);
|
||||
|
||||
stage = clutter_stage_get_default ();
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file ("clutter-logo-800x600.png", NULL);
|
||||
|
||||
if (!pixbuf)
|
||||
@ -254,7 +256,6 @@ main (int argc, char *argv[])
|
||||
g_error("failed to create vtexture, err: %s", err->message);
|
||||
}
|
||||
|
||||
|
||||
clutter_media_set_filename (CLUTTER_MEDIA(vtexture), argv[1]);
|
||||
|
||||
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