# HG changeset patch # User wycc # Date 1234658027 -28800 # Node ID 8b45e7b374b8d3a47b93d5f60587e29f83734d80 # Parent c8173a65e384459d529df47183193681858169a1 Rewrite the menu as a widget style diff -r c8173a65e384 -r 8b45e7b374b8 examples/menu/main.c --- a/examples/menu/main.c Sun Feb 15 08:32:09 2009 +0800 +++ b/examples/menu/main.c Sun Feb 15 08:33:47 2009 +0800 @@ -16,6 +16,21 @@ #include "menu.h" #include "mbapp.h" + +typedef struct { + char **titles; + int *menus_y; + int *items; + int top; + int cur; + int max; + int ready; + MBApp *app; + mb_sprite_t *sprite; + mb_obj_t **objects; + mb_obj_t *lightbar; +} mb_animated_menu_t; + char *menus[] = { "Item 1", "Item 2", @@ -42,23 +57,32 @@ #define SPEED 600000 typedef struct { - int top; - int cur; - int max; + mb_animated_menu_t *m; }MyAppData; MBApp *myApp; -static void fillMenuContent() + +static void set_text(coord_t *g, char *text) +{ + geo_t *geo; + shape_t *shape; + + FOR_COORD_MEMBERS(g, geo) { + shape = geo_get_shape(geo); + if(shape->obj.obj_type == MBO_TEXT) { + sh_text_set_text(shape, text); + } + } +} + +static void mb_animated_menu_fillMenuContent(mb_animated_menu_t *m) { int i; - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - mb_sprite_t *sprite=myApp->rootsprite; coord_t *textgroup; shape_t *text; coord_t *group; coord_t *lightbar; - char name[255]; int tmp; mb_timeval_t start, playing, now; mb_progm_t *progm; @@ -67,36 +91,37 @@ // fill new item for(i=0;i<8;i++) { - snprintf(name, sizeof(name),"item%dtext", items[i]); - text = (shape_t *) MB_SPRITE_GET_OBJ(sprite,name); - sh_text_set_text(text, menus[data->top+i]); - rdman_shape_changed(MBAPP_RDMAN(myApp),text); + text = (shape_t *) m->objects[m->items[i]]; + set_text(text, m->titles[m->top+i]); + //rdman_shape_changed(MBAPP_RDMAN(m->app),text); } - snprintf(name, sizeof(name),"item%d", items[i]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); + textgroup = (coord_t *) m->objects[m->items[i]]; coord_hide(textgroup); - rdman_coord_changed(MBAPP_RDMAN(myApp),textgroup); + rdman_coord_changed(MBAPP_RDMAN(m->app),textgroup); - lightbar = (coord_t *) MB_SPRITE_GET_OBJ(sprite, "lightbar"); - snprintf(name,sizeof(name),"item%d", data->cur+1); - group = (coord_t *) MB_SPRITE_GET_OBJ(sprite, name); + lightbar = (coord_t *) m->lightbar; + group = (coord_t *) m->objects[m->cur+1]; coord_x(lightbar) = coord_x(group); coord_y(lightbar) = coord_y(group); - rdman_redraw_changed(MBAPP_RDMAN(myApp)); + rdman_redraw_changed(MBAPP_RDMAN(m->app)); } -static void fillMenuContentUp() +static void mb_animated_menu_complete(void *arg) +{ + mb_animated_menu_t *m = (mb_animated_menu_t *) arg; + + m->ready++; +} + +static void mb_animated_menu_fillMenuContentUp(mb_animated_menu_t *m) { int i; - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - mb_sprite_t *sprite=myApp->rootsprite; coord_t *textgroup; shape_t *text; coord_t *group; coord_t *lightbar; - char name[255]; int tmp; mb_timeval_t start, playing, now; mb_progm_t *progm; @@ -104,11 +129,10 @@ // fill new item - snprintf(name, sizeof(name),"item%dtext", items[8]); - text = (shape_t *) MB_SPRITE_GET_OBJ(sprite,name); - sh_text_set_text(text, menus[data->top]); + text = (shape_t *) m->objects[m->items[8]]; + set_text(text, m->titles[m->top]); - progm = mb_progm_new(2, MBAPP_RDMAN(myApp)); + progm = mb_progm_new(2, MBAPP_RDMAN(m->app)); MB_TIMEVAL_SET(&start, 0, 0); MB_TIMEVAL_SET(&playing, 0, SPEED); word = mb_progm_next_word(progm, &start, &playing); @@ -116,48 +140,45 @@ for(i=0;i<7;i++) { //shift to the next item - snprintf(name, sizeof(name),"item%d", items[i]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - mb_shift_new(0,menus_y[i+1]-coord_y(textgroup), textgroup,word); + textgroup = (coord_t *) m->objects[m->items[i]]; + mb_shift_new(0,m->menus_y[i+1]-coord_y(textgroup), textgroup,word); } // fade out the item[7] - snprintf(name, sizeof(name),"item%d", items[7]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); + textgroup = (coord_t *) m->objects[m->items[7]]; mb_shift_new(0,100, textgroup,word); // fade in the item[8] - snprintf(name, sizeof(name),"item%d", items[8]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - snprintf(name,sizeof(name),"item%d", items[0]); - group = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - coord_y(textgroup) = menus_y[0]-100; + textgroup = (coord_t *) m->objects[m->items[8]]; + group = (coord_t *) m->objects[m->items[0]]; + coord_y(textgroup) = m->menus_y[0]-100; coord_show(textgroup); mb_shift_new(0,100, textgroup,word); - lightbar = (coord_t *) MB_SPRITE_GET_OBJ(sprite, "lightbar"); - mb_shift_new(0,menus_y[data->cur]-coord_y(lightbar),lightbar,word); + lightbar = (coord_t *) m->lightbar; + mb_shift_new(0,m->menus_y[m->cur]-coord_y(lightbar),lightbar,word); MB_TIMEVAL_SET(&start, 0, SPEED); MB_TIMEVAL_SET(&playing, 0, 0); word = mb_progm_next_word(progm, &start, &playing); - snprintf(name, sizeof(name),"item%d", items[7]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); + textgroup = (coord_t *) m->objects[m->items[7]]; mb_visibility_new(VIS_HIDDEN, textgroup,word); mb_progm_free_completed(progm); - mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(myApp)->rt), &now); - rdman_redraw_changed(MBAPP_RDMAN(myApp)); - tmp = items[8]; + m->ready--; + subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); + mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(m->app)->rt), &now); + rdman_redraw_changed(MBAPP_RDMAN(m->app)); + tmp = m->items[8]; for(i=8;i>0;i--) { - items[i] = items[i-1]; + m->items[i] = m->items[i-1]; } - items[0] = tmp; + m->items[0] = tmp; } -static void fillMenuContentDown() + + +static void mb_animated_menu_fillMenuContentDown(mb_animated_menu_t *m) { int i; - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - mb_sprite_t *sprite=myApp->rootsprite; coord_t *textgroup; shape_t *text; coord_t *group; @@ -170,11 +191,9 @@ // fill new item - snprintf(name, sizeof(name),"item%dtext", items[8]); - text = (shape_t *) MB_SPRITE_GET_OBJ(sprite,name); - sh_text_set_text(text, menus[data->top+7]); + set_text(m->objects[m->items[8]], m->titles[m->top+7]); - progm = mb_progm_new(2, MBAPP_RDMAN(myApp)); + progm = mb_progm_new(2, MBAPP_RDMAN(m->app)); MB_TIMEVAL_SET(&start, 0, 0); MB_TIMEVAL_SET(&playing, 0, SPEED); word = mb_progm_next_word(progm, &start, &playing); @@ -182,118 +201,102 @@ for(i=1;i<8;i++) { //shift to the next item - snprintf(name, sizeof(name),"item%d", items[i]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - mb_shift_new(0,menus_y[i-1]-coord_y(textgroup), textgroup,word); + mb_shift_new(0,m->menus_y[i-1]-coord_y((coord_t *)m->objects[m->items[i]]), (coord_t *) m->objects[m->items[i]],word); } // fade out the item[0] - snprintf(name, sizeof(name),"item%d", items[0]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - mb_shift_new(0,-100, textgroup,word); + mb_shift_new(0,-100, (coord_t *)m->objects[m->items[0]],word); // fade in the item[8] - snprintf(name, sizeof(name),"item%d", items[8]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - coord_y(textgroup) = menus_y[7]+100; - coord_show(textgroup); - mb_shift_new(0,-100, textgroup,word); + coord_y((coord_t *)m->objects[m->items[8]]) = m->menus_y[7]+100; + coord_show(((coord_t *)(m->objects[m->items[8]]))); + mb_shift_new(0,-100, (coord_t *)m->objects[m->items[8]],word); - lightbar = (coord_t *) MB_SPRITE_GET_OBJ(sprite, "lightbar"); - mb_shift_new(0,menus_y[data->cur]-coord_y(lightbar),lightbar,word); + mb_shift_new(0,m->menus_y[m->cur]-coord_y((coord_t *)m->lightbar),((coord_t *)(m->lightbar)),word); MB_TIMEVAL_SET(&start, 0, SPEED); MB_TIMEVAL_SET(&playing, 0, 0); word = mb_progm_next_word(progm, &start, &playing); - snprintf(name, sizeof(name),"item%d", items[0]); - textgroup = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - mb_visibility_new(VIS_VISIBLE, textgroup,word); + mb_visibility_new(VIS_VISIBLE, (coord_t *) m->objects[m->items[0]],word); mb_progm_free_completed(progm); - mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(myApp)->rt), &now); - rdman_redraw_changed(MBAPP_RDMAN(myApp)); - tmp = items[0]; + m->ready--; + subject_add_observer(mb_progm_get_complete(progm), mb_animated_menu_complete,m); + mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(m->app)->rt), &now); + rdman_redraw_changed(MBAPP_RDMAN(m->app)); + tmp = m->items[0]; for(i=0;i<8;i++) { - items[i] = items[i+1]; + m->items[i] = m->items[i+1]; } - items[8] = tmp; + m->items[8] = tmp; } -MoveLightBar() +void mb_animated_menu_moveLightBar(mb_animated_menu_t *m) { - mb_sprite_t *sprite=myApp->rootsprite; - MyAppData *data = MBAPP_DATA(myApp,MyAppData); mb_timeval_t start, playing, now; mb_progm_t *progm; mb_word_t *word; coord_t *group; coord_t *lightbar; - char name[255]; - progm = mb_progm_new(1, MBAPP_RDMAN(myApp)); + progm = mb_progm_new(1, MBAPP_RDMAN(m->app)); MB_TIMEVAL_SET(&start, 0, 0); MB_TIMEVAL_SET(&playing, 0, 200000); word = mb_progm_next_word(progm, &start, &playing); get_now(&now); - lightbar = (coord_t *) MB_SPRITE_GET_OBJ(sprite, "lightbar"); - snprintf(name,sizeof(name),"item%d", items[data->cur]); - group = (coord_t *) MB_SPRITE_GET_OBJ(sprite, name); + lightbar = (coord_t *) m->lightbar; + group = (coord_t *) m->objects[m->cur]; mb_shift_new(coord_x(group)-coord_x(lightbar),coord_y(group)-coord_y(lightbar),lightbar,word); mb_progm_free_completed(progm); - mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(myApp)->rt), &now); - rdman_redraw_changed(MBAPP_RDMAN(myApp)); + mb_progm_start(progm, X_MB_tman(MBAPP_RDMAN(m->app)->rt), &now); + rdman_redraw_changed(MBAPP_RDMAN(m->app)); } -void menu_up() +void mb_animated_menu_up(mb_animated_menu_t *m) { - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - - if (data->cur > 5) { - data->cur--; - MoveLightBar(); + if (m->cur > 5) { + m->cur--; + mb_animated_menu_moveLightBar(m); } else { - if (data->top > 0) { - data->top--; - fillMenuContentUp(); + if (m->top > 0) { + m->top--; + mb_animated_menu_fillMenuContentUp(m); } else { - if (data->cur == 0) + if (m->cur == 0) return; - data->cur--; - MoveLightBar(); + m->cur--; + mb_animated_menu_moveLightBar(m); } } } -void menu_down() +void mb_animated_menu_down(mb_animated_menu_t *m) { - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - if (data->cur < 4) { - if (data->top+data->cur <= data->max) { - data->cur++; - MoveLightBar(); + if (m->cur < 4) { + if (m->top+m->cur <= m->max) { + m->cur++; + mb_animated_menu_moveLightBar(m); } } else { - if ((data->top+8) < data->max) { - data->top++; - fillMenuContentDown(); + if ((m->top+8) < m->max) { + m->top++; + mb_animated_menu_fillMenuContentDown(m); } else { - if (data->cur+data->top < data->max-1) { - data->cur++; - MoveLightBar(); + if (m->cur+m->top < m->max-1) { + m->cur++; + mb_animated_menu_moveLightBar(m); } else return; } } } -void menu_select() +void mb_animated_menu_select(mb_animated_menu_t *m) { - MyAppData *data = MBAPP_DATA(myApp,MyAppData); - - printf("menu '%s' is selected\n", menus[data->top+data->cur]); } -void keyHandler(event_t *ev, void *arg) +void mb_animated_menu_keyHandler(event_t *ev, void *arg) { + mb_animated_menu_t *m = (mb_animated_menu_t *) arg; X_kb_event_t *xkey = (X_kb_event_t *)ev; if(xkey->event.type != EVT_KB_PRESS) { return; @@ -303,24 +306,71 @@ break; case 0xff52: /* up */ - menu_up(); + mb_animated_menu_up(m); break; case 0xff53: /* right */ break; case 0xff54: /* down */ - menu_down(); + mb_animated_menu_down(m); break; case 0xff0d: /* enter */ - menu_select(); + mb_animated_menu_select(m); break; default: return; } } +/** \brief Create an instace of animated menu. + * + * The objectnames is used to extract symbols from the SVG file. + * ${objectnames}0 - ${objectnames}8 is the text object. + * ${objectnames}_lightbar is the lightbar. + * + */ +mb_animated_menu_t *mb_animated_menu_new(MBApp *app,mb_sprite_t *sp,char *objnames,char *menus[]) +{ + mb_animated_menu_t *m; + int i,len; + char name[255]; + mb_obj_t *l; + + for(i=0;menus[i];i++); + len = i; + + m = (mb_animated_menu_t *) malloc(sizeof(mb_animated_menu_t)+sizeof(int)*len*2+sizeof(mb_obj_t *)*len); + m->app = app; + m->sprite = sp; + m->top = 0; + m->cur = 0; + m->ready = 1; + m->max = len; + m->items = (int *) (m+1); + m->menus_y = (int *) (m->items+len); + m->objects = (mb_obj_t **) (m->menus_y+len); + for(i=0;i<9;i++) { + m->items[i] = i; + snprintf(name,sizeof(name),"%s%d", objnames, i+1); + l = MB_SPRITE_GET_OBJ(sp,name); + if (l == NULL) { + fprintf(stderr,"Can not find symbol %s\n",name); + } + m->objects[i] = (mb_obj_t *) l; + m->menus_y[i] = coord_y((coord_t*)l); + } + m->titles = menus; + snprintf(name,sizeof(name), "%s_lightbar", objnames); + m->lightbar = (mb_obj_t *) MB_SPRITE_GET_OBJ(sp,name); + if (m->lightbar) + fprintf(stderr,"Can not find object %s\n",name); + mb_animated_menu_fillMenuContent(m); + subject_add_observer(MBAPP_keySubject(myApp), mb_animated_menu_keyHandler,m); + return m; +} + MyApp_InitContent() { MyAppData *data = MBAPP_DATA(myApp,MyAppData); @@ -330,18 +380,7 @@ int i; mb_sprite_t *sprite=myApp->rootsprite; - data->top = 0; - data->cur = 0; - data->max = sizeof(menus)/sizeof(int)-1; - for(i=0;i<9;i++) { - items[i] = i+1; - snprintf(name,255,"item%d", i+1); - l = (coord_t *) MB_SPRITE_GET_OBJ(sprite,name); - menus_y[i] = coord_y(l); - } - - fillMenuContent(); - subject_add_observer(key, keyHandler,NULL); + data->m = mb_animated_menu_new(myApp,myApp->rootsprite,"item",menus); } int main(int argc, char * const argv[]) {