mutter/clutter/cltr-list.c

340 lines
6.8 KiB
C
Raw Normal View History

2005-04-07 22:46:43 +00:00
#include "cltr-list.h"
#include "cltr-private.h"
2005-03-22 14:53:51 +00:00
2005-05-14 10:19:39 +00:00
#define ANIM_FPS 50
2005-04-07 22:46:43 +00:00
#define FPS_TO_TIMEOUT(t) (1000/(t))
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
typedef struct CltrListCell
{
CltrRect rect;
Pixbuf *pixb;
CltrTexture *texture;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
} CltrListCell;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
struct CltrList
{
CltrWidget widget;
GList *cells, *active_cell;
int active_cell_y;
int cell_height;
int cell_width;
CltrListState state;
int scroll_dir;
};
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
static void
cltr_list_show(CltrWidget *widget);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
static gboolean
cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
static void
cltr_list_paint(CltrWidget *widget);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
static float
distfunc(CltrList *list, int d)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
int maxdist = list->widget.height;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
d = (maxdist-ABS(d)) ;
2005-05-14 10:19:39 +00:00
return ( exp( (float)d/maxdist * 0.8 ) / exp(0.8) ) ;
2005-04-07 22:46:43 +00:00
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
CltrListCell*
cltr_list_cell_new(CltrList *list)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
CltrListCell *cell = NULL;
ClutterFont *font;
gchar buf[24];
2005-05-14 10:19:39 +00:00
PixbufPixel pixel = { 0xff, 0, 0, 0 }, font_pixel = { 255, 255, 255, 255};
2005-03-22 14:53:51 +00:00
2005-05-14 10:19:39 +00:00
font = font_new ("Sans Bold 48");
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell = g_malloc0(sizeof(CltrListCell));
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell->pixb = pixbuf_new(list->cell_width, list->cell_height);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
pixbuf_fill_rect(cell->pixb, 0, 0, -1, -1, &pixel);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
g_snprintf(&buf[0], 24, "%i %i %i", rand()%10, rand()%10, rand()%10);
2005-03-22 14:53:51 +00:00
font_draw(font, cell->pixb, buf, 10, 10, &font_pixel);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell->texture = cltr_texture_new(cell->pixb);
2005-03-22 14:53:51 +00:00
return cell;
}
2005-04-07 22:46:43 +00:00
CltrWidget*
cltr_list_new(int width,
int height,
int cell_width,
int cell_height)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
CltrList *list;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
list = g_malloc0(sizeof(CltrList));
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
list->widget.width = width;
list->widget.height = height;
list->widget.show = cltr_list_show;
list->widget.paint = cltr_list_paint;
list->cell_height = cell_height; /* maximum */
list->cell_width = cell_width; /* maximum */
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
list->widget.xevent_handler = cltr_list_handle_xevent;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
return CLTR_WIDGET(list);
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
static void
cltr_list_show(CltrWidget *widget)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
CltrList *list = CLTR_LIST(widget);
2005-05-14 10:19:39 +00:00
int n_items = 20, i;
2005-03-22 14:53:51 +00:00
2005-05-14 10:19:39 +00:00
list->active_cell_y = (widget->height / 2) - (list->cell_height/2);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
for (i=0; i<n_items; i++)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
list->cells = g_list_append(list->cells, cltr_list_cell_new(list));
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
list->active_cell = g_list_first(list->cells);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cltr_widget_queue_paint(widget);
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
static gboolean
cltr_list_handle_xevent (CltrWidget *widget, XEvent *xev)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
CltrList *list = CLTR_LIST(widget);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
switch (xev->type)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
case KeyPress:
{
KeySym kc;
kc = XKeycodeToKeysym(xev->xkey.display, xev->xkey.keycode, 0);
switch (kc)
{
case XK_Up:
case XK_KP_Up:
cltr_list_scroll_up(list);
break;
case XK_Down:
case XK_KP_Down:
cltr_list_scroll_down(list);
break;
case XK_Return:
CLTR_DBG("Return");
break;
case XK_Left:
case XK_KP_Left:
case XK_Right:
case XK_KP_Right:
default:
CLTR_DBG("unhandled keysym");
}
}
break;
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
return TRUE;
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
static void
cltr_list_animate(CltrList *list)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
GList *cell_item = NULL;
CltrListCell *next_active = NULL, *cell_top = NULL;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell_top = (CltrListCell *)g_list_nth_data(list->cells, 0);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
if (list->state == CLTR_LIST_STATE_SCROLL_UP)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
cell_item = g_list_previous(list->active_cell);
if (!cell_item)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
next_active = (CltrListCell *)cell_item->data;
if (next_active->rect.y < list->active_cell_y)
{
2005-05-14 10:19:39 +00:00
cell_top->rect.y += 10;
2005-04-07 22:46:43 +00:00
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
}
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
else if (list->state == CLTR_LIST_STATE_SCROLL_DOWN)
{
cell_item = g_list_next(list->active_cell);
if (!cell_item)
{
list->state = CLTR_LIST_STATE_BROWSE;
return;
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
next_active = (CltrListCell *)cell_item->data;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
if (next_active->rect.y > list->active_cell_y)
{
2005-05-14 10:19:39 +00:00
cell_top->rect.y -= 10;
2005-04-07 22:46:43 +00:00
}
else
{
list->active_cell = cell_item;
list->state = CLTR_LIST_STATE_BROWSE;
}
}
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
gboolean
cltr_list_timeout_cb(gpointer data)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
CltrList *list = (CltrList *)data;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cltr_list_animate(list);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cltr_widget_queue_paint(CLTR_WIDGET(list));
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
switch(list->state)
2005-03-22 14:53:51 +00:00
{
2005-04-07 22:46:43 +00:00
case CLTR_LIST_STATE_SCROLL_UP:
case CLTR_LIST_STATE_SCROLL_DOWN:
return TRUE;
case CLTR_LIST_STATE_LOADING:
case CLTR_LIST_STATE_LOAD_COMPLETE:
case CLTR_LIST_STATE_BROWSE:
default:
return FALSE;
2005-03-22 14:53:51 +00:00
}
2005-04-07 22:46:43 +00:00
}
2005-03-22 14:53:51 +00:00
2005-05-14 10:19:39 +00:00
2005-04-07 22:46:43 +00:00
static void
cltr_list_paint(CltrWidget *widget)
{
GList *cell_item = NULL;
CltrList *list = CLTR_LIST(widget);
CltrListCell *cell = NULL;
2005-05-14 10:19:39 +00:00
PixbufPixel col = { 0xff, 0, 0, 0xff };
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
int last;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell_item = g_list_first(list->cells);
cell = (CltrListCell *)cell_item->data;
last = cell->rect.y;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glPushMatrix();
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glEnable(GL_TEXTURE_2D);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glEnable(GL_BLEND);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
while (cell_item)
2005-03-22 14:53:51 +00:00
{
2005-05-14 10:19:39 +00:00
float scale = 0.0;
2005-04-07 22:46:43 +00:00
cell = (CltrListCell *)cell_item->data;
2005-05-14 10:19:39 +00:00
col.r = 0xff; col.g = 0; col.b = 0; col.a = 0xff;
2005-04-07 22:46:43 +00:00
cell->rect.y = last;
if (cell->rect.y + cell->rect.height >= 0)
{
2005-05-14 10:19:39 +00:00
scale = distfunc(list, cell->rect.y - list->active_cell_y);
cell->rect.width = list->cell_width * scale;
cell->rect.height = list->cell_height * scale;
2005-04-07 22:46:43 +00:00
2005-05-14 10:19:39 +00:00
cell->rect.x = (list->widget.width - cell->rect.width) / 2;
2005-04-07 22:46:43 +00:00
}
last = cell->rect.y + cell->rect.height;
if (last > 0 && cell->rect.y < list->widget.width) /* crappy clip */
{
2005-05-14 10:19:39 +00:00
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_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);
col.r = 0xff; col.g = 0xff; col.b = 0xff; col.a = 0xff;
/*
cltr_glu_rounded_rect(cltr_rect_x1(cell->rect) + 10,
cltr_rect_y1(cell->rect) + 12,
cltr_rect_x2(cell->rect) - 10,
cltr_rect_y2(cell->rect) - 12,
10,
&col);
*/
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, 1.0);
2005-04-07 22:46:43 +00:00
cltr_texture_render_to_gl_quad(cell->texture,
2005-05-14 10:19:39 +00:00
cltr_rect_x1(cell->rect) + 100,
cltr_rect_y1(cell->rect) + 10,
cltr_rect_x2(cell->rect) - 100,
cltr_rect_y2(cell->rect) - 10);
2005-04-07 22:46:43 +00:00
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
cell_item = g_list_next(cell_item);
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glDisable(GL_BLEND);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glDisable(GL_TEXTURE_2D);
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
glPopMatrix();
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
void
cltr_list_scroll_down(CltrList *list)
{
list->state = CLTR_LIST_STATE_SCROLL_DOWN;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
cltr_list_timeout_cb, list);
}
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
void
cltr_list_scroll_up(CltrList *list)
{
list->state = CLTR_LIST_STATE_SCROLL_UP;
2005-03-22 14:53:51 +00:00
2005-04-07 22:46:43 +00:00
g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
cltr_list_timeout_cb, list);
2005-03-22 14:53:51 +00:00
}