[pinpoint/wip/speaker-view: 3/3] add the start of a speaker screen
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pinpoint/wip/speaker-view: 3/3] add the start of a speaker screen
- Date: Wed, 25 May 2011 16:12:50 +0000 (UTC)
commit 5f5995a7ab14d55980c303fc9dd953672c3f3b0a
Author: �yvind Kolås <pippin gimp org>
Date: Wed May 25 03:21:15 2011 +0100
add the start of a speaker screen
pinpoint.c | 7 +-
pinpoint.h | 9 ++-
pp-clutter.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 319 insertions(+), 10 deletions(-)
---
diff --git a/pinpoint.c b/pinpoint.c
index a575ca7..7ed0e20 100644
--- a/pinpoint.c
+++ b/pinpoint.c
@@ -64,6 +64,8 @@ static PinPointPoint default_point = {
.text_align = PP_TEXT_LEFT,
.use_markup = TRUE,
+ .duration = 30,
+
.speaker_notes = NULL,
.shading_color = "black",
@@ -74,6 +76,8 @@ static PinPointPoint default_point = {
.data = NULL,
};
+PinPointPoint *point_defaults = &default_point;
+
char *pp_output_filename = NULL;
gboolean pp_fullscreen = FALSE;
gboolean pp_maximized = FALSE;
@@ -157,8 +161,8 @@ main (int argc,
#endif
}
- renderer->init (renderer, argv[1]);
+ renderer->init (renderer, argv[1]);
pp_parse_slides (renderer, text);
g_free (text);
@@ -354,6 +358,7 @@ parse_setting (PinPointPoint *point,
IF_PREFIX("text-align=") ENUM(point->text_align, PPTextAlign, STRING);
IF_PREFIX("shading-color=") point->shading_color = STRING;
IF_PREFIX("shading-opacity=") point->shading_opacity = FLOAT;
+ IF_PREFIX("duration=") point->duration = FLOAT;
IF_PREFIX("command=") point->command = STRING;
IF_PREFIX("transition=") point->transition = STRING;
IF_EQUAL("fill") point->bg_scale = PP_BG_FILL;
diff --git a/pinpoint.h b/pinpoint.h
index 56d32f0..9f67920 100644
--- a/pinpoint.h
+++ b/pinpoint.h
@@ -88,6 +88,10 @@ struct _PinPointPoint
const char *text_color;
gboolean use_markup;
+ gfloat duration; /* on slide 0 the duration is the duration of the
+ presentation, other slides have a representation
+ of their portion of the presentation */
+
char *speaker_notes; /* speaker comments for the slide */
const char *shading_color;
@@ -103,8 +107,9 @@ extern char *pp_output_filename;
extern gboolean pp_fullscreen;
extern gboolean pp_maximized;
-extern GList *pp_slides; /* list of slide text */
-extern GList *pp_slidep; /* current slide */
+extern GList *pp_slides; /* list of slide text */
+extern GList *pp_slidep; /* current slide */
+extern PinPointPoint *point_defaults;
void pp_parse_slides (PinPointRenderer *renderer,
const char *slide_src);
diff --git a/pp-clutter.c b/pp-clutter.c
index 94a6237..37c6cd2 100644
--- a/pp-clutter.c
+++ b/pp-clutter.c
@@ -48,13 +48,21 @@
#define RESTX 4600.0
#define STARTPOS -3000.0
+static ClutterColor c_prog_bg = {0x11,0x11,0x11,0xff};
+static ClutterColor c_prog_slide = {0xff,0xff,0xff,0xbb};
+static ClutterColor c_prog_time = {0x66,0x66,0x66,0xff};
+
static ClutterColor black = {0x00,0x00,0x00,0xff};
+static ClutterColor gray = {0x77,0x77,0x77,0xff};
+static ClutterColor white = {0xff,0xff,0xff,0xff};
typedef struct _ClutterRenderer
{
PinPointRenderer renderer;
GHashTable *bg_cache; /* only load the same backgrounds once */
ClutterActor *stage;
+ ClutterActor *root;
+
ClutterActor *background;
ClutterActor *midground;
ClutterActor *shading;
@@ -64,6 +72,23 @@ typedef struct _ClutterRenderer
ClutterActor *commandline;
ClutterActor *commandline_shading;
+
+ gboolean speaker_mode;
+ ClutterActor *speaker_screen;
+ ClutterActor *speaker_slide_info;
+
+ ClutterActor *speaker_time_remaining;
+
+ GTimer *timer;
+ gboolean timer_paused;
+ int total_seconds;
+
+ ClutterActor *speaker_notes;
+ ClutterActor *speaker_clone;
+ ClutterActor *speaker_prog_bg;
+ ClutterActor *speaker_prog_slide;
+ ClutterActor *speaker_prog_time;
+
char *path; /* path of the file of the GFileMonitor callback */
float rest_y; /* where the text can rest */
} ClutterRenderer;
@@ -317,6 +342,107 @@ static gboolean stage_motion (ClutterActor *actor,
return FALSE;
}
+#define NORMAL_OPACITY 200
+#define HOVER_OPACITY 255
+
+static gboolean
+opacity_hover_enter (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ clutter_actor_set_opacity (actor, HOVER_OPACITY);
+ return FALSE;
+}
+
+
+static gboolean
+opacity_hover_leave (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ clutter_actor_set_opacity (actor, NORMAL_OPACITY);
+ return FALSE;
+}
+
+
+static gboolean
+elapsed_pressed (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ ClutterRenderer *renderer = CLUTTER_RENDERER (data);
+ if (renderer->timer_paused)
+ {
+ g_timer_continue (renderer->timer);
+ renderer->timer_paused = FALSE;
+ }
+ else
+ {
+ g_timer_stop (renderer->timer);
+ renderer->timer_paused = TRUE;
+ }
+ return TRUE;
+}
+
+static gfloat prev_x = 0.0;
+static gfloat prev_y = 0.0;
+
+static gboolean
+time_extend_capture (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ ClutterRenderer *renderer = CLUTTER_RENDERER (data);
+ float delta;
+ switch (event->any.type)
+ {
+ case CLUTTER_MOTION:
+ delta = event->motion.x - prev_x;
+ renderer->total_seconds += delta * 20;
+ if (renderer->total_seconds < 0)
+ renderer->total_seconds = 0;
+ g_printf ("%f\n", delta);
+
+ prev_x = event->motion.x;
+ prev_y = event->motion.y;
+ break;
+ case CLUTTER_BUTTON_RELEASE:
+ g_signal_handlers_disconnect_by_func (actor, time_extend_capture, data);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+total_pressed (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ g_printf ("total pressed! %p\n");
+ prev_x = event->button.x;
+ prev_y = event->button.y;
+ g_signal_connect (clutter_actor_get_stage (actor),
+ "captured-event", G_CALLBACK (time_extend_capture),
+ data);
+ return TRUE;
+}
+
+static gboolean
+remaining_pressed (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer data)
+{
+ g_printf ("remaining pressed! %p\n");
+ prev_x = event->button.x;
+ prev_y = event->button.y;
+ g_signal_connect (clutter_actor_get_stage (actor),
+ "captured-event", G_CALLBACK (time_extend_capture),
+ data);
+ return TRUE;
+}
+
+
static void
clutter_renderer_init (PinPointRenderer *pp_renderer,
char *pinpoint_file)
@@ -325,10 +451,11 @@ clutter_renderer_init (PinPointRenderer *pp_renderer,
GFileMonitor *monitor;
ClutterActor *stage;
- renderer->rest_y = STARTPOS;
-
- renderer->stage = stage = clutter_stage_get_default ();
+ renderer->speaker_mode = TRUE; /* enable rendering of speaker window */
+ renderer->stage = stage = clutter_stage_new ();
+ renderer->root = clutter_group_new ();
+ renderer->rest_y = STARTPOS;
renderer->background = clutter_group_new ();
renderer->midground = clutter_group_new ();
renderer->foreground = clutter_group_new ();
@@ -336,12 +463,18 @@ clutter_renderer_init (PinPointRenderer *pp_renderer,
renderer->shading = clutter_rectangle_new_with_color (&black);
renderer->commandline_shading = clutter_rectangle_new_with_color (&black);
renderer->commandline = clutter_text_new ();
+
clutter_actor_set_opacity (renderer->shading, 0x77);
clutter_actor_set_opacity (renderer->commandline_shading, 0x77);
clutter_container_add_actor (CLUTTER_CONTAINER (renderer->midground),
renderer->shading);
- clutter_container_add (CLUTTER_CONTAINER (stage),
+
+
+ clutter_container_add (CLUTTER_CONTAINER (renderer->stage),
+ renderer->root,
+ NULL);
+ clutter_container_add (CLUTTER_CONTAINER (renderer->root),
renderer->background,
renderer->midground,
renderer->foreground,
@@ -350,7 +483,77 @@ clutter_renderer_init (PinPointRenderer *pp_renderer,
renderer->commandline,
NULL);
+
+ if (renderer->speaker_mode)
+ {
+ renderer->speaker_screen = clutter_stage_new ();
+
+ renderer->speaker_notes = g_object_new (CLUTTER_TYPE_TEXT,
+ "x", 10.0,
+ "y", 20.0,
+ "font-name", "Sans 20px",
+ "color", &white,
+ NULL);
+ renderer->speaker_slide_info = g_object_new (CLUTTER_TYPE_TEXT,
+ "x", 10.0,
+ "y", 400.0,
+ "font-name", "Sans 20px",
+ "color", &gray,
+ NULL);
+
+ renderer->speaker_time_remaining = g_object_new (CLUTTER_TYPE_TEXT,
+ "x", 300.0,
+ "y", 340.0,
+ "opacity", NORMAL_OPACITY,
+ "font-name", "Sans 40px",
+ "text", "-3",
+ "reactive", TRUE,
+ "color", &white,
+ NULL);
+
+ g_signal_connect (renderer->speaker_time_remaining, "button-press-event",
+ G_CALLBACK (elapsed_pressed), renderer);
+
+
+ renderer->timer_paused = FALSE;
+ renderer->timer = g_timer_new ();
+
+ renderer->speaker_prog_bg = clutter_rectangle_new_with_color (&c_prog_bg);
+ renderer->speaker_prog_time = clutter_rectangle_new_with_color (&c_prog_time);
+ renderer->speaker_prog_slide = clutter_rectangle_new_with_color (&c_prog_slide);
+
+ clutter_stage_set_color (CLUTTER_STAGE (renderer->speaker_screen), &black);
+ clutter_stage_set_color (CLUTTER_STAGE (renderer->speaker_screen), &black);
+ clutter_stage_set_user_resizable (CLUTTER_STAGE (renderer->speaker_screen), TRUE);
+
+
+ clutter_container_add (CLUTTER_CONTAINER (renderer->speaker_screen),
+ renderer->speaker_notes,
+ renderer->speaker_slide_info,
+ renderer->speaker_prog_bg,
+ renderer->speaker_prog_time,
+ renderer->speaker_prog_slide,
+
+ renderer->speaker_time_remaining,
+
+ renderer->speaker_clone,
+ NULL);
+
+ /* offscreen creation for actor on different stage not supported */
+ //renderer->speaker_clone = clutter_texture_new_from_actor (renderer->root);
+ renderer->speaker_clone = clutter_clone_new (renderer->root);
+ clutter_container_add (CLUTTER_CONTAINER (renderer->speaker_screen),
+ renderer->speaker_clone,
+ NULL);
+
+
+ clutter_actor_show (renderer->speaker_screen);
+ }
+
+
clutter_actor_show (stage);
+
+
clutter_stage_set_color (CLUTTER_STAGE (stage), &black);
g_signal_connect (stage, "key-press-event",
G_CALLBACK (key_pressed), renderer);
@@ -385,10 +588,20 @@ clutter_renderer_init (PinPointRenderer *pp_renderer,
NULL, _destroy_surface);
}
+static gboolean update_speaker_screen (ClutterRenderer *renderer);
+
static void
-clutter_renderer_run (PinPointRenderer *renderer)
+clutter_renderer_run (PinPointRenderer *pp_renderer)
{
- show_slide (CLUTTER_RENDERER (renderer), FALSE);
+ ClutterRenderer *renderer = CLUTTER_RENDERER (pp_renderer);
+
+ show_slide (renderer, FALSE);
+
+ /* the presentaiton is not parsed at first initialization,.. */
+ renderer->total_seconds = point_defaults->duration * 60;
+
+ if (renderer->speaker_mode)
+ g_timeout_add (250, (GSourceFunc)update_speaker_screen, renderer);
clutter_main ();
}
@@ -792,6 +1005,88 @@ static void update_commandline_shading (ClutterRenderer *renderer)
NULL);
}
+static gboolean update_speaker_screen (ClutterRenderer *renderer)
+{
+ PinPointPoint *point;
+ int n_slides;
+ int slide_no;
+ point = pp_slidep->data;
+
+ if (point->speaker_notes)
+ clutter_text_set_text (CLUTTER_TEXT (renderer->speaker_notes),
+ point->speaker_notes);
+ else
+ clutter_text_set_text (CLUTTER_TEXT (renderer->speaker_notes), "");
+
+ { /* should draw rectangles representing progress instead... */
+ GString *str = g_string_new ("");
+ int i;
+ GList *iter;
+ for (iter = pp_slides, i=0; iter && iter != pp_slidep;
+ iter = iter->next, i++);
+
+ slide_no = i+1;
+ n_slides = g_list_length (pp_slides);
+
+ //g_string_printf (str, "%d / %d\n", i+1, g_list_length (pp_slides));
+ clutter_text_set_text (CLUTTER_TEXT (renderer->speaker_slide_info),
+ str->str);
+
+ {
+ int time = renderer->total_seconds -
+ g_timer_elapsed (renderer->timer, NULL);
+ g_string_printf (str, "%im%is\n", time / 60, time % 60);
+ clutter_text_set_text (CLUTTER_TEXT (renderer->speaker_time_remaining),
+ str->str);
+ }
+
+ g_string_assign (str, "");
+
+ g_string_free (str, TRUE);
+ }
+
+ {
+ float height = 40;
+ float nw = clutter_actor_get_width (renderer->speaker_screen);
+ float y = clutter_actor_get_height (renderer->speaker_screen) - height;
+ float elapsed_part = g_timer_elapsed (renderer->timer, NULL) / renderer->total_seconds;
+
+ clutter_actor_set_height (renderer->speaker_prog_bg, height);
+ clutter_actor_set_height (renderer->speaker_prog_slide, height);
+ clutter_actor_set_height (renderer->speaker_prog_time, height);
+ clutter_actor_set_y (renderer->speaker_prog_bg, y);
+ clutter_actor_set_y (renderer->speaker_prog_slide, y);
+ clutter_actor_set_y (renderer->speaker_prog_time, y);
+
+ clutter_actor_set_width (renderer->speaker_prog_bg, nw);
+
+
+ clutter_actor_set_x (renderer->speaker_prog_slide, nw * (1.0 * (slide_no-1) / n_slides));
+ clutter_actor_set_width (renderer->speaker_prog_slide, nw / n_slides);
+
+ clutter_actor_set_x (renderer->speaker_prog_time, nw * elapsed_part);
+
+ clutter_actor_set_width (renderer->speaker_prog_time, nw * (1.0-elapsed_part));
+ clutter_actor_set_height (renderer->speaker_prog_slide, height);
+ clutter_actor_set_height (renderer->speaker_prog_time, height);
+ }
+
+
+ {
+ float scale;
+ scale = clutter_actor_get_width (renderer->speaker_screen) / clutter_actor_get_width (renderer->stage) * 0.4;
+ clutter_actor_set_scale (renderer->speaker_clone, scale, scale);
+ }
+ clutter_actor_set_position (renderer->speaker_clone,
+ clutter_actor_get_width (renderer->speaker_screen) * 0.05,
+ clutter_actor_get_height (renderer->speaker_screen) * 0.3);
+ clutter_actor_set_clip (renderer->speaker_clone,
+ 0,0,
+ clutter_actor_get_width (renderer->stage),
+ clutter_actor_get_height (renderer->stage));
+ return TRUE;
+}
+
static void
show_slide (ClutterRenderer *renderer, gboolean backwards)
{
@@ -1106,7 +1401,6 @@ show_slide (ClutterRenderer *renderer, gboolean backwards)
text_x = clutter_actor_get_width (renderer->stage) * 0.05;
-
g_object_set (renderer->commandline,
"x", text_x,
"y", text_y,
@@ -1118,6 +1412,11 @@ show_slide (ClutterRenderer *renderer, gboolean backwards)
update_commandline_shading (renderer);
}
+
+ if (renderer->speaker_mode)
+ {
+ update_speaker_screen (renderer);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]