much select hacking
authorMatthew Allum <mallum@openedhand.com>
Mon, 23 May 2005 21:21:50 +0000 (21:21 +0000)
committerMatthew Allum <mallum@openedhand.com>
Mon, 23 May 2005 21:21:50 +0000 (21:21 +0000)
13 files changed:
ChangeLog
clutter/cltr-button.c
clutter/cltr-button.h
clutter/cltr-events.c
clutter/cltr-list.c
clutter/cltr-list.h
clutter/cltr-overlay.c
clutter/cltr-private.h
clutter/cltr-widget.c
clutter/cltr-widget.h
clutter/cltr-window.c
clutter/cltr-window.h
examples/select.c

index 456dd59..17f1fb6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2005-05-23  mallum,,,  <mallum@openedhand.com>
+
+       * clutter/cltr-button.c: (cltr_button_new_with_label),
+       (cltr_button_handle_xevent), (cltr_button_paint):
+       * clutter/cltr-button.h:
+       * clutter/cltr-events.c: (cltr_main_loop):
+       * clutter/cltr-list.c: (cltr_list_cell_new),
+       (cltr_list_append_cell), (cltr_list_update_layout),
+       (cltr_list_paint):
+       * clutter/cltr-list.h:
+       * clutter/cltr-overlay.c: (cltr_overlay_paint):
+       * clutter/cltr-private.h:
+       * clutter/cltr-widget.c: (cltr_widget_show),
+       (cltr_widget_show_all), (cltr_widget_add_child):
+       * clutter/cltr-widget.h:
+       * clutter/cltr-window.c: (cltr_window_show), (cltr_window_paint),
+       (cltr_window_handle_xevent), (cltr_window_post_paint),
+       (cltr_window_set_paint_funcs), (cltr_window_xwin),
+       (cltr_window_hide_cursor), (cltr_window_set_fullscreen):
+       * clutter/cltr-window.h:
+       * examples/select.c: (usage), (init_video_ctrl), (show_video_ctrl),
+       (populate), (cell_to_item), (handle_xevent), (zoom_out_complete),
+       (zoom_in_complete), (cell_activated), (main):
+       Much Select hacking
+
 2005-05-17  mallum,,,  <mallum@openedhand.com>
 
        * clutter/cltr-video.c: (cltr_video_get_pixbuf):
