Version 4, last updated by wycc at Aug 17 17:58 2010 UTC

SVG extention for the scene

A scene is a set of SVG groups which should be displayed together. An UI is composed of multiple scenes accoridng to the UI flow. Different scenes may share some common objects. The format of the scene allow the object sharing.

The scene defeinition is in the 'scenes' tag under the metadata tag. It contains multiple scene tag inside it to define all scenes. Each scene will refer to one of the layer in the inkscape. For example,

<metadata id="metadata1">
    <scenes current="2">
        <scene start="1" end="3" xlink:ref="g1234" />
        <scene start="1" xlink:ref="g1235" />
        <scene start="2" xlink:ref="g1236" />
        <scene start="3" xlink:ref="g1237" />
    </scenes>
</metadata>

In the above example, we deefines three scenes. g1234 is in layer 1. g1235,g1236 and g1237 is in layer 2. The first scene contains group g1234 and g1235. The second scene contains g1234 and g1236 and so on.

The real elements is inside the regular SVG groups. For example,

<g id="layer1">
    <g id="g1234" style="display:none">
        <rect id="r1234"/>
    </g>
</g>
< g id="layer2">
    <g id="g1235" style="display:none">
    <g id="g1236" style="display:none">
    <g id="g1237" style="display:none">
</g>

In oreder to prevent these "scene groups" are visible in the inkscape, all of them are marked as invisible attribute 'display:none'. All non scene group elements are created by the inkscape extention to give users visual feedback about what they re editing. For example, when user select the scene 2 to edit, the extention will make a copy of the children nodes of group g1234 under the layer1 as

<g id="layer1">
    <rect id="r1234"/>
    <g id="g1234" style="display:none">
        <rect id="r1234"/>
    </g>
</g>
< g id="layer2">
    <g id="g1235" style="display:none"/>
    <g id="g1236" style="display:none"/>
    <g id="g1237" style="display:none"/>
</g>

In this way, the rectangle will become visible in the inkscape. The svg2code.py should use all elements outside the scene groups to replace the content of the scene group. For example, if we add one rectangle in both layer 1 and layer 2,

<g id="layer1">
    <rect id="r1234"/>
    <rect id="r1239"/>
    <g id="g1234" style="display:none">
        <rect id="r1234"/>
    </g>
</g>
< g id="layer2">
    <rect id="r1240"/>
    <g id="g1235" style="display:none"/>
    <g id="g1236" style="display:none"/>
    <g id="g1237" style="display:none"/>
</g>

the new content of the layer 1 will have two rectangles instead one. After the scene is changed to scene 3, it will become

<g id="layer1">
    <rect id="r1234"/>
    <rect id="r1239"/>
    <g id="g1234" style="display:none">
        <rect id="r1234"/>
        <rect id="r1239"/>
    </g>
</g>
< g id="layer2">
    <g id="g1235" style="display:none"/>
    <g id="g1236" style="display:none">
        <rect id="r1240"/>
    </g>
    <g id="g1237" style="display:none"/>
</g>

The meta data will become

<metadata id="metadata1">
    <scenes current="3">
        <scene start="1" end="3" xlink:ref="g1234" />
        <scene start="1" xlink:ref="g1235" />
        <scene start="2" xlink:ref="g1236" />
        <scene start="3" xlink:ref="g1237" />
    </scenes>
</metadata>

This structure allow us to create new scene easily. We only need to add one line into the scene.

<metadata id="metadata1">
    <scenes current="3">
        <scene start="1" end="3" xlink:ref="g1234" />
        <scene start="1" xlink:ref="g1235" />
        <scene start="2" xlink:ref="g1236" />
        <scene start="3" xlink:ref="g1237" />
        <scene start="4" xlink:ref="g1238" />
    </scenes>
</metadata>

Of course, we need to insert one more scene group g1238 in the layer2. This will create a key scene. Each key scene is mapped into an unique scene group. We can create "filled scene" as well. A filled scene does not has its scene group. The following line define a key scene at 1 and two filled scene in 2 and 3.

    <scene start="1" end="3" xlink:ref="g1234" />

How to support scene in the MadButterfly

The mb_sprite_t should be expanded to add one more function gotoScene to switch between scenes.

In addition, the svg2code.py must be rewriiten to support the scene. Firstly, we need to replace the elements of the current scene by using the non-scene-group elements to reflect the final result. This may be implemented outside the svg2code.py to generate a final SVG file before we generate the C source code.

Secondly, we can generate the entire SVG file as usual. Since all elements are not visible, nothing can be seen initially. We need to generate a scene table as well. This table is used by the gotoScene funcrtion to display/hide groups. This table can ge generated from the scenes tag. For example, in the above SVG file, the table will looks like.

coord_t *scene1 = {obj->g1234,obj->g1235};
coord_t *scene2 = {obj->g1234,obj->g1236};
coord_t *scene3 = {obj->g1234,obj->g1237};
coord_t *scenes[3] = {scene1,scene2,scene3};

The gotoScene(n) can hide all scene groups and then show the ones in the scene[n].

The Library extention

This extention will allows us to share objects between scenes. It can help us to build some reusable components. In the future, we can build a library of components and allow users to import them into the SVG file. This is similiar with the Library function in the Flash. When we add a symbol in the library into the scene, it is represented as a reference to the original id in the scene group.

However,since the inkscape can not edit the reference node defined by us, we need to put a copy of the symbol as a non-screne-group group. Inkscape can edit it as usual, the inkscape extention or svg2code will replace the old content with the new one before it is future processed. In order to associate it with the original symbol in the library, we will put a xlink:ref attribute to do the job.

To be finished....