changeset 252:3271ea1ef96f

merge
author Thinker K.F. Li <thinker@branda.to>
date Sun, 04 Jan 2009 12:11:09 +0800
parents f08b3ba9c1d8 (current diff) ab8284c8dcee (diff)
children 99a9cca4bbd0
files inkscape/MB_EditActiveButton.py inkscape/MB_EditClickButton.py inkscape/MB_EditNormalButton.py inkscape/MB_button_select_click.inx inkscape/MB_button_select_normal.inx
diffstat 21 files changed, 583 insertions(+), 491 deletions(-) [+]
line wrap: on
line diff
--- a/examples/dynamic/Makefile.am	Sun Jan 04 12:09:29 2009 +0800
+++ b/examples/dynamic/Makefile.am	Sun Jan 04 12:11:09 2009 +0800
@@ -1,16 +1,21 @@
 include $(top_srcdir)/config.mk
 
-noinst_PROGRAMS = dynamic button.so
+noinst_PROGRAMS = dynamic hello button.so scene.so
 EXTRA_DIST = menu.svg button.svg
 
-dynamic_SOURCES = main.c
-nodist_dynamic_SOURCES = menu.c menu.h menu.mb button.c button.h button.mb
+dynamic_SOURCES = main.c mbapp.c mbapp.h mbbutton.c mbbutton.h
+nodist_dynamic_SOURCES = menu.c menu.h menu.mb
 CPPFLAGS = @cairo_CFLAGS@ $(INCLUDES)
 dynamic_LDFLAGS = @cairo_LIBS@ 
 dynamic_LDADD = $(top_builddir)/src/libmbfly.la
 BUILT_SOURCES = menu.c menu.h menu.mb button.c button.h button.mb
 CLEANFILES = menu.c menu.h menu.mb button.c button.h button.mb
 
+
+hello_SOURCES = hello.c mbapp.c mbapp.h
+hello_LDFLAGS = @cairo_LIBS@ 
+hello_LDADD = $(top_builddir)/src/libmbfly.la
+
 menu.mb: $(srcdir)/menu.svg
 	$(top_srcdir)/tools/svg2code.py $? $@
 
--- a/examples/dynamic/button.svg	Sun Jan 04 12:09:29 2009 +0800
+++ b/examples/dynamic/button.svg	Sun Jan 04 12:11:09 2009 +0800
@@ -30,7 +30,7 @@
      inkscape:cx="257.06285"
      inkscape:cy="365.06674"
      inkscape:document-units="px"
-     inkscape:current-layer="btn_click"
+     inkscape:current-layer="layer1"
      showgrid="false"
      inkscape:window-width="1400"
      inkscape:window-height="978"
@@ -106,6 +106,7 @@
          x="235.71429"
          y="282.36218" /></text>
     <g
+       mbtype="button"
        id="btn"
        transform="translate(148.57143,98.571429)"
        mbname="btn">
@@ -114,7 +115,7 @@
          id="btn_normal"
          transform="translate(148.57143,98.571429)"
          mbname="btn_normal"
-         style="display:none">
+         style="">
         <rect
            ry="5.0559778"
            rx="6.0995407"
@@ -134,6 +135,15 @@
              x="10.000002"
              id="tspan2655"
              sodipodi:role="line">Click Me</tspan></text>
+        <rect
+           ry="5.0559778"
+           rx="6.0995407"
+           y="38.600159"
+           x="105.64253"
+           height="42.66333"
+           width="34.536983"
+           id="rect2385"
+           style="fill:#f136ff;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
       </g>
       <g
          frame="active"
@@ -162,11 +172,11 @@
              sodipodi:role="line">Click Me</tspan></text>
       </g>
       <g
+         style="display:none"
          frame="click"
          id="btn_click"
          transform="translate(148.57143,98.571429)"
-         mbname="btn_click"
-         style="">
+         mbname="btn_click">
         <rect
            ry="5.0559778"
            rx="6.0995407"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic/hello.c	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,66 @@
+/*! \file
+ *
+ * svg2code_ex is an example that show programmers how to create a
+ * menu with MadButterfly.
+ *
+ */
+#include <stdio.h>
+#include <mb.h>
+#include <string.h>
+#include "menu.h"
+#include "mbapp.h"
+
+
+MBApp *myApp;
+
+typedef struct {
+    shape_t *rect;
+    co_aix orx,ory;
+    int start_x,start_y;
+    observer_t *obs1,*obs2;
+    int currentscene;
+}MyAppData;
+
+
+void switch_scene(const mb_timeval_t *tmo, const mb_timeval_t *now,void *arg)
+{
+    MyAppData *en = MBAPP_DATA((MBApp *)arg,MyAppData );
+    mb_timeval_t timer,interval;
+
+    
+    get_now(&timer);
+    MB_TIMEVAL_SET(&interval, 1 ,0);
+    MB_TIMEVAL_ADD(&timer, &interval);
+    mb_tman_timeout( MBApp_getTimer(myApp), &timer, switch_scene, myApp);
+
+    en->currentscene = (en->currentscene + 1) % 2;
+    printf("switch to scene %d\n", en->currentscene + 1);
+    MB_SPRITE_GOTO_SCENE(myApp->rootsprite,en->currentscene + 1);
+}
+
+int main(int argc, char * const argv[]) {
+    subject_t *subject;
+    mb_button_t *b;
+    mb_obj_t *button;
+    MyAppData data;
+    mb_timeval_t tmo,interval;
+
+    if (argc > 1) 
+	    myApp = MBApp_Init(argv[1]);
+    else
+	    myApp = MBApp_Init("scene");
+    data.currentscene=0;
+    MBApp_setData(myApp,&data);
+    //b = mb_button_new(myApp, myApp->rootsprite, "btn");
+    //mb_button_add_onClick(b, test,NULL);
+    get_now(&tmo);
+    MB_TIMEVAL_SET(&interval, 1 ,0);
+    mb_tman_timeout( MBApp_getTimer(myApp), &tmo, switch_scene, myApp);
+    
+
+    MBApp_loop(myApp);
+
+    return 0;
+}
+
+/* vim: set ts=4 */
--- a/examples/dynamic/main.c	Sun Jan 04 12:09:29 2009 +0800
+++ b/examples/dynamic/main.c	Sun Jan 04 12:11:09 2009 +0800
@@ -8,16 +8,9 @@
 #include <mb.h>
 #include <string.h>
 #include "menu.h"
