Back to index

gcompris  8.2.2
anim.py
Go to the documentation of this file.
00001 #  gcompris - anim
00002 #
00003 # Time-stamp: <2001/08/20 00:54:45 bruno>
00004 #
00005 # Copyright (C) 2003 Bruno Coudoin (redraw code), 2004 Yves Combe (anim code)
00006 #
00007 #   This program is free software; you can redistribute it and/or modify
00008 #   it under the terms of the GNU General Public License as published by
00009 #   the Free Software Foundation; either version 2 of the License, or
00010 #   (at your option) any later version.
00011 #
00012 #   This program is distributed in the hope that it will be useful,
00013 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 #   GNU General Public License for more details.
00016 #
00017 #   You should have received a copy of the GNU General Public License
00018 #   along with this program; if not, write to the Free Software
00019 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 #
00021 
00022 #  Version 2 of anim
00023 # Due to performance, the animation code as been rewriten
00024 # For now, the animation is done keeping difference
00025 # in parameters of graphicals object between shots?
00026 
00027 
00028 from gettext import gettext as _
00029 # PythonTest Board module
00030 import gobject
00031 import gnomecanvas
00032 import gcompris
00033 import gcompris.utils
00034 import gcompris.skin
00035 import gcompris.bonus
00036 import gtk
00037 import gtk.gdk
00038 import gtk.keysyms
00039 import copy
00040 import math
00041 import time
00042 import os
00043 import sys
00044 import tempfile
00045 import cPickle as pickle
00046 import base64
00047 
00048 # Note that we only need one of these for any given version of the
00049 # processing class.
00050 #
00051 python_xml = False
00052 # python_xml = True
00053 # try:
00054 #   from xml.dom.DOMImplementation import implementation
00055 #   import xml.sax.writer
00056 #   import xml.utils
00057 # except:
00058 #   python_xml = False
00059   # Commented out, until we have a clean support for a mainstream mozilla
00060   #print _('You need the python xml module. Disabling SVG.')
00061 
00062 fles=None
00063 
00064 # When anim is passed the mode 'draw', animation is disabled.
00065 #
00066 
00067 #class Gcompris_anim:
00068 class Gcompris_anim:
00069   """The cartoon activity"""
00070 
00071   def __init__(self, gcomprisBoard):
00072 
00073     self.gcomprisBoard = gcomprisBoard
00074 
00075     # There is two board in the same code
00076     # here the diff in parameters
00077 
00078     # The main list of items
00079     # this parameter is used in svg save, to know where to get the list
00080     self.itemlist = { 'draw' : 'framelist',
00081                     'anim': 'animlist'
00082                       }
00083 
00084     if self.gcomprisBoard.mode == 'draw':
00085       self.format_string = { 'gcompris' : 'GCompris draw 2 cPikle file',
00086                              'svg' : 'GCompris draw 2 svg file'
00087                              }
00088     else:
00089       self.format_string = { 'gcompris' : 'GCompris anim 2 cPikle file',
00090                              'svg' : 'GCompris anim 2 svg file'
00091                              }
00092 
00093     if self.gcomprisBoard.mode == 'draw':
00094       # DRAW
00095       #
00096       # draw is adapted to little kids : big anchors
00097       self.DEFAULT_ANCHOR_SIZE     = 12
00098 
00099       # Step used in grid is wider
00100       self.grid_step = 10
00101 
00102       # draw specific UI
00103       self.selector_section = "draw2"
00104     else:
00105       # Anim
00106       #
00107       # Normal anchors
00108       self.DEFAULT_ANCHOR_SIZE     = 8
00109 
00110       # Step used in grid is wider
00111       self.grid_step = 5
00112 
00113       # anim specific UI
00114       self.selector_section = "anim2"
00115 
00116     # Initialisation. Should not change in draw.
00117     self.running = False
00118 
00119 
00120     # In draw objects are created without drag&drop
00121     # Default size for rect, circle, line
00122     self.draw_defaults_size = { 'RECT' : {'width' : 60 , 'height' : 40 },
00123                             'FILL_RECT' : {'width' : 60 , 'height' : 40 },
00124                             'CIRCLE' : {'width' : 60 , 'height' : 40 },
00125                                 'FILL_CIRCLE' : {'width' : 60 , 'height' : 40 },
00126                                 'LINE' : {'width' : 60 , 'height' : 40 }
00127                               }
00128 
00129     # Cool !!!
00130     self.empty="empty"
00131 
00132     # global parameter to access object structures from global fonctions
00133     global fles
00134     fles=self
00135 
00136     # File formats to save/restore
00137     #
00138     # svg has proprietary data to handle animation, base64 included images
00139     # gcompris is cPickle python saved data
00140     #
00141     # svg in draw mode is normal svg file with base64 included images
00142     global python_xml
00143     if self.gcomprisBoard.mode == 'draw':
00144       self.file_type = "image/gcompris+draw"
00145       if python_xml:
00146         self.file_type = self.file_type + " image/svg+xml"
00147     else:
00148       self.file_type = "image/gcompris+anim"
00149       #      if python_xml:
00150       #        self.file_type = self.file_type +"  image/svg+xml+javascript"
00151 
00152     # These are used to let us restart only after the bonux is displayed.
00153     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00154     self.board_paused  = 0
00155     self.gamewon       = 0
00156 
00157     self.MAX_TEXT_CHAR = 50
00158 
00159     # kind of beautiful blue
00160     self.ANCHOR_COLOR = 0x36ede480
00161 
00162 
00163     # anchortype
00164     self.ANCHOR_NW = 1
00165     self.ANCHOR_N  = 2
00166     self.ANCHOR_NE = 3
00167     self.ANCHOR_E  = 4
00168     self.ANCHOR_W  = 5
00169     self.ANCHOR_SW = 6
00170     self.ANCHOR_S  = 7
00171     self.ANCHOR_SE = 8
00172     self.ANCHOR_T  = 9
00173 
00174     self.anchors = { 'LINE': [ self.ANCHOR_SW , self.ANCHOR_NE ],
00175                      'RECT': [ self.ANCHOR_N,
00176                                self.ANCHOR_NE,
00177                                self.ANCHOR_E,
00178                                self.ANCHOR_SE,
00179                                self.ANCHOR_S,
00180                                self.ANCHOR_SW,
00181                                self.ANCHOR_W,
00182                                self.ANCHOR_NW
00183                                ],
00184                      'TEXT': [ self.ANCHOR_T ]
00185                      }
00186     self.anchors ['FILL_RECT'] =  self.anchors ['RECT']
00187     self.anchors ['CIRCLE'] =  self.anchors ['RECT']
00188     self.anchors ['FILL_CIRCLE'] =  self.anchors ['RECT']
00189     self.anchors ['IMAGE'] =  self.anchors ['RECT']
00190 
00191     # gnomecanvas type corresponding
00192     self.types = { 'RECT' : gnomecanvas.CanvasRect,
00193                    'FILL_RECT' : gnomecanvas.CanvasRect,
00194                    'CIRCLE' : gnomecanvas.CanvasEllipse,
00195                    'FILL_CIRCLE' : gnomecanvas.CanvasEllipse,
00196                    'TEXT' : gnomecanvas.CanvasText,
00197                    'IMAGE' : gnomecanvas.CanvasPixbuf,
00198                    'LINE' : gnomecanvas.CanvasLine
00199                    }
00200 
00201     # mutable gnomecanvas attributs
00202     self.attributs = { 'LINE' : [ "points",
00203                                   "fill_color_rgba",
00204                                   ],
00205                        'RECT' : [ "x1",
00206                                   "y1",
00207                                   "x2",
00208                                   "y2",
00209                                   "outline_color_rgba",
00210                                   ],
00211                        'FILL_RECT' : [ "x1",
00212                                        "y1",
00213                                        "x2",
00214                                        "y2",
00215                                        "fill_color_rgba",
00216                                        ],
00217                        'CIRCLE' : [ "x1",
00218                                     "y1",
00219                                     "x2",
00220                                     "y2",
00221                                     "outline_color_rgba",
00222                                     ],
00223                        'FILL_CIRCLE' : [ "x1",
00224                                          "y1",
00225                                          "x2",
00226                                          "y2",
00227                                          "fill_color_rgba",
00228                                          ],
00229                        'TEXT' : [ "x",
00230                                   "y",
00231                                   "text",
00232                                   "fill_color_rgba",
00233                                   ],
00234                        'IMAGE' : [ "x",
00235                                    "y",
00236                                    "width",
00237                                    "height",
00238                                    ]
00239                        }
00240 
00241     # non mutable gnomecanvas attributs
00242     self.fixedattributs = { 'LINE' : { 'width-units': 8.0
00243                                        },
00244                             'RECT' : { 'width-units': 4.0
00245                                        },
00246                             'FILL_RECT' : { 'width-units': 1.0,
00247                                             'outline_color_rgba': 0x000000FFL
00248                                             },
00249                             'CIRCLE' : { 'width-units': 4.0 },
00250                             'FILL_CIRCLE' : { 'width-units': 1.0,
00251                                               'outline_color_rgba': 0x000000FFL
00252                                               },
00253                             'TEXT' : { 'font': gcompris.FONT_BOARD_BIG_BOLD,
00254                                        'anchor' : gtk.ANCHOR_CENTER
00255                                        },
00256                             'IMAGE' : { 'width_set': True,
00257                                         'height_set': True
00258                                         }
00259                        }
00260 
00261 
00262     # events handled by each type
00263     self.events = { 'LINE' : [ self.fillin_item_event,
00264                                self.move_item_event,
00265                                self.create_item_event,
00266                                self.del_item_event ] ,
00267                     'RECT' : [ self.fillout_item_event,
00268                                self.move_item_event,
00269                                self.create_item_event,
00270                                self.del_item_event ],
00271                     'TEXT' : [ self.fillin_item_event,
00272                                self.move_item_event,
00273                                self.create_item_event,
00274                                self.del_item_event ],
00275                     'IMAGE' : [ self.move_item_event,
00276                                 self.create_item_event,
00277                                 self.del_item_event ]
00278                     }
00279 
00280     self.events ['FILL_RECT']         = self.events ['LINE']
00281     self.events ['FILL_CIRCLE']       = self.events ['LINE']
00282     self.events ['CIRCLE']  = self.events ['RECT']
00283 
00284 
00285     # Part of UI : tools buttons
00286     # TOOL SELECTION
00287     self.tools = [
00288       ["SAVE",           "draw/tool-save.png",            "draw/tool-save.png",                  gcompris.CURSOR_SELECT],
00289       ["LOAD",           "draw/tool-load.png",            "draw/tool-load.png",                  gcompris.CURSOR_SELECT],
00290       ["MOVIE",          "draw/tool-movie.png",           "draw/tool-movie_on.png",              gcompris.CURSOR_SELECT],
00291       ["PICTURE",        "draw/tool-camera.png",          "draw/tool-camera_on.png",             gcompris.CURSOR_SELECT],
00292       ["RECT",           "draw/tool-rectangle.png",       "draw/tool-rectangle_on.png",          gcompris.CURSOR_RECT],
00293       ["FILL_RECT",      "draw/tool-filledrectangle.png", "draw/tool-filledrectangle_on.png",    gcompris.CURSOR_FILLRECT],
00294       ["CIRCLE",         "draw/tool-circle.png",          "draw/tool-circle_on.png",             gcompris.CURSOR_CIRCLE],
00295       ["FILL_CIRCLE",    "draw/tool-filledcircle.png",    "draw/tool-filledcircle_on.png",       gcompris.CURSOR_FILLCIRCLE],
00296       ["LINE",           "draw/tool-line.png",            "draw/tool-line_on.png",               gcompris.CURSOR_LINE],
00297       ["FILL",           "draw/tool-fill.png",            "draw/tool-fill_on.png",               gcompris.CURSOR_FILL],
00298       ["DEL",            "draw/tool-del.png",             "draw/tool-del_on.png",                gcompris.CURSOR_DEL],
00299       ["SELECT",         "draw/tool-select.png",          "draw/tool-select_on.png",             gcompris.CURSOR_SELECT],
00300       ["RAISE",          "draw/tool-up.png",              "draw/tool-up_on.png",                 gcompris.CURSOR_DEFAULT],
00301       ["LOWER",          "draw/tool-down.png",            "draw/tool-down_on.png",               gcompris.CURSOR_DEFAULT],
00302       ["CCW",            "draw/tool-rotation-ccw.png",    "draw/tool-rotation-ccw_on.png",       gcompris.CURSOR_DEFAULT],
00303       ["CW",             "draw/tool-rotation-cw.png",     "draw/tool-rotation-cw_on.png",        gcompris.CURSOR_DEFAULT],
00304       ["FLIP",           "draw/tool-flip.png",            "draw/tool-flip_on.png",               gcompris.CURSOR_DEFAULT],
00305       ["TEXT",           "draw/tool-text.png",            "draw/tool-text_on.png",               gcompris.CURSOR_LINE],
00306       ["IMAGE",          "draw/tool-image.png",           "draw/tool-image_on.png",              gcompris.CURSOR_DEFAULT],
00307       ]
00308 
00309     # keep the tool selected
00310     self.current_tool=0
00311 
00312     # Part of UI: colors buttons
00313     # COLOR SELECTION
00314     # RGBA unsigned long. A is always FF.
00315     # keep in mind if you change that to change the svg export: it does not pass A.
00316     self.colors = [   0x000000FFL, 0x202020FFL, 0x404040FFL, 0x505050FFL,
00317                       0x815a38FFL, 0xb57c51FFL, 0xe5a370FFL, 0xfcc69cFFL,
00318                       0xb20c0cFFL, 0xea2c2cFFL, 0xf26363FFL, 0xf7a3a3FFL,
00319                       0xff6600FFL, 0xff8a3dFFL, 0xfcaf7bFFL, 0xf4c8abFFL,
00320                       0x9b8904FFL, 0xd3bc10FFL, 0xf4dd2cFFL, 0xfcee85FFL,
00321                       0x255b0cFFL, 0x38930eFFL, 0x56d11dFFL, 0x8fe268FFL,
00322                       0x142f9bFFL, 0x2d52e5FFL, 0x667eddFFL, 0xa6b4eaFFL,
00323                       0x328989FFL, 0x37b2b2FFL, 0x3ae0e0FFL, 0x96e0e0FFL,
00324                       0x831891FFL, 0xc741d8FFL, 0xde81eaFFL, 0xeecdf2FFL,
00325                       0x666666FFL, 0x838384FFL, 0xc4c4c4FFL, 0xffffffFFL
00326                       ]
00327 
00328     # keep the current color here
00329     self.current_color = 0
00330 
00331     # step of the grid used for positioning objects
00332     # TODO : add a parameters to put step=5 in draw and step=1 in anim
00333     self.current_step = 0
00334 
00335     # selected object
00336     self.selected = None
00337 
00338     # Part of UI : drawing_area is the drawing zone
00339     # when anim is played, it's masked and playing_area is displayed
00340     #
00341     # Drawing area is editing image area
00342     # Palying area is playing map
00343     self.drawing_area = [124.0, 20.0, gcompris.BOARD_WIDTH - 15, gcompris.BOARD_HEIGHT - 78]
00344     self.playing_area = [124.0, 20.0, gcompris.BOARD_WIDTH - 15, gcompris.BOARD_HEIGHT - 78]
00345 
00346     # Global used for the select event
00347     #
00348     # used to keep the distance between pointer and corner in moving objects
00349     self.in_select_ofx = -1
00350     self.in_select_ofy = -1
00351 
00352     # The frame counter
00353     # TODO : check if used
00354     self.item_frame_counter = []
00355 
00356     # Not used for the moment in anim2
00357     # TODO : fix that
00358     #self.current_image = 0
00359 
00360     # Part of UI
00361     # The root items
00362     self.root_coloritem = []
00363     self.root_toolitem  = []
00364 
00365     # Anim2 variables
00366     # animlist is the full list of all items.
00367     # each item is keeped with it's frame information
00368     #    - frames where it's modified
00369     #    - all modifications for each frame
00370     #
00371     # list of items in current frame
00372     self.framelist = []
00373     # list of items in the full animation
00374     self.animlist = []
00375     # rank of the current frame being processed
00376     self.current_frame = 0
00377     self.frames_total =  self.current_frame
00378     # list of z values in last shot
00379     self.list_z_last_shot = []
00380     # list of actual z values
00381     self.list_z_actual = []
00382 
00383     # used to handle draw creation of object
00384     self.draw_created_object = False
00385 
00386   def start(self):
00387 
00388     self.last_commit = None
00389 
00390     # GCompris initialisation
00391     self.gcomprisBoard.level=1
00392     self.gcomprisBoard.maxlevel=1
00393     self.gcomprisBoard.sublevel=0
00394     self.gcomprisBoard.number_of_sublevel=0
00395 
00396     gcompris.bar_set(0)
00397     gcompris.set_background(self.gcomprisBoard.canvas.root(),
00398                             gcompris.skin.image_to_skin("gcompris-bg.jpg"))
00399 
00400     # Create our rootitem. We put each canvas item in it so at the end we
00401     # only have to kill it. The canvas deletes all the items it contains automaticaly.
00402     self.rootitem = self.gcomprisBoard.canvas.root().add(
00403       gnomecanvas.CanvasGroup,
00404       x=0.0,
00405       y=0.0
00406       )
00407 
00408     # initialisation
00409     self.draw_tools()
00410     self.draw_animtools()
00411     self.draw_colors()
00412     self.draw_drawing_area(self.grid_step)
00413     self.draw_playing_area()
00414     self.pause(0)
00415 
00416     global python_xml
00417     if not python_xml:
00418       #gcompris.utils.dialog(_('Python xml module not found. SVG is disabled. Install the python xml module to enable SVG Save/restore.'), None)
00419       #print _('Python xml module not found. SVG is disabled. Install the python xml module to enable SVG Save/restore.')
00420       pass
00421 
00422   def end(self):
00423     # stop the animation
00424     if self.running:
00425       self.playing_stop()
00426 
00427     # Remove the root item removes all the others inside it
00428     gcompris.set_cursor(gcompris.CURSOR_DEFAULT);
00429     self.rootitem.destroy()
00430 
00431   def pause(self, pause):
00432     #used to stop the event reception at the end?
00433     self.board_paused = pause
00434     return
00435 
00436   def repeat(self):
00437     print("Gcompris_anim repeat.")
00438 
00439   def config(self):
00440     print("Gcompris_anim config.")
00441 
00442   def key_press(self, keyval, commit_str, preedit_str):
00443     #
00444     # I suppose codec is the stdin one.
00445     #
00446     codec = sys.stdin.encoding
00447 
00448     # keyboard shortcuts
00449     if (keyval == gtk.keysyms.F1):
00450       gcompris.file_selector_save( self.gcomprisBoard, self.selector_section, self.file_type, general_save)
00451     elif (keyval == gtk.keysyms.F2):
00452       gcompris.file_selector_load( self.gcomprisBoard, self.selector_section, self.file_type, general_restore)
00453 
00454     # Printing
00455     # Bruno we need a print button !
00456     #
00457     # was in anim1, but not print an animation is not interesting.
00458     elif (keyval == gtk.keysyms.F3):
00459       pass
00460       #if self.gcomprisBoard.mode == 'draw':
00461         # We can keep in draw2, svg export will be pure svg.
00462         #self.ps_print(self.get_drawing(self.current_image))
00463       #else:
00464         #print "Sorry i can't print an animation"
00465 
00466     # AFAIR The keyboard part was written by bruno
00467     elif ((keyval == gtk.keysyms.Shift_L) or
00468           (keyval == gtk.keysyms.Shift_R) or
00469           (keyval == gtk.keysyms.Control_L) or
00470           (keyval == gtk.keysyms.Control_R) or
00471           (keyval == gtk.keysyms.Caps_Lock) or
00472           (keyval == gtk.keysyms.Shift_Lock) or
00473           (keyval == gtk.keysyms.Meta_L) or
00474           (keyval == gtk.keysyms.Meta_R) or
00475           (keyval == gtk.keysyms.Alt_L) or
00476           (keyval == gtk.keysyms.Alt_R) or
00477           (keyval == gtk.keysyms.Super_L) or
00478           (keyval == gtk.keysyms.Super_R) or
00479           (keyval == gtk.keysyms.Hyper_L) or
00480           (keyval == gtk.keysyms.Hyper_R) or
00481           (keyval == gtk.keysyms.Mode_switch) or
00482           (keyval == gtk.keysyms.dead_circumflex) or
00483           (keyval == gtk.keysyms.Num_Lock)):
00484       return False
00485 
00486     if (self.selected == None):
00487       return True
00488     elif (gobject.type_name(self.selected.item_list[0])!="GnomeCanvasText"):
00489       #print "Not Text object when got key !!!"
00490       return True
00491 
00492     textItem = self.selected.item_list[0]
00493     if (self.last_commit == None):
00494       oldtext = textItem.get_property('text').decode('UTF-8')
00495     else:
00496       oldtext = self.last_commit
00497 
00498     if ((keyval == gtk.keysyms.BackSpace) or
00499         (keyval == gtk.keysyms.Delete)):
00500       if (len(oldtext) != 1):
00501         newtext = oldtext[:-1]
00502       else:
00503         newtext = u'?'
00504       self.last_commit = newtext
00505     else:
00506       if ((oldtext[:1] == u'?') and (len(oldtext)==1)):
00507         oldtext = u' '
00508         oldtext = oldtext.strip()
00509 
00510       if (commit_str != None):
00511         str = commit_str
00512         self.last_commit = oldtext + str
00513       if (preedit_str != None):
00514         str = '<span foreground="red">'+ preedit_str +'</span>'
00515         self.last_commit = oldtext
00516 
00517       if (len(oldtext) < self.MAX_TEXT_CHAR):
00518         newtext = oldtext + str
00519       else:
00520         newtext = oldtext
00521 
00522     textItem.set(markup=newtext.encode('UTF-8'))
00523 
00524     return True
00525 
00526   # Display the tools
00527   def draw_tools(self):
00528 
00529     self.root_toolitem = self.rootitem.add(
00530       gnomecanvas.CanvasGroup,
00531       x=0.0,
00532       y=0.0
00533       )
00534 
00535     self.root_toolitem.add(
00536       gnomecanvas.CanvasPixbuf,
00537       pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/tool-selector.png")),
00538       x=5,
00539       y=5.0,
00540       width=107.0,
00541       height=517.0,
00542       width_set=True,
00543       height_set=True
00544       )
00545 
00546     x1=11.0
00547     x2=56.0
00548     y=11.0
00549     stepy=45
00550 
00551     # Display the tools
00552     for i in range(0,len(self.tools)):
00553 
00554       # Exclude the anim specific buttons
00555       if self.gcomprisBoard.mode == 'draw':
00556         if self.tools[i][0]=="MOVIE" or self.tools[i][0]=="PICTURE":
00557           continue
00558 
00559       if(i%2):
00560         theX = x2
00561       else:
00562         theX = x1
00563 
00564       item = self.root_toolitem.add(
00565         gnomecanvas.CanvasPixbuf,
00566         pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[i][1])),
00567         x=theX,
00568         y=y
00569         )
00570       item.connect("event", self.tool_item_event, i)
00571       if i%2:
00572         y += stepy
00573 
00574       if(self.tools[i][0]=="SELECT"):
00575         self.select_tool = item
00576         self.select_tool_number = i
00577         # Always select the SELECT item by default
00578         self.current_tool = i
00579         self.old_tool_item = item
00580         self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[i][2])))
00581         gcompris.set_cursor(self.tools[i][3]);
00582 
00583 
00584   # Event when a tool is selected
00585   # Perform instant action or swich the tool selection
00586   def tool_item_event(self, item, event, tool):
00587 
00588     if event.type == gtk.gdk.BUTTON_PRESS:
00589       if event.button == 1:
00590         # Some button have instant effects
00591         if (self.tools[tool][0] == "SAVE"):
00592 #          self.Anim2Shot()
00593           gcompris.file_selector_save( self.gcomprisBoard, self.selector_section, self.file_type, general_save)
00594           return True
00595 
00596         elif (self.tools[tool][0] == "LOAD"):
00597           gcompris.file_selector_load( self.gcomprisBoard, self.selector_section, self.file_type, general_restore)
00598           return True
00599 
00600         elif (self.tools[tool][0] == "IMAGE"):
00601           self.pos_x = gcompris.BOARD_WIDTH/2
00602           self.pos_y = gcompris.BOARD_HEIGHT/2
00603 
00604           gcompris.images_selector_start(self.gcomprisBoard,
00605                                          "dataset",
00606                                          image_selected);
00607           return True
00608 
00609         elif (self.tools[tool][0] == "PICTURE"):
00610           self.Anim2Shot()
00611           return True
00612 
00613         elif (self.tools[tool][0] == "MOVIE"):
00614           if self.frames_total == 0:
00615             print 'Mmm... Need to make shots before run anim !!'
00616             return True
00617 
00618           if not self.running:
00619             # unselect object if necessary
00620             self.unselect()
00621 
00622             self.playing_start()
00623             return True
00624 
00625         elif (self.tools[tool][0] != "SELECT") and (self.selected != None):
00626           self.unselect()
00627 
00628         #
00629         # Normal case, tool button switch
00630         # -------------------------------
00631 
00632         # Deactivate old button
00633         self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[self.current_tool][1])))
00634 
00635         # Activate new button
00636         self.current_tool = tool
00637         self.old_tool_item = item
00638         self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[self.current_tool][2])))
00639         gcompris.set_cursor(self.tools[self.current_tool][3]);
00640 
00641 
00642   # Display the color selector
00643   def draw_colors(self):
00644 
00645     pixmap = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/color-selector.png"))
00646 
00647     x = (self.drawing_area[2] - self.drawing_area[0]
00648          - pixmap.get_width())/2 + self.drawing_area[0]
00649 
00650     color_pixmap_height = pixmap.get_height()
00651 
00652     y = gcompris.BOARD_HEIGHT - color_pixmap_height - 8
00653 
00654     c = 0
00655 
00656     self.root_coloritem = self.rootitem.add(
00657       gnomecanvas.CanvasGroup,
00658       x=0.0,
00659       y=0.0
00660       )
00661 
00662     self.root_coloritem.add(
00663       gnomecanvas.CanvasPixbuf,
00664       pixbuf = pixmap,
00665       x=x,
00666       y=y,
00667       )
00668 
00669     for i in range(0,10):
00670       x1=x+26+i*56
00671 
00672       for j in range(0,4):
00673         c = i*4 +j
00674         item = self.root_coloritem.add(
00675           gnomecanvas.CanvasRect,
00676           x1=x1 + 26*(j%2),
00677           y1=y+8 + (color_pixmap_height/2 -6)*(j/2),
00678           x2=x1 + 24  + 26*(j%2),
00679           y2=y + color_pixmap_height/2  + (color_pixmap_height/2 -6)*(j/2),
00680           fill_color_rgba=self.colors[c],
00681           outline_color_rgba=0x07A3E0FFL
00682           )
00683 
00684         item.connect("event", self.color_item_event, c)
00685         if (c==0):
00686           self.current_color = c
00687           self.old_color_item = item
00688           self.old_color_item.set(width_units = 4.0,
00689                                   outline_color_rgba= 0x16EC3DFFL)
00690 
00691   # Color event
00692   def color_item_event(self, item, event, color):
00693     if self.running:
00694       return
00695 
00696     if event.type == gtk.gdk.BUTTON_PRESS:
00697       if event.button == 1:
00698         # Deactivate old button
00699         self.old_color_item.set(width_units = 0.0,
00700                                 outline_color_rgba= 0x144B9DFFL)
00701 
00702         # Activate new button
00703         self.current_color = color
00704         self.old_color_item = item
00705         self.old_color_item.set(width_units = 4.0,
00706                                 outline_color_rgba= 0x16EC3DFFL)
00707 
00708 
00709   # Display the drawing area
00710   def draw_drawing_area(self,step):
00711 
00712     x1=self.drawing_area[0]
00713     y1=self.drawing_area[1]
00714     x2=self.drawing_area[2]
00715     y2=self.drawing_area[3]
00716 
00717     item = self.rootitem.add (
00718       gnomecanvas.CanvasRect,
00719       x1=x1,
00720       y1=y1,
00721       x2=x2,
00722       y2=y2,
00723       fill_color_rgba=0xFFFFFFFFL,
00724       width_units=2.0,
00725       outline_color_rgba=0x111199FFL
00726       )
00727     item.connect("event", self.create_item_event)
00728 
00729     # The CanvasGroup for the edit space.
00730     self.root_drawingitem = self.rootitem.add(
00731       gnomecanvas.CanvasGroup,
00732       x=0.0,
00733       y=0.0
00734       )
00735     self.draw_grid(x1,x2,y1,y2,step)
00736 
00737     # Create the root_anim group which contains all the drawings.
00738     # At root_anim root, there is a group for each drawings.
00739     self.root_anim = self.rootitem.add(
00740       gnomecanvas.CanvasGroup,
00741       x=0.0,
00742       y=0.0
00743       )
00744 
00745     gcompris.utils.item_absolute_move(self.root_anim,
00746                                       int(self.playing_area[0]-self.drawing_area[0]),
00747                                       int(self.playing_area[1]-self.drawing_area[1])
00748                                       )
00749 
00750     # Create a group for the first drawing
00751 
00752     self.flash = self.rootitem.add (
00753       gnomecanvas.CanvasPixbuf,
00754       pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/camera.png")),
00755       x=300,
00756       y=200,
00757       )
00758     self.flash.hide()
00759 
00760 
00761   # Display the drawing area
00762   def draw_playing_area(self):
00763 
00764     x1=self.playing_area[0]
00765     y1=self.playing_area[1]
00766     x2=self.playing_area[2]
00767     y2=self.playing_area[3]
00768 
00769 
00770     # The CanvasGroup for the playing area.
00771     self.root_playingitem = self.rootitem.add(
00772       gnomecanvas.CanvasGroup,
00773       x=0.0,
00774       y=0.0
00775       )
00776     self.root_playingitem.hide()
00777 
00778     # intervall = 1000 / anim_speed
00779     self.anim_speed=5
00780 
00781     run = self.root_playingitem.add(
00782       gnomecanvas.CanvasPixbuf,
00783       pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/down.png")),
00784       x = 15,
00785       y = 410,
00786       width = 20,
00787       height = 20,
00788       width_set = 1,
00789       height_set = 1
00790       )
00791     run.connect("event", self.speed_event,False)
00792 
00793     self.speed_item = self.root_playingitem.add(
00794       gnomecanvas.CanvasText,
00795       text=self.anim_speed,
00796       font = gcompris.skin.get_font("gcompris/board/medium"),
00797       x=52,
00798       y=420,
00799       anchor=gtk.ANCHOR_CENTER,
00800       )
00801 
00802 
00803     run = self.root_playingitem.add(
00804       gnomecanvas.CanvasPixbuf,
00805       pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/up.png")),
00806       x = 70,
00807       y = 410,
00808       width = 20,
00809       height = 20,
00810       width_set = 1,
00811       height_set = 1
00812       )
00813     run.connect("event", self.speed_event,True)
00814 
00815     # And finaly a STOP icon
00816     run = self.root_playingitem.add(
00817       gnomecanvas.CanvasPixbuf,
00818       pixbuf = gcompris.utils.load_pixmap("boardicons/draw.png"),
00819       x = 16,
00820       y = 110,
00821       )
00822     run.connect("event", self.stop_event,True)
00823 
00824 
00825   def stop_event(self, item, event, up):
00826     if event.type == gtk.gdk.BUTTON_PRESS:
00827       self.playing_stop()
00828 
00829   def playing_stop(self):
00830     self.running=False
00831     gobject.source_remove(self.timeout)
00832     self.run_anim2()
00833 
00834   def speed_event(self, item, event, up):
00835 
00836     if event.type == gtk.gdk.BUTTON_PRESS:
00837       if up:
00838         if self.anim_speed==25:
00839           return
00840         else:
00841           self.anim_speed=self.anim_speed+1
00842       else:
00843         if self.anim_speed==1:
00844           return
00845         else:
00846           self.anim_speed=self.anim_speed-1
00847 
00848       gobject.source_remove(self.timeout)
00849       self.timeout=gobject.timeout_add(1000/self.anim_speed, self.run_anim2)
00850       self.speed_item.set(text=self.anim_speed)
00851 
00852   # Draw the grid
00853   #
00854   def draw_grid(self, x1, x2, y1, y2, step):
00855 
00856     self.current_step = step
00857 
00858     color = 0x1D0DFFFFL
00859 
00860     self.grid = self.rootitem.add (
00861       gnomecanvas.CanvasGroup,
00862       x=0.0,
00863       y=0.0
00864       )
00865     self.grid.hide()
00866 
00867     for i in range(int(x1), int(x2), step):
00868       item = self.grid.add (
00869         gnomecanvas.CanvasLine,
00870         points=(i , y1, i , y2),
00871         fill_color_rgba=color,
00872         width_units=1.0,
00873         )
00874       # Clicking on lines let you create object
00875       item.connect("event", self.create_item_event)
00876 
00877     for i in range(int(y1), int(y2), step):
00878       item = self.grid.add (
00879         gnomecanvas.CanvasLine,
00880         points=(x1, i, x2 , i),
00881         fill_color_rgba=color,
00882         width_units=1.0,
00883         )
00884       item.connect("event", self.create_item_event)
00885 
00886   # Given x,y return a new x,y snapped to the grid
00887   def snap_to_grid(self, x, y):
00888     result = []
00889     tmp = round(((x+(self.current_step)) -
00890                self.drawing_area[0])/self.current_step) - 1
00891     result.append(float(self.drawing_area[0] + tmp*self.current_step))
00892 
00893     tmp = round(((y+(self.current_step)) -
00894                self.drawing_area[1])/self.current_step) - 1
00895     result.append(float(self.drawing_area[1] + tmp*self.current_step))
00896     return result
00897 
00898 
00899   # Event when a click on any item. Perform the move
00900   def move_item_event(self, item, event):
00901     if self.tools[self.current_tool][0] == "CCW":
00902       if ((event.type == gtk.gdk.BUTTON_PRESS) and
00903           (event.button == 1) and
00904           (gobject.type_name(item)!="GnomeCanvasText")):
00905         # this one seems broken
00906         #gcompris.utils.item_rotate_relative(item.get_property("parent"),-10)
00907         self.rotate_relative(item,-10)
00908         return True
00909       else:
00910         return False
00911 
00912     if self.tools[self.current_tool][0] == "CW":
00913       if ((event.type == gtk.gdk.BUTTON_PRESS) and
00914           (event.button == 1) and
00915           (gobject.type_name(item)!="GnomeCanvasText")):
00916         self.rotate_relative(item,10)
00917         return True
00918       else:
00919         return False
00920 
00921     if self.tools[self.current_tool][0] == "FLIP":
00922       if ((event.type == gtk.gdk.BUTTON_PRESS) and
00923           (event.button == 1) and
00924           (gobject.type_name(item)!="GnomeCanvasText")):
00925         self.item_flip(item);
00926         return True
00927       else:
00928         return False
00929 
00930     if self.tools[self.current_tool][0] == "RAISE":
00931       if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
00932         item.get_property("parent").raise_(1)
00933         self.z_raise(item.get_data("AnimItem"))
00934         return True
00935       else:
00936         return False
00937 
00938     if self.tools[self.current_tool][0] == "LOWER":
00939       if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
00940         item.get_property("parent").lower(1)
00941         self.z_lower(item.get_data("AnimItem"))
00942         return True
00943       else:
00944         return False
00945 
00946     if self.tools[self.current_tool][0] != "SELECT":
00947       return False
00948 
00949     if event.type == gtk.gdk.BUTTON_PRESS and event.button == 1:
00950       if event.button == 1:
00951         self.unselect()
00952 
00953     #
00954     # MOUSE DRAG STOP
00955     # ---------------
00956     if event.type == gtk.gdk.BUTTON_RELEASE:
00957       if event.button == 1:
00958         if self.draw_created_object:
00959           self.draw_created_object = False
00960           return True
00961         # activate the anchors
00962         self.selected=item.get_property("parent")
00963         self.selected.item_list[1].show()
00964 
00965         # Reset the in_select_ofx ofset
00966         self.in_select_ofx = -1
00967         self.in_select_ofy = -1
00968 
00969         return True
00970 
00971     if event.state & gtk.gdk.BUTTON1_MASK:
00972       wx=event.x
00973       wy=event.y
00974       #pass in item relative coordinate
00975       (x, y)= item.w2i( wx, wy)
00976 
00977       bounds = item.get_bounds()
00978       #bounds = self.get_bounds(item)
00979 
00980       # Save the ofset between the mouse pointer and the upper left corner of the object
00981       if(self.in_select_ofx == -1):
00982         self.in_select_ofx = x-bounds[0]
00983         self.in_select_ofy = y-bounds[1]
00984 
00985       x -= self.in_select_ofx
00986       y -= self.in_select_ofy
00987 
00988       x,y = self.snap_to_grid(x,y)
00989 
00990       # Check drawing boundaries
00991       #needs to be corrected with item relative coordinate
00992       # FIXME
00993 #      if(x<self.drawing_area[0]):
00994 #        x=self.drawing_area[0]
00995 #      if(x>(self.drawing_area[2]-(bounds[2]-bounds[0]))):
00996 #        x=self.drawing_area[2]-(bounds[2]-bounds[0])
00997         # We need to realign x cause the bounds values are not precise enough
00998 #        x,n = self.snap_to_grid(x,y)
00999 #      if(y<self.drawing_area[1]):
01000 #        y=self.drawing_area[1]
01001 #      if(y>(self.drawing_area[3]-(bounds[3]-bounds[1]))):
01002 #        y=self.drawing_area[3]-(bounds[3]-bounds[1])
01003         # We need to realign y cause the bounds values are not precise enough
01004 #        n,y = self.snap_to_grid(x,y)
01005 
01006       # Now perform the object move
01007       #gcompris.utils.item_absolute_move(item.get_property("parent"), x, y)
01008       # pass it in item coordinate:
01009       #(idx, idy) =  item.w2i( x-bounds[0], y-bounds[1] )
01010       (idx, idy) =  ( x-bounds[0], y-bounds[1] )
01011       self.object_move(
01012         item.get_property("parent"),
01013         idx,
01014         idy
01015         )
01016 
01017       return True
01018 
01019     return False
01020 
01021   # Event when a click on an item happen on fill in type object
01022   def fillin_item_event(self, item, event):
01023     if event.type == gtk.gdk.BUTTON_PRESS:
01024       if event.button == 1:
01025         if self.tools[self.current_tool][0] == "FILL":
01026           item.set(fill_color_rgba=self.colors[self.current_color])
01027           return True
01028     return False
01029 
01030   # Event when a click on an item happen on border fill type object
01031   def fillout_item_event(self, item, event):
01032     if event.type == gtk.gdk.BUTTON_PRESS:
01033       if event.button == 1:
01034         if self.tools[self.current_tool][0] == "FILL":
01035           item.set(outline_color_rgba=self.colors[self.current_color])
01036           return True
01037     return False
01038 
01039   # Del an item and internal struct cleanup
01040   def del_item(self, item):
01041     item.get_property("parent").destroy()
01042     self.del_AnimItem(item.get_data("AnimItem"))
01043 
01044   # Event when a click on an item happen
01045   def del_item_event(self, item, event):
01046     if event.type == gtk.gdk.BUTTON_PRESS:
01047       if event.button == 1:
01048         if self.tools[self.current_tool][0] == "DEL":
01049           self.del_item(item);
01050           return True
01051     return False
01052 
01053   # Event when an event on the drawing area happen
01054   def create_item_event(self, item, event):
01055     if(event.type == gtk.gdk.BUTTON_PRESS and self.running==True):
01056       self.playing_stop()
01057       return False
01058 
01059     # Right button is a shortcup to Shot
01060     if (self.gcomprisBoard.mode != 'draw' and
01061         event.type == gtk.gdk.BUTTON_PRESS and
01062         event.button == 3):
01063       self.Anim2Shot()
01064       return False
01065 
01066     if (not (self.tools[self.current_tool][0] == "RECT" or
01067              self.tools[self.current_tool][0] == "CIRCLE" or
01068              self.tools[self.current_tool][0] == "FILL_RECT" or
01069              self.tools[self.current_tool][0] == "FILL_CIRCLE" or
01070              self.tools[self.current_tool][0] == "IMAGE" or
01071              self.tools[self.current_tool][0] == "TEXT" or
01072              self.tools[self.current_tool][0] == "LINE")):
01073       return False
01074 
01075     if event.type == gtk.gdk.BUTTON_PRESS:
01076 
01077       if event.button == 1:
01078         self.newitem = None
01079         print "----------------------------------------"
01080         print "Current image = " + str(self.current_frame)
01081         #self.dump_group(self.root_anim)
01082         self.newitemgroup = self.root_anim.add(
01083           gnomecanvas.CanvasGroup,
01084           x=0.0,
01085           y=0.0
01086           )
01087 
01088 
01089         if (self.tools[self.current_tool][0] == "DEL" or
01090             self.tools[self.current_tool][0] == "SELECT" or
01091             self.tools[self.current_tool][0] == "FILL"):
01092           # This event is treated in del_item_event to avoid
01093           # operating on background item and grid
01094           return False
01095 
01096         elif self.tools[self.current_tool][0] == "LINE":
01097 
01098           x,y = self.snap_to_grid(event.x,event.y)
01099           self.pos_x = x
01100           self.pos_y = y
01101 
01102           tuple_points = (x , y,  self.pos_x, self.pos_y)
01103 
01104           if self.gcomprisBoard.mode == 'draw':
01105             dist = {'x' : 'width', 'y' : 'height'}
01106 
01107             points = {}
01108             for c in ['x', 'y']:
01109               points[c + '1'] = eval(c) - self.draw_defaults_size['LINE'][dist[c]]/2
01110               points[c + '2'] = eval(c) + self.draw_defaults_size['LINE'][dist[c]]/2
01111             tuple_points = ( points['x1'], points['y1'], points['x2'], points['y2'])
01112 
01113 #     ItemGroup:
01114 #        AnchorsGroup
01115 #           ANCHOR_SE
01116 #           .....
01117 #        Item
01118 
01119           self.newitem = self.newitemgroup.add(
01120             gnomecanvas.CanvasLine,
01121             points=tuple_points,
01122             fill_color_rgba=self.colors[self.current_color],
01123             width_units=8.0
01124             )
01125 
01126         elif self.tools[self.current_tool][0] == "RECT":
01127 
01128           x,y = self.snap_to_grid(event.x,event.y)
01129           self.pos_x = x
01130           self.pos_y = y
01131 
01132           points = {}
01133           for c in ['x' , 'y']:
01134             points[c + '1'] = eval(c)
01135             points[c + '2'] = eval( 'self.pos_' + c )
01136 
01137 
01138           if self.gcomprisBoard.mode == 'draw':
01139             dist = {'x' : 'width', 'y' : 'height'}
01140 
01141             points = {}
01142             for c in ['x', 'y']:
01143               points[c + '1'] = eval(c) - self.draw_defaults_size['LINE'][dist[c]]/2
01144               points[c + '2'] = eval(c) + self.draw_defaults_size['LINE'][dist[c]]/2
01145 
01146           self.newitem = self.newitemgroup.add(
01147             gnomecanvas.CanvasRect,
01148             x1=points['x1'],
01149             y1=points['y1'],
01150             x2=points['x2'],
01151             y2=points['y2'],
01152             outline_color_rgba=self.colors[self.current_color],
01153             width_units=4.0
01154             )
01155           #          self.newitem.set_data('empty',True)
01156           gcompris.utils.canvas_set_property(self.newitem, "empty", "True")
01157 
01158         elif self.tools[self.current_tool][0] == "FILL_RECT":
01159 
01160           x,y = self.snap_to_grid(event.x,event.y)
01161           self.pos_x = x
01162           self.pos_y = y
01163 
01164           points = {}
01165           for c in ['x' , 'y']:
01166             points[c + '1'] = eval(c)
01167             points[c + '2'] = eval( 'self.pos_' + c )
01168 
01169           if self.gcomprisBoard.mode == 'draw':
01170             dist = {'x' : 'width', 'y' : 'height'}
01171 
01172             points = {}
01173             for c in ['x', 'y']:
01174               points[c + '1'] = eval(c) - self.draw_defaults_size['LINE'][dist[c]]/2
01175               points[c + '2'] = eval(c) + self.draw_defaults_size['LINE'][dist[c]]/2
01176 
01177           self.newitem = self.newitemgroup.add(
01178             gnomecanvas.CanvasRect,
01179             x1=points['x1'],
01180             y1=points['y1'],
01181             x2=points['x2'],
01182             y2=points['y2'],
01183             fill_color=self.colors[self.current_color],
01184             fill_color_rgba=self.colors[self.current_color],
01185             outline_color_rgba=0x000000FFL,
01186             width_units=1.0
01187             )
01188 
01189         elif self.tools[self.current_tool][0] == "CIRCLE":
01190 
01191           x,y = self.snap_to_grid(event.x,event.y)
01192           self.pos_x = x
01193           self.pos_y = y
01194 
01195 
01196           points = {}
01197           for c in ['x' , 'y']:
01198             points[c + '1'] = eval(c)
01199             points[c + '2'] = eval( 'self.pos_' + c )
01200 
01201 
01202           if self.gcomprisBoard.mode == 'draw':
01203             dist = {'x' : 'width', 'y' : 'height'}
01204 
01205             points = {}
01206             for c in ['x', 'y']:
01207               points[c + '1'] = eval(c) - self.draw_defaults_size['LINE'][dist[c]]/2
01208               points[c + '2'] = eval(c) + self.draw_defaults_size['LINE'][dist[c]]/2
01209 
01210           self.newitem = self.newitemgroup.add(
01211             gnomecanvas.CanvasEllipse,
01212             x1=points['x1'],
01213             y1=points['y1'],
01214             x2=points['x2'],
01215             y2=points['y2'],
01216              outline_color_rgba=self.colors[self.current_color],
01217             width_units=5.0
01218             )
01219           #          self.newitem.set_data('empty',True)
01220           gcompris.utils.canvas_set_property(self.newitem, "empty", "True")
01221 
01222         elif self.tools[self.current_tool][0] == "FILL_CIRCLE":
01223 
01224           x,y = self.snap_to_grid(event.x,event.y)
01225           self.pos_x = x
01226           self.pos_y = y
01227 
01228 
01229           points = {}
01230           for c in ['x' , 'y']:
01231             points[c + '1'] = eval(c)
01232             points[c + '2'] = eval( 'self.pos_' + c )
01233 
01234 
01235           if self.gcomprisBoard.mode == 'draw':
01236             dist = {'x' : 'width', 'y' : 'height'}
01237 
01238             points = {}
01239             for c in ['x', 'y']:
01240               points[c + '1'] = eval(c) - self.draw_defaults_size['LINE'][dist[c]]/2
01241               points[c + '2'] = eval(c) + self.draw_defaults_size['LINE'][dist[c]]/2
01242 
01243           self.newitem = self.newitemgroup.add(
01244             gnomecanvas.CanvasEllipse,
01245             x1=points['x1'],
01246             y1=points['y1'],
01247             x2=points['x2'],
01248             y2=points['y2'],
01249             fill_color_rgba=self.colors[self.current_color],
01250             outline_color_rgba=0x000000FFL,
01251             width_units=1.0
01252             )
01253 
01254         elif self.tools[self.current_tool][0] == "TEXT":
01255 
01256           x,y = self.snap_to_grid(event.x,event.y)
01257           self.pos_x = x
01258           self.pos_y = y
01259 
01260           self.newitem = self.newitemgroup.add(
01261             gnomecanvas.CanvasText,
01262             x=self.pos_x,
01263             y=self.pos_y,
01264             fill_color_rgba=self.colors[self.current_color],
01265             font=gcompris.FONT_BOARD_BIG_BOLD,
01266             text=u'?',
01267             anchor=gtk.ANCHOR_CENTER
01268             )
01269 
01270         if self.newitem != 0:
01271           self.anchorize(self.newitemgroup)
01272           anAnimItem = self.AnimItem()
01273           anAnimItem.z = self.new_z()
01274           anAnimItem.canvas_item = self.newitem
01275           anAnimItem.type = self.tools[self.current_tool][0]
01276           anAnimItem.canvas_item.set_data("AnimItem", anAnimItem)
01277           self.framelist.append(anAnimItem)
01278           self.list_z_actual.append(anAnimItem.z)
01279           self.draw_created_object = True
01280 
01281 
01282           if self.tools[self.current_tool][0] == "TEXT":
01283             (x1, x2, y1, y2) = self.get_bounds(self.newitem)
01284             self.object_set_size_and_pos(self.newitemgroup, x1, x2, y1, y2)
01285             self.select_item(self.newitemgroup)
01286             self.newitem = None
01287             self.newitemgroup = None
01288 
01289           elif self.gcomprisBoard.mode == 'draw':
01290             # needed because used to set the anchors.
01291             # The item has already the right size
01292             self.object_set_size_and_pos(self.newitemgroup,
01293                                           x1=points['x1'],
01294                                           y1=points['y1'],
01295                                           x2=points['x2'],
01296                                           y2=points['y2']
01297                                           )
01298 
01299             self.select_item(self.newitemgroup)
01300             # in draw creation is finished. Object is selected.
01301             self.newitem = None
01302             self.newitemgroup = None
01303 
01304       return True
01305 
01306     #
01307     # MOTION EVENT
01308     # ------------
01309     if event.type == gtk.gdk.MOTION_NOTIFY:
01310       # That's used only in itel creation.
01311       # In draw mode, item creation does not use drag&drop
01312       if self.gcomprisBoard.mode == 'draw':
01313         return False
01314 
01315       if ((self.tools[self.current_tool][0] == "IMAGE") or
01316           (self.tools[self.current_tool][0] == "TEXT")):
01317         return False
01318 
01319       if event.state & gtk.gdk.BUTTON1_MASK:
01320         if (self.tools[self.current_tool][0] == "RAISE" or
01321             self.tools[self.current_tool][0] == "LOWER"):
01322           return False
01323         x=event.x
01324         y=event.y
01325         x,y = self.snap_to_grid(event.x,event.y)
01326 
01327         # Check drawing boundaries
01328         if(event.x<self.drawing_area[0]):
01329           x=self.drawing_area[0]
01330         if(event.x>self.drawing_area[2]):
01331           x=self.drawing_area[2]
01332         if(event.y<self.drawing_area[1]):
01333           y=self.drawing_area[1]
01334         if(event.y>self.drawing_area[3]):
01335           y=self.drawing_area[3]
01336 
01337 #        if self.tools[self.current_tool][0] == "LINE":
01338 #          self.newitem.set( points=( self.pos_x, self.pos_y, x, y) )
01339 #        elif (self.tools[self.current_tool][0] == "RECT" or
01340 #              self.tools[self.current_tool][0] == "FILL_RECT" or
01341 #              self.tools[self.current_tool][0] == "CIRCLE" or
01342 #              self.tools[self.current_tool][0] == "FILL_CIRCLE"):
01343 #          self.newitem.set(
01344 #            x2=x,
01345 #            y2=y)
01346 
01347         if self.tools[self.current_tool][0] == "LINE":
01348           points= self.newitem.get_property("points")
01349           x1=points[0]
01350           y1=points[1]
01351         else:
01352           x1=self.newitem.get_property("x1")
01353           y1=self.newitem.get_property("y1")
01354         self.object_set_size_and_pos(self.newitemgroup,
01355                                      x1=x1,
01356                                      y1=y1,
01357                                      x2=x,
01358                                      y2=y
01359                                      )
01360     #
01361     # MOUSE DRAG STOP
01362     # ---------------
01363     if event.type == gtk.gdk.BUTTON_RELEASE:
01364       # That's used only in item creation.
01365       # In draw mode, item creation does not use drag&drop
01366       if self.draw_created_object:
01367         self.draw_created_object = False
01368         return True
01369 
01370       if ((self.tools[self.current_tool][0] == "IMAGE") or
01371           (self.tools[self.current_tool][0] == "TEXT")):
01372         return False
01373 
01374       if event.button == 1:
01375         if (self.tools[self.current_tool][0] == "RAISE" or
01376             self.tools[self.current_tool][0] == "LOWER"):
01377           return False
01378         # We have to remove empty created items (the kid did not drag enough)
01379         if self.tools[self.current_tool][0] == "LINE":
01380           # need to delete empty line. self.newitem est l'objet courant
01381           pass
01382         elif (self.tools[self.current_tool][0] == "RECT" or
01383               self.tools[self.current_tool][0] == "FILL_RECT" or
01384               self.tools[self.current_tool][0] == "CIRCLE" or
01385               self.tools[self.current_tool][0] == "FILL_CIRCLE"):
01386           # Oups, empty rect
01387           #self.del_item(self.newitem)
01388           pass
01389 
01390 #        print self.tools[self.current_tool][0]
01391 #        print self.newitem.get_bounds()
01392 #        print self.newitemgroup.get_bounds()
01393 
01394         return True
01395     return False
01396 
01397   def snapshot_event(self, item, event):
01398     if event.type == gtk.gdk.BUTTON_PRESS:
01399       self.Anim2Shot()
01400 
01401   def run_flash(self):
01402     self.flash.hide()
01403     return False
01404 
01405   def playing_start(self):
01406     if not self.running:
01407       self.running=True
01408       self.root_coloritem.hide()
01409       self.root_toolitem.hide()
01410       self.root_playingitem.show()
01411       self.Anim2Run()
01412 
01413   def playing_event(self, item, event, state):
01414     if event.type == gtk.gdk.BUTTON_PRESS:
01415       if state:
01416         self.playing_start()
01417       else:
01418         self.playing_stop()
01419 
01420   # Display the animation tools
01421   def draw_animtools(self):
01422     # Desactived for the moment
01423 
01424     x_left = 8
01425     y_top  = 472
01426     minibutton_width = 32
01427     minibutton_height = 20
01428 
01429     if self.gcomprisBoard.mode == 'draw':
01430       return
01431 
01432     # Draw the background area
01433     self.rootitem.add(
01434       gnomecanvas.CanvasPixbuf,
01435       pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("draw/counter.png")),
01436       x=x_left - -11,
01437       y=y_top - 2,
01438       width=70.0,
01439       height=34.0,
01440       width_set=True,
01441       height_set=True
01442       )
01443 
01444     # First
01445     #item = self.rootitem.add(
01446     #  gnomecanvas.CanvasPixbuf,
01447     #  pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("anim/minibutton.png")),
01448     #  x = x_left,
01449     #  y = y_top,
01450     #  )
01451     #item.connect("event", self.image_select_event, "first")
01452     #item = self.rootitem.add(
01453     #  gnomecanvas.CanvasText,
01454     #  text = "<<",
01455     #  x = x_left + 14,
01456     #  y = y_top + 7,
01457     #  )
01458     #item.connect("event", self.image_select_event, "first")
01459 
01460     # Image Number
01461     self.item_frame_counter = self.rootitem.add(
01462       gnomecanvas.CanvasText,
01463       text = self.current_frame + 1,
01464       x = x_left + minibutton_width + 14,
01465       y = y_top + 15,
01466       font = gcompris.skin.get_font("gcompris/board/medium"))
01467 
01468     # Last
01469     #item = self.rootitem.add(
01470     #  gnomecanvas.CanvasPixbuf,
01471     #  pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("anim/minibutton.png")),
01472     #  x = x_left + 2*minibutton_width,
01473     #  y = y_top,
01474     #  )
01475     #item.connect("event", self.image_select_event, "last")
01476     #item = self.rootitem.add(
01477     #  gnomecanvas.CanvasText,
01478     #  text = ">>",
01479     #  x = x_left + 2*minibutton_width + 14,
01480     #  y = y_top + 7,
01481     #  )
01482     #item.connect("event", self.image_select_event, "last")
01483 
01484     # Next line
01485     #y_top += minibutton_height
01486 
01487     # Previous
01488     #item = self.rootitem.add(
01489     #  gnomecanvas.CanvasPixbuf,
01490     #  pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("anim/minibutton.png")),
01491     #  x = x_left,
01492     #  y = y_top,
01493     #  )
01494     #item.connect("event", self.image_select_event, "previous")
01495     ##item = self.rootitem.add(
01496     #  gnomecanvas.CanvasText,
01497     #  text = "<",
01498     #  x = x_left + 14,
01499     #  y = y_top + 7,
01500     #  )
01501     #item.connect("event", self.image_select_event, "previous")
01502 
01503     # Next
01504     #item = self.rootitem.add(
01505     #  gnomecanvas.CanvasPixbuf,
01506     #  pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("anim/minibutton.png")),
01507     #  x = x_left + 2*minibutton_width,
01508     #  y = y_top,
01509     #  )
01510     #item.connect("event", self.image_select_event, "next")
01511     #item = self.rootitem.add(
01512     #  gnomecanvas.CanvasText,
01513     #  text = ">",
01514     #  x = x_left + 2*minibutton_width + 14,
01515     #  y = y_top + 7,
01516     #  )
01517     #item.connect("event", self.image_select_event, "next")
01518 
01519     # Last button line
01520     #y_top += minibutton_height
01521 
01522   def object_move(self,object,dx,dy):
01523     # Unfortunately object.move is broken for 'TEXT' group.
01524 
01525     if gobject.type_name(object.item_list[0])=="GnomeCanvasText":
01526       (x1,y1,x2,y2) = object.get_bounds()
01527       (idx, idy) =  object.w2i( dx, dy )
01528       self.object_set_size_and_pos(object, x1+idx, y1+idy, x2+idx, y2+idy)
01529     else:
01530       object.move(dx, dy)
01531 
01532   def object_set_size_and_pos(self, object, x1, y1, x2, y2):
01533     if gobject.type_name(object.item_list[0])=="GnomeCanvasLine":
01534       object.item_list[0].set(
01535         points=(x1,y1,x2,y2)
01536         )
01537     elif gobject.type_name(object.item_list[0])=="GnomeCanvasPixbuf":
01538       object.item_list[0].set(
01539         x=x1,
01540         y=y1,
01541         width=x2-x1,
01542         height=y2-y1
01543         )
01544     elif gobject.type_name(object.item_list[0])=="GnomeCanvasText":
01545       object.item_list[0].set(
01546         x=(x1+x2)/2,
01547         y=(y1+y2)/2
01548         )
01549     else:
01550       object.item_list[0].set(
01551         x1=x1,
01552         x2=x2,
01553         y1=y1,
01554         y2=y2
01555         )
01556 
01557     for anchor in object.item_list[1].item_list:
01558       anchor_type = anchor.get_data('anchor_type')
01559 
01560       if anchor_type == self.ANCHOR_N:
01561         anchor.set(
01562           x1= (x1 + x2 - self.DEFAULT_ANCHOR_SIZE)/2,
01563           x2= (x1 + x2 + self.DEFAULT_ANCHOR_SIZE)/2,
01564           y1= y2,
01565           y2= y2 + self.DEFAULT_ANCHOR_SIZE
01566           )
01567       elif anchor_type == self.ANCHOR_T:
01568         anchor.set(
01569           x1= (x1 + x2 - self.DEFAULT_ANCHOR_SIZE*3)/2,
01570           x2= (x1 + x2 + self.DEFAULT_ANCHOR_SIZE*3)/2,
01571           y1= y2,
01572           y2= y2 + self.DEFAULT_ANCHOR_SIZE
01573           )
01574       elif anchor_type == self.ANCHOR_NE:
01575         anchor.set(
01576           x1= x2,
01577           x2= x2 + self.DEFAULT_ANCHOR_SIZE,
01578           y1= y2,
01579           y2= y2 + self.DEFAULT_ANCHOR_SIZE
01580           )
01581       elif anchor_type == self.ANCHOR_E:
01582         anchor.set(
01583           x1= x2,
01584           x2= x2 + self.DEFAULT_ANCHOR_SIZE,
01585           y1= (y1 + y2 - self.DEFAULT_ANCHOR_SIZE)/2,
01586           y2= (y1 + y2 + self.DEFAULT_ANCHOR_SIZE)/2
01587           )
01588       elif anchor_type == self.ANCHOR_SE:
01589         anchor.set(
01590           x1= x2,
01591           x2= x2 + self.DEFAULT_ANCHOR_SIZE,
01592           y1= y1,
01593           y2= y1 - self.DEFAULT_ANCHOR_SIZE
01594           )
01595       elif anchor_type == self.ANCHOR_S:
01596         anchor.set(
01597           x1= (x1 + x2 - self.DEFAULT_ANCHOR_SIZE)/2,
01598           x2= (x1 + x2 + self.DEFAULT_ANCHOR_SIZE)/2,
01599           y1= y1,
01600           y2= y1 - self.DEFAULT_ANCHOR_SIZE
01601           )
01602       elif anchor_type == self.ANCHOR_SW:
01603         anchor.set(
01604           x1= x1,
01605           x2= x1 - self.DEFAULT_ANCHOR_SIZE,
01606           y1= y1,
01607           y2= y1 - self.DEFAULT_ANCHOR_SIZE
01608           )
01609       elif anchor_type == self.ANCHOR_W:
01610         anchor.set(
01611           x1= x1,
01612           x2= x1 - self.DEFAULT_ANCHOR_SIZE,
01613           y1= (y1 + y2 - self.DEFAULT_ANCHOR_SIZE)/2,
01614           y2=  (y1 + y2 + self.DEFAULT_ANCHOR_SIZE)/2,
01615           )
01616       elif anchor_type == self.ANCHOR_NW:
01617         anchor.set(
01618           x1= x1,
01619           x2= x1 - self.DEFAULT_ANCHOR_SIZE,
01620           y1= y2,
01621           y2= y2 + self.DEFAULT_ANCHOR_SIZE
01622           )
01623 
01624 
01625   def resize_item_event(self, item, event, anchor_type):
01626     if self.running:
01627       return
01628 
01629     # Right button is a shortcup to Shot
01630     if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3:
01631       self.Anim2Shot()
01632       return False
01633 
01634     if event.state & gtk.gdk.BUTTON1_MASK:
01635       # warning: anchor is in a group of anchors, which is in the object group
01636       parent=item.get_property("parent").get_property("parent")
01637       real_item=parent.item_list[0]
01638 
01639       wx=event.x
01640       wy=event.y
01641       #passing x, y to item relative coordinate
01642       (x,y)= item.w2i(wx,wy)
01643 
01644       if gobject.type_name(real_item)=="GnomeCanvasLine":
01645         points= real_item.get_property("points")
01646         x1=points[0]
01647         y1=points[1]
01648         x2=points[2]
01649         y2=points[3]
01650       elif gobject.type_name(real_item)=="GnomeCanvasPixbuf":
01651         x1=real_item.get_property("x")
01652         y1=real_item.get_property("y")
01653         x2=x1+real_item.get_property("width")
01654         y2=y1+real_item.get_property("height")
01655       elif gobject.type_name(real_item)=="GnomeCanvasText":
01656         y1=y
01657         y2=y+real_item.get_property("text_height")
01658         pass
01659       else:
01660         x1=real_item.get_property("x1")
01661         y1=real_item.get_property("y1")
01662         x2=real_item.get_property("x2")
01663         y2=real_item.get_property("y2")
01664 
01665       if (anchor_type == self.ANCHOR_N):
01666         self.object_set_size_and_pos(parent,
01667                                      x1=x1,
01668                                      y1=y1,
01669                                      x2=x2,
01670                                      y2=y
01671                                      )
01672       elif (anchor_type == self.ANCHOR_T):
01673         self.object_set_size_and_pos(parent,
01674                                      x1=x,
01675                                      y1=y1,
01676                                      x2=x,
01677                                      y2=y2
01678                                      )
01679       elif (anchor_type == self.ANCHOR_NE):
01680         self.object_set_size_and_pos(parent,
01681                                      x1=x1,
01682                                      y1=y1,
01683                                      x2=x,
01684                                      y2=y
01685                                      )
01686       elif (anchor_type == self.ANCHOR_E):
01687         self.object_set_size_and_pos(parent,
01688                                      x1=x1,
01689                                      y1=y1,
01690                                      x2=x,
01691                                      y2=y2
01692                                      )
01693       elif (anchor_type == self.ANCHOR_SE):
01694         self.object_set_size_and_pos(parent,
01695                                      x1=x1,
01696                                      y1=y,
01697                                      x2=x,
01698                                      y2=y2
01699                                      )
01700       elif (anchor_type == self.ANCHOR_S):
01701         self.object_set_size_and_pos(parent,
01702                                      x1=x1,
01703                                      y1=y,
01704                                      x2=x2,
01705                                      y2=y2
01706                                      )
01707       elif (anchor_type == self.ANCHOR_SW):
01708         self.object_set_size_and_pos(parent,
01709                                      x1=x,
01710                                      y1=y,
01711                                      x2=x2,
01712                                      y2=y2
01713                                      )
01714       elif (anchor_type == self.ANCHOR_W):
01715         self.object_set_size_and_pos(parent,
01716                                      x1=x,
01717                                      y1=y1,
01718                                      x2=x2,
01719                                      y2=y2
01720                                      )
01721       elif (anchor_type == self.ANCHOR_NW):
01722         self.object_set_size_and_pos(parent,
01723                                      x1=x,
01724                                      y1=y1,
01725                                      x2=x2,
01726                                      y2=y
01727                                      )
01728 
01729 
01730   def get_bounds(self, item):
01731 
01732     if gobject.type_name(item)=="GnomeCanvasLine":
01733       (x1,y1,x2,y2)=item.get_property("points")
01734     elif gobject.type_name(item)=="GnomeCanvasPixbuf":
01735       x1=item.get_property("x")
01736       y1=item.get_property("y")
01737       x2=item.get_property("x")+item.get_property("width")
01738       y2=item.get_property("y")+item.get_property("height")
01739     elif gobject.type_name(item)=="GnomeCanvasText":
01740       x=item.get_property("x")
01741       y=item.get_property("y")
01742       width=item.get_property("text_width")
01743       height=item.get_property("text_height")
01744       x1=x-width/2
01745       y1=y-height/2
01746       x2=x1+width
01747       y2=y1+height
01748     else:
01749       x1=item.get_property("x1")
01750       y1=item.get_property("y1")
01751       x2=item.get_property("x2")
01752       y2=item.get_property("y2")
01753 
01754     return (min(x1,x2),min(y1,y2),max(x1,x2),max(y1,y2))
01755 
01756 
01757   def item_type(self, item):
01758 
01759     item_type = ''
01760 
01761     if gobject.type_name(item)=="GnomeCanvasGroup":
01762       item_type='GROUP'
01763     elif gobject.type_name(item)=="GnomeCanvasLine":
01764       item_type='LINE'
01765     elif gobject.type_name(item)=="GnomeCanvasPixbuf":
01766       item_type='IMAGE'
01767     elif gobject.type_name(item)=="GnomeCanvasRect":
01768       try:
01769         # Can't do it here because it needs to be C compatible for the svgexport
01770         empty = gcompris.utils.canvas_get_property(item, "empty")
01771         #empty = item.get_data('empty')
01772         if empty == None:
01773           empty = Fale
01774         else:
01775           empty = True
01776         # empty is passed from C, not python object
01777         # if we get it that means is True
01778       except:
01779         empty = False
01780 
01781       if empty:
01782         item_type='RECT'
01783       else:
01784         item_type='FILL_RECT'
01785 
01786     elif gobject.type_name(item)=="GnomeCanvasEllipse":
01787       try:
01788         #empty = item.get_data('empty')
01789         # Can't do it here because it needs to be C compatible for the svgexport
01790         empty = gcompris.utils.canvas_get_property(item, "empty")
01791 
01792         if empty == None:
01793           empty = Fale
01794         else:
01795           empty = True
01796         # empty is passed from C, not python object
01797         # if we get it that means is True
01798       except:
01799         empty = False
01800 
01801       if empty:
01802         item_type='CIRCLE'
01803       else:
01804         item_type='FILL_CIRCLE'
01805 
01806     elif gobject.type_name(item)=="GnomeCanvasText":
01807       item_type='TEXT'
01808 
01809 
01810     return item_type
01811 
01812 
01813   #
01814   # Call anchorize recursively on each item of the group
01815   #
01816   def recursive_anchorize(self, root_item):
01817     for item in root_item.item_list:
01818       if gobject.type_name(item)=="GnomeCanvasGroup":
01819         self.recursive_anchorize(item)
01820       else:
01821         self.anchorize(item.get_property("parent"))
01822 
01823   #
01824   # Add the anchors and callbacks on an item
01825   #
01826   def anchorize(self, group):
01827     # group contains normal items.
01828 
01829     item = group.item_list[0]
01830 
01831     item_type = self.item_type(item)
01832 
01833     if item_type == "GROUP" or not item_type:
01834       return
01835 
01836     for event in self.events[item_type]:
01837       item.connect("event", event)
01838 
01839     anchorgroup=group.add(
01840       gnomecanvas.CanvasGroup,
01841       x=0,
01842       y=0
01843       )
01844     anchorgroup.set_data('anchors',True)
01845     anchorgroup.hide()
01846 
01847     for anchor_type in self.anchors[item_type]:
01848       anchor=anchorgroup.add(
01849         gnomecanvas.CanvasRect,
01850         fill_color_rgba=self.ANCHOR_COLOR,
01851         outline_color_rgba=0x000000FFL,
01852         width_pixels=1,
01853         )
01854       anchor.set_data('anchor_type', anchor_type)
01855       anchor.connect("event", self.resize_item_event,anchor_type)
01856 
01857   def select_item(self, group):
01858     if (self.selected != None):
01859       self.unselect()
01860 
01861     # Deactivate old button
01862     self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[self.current_tool][1])))
01863 
01864     # Activate new button
01865     self.current_tool = self.select_tool_number
01866     self.old_tool_item = self.select_tool
01867     self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin(self.tools[self.current_tool][2])))
01868     gcompris.set_cursor(self.tools[self.current_tool][3]);
01869 
01870     self.selected = group
01871     self.selected.item_list[1].show()
01872 
01873   def rotate_relative(self, item, angle):
01874     bounds = item.get_bounds()
01875     #    print "Item bounds : ", bounds
01876 
01877     #bds = item.get_property("parent").get_bounds()
01878     #    print "Item parent bounds : ", bounds
01879 
01880     (cx, cy) = ( (bounds[2]+bounds[0])/2 , (bounds[3]+bounds[1])/2)
01881 
01882 
01883     t = math.radians(angle)
01884 
01885     # This matrix rotate around ( cx, cy )
01886 
01887     #     This is the result of the product:
01888 
01889 
01890     #            T_{-c}             Rot (t)                 T_c
01891 
01892     #       1    0   cx       cos(t) -sin(t)    0        1    0  -cx
01893     #       0    1   cy  by   sin(t)  cos(t)    0   by   0    1  -cy
01894     #       0    0    1         0       0       1        0    0   1
01895 
01896 
01897     mat = ( math.cos(t),
01898             math.sin(t),
01899             -math.sin(t),
01900             math.cos(t),
01901             (1-math.cos(t))*cx + math.sin(t)*cy,
01902             -math.sin(t)*cx + (1 - math.cos(t))*cy)
01903 
01904     item.get_property("parent").affine_relative(mat)
01905 
01906 
01907     return
01908 
01909   def item_flip(self, item):
01910     bounds = self.get_bounds(item)
01911     (cx, cy) = ( (bounds[2]+bounds[0])/2 , (bounds[3]+bounds[1])/2)
01912 
01913     mat = ( -1, 0, 0, 1, 2*cx, 0)
01914 
01915     item.get_property("parent").affine_relative(mat)
01916 
01917 
01918 ###########################################
01919 # Anim 2 specific
01920 ###########################################
01921 
01922   class AnimItem:
01923     def __init__(self):
01924       self.z = None
01925       self.frames_info = {}
01926       self.canvas_item = None
01927       self.z_previous = None
01928 
01929   def new_z(self):
01930     if self.list_z_actual != []:
01931       return int(self.list_z_actual[-1] + 1 )
01932     else:
01933       return 1
01934 
01935   def del_AnimItem(self, AnimItem):
01936     # AnimItem is really deleted only on shot.
01937     self.list_z_actual.remove(AnimItem.z)
01938     AnimItem.z = None
01939     #AnimItem.frames_info[self.current_frame]['deleted']=True
01940 
01941   def z_raise(self, anAnimItem):
01942     index = self.list_z_actual.index(anAnimItem.z)
01943     if index < len(self.list_z_actual) -1 :
01944       if index < len(self.list_z_actual) - 2 :
01945         anAnimItem.z = (self.list_z_actual[index + 1] + self.list_z_actual[index + 2])/2.0
01946       else:
01947         anAnimItem.z = self.list_z_actual[-1] + 1
01948       self.list_z_actual.pop(index)
01949       self.list_z_actual.insert(index+1, anAnimItem.z)
01950 
01951   def z_lower(self, anAnimItem):
01952     index = self.list_z_actual.index(anAnimItem.z)
01953     if index > 0:
01954       if index > 1:
01955          anAnimItem.z = (self.list_z_actual[index - 1] + self.list_z_actual[index - 2])/2.0
01956       else:
01957         anAnimItem.z = self.list_z_actual[0] /2.0
01958       self.list_z_actual.pop(index)
01959       self.list_z_actual.insert(index-1, anAnimItem.z)
01960 
01961   # Version 2: compare attributs and put those with difference in frames_info
01962   #
01963   # self.attributs is list of specific attributs usable for animation
01964   # There is matrice (rotation, flip) and z position to check too
01965 
01966 
01967   def get_animitem_properties(self, anAnimItem):
01968     properties = {'matrice' : anAnimItem.canvas_item.i2c_affine((0,0,0,0,0,0)) }
01969     for property_name in self.attributs[anAnimItem.type]:
01970       properties [property_name] = anAnimItem.canvas_item.get_property(property_name)
01971       if property_name == 'text':
01972         properties [property_name] = properties [property_name].decode('UTF-8')
01973     return properties
01974 
01975   def z_reinit(self):
01976     for anAnimItem in self.framelist:
01977       anAnimItem.z = self.list_z_actual.index(anAnimItem.z)+1
01978       anAnimItem.z_previous =  anAnimItem.z
01979 
01980     self.list_z_last_shot= range(1, len(self.list_z_actual) + 1)
01981     self.list_z_actual=self.list_z_last_shot[:]
01982 
01983   def z_delete_on_shot(self, anAnimItem):
01984     if anAnimItem.z_previous != None:
01985         self.list_z_last_shot.remove(anAnimItem.z_previous)
01986 
01987   def get_modified_parameters(self, animItem):
01988 
01989         modified= {}
01990         dict_properties = self.get_animitem_properties(animItem)
01991         frames = animItem.frames_info.keys()
01992         if frames != []:
01993           frames.sort()
01994           frames.reverse()
01995 
01996           for property in dict_properties.keys():
01997             for frame in frames:
01998 #              print animItem.type, property, frame, animItem.frames_info[frame]
01999               if animItem.frames_info[frame].has_key(property):
02000                 if not animItem.frames_info[frame][property]==dict_properties[property]:
02001                   modified[property]=dict_properties[property]
02002                 break
02003         else:
02004           modified = dict_properties
02005           modified.update(self.fixedattributs[animItem.type])
02006           if animItem.type == 'IMAGE':
02007             modified['image_name']= animItem.image_name
02008           modified['create']=True
02009           self.animlist.append(animItem)
02010 
02011         if animItem.z != animItem.z_previous:
02012           if animItem.z_previous != None:
02013             self.list_z_last_shot.remove(animItem.z_previous)
02014           modified['z'] = self.z_find_index(animItem)
02015           self.list_z_last_shot.insert( modified['z'], animItem.z)
02016 
02017         return modified
02018 
02019   def Anim2Shot(self):
02020     if self.gcomprisBoard.mode == 'draw':
02021       return
02022     self.flash.show()
02023     for anAnimItem in self.framelist[:]:
02024       if anAnimItem.z == None:
02025         # deleted
02026         self.z_delete_on_shot(anAnimItem)
02027         modified = { 'delete': True }
02028         self.framelist.remove(anAnimItem)
02029         if self.animlist.count(anAnimItem) == 0:
02030           # deleted without being in any shot
02031           continue
02032       else:
02033 #
02034         modified = self.get_modified_parameters(anAnimItem)
02035 
02036 
02037       if len(modified) != 0:
02038         anAnimItem.frames_info[self.current_frame] = modified
02039 #
02040     self.current_frame = self.current_frame + 1
02041     self.frames_total =  self.current_frame
02042     self.z_reinit()
02043     self.item_frame_counter.set(text=self.current_frame + 1)
02044     # print self.current_frame + 1
02045     gtk.timeout_add(500, self.run_flash)
02046 
02047   def z_find_index(self, anAnimItem):
02048     def f(x): return x < anAnimItem.z
02049 
02050     return len(filter(f, self.list_z_last_shot))
02051 
02052 #    self.z_reinit()
02053 
02054 #  def anim2Run(self):
02055 
02056   def apply_frame(self, frame):
02057     for item in self.playlist:
02058       if not item.frames_info.has_key(frame):
02059         continue
02060       modif = item.frames_info[frame].copy()
02061       if modif.has_key('delete'):
02062         item.canvas_item.destroy()
02063         continue
02064       if modif.has_key('create'):
02065         del modif['create']
02066         z = modif['z']
02067         del modif['z']
02068         matrice = modif['matrice']
02069         del modif['matrice']
02070         if item.type == 'IMAGE':
02071           image =  modif['image_name']
02072           del modif['image_name']
02073           pixmap = gcompris.utils.load_pixmap(image)
02074           modif['pixbuf']= pixmap
02075         item.canvas_item = self.playing.add(self.types[item.type], **modif)
02076         delta = len(self.playing.item_list) - z -1
02077         if delta != 0:
02078           item.canvas_item.lower(delta)
02079         item.canvas_item.affine_absolute(matrice)
02080         continue
02081       else:
02082         if modif.has_key('z'):
02083           z = modif['z']
02084           del modif['z']
02085           index = self.playing.item_list.index(item.canvas_item)
02086           if index > z:
02087             item.canvas_item.lower(index - z)
02088           else:
02089             item.canvas_item.raise_(z - index)
02090         if  modif.has_key('matrice'):
02091           matrice = modif['matrice']
02092           del modif['matrice']
02093           item.canvas_item.affine_absolute(matrice)
02094         if len(modif) != 0:
02095           item.canvas_item.set(**modif)
02096 
02097   def run_anim2(self):
02098     if self.running:
02099       if self.current_frame==0:
02100         self.playing.destroy()
02101         self.playing = self.rootitem.add(
02102           gnomecanvas.CanvasGroup,
02103           x=0.0,
02104           y=0.0
02105           )
02106       self.apply_frame((self.current_frame)%(self.frames_total))
02107       self.current_frame=(self.current_frame+1)%(self.frames_total)
02108       self.item_frame_counter.set(text=self.current_frame + 1)
02109     else:
02110       self.playing.destroy()
02111       self.current_frame = self.frames_total
02112       self.item_frame_counter.set(text=self.current_frame + 1)
02113       self.root_anim.show()
02114       self.root_coloritem.show()
02115       self.root_toolitem.show()
02116       self.root_playingitem.hide()
02117       gcompris.bar_hide(False)
02118     return self.running
02119 
02120   def Anim2Run(self):
02121     gcompris.bar_hide(True)
02122     if self.frames_total==0:
02123       print "Mmm... Need to make shots before run anim !!"
02124       self.running=False
02125       return
02126     # Hide the current drawing
02127     self.root_anim.hide()
02128     self.playing = self.root_anim.add(
02129       gnomecanvas.CanvasGroup,
02130       x=0.0,
02131       y=0.0
02132       )
02133 
02134     self.playlist = []
02135     for aItem in self.animlist:
02136       playItem = self.AnimItem()
02137       playItem.frames_info = aItem.frames_info.copy()
02138       playItem.type = aItem.type
02139       self.playlist.append(playItem)
02140 
02141     # Show the first drawing
02142     self.apply_frame(0)
02143     self.current_frame = 0
02144 
02145     self.timeout=gobject.timeout_add(1000/self.anim_speed, self.run_anim2)
02146 
02147 
02148   def unselect(self):
02149     if not self.selected:
02150       return
02151     if ((gobject.type_name(self.selected.item_list[0])=="GnomeCanvasText")
02152         and
02153         (self.last_commit != None)):
02154       #suppress preedit
02155       self.selected.item_list[0].set(markup=self.last_commit)
02156       self.last_commit = None
02157       gcompris.im_reset()
02158     self.selected.item_list[1].hide()
02159     self.selected = None
02160 
02161 
02162 
02163 
02164 
02165 ###############################################
02166 #
02167 #             GLOBAL functions
02168 #
02169 ###############################################
02170 def general_save(filename, filetype):
02171   global fles
02172 
02173   fles.z_reinit()
02174 
02175   #print "general_save : ", filename, " type ",filetype
02176   if filetype == None:
02177     filetype = filename.split('.')[-1]
02178   if (filetype in ['image/svg+xml+javascript','image/svg+xml']):
02179     anim2_to_svg(filename)
02180     return
02181   if (filetype in ['image/gcompris+anim','image/gcompris+draw']):
02182     anim2_to_file(filename)
02183     return
02184   print "Error File selector return unknown filetype :",'|' + filetype + '|', "!!!"
02185 
02186 def general_restore(filename, filetype):
02187   #print "general_restore : ", filename, " type ",filetype
02188   if filetype == None:
02189     filetype = filename.split('.')[-1]
02190 
02191   # Determine the file format by reading the first line
02192   file = open(filename, 'r')
02193   line = file.read(24)
02194   file.close();
02195   filetype = ""
02196   if(line == "UGCompris draw 2 cPikle"
02197      or line == "UGCompris anim 2 cPikle"):
02198     filetype = 'image/gcompris+anim'
02199   elif(line == "<?xml version='1.0' enco"):
02200     filetype = 'image/svg+xml'
02201 
02202   #   print " Detected type ",filetype
02203 
02204   if (filetype in ['image/svg+xml+javascript','image/svg+xml']):
02205     global python_xml
02206     if python_xml:
02207       svg_to_anim2(filename)
02208     else:
02209       gcompris.utils.dialog(_('SVG is disabled. Install python xml module to enable it'),None)
02210     return
02211   if (filetype in ['image/gcompris+anim','image/gcompris+draw']):
02212     file_to_anim2(filename)
02213     return
02214   print "Error File selector return unknown filetype :",filetype, "!!!"
02215 
02216 
02217 def anim2_to_file(filename):
02218   global fles
02219 
02220   file =   open(filename, 'wb')
02221 
02222   # Save the descriptif frame:
02223   pickle.dump(fles.format_string['gcompris'],file,True)
02224 
02225   # save the total of frames
02226   pickle.dump(fles.frames_total, file, True)
02227 
02228   # save the list into
02229   list_to = []
02230 
02231   # get the list
02232   list_from = []
02233 
02234   if (fles.gcomprisBoard.mode == 'draw'):
02235     # in draw we need to get the list in z order, because of svg.
02236     def get_item_at(z):
02237       for item in eval('fles.' + fles.itemlist[fles.gcomprisBoard.mode]):
02238         if item.z == z: return item
02239     for z in fles.list_z_actual:
02240       list_from.append(get_item_at(z))
02241 
02242     # now each item needs to get it's frames_info updated
02243     for anAnimItem in list_from[:]:
02244       modified = fles.get_modified_parameters(anAnimItem)
02245       if len(modified) != 0:
02246         anAnimItem.frames_info[fles.current_frame] = modified
02247 
02248   else:
02249     list_from = fles.animlist
02250 
02251   for item in list_from:
02252     frames_info_copied = {}
02253     for t, d  in item.frames_info.iteritems():
02254       frames_info_copied[t] = d.copy();
02255     Sitem = [ item.type, frames_info_copied]
02256     list_frames = Sitem[1].keys()
02257     list_frames.sort()
02258     if ((Sitem[0] == 'TEXT') and (Sitem[1][list_frames[0]].has_key('anchor'))):
02259         Sitem[1][list_frames[0]]['text-anchor']='middle'
02260         del Sitem[1][list_frames[0]]['anchor']
02261     list_to.append(Sitem)
02262 
02263   pickle.dump(list_to, file, True)
02264   file.close()
02265 
02266 def file_to_anim2(filename):
02267   global fles
02268 
02269   file =   open(filename, 'rb')
02270   try:
02271     desc = pickle.load(file)
02272   except:
02273     file.close()
02274     print 'Cannot load ', filename , " as a GCompris animation"
02275     return
02276 
02277   if type(desc) == type('str'):
02278     # string
02279     if 'desc' != fles.format_string['gcompris']:
02280       if (desc == 'GCompris draw 2 cPikle file'
02281           or desc == 'GCompris anim 2 cPikle file'):
02282         fles.frames_total = pickle.load(file)
02283       else:
02284         print "ERROR: Unrecognized file format, file", filename, ' has description : ', desc
02285         file.close()
02286         return
02287     else:
02288       print "ERROR: Unrecognized file format (desc), file", filename, ' has description : ', desc
02289       file.close()
02290       return
02291 
02292   elif type(desc) == type(1):
02293     print filename, 'has no description. Are you sure it\'s', fles.format_string['gcompris'],'?'
02294     # int
02295     fles.frames_total = desc
02296 
02297   picklelist = pickle.load(file)
02298   file.close()
02299   list_restore(picklelist)
02300 
02301 def list_restore(picklelist):
02302   global fles
02303 
02304   def update_anchors(item):
02305     global fles
02306 
02307     data_list = { 'LINE' : ['parent', 'points'],
02308                   'IMAGE' : ['parent', 'x', 'y', 'width', 'height'],
02309                   'TEXT' : ['parent', 'x', 'y'],
02310                   'RECT': ['parent', 'x1', 'y1', 'x2', 'y2'],
02311                   'FILL_RECT': ['parent', 'x1', 'y1', 'x2', 'y2'],
02312                   'CIRCLE': ['parent', 'x1', 'y1', 'x2', 'y2'],
02313                   'FILL_CIRCLE': ['parent', 'x1', 'y1', 'x2', 'y2']
02314       }
02315 
02316     data = {}
02317     for prop in data_list[item.type]:
02318       data[prop]=item.canvas_item.get_property(prop)
02319 
02320     if item.type == 'LINE':
02321       param = data['parent'], data['points'][0], data['points'][1], data['points'][2], data['points'][3],
02322     elif item.type == 'TEXT':
02323       bounds = item.canvas_item.get_bounds()
02324       param = data['parent'], bounds[0],bounds[1],bounds[2],bounds[3]
02325     elif item.type == 'IMAGE':
02326       param = data['parent'], data['x'], data['y'], data['x']+data['width'], data['y']+data['height']
02327     else:
02328       param = data['parent'], data['x1'], data['y1'], data['x2'], data['y2']
02329 
02330 
02331     fles.object_set_size_and_pos(*param)
02332 
02333   # Historic strate
02334   #fles.current_image = 0
02335 
02336   fles.selected = None
02337 
02338   for item in fles.framelist:
02339     try:
02340       # can have been destroyed before by a delete action. No matter
02341       item.canvas_item.get_property("parent").destroy()
02342     except:
02343       pass
02344 
02345   fles.framelist = []
02346   fles.animlist=[]
02347 
02348   for Sitem in picklelist:
02349     AItem = fles.AnimItem()
02350     AItem.type = Sitem[0]
02351     AItem.frames_info = Sitem[1]
02352     fles.animlist.append(AItem)
02353 
02354   missing_images = []
02355   for fles.current_frame in range(fles.frames_total+1):
02356     for item in fles.animlist[:]:
02357       if fles.gcomprisBoard.mode == 'draw':
02358         item.z = fles.animlist.index(item)
02359       restore_item( item, fles.current_frame, missing_images)
02360 
02361   if missing_images:
02362     list_images = ''
02363     for im in missing_images:
02364       list_images = list_images + im + '\n'
02365       gcompris.utils.dialog(_('Warning: the following images cannot be accessed on your system.\n') +
02366                             list_images +
02367                             _('The corresponding items have been skipped.'),
02368                             None)
02369   fles.list_z_last_shot= []
02370   for item in fles.framelist:
02371     fles.list_z_last_shot.append(item.z)
02372     update_anchors(item)
02373   fles.list_z_last_shot.sort()
02374   fles.list_z_actual = fles.list_z_last_shot[:]
02375   fles.z_reinit()
02376   fles.current_frame = fles.frames_total
02377 
02378   fles.root_anim.show()
02379 
02380   # now each item needs to get it's frames_info cleared
02381   if fles.gcomprisBoard.mode != 'draw':
02382     fles.item_frame_counter.set(text=fles.current_frame + 1)
02383   else:
02384     for anAnimItem in fles.animlist[:]:
02385       anAnimItem.frames_info = {}
02386 
02387 def restore_item(item, frame, missing):
02388   global fles
02389   if not item.frames_info.has_key(frame):
02390     return
02391   modif = item.frames_info[frame].copy()
02392   if modif.has_key('delete'):
02393     item.canvas_item.get_property("parent").destroy()
02394     fles.framelist.remove(item)
02395     return False
02396   if (modif.has_key('create') or (fles.gcomprisBoard.mode == 'draw')):
02397 
02398     if modif.has_key('create'):
02399       del modif['create']
02400     if modif.has_key('z'):
02401       item.z = modif['z']
02402       del modif['z']
02403     if fles.gcomprisBoard.mode == 'draw':
02404       modif.update(fles.fixedattributs[item.type])
02405     matrice = modif['matrice']
02406     del modif['matrice']
02407     if ((item.type == 'TEXT') and (modif.has_key('text-anchor'))):
02408       del modif['text-anchor']
02409       del item.frames_info[frame]['text-anchor']
02410       item.frames_info[frame]['anchor']= gtk.ANCHOR_CENTER
02411       modif['anchor']= gtk.ANCHOR_CENTER
02412     if item.type == 'IMAGE':
02413       item.image_name =  modif['image_name']
02414 
02415       if (not os.access(gcompris.DATA_DIR + '/' + item.image_name, os.R_OK)
02416           and not os.access(item.image_name, os.R_OK)):
02417         missing.append(item.image_name)
02418         fles.animlist.remove(item)
02419         return False
02420       del modif['image_name']
02421       pixmap = gcompris.utils.load_pixmap(item.image_name)
02422       modif['pixbuf']= pixmap
02423     newitemgroup = fles.root_anim.add(
02424         gnomecanvas.CanvasGroup,
02425         x=0.0,
02426         y=0.0
02427         )
02428     item.canvas_item = newitemgroup.add(fles.types[item.type], **modif)
02429     item.canvas_item.set_data("AnimItem", item)
02430     fles.anchorize(newitemgroup)
02431     delta = len(fles.root_anim.item_list) - item.z -1
02432     if delta != 0:
02433       newitemgroup.lower(delta)
02434     newitemgroup.affine_absolute(matrice)
02435     fles.framelist.append(item)
02436     return True
02437   else:
02438     if modif.has_key('z'):
02439       item.z = modif['z']
02440       del modif['z']
02441       index = fles.root_anim.item_list.index(item.canvas_item.get_property("parent"))
02442       if index > item.z:
02443         item.canvas_item.get_property("parent").lower(index - item.z)
02444       else:
02445         item.canvas_item.get_property("parent").raise_(item.z - index)
02446     if  modif.has_key('matrice'):
02447       matrice = modif['matrice']
02448       del modif['matrice']
02449       item.canvas_item.get_property("parent").affine_absolute(matrice)
02450     if len(modif) != 0:
02451       # Bourrin: je supprime les ancres et je les remets apres les modifs
02452       # Pas envie de me faire ch*** a retraiter les resize et les move
02453       #item.canvas_item.get_property("parent").item_list[1].destroy()
02454       item.canvas_item.set(**modif)
02455       #fles.anchorize(item.canvas_item.get_property("parent"))
02456     return True
02457 
02458 ##############################################
02459 #
02460 #  SVG anim 2 export
02461 #
02462 ##############################################
02463 
02464 def anim2_to_svg(filename):
02465 
02466     processor_class = DOMProcess
02467 
02468     outfp = open(filename,'w')
02469 
02470     processor = processor_class(outfp)
02471     processor.run()
02472 
02473     outfp.close()
02474 
02475 
02476 class BaseProcess:
02477     """Base class for the conversion processors.  Each concrete subclass
02478     must provide the following methods:
02479 
02480     initOutput()
02481         Initialize the output stream and any internal data structures
02482         that the conversion process needs.
02483 
02484     addRecord(lname, fname, type)
02485         Add one record to the output stream (or the internal structures)
02486         where lname is the last name, fname is the first name, and type
02487         is either 'manager' or 'employee'.
02488 
02489     finishOutput()
02490         Finish all output generation.  If all work has been on internal
02491         data structures, this is where they should be converted to text
02492         and written out.
02493     """
02494     def __init__(self, outfp):
02495         """Store the input and output streams for later use."""
02496         self.types = { 'RECT' : 'rect',
02497                        'FILL_RECT' : 'rect',
02498                        'CIRCLE' : 'ellipse',
02499                        'FILL_CIRCLE' : 'ellipse',
02500                        'TEXT' : 'text',
02501                        'IMAGE' : 'use',
02502                        'LINE' : 'line'
02503                    }
02504 
02505         global fles
02506 
02507         self.outfp = outfp
02508         self.images_list = {}
02509 
02510         self.frames_total = fles.frames_total
02511 
02512 
02513         # save the list into
02514         self.list_to = []
02515 
02516         # get the list
02517         self.list_from = []
02518 
02519         if (fles.gcomprisBoard.mode == 'draw'):
02520           # in draw we need to get the list in z order, because of svg.
02521           def get_item_at(z):
02522             for item in eval('fles.' + fles.itemlist[fles.gcomprisBoard.mode]):
02523               if item.z == z: return item
02524           for z in fles.list_z_actual:
02525             self.list_from.append(get_item_at(z))
02526 
02527           # now each item needs to get it's frames_info updated
02528           for anAnimItem in self.list_from[:]:
02529             modified = fles.get_modified_parameters(anAnimItem)
02530             if len(modified) != 0:
02531               anAnimItem.frames_info[fles.current_frame] = modified
02532         else:
02533           self.list_from = fles.animlist
02534 
02535         for item in self.list_from:
02536           frames_info_copied = {}
02537           for t, d  in item.frames_info.iteritems():
02538             frames_info_copied[t] = d.copy();
02539           Sitem = [ item.type, frames_info_copied]
02540           list_frames = Sitem[1].keys()
02541           list_frames.sort()
02542 #          if ((Sitem[0] == 'TEXT') and (Sitem[1][list_frames[0]].has_key('anchor'))):
02543 #            Sitem[1][list_frames[0]]['text-anchor']='middle'
02544 #            del Sitem[1][list_frames[0]]['anchor']
02545           self.list_to.append(Sitem)
02546 
02547 
02548     def get_last_rectel_bounds(self, item, frame_no):
02549         listkeys = item[1].keys()
02550         listkeys.sort()
02551 
02552 
02553         def f(x): return x < frame_no
02554 
02555         #print "rectel last", item, frame_no, filter(f,listkeys)
02556 
02557         for frame in filter(f,listkeys):
02558           if item[1][frame].has_key('x1'):
02559              x1 = item[1][frame]['x1']
02560           if item[1][frame].has_key('x2'):
02561              x2 = item[1][frame]['x2']
02562           if item[1][frame].has_key('y1'):
02563              y1 = item[1][frame]['y1']
02564           if item[1][frame].has_key('y2'):
02565              y2 = item[1][frame]['y2']
02566 
02567         return (x1,y1,x2,y2)
02568 
02569     def get_last_line_points(self, item, frame_no):
02570         listkeys = item[1].keys()
02571         listkeys.sort()
02572 
02573         def f(x): return x < frame_no
02574 
02575         for frame in filter(f,listkeys):
02576             if  item[1][frame].has_key('points'):
02577                 points = item[1][frame]['points']
02578         return points
02579 
02580     def rgb_write(self, rgba):
02581         red = int ( ( rgba >> 24 ) & 255 )
02582         green = int ( ( rgba >> 16 ) & 255 )
02583         blue = int ( ( rgba >> 8 ) & 255 )
02584         return 'rgb(' + str(red) +',' + str(green) + ',' + str(blue) + ')'
02585 
02586     def run(self):
02587         """Perform the complete conversion process.
02588 
02589         This method is responsible for parsing the input and calling the
02590         subclass-provided methods in the right order.
02591         """
02592         self.initOutput()
02593 
02594         global fles
02595 
02596         for item in self.list_to:
02597           self.element = self.document.createElement(self.types[item[0]])
02598           self.svg.appendChild(self.element)
02599           listkeys = item[1].keys()
02600           listkeys.sort()
02601           for frame_no in listkeys:
02602             # if draw there is only one key.
02603             # in this case parameters are put in self.element
02604             # and not in self.frame
02605 
02606             if fles.gcomprisBoard.mode == 'draw':
02607               self.frame = self.element
02608             else:
02609              self.frame = self.document.createElement("gcompris:frame")
02610              self.frame.setAttribute('time',str(frame_no))
02611              self.element.appendChild(self.frame)
02612 
02613             for attr in item[1][frame_no].keys():
02614               if (self.types[item[0]] == 'rect'):
02615 
02616                 if (item[0] == 'RECT') and item[1][frame_no].has_key('create'):
02617                   self.frame.setAttribute('fill', 'none')
02618                 if (attr == 'x2'):
02619                   if item[1][frame_no].has_key('x1'):
02620                     self.frame.setAttribute('width', str(item[1][frame_no]['x2']-item[1][frame_no]['x1']))
02621                   else:
02622                          points = self.get_last_rectel_bounds(item, frame_no)
02623                     self.frame.setAttribute('width', str(item[1][frame_no]['x2']- points[0]))
02624                   continue
02625                 if (attr == 'y2'):
02626                   if item[1][frame_no].has_key('y1'):
02627                     self.frame.setAttribute('height', str(item[1][frame_no]['y2']-item[1][frame_no]['y1']))
02628                   else:
02629                          points = self.get_last_rectel_bounds(item, frame_no)
02630                     self.frame.setAttribute('height', str(item[1][frame_no]['y2']- points[1]))
02631                   continue
02632                 if (attr == 'x1'):
02633                   self.frame.setAttribute('x', str(item[1][frame_no]['x1']))
02634                   if not item[1][frame_no].has_key('x2'):
02635                     points = self.get_last_rectel_bounds(item, frame_no)
02636                     self.frame.setAttribute('width', str( - item[1][frame_no]['x1'] + points[2]))
02637                   continue
02638                 if (attr == 'y1'):
02639                   self.frame.setAttribute('y', str(item[1][frame_no]['y1']))
02640                   if not item[1][frame_no].has_key('y2'):
02641                     points = self.get_last_rectel_bounds(item, frame_no)
02642                     self.frame.setAttribute('width', str( - item[1][frame_no]['y1']+ points[3]))
02643                   continue
02644                 if (attr == 'fill_color_rgba'):
02645                   self.frame.setAttribute(
02646                       'fill',
02647                       self.rgb_write(item[1][frame_no]['fill_color_rgba']))
02648                   continue
02649                 if (attr == 'outline_color_rgba'):
02650                   self.frame.setAttribute(
02651                       'stroke',
02652                       self.rgb_write(item[1][frame_no]['outline_color_rgba']))
02653                   continue
02654                 if (attr == 'width-units'):
02655                   self.frame.setAttribute(
02656                       'stroke-width',
02657                       str(item[1][frame_no]['width-units']))
02658                   continue
02659 
02660               if (self.types[item[0]] == 'ellipse'):
02661                 if (attr == 'width-units'):
02662                   self.frame.setAttribute(
02663                       'stroke-width',
02664                       str(item[1][frame_no]['width-units']))
02665                   continue
02666 
02667                 if (attr == 'outline_color_rgba'):
02668                   self.frame.setAttribute(
02669                       'stroke',
02670                       self.rgb_write(item[1][frame_no]['outline_color_rgba']))
02671                   continue
02672                 if (item[0] == 'CIRCLE') and item[1][frame_no].has_key('create'):
02673                   self.frame.setAttribute('fill', 'none')
02674 
02675                 if (attr == 'fill_color_rgba'):
02676                   self.frame.setAttribute(
02677                       'fill',
02678                       self.rgb_write(item[1][frame_no]['fill_color_rgba']))
02679                   continue
02680 
02681                 if (attr == 'x2'):
02682                   if item[1][frame_no].has_key('x1'):
02683                     cx = (item[1][frame_no]['x2']+item[1][frame_no]['x1'])/2
02684                   else:
02685                          points = self.get_last_rectel_bounds(item, frame_no)
02686                     cx = (item[1][frame_no]['x2']+ points[0])/2
02687                   rx = item[1][frame_no]['x2']-cx
02688                   self.frame.setAttribute('cx',str(cx))
02689                   self.frame.setAttribute('rx',str(rx))
02690                   continue
02691                 if (attr == 'x1'):
02692                   if item[1][frame_no].has_key('x2'):
02693                     continue
02694                   else:
02695                          points = self.get_last_rectel_bounds(item, frame_no)
02696                     cx = (item[1][frame_no]['x1']+ points[2])/2
02697                     rx = cx - item[1][frame_no]['x1']
02698                     self.frame.setAttribute('cx',str(cx))
02699                     self.frame.setAttribute('rx',str(rx))
02700                   continue
02701 
02702                 if (attr == 'y2'):
02703                   if item[1][frame_no].has_key('y1'):
02704                     cy = (item[1][frame_no]['y2']+item[1][frame_no]['y1'])/2
02705                   else:
02706                          points = self.get_last_rectel_bounds(item, frame_no)
02707                     cy = (item[1][frame_no]['y2']+ points[1])/2
02708                   ry = item[1][frame_no]['y2']-cy
02709                   self.frame.setAttribute('cy',str(cy))
02710                   self.frame.setAttribute('ry',str(ry))
02711                   continue
02712                 if (attr == 'y1'):
02713                   if item[1][frame_no].has_key('y2'):
02714                     continue
02715                   else:
02716                          points = self.get_last_rectel_bounds(item, frame_no)
02717                     cy = (item[1][frame_no]['y1']+ points[3])/2
02718                     ry = cy - item[1][frame_no]['y1']
02719                     self.frame.setAttribute('cy',str(cy))
02720                     self.frame.setAttribute('ry',str(ry))
02721                   continue
02722 
02723               if (self.types[item[0]] == 'line'):
02724                 if (attr == 'fill_color_rgba'):
02725                   self.frame.setAttribute(
02726                       'stroke',
02727                       self.rgb_write(item[1][frame_no]['fill_color_rgba']))
02728                   continue
02729                 if (attr == 'width-units'):
02730                   self.frame.setAttribute(
02731                       'stroke-width',
02732                       str(item[1][frame_no]['width-units']))
02733                   continue
02734                 if (attr == 'points'):
02735                     if item[1][frame_no].has_key('create'):
02736                         self.frame.setAttribute('x1', str(item[1][frame_no]['points'][0]))
02737                         self.frame.setAttribute('y1', str(item[1][frame_no]['points'][1]))
02738                         self.frame.setAttribute('x2', str(item[1][frame_no]['points'][2]))
02739                         self.frame.setAttribute('y2', str(item[1][frame_no]['points'][3]))
02740                     else:
02741                         last_points = self.get_last_line_points(item, frame_no)
02742                         points = item[1][frame_no]['points']
02743 
02744                         if points[0] != last_points[0]:
02745                             self.frame.setAttribute('x1', str(points[0]))
02746                         if points[1] != last_points[1]:
02747                             self.frame.setAttribute('y1', str(points[1]))
02748                         if points[2] != last_points[2]:
02749                             self.frame.setAttribute('x2', str(points[2]))
02750                         if points[3] != last_points[3]:
02751                             self.frame.setAttribute('y2',str( points[3]))
02752                     continue
02753 
02754               if (self.types[item[0]] == 'text'):
02755                 if (attr == 'fill_color_rgba'):
02756                   self.frame.setAttribute(
02757                       'fill',
02758                       self.rgb_write(item[1][frame_no]['fill_color_rgba']))
02759                   continue
02760                 if (attr == 'anchor'):
02761                     self.frame.setAttribute(
02762                         'text-anchor',
02763                         'middle')
02764                     continue
02765 #                if (attr == 'text'):
02766 #                  self.frame.appendChild(self.document.createTextNode(item[1][frame_no]['text'].encode('UTF-8')))
02767 #                  continue
02768 
02769               if ( attr == 'font' ):
02770                   font = item[1][frame_no]['font']
02771                   list = font.split()
02772 
02773                   self.frame.setAttribute(
02774                       'font-size',list[-1] + 'pt')
02775                   self.frame.setAttribute(
02776                       'font-family',list[0] + ' ' + list[1])
02777 
02778 
02779               if (item[0] == 'IMAGE'):
02780                 if (attr == 'image_name'):
02781                   image_name=item[1][frame_no]['image_name']
02782                   list_image_name = image_name.split('/')
02783                   if self.images_list.has_key(image_name):
02784                     self.element.setAttribute(
02785                         'xlink:href',self.images_list[image_name])
02786                   else:
02787                     self.symbol = self.document.createElement('symbol')
02788                     self.defel.appendChild(self.symbol)
02789                     self.image = self.document.createElement('image')
02790                     self.symbol.appendChild(self.image)
02791                     self.symbol.setAttribute(
02792                         'id', 'image' + str(len(self.images_list)))
02793                     self.element.setAttribute(
02794                         'xlink:href', '#image' + str(len(self.images_list)))
02795                     self.images_list[image_name]= 'image' + str(len(self.images_list))
02796                     # Base64 included image, to get all in one file
02797                     #
02798                     # that's dirty, but i want something simple for kids
02799                     #
02800                     # anyway image can be used multiple time,
02801                     # it will be included only once
02802                     #
02803                     # Maybe put file and image in same directory ?
02804                     #
02805                     imagefile = open(gcompris.DATA_DIR + '/' + image_name)
02806                     base64string = base64.encodestring(imagefile.read())
02807                     self.image.setAttribute(
02808                         'xlink:href','data:image/png;base64,' + base64string)
02809 
02810                     # get real size of the image.
02811                     pixmap = gcompris.utils.load_pixmap(image_name)
02812                     width = pixmap.get_width()
02813                     height = pixmap.get_height()
02814 
02815                     # Pass the <symbol> with image included.
02816                     self.image.setAttribute(
02817                         'x','0')
02818                     self.image.setAttribute(
02819                         'y','0')
02820                     self.image.setAttribute(
02821                         'width', str(width))
02822                     self.image.setAttribute(
02823                         'height',str(height))
02824                     self.symbol.setAttribute(
02825                         'viewBox','0 0 '+ str(width) + ' ' + str(height))
02826                     self.symbol.setAttribute(
02827                         'preserveAspectRatio','none')
02828                     self.gcompris_name = self.document.createElement('gcompris:image_name')
02829                     # Pass the image_name info in private child
02830                     self.image.appendChild(self.gcompris_name)
02831                     self.gcompris_name.setAttribute('value',image_name)
02832                   continue
02833 
02834                 if ((attr == 'height_set') or  (attr == 'width_set')):
02835                   continue
02836 
02837               if (attr == 'matrice'):
02838                   self.frame.setAttribute(
02839                       'transform',
02840                       'matrix' + str(item[1][frame_no]['matrice']))
02841                   continue
02842 
02843               if fles.gcomprisBoard.mode == 'draw':
02844                 if (attr != 'create'):
02845                   self.frame.setAttribute(attr,str(item[1][frame_no][attr]))
02846               else:
02847                 self.frame.setAttribute(attr,str(item[1][frame_no][attr]))
02848         self.finishOutput()
02849 
02850 
02851 class DOMProcess(BaseProcess):
02852     """Concrete conversion process which uses a DOM structure as an
02853     internal data structure.
02854 
02855     Content is added to the DOM tree for each input record, and the
02856     entire tree is serialized and written to the output stream in the
02857     finishOutput() method.
02858     """
02859     def initOutput(self):
02860         global fles
02861         # Create a new document with no namespace uri, qualified name,
02862         # or document type
02863         self.document = implementation.createDocument(None,None,None)
02864         self.svg = self.document.createElement("svg")
02865         self.svg.setAttribute("id","svgroot")
02866         self.svg.setAttribute("width","800")
02867         self.svg.setAttribute("height","550")
02868         self.svg.setAttribute("version","1.1")
02869         self.svg.setAttribute("xmlns","http://www.w3.org/2000/svg")
02870         self.svg.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink")
02871         self.svg.setAttribute("xmlns:html","http://www.w3.org/1999/xhtml")
02872         self.svg.setAttribute("xmlns:gcompris","http://www.ofset.org/gcompris")
02873         self.svg.setAttribute("onload","init();")
02874         self.document.appendChild(self.svg)
02875 
02876         self.metadata = self.document.createElement("metadata")
02877         self.svg.appendChild(self.metadata)
02878         self.gc_desc = self.document.createElement("gcompris:description")
02879         self.metadata.appendChild(self.gc_desc)
02880         self.gc_desc.setAttribute('value',fles.format_string['svg'])
02881 
02882         if fles.gcomprisBoard.mode != 'draw':
02883           self.script = self.document.createElement("script")
02884           self.svg.appendChild(self.script)
02885           self.gcompris_frames_total = self.document.createElement("gcompris:frames_total")
02886           self.svg.appendChild(self.gcompris_frames_total)
02887           self.gcompris_frames_total.setAttribute("value",str(self.frames_total))
02888           scriptfile = open(gcompris.DATA_DIR + "/anim/animation.js")
02889           t = self.document.createCDATASection(scriptfile.read())
02890           self.script.appendChild(t)
02891 
02892         self.defel = self.document.createElement("defs")
02893         self.svg.appendChild(self.defel)
02894 
02895         if fles.gcomprisBoard.mode != 'draw':
02896           # html buttons included
02897           self.foreign = self.document.createElement("foreignObject")
02898           self.svg.appendChild(self.foreign)
02899           self.foreign.setAttribute("x","300")
02900           self.foreign.setAttribute("y","520")
02901           self.foreign.setAttribute("width","800")
02902           self.foreign.setAttribute("height","30")
02903           self.foreign.setAttribute("requiredExtensions","http://www.mozilla.org/SVGExtensions/EmbeddedXHTML")
02904           self.button1 = self.document.createElement("html:button")
02905           self.foreign.appendChild(self.button1)
02906           self.button1.setAttribute("onclick", "start_animation();")
02907           self.button1text = self.document.createTextNode(u'>'.encode('UTF-8'))
02908           self.button1.appendChild(self.button1text)
02909 
02910           self.button2 = self.document.createElement("html:button")
02911           self.foreign.appendChild(self.button2)
02912           self.button2.setAttribute("onclick", "speed_down();")
02913           self.button2text = self.document.createTextNode(u'<<'.encode('UTF-8'))
02914           self.button2.appendChild(self.button2text)
02915 
02916           self.speedtext = self.document.createElement("html:input")
02917           self.foreign.appendChild(self.speedtext)
02918           self.speedtext.setAttribute("id","speed_text")
02919           self.speedtext.setAttribute("type","TEXT")
02920           self.speedtext.setAttribute("size","6")
02921           self.speedtext.setAttribute("maxlength","6")
02922           self.speedtext.setAttribute("value","4 fps")
02923 
02924           self.ratetext = self.document.createElement("html:input")
02925           self.foreign.appendChild(self.ratetext)
02926           self.ratetext.setAttribute("id","rate_text")
02927           self.ratetext.setAttribute("type","TEXT")
02928           self.ratetext.setAttribute("size","6")
02929           self.ratetext.setAttribute("maxlength","6")
02930           self.ratetext.setAttribute("value","")
02931 
02932           self.button3 = self.document.createElement("html:button")
02933           self.foreign.appendChild(self.button3)
02934           self.button3.setAttribute("onclick", "speed_up();")
02935           self.button3text = self.document.createTextNode(u'>>'.encode('UTF-8'))
02936           self.button3.appendChild(self.button3text)
02937 
02938           self.button4 = self.document.createElement("html:button")
02939           self.foreign.appendChild(self.button4)
02940           self.button4.setAttribute("onclick", "stop_animation();")
02941           self.button4text = self.document.createTextNode(u'||'.encode('UTF-8'))
02942           self.button4.appendChild(self.button4text)
02943 
02944 
02945     def finishOutput(self):
02946 #        t = self.document.createTextNode("\n")
02947 #        self.svg.appendChild(t)
02948         # XXX toxml not supported by 4DOM
02949         # self.outfp.write(self.document.toxml())
02950         xml.dom.ext.PrettyPrint(self.document, self.outfp)
02951         self.outfp.write("\n")
02952 
02953         # now each item needs to get it's frames_info cleared
02954         global fles
02955         if fles.gcomprisBoard.mode == 'draw':
02956           for anAnimItem in self.list_from[:]:
02957             del anAnimItem.frames_info[fles.current_frame]
02958 
02959 
02960 
02961 
02962 
02963 
02964 ##############################################
02965 #
02966 #  SVG anim 2 import
02967 #
02968 ##############################################
02969 
02970 
02971 #try:
02972 #    import xml.parsers.expat
02973 #except ImportError:
02974 #    import pyexpat
02975 
02976 #from xml.parsers import expat
02977 
02978 def svg_to_anim2(filename):
02979     """Process command line parameters and run the conversion."""
02980 
02981     infp = open(filename)
02982     global fles
02983 
02984     fles.filename = filename
02985     out = Outputter()
02986     parser = expat.ParserCreate()
02987 
02988     HANDLER_NAMES = [
02989         'StartElementHandler', 'EndElementHandler',
02990         'CharacterDataHandler', 'ProcessingInstructionHandler',
02991         'UnparsedEntityDeclHandler', 'NotationDeclHandler',
02992         'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
02993         'CommentHandler', 'StartCdataSectionHandler',
02994         'EndCdataSectionHandler',
02995         'DefaultHandler', 'DefaultHandlerExpand',
02996         #'NotStandaloneHandler',
02997         'ExternalEntityRefHandler', 'SkippedEntityHandler',
02998         ]
02999     parser.returns_unicode = 1
03000 
03001     for name in HANDLER_NAMES:
03002         setattr(parser, name, getattr(out, name))
03003 
03004     try:
03005         parser.ParseFile(infp)
03006     except expat.error:
03007         print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
03008         print '** Line', parser.ErrorLineNumber
03009         print '** Column', parser.ErrorColumnNumber
03010         print '** Byte', parser.ErrorByteIndex
03011 
03012 
03013     infp.close()
03014     return
03015 
03016 class Outputter:
03017     global fles
03018 
03019     def __init__(self):
03020        self.fixedattributs = fles.fixedattributs
03021 
03022        # used to check the element coming is the right one
03023        self.wait_element_list = ['svg']
03024 
03025        # keep where we are in the tree
03026        self.in_element = []
03027 
03028        # elements constituting the draws.
03029        self.svg_element = ['use', 'rect', 'ellipse', 'line', 'text']
03030 
03031        # dict with id : image_name pairs
03032        self.images = {}
03033 
03034        # Format of output in the gcompris anim2 pickle format,
03035        # close to the anim2 internal format
03036        self.picklelist = []
03037 
03038        # Item we are looking in. In fact we keep here the item we actually read the frames information.
03039        self.item_getting = None
03040 
03041        # id of image we are looking in
03042        self.image_getting = None
03043 
03044        # used to skip elements we are not interested in (foreignObject, script)
03045        self.wait_end_of = None
03046 
03047 
03048     def StartElementHandler(self, name, attrs):
03049         global fles
03050         def get_attrs(attrs):
03051           global fles
03052 
03053           def rgb(r,g,b):
03054              return (r<<24L) + (g<<16) + (b<<8) + 255
03055 
03056           def matrix(a, b, c, d, e, f):
03057             return (a , b, c, d, e, f)
03058 
03059           frame_info = {}
03060 
03061           keys = attrs.keys()
03062           for k in keys:
03063              if (k == 'create'):
03064                if (self.item_getting[0] == 'IMAGE'):
03065                  frame_info['image_name'] = self.image_getting
03066                if ('fill' in keys):
03067                  if (attrs['fill']=='none'):
03068                    if (self.item_getting[0] == 'FILL_RECT'):
03069                      self.item_getting[0] = 'RECT'
03070                    if (self.item_getting[0] == 'FILL_CIRCLE'):
03071                      self.item_getting[0] = 'CIRCLE'
03072                frame_info.update(self.fixedattributs[self.item_getting[0]])
03073              if (k == 'transform'):
03074                  frame_info['matrice'] =  eval(attrs[k])
03075                  continue
03076              if (k == 'stroke'):
03077                # used in CIRCLE LINE and RECT
03078                if (self.item_getting[0] in ['CIRCLE','RECT','LINE','FILL_RECT','FILL_CIRCLE']):
03079                  # CIRCLE RECT -> outline_color_rgba
03080                  # LINE -> fill_color_rgba
03081                  if (self.item_getting[0] == 'LINE'):
03082                    frame_info['fill_color_rgba'] = eval(attrs[k])
03083                  else:
03084                    frame_info['outline_color_rgba'] = eval(attrs[k])
03085                  continue
03086              if (k == 'fill'):
03087                #used in FILL_CIRCLE and FILL_RECT
03088                if (self.item_getting[0] in ['FILL_CIRCLE','FILL_RECT','TEXT']):
03089                  frame_info['fill_color_rgba'] = eval(attrs[k])
03090                continue
03091              if (k in ['stroke-width', 'font-size', 'font-family', 'font', 'text-anchor']):
03092                continue
03093              if (k in ['x1', 'y1', 'x2', 'y2','x','y','width','height', 'cx', 'cy', 'rx', 'ry']):
03094                self.points[k] =  eval(attrs[k])
03095                continue
03096 
03097              if (k == 'text'):
03098                 frame_info['text']=attrs[k]
03099                 continue
03100              if (k == 'xlink:href'):
03101                # in draw, this is in attrs becaus the frame is directly in element.
03102                frame_info['image_name'] = self.image_getting
03103                continue
03104 
03105              if (not (k in ['x1', 'y1', 'x2', 'y2','x','y','width','height', 'cx', 'cy', 'rx', 'ry'])):
03106                #print u'Attribut non trait\xe9 :', self.item_getting[0], " ", k, "=", attrs[k]
03107                frame_info[k] = eval(attrs[k])
03108 
03109           if (self.points != {}):
03110             if (self.item_getting[0] == 'LINE'):
03111               for coord in ['x1', 'y1', 'x2', 'y2']:
03112                 if (not self.points.has_key(coord)):
03113                   self.points[coord] = self.last_points[coord]
03114               frame_info['points'] = ( self.points['x1'],
03115                                          self.points['y1'],
03116                                          self.points['x2'],
03117                                          self.points['y2'])
03118               self.last_points.update(self.points)
03119               self.points = {}
03120 
03121             if (self.item_getting[0] == 'IMAGE'):
03122               for j in self.points.keys():
03123                   frame_info[j] = self.points[j]
03124               self.points = {}
03125 
03126             if (self.item_getting[0] in ['RECT', 'FILL_RECT']):
03127               dist = { 'x' : 'width', 'y': 'height'}
03128               for c in ['x', 'y']:
03129                 if (self.points.has_key(c)):
03130                   b1 = self.points[c]
03131                   if (self.points.has_key(dist[c])):
03132                     # x and w changed
03133                     b2 = b1 + self.points[dist[c]]
03134                   else:
03135                     # x changed but not w
03136                     b2 = b1 + self.last_points[c + '2'] - self.last_points[c + 1]
03137                 else:
03138                   b1 = self.last_points[c + '1']
03139 
03140                   if (self.points.has_key(dist[c])):
03141                     # x not changed but w
03142                     b2 = b1 + self.points[dist[c]]
03143                   else:
03144                     # x and w not changed. normally never here
03145                     b2 = self.last_points[c + '2']
03146 
03147                 if (b1 != self.last_points[c+'1']):
03148                   frame_info[c+'1'] = b1
03149                   self.last_points[c+'1'] = b1
03150                 if (b2 != self.last_points[c+'2']):
03151                   frame_info[c+'2'] = b2
03152                   self.last_points[c+'2'] = b2
03153 
03154             if (self.item_getting[0] in ['CIRCLE', 'FILL_CIRCLE']):
03155               dist = { 'x' : 'rx', 'y': 'ry'}
03156               for c in ['x', 'y']:
03157                 if (self.points.has_key('c' + c)):
03158                   if (self.points.has_key(dist[c])):
03159                     # c and r change
03160                     b1 = self.points['c' + c] - self.points[dist[c]]
03161                     b2 = self.points['c' + c] + self.points[dist[c]]
03162                   else:
03163                     # c changed but not r
03164                     b1 = self.points['c' + c] - (self.last_points[c +'2'] - self.last_points[c +'1'])/2
03165                     b2 = self.points['c' + c] + (self.last_points[c +'2'] - self.last_points[c +'1'])/2
03166                 else:
03167                   if (self.points.has_key(dist[c])):
03168                     # c not changed , r changed
03169                     b1 = (self.last_points[c + '1'] + self.last_points[c + '2'])/2 - self.points[dist[c]]
03170                     b2 = b1 + 2 * self.points[dist[c]]
03171                   else:
03172                     # c and r not changed
03173                     b1 = self.last_points[c + '1']
03174                     b2 = self.last_points[c + '2']
03175 
03176                 if (b1 != self.last_points[c+'1']):
03177                   frame_info[c+'1'] = b1
03178                   self.last_points[c+'1'] = b1
03179                 if (b2 != self.last_points[c+'2']):
03180                   frame_info[c+'2'] = b2
03181                   self.last_points[c+'2'] = b2
03182 
03183             if (self.item_getting[0] in ['TEXT']):
03184               for c in ['x', 'y']:
03185                 if (self.points[c] != self.last_points[c+'1']):
03186                   frame_info[c] = self.points[c]
03187                   self.last_points[c+'1'] = self.points[c]
03188 
03189           return frame_info
03190 
03191         if self.wait_end_of != None:
03192            # ignore all childs of that element .
03193            return
03194 
03195         if not (name in self.wait_element_list):
03196            #print "Error : wait ", self.wait_element_list, " get ", name
03197            return
03198         self.in_element.append(name)
03199         if (name == 'svg'):
03200           if (fles.gcomprisBoard.mode == 'draw'):
03201             self.wait_element_list = [ 'defs', 'metadata' ]
03202           else:
03203             self.wait_element_list = [ 'script', 'metadata' ]
03204           return
03205         if (name == 'metadata'):
03206            self.wait_element_list = ['gcompris:description']
03207            return
03208         if (name == 'gcompris:description'):
03209            desc = attrs['value']
03210            return
03211         if (name == 'script'):
03212            self.wait_end_of = name
03213            return
03214         if (name == 'foreignObject'):
03215            self.wait_end_of = name
03216            return
03217         if (name == 'gcompris:frames_total'):
03218            fles.frames_total = eval(attrs['value'])
03219            return
03220         if (name == 'defs'):
03221            self.wait_element_list = ['symbol']
03222            return
03223         if (name == 'symbol'):
03224            # just get the id.
03225            self.wait_element_list = ['image']
03226            self.image_getting = attrs['id']
03227         if (name == 'image'):
03228            #the only interresting thing is the name in gcompris tree of this image. This the child element <gcompris:image_name /> value attribut.
03229            self.wait_element_list = ['gcompris:image_name']
03230            return
03231         if (name == 'gcompris:image_name'):
03232            #the only interresting thing is the name in gcompris tree of this image. This the child element <gcompris:image_name /> value attribut.
03233            image_id = attrs['value']
03234            self.images['#' + self.image_getting] =  image_id
03235            return
03236         if (name in self.svg_element):
03237            self.wait_element_list = ['gcompris:frame']
03238            # used to check modification in x, y, w, h positions
03239            self.points = {}
03240            self.last_points = { 'x1' : None,
03241                                 'y1' : None,
03242                                 'x2' : None,
03243                                 'y2' : None
03244                                 }
03245 
03246            if (name == 'use'):
03247              self.item_getting = ['IMAGE',{}]
03248              # We will put image_name when we meet 'create' attr, in frame_info spec. For that we need to keep the name of that image.
03249              self.image_getting = self.images[attrs['xlink:href']]
03250            if (name == 'text'):
03251              self.item_getting = ['TEXT',{}]
03252            if (name == 'line'):
03253              self.item_getting = ['LINE',{}]
03254            if (name == 'rect'):
03255              # Warning ! Will be changed in RECT
03256              # if fill='none' found with create attr.
03257              self.item_getting = ['FILL_RECT',{}]
03258            if (name == 'ellipse'):
03259              # Warning ! Will be changed in CIRCLE
03260              # if fill='none'  found with create attr.
03261              self.item_getting = ['FILL_CIRCLE',{}]
03262 
03263            if (fles.gcomprisBoard.mode == 'draw'):
03264              self.item_getting[1][0] = get_attrs(attrs)
03265 
03266         if (name == 'gcompris:frame'):
03267           self.item_getting[1][eval(attrs['time'])] = {}
03268           frame_info = self.item_getting[1][eval(attrs['time'])]
03269           del attrs['time']
03270 
03271           frame_info.update(get_attrs(attrs))
03272 
03273     def EndElementHandler(self, name):
03274         if (self.wait_end_of != None):
03275           if (name == self.wait_end_of):
03276             self.wait_end_of = None
03277           else: return
03278 
03279         if (name != self.in_element[-1]):
03280           # Let this print it can handle error
03281           print "Error close ", name, " but ", self.in_element[-1], " waited."
03282           return
03283         self.in_element.pop()
03284 
03285         if (name == 'svg'):
03286             list_restore(self.picklelist)
03287             return
03288         if (name == 'metadata'):
03289           if (fles.gcomprisBoard.mode == 'draw'):
03290             self.wait_element_list = [ 'defs' ]
03291           else:
03292             self.wait_element_list = [ 'script' ]
03293           return
03294         if (name == 'script'):
03295             self.wait_element_list = [ 'gcompris:frames_total' ]
03296             return
03297         if (name == 'gcompris:frames_total'):
03298             self.wait_element_list = ['defs']
03299             return
03300         if (name == 'symbol'):
03301             self.wait_element_list = ['symbol']
03302             return
03303         if (name == 'defs'):
03304           if (fles.gcomprisBoard.mode == 'draw'):
03305             self.wait_element_list = self.svg_element
03306           else:
03307             self.wait_element_list = ['foreignObject']
03308             return
03309         if (name == 'foreignObject'):
03310             self.wait_element_list = self.svg_element
03311             return
03312         if (name in self.svg_element):
03313             self.wait_element_list = self.svg_element
03314             self.picklelist.append([self.item_getting[0],self.item_getting[1].copy()])
03315             self.item_getting = None
03316             return
03317 
03318     def CharacterDataHandler(self, data):
03319       pass
03320 
03321     def ProcessingInstructionHandler(self, target, data):
03322       pass
03323 
03324     def StartNamespaceDeclHandler(self, prefix, uri):
03325       pass
03326 
03327     def EndNamespaceDeclHandler(self, prefix):
03328       pass
03329 
03330     def StartCdataSectionHandler(self):
03331       pass
03332 
03333     def EndCdataSectionHandler(self):
03334       pass
03335 
03336     def CommentHandler(self, text):
03337       pass
03338 
03339     def NotationDeclHandler(self, *args):
03340       pass
03341 
03342     def UnparsedEntityDeclHandler(self, *args):
03343       pass
03344 
03345     def NotStandaloneHandler(self, userData):
03346       return 1
03347 
03348     def ExternalEntityRefHandler(self, *args):
03349       return 1
03350 
03351     def SkippedEntityHandler(self, *args):
03352       pass
03353 
03354     def DefaultHandler(self, userData):
03355       pass
03356 
03357     def DefaultHandlerExpand(self, userData):
03358       pass
03359 
03360 
03361 
03362 def image_selected(image):
03363   #fles is used because self is not passed through callback
03364   global fles
03365 
03366   pixmap = gcompris.utils.load_pixmap(image)
03367 
03368   fles.newitem = None
03369   fles.newitemgroup = fles.root_anim.add(
03370     gnomecanvas.CanvasGroup,
03371     x=0.0,
03372     y=0.0
03373     )
03374 
03375   x= fles.pos_x
03376   y= fles.pos_y
03377   width  = pixmap.get_width()
03378   height = pixmap.get_height()
03379 
03380   fles.newitem = fles.newitemgroup.add(
03381     gnomecanvas.CanvasPixbuf,
03382     pixbuf = pixmap,
03383     x=x,
03384     y=y,
03385     width=width,
03386     height=height,
03387     width_set = True,
03388     height_set = True
03389     )
03390 
03391   # Tell svg_save the filename
03392   # Write "filename=image" in the property of newitem
03393   # Can't do it here because in C python string are unreadable
03394   # gcompris.utils.canvas_set_property(fles.newitem, "filename", image)
03395 
03396   anAnimItem = fles.AnimItem()
03397   anAnimItem.z = fles.new_z()
03398   anAnimItem.canvas_item = fles.newitem
03399   anAnimItem.canvas_item.set_data("AnimItem", anAnimItem)
03400   anAnimItem.type = 'IMAGE'
03401   anAnimItem.image_name = image
03402   fles.framelist.append(anAnimItem)
03403   fles.list_z_actual.append(anAnimItem.z)
03404 
03405   fles.anchorize(fles.newitemgroup)
03406   fles.object_set_size_and_pos(fles.newitemgroup, x, y, x+width, y+height)
03407   fles.select_item(fles.newitemgroup)
03408 
03409   fles.newitem = None
03410   fles.newitemgroup = None
03411