+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):
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",
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)
{
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);
CltrButtonActivate callback,
void* userdata);
+void
+cltr_button_set_label(CltrButton *button,
+ const char *text,
+ CltrFont *font,
+ PixbufPixel *col);
#endif
*/
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));
}
};
+#define PAD 10
+
static void
cltr_list_show(CltrWidget *widget);
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));
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);
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;
}
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();
glPushMatrix();
+ cltr_glu_set_color(&bgcol);
+
+ glRecti(0, 0, widget->width, widget->height);
+
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
{
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;
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);
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);
{
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,
gboolean visible;
GList *children;
+ int refcnt;
/* focus */
WidgetShowMethod show;
WidgetDestroyMethod destroy;
WidgetFocusMethod focus_in;
- WidgetUnfocusMethod focus_out;
-
+ WidgetUnfocusMethod focus_out;
WidgetXEventHandler xevent_handler;
/* Anim ref */
}
}
+void
+cltr_widget_unref(CltrWidget *widget)
+{
+ widget->refcnt--;
+
+ if (widget->refcnt < 0 && widget->destroy)
+ {
+ widget->destroy(widget);
+ }
+}
+
/* XXX Focus hacks;
*
}
+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)
void
cltr_widget_paint(CltrWidget *widget);
+void
+cltr_widget_unref(CltrWidget *widget);
+
gboolean
cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
void
cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
+void
+cltr_widget_remove_child(CltrWidget *widget, CltrWidget *child);
+
#endif
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
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);
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
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);
/* 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)
{
}
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();
XF86VidModeSwitchToMode (GLWin.dpy, GLWin.screen, &GLWin.deskMode);
XF86VidModeSetViewPort (GLWin.dpy, GLWin.screen, 0, 0);
*/
+
+ cltr_window_hide_cursor(win);
}
cltr_window_xwin(CltrWindow *win);
void
+cltr_window_hide_cursor(CltrWindow *win);
+
+void
cltr_window_set_fullscreen(CltrWindow *win);
void
cltr_window_on_xevent(CltrWindow *win,
CltrXEventCallback callback,
void *userdata);
+void
+cltr_window_post_paint(CltrWindow *win);
#endif
#include <clutter/cltr.h>
typedef struct ItemEntry ItemEntry;
+typedef struct VideoCtrls VideoCtrls;
typedef struct DemoApp
{
CltrWidget *list;
CltrWidget *video;
CltrWidget *win;
+ VideoCtrls *video_ctrls;
GList *items;
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);
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)
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") ||
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;
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);
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",
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);
}
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);
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))
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);