+#include "mbapp.h"
 
 
-typedef struct _mbapp MBApp;
-struct _mbapp {
-    void *rt;
-    redraw_man_t *rdman;
-    mb_sprite_t *rootsprite;
-    mb_obj_t *root;
-    void *private;
-};
 
 typedef struct {
     shape_t *rect;
@@ -27,195 +20,9 @@
     int currentscene;
 }MyAppData;
 
-#define MBAPP_DATA(app,type) ((type *) ((app)->private))
-#define MBAPP_RDMAN(app) (((MBApp *) app)->rdman)
-
-
-typedef struct _mb_button {
-    mb_obj_t obj;
-    MBApp *en;
-    int state;
-    coord_t *root;
-    coord_t *active;
-    coord_t *normal;
-    coord_t *click;
-    void (*press)();
-    void *arg;
-    observer_t *obs_move,*obs_out,*obs_press;
-    mb_progm_t *progm;
-} mb_button_t;
-
-
 
 #define CMOUSE(e) (coord_get_mouse_event(e))
 
-
-static void mb_button_pressed(event_t *evt, void *arg);
-static void mb_button_out(event_t *evt, void *arg);
-
-void mb_button_refresh(mb_button_t *btn)
-{
-    rdman_coord_changed(btn->en->rdman,btn->root);
-    rdman_redraw_changed(btn->en->rdman);
-}
-
-static void mb_button_move(event_t *evt, void *arg) 
-{
-    mb_button_t *btn = (mb_button_t *) arg;
-    MBApp *en = btn->en;
-
-    
-    printf("Mouse move\n");
-    arg = (void *)en;
-    coord_show(btn->active);
-    mb_button_refresh(btn);
-}
-static void mb_button_out(event_t *evt, void *arg) 
-{
-    mb_button_t *btn = (mb_button_t *) arg;
-    MBApp *en = btn->en;
-    arg = (void *) en;
-
-    if (btn->progm) {
-	    mb_progm_abort(btn->progm);
-	    btn->progm = NULL;
-    }
-    printf("mouse out\n");
-    coord_hide(btn->click);
-    coord_hide(btn->active);
-    coord_show(btn->normal);
-    mb_button_refresh(btn);
-}
-
-void mb_button_show_active(event_t *evt, void *arg)
-{
-    mb_button_t *btn = (mb_button_t *) arg;
-    MBApp *en = btn->en;
-
-    coord_show(btn->active);
-    mb_button_refresh(btn);
-}
-
-void mb_button_pressed(event_t *evt, void *arg)
-{
-    mb_button_t *btn = (mb_button_t *) arg;
-    MBApp *en = btn->en;
-    mb_timeval_t start, playing, now;
-    mb_progm_t *progm;
-    mb_word_t *word;
-    arg = (void *) en;
-
-    printf("Pressed\n");
-    if (btn->progm) {
-	    mb_progm_abort(btn->progm);
-	    btn->progm = NULL;
-    }
-    coord_show(btn->click);
-    coord_hide(btn->active);
-    rdman_coord_changed(MBAPP_RDMAN(arg),btn->root);
-    rdman_redraw_changed(MBAPP_RDMAN(arg));
-
-    btn->progm = progm = mb_progm_new(1, MBAPP_RDMAN(arg));
-    MB_TIMEVAL_SET(&start, 0, 500000);
-    MB_TIMEVAL_SET(&playing, 0, 0);
-    word = mb_progm_next_word(progm, &start, &playing);
-    mb_visibility_new(VIS_HIDDEN, btn->click, word);
-    mb_visibility_new(VIS_VISIBLE, btn->active, word);
-    mb_progm_free_completed(progm);
-    get_now(&now);
-    mb_progm_start(progm, X_MB_tman(en->rt), &now);
-    if (btn->press)
-    	btn->press(btn->arg);
-}
-mb_button_t *mb_button_new(MBApp *app,mb_sprite_t *sp, char *name)
-{
-    mb_button_t *btn = (mb_button_t *) malloc(sizeof(mb_button_t));
-    char *buf = (char *) malloc(strlen(name)+5);
-    MBApp *arg = app;
-
-    btn->root = (coord_t *) MB_SPRITE_GET_OBJ(sp, name);
-    sprintf(buf, "%s_normal", name);
-    btn->normal = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
-    if (btn->normal == NULL) {
-    	printf("Missing normal button, this is not a correct button\n");
-    }
-    sprintf(buf, "%s_active", name);
-    btn->active = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
-    if (btn->active == NULL) {
-    	printf("Missing click button, this is not a correct button\n");
-    }
-    sprintf(buf, "%s_click", name);
-    btn->click = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
-    if (btn->active == NULL) {
-    	printf("Missing click button, this is not a correct button\n");
-    }
-    btn->press = NULL;
-    // Show only the normal button
-    coord_hide(btn->active);
-    coord_hide(btn->click);
-    coord_show(btn->normal);
-    // Move to the same position
-    btn->active->matrix[2] = 200;
-    btn->active->matrix[5] = 200;
-    btn->normal->matrix[2] = 200;
-    btn->normal->matrix[5] = 200;
-    btn->click->matrix[2] = 200;
-    btn->click->matrix[5] = 200;
-    btn->en = app;
-    btn->obs_move = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_MOVE, mb_button_move,btn);
-    btn->obs_press = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_BUT_PRESS, mb_button_pressed,btn);
-    btn->obs_out = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_OUT, mb_button_out,btn);
-    btn->progm = NULL;
-    rdman_redraw_changed(MBAPP_RDMAN(arg));
-    return btn;
-}
-
-
-void mb_button_add_onClick(mb_button_t *b, void (*h)(void *arg), void *arg)
-{
-    b->press = h;
-    b->arg = arg;
-}
-
-MBApp *MBApp_Init(char *module)
-{
-    MBApp *app = (MBApp *) malloc(sizeof(MBApp));
-    X_MB_runtime_t *rt;
-
-    rt = X_MB_new(":0.0", 800, 600);
-
-    app->rt = rt;
-    app->rdman =  X_MB_rdman(rt);
-    app->rootsprite= sprite_load(module,app->rdman, app->rdman->root_coord);
-    return app;
-}
-
-void MBApp_setData(MBApp *app,void *data)
-{
-    app->private = (void *) data;
-}
-
-mb_tman_t *MBApp_getTimer(MBApp *app)
-{
-    return X_MB_tman(app->rt);
-}
-
-void MBApp_loop(MBApp *en)
-{
-    /*
-     * Start handle connections, includes one to X server.
-     * User start to interact with the application.
-     */
-    X_MB_handle_connection(en->rt);
-
-    /*
-     * Clean
-     */
-    X_MB_free(en->rt);
-    free(en);
-}
-
-
 static void add_rect_move(event_t *evt, void *arg) 
 {
     MyAppData *en = MBAPP_DATA((MBApp *)arg,MyAppData );
@@ -309,9 +116,18 @@
     MB_SPRITE_GOTO_SCENE(myApp->rootsprite,en->currentscene + 1);
 }
 