index cb26477..d022ae8 100644 (file)
@@ -73,7 +73,7 @@ cltr_button_new_with_label(const char  *label,
 
   button->label = CLTR_LABEL(cltr_label_new(label, font, col));
 
-  button->widget.width  = cltr_widget_width((CltrWidget*)button->label) + (2 * ( BUTTON_BORDER + BUTTON_PAD));
+  button->widget.width  =   cltr_widget_width((CltrWidget*)button->label) + (2 * ( BUTTON_BORDER + BUTTON_PAD));
   button->widget.height = cltr_widget_height((CltrWidget*)button->label) + ( 2 * ( BUTTON_BORDER + BUTTON_PAD));
 
   CLTR_DBG("width: %i, height %i", 
@@ -88,6 +88,34 @@ cltr_button_new_with_label(const char  *label,
   return CLTR_WIDGET(button);
 }
 
+void
+cltr_button_set_label(CltrButton  *button, 
+                     const char  *text,
+                     CltrFont    *font,
+                     PixbufPixel *col)
+{
+  int x, y;
+
+  if (button->label)
+    {
+      cltr_widget_remove_child(CLTR_WIDGET(button), 
+                              CLTR_WIDGET(button->label));
+
+      cltr_widget_unref(CLTR_WIDGET(button));
+      /* XXX free up pre-existing label */
+    }
+
+  button->label = CLTR_LABEL(cltr_label_new(text, font, col));
+
+  x = (cltr_widget_width(CLTR_WIDGET(button)) - cltr_widget_width(CLTR_WIDGET(button->label)))/2;
+
+  y = (cltr_widget_height(CLTR_WIDGET(button)) - cltr_widget_height(CLTR_WIDGET(button->label)))/2;
+
+  cltr_widget_add_child(CLTR_WIDGET(button), 
+                       CLTR_WIDGET(button->label), 
+                       x, y);
+}
+
 CltrWidget*
 cltr_button_new_with_pixbuf(Pixbuf *pixb)
 {
@@ -251,10 +279,10 @@ cltr_button_paint(CltrWidget *widget)
       glColor4f(1.0, 1.0, 1.0, 1.0);
     }
 
-  cltr_glu_rounded_rect(widget->x,
-                       widget->y,
-                       widget->x + widget->width,
-                       widget->y + widget->height,
+  cltr_glu_rounded_rect(cltr_widget_abs_x(widget),
+                       cltr_widget_abs_y(widget),
+                       cltr_widget_abs_x2(widget),
+                       cltr_widget_abs_y2(widget),
                        2, 5,
                        NULL);
 
index 9b0f0b7..c07ea79 100644 (file)
@@ -26,5 +26,10 @@ cltr_button_on_activate(CltrButton         *button,
                        CltrButtonActivate  callback,
                        void*               userdata);
 
+void
+cltr_button_set_label(CltrButton  *button, 
+                     const char  *text,
+                     CltrFont    *font,
+                     PixbufPixel *col);
 
 #endif
index 9b089c5..8f9557b 100644 (file)
@@ -169,6 +169,9 @@ cltr_main_loop()
          */
          cltr_widget_paint(CLTR_WIDGET(win));
 
+         /* pre paint in window paint method */
+         cltr_window_post_paint(win);
+
          /* Swap Buffers */
          glXSwapBuffers(ctx->xdpy, cltr_window_xwin(win));  
        }
index be517bc..2267990 100644 (file)
@@ -34,6 +34,8 @@ struct CltrList
 
 };
 
+#define PAD 10
+
 static void
 cltr_list_show(CltrWidget *widget);
 
@@ -61,7 +63,7 @@ cltr_list_cell_new(CltrList *list,
   ClutterFont  *font;
   PixbufPixel   pixel = { 0, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255};
 
-  font = font_new ("Sans Bold 32");
+  font = font_new ("Sans Bold 24");
 
   cell = g_malloc0(sizeof(CltrListCell));
 
@@ -70,7 +72,7 @@ cltr_list_cell_new(CltrList *list,
   cell->thumb_texture = cltr_texture_new(cell->thumb_pixb);
 
   cell->text_pixb = pixbuf_new(list->cell_width - (list->cell_width/4), 
-                              list->cell_height);
+                              (list->cell_height/2) - (2*PAD));
 
   pixbuf_fill_rect(cell->text_pixb, 0, 0, -1, -1, &pixel);
   font_draw(font, cell->text_pixb, text, 0, 0, &font_pixel);
@@ -126,25 +128,38 @@ cltr_list_append_cell(CltrList *list, CltrListCell *cell)
   list->n_cells++;
 }
 
+static void
+video_box_co_ords(CltrList    *list,
+                 CltrListCell *cell, 
+                 int          *x1, int *y1, int *x2, int *y2)
+{
+  CltrWidget *widget = CLTR_WIDGET(list);
+  int         vw, vh;
+
+  vh  = cltr_rect_y2(cell->rect) - cltr_rect_y1(cell->rect);
+  vh -= (PAD*2);
+  vw  = ( widget->width * vh ) / widget->height;
+  
+  *x1 = cltr_rect_x1(cell->rect) + PAD; *x2 = *x1 + vw;
+  *y1 = cltr_rect_y1(cell->rect) + PAD; *y2 = *y1 + vh;
+}
+
 /* 
- * This is messy hack cos, cells arn't real widgets :(
+ * This is messy hack as cells arn't real widgets :(
  *
  */
 gboolean
-cltr_list_get_active_cell_co_ords(CltrList *list,
-                                 int      *x1,
-                                 int      *y1,
-                                 int      *x2,
-                                 int      *y2)
+cltr_list_get_active_cell_video_box_co_ords(CltrList *list,
+                                           int      *x1,
+                                           int      *y1,
+                                           int      *x2,
+                                           int      *y2)
 {
   if (list->active_cell)
     {
       CltrListCell *cell = list->active_cell->data; 
 
-      *x1 = cltr_rect_x1(cell->rect);
-      *y1 = cltr_rect_y1(cell->rect);
-      *x2 = cltr_rect_x2(cell->rect);
-      *y2 = cltr_rect_y2(cell->rect);
+      video_box_co_ords(list, cell, x1, y1, x2, y2);
 
       return TRUE;
     }
@@ -366,9 +381,12 @@ cltr_list_paint(CltrWidget *widget)
   GList        *cell_item = NULL;
   CltrList     *list = CLTR_LIST(widget);
   CltrListCell *cell = NULL;
-  PixbufPixel col = { 0xff, 0, 0, 0xff };
+  int           last;
 
-  int       last;
+  PixbufPixel col       = { 0xff, 0, 0, 0xff };
+  PixbufPixel bgcol     = { 0xe7, 0xe7, 0xe7, 0xff };
+  PixbufPixel boxcol    = { 0xd7, 0xd7, 0xd7, 0xff };
+  PixbufPixel hlfontcol = { 0xff, 0x33, 0x66, 0xff };
 
   CLTR_MARK();
 
@@ -378,6 +396,10 @@ cltr_list_paint(CltrWidget *widget)
 
   glPushMatrix();
 
+  cltr_glu_set_color(&bgcol);
+
+  glRecti(0, 0, widget->width, widget->height);
+
   glEnable(GL_TEXTURE_2D);
 
   glEnable(GL_BLEND);
@@ -400,19 +422,19 @@ cltr_list_paint(CltrWidget *widget)
        {
          glDisable(GL_TEXTURE_2D);
 
-
-
          if (cell_item == list->active_cell && list->state == CLTR_LIST_STATE_BROWSE)
            col.b = 0xff;
          else
            col.b = 0x00;
 
+         cltr_glu_set_color(&boxcol);
+
          cltr_glu_rounded_rect_filled(cltr_rect_x1(cell->rect),
                                       cltr_rect_y1(cell->rect) + (5.0 * scale),
                                       cltr_rect_x2(cell->rect),
                                       cltr_rect_y2(cell->rect) - (5.0 * scale),
                                       10,
-                                      &col);
+                                      &boxcol);
 
          col.r = 0xff; col.g = 0xff;  col.b = 0xff; col.a = 0xff;
 
@@ -431,19 +453,32 @@ cltr_list_paint(CltrWidget *widget)
 
          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-         glColor4f(1.0, 1.0, 1.0, 1.0); 
 
-         cltr_texture_render_to_gl_quad(cell->text_texture,
-                                        cltr_rect_x1(cell->rect) + 100,
-                                        cltr_rect_y1(cell->rect) + 10,
-                                        cltr_rect_x2(cell->rect) - 100,
-                                        cltr_rect_y2(cell->rect) - 10);
+         {
+           /* Video Box */
+
+           int vx1, vx2, vy1, vy2;
+
+           video_box_co_ords(list, cell, &vx1, &vy1, &vx2, &vy2);
+
+           cltr_texture_render_to_gl_quad(cell->thumb_texture,
+                                          vx1, vy1, vx2, vy2);
+
+           /* Text */
 
-         cltr_texture_render_to_gl_quad(cell->thumb_texture,
-                                        cltr_rect_x1(cell->rect),
-                                        cltr_rect_y1(cell->rect),
-                                        cltr_rect_x1(cell->rect) + 80 ,
-                                        cltr_rect_y1(cell->rect) + 60);
+           if (cell_item == list->active_cell 
+               && list->state == CLTR_LIST_STATE_BROWSE)
+             cltr_glu_set_color(&hlfontcol);
+           else
+             glColor4f(0.4, 0.4, 0.4, 1.0); 
+           
+           cltr_texture_render_to_gl_quad(cell->text_texture,
+                                          vx2 + PAD,
+                                          vy1,
+                                          cltr_rect_x2(cell->rect) - PAD,
+                                          vy1 + (list->cell_height/2) - PAD);
+
+         }
 
          glDisable(GL_BLEND);
 
index 4ef7f31..ec2d6e0 100644 (file)
@@ -50,12 +50,11 @@ cltr_list_on_activate_cell(CltrList             *list,
                           gpointer             *userdata);
 
 gboolean
-cltr_list_get_active_cell_co_ords(CltrList *list,
-                                 int      *x1,
-                                 int      *y1,
-                                 int      *x2,
-                                 int      *y2);
-
+cltr_list_get_active_cell_video_box_co_ords(CltrList *list,
+                                           int      *x1,
+                                           int      *y1,
+                                           int      *x2,
+                                           int      *y2);
 
 void
 cltr_list_scroll_down(CltrList *list);
index c8d6520..b68103e 100644 (file)
@@ -52,7 +52,7 @@ cltr_overlay_paint(CltrWidget *widget)
 {
   glEnable(GL_BLEND);
 
-  glColor4f(0.5, 0.5, 0.5, 1.0);
+  glColor4f(0.5, 0.5, 0.5, 0.5);
 
   cltr_glu_rounded_rect_filled(widget->x,
                               widget->y,
index dd85679..e7247b4 100644 (file)
@@ -45,6 +45,7 @@ struct CltrWidget
   gboolean    visible;
 
   GList      *children;
+  int         refcnt;
 
   /* focus */
 
@@ -57,8 +58,7 @@ struct CltrWidget
   WidgetShowMethod    show;
   WidgetDestroyMethod destroy;
   WidgetFocusMethod   focus_in;
-  WidgetUnfocusMethod  focus_out;
-
+  WidgetUnfocusMethod focus_out;
   WidgetXEventHandler xevent_handler;
 
   /* Anim ref */
index 0cf9cb5..3d12337 100644 (file)
@@ -75,6 +75,17 @@ cltr_widget_show(CltrWidget *widget)
     }
 }
 
+void
+cltr_widget_unref(CltrWidget *widget)
+{
+  widget->refcnt--;
+
+  if (widget->refcnt < 0 && widget->destroy)
+    {
+      widget->destroy(widget);
+    }
+}
+
 
 /* XXX Focus hacks; 
  * 
@@ -175,6 +186,16 @@ cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y)
 
 }
 
+void
+cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child)
+{
+  g_list_remove(widget->children, child);
+
+  child->parent = NULL;
+  child->x      = 0;
+  child->y      = 0;
+}
+
 
 void
 cltr_widget_hide(CltrWidget *widget)
index c7bb377..ca106e0 100644 (file)
@@ -51,6 +51,9 @@ cltr_widget_show(CltrWidget *widget);
 void
 cltr_widget_paint(CltrWidget *widget);
 
+void
+cltr_widget_unref(CltrWidget *widget);
+
 gboolean
 cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
 
@@ -63,4 +66,7 @@ cltr_widget_queue_paint(CltrWidget *widget);
 void
 cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
 
+void
+cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child);
+
 #endif
index 38667f9..33beb83 100644 (file)
@@ -19,8 +19,13 @@ struct CltrWindow
   CltrCallback *pre_paint_hook, *post_paint_hook;
 
   CltrXEventCallback  xevent_cb;
-  void               *xevent_cb_data;
+  gpointer           *xevent_cb_data;
 
+  CltrCallback        post_paint_cb;
+  gpointer           *post_paint_cb_data;
+
+  CltrCallback        pre_paint_cb;
+  gpointer           *pre_paint_cb_data;
 };
 
 void
@@ -91,6 +96,10 @@ cltr_window_show(CltrWidget *widget)
 static void
 cltr_window_paint(CltrWidget *widget)
 {
+  CltrWindow         *win = CLTR_WINDOW(widget);
+
+  clrt_window_set_gl_viewport(win);
+
   glClear(GL_COLOR_BUFFER_BIT);
 
   glDisable(GL_LIGHTING); 
@@ -98,6 +107,8 @@ cltr_window_paint(CltrWidget *widget)
 
   glClearColor( 0.0, 0.0, 0.0, 0.0 ); /* needed for saturate to work */
 
+  if (win->pre_paint_cb)
+    win->pre_paint_cb(widget, win->pre_paint_cb_data);
 }
 
 static void
@@ -127,6 +138,13 @@ cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
     wm_handle_configure_request(w, &ev.xconfigure); break;
   */
 
+  if (xev->type == KeyPress)
+    {
+      if (XKeycodeToKeysym(xev->xkey.display, 
+                          xev->xkey.keycode, 0) == XK_Escape)
+       exit(0);
+    }
+
   /* XXX Very basic - assumes we are only interested in mouse clicks */
   if (win->focused_child)
     cltr_widget_handle_xevent(win->focused_child, xev);
@@ -139,6 +157,28 @@ cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
 
 /* window only methods */
 
+void
+cltr_window_post_paint(CltrWindow *win)
+{
+  if (win->post_paint_cb)
+    win->post_paint_cb(CLTR_WIDGET(win), win->post_paint_cb_data);
+}
+
+/* naming is a little odd */
+void
+cltr_window_set_paint_funcs(CltrWindow  *win,
+                           CltrCallback pre_paint,
+                           gpointer     pre_userdata,
+                           CltrCallback post_paint,
+                           gpointer     post_userdata)
+{
+  win->post_paint_cb      = post_paint;
+  win->post_paint_cb_data = post_userdata;
+  win->pre_paint_cb       = pre_paint;
+  win->pre_paint_cb_data = pre_userdata;
+}
+
+
 Window
 cltr_window_xwin(CltrWindow *win)
 {
@@ -146,6 +186,25 @@ cltr_window_xwin(CltrWindow *win)
 }
 
 void
+cltr_window_hide_cursor(CltrWindow *win)
+{
+  ClutterMainContext *ctx = CLTR_CONTEXT();
+  XColor              col;
+  Pixmap              pix;
+  Cursor              curs;
+
+  pix = XCreatePixmap (ctx->xdpy, win->xwin, 1, 1, 1);
+
+  memset (&col, 0, sizeof (col));
+
+  curs = XCreatePixmapCursor (ctx->xdpy, pix, pix, &col, &col, 1, 1);
+
+  XFreePixmap (ctx->xdpy, pix);
+
+  XDefineCursor(ctx->xdpy, win->xwin, curs);
+}
+
+void
 cltr_window_set_fullscreen(CltrWindow *win)
 {
   ClutterMainContext *ctx = CLTR_CONTEXT();
@@ -166,6 +225,8 @@ cltr_window_set_fullscreen(CltrWindow *win)
     XF86VidModeSwitchToMode (GLWin.dpy, GLWin.screen, &GLWin.deskMode);
     XF86VidModeSetViewPort (GLWin.dpy, GLWin.screen, 0, 0);
   */
+
+  cltr_window_hide_cursor(win);
 }
 
 
index 46c16b7..b0a3c68 100644 (file)
@@ -19,6 +19,9 @@ Window
 cltr_window_xwin(CltrWindow *win);
 
 void
+cltr_window_hide_cursor(CltrWindow *win);
+
+void
 cltr_window_set_fullscreen(CltrWindow *win);
 
 void
@@ -28,6 +31,8 @@ void
 cltr_window_on_xevent(CltrWindow         *win,
                      CltrXEventCallback  callback,
                      void               *userdata);
+void
+cltr_window_post_paint(CltrWindow *win);
 
 
 #endif
index 5201fb2..0bb80b0 100644 (file)
@@ -1,6 +1,7 @@
 #include <clutter/cltr.h>
 
 typedef struct ItemEntry ItemEntry;
+typedef struct VideoCtrls VideoCtrls;
 
 typedef struct DemoApp
 {
@@ -8,6 +9,7 @@ typedef struct DemoApp
   CltrWidget   *list;
   CltrWidget   *video;
   CltrWidget   *win;
+  VideoCtrls   *video_ctrls;
 
   GList        *items;
 
@@ -18,9 +20,27 @@ struct ItemEntry
   gchar        *nice_name;
   gchar        *path;
   gchar        *uri;
+  gint64        stoptime;
   CltrListCell *cell;
 };
 
+enum {
+  VIDEO_PLAY_BTN = 0,
+  VIDEO_STOP_BTN,
+  VIDEO_REWND_BTN,
+  VIDEO_FFWD_BTN,
+  N_VIDEO_BTNS
+};
+
+struct VideoCtrls
+{
+  ClutterFont *font;
+
+
+  CltrWidget *container;
+  CltrWidget *buttons[N_VIDEO_BTNS];
+};
+
 static void
 zoom_out_complete (CltrAnimator *anim, void *userdata);
 
@@ -31,6 +51,92 @@ usage(char *progname)
   exit(-1);
 }
 
