changeset 302:8b45e7b374b8

Rewrite the menu as a widget style
author wycc
date Sun, 15 Feb 2009 08:33:47 +0800
parents c8173a65e384
children f894b30676e9
files examples/menu/main.c
diffstat 1 files changed, 166 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- 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[]) {