much select hacking

This commit is contained in:
Matthew Allum 2005-05-23 21:21:50 +00:00
parent 956008e6c3
commit 8f30e4e0c1
13 changed files with 380 additions and 63 deletions

View File

@ -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):

View 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);

View 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

View 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));
}

View 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 */
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);
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 */
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);

View 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);

View 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,

View 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 */

View 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)

View 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

View 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,12 +157,53 @@ 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)
{
return win->xwin;
}
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)
{
@ -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);
}

View File

@ -18,6 +18,9 @@ cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
Window
cltr_window_xwin(CltrWindow *win);
void
cltr_window_hide_cursor(CltrWindow *win);
void
cltr_window_set_fullscreen(CltrWindow *win);
@ -28,6 +31,8 @@ void
cltr_window_on_xevent(CltrWindow *win,
CltrXEventCallback callback,
void *userdata);
void
cltr_window_post_paint(CltrWindow *win);
#endif

View 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);
cltr_list_get_active_cell_video_box_co_ords(CLTR_LIST(list),
&x1, &y1, &x2, &y2);
if (app->video == NULL)
{
/*
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, x1+80, y1+60);
if (!have_added_child)
cltr_widget_add_child(app->win, app->video, x1, y1);
else
{
printf("x1: %i, y1: %i\n", x1, y1);
}
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);