+/* video control buttons */
+
+void
+init_video_ctrl(DemoApp *app)
+{
+  VideoCtrls *v;
+  int         width, height, x =0, y = 0;
+  PixbufPixel col = { 0xff, 0xff, 0xff, 0xff };
+
+  v = app->video_ctrls = g_malloc0(sizeof(VideoCtrls));
+
+  v->font = font_new ("Sans Bold 20");
+
+  font_get_pixel_size (v->font, "1234567890", &width, &height); 
+
+  height += 6;
+
+  v->container = cltr_overlay_new(width, height * N_VIDEO_BTNS);
+
+  v->buttons[VIDEO_PLAY_BTN] = cltr_button_new(width, height);
+
+  cltr_button_set_label(v->buttons[VIDEO_PLAY_BTN],
+                       "PlAY", v->font, &col);
+
+  cltr_widget_add_child(v->container, 
+                       v->buttons[VIDEO_PLAY_BTN],
+                       x, y);
+  y += height;
+
+  v->buttons[VIDEO_STOP_BTN] =  cltr_button_new(width, height); 
+
+  cltr_button_set_label(v->buttons[VIDEO_STOP_BTN],
+                       "STOP", 
+                       v->font, &col);
+
+  cltr_widget_add_child(v->container, 
+                       v->buttons[VIDEO_STOP_BTN],
+                       x, y);
+  y += height;
+
+
+  v->buttons[VIDEO_REWND_BTN] =  cltr_button_new(width, height);
+
+  cltr_button_set_label(v->buttons[VIDEO_REWND_BTN],
+                       "RWND", 
+                       v->font, &col);
+
+  cltr_widget_add_child(v->container, 
+                       v->buttons[VIDEO_REWND_BTN],
+                       x, y);
+  y += height;
+
+  v->buttons[VIDEO_FFWD_BTN] =  cltr_button_new(width, height);
+
+  cltr_button_set_label(v->buttons[VIDEO_FFWD_BTN],
+                       "FFWD", 
+                       v->font, &col);
+
+  cltr_widget_add_child(v->container, 
+                       v->buttons[VIDEO_FFWD_BTN],
+                       x, y);
+  y += height;
+  
+  cltr_widget_add_child(app->video, v->container, 100, 100);
+
+  /* focus */
+
+  cltr_widget_set_focus_next(v->buttons[VIDEO_PLAY_BTN], 
+                            v->buttons[VIDEO_STOP_BTN], 
+                            CLTR_SOUTH);
+
+  cltr_widget_set_focus_next(v->buttons[VIDEO_STOP_BTN], 
+                            v->buttons[VIDEO_PLAY_BTN], 
+                            CLTR_NORTH);
+
+}
+
+void
+show_video_ctrl(DemoApp *app)
+{
+  cltr_widget_show_all(app->video_ctrls->container);
+}
+
+
+
+/* ********************* */
 
 gboolean
 populate(DemoApp *app, char *path)