+MyApp_InitContent()
+{
+    mb_button_t *b;
+    mb_sprite_t *sprite;
+
+    sprite = sprite_load("button", myApp->rdman, myApp->rdman->root_coord);
+    b = mb_button_new(myApp->rdman, sprite, "btn");
+    mb_button_add_onClick(b, test,NULL);
+}
+
 int main(int argc, char * const argv[]) {
     subject_t *subject;
-    mb_button_t *b;
     mb_obj_t *button;
     MyAppData data;
     mb_timeval_t tmo,interval;
@@ -322,8 +138,7 @@
 	    myApp = MBApp_Init("scene");
     data.currentscene=0;
     MBApp_setData(myApp,&data);
-    //b = mb_button_new(myApp, myApp->rootsprite, "btn");
-    //mb_button_add_onClick(b, test,NULL);
+    MyApp_InitContent();
     get_now(&tmo);
     MB_TIMEVAL_SET(&interval, 1 ,0);
     mb_tman_timeout( MBApp_getTimer(myApp), &tmo, switch_scene, myApp);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic/mbapp.c	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,40 @@
+#include <mb.h>
+#include <mbapp.h>
+MBApp *MBApp_Init(char *module)
+{
+    MBApp *app = (MBApp *) malloc(sizeof(MBApp));
+    X_MB_runtime_t *rt;
+
+    rt = X_MB_new(":0.0", 800, 600);
+
+    app->rt = rt;
+    app->rdman =  X_MB_rdman(rt);
+    app->rootsprite= sprite_load(module,app->rdman, app->rdman->root_coord);
+    rdman_attach_backend(app->rdman, rt);
+    return app;
+}
+
+void MBApp_setData(MBApp *app,void *data)
+{
+    app->private = (void *) data;
+}
+
+mb_tman_t *MBApp_getTimer(MBApp *app)
+{
+    return X_MB_tman(app->rt);
+}
+
+void MBApp_loop(MBApp *en)
+{
+    /*
+     * Start handle connections, includes one to X server.
+     * User start to interact with the application.
+     */
+    X_MB_handle_connection(en->rt);
+
+    /*
+     * Clean
+     */
+    X_MB_free(en->rt);
+    free(en);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic/mbapp.h	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,19 @@
+#ifndef __APP_H
+#define __APP_H
+typedef struct _mbapp MBApp;
+struct _mbapp {
+    void *rt;
+    redraw_man_t *rdman;
+    mb_sprite_t *rootsprite;
+    mb_obj_t *root;
+    void *private;
+};
+MBApp *MBApp_Init(char *module);
+void MBApp_setData(MBApp *app,void *data);
+mb_tman_t *MBApp_getTimer(MBApp *app);
+void MBApp_loop(MBApp *en);
+#define MBAPP_DATA(app,type) ((type *) ((app)->private))
+#define MBAPP_RDMAN(app) (((MBApp *) app)->rdman)
+
+#include "mbbutton.h"
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic/mbbutton.c	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,129 @@
+
+#include <stdio.h>
+#include <mb.h>
+#include <string.h>
+#include "mbapp.h"
+
+
+
+#define CMOUSE(e) (coord_get_mouse_event(e))
+
+
+static void mb_button_pressed(event_t *evt, void *arg);
+static void mb_button_out(event_t *evt, void *arg);
+
+void mb_button_add_onClick(mb_button_t *b, void (*h)(void *arg), void *arg)
+{
+    b->press = h;
+    b->arg = arg;
+}
+
+void mb_button_refresh(mb_button_t *btn)
+{
+    rdman_coord_changed(btn->rdman,btn->root);
+    rdman_redraw_changed(btn->rdman);
+}
+
+static void mb_button_move(event_t *evt, void *arg) 
+{
+    mb_button_t *btn = (mb_button_t *) arg;
+
+    
+    printf("Mouse move\n");
+    coord_show(btn->active);
+    mb_button_refresh(btn);
+}
+static void mb_button_out(event_t *evt, void *arg) 
+{
+    mb_button_t *btn = (mb_button_t *) arg;
+
+    if (btn->progm) {
+	    mb_progm_abort(btn->progm);
+	    btn->progm = NULL;
+    }
+    printf("mouse out\n");
+    coord_hide(btn->click);
+    coord_hide(btn->active);
+    coord_show(btn->normal);
+    mb_button_refresh(btn);
+}
+
+static void mb_button_show_active(event_t *evt, void *arg)
+{
+    mb_button_t *btn = (mb_button_t *) arg;
+
+    coord_show(btn->active);
+    mb_button_refresh(btn);
+}
+
+static void mb_button_pressed(event_t *evt, void *arg)
+{
+    mb_button_t *btn = (mb_button_t *) arg;
+    mb_timeval_t start, playing, now;
+    mb_progm_t *progm;
+    mb_word_t *word;
+
+    printf("Pressed\n");
+    if (btn->progm) {
+	    mb_progm_abort(btn->progm);
+	    btn->progm = NULL;
+    }
+    coord_show(btn->click);
+    coord_hide(btn->active);
+    rdman_coord_changed(btn->rdman,btn->root);
+    rdman_redraw_changed(btn->rdman);
+
+    btn->progm = progm = mb_progm_new(1, btn->rdman);
+    MB_TIMEVAL_SET(&start, 0, 500000);
+    MB_TIMEVAL_SET(&playing, 0, 0);
+    word = mb_progm_next_word(progm, &start, &playing);
+    mb_visibility_new(VIS_HIDDEN, btn->click, word);
+    mb_visibility_new(VIS_VISIBLE, btn->active, word);
+    mb_progm_free_completed(progm);
+    get_now(&now);
+    printf("rt = %x\n", btn->rdman->rt);
+    mb_progm_start(progm, X_MB_tman(btn->rdman->rt), &now);
+    if (btn->press)
+    	btn->press(btn->arg);
+}
+mb_button_t *mb_button_new(redraw_man_t *rdman,mb_sprite_t *sp, char *name)
+{
+    mb_button_t *btn = (mb_button_t *) malloc(sizeof(mb_button_t));
+    char *buf = (char *) malloc(strlen(name)+5);
+
+    btn->root = (coord_t *) MB_SPRITE_GET_OBJ(sp, name);
+    sprintf(buf, "%s_normal", name);
+    btn->normal = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
+    if (btn->normal == NULL) {
+    	printf("Missing normal button, this is not a correct button\n");
+    }
+    sprintf(buf, "%s_active", name);
+    btn->active = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
+    if (btn->active == NULL) {
+    	printf("Missing click button, this is not a correct button\n");
+    }
+    sprintf(buf, "%s_click", name);
+    btn->click = (coord_t *) MB_SPRITE_GET_OBJ(sp, buf);
+    if (btn->active == NULL) {
+    	printf("Missing click button, this is not a correct button\n");
+    }
+    btn->press = NULL;
+    // Show only the normal button
+    coord_hide(btn->active);
+    coord_hide(btn->click);
+    coord_show(btn->normal);
+    // Move to the same position
+    btn->active->matrix[2] = 200;
+    btn->active->matrix[5] = 200;
+    btn->normal->matrix[2] = 200;
+    btn->normal->matrix[5] = 200;
+    btn->click->matrix[2] = 200;
+    btn->click->matrix[5] = 200;
+    btn->rdman = rdman;
+    btn->obs_move = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_MOVE, mb_button_move,btn);
+    btn->obs_press = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_BUT_PRESS, mb_button_pressed,btn);
+    btn->obs_out = subject_add_event_observer(CMOUSE(btn->root), EVT_MOUSE_OUT, mb_button_out,btn);
+    btn->progm = NULL;
+    rdman_redraw_changed(rdman);
+    return btn;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/dynamic/mbbutton.h	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,19 @@
+#ifndef __MBBUTTON_H
+#define __MBBUTTON_H
+typedef struct _mb_button {
+    mb_obj_t obj;
+    redraw_man_t *rdman;
+    int state;
+    coord_t *root;
+    coord_t *active;
+    coord_t *normal;
+    coord_t *click;
+    void (*press)();
+    void *arg;
+    observer_t *obs_move,*obs_out,*obs_press;
+    mb_progm_t *progm;
+} mb_button_t;
+mb_button_t *mb_button_new(redraw_man_t *rdman,mb_sprite_t *sp, char *name);
+void mb_button_add_onClick(mb_button_t *b, void (*h)(void *arg), void *arg);
+#endif
+
--- a/examples/dynamic/scene.svg	Sun Jan 04 12:09:29 2009 +0800
+++ b/examples/dynamic/scene.svg	Sun Jan 04 12:11:09 2009 +0800
@@ -36,12 +36,12 @@
   <defs
      id="defs2385">
     <inkscape:perspective
-       id="perspective2391"
-       inkscape:persp3d-origin="320 : 160 : 1"
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 240 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
        inkscape:vp_z="640 : 240 : 1"
-       inkscape:vp_y="0 : 1000 : 0"
-       inkscape:vp_x="0 : 240 : 1"
-       sodipodi:type="inkscape:persp3d" />
+       inkscape:persp3d-origin="320 : 160 : 1"
+       id="perspective2391" />
   </defs>
   <metadata
      id="metadata2388">
@@ -54,45 +54,52 @@
       </cc:Work>
     </rdf:RDF>
     <ns0:scenes
-       current="1">
+       current="3">
       <ns0:scene
          start="1"
          ref="s7737" />
       <ns0:scene
          start="2"
          ref="s4405" />
+      <ns0:scene
+         start="3"
+         ref="s4702" />
     </ns0:scenes>
   </metadata>
   <g
-     inkscape:groupmode="layer"
+     id="layer1"
      inkscape:label="Layer 1"
-     id="layer1">
-    <text
-       xml:space="preserve"
-       style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-       x="188.4539"
-       y="189.57446"
-       id="text2554"><tspan
-         sodipodi:role="line"
-         id="tspan2556"
+     inkscape:groupmode="layer">
+    <g
+       id="s7737"
+       style="display:none">
+      <text
+         id="text2554"
+         y="189.57446"
          x="188.4539"
-         y="189.57446">This is scene 1</tspan></text>
+         style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         xml:space="preserve"><tspan
+           y="189.57446"
+           x="188.4539"
+           id="tspan2556"
+           sodipodi:role="line">This is scene 1</tspan></text>
+    </g>
+    <g
+       id="s4405"
+       style="display:none">
+      <text
+         xml:space="preserve"
+         style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         x="196.19858"
+         y="199.90071"
+         id="text2576"><tspan
+           sodipodi:role="line"
+           id="tspan2578"
+           x="196.19858"
+           y="199.90071">This is scene 2</tspan></text>
+    </g>
     <g
        style=""
-       id="s7737" />
-    <g
-       style="display:none"
-       id="s4405">
-      <text
-         id="text2576"
-         y="199.90071"
-         x="196.19858"
-         style="font-size:24px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
-         xml:space="preserve"><tspan
-           y="199.90071"
-           x="196.19858"
-           id="tspan2578"
-           sodipodi:role="line">This is scene 2</tspan></text>
-    </g>
+       id="s4702" />
   </g>
 </svg>
--- a/include/mb_redraw_man.h	Sun Jan 04 12:09:29 2009 +0800
+++ b/include/mb_redraw_man.h	Sun Jan 04 12:11:09 2009 +0800
@@ -74,6 +74,10 @@
 				 *	    \see addrm_monitor_hdlr()
 				 */
     mb_obj_t *last_mouse_over;
+    void *rt;                  /*!< \brief This is a pointer to the current 
+                                *          graphic backend. 
+				*          \see rdman_attach_backend()
+				*/
 };
 
 extern int redraw_man_init(redraw_man_t *rdman, cairo_t *cr,
@@ -186,6 +190,10 @@
 #define rdman_clear_shape_gl(rdman)		\
     DARRAY_CLEAN(rdman_get_gen_geos(rdman))
 
+/*! \brief Attach backend to the redraw manager so that we can hide the backend from the users.
+ *
+ */
+#define rdman_attach_backend(rdman,backend) (((rdman)->rt)=(backend))
 /*! \brief Load sprite dymanicly from the shared object module. 
  *  
  *   The search path can be changed by sprite_set_search_path. The name can have a relative path in the front of it.
@@ -199,5 +207,4 @@
  */
 void sprite_set_search_path(char *path);
 
-
 #endif /* __REDRAW_MAN_H_ */
--- a/inkscape/AssignSymbol.py	Sun Jan 04 12:09:29 2009 +0800
+++ b/inkscape/AssignSymbol.py	Sun Jan 04 12:11:09 2009 +0800
@@ -46,6 +46,9 @@
 			return
 		for id,node in self.selected.iteritems():
 			#self.dump(node)
+			if node.tag != '{http://www.w3.org/2000/svg}g':
+				self.confirm('Only group element can be converted into a symbol')
+				return
 			self.node = node
 			vbox = gtk.VBox()
 			vbox.pack_start(gtk.Label('Please input the symbol name'))
--- a/inkscape/MB_EditActiveButton.py	Sun Jan 04 12:09:29 2009 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-import inkex
-import pygtk
-import gtk
-from copy import deepcopy
-
-class ConvertToButton(inkex.Effect):
-	def effect(self):
-		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-		self.window.set_position(gtk.WIN_POS_MOUSE)
-		self.defaultname = 'input symbol name here'
-		if self.fillcontent() == False:
-			self.window.show_all()
-			self.window.connect("delete_event", gtk.main_quit)
-			gtk.main()
-	def onQuit(self,data):
-		gtk.main_quit()
-	def onAssign(self,data):
-		text = self.text.get_text()
-		if text != self.defaultname:
-			self.node.set("mbname",text)
-		gtk.main_quit()
-		
-	def confirm(self,msg):
-		vbox = gtk.VBox()
-		vbox.pack_start(gtk.Label(msg))
-		self.button = gtk.Button('OK')
-		vbox.pack_start(self.button)
-		self.button.connect("clicked", self.onQuit)
-		self.window.add(vbox)
-	def dumpattr(self,n):
-		s = ""
-		for a,v in n.attrib.items():
-			s = s + ("%s=%s"  % (a,v))
-		return s
-			
-	def dump(self,node,l=0):
-		print " " * l*2,"<", node.tag, self.dumpattr(node),">"
-		for n in node:
-			self.dump(n,l+1)
-		print " " * l * 2,"/>"
-
-	def hide_frame(self,frame):
-		frame.set('style','display:none')
-	def show_frame(self,frame):
-		frame.set('style','')
-		
-
-	def fillcontent(self):
-		if len(self.selected) != 1:
-			self.confirm('Please select one group only')
-			return False
-		for id,node in self.selected.iteritems():
-			#self.dump(node)
-			name = node.get("mbname")
-			if name == None:
-				self.confirm("The MadButterFly symbol is not defined yet. Please convert it to the symbol before convert it to button.")
-				return False
-			for frame in node:
-				if frame.get('mbname') == name+'_active':
-					self.show_frame(frame)
-				else:
-					self.hide_frame(frame)
-			return True
-
-
-a=ConvertToButton()
-a.affect()
-
-# vim: set ts=4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inkscape/MB_EditButton.inx	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,17 @@
+<inkscape-extension>
+    <name>Edit Button</name>
+    <id>MadButterfly.EditButton</id>
+	<dependency type="executable" location="extensions">MB_EditButton.py</dependency>
+	<dependency type="executable" location="extensions">inkex.py</dependency>
+    <effect>
+		<object-type>any</object-type>
+		<effects-menu>
+			<submenu _name="MadButterfly">
+				<submenu _name="Button"/>
+			</submenu>
+		</effects-menu>
+    </effect>
+    <script>
+        <command reldir="extensions" interpreter="python">MB_EditButton.py</command>
+    </script>
+</inkscape-extension>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inkscape/MB_EditButton.py	Sun Jan 04 12:11:09 2009 +0800
@@ -0,0 +1,158 @@
+#!/usr/bin/python
+import inkex
+import pygtk
+import gtk
+from copy import deepcopy
+from lxml import etree
+import os
+import tempfile
+
+class ConvertToButton(inkex.Effect):
+	def effect(self):
+		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+		self.window.set_position(gtk.WIN_POS_MOUSE)
+		self.defaultname = 'input symbol name here'
+		if self.fillcontent() == False:
+			self.window.show_all()
+			self.window.connect("delete_event", gtk.main_quit)
+			gtk.main()
+	def onQuit(self,data):
+		gtk.main_quit()
+	def onAssign(self,data):
+		text = self.text.get_text()
+		if text != self.defaultname:
+			self.node.set("mbname",text)
+		gtk.main_quit()
+		
+	def confirm(self,msg):
+		vbox = gtk.VBox()
+		vbox.pack_start(gtk.Label(msg))
+		self.button = gtk.Button('OK')
+		vbox.pack_start(self.button)
+		self.button.connect("clicked", self.onQuit)
+		self.window.add(vbox)
+	def dumpattr(self,n):
+		s = ""
+		for a,v in n.attrib.items():
+			s = s + ("%s=%s"  % (a,v))
+		return s
+			
+	def dump(self,node,l=0):
+		print " " * l*2,"<", node.tag, self.dumpattr(node),">"
+		for n in node:
+			self.dump(n,l+1)
+		print " " * l * 2,"/>"
+
+	def hide_frame(self,frame):
+		frame.set('style','display:none')
+	def show_frame(self,frame):
+		frame.set('style','')
+
+	def EditNormalButton(self,event,node):
+		self.EditButton(node,'_normal')
+
+	def EditActiveButton(self,event,node):
+		self.EditButton(node,'_active')
+
+	def EditClickButton(self,event,node):
+		self.EditButton(node,'_click')
+
+	def EditFrame(self,node):
+		# Generate a SVG file with node and invoke inkscape to edit it
+		svg = etree.Element('svg')
+		for n in node:
+			svg.append(deepcopy(n))
+		fd,fname = tempfile.mkstemp(suffix='.svg')
+		f = os.fdopen(fd,"w")
+		f.write(etree.tostring(svg))
+		f.close()
+		os.system("inkscape %s >/dev/null 2>/dev/null" % fname)
+		svg = etree.parse(fname)
+		os.unlink(fname)
+		newnode=[]
+		for n in svg.getroot():
+			if n.tag == '{http://www.w3.org/2000/svg}g':
+				newnode.append(n)
+			if n.tag == '{http://www.w3.org/2000/svg}rect':
+				newnode.append(n)
+			if n.tag == '{http://www.w3.org/2000/svg}text':
+				newnode.append(n)
+		return newnode
+				
+
+
+		
+	def duplicateAttribute(self,new,old):
+		for k,v in old.attrib.items():
+			new.set(k,v)
+
+
+	def EditButton(self,node,mode):
+		name = node.get('mbname')
+		for frame in node:
+			if frame.get('mbname') == name+mode:
+				newnode = self.EditFrame(frame)
+				oldframe = deepcopy(frame)
+				frame.clear()
+				self.duplicateAttribute(frame,oldframe)
+				for n in newnode:
+					frame.append(n)
+				return
+	def DisplayNormalButton(self,event,node):
+		self.displayButton(node,'_normal')
+	def DisplayActiveButton(self,event,node):
+		self.displayButton(node,'_active')
+	def DisplayClickButton(self,event,node):
+		self.displayButton(node,'_click')
+	def displayButton(self,node,mode):
+		name = node.get('mbname')
+		for n in node:
+			if n.get('mbname') == name+mode:
+				n.set('style','')
+			else:
+				n.set('style','display:none')
+		gtk.main_quit()
+		
+		
+
+	def fillcontent(self):
+		if len(self.selected) != 1:
+			self.confirm('Please select one group only')
+			return False
+		for id,node in self.selected.iteritems():
+			#self.dump(node)
+			name = node.get("mbname")
+			if name == None:
+				self.confirm("The MadButterFly symbol is not defined yet. Please convert it to the symbol before convert it to button.")
+				return False
+			type = node.get("mbtype")
+			if type != 'button':
+				self.confirm('This is not a button')
+				return False
+			hbox = gtk.HBox()
+			self.window.add(hbox)
+			button = gtk.Button('Edit Normal')
+			hbox.pack_start(button)
+			button.connect("clicked", self.EditNormalButton,node)
+			button = gtk.Button('Edit Active')
+			hbox.pack_start(button)
+			button.connect("clicked", self.EditActiveButton,node)
+			button = gtk.Button('Edit Click')
+			hbox.pack_start(button)
+			button.connect("clicked", self.EditClickButton,node)
+			button = gtk.Button('Display Normal')
+			hbox.pack_start(button)
+			button.connect("clicked", self.DisplayNormalButton,node)
+			button = gtk.Button('Display Active')
+			hbox.pack_start(button)
+			button.connect("clicked", self.DisplayActiveButton,node)
+			button = gtk.Button('Display Click')
+			hbox.pack_start(button)
+			button.connect("clicked", self.DisplayClickButton,node)
+			return False
+
+
+a=ConvertToButton()
+a.affect()
+
+# vim: set ts=4
--- a/inkscape/MB_EditClickButton.py	Sun Jan 04 12:09:29 2009 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-import inkex
-import pygtk
-import gtk
-from copy import deepcopy
-
-class ConvertToButton(inkex.Effect):
-	def effect(self):
-		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-		self.window.set_position(gtk.WIN_POS_MOUSE)
-		self.defaultname = 'input symbol name here'
-		if self.fillcontent() == False:
-			self.window.show_all()
-			self.window.connect("delete_event", gtk.main_quit)
-			gtk.main()
-	def onQuit(self,data):
-		gtk.main_quit()
-	def onAssign(self,data):
-		text = self.text.get_text()
-		if text != self.defaultname:
-			self.node.set("mbname",text)
-		gtk.main_quit()
-		
-	def confirm(self,msg):
-		vbox = gtk.VBox()
-		vbox.pack_start(gtk.Label(msg))
-		self.button = gtk.Button('OK')
-		vbox.pack_start(self.button)
-		self.button.connect("clicked", self.onQuit)
-		self.window.add(vbox)
-	def dumpattr(self,n):
-		s = ""
-		for a,v in n.attrib.items():
-			s = s + ("%s=%s"  % (a,v))
-		return s
-			
-	def dump(self,node,l=0):
-		print " " * l*2,"<", node.tag, self.dumpattr(node),">"
-		for n in node:
-			self.dump(n,l+1)
-		print " " * l * 2,"/>"
-
-	def hide_frame(self,frame):
-		frame.set('style','display:none')
-	def show_frame(self,frame):
-		frame.set('style','')
-		
-
-	def fillcontent(self):
-		if len(self.selected) != 1:
-			self.confirm('Please select one group only')
-			return False
-		for id,node in self.selected.iteritems():
-			#self.dump(node)
-			name = node.get("mbname")
-			if name == None:
-				self.confirm("The MadButterFly symbol is not defined yet. Please convert it to the symbol before convert it to button.")
-				return False
-			for frame in node:
-				if frame.get('mbname') == name+'_click':
-					self.show_frame(frame)
-				else:
-					self.hide_frame(frame)
-			return True
-
-
-a=ConvertToButton()
-a.affect()
-
-# vim: set ts=4
--- a/inkscape/MB_EditNormalButton.py	Sun Jan 04 12:09:29 2009 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#!/usr/bin/python
-import inkex
-import pygtk
-import gtk
-from copy import deepcopy
-
-class ConvertToButton(inkex.Effect):
-	def effect(self):
-		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
-		self.window.set_position(gtk.WIN_POS_MOUSE)
-		self.defaultname = 'input symbol name here'
-		if self.fillcontent() == False:
-			self.window.show_all()
-			self.window.connect("delete_event", gtk.main_quit)
-			gtk.main()
-	def onQuit(self,data):
-		gtk.main_quit()
-	def onAssign(self,data):
-		text = self.text.get_text()
-		if text != self.defaultname:
-			self.node.set("mbname",text)
-		gtk.main_quit()
-		
-	def confirm(self,msg):
-		vbox = gtk.VBox()
-		vbox.pack_start(gtk.Label(msg))
-		self.button = gtk.Button('OK')
-		vbox.pack_start(self.button)
-		self.button.connect("clicked", self.onQuit)
-		self.window.add(vbox)
-	def dumpattr(self,n):
-		s = ""
-		for a,v in n.attrib.items():
-			s = s + ("%s=%s"  % (a,v))
-		return s
-			
-	def dump(self,node,l=0):
-		print " " * l*2,"<", node.tag, self.dumpattr(node),">"
-		for n in node:
-			self.dump(n,l+1)
-		print " " * l * 2,"/>"
-
-	def hide_frame(self,frame):
-		frame.set('style','display:none')
-	def show_frame(self,frame):
-		frame.set('style','')
-		
-
-	def fillcontent(self):
-		if len(self.selected) != 1:
-			self.confirm('Please select one group only')
-			return False
-		for id,node in self.selected.iteritems():
-			#self.dump(node)
-			name = node.get("mbname")
-			if name == None:
-				self.confirm("The MadButterFly symbol is not defined yet. Please convert it to the symbol before convert it to button.")
-				return False
-			for frame in node:
-				if frame.get('mbname') == name+'_normal':
-					self.show_frame(frame)
-				else:
-					self.hide_frame(frame)
-			return True
-
-
-a=ConvertToButton()
-a.affect()
-
-# vim: set ts=4
--- a/inkscape/MB_Frame.py	Sun Jan 04 12:09:29 2009 +0800
+++ b/inkscape/MB_Frame.py	Sun Jan 04 12:11:09 2009 +0800
@@ -83,12 +83,12 @@
 		pass
 						
 						
-
 	def parseScene(self):
 		"""
 		In this function, we will collect all items for the current scene and then relocate them back to the appropriate scene object.
 		"""
 		self.layer = []
+		self.scenemap = None
 		for node in self.document.getroot():
 			if node.tag == '{http://www.w3.org/2000/svg}metadata':
 				self.parseMetadata(node)
@@ -468,20 +468,53 @@
 		btn=gtk.Button('Extend scene')
 		btn.connect('clicked', self.doExtendScene)
 		hbox.pack_start(btn)
+	def onQuit(self, event):
+		self.OK = False
+		gtk.main_quit()
+	def onOK(self,event):
+		self.OK = True
+		gtk.main_quit()
+
+	def onConfirmDelete(self):
+		if self.scenemap == None:
+			vbox = gtk.VBox()
+			vbox.pack_start(gtk.Label('Convert the SVG into a MadButterfly SVG file. All current element will be delted'))
+			hbox = gtk.HBox()
+			self.button = gtk.Button('OK')
+			hbox.pack_start(self.button)
+			self.button.connect('clicked', self.onOK)
+			self.button = gtk.Button('Cancel')
+			hbox.pack_start(self.button)
+			self.button.connect("clicked", self.onQuit)
+			vbox.pack_start(hbox)
+			self.window.add(vbox)
+			self.window.show_all()
+			gtk.main()
+			self.window.remove(vbox)
+
+
 	def effect(self):
+		self.OK = False
 		self.parseScene()
 		self.showGrid()
 		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
 		self.window.connect("destroy", gtk.main_quit)
 		self.window.set_position(gtk.WIN_POS_MOUSE)
-		vbox = gtk.VBox()
-		self.window.add(vbox)
-		vbox.add(self.scrollwin)
-		self.vbox = vbox
-		hbox=gtk.HBox()
-		self.addButtons(hbox)
-		vbox.add(hbox)
+		if self.scenemap == None:
+			self.onConfirmDelete()
+		if self.OK:
+			vbox = gtk.VBox()
+			self.window.add(vbox)
+			vbox.add(self.scrollwin)
+			self.vbox = vbox
+			hbox=gtk.HBox()
+			self.addButtons(hbox)
+			vbox.add(hbox)
+		else:
+			return
+
 		self.window.set_size_request(600,200)
+
 		self.window.show_all()
 		gtk.main()
 
--- a/inkscape/MB_button_select_click.inx	Sun Jan 04 12:09:29 2009 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<inkscape-extension>
-    <name>Edit Click button</name>
-    <id>MadButterfly.EditClickButton</id>
-	<dependency type="executable" location="extensions">MB_EditClickButton.py</dependency>
-	<dependency type="executable" location="extensions">inkex.py</dependency>
-    <effect>
-		<object-type>any</object-type>
-		<effects-menu>
-			<submenu _name="MadButterfly">
-				<submenu _name="Button"/>
-			</submenu>
-		</effects-menu>
-    </effect>
-    <script>
-        <command reldir="extensions" interpreter="python">MB_EditClickButton.py</command>
-    </script>
-</inkscape-extension>
-
--- a/inkscape/MB_button_select_normal.inx	Sun Jan 04 12:09:29 2009 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-<inkscape-extension>
-    <name>Edit Normal button</name>
-    <id>MadButterfly.EditNormalButton</id>
-	<dependency type="executable" location="extensions">MB_EditNormalButton.py</dependency>
-	<dependency type="executable" location="extensions">inkex.py</dependency>
-    <effect>
-		<object-type>any</object-type>
-		<effects-menu>
-			<submenu _name="MadButterfly">
-				<submenu _name="Button"/>
-			</submenu>
-		</effects-menu>
-    </effect>
-    <script>
-        <command reldir="extensions" interpreter="python">MB_EditNormalButton.py</command>
-    </script>
-</inkscape-extension>
-
--- a/inkscape/README.mbext	Sun Jan 04 12:09:29 2009 +0800
+++ b/inkscape/README.mbext	Sun Jan 04 12:11:09 2009 +0800
@@ -51,3 +51,9 @@
 
 This function will invoke another inkscape to edit the selected button. In the new inkscape, all three group will be visible and put in different layer. We can move them and edit them. When we close the inkscape, the MB extention will collect the new content and update the groups in the original SVG file. By this way, we can edit the button in any SVG file.
 
+Button 
+   +--- Convert to button
+   +--- Edit Button
+       +---- Normal Frame
+       +---- Active Frame
+       +---- Click Frame
--- a/src/X_supp.c	Sun Jan 04 12:09:29 2009 +0800
+++ b/src/X_supp.c	Sun Jan 04 12:11:09 2009 +0800
@@ -442,6 +442,10 @@
 
     xmb_rt->rdman = (redraw_man_t *)malloc(sizeof(redraw_man_t));
     redraw_man_init(xmb_rt->rdman, xmb_rt->cr, xmb_rt->backend_cr);
+    // FIXME: This is a wired loopback reference. This is inly required when we need 
+    //        to get the xmb_rt->tman for the animation. We should relocate the tman
+    //	      to the redraw_man_t instead.
+    xmb_rt->rdman->rt = xmb_rt;
 
     xmb_rt->tman = mb_tman_new();