@@ -63,6 +169,7 @@ populate(DemoApp *app, char *path)
       ItemEntry    *new_item;
       char         *img_path;
 
+      /* Eeek! */
       if (!(g_str_has_suffix (entry, ".mpg") ||
            g_str_has_suffix (entry, ".MPG") ||
            g_str_has_suffix (entry, ".mpg4") ||
@@ -70,6 +177,8 @@ populate(DemoApp *app, char *path)
            g_str_has_suffix (entry, ".avi") ||
            g_str_has_suffix (entry, ".mov") ||
            g_str_has_suffix (entry, ".MOV") ||
+           g_str_has_suffix (entry, ".ogg") ||
+           g_str_has_suffix (entry, ".OGG") ||
            g_str_has_suffix (entry, ".AVI")))
        {
          continue;
@@ -157,10 +266,12 @@ handle_xevent(CltrWidget *win, XEvent *xev, void *cookie)
            PixbufPixel   col = { 0, 0, 0, 0xff };
            int           x1, y1, x2, y2;
 
-           // cltr_video_pause (CLTR_VIDEO(app->video));
+           cltr_video_pause (CLTR_VIDEO(app->video));
 
            item = cell_to_item(app, cltr_list_get_active_cell(app->list));
 
+           item->stoptime = cltr_video_get_time (app->video);
+
            snprintf(filename, 1024, "%s/%s.png", item->path, item->nice_name);
 
            spixb = cltr_video_get_pixbuf (app->video);
@@ -195,16 +306,15 @@ handle_xevent(CltrWidget *win, XEvent *xev, void *cookie)
 
            pixbuf_unref(dpixb);
 
-           cltr_list_get_active_cell_co_ords(CLTR_LIST(app->list), 
-                                             &x1, &y1, &x2, &y2);
-
+           cltr_list_get_active_cell_video_box_co_ords(CLTR_LIST(app->list), 
+                                                       &x1, &y1, &x2, &y2);
 
            cltr_video_stop (CLTR_VIDEO(app->video));
 
            /* zoom out, XXX old anim needs freeing */
 
            app->anim = cltr_animator_zoom_new(app->list,
-                                              x1, y1, x1+80, y1+60,
+                                              x1, y1, x2, y2,
                                               0,0,800,600);
 
            printf("got return, seek time %li, %i, %i \n", 
@@ -241,18 +351,32 @@ zoom_in_complete (CltrAnimator *anim, void *userdata)
   DemoApp      *app = (DemoApp*)userdata;
   ItemEntry    *item;
 
-  cltr_widget_hide(CLTR_WIDGET(app->list));
-
   /* cltr_animator_reset(anim); */
 
   item = cell_to_item(app, cltr_list_get_active_cell(app->list));
 
   cltr_video_set_source(CLTR_VIDEO(app->video), item->uri);
 
+  if (item->stoptime)
+    {
+      printf("*** seeking to %li\n", item->stoptime);
+      cltr_video_seek_time (CLTR_VIDEO(app->video), item->stoptime, NULL);
+    }
+
   cltr_video_play(CLTR_VIDEO(app->video), NULL);
 
+  if (item->stoptime)
+    {
+      printf("*** seeking to %li\n", item->stoptime);
+      cltr_video_seek_time (CLTR_VIDEO(app->video), item->stoptime, NULL);
+    }
+
   cltr_widget_show(app->video);
 
+  cltr_widget_hide(CLTR_WIDGET(app->list));
+
+  show_video_ctrl(app);
+
   cltr_window_on_xevent(CLTR_WINDOW(app->win), handle_xevent, app);
 }
 
@@ -265,19 +389,24 @@ cell_activated (CltrList     *list,
   int           x1, y1, x2, y2;
   static        have_added_child = 0; /* HACK */
 
-  cltr_list_get_active_cell_co_ords(CLTR_LIST(list), &x1, &y1, &x2, &y2);
-
-  app->anim = cltr_animator_zoom_new(CLTR_WIDGET(list),
-                                    0,0,800,600,
-                                    x1, y1, x1+80, y1+60);
+  cltr_list_get_active_cell_video_box_co_ords(CLTR_LIST(list), 
+                                             &x1, &y1, &x2, &y2);
 
-  if (!have_added_child)
-    cltr_widget_add_child(app->win, app->video, x1, y1);
-  else
+  if (app->video == NULL) 
     {
-      printf("x1: %i, y1: %i\n", x1, y1); 
+      /*
+      app->video = cltr_video_new(x2-x1, y2-y1);
+      cltr_widget_add_child(app->win, app->video, x1, y1);
+      */
+      app->video = cltr_video_new(800, 600);
+      cltr_widget_add_child(app->win, app->video, 0, 0);
+
+      init_video_ctrl(app);
     }
 
+  app->anim = cltr_animator_zoom_new(CLTR_WIDGET(list),
+                                    0,0,800,600,
+                                    x1, y1, x2, y2);
   have_added_child = 1;
 
   cltr_animator_run(app->anim, zoom_in_complete, app);
@@ -339,6 +468,8 @@ main(int argc, char **argv)
   if (want_fullscreen)
     cltr_window_set_fullscreen(CLTR_WINDOW(app->win));
 
+
+
   app->list = cltr_list_new(800, 600, 800, 600/5);
   
   if (!populate(app, movie_path))
@@ -346,12 +477,10 @@ main(int argc, char **argv)
 
   cltr_widget_add_child(app->win, app->list, 0, 0);
 
-  app->video = cltr_video_new(80, 60);
-
   cltr_window_focus_widget(CLTR_WINDOW(app->win), app->list);
 
   cltr_widget_show_all(app->win);
-  cltr_widget_hide(app->video);
+
 
   cltr_list_on_activate_cell(CLTR_LIST(app->list), 
                             cell_activated, (gpointer)app);