Back to index

gcompris  8.2.2
redraw.py
Go to the documentation of this file.
00001 #  gcompris - redraw
00002 #
00003 # Time-stamp: <2001/08/20 00:54:45 bruno>
00004 #
00005 # Copyright (C) 2003 Bruno Coudoin
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 from gettext import gettext as _
00022 # PythonTest Board module
00023 import gnomecanvas
00024 import gcompris
00025 import gcompris.utils
00026 import gcompris.skin
00027 import gcompris.bonus
00028 import gtk
00029 import gtk.gdk
00030 import copy
00031 import math
00032 
00033 class Gcompris_redraw:
00034   """The Re-drawing activity"""
00035 
00036 
00037   def __init__(self, gcomprisBoard):
00038 
00039     self.gcomprisBoard = gcomprisBoard
00040 
00041     # These are used to let us restart only after the bonus is displayed.
00042     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00043     self.board_paused  = 0;
00044     self.gamewon       = 0;
00045 
00046     # TOOL SELECTION
00047     self.tools = [
00048       ["RECT",           "draw/tool-rectangle.png",       "draw/tool-rectangle_on.png",          gcompris.CURSOR_RECT],
00049       ["FILL_RECT",      "draw/tool-filledrectangle.png", "draw/tool-filledrectangle_on.png",    gcompris.CURSOR_FILLRECT],
00050       ["CIRCLE",         "draw/tool-circle.png",          "draw/tool-circle_on.png",             gcompris.CURSOR_CIRCLE],
00051       ["FILL_CIRCLE",    "draw/tool-filledcircle.png",    "draw/tool-filledcircle_on.png",       gcompris.CURSOR_FILLCIRCLE],
00052       ["LINE",           "draw/tool-line.png",            "draw/tool-line_on.png",               gcompris.CURSOR_LINE],
00053       ["DEL",            "draw/tool-del.png",             "draw/tool-del_on.png",                gcompris.CURSOR_DEL],
00054       ["FILL",           "draw/tool-fill.png",            "draw/tool-fill_on.png",               gcompris.CURSOR_FILL],
00055       ["SELECT",         "draw/tool-select.png",          "draw/tool-select_on.png",             gcompris.CURSOR_SELECT]
00056       ]
00057 
00058     self.current_tool=0
00059 
00060     # COLOR SELECTION
00061     self.colors = [ 0x2A2A2AFFL,
00062                     0x7C4B21FFL,
00063                     0xEE0000FFL,
00064                     0xFF8C45FFL,
00065                     0xFFFF0cFFL,
00066                     0xB9BC0DFFL,
00067                     0x14FF3bFFL,
00068                     0xA4FFB3FFL,
00069                     0xFF53AFFFL,
00070                     0x831891FFL,
00071                     0x666666FFL,
00072                     0xF0F0F0FFL]
00073 
00074     self.current_color = 0
00075     self.current_step = 0
00076 
00077     self.current_drawing = []
00078     self.image_target    = []
00079 
00080     # Define the coord of each drawing area
00081     self.drawing_area = [140.0, 20.0, 420.0, 500.0]
00082     self.target_area  = [440.0, 20.0, 720.0, 500.0]
00083 
00084     # Global used for the select event
00085     self.in_select_ofx = -1
00086     self.in_select_ofy = -1
00087 
00088     # The error root item
00089     self.root_erroritem = []
00090 
00091     # Set it to 1 to let you create new forms
00092     # Once set, draw your shape in the right area. Then clic on OK to display
00093     # the data for the form (in the console). Then copy the data in the list at the end of
00094     # this file in init_item_list
00095     # Set self.editing_mode = None to forbid drawing in the right area
00096     self.editing_mode = None
00097     #self.editing_mode = 1
00098 
00099 
00100   def start(self):
00101     self.gcomprisBoard.level=1
00102     self.gcomprisBoard.maxlevel=1
00103     self.gcomprisBoard.sublevel=1
00104     self.gcomprisBoard.number_of_sublevel=1
00105 
00106     gcompris.bar_set(gcompris.BAR_OK|gcompris.BAR_LEVEL)
00107     gcompris.set_background(self.gcomprisBoard.canvas.root(),
00108                             gcompris.skin.image_to_skin("gcompris-bg.jpg"))
00109     gcompris.bar_set_level(self.gcomprisBoard)
00110 
00111     # Create our rootitem. We put each canvas item in it so at the end we
00112     # only have to kill it. The canvas deletes all the items it contains automaticaly.
00113     self.rootitem = self.gcomprisBoard.canvas.root().add(
00114       gnomecanvas.CanvasGroup,
00115       x=0.0,
00116       y=0.0
00117       )
00118 
00119     self.rootitem.add(
00120       gnomecanvas.CanvasPixbuf,
00121       pixbuf = gcompris.utils.load_pixmap(self.gcomprisBoard.icon_name),
00122       x = gcompris.BOARD_WIDTH - 60,
00123       y = 5,
00124       width = 60,
00125       height = 60,
00126       width_set = 1,
00127       height_set = 1
00128       )
00129 
00130     self.draw_tools()
00131     self.draw_colors()
00132     self.draw_drawing_area(20)
00133 
00134     self.init_item_list()
00135     self.display_current_level()
00136 
00137     self.pause(0);
00138 
00139   def end(self):
00140     # Remove the root item removes all the others inside it
00141     gcompris.set_cursor(gcompris.CURSOR_DEFAULT);
00142     self.rootitem.destroy()
00143     self.root_drawingitem.destroy()
00144     self.root_targetitem.destroy()
00145     # Delete error previous mark if any
00146     if(self.root_erroritem):
00147       self.root_erroritem.destroy()
00148 
00149 
00150 
00151   def pause(self, pause):
00152 
00153     self.board_paused = pause
00154 
00155     # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
00156     # the game is won
00157     if(self.gamewon == 1 and pause == 0):
00158       self.root_targetitem.show()
00159       self.gamewon = 0
00160 
00161     return
00162 
00163 
00164   def ok(self):
00165     # Save a copy of the target drawing future comparison
00166     target  = list(self.image_target)
00167     target2 = list(self.image_target)
00168 
00169     # Save a copy of the drawing cause we need to remove empty items
00170     source = list(self.current_drawing)
00171 
00172     # Remove all empty items
00173     while 1:
00174       try:
00175         source.remove ([])
00176       except:
00177         break
00178 
00179     if self.editing_mode != None :
00180       print("To add item in this activity, Copy the following data in init_item_list in redraw.py (near the end)")
00181       print("-------------------------------------------------------------------------------")
00182       print source
00183       print("-------------------------------------------------------------------------------")
00184 
00185     # Need to check if target image equals drawing image
00186     for i in source:
00187       for j in target:
00188         if i == j:
00189           target.remove(j)
00190 
00191     for i in target2:
00192       for j in source:
00193         if i == j:
00194           source.remove(j)
00195 
00196     if(len(target) == 0 and len(source) == 0):
00197       # This is a WIN
00198       self.erase_drawing_area()
00199       if (self.increment_level() == 1):
00200         self.gamewon = 1
00201         gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.FLOWER)
00202         self.display_current_level()
00203         self.root_targetitem.hide()
00204 
00205     else:
00206       # Delete previous mark if any
00207       if(self.root_erroritem):
00208         self.root_erroritem.destroy()
00209 
00210       # Create our rootitem for error items mark
00211       self.root_erroritem = self.gcomprisBoard.canvas.root().add(
00212         gnomecanvas.CanvasGroup,
00213         x=0.0,
00214         y=0.0
00215         )
00216 
00217       self.display_error(target, 1)
00218       self.display_error(source, 0)
00219 
00220 
00221   # display where there is errors
00222   # if in_target is set then error are displayed in the target area
00223   def display_error(self, target, in_target):
00224 
00225     # Bad Icon Width and Height / 2
00226     icw=8
00227     ich=8
00228 
00229     if self.gcomprisBoard.mode == 'symmetrical' and in_target:
00230       target = self.get_symmetry(target)
00231 
00232     # The images target are always drawn on the drawing area to ease the final comparison
00233     if in_target:
00234       xofset = self.target_area[0] - self.drawing_area[0]
00235     else:
00236       xofset = 0
00237 
00238     for t in target:
00239       if(t.has_key('points')):
00240         self.root_erroritem.add(
00241           gnomecanvas.CanvasPixbuf,
00242           pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("mini_bad.png")),
00243           x = t['points'][0] + (t['points'][2]-t['points'][0])/2 - icw + xofset,
00244           y = t['points'][1] + (t['points'][3]-t['points'][1])/2 -ich
00245           )
00246       else:
00247         self.root_erroritem.add(
00248           gnomecanvas.CanvasPixbuf,
00249           pixbuf = gcompris.utils.load_pixmap(gcompris.skin.image_to_skin("mini_bad.png")),
00250           x = t['x1'] + (t['x2']-t['x1'])/2 -icw + xofset,
00251           y = t['y1'] + (t['y2']-t['y1'])/2 -ich
00252           )
00253 
00254 
00255   # Called by gcompris when the user click on the level icon
00256   def set_level(self, level):
00257     self.gcomprisBoard.level=level;
00258     self.gcomprisBoard.sublevel=1;
00259 
00260     self.erase_drawing_area()
00261     self.display_current_level()
00262 
00263   def repeat(self):
00264     print("Gcompris_redraw repeat.")
00265 
00266 
00267   def config(self):
00268     print("Gcompris_redraw config.")
00269 
00270   def key_press(self, keyval, commit_str, preedit_str):
00271     print("got key %i" % keyval)
00272     return False
00273 
00274   # Erase any displayed items (drawing and target)
00275   def erase_drawing_area(self):
00276     self.root_targetitem.destroy()
00277     self.root_drawingitem.destroy()
00278     if(self.root_erroritem):
00279       self.root_erroritem.destroy()
00280 
00281   # Display the current level target
00282   def display_current_level(self):
00283     # Set the level in the control bar
00284     gcompris.bar_set_level(self.gcomprisBoard);
00285 
00286     # Calc the index in drawlist
00287     i = (self.gcomprisBoard.level-1)*self.gcomprisBoard.number_of_sublevel+ \
00288         (self.gcomprisBoard.sublevel-1)
00289 
00290     if(i>=len(self.drawlist)):
00291        # the current board is finished : bail out
00292        gcompris.bonus.board_finished(gcompris.bonus.FINISHED_RANDOM)
00293        return
00294 
00295     self.draw_image_target(self.drawlist[i])
00296 
00297     self.display_sublevel()
00298 
00299     # Prepare an item for the coord display
00300     self.coorditem = self.root_targetitem.add(
00301       gnomecanvas.CanvasText,
00302       font=gcompris.skin.get_font("gcompris/content"),
00303       x=gcompris.BOARD_WIDTH / 2 + 1,
00304       y=gcompris.BOARD_HEIGHT - 10 + 1 ,
00305       fill_color_rgba=0x000000FFL
00306       )
00307     self.coorditem_shadow = self.root_targetitem.add(
00308       gnomecanvas.CanvasText,
00309       font=gcompris.skin.get_font("gcompris/content"),
00310       x=gcompris.BOARD_WIDTH / 2,
00311       y= gcompris.BOARD_HEIGHT - 10,
00312       fill_color_rgba=0xFFFFFFFFL
00313       )
00314 
00315     # Create our rootitem for drawing items
00316     self.root_drawingitem = self.gcomprisBoard.canvas.root().add(
00317       gnomecanvas.CanvasGroup,
00318       x=0.0,
00319       y=0.0
00320       )
00321 
00322     # Reset the drawing
00323     self.current_drawing = []
00324 
00325   # Code that increments the sublevel and level
00326   # And bail out if no more levels are available
00327   # return 1 if continue, 0 if bail out
00328   def increment_level(self):
00329     self.gcomprisBoard.sublevel += 1
00330 
00331     if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
00332       # Try the next level
00333       self.gcomprisBoard.sublevel=1
00334       self.gcomprisBoard.level += 1
00335       if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel) or self.gcomprisBoard.level*self.gcomprisBoard.sublevel>=len(self.drawlist):
00336         # the current board is finished : bail out
00337         gcompris.bonus.board_finished(gcompris.bonus.FINISHED_RANDOM)
00338         return 0
00339 
00340     return 1
00341 
00342   # display current/sublevel number
00343   def display_sublevel(self):
00344 
00345     self.root_targetitem.add(
00346       gnomecanvas.CanvasText,
00347       text=_("Level") + " " + str(self.gcomprisBoard.sublevel) + "/"
00348       + str(self.gcomprisBoard.number_of_sublevel),
00349       font=gcompris.skin.get_font("gcompris/content"),
00350       x=gcompris.BOARD_WIDTH - 10 + 1,
00351       y=gcompris.BOARD_HEIGHT - 10 + 1,
00352       fill_color_rgba=0x000000FFL,
00353       anchor=gtk.ANCHOR_EAST,
00354       )
00355     self.root_targetitem.add(
00356       gnomecanvas.CanvasText,
00357       text=_("Level") + " " + str(self.gcomprisBoard.sublevel) + "/"
00358       + str(self.gcomprisBoard.number_of_sublevel),
00359       font=gcompris.skin.get_font("gcompris/content"),
00360       x=gcompris.BOARD_WIDTH - 10,
00361       y=gcompris.BOARD_HEIGHT - 10,
00362       fill_color_rgba=0xFFFFFFFFL,
00363       anchor=gtk.ANCHOR_EAST
00364       )
00365 
00366   # Display the tools
00367   def draw_tools(self):
00368 
00369     self.rootitem.add(
00370       gnomecanvas.CanvasPixbuf,
00371       pixbuf = gcompris.utils.load_pixmap("draw/little-tool-selector.png"),
00372       x=5,
00373       y=20.0,
00374       width=30.0
00375       )
00376 
00377     x1=11.0
00378     x2=56.0
00379     y=30.0
00380     stepy=45
00381 
00382     # Display the tools
00383     for i in range(0,len(self.tools)):
00384       if(i%2):
00385         theX = x2
00386       else:
00387         theX = x1
00388 
00389       item = self.rootitem.add(
00390         gnomecanvas.CanvasPixbuf,
00391         pixbuf = gcompris.utils.load_pixmap(self.tools[i][1]),
00392         x=theX,
00393         y=y
00394         )
00395       item.connect("event", self.tool_item_event, i)
00396       if i%2:
00397         y += stepy
00398 
00399     # The last item is select, we select it by default
00400     self.current_tool = i
00401     self.old_tool_item = item
00402     self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(self.tools[i][2]))
00403     gcompris.set_cursor(self.tools[i][3]);
00404 
00405 
00406   # Event when a tool is selected
00407   def tool_item_event(self, item, event, tool):
00408     if event.type == gtk.gdk.BUTTON_PRESS:
00409       if event.button == 1:
00410         # Deactivate old button
00411         self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(self.tools[self.current_tool][1]))
00412 
00413         # Activate new button
00414         self.current_tool = tool
00415         self.old_tool_item = item
00416         self.old_tool_item.set(pixbuf = gcompris.utils.load_pixmap(self.tools[self.current_tool][2]))
00417         gcompris.set_cursor(self.tools[self.current_tool][3]);
00418 
00419   # Display the color selector
00420   def draw_colors(self):
00421 
00422     x1=13.0
00423     x2=59.0
00424     y=230.0
00425     stepy=45
00426 
00427     # Display the tools
00428     for i in range(0,len(self.colors)):
00429       if(i%2):
00430         theX = x2
00431       else:
00432         theX = x1
00433 
00434       item = self.rootitem.add(
00435         gnomecanvas.CanvasRect,
00436         fill_color_rgba = self.colors[i],
00437         x1=theX,
00438         y1=y,
00439         x2=theX+30,
00440         y2=y+30,
00441         width_units=0.0,
00442         outline_color_rgba= 0x144B9DFFL
00443         )
00444       item.connect("event", self.color_item_event, i)
00445       if i%2:
00446         y += stepy
00447 
00448     # The last item is the one we select by default
00449     self.current_color = i
00450     self.old_color_item = item
00451     self.old_color_item.set(width_units = 4.0,
00452                             outline_color_rgba= 0x16EC3DFFL)
00453 
00454   # Color event
00455   def color_item_event(self, item, event, color):
00456     if event.type == gtk.gdk.BUTTON_PRESS:
00457       if event.button == 1:
00458         # Deactivate old button
00459         self.old_color_item.set(width_units = 0.0,
00460                                 outline_color_rgba= 0x144B9DFFL)
00461 
00462         # Activate new button
00463         self.current_color = color
00464         self.old_color_item = item
00465         self.old_color_item.set(width_units = 4.0,
00466                                 outline_color_rgba= 0x16EC3DFFL)
00467 
00468 
00469   # Display the drawing area
00470   def draw_drawing_area(self, step):
00471 
00472     self.current_step = step
00473 
00474     x1=self.drawing_area[0]
00475     y1=self.drawing_area[1]
00476     x2=self.drawing_area[2]
00477     y2=self.drawing_area[3]
00478 
00479     item = self.rootitem.add (
00480       gnomecanvas.CanvasRect,
00481       x1=x1,
00482       y1=y1,
00483       x2=x2,
00484       y2=y2,
00485       fill_color_rgba=0x0099FFFFL,
00486       width_units=2.0,
00487       outline_color_rgba=0x111199FFL
00488       )
00489     item.connect("event", self.create_item_event)
00490 
00491     self.draw_grid(x1,x2,y1,y2,step)
00492 
00493     x1=self.target_area[0]
00494     y1=self.target_area[1]
00495     x2=self.target_area[2]
00496     y2=self.target_area[3]
00497 
00498     item = self.rootitem.add (
00499       gnomecanvas.CanvasRect,
00500       x1=x1,
00501       y1=y1,
00502       x2=x2,
00503       y2=y2,
00504       fill_color_rgba=0x0099FFFFL,
00505       width_units=2.0,
00506       outline_color_rgba=0x111199FFL
00507       )
00508     item.connect("event", self.target_item_event)
00509 
00510     self.draw_grid(x1,x2,y1,y2,step)
00511 
00512     #
00513     # Given coord are returned swapped
00514     # Work fine for rect and ellipse but not line
00515     # so that y2 > y1 and x2 > x1
00516     #
00517   def reorder_coord(self, x1, y1, x2, y2):
00518     p = [x1, y1, x2, y2]
00519     if(x1>x2):
00520       p[0] = x2
00521       p[2] = x1
00522     if(y1>y2):
00523       p[1] = y2
00524       p[3] = y1
00525     return p
00526 
00527 
00528   #
00529   # Take a drawing and return a symmetrical one
00530   #
00531   def get_symmetry(self, drawing_source):
00532     # Make a deepcopy of the list
00533     drawing  = copy.deepcopy(drawing_source)
00534 
00535     xofset = 0
00536 
00537     for item in drawing:
00538 
00539       for k, v in item.items():
00540 
00541         if k == 'points' :
00542           if self.gcomprisBoard.mode == 'normal':
00543             v2 = (v[0]+xofset, v[1], v[2]+xofset, v[3])
00544           else:
00545             # Symmetrical view
00546             v2 = (self.drawing_area[2] - (v[0] - self.drawing_area[0])+xofset, v[1],
00547                   self.drawing_area[2] - (v[2] - self.drawing_area[0])+xofset, v[3])
00548           item[k] = v2
00549 
00550         elif k == 'x' :
00551           if self.gcomprisBoard.mode == 'normal':
00552             item[k] = v + xofset
00553           else:
00554             # Symmetrical view
00555             item[k] = self.drawing_area[2] - (v - self.drawing_area[0])  + xofset
00556 
00557         elif k == 'x1' :
00558           if self.gcomprisBoard.mode == 'normal':
00559             item[k] = v + xofset
00560           else:
00561             # Symmetrical view
00562             item[k] = self.drawing_area[2] - (v - self.drawing_area[0])  + xofset
00563 
00564         elif k == 'x2' :
00565           if self.gcomprisBoard.mode == 'normal':
00566             item[k] = v + xofset
00567           else:
00568             # Symmetrical view
00569             item[k] = self.drawing_area[2] - (v - self.drawing_area[0])  + xofset
00570 
00571     return drawing
00572 
00573   # Draw the image target
00574   # depending on self.gcomprisBoard.level drawing is 'normal' or 'symmetric'
00575   #
00576   def draw_image_target(self, drawing):
00577 
00578     # Save the drawing in image_target for future comparison
00579     self.image_target = drawing
00580 
00581     # Create our rootitem for target items
00582     self.root_targetitem = self.gcomprisBoard.canvas.root().add(
00583       gnomecanvas.CanvasGroup,
00584       x=0.0,
00585       y=0.0
00586       )
00587 
00588     if self.gcomprisBoard.mode == 'symmetrical':
00589       drawing = self.get_symmetry(drawing)
00590 
00591     # The images target are always drawn on the drawing area to ease the final comparison
00592     xofset = self.target_area[0] - self.drawing_area[0]
00593     for i in drawing:
00594       #
00595       # Can specify the item type to draw via a real GTK type or a TOOL string
00596       if(i.has_key('type')):
00597         item = self.root_targetitem.add ( i['type'] )
00598         item.connect("event", self.target_item_event)
00599 
00600       elif(i.has_key('tool')):
00601         if(i['tool'] == "RECT"):
00602           item = self.root_targetitem.add ( gnomecanvas.CanvasRect )
00603         elif(i['tool'] == "FILL_RECT"):
00604           item = self.root_targetitem.add ( gnomecanvas.CanvasRect )
00605         elif(i['tool'] == "CIRCLE"):
00606           item = self.root_targetitem.add ( gnomecanvas.CanvasEllipse )
00607         elif(i['tool'] == "FILL_CIRCLE"):
00608           item = self.root_targetitem.add ( gnomecanvas.CanvasEllipse )
00609         elif(i['tool'] == "LINE"):
00610           item = self.root_targetitem.add ( gnomecanvas.CanvasLine )
00611         else:
00612           print ("ERROR: incorrect type in draw_image_target", i)
00613         item.connect("event", self.target_item_event)
00614 
00615       for k, v in i.items():
00616         if k == 'fill_color' :
00617           item.set ( fill_color = v )
00618         elif k == 'fill_color_rgba' :
00619           item.set ( fill_color_rgba = v )
00620         elif k == 'height' :
00621           item.set ( height = v )
00622         elif k == 'height_set' :
00623           item.set ( height_set = v )
00624         elif k == 'outline_color' :
00625           item.set ( outline_color = v )
00626         elif k == 'outline_color_rgba' :
00627           item.set ( outline_color_rgba = v )
00628         elif k == 'points' :
00629           v2 = (v[0]+xofset, v[1], v[2]+xofset, v[3])
00630           item.set ( points = v2)
00631         elif k == 'width_units' :
00632           item.set ( width_units = v )
00633         elif k == 'width_pixels' :
00634           item.set ( width_pixels = v )
00635         elif k == 'width' :
00636           v[0] += xofset
00637           v[2] += xofset
00638           item.set ( width = v )
00639         elif k == 'width_set' :
00640           item.set ( width_set = v )
00641         elif k == 'x' :
00642           item.set ( x = v + xofset)
00643         elif k == 'y' :
00644           item.set ( y = v)
00645         elif k == 'x1' :
00646           item.set ( x1 = v + xofset)
00647         elif k == 'y1' :
00648           item.set ( y1 = v)
00649         elif k == 'x2' :
00650           item.set ( x2 = v + xofset)
00651         elif k == 'y2' :
00652           item.set ( y2 = v)
00653 
00654   #
00655   # Draw the grid
00656   #
00657   def draw_grid(self, x1, x2, y1, y2, step):
00658 
00659     # Coord of the written numbers
00660     if(x1<self.target_area[0]):
00661       x_text = x1 - 14
00662     else:
00663       x_text = x2 + 14
00664 
00665     y_text = y1 - 10
00666 
00667     # We manage a 2 colors grid
00668     ci = 0
00669     ca = 0x1D0DFFFFL
00670     cb = 0xAAEEAAFFL
00671 
00672     for i in range(x1,x2,step):
00673       if(ci%2):
00674         color = ca
00675       else:
00676         color = cb
00677       ci += 1
00678 
00679       item = self.rootitem.add (
00680         gnomecanvas.CanvasLine,
00681         points=(i , y1, i , y2),
00682         fill_color_rgba=color,
00683         width_units=1.0,
00684         )
00685       # Shadow for text number
00686       self.rootitem.add (
00687         gnomecanvas.CanvasText,
00688         text=int((i-x1) / step),
00689         font=gcompris.skin.get_font("gcompris/content"),
00690         x=i+1,
00691         y=y_text+1,
00692         fill_color_rgba=0x000000FFL
00693         )
00694       # Text number
00695       self.rootitem.add (
00696         gnomecanvas.CanvasText,
00697         text=int((i-x1) / step),
00698         font=gcompris.skin.get_font("gcompris/content"),
00699         x=i,
00700         y=y_text,
00701         fill_color_rgba=0xFFFFA0FFL
00702         )
00703 
00704       # Clicking on lines let you create object
00705       if(x1<self.target_area[0]):
00706         item.connect("event", self.create_item_event)
00707       else:
00708         item.connect("event", self.target_item_event)
00709 
00710     for i in range(y1,y2,step):
00711       if(ci%2):
00712         color = ca
00713       else:
00714         color = cb
00715       ci += 1
00716 
00717       item = self.rootitem.add (
00718         gnomecanvas.CanvasLine,
00719         points=(x1, i, x2 , i),
00720         fill_color_rgba=color,
00721         width_units=1.0,
00722         )
00723       # Shadow for text number
00724       self.rootitem.add (
00725         gnomecanvas.CanvasText,
00726         text=int((i-y1) / step),
00727         font=gcompris.skin.get_font("gcompris/content"),
00728         x=x_text+1,
00729         y=i+1,
00730         fill_color_rgba=0x000000FFL
00731         )
00732       # Text number
00733       self.rootitem.add (
00734         gnomecanvas.CanvasText,
00735         text=int((i-y1) / step),
00736         font=gcompris.skin.get_font("gcompris/content"),
00737         x=x_text,
00738         y=i,
00739         fill_color_rgba=0xFFFFA0FFL
00740         )
00741 
00742       # Clicking on lines let you create object
00743       if(x1<self.target_area[0]):
00744         item.connect("event", self.create_item_event)
00745 
00746   # Given x,y return a new x,y snapped to the grid
00747   def snap_to_grid(self, x, y):
00748     result = []
00749     tmp = round(((x+(self.current_step)) -
00750                self.drawing_area[0])/self.current_step) - 1
00751     result.append(float(self.drawing_area[0] + tmp*self.current_step))
00752 
00753     tmp = round(((y+(self.current_step)) -
00754                self.drawing_area[1])/self.current_step) - 1
00755     result.append(float(self.drawing_area[1] + tmp*self.current_step))
00756     return result
00757 
00758 
00759   # Event when a click on any item. Perform the move
00760   def move_item_event(self, item, event, item_index):
00761 
00762     if self.tools[self.current_tool][0] != "SELECT":
00763       return False
00764 
00765     #
00766     # MOUSE DRAG STOP
00767     # ---------------
00768     if event.type == gtk.gdk.BUTTON_RELEASE:
00769       if event.button == 1:
00770 
00771         # Reset thein_select_ofx ofset
00772         self.in_select_ofx = -1
00773         self.in_select_ofy = -1
00774 
00775         return True
00776 
00777     if event.state & gtk.gdk.BUTTON1_MASK:
00778       x=event.x
00779       y=event.y
00780 
00781       # Workaround for bad line positionning
00782       if(self.current_drawing[item_index].has_key('points')):
00783         item.set(width_units=1.0)
00784 
00785       bounds = item.get_bounds()
00786 
00787       # Save the ofset between the mouse pointer and the upper left corner of the object
00788       if(self.in_select_ofx == -1):
00789         self.in_select_ofx = x-bounds[0]
00790         self.in_select_ofy = y-bounds[1]
00791 
00792       x -= self.in_select_ofx
00793       y -= self.in_select_ofy
00794 
00795       x,y = self.snap_to_grid(x,y)
00796 
00797       # Check drawing boundaries
00798       if(x<self.drawing_area[0]):
00799         x=self.drawing_area[0]
00800       if(x>(self.drawing_area[2]-(bounds[2]-bounds[0]))):
00801         x=self.drawing_area[2]-(bounds[2]-bounds[0])
00802         # We need to realign x cause the bounds values are not precise enough
00803         x,n = self.snap_to_grid(x,y)
00804       if(y<self.drawing_area[1]):
00805         y=self.drawing_area[1]
00806       if(y>(self.drawing_area[3]-(bounds[3]-bounds[1]))):
00807         y=self.drawing_area[3]-(bounds[3]-bounds[1])
00808         # We need to realign y cause the bounds values are not precise enough
00809         n,y = self.snap_to_grid(x,y)
00810 
00811       # Need to update current_drawing
00812       if(self.current_drawing[item_index].has_key('x1')):
00813         # It's not a line
00814         ox = x - self.current_drawing[item_index]['x1']
00815         oy = y - self.current_drawing[item_index]['y1']
00816         self.current_drawing[item_index]['x1'] += ox
00817         self.current_drawing[item_index]['y1'] += oy
00818         self.current_drawing[item_index]['x2'] += ox
00819         self.current_drawing[item_index]['y2'] += oy
00820       else:
00821         # It can only be a line
00822         ox = x - min(self.current_drawing[item_index]['points'][0], self.current_drawing[item_index]['points'][2])
00823         oy = y - min(self.current_drawing[item_index]['points'][1], self.current_drawing[item_index]['points'][3])
00824         nx1 = self.current_drawing[item_index]['points'][0] + ox
00825         ny1 = self.current_drawing[item_index]['points'][1] + oy
00826         nx2 = self.current_drawing[item_index]['points'][2] + ox
00827         ny2 = self.current_drawing[item_index]['points'][3] + oy
00828         self.current_drawing[item_index]['points'] = (nx1, ny1, nx2, ny2)
00829 
00830       # Now perform the object move
00831       gcompris.utils.item_absolute_move(item, x, y)
00832 
00833       # Workaround for bad line positionning
00834       if(self.current_drawing[item_index].has_key('points')):
00835         item.set(width_units=8.0)
00836 
00837       return True
00838 
00839     return False
00840 
00841   # Event when a click on an item happen on fill in type object
00842   def fillin_item_event(self, item, event, drawing_item_index):
00843     if event.type == gtk.gdk.BUTTON_PRESS:
00844       if event.button == 1:
00845         if self.tools[self.current_tool][0] == "FILL":
00846           item.set(fill_color_rgba=self.colors[self.current_color])
00847           # Reset the item to our list
00848           self.current_drawing[drawing_item_index]['fill_color_rgba'] = self.colors[self.current_color]
00849           return True
00850     return False
00851 
00852   # Event when a click on an item happen on border fill type object
00853   def fillout_item_event(self, item, event, drawing_item_index):
00854     if event.type == gtk.gdk.BUTTON_PRESS:
00855       if event.button == 1:
00856         if self.tools[self.current_tool][0] == "FILL":
00857           item.set(outline_color_rgba=self.colors[self.current_color])
00858           # Reset the item to our list
00859           self.current_drawing[drawing_item_index]['outline_color_rgba'] = self.colors[self.current_color]
00860           return True
00861     return False
00862 
00863   # Del an item and internal struct cleanup
00864   def del_item(self, item, drawing_item_index):
00865     item.destroy()
00866     # Warning, do not realy delete it or we bug the index of other items
00867     self.current_drawing[drawing_item_index] = []
00868 
00869   # Event when a click on an item happen
00870   def del_item_event(self, item, event, drawing_item_index):
00871     if event.type == gtk.gdk.BUTTON_PRESS:
00872       if event.button == 1:
00873         if self.tools[self.current_tool][0] == "DEL":
00874           self.del_item(item, drawing_item_index);
00875           return True
00876     return False
00877 
00878   #
00879   # Display the mouse coord in the drawing or target area
00880   # type:
00881   # 1 = in drawing area
00882   # 2 = in target area
00883   # 3 = out of both area
00884   #
00885   def display_coord(self, x, y, type):
00886     if(type == 1):
00887       xl = self.drawing_area[0]
00888     else:
00889       xl = self.target_area[0]
00890 
00891     yl = self.drawing_area[1]
00892 
00893     x = int(round(((x+(self.current_step/2)) - xl)/self.current_step) - 1)
00894     y = int(round(((y+(self.current_step/2)) - yl)/self.current_step) - 1)
00895 
00896     if(type == 3):
00897       self.coorditem.set(text="")
00898       self.coorditem_shadow.set(text="")
00899     else:
00900       self.coorditem.set(
00901         text=_("Coordinate") + " = (" + str(x) + "/" + str(y) + ")"
00902         )
00903       self.coorditem_shadow.set(
00904         text=_("Coordinate") + " = (" + str(x) + "/" + str(y) + ")"
00905         )
00906 
00907 
00908 
00909 
00910   # Event when an event on the target area happen
00911   def target_item_event(self, item, event):
00912 
00913     if event.type == gtk.gdk.LEAVE_NOTIFY:
00914       self.display_coord(event.x,event.y, 3)
00915     else:
00916       self.display_coord(event.x,event.y, 2)
00917 
00918 
00919   # Event when an event on the drawing area happen
00920   def create_item_event(self, item, event):
00921 
00922     if event.type == gtk.gdk.LEAVE_NOTIFY:
00923       self.display_coord(event.x,event.y, 3)
00924     else:
00925       self.display_coord(event.x,event.y, 1)
00926 
00927     if event.type == gtk.gdk.BUTTON_PRESS:
00928 
00929       # Delete error previous mark if any
00930       if(self.root_erroritem):
00931         self.root_erroritem.destroy()
00932 
00933       if event.button == 1:
00934         self.newitem = None
00935 
00936         if (self.tools[self.current_tool][0] == "DEL" or
00937             self.tools[self.current_tool][0] == "SELECT" or
00938             self.tools[self.current_tool][0] == "FILL"):
00939           # This event is treated in del_item_event to avoid
00940           # operating on background item and grid
00941           return False
00942 
00943         elif self.tools[self.current_tool][0] == "LINE":
00944 
00945           x,y = self.snap_to_grid(event.x,event.y)
00946           self.pos_x = x
00947           self.pos_y = y
00948 
00949           self.newitem = self.root_drawingitem.add(
00950             gnomecanvas.CanvasLine,
00951             points=(self.pos_x, self.pos_y, x, y),
00952             fill_color_rgba=self.colors[self.current_color],
00953             width_units=8.0
00954             )
00955           self.newitem.connect("event", self.fillin_item_event, len(self.current_drawing))
00956           self.newitem.connect("event", self.move_item_event, len(self.current_drawing))
00957 
00958           # Add the new item to our list
00959           self.current_drawing.append({'tool': self.tools[self.current_tool][0],
00960                                         'points':(self.pos_x, self.pos_y, x, y),
00961                                         'fill_color_rgba':self.colors[self.current_color],
00962                                         'width_units':8.0})
00963 
00964         elif self.tools[self.current_tool][0] == "RECT":
00965 
00966           x,y = self.snap_to_grid(event.x,event.y)
00967           self.pos_x = x
00968           self.pos_y = y
00969 
00970           self.newitem = self.root_drawingitem.add(
00971             gnomecanvas.CanvasRect,
00972             x1=self.pos_x,
00973             y1=self.pos_y,
00974             x2=x,
00975             y2=y,
00976             outline_color_rgba=self.colors[self.current_color],
00977             width_units=4.0
00978             )
00979           self.newitem.connect("event", self.fillout_item_event, len(self.current_drawing))
00980           self.newitem.connect("event", self.move_item_event, len(self.current_drawing))
00981 
00982           # Add the new item to our list
00983           self.current_drawing.append({'tool': self.tools[self.current_tool][0],
00984                                        'x1':self.pos_x,
00985                                        'y1':self.pos_y,
00986                                        'x2':x,
00987                                        'y2':y,
00988                                        'outline_color_rgba':self.colors[self.current_color],
00989                                        'width_units':4.0})
00990 
00991         elif self.tools[self.current_tool][0] == "FILL_RECT":
00992 
00993           x,y = self.snap_to_grid(event.x,event.y)
00994           self.pos_x = x
00995           self.pos_y = y
00996 
00997           self.newitem = self.root_drawingitem.add(
00998             gnomecanvas.CanvasRect,
00999             x1=self.pos_x,
01000             y1=self.pos_y,
01001             x2=x,
01002             y2=y,
01003             fill_color_rgba=self.colors[self.current_color],
01004             outline_color_rgba=0x000000FFL,
01005             width_units=1.0
01006             )
01007           self.newitem.connect("event", self.fillin_item_event, len(self.current_drawing))
01008           self.newitem.connect("event", self.move_item_event, len(self.current_drawing))
01009 
01010           # Add the new item to our list
01011           self.current_drawing.append({'tool': self.tools[self.current_tool][0],
01012                                        'x1':self.pos_x,
01013                                        'y1':self.pos_y,
01014                                        'x2':x,
01015                                        'y2':y,
01016                                        'fill_color_rgba':self.colors[self.current_color],
01017                                        'outline_color_rgba':0x000000FFL,
01018                                        'width_units':1.0})
01019 
01020         elif self.tools[self.current_tool][0] == "CIRCLE":
01021 
01022           x,y = self.snap_to_grid(event.x,event.y)
01023           self.pos_x = x
01024           self.pos_y = y
01025 
01026           self.newitem = self.root_drawingitem.add(
01027             gnomecanvas.CanvasEllipse,
01028             x1=self.pos_x,
01029             y1=self.pos_y,
01030             x2=x,
01031             y2=y,
01032             outline_color_rgba=self.colors[self.current_color],
01033             width_units=5.0
01034             )
01035           self.newitem.connect("event", self.fillout_item_event, len(self.current_drawing))
01036           self.newitem.connect("event", self.move_item_event, len(self.current_drawing))
01037 
01038           # Add the new item to our list
01039           self.current_drawing.append({'tool': self.tools[self.current_tool][0],
01040                                        'x1':self.pos_x,
01041                                        'y1':self.pos_y,
01042                                        'x2':x,
01043                                        'y2':y,
01044                                        'outline_color_rgba':self.colors[self.current_color],
01045                                        'width_units':5.0})
01046 
01047         elif self.tools[self.current_tool][0] == "FILL_CIRCLE":
01048 
01049           x,y = self.snap_to_grid(event.x,event.y)
01050           self.pos_x = x
01051           self.pos_y = y
01052 
01053           self.newitem = self.root_drawingitem.add(
01054             gnomecanvas.CanvasEllipse,
01055             x1=self.pos_x,
01056             y1=self.pos_y,
01057             x2=x,
01058             y2=y,
01059             fill_color_rgba=self.colors[self.current_color],
01060             outline_color_rgba=0x000000FFL,
01061             width_units=1.0
01062             )
01063           self.newitem.connect("event", self.fillin_item_event, len(self.current_drawing))
01064           self.newitem.connect("event", self.move_item_event, len(self.current_drawing))
01065 
01066           # Add the new item to our list
01067           self.current_drawing.append({'tool': self.tools[self.current_tool][0],
01068                                        'x1':self.pos_x,
01069                                        'y1':self.pos_y,
01070                                        'x2':x,
01071                                        'y2':y,
01072                                        'fill_color_rgba':self.colors[self.current_color],
01073                                        'outline_color_rgba':0x000000FFL,
01074                                        'width_units':1.0})
01075         if self.newitem != 0:
01076           self.newitem.connect("event", self.create_item_event)
01077           self.newitem.connect("event", self.del_item_event, len(self.current_drawing)-1)
01078 
01079       return True
01080 
01081     #
01082     # MOTION EVENT
01083     # ------------
01084     if event.type == gtk.gdk.MOTION_NOTIFY:
01085       if event.state & gtk.gdk.BUTTON1_MASK:
01086         x=event.x
01087         y=event.y
01088         x,y = self.snap_to_grid(event.x,event.y)
01089 
01090         # Check drawing boundaries
01091         if(event.x<self.drawing_area[0]):
01092           x=self.drawing_area[0]
01093         if(event.x>self.drawing_area[2]):
01094           x=self.drawing_area[2]
01095         if(event.y<self.drawing_area[1]):
01096           y=self.drawing_area[1]
01097         if(event.y>self.drawing_area[3]):
01098           y=self.drawing_area[3]
01099 
01100         if self.tools[self.current_tool][0] == "LINE":
01101           self.newitem.set( points=( self.pos_x, self.pos_y, x, y) )
01102           # Reset the item to our list
01103           self.current_drawing[len(self.current_drawing)-1]['points'] = ( self.pos_x, self.pos_y, x, y)
01104         elif (self.tools[self.current_tool][0] == "RECT" or
01105               self.tools[self.current_tool][0] == "FILL_RECT" or
01106               self.tools[self.current_tool][0] == "CIRCLE" or
01107               self.tools[self.current_tool][0] == "FILL_CIRCLE"):
01108           self.newitem.set(
01109             x2=x,
01110             y2=y)
01111           # Reset the item to our list
01112           self.current_drawing[len(self.current_drawing)-1]['x2'] = x
01113           self.current_drawing[len(self.current_drawing)-1]['y2'] = y
01114 
01115 
01116     #
01117     # MOUSE DRAG STOP
01118     # ---------------
01119     if event.type == gtk.gdk.BUTTON_RELEASE:
01120       if event.button == 1:
01121         # We have to remove empty created items (the kid did not drag enough)
01122         if self.tools[self.current_tool][0] == "LINE":
01123           bounds = self.current_drawing[len(self.current_drawing)-1]['points']
01124           if (bounds[0] == bounds[2]) and (bounds[1] == bounds[3]):
01125             # Oops, empty line
01126             self.del_item(self.newitem, len(self.current_drawing)-1)
01127           else:
01128             # We need to reord the coord in increasing order to allow later comparison
01129             # I use a trick, I do x1*x1+y1 and x2*x2+y2, put the lower as the A point
01130             i = bounds[0]*bounds[0] + bounds[1]
01131             j = bounds[2]*bounds[2] + bounds[3]
01132             if(i<=j):
01133               self.current_drawing[len(self.current_drawing)-1]['points'] = (bounds[0], bounds[1],
01134                                                                              bounds[2], bounds[3])
01135             else:
01136               self.current_drawing[len(self.current_drawing)-1]['points'] = (bounds[2], bounds[3],
01137                                                                              bounds[0], bounds[1])
01138 
01139         elif (self.tools[self.current_tool][0] == "RECT" or
01140               self.tools[self.current_tool][0] == "FILL_RECT" or
01141               self.tools[self.current_tool][0] == "CIRCLE" or
01142               self.tools[self.current_tool][0] == "FILL_CIRCLE"):
01143           # It's a rect or ellipse
01144           x1 = self.current_drawing[len(self.current_drawing)-1]['x1']
01145           y1 = self.current_drawing[len(self.current_drawing)-1]['y1']
01146           x2 = self.current_drawing[len(self.current_drawing)-1]['x2']
01147           y2 = self.current_drawing[len(self.current_drawing)-1]['y2']
01148           if (x1 == x2) or (y1 == y2):
01149             # Oups, empty rect
01150             self.del_item(self.newitem, len(self.current_drawing)-1)
01151           else:
01152             # We need to reord the coord in increasing order to allow later comparison
01153             x1, y1, x2, y2 = self.reorder_coord(x1, y1, x2, y2)
01154             self.current_drawing[len(self.current_drawing)-1]['x1'] = x1
01155             self.current_drawing[len(self.current_drawing)-1]['y1'] = y1
01156             self.current_drawing[len(self.current_drawing)-1]['x2'] = x2
01157             self.current_drawing[len(self.current_drawing)-1]['y2'] = y2
01158 
01159         return True
01160     return False
01161 
01162 
01163   # The list of items (data) for this game
01164   def init_item_list(self):
01165 
01166     if self.gcomprisBoard.mode == 'normal':
01167       self.drawlist = \
01168                     [
01169         # Two stripes
01170       [{'x2': 420.0, 'width_units': 1.0, 'y2': 100.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 80.0, 'tool': 'FILL_RECT', 'x1': 140.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 440.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 420.0, 'tool': 'FILL_RECT', 'x1': 140.0}]
01171       ,
01172       # Top centered box
01173       [{'x2': 360.0, 'y2': 80.0, 'width_units': 1.0, 'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 40.0, 'x1': 200.0, 'tool': 'FILL_RECT'}]
01174       ,
01175       # 4 small corners
01176       [{'x2': 200.0, 'y2': 80.0,  'width_units': 1.0,'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 40.0, 'x1': 160.0, 'tool': 'FILL_RECT'},
01177        {'x2': 400.0, 'y2': 80.0,  'width_units': 1.0,'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 40.0, 'x1': 360.0, 'tool': 'FILL_RECT'},
01178        {'x2': 200.0, 'y2': 480.0, 'width_units': 1.0, 'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 440.0, 'x1': 160.0, 'tool': 'FILL_RECT'},
01179        {'x2': 400.0, 'y2': 480.0,  'width_units': 1.0,'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 440.0, 'x1': 360.0, 'tool': 'FILL_RECT'}]
01180       ,
01181       # 4 non filled Rects organised in rect and shifted
01182       [{'x2': 200.0, 'y2': 360.0, 'outline_color_rgba': 4042322175L, 'width_units': 4.0, 'y1': 200.0, 'x1': 180.0, 'tool': 'RECT'},
01183        {'x2': 340.0, 'y2': 400.0, 'outline_color_rgba': 4042322175L, 'width_units': 4.0, 'y1':380.0, 'x1': 180.0, 'tool': 'RECT'},
01184        {'x2': 380.0, 'y2': 400.0, 'outline_color_rgba': 4042322175L, 'width_units': 4.0, 'y1': 240.0, 'x1': 360.0, 'tool': 'RECT'},
01185        {'x2': 380.0, 'y2': 220.0, 'outline_color_rgba': 4042322175L, 'width_units': 4.0, 'y1': 200.0, 'x1': 220.0, 'tool': 'RECT'}]
01186       ,
01187       # Letter A
01188       [{'tool': 'LINE', 'points': (200.0, 120.0, 280.0, 120.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (280.0, 120.0, 280.0,240.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (200.0, 120.0, 200.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (200.0, 180.0, 280.0, 180.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01189       ,
01190       # Letter B
01191       [{'tool': 'LINE', 'points': (240.0, 240.0, 320.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (300.0, 180.0, 320.0,200.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (300.0, 180.0, 320.0, 160.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (240.0, 180.0, 300.0, 180.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (320.0, 100.0, 320.0, 160.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool':'LINE', 'points': (240.0, 100.0, 320.0, 100.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (240.0, 100.0, 240.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (320.0, 200.0, 320.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01192       ,
01193       # A door
01194       [{'x2': 360.0, 'y2': 360.0, 'outline_color_rgba': 4042322175L, 'width_units': 4.0, 'y1': 180.0, 'x1': 200.0, 'tool': 'RECT'},
01195        {'x2': 340.0, 'y2': 320.0, 'width_units': 1.0, 'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 280.0, 'x1': 300.0, 'tool': 'FILL_CIRCLE'},
01196        {'x2': 320.0, 'y2': 260.0, 'width_units': 1.0, 'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 200.0, 'x1': 240.0, 'tool': 'FILL_RECT'}]
01197       ,
01198       # A top left kind of target
01199       [{'x2': 260.0, 'y2': 140.0, 'outline_color_rgba': 4042322175L, 'y1': 40.0, 'x1': 160.0, 'tool': 'CIRCLE', 'width_units': 5.0},
01200        {'x2': 240.0, 'y2': 120.0, 'width_units': 1.0, 'fill_color_rgba': 4042322175L, 'outline_color_rgba': 255L, 'y1': 60.0, 'x1': 180.0, 'tool': 'FILL_CIRCLE'}]
01201       ,
01202       # 4 Huge Diagonal lines
01203       [{'tool': 'LINE', 'points': (140.0, 260.0, 260.0, 20.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (140.0, 260.0, 260.0, 500.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (260.0, 500.0, 420.0, 260.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (260.0, 20.0, 420.0, 260.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01204       ,
01205       # Balloon
01206       [{'tool': 'LINE', 'points': (220.0, 240.0, 220.0, 340.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'x2': 260.0, 'width_units': 1.0, 'y2': 240.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 140.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 80.0, 'tool': 'FILL_CIRCLE', 'x1': 300.0}, {'tool': 'LINE', 'points': (340.0, 180.0, 340.0, 280.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01207       ,
01208       # Watch
01209       [{'x2': 380.0, 'y2': 340.0, 'outline_color_rgba': 4042322175L, 'width_units': 5.0, 'y1': 140.0, 'tool': 'CIRCLE', 'x1': 180.0}, {'tool': 'LINE', 'points': (280.0, 160.0, 280.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (280.0, 240.0, 320.0, 200.0), 'width_units': 8.0, 'fill_color_rgba': 352271359L}, {'tool': 'LINE', 'points': (220.0, 280.0, 280.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4294905087L}]
01210       ,
01211       # Colored pyramid
01212       [{'x2': 280.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 100.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 140.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 120.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 160.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 140.0, 'tool': 'FILL_RECT', 'x1': 220.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 1717987071L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 180.0}]
01213       ,
01214       # Colored Rectangle bigger and bigger
01215       [{'x2': 180.0, 'width_units': 1.0, 'y2': 60.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 20.0, 'tool': 'FILL_RECT', 'x1': 140.0}, {'x2': 240.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 60.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 120.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 320.0}]
01216       ,
01217       # Tree
01218       [{'x2': 420.0, 'width_units': 1.0, 'y2': 500.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2085298687L, 'y1': 460.0, 'tool': 'FILL_RECT', 'x1': 140.0}, {'x2': 260.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 360.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 360.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 280.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}]
01219       ,
01220       # bipbip (big non flying bird)
01221       [{'x2': 280.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 120.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 80.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 100.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 320.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 220.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 300.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 260.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 380.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 440.0, 'tool': 'FILL_RECT', 'x1': 260.0}]
01222       ,
01223       # Dog
01224       [{'x2': 180.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 160.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 240.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 200.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 340.0,'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba':2199425535L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 320.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 320.0}]
01225       ,
01226       # Fish
01227       [{'x2': 360.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 160.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 200.0, 'tool': 'FILL_CIRCLE', 'x1': 320.0}, {'x2': 180.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 160.0}]
01228       ,
01229       # Balloon (human)
01230       [{'x2': 380.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 100.0, 'tool': 'FILL_CIRCLE', 'x1': 200.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 320.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'tool': 'LINE', 'points': (220.0, 260.0, 260.0, 320.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}, {'tool': 'LINE', 'points': (320.0, 320.0, 360.0, 260.0),
01231 'width_units': 8.0, 'fill_color_rgba': 4287383039L}]
01232       ,
01233       # House
01234       [{'x2': 360.0, 'width_units': 1.0, 'y2': 340.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 340.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 280.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 260.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'tool': 'LINE', 'points': (200.0, 240.0, 280.0, 160.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}, {'tool': 'LINE', 'points': (280.0, 160.0, 360.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}]
01235       ,
01236       # Truck
01237       [{'x2': 220.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 240.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 240.0, 'tool': 'FILL_CIRCLE', 'x1': 280.0}, {'x2': 220.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 160.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 220.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 240.0}]
01238       ,
01239       # Fire truck
01240       [{'x2': 200.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 260.0, 'tool': 'FILL_CIRCLE', 'x1': 160.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 260.0, 'tool': 'FILL_CIRCLE', 'x1': 320.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 160.0}, {'tool': 'LINE', 'points': (160.0, 200.0, 340.0, 180.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'x2': 200.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 320.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 280.0}]
01241       ,
01242       # Billard
01243       [
01244         {'width_units': 8.0, 'points': (180.0, 80.0, 180.0, 440.0), 'tool': 'LINE', 'fill_color_rgba': 4042322175L},
01245         {'width_units': 8.0, 'points': (180.0, 460.0, 380.0, 460.0), 'tool': 'LINE', 'fill_color_rgba': 4042322175L},
01246         {'width_units': 8.0, 'points': (380.0, 80.0, 380.0, 440.0), 'tool': 'LINE', 'fill_color_rgba': 4042322175L},
01247         {'width_units': 8.0, 'points': (180.0, 60.0, 380.0, 60.0), 'tool': 'LINE', 'fill_color_rgba': 4042322175L},
01248         {'width_units': 8.0, 'points': (280.0, 320.0, 280.0, 420.0), 'tool': 'LINE', 'fill_color_rgba': 2199425535L},
01249         {'x2': 280.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 300.0, 'x1': 260.0, 'tool': 'FILL_CIRCLE'},
01250         {'x2': 260.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 100.0, 'x1': 240.0, 'tool': 'FILL_CIRCLE'},
01251         {'x2': 280.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 100.0, 'x1': 260.0, 'tool': 'FILL_CIRCLE'},
01252         {'x2': 300.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 100.0, 'x1': 280.0, 'tool': 'FILL_CIRCLE'},
01253         {'x2': 320.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2085298687L, 'y1': 100.0, 'x1': 300.0, 'tool': 'FILL_CIRCLE'},
01254         {'x2': 280.0, 'width_units': 1.0, 'y2': 140.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3116109311L, 'y1': 120.0, 'x1': 260.0, 'tool': 'FILL_CIRCLE'},
01255         {'x2': 300.0, 'width_units': 1.0, 'y2': 140.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 120.0, 'x1': 280.0, 'tool': 'FILL_CIRCLE'}
01256         ]
01257       ,
01258       # Clara (my daughter)
01259       [{'x2': 240.0, 'width_units': 1.0, 'y2': 480.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 400.0, 'x1': 220.0, 'tool': 'FILL_RECT'}, {'x2': 320.0, 'width_units': 1.0, 'y2': 480.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 400.0, 'x1': 300.0, 'tool': 'FILL_RECT'}, {'x2': 220.0, 'width_units': 1.0, 'y2': 200.0,'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 180.0, 'x1': 160.0, 'tool': 'FILL_RECT'}, {'x2': 380.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 180.0, 'x1': 320.0, 'tool': 'FILL_RECT'}, {'x2': 380.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 120.0, 'x1': 360.0, 'tool': 'FILL_RECT'}, {'x2': 180.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 200.0, 'x1': 160.0, 'tool': 'FILL_RECT'}, {'x2': 320.0, 'width_units': 1.0, 'y2': 160.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 60.0, 'x1': 220.0, 'tool': 'FILL_CIRCLE'}, {'x2': 260.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2768221183L, 'y1': 100.0, 'x1': 240.0, 'tool': 'FILL_CIRCLE'}, {'x2': 300.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2768221183L, 'y1': 100.0, 'x1': 280.0, 'tool': 'FILL_CIRCLE'}, {'width_units': 8.0, 'points': (260.0, 140.0, 280.0, 140.0), 'tool': 'LINE', 'fill_color_rgba': 3992977663L}, {'x2': 300.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 160.0, 'x1': 240.0, 'tool': 'FILL_RECT'}, {'x2': 320.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 180.0, 'x1': 220.0, 'tool': 'FILL_RECT'}, {'x2': 340.0, 'width_units': 1.0, 'y2': 400.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 320.0, 'x1': 200.0, 'tool': 'FILL_RECT'}]
01260       ,
01261       # Bicycle
01262       [{'x2': 240.0, 'y2': 340.0, 'outline_color_rgba': 4287383039L, 'width_units': 5.0, 'y1': 260.0, 'tool': 'CIRCLE', 'x1': 160.0}, {'x2': 400.0, 'y2': 340.0, 'outline_color_rgba': 4287383039L, 'width_units': 5.0, 'y1': 260.0, 'tool': 'CIRCLE', 'x1': 320.0}, {'tool': 'LINE', 'points': (200.0, 300.0, 280.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (280.0,300.0, 340.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (240.0, 240.0, 340.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (200.0, 300.0, 240.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (240.0, 220.0, 240.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 2199425535L}, {'tool': 'LINE', 'points': (220.0, 220.0, 260.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 2199425535L}, {'tool': 'LINE', 'points': (340.0, 200.0, 340.0, 240.0), 'width_units': 8.0, 'fill_color_rgba': 2199425535L}, {'tool': 'LINE', 'points': (320.0, 200.0, 340.0, 200.0), 'width_units': 8.0, 'fill_color_rgba': 2199425535L}, {'tool': 'LINE', 'points': (340.0, 240.0, 360.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}]
01263       ,
01264       # Sea boat and sun
01265       [{'x2': 420.0, 'width_units': 1.0, 'y2': 500.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2768221183L, 'y1': 420.0, 'tool': 'FILL_RECT', 'x1': 140.0}, {'x2': 260.0, 'width_units': 1.0, 'y2': 160.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 60.0, 'tool': 'FILL_CIRCLE', 'x1': 160.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 160.0, 'tool': 'FILL_CIRCLE', 'x1': 260.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 200.0, 'tool': 'FILL_CIRCLE', 'x1': 300.0}, {'x2': 400.0,'width_units': 1.0, 'y2': 160.0, 'outline_color_rgba': 255L, 'fill_color_rgba':4042322175L, 'y1': 140.0, 'tool': 'FILL_CIRCLE', 'x1': 360.0}, {'tool': 'LINE','points': (220.0, 400.0, 240.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (240.0, 420.0, 280.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (280.0, 420.0, 300.0, 400.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (220.0, 400.0, 300.0, 400.0), 'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points': (260.0, 280.0, 260.0, 400.0),'width_units': 8.0, 'fill_color_rgba': 3992977663L}, {'tool': 'LINE', 'points':(260.0, 280.0, 300.0, 380.0), 'width_units': 8.0, 'fill_color_rgba': 2199425535L}, {'tool': 'LINE', 'points': (260.0, 380.0, 300.0, 380.0), 'width_units': 8.0,'fill_color_rgba': 2199425535L}]
01266 
01267       ]
01268     else:
01269       # Symmetrical items
01270       self.drawlist = \
01271       [
01272         # 3 white box in triangle
01273         [{'x2': 420.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 380.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 340.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 260.0, 'tool': 'FILL_RECT', 'x1': 340.0}]
01274         ,
01275         # Colored pyramid
01276         [{'x2': 420.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 1717987071L, 'y1': 420.0, 'tool': 'FILL_RECT', 'x1': 140.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 420.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 380.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 340.0, 'tool': 'FILL_RECT', 'x1': 220.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 340.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 300.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 260.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 707406591L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 340.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2085298687L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 380.0}]
01277         ,
01278         # Butterfly
01279         [{'x2': 420.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 380.0}, {'tool': 'LINE', 'points': (360.0, 80.0, 400.0, 180.0), 'width_units': 8.0, 'fill_color_rgba': 707406591L}, {'x2': 380.0, 'width_units': 1.0, 'y2': 440.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 100.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 180.0, 'tool': 'FILL_CIRCLE', 'x1': 260.0}]
01280         ,
01281         # Robot
01282         [{'x2': 420.0, 'width_units': 1.0, 'y2': 360.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 340.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 500.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 360.0, 'tool': 'FILL_RECT', 'x1': 340.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 160.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 140.0, 'tool': 'FILL_RECT', 'x1': 380.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 140.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2768221183L, 'y1': 60.0, 'tool': 'FILL_RECT', 'x1': 360.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3116109311L, 'y1': 100.0, 'tool': 'FILL_RECT', 'x1': 400.0}, {'x2': 400.0, 'width_units': 1.0, 'y2': 100.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4283674623L, 'y1': 80.0, 'tool': 'FILL_CIRCLE', 'x1': 380.0}]
01283         ,
01284         # Arrow
01285         [{'x2': 420.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'tool': 'LINE', 'points': (180.0, 240.0, 300.0, 140.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}, {'tool': 'LINE', 'points': (180.0, 240.0, 180.0, 260.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}, {'tool': 'LINE', 'points': (180.0, 260.0, 300.0, 360.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}, {'tool': 'LINE', 'points': (300.0, 140.0, 300.0, 360.0), 'width_units': 8.0, 'fill_color_rgba': 4287383039L}]
01286         ,
01287         # House
01288         [{'x2': 420.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 440.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 220.0, 'width_units': 1.0, 'y2': 440.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 280.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 260.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 440.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 360.0, 'tool': 'FILL_RECT', 'x1': 380.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 400.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 300.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'tool': 'LINE', 'points': (200.0, 260.0, 420.0, 100.0), 'width_units': 8.0, 'fill_color_rgba': 4294905087L}]
01289         ,
01290         # Plane
01291         [{'x2': 420.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 140.0, 'tool': 'FILL_RECT', 'x1': 360.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 220.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 260.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 707406591L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'tool': 'LINE', 'points': (180.0, 200.0, 320.0, 200.0), 'width_units': 8.0, 'fill_color_rgba': 4283674623L}, {'x2': 420.0, 'width_units': 1.0, 'y2': 420.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 360.0, 'tool': 'FILL_RECT', 'x1': 400.0}, {'x2': 420.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 380.0}]
01292         ,
01293         # bipbip (big non flying bird)
01294         [{'x2': 280.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 120.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 80.0, 'tool': 'FILL_RECT', 'x1': 260.0}, {'x2': 320.0, 'width_units': 1.0, 'y2': 120.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 100.0, 'tool': 'FILL_RECT', 'x1': 300.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 380.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 320.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 220.0, 'width_units': 1.0, 'y2': 320.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 300.0, 'tool': 'FILL_RECT', 'x1': 200.0}, {'x2': 260.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 380.0, 'tool': 'FILL_RECT', 'x1': 240.0}, {'x2': 280.0, 'width_units': 1.0, 'y2': 460.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 352271359L, 'y1': 440.0, 'tool': 'FILL_RECT', 'x1': 260.0}]
01295         ,
01296         # Dog
01297         [{'x2': 180.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 160.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 240.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 200.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 180.0}, {'x2': 340.0,'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba':2199425535L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 320.0}, {'x2': 380.0, 'width_units': 1.0, 'y2': 200.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 2199425535L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 320.0}]
01298         ,
01299         # Fish
01300         [{'x2': 360.0, 'width_units': 1.0, 'y2': 280.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 160.0, 'tool': 'FILL_CIRCLE', 'x1': 180.0}, {'x2': 340.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4042322175L, 'y1': 200.0, 'tool': 'FILL_CIRCLE', 'x1': 320.0}, {'x2': 180.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4294905087L, 'y1': 180.0, 'tool': 'FILL_RECT', 'x1': 160.0}]
01301         ,
01302         # Boat
01303         [{'tool': 'LINE', 'points': (260.0, 340.0, 420.0, 340.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 260.0, 260.0, 340.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 260.0, 420.0, 260.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (340.0, 260.0, 360.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (360.0, 220.0, 420.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'x2': 320.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 280.0, 'tool': 'FILL_CIRCLE', 'x1': 300.0}, {'x2': 360.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 280.0, 'tool': 'FILL_CIRCLE', 'x1': 340.0}, {'x2': 400.0, 'width_units': 1.0, 'y2': 300.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 280.0, 'tool': 'FILL_CIRCLE', 'x1': 380.0}]
01304         ,
01305         # Spaceship
01306         [{'tool': 'LINE', 'points': (220.0, 400.0, 340.0, 400.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (340.0, 400.0, 360.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (360.0, 320.0, 360.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (340.0, 300.0, 360.0, 320.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (340.0, 100.0, 340.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (200.0, 420.0, 220.0, 400.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (200.0, 320.0, 200.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (200.0, 320.0, 220.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 100.0, 220.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 100.0, 280.0, 20.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (280.0, 20.0, 340.0, 100.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 100.0, 340.0, 100.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 120.0, 340.0, 120.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 300.0, 340.0, 300.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (280.0, 300.0, 280.0, 420.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01307         ,
01308         # Question mark
01309         [{'tool': 'LINE', 'points': (280.0, 260.0, 280.0, 440.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (280.0, 260.0, 340.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (340.0, 160.0, 340.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (280.0, 120.0, 340.0, 160.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 160.0, 280.0, 120.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 160.0, 220.0, 200.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 200.0, 260.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}]
01310         ,
01311         # Flying toy (cerf volant in french)
01312         [{'tool': 'LINE', 'points': (160.0, 140.0, 260.0, 100.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (160.0, 140.0, 160.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (160.0, 220.0, 260.0, 380.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (260.0, 380.0, 360.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (360.0, 140.0, 360.0, 220.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (260.0, 100.0, 360.0, 140.0), 'width_units': 8.0, 'fill_color_rgba': 4042322175L}, {'tool': 'LINE', 'points': (220.0, 500.0, 260.0, 380.0), 'width_units': 8.0, 'fill_color_rgba': 707406591L}, {'x2': 240.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 160.0, 'tool': 'FILL_RECT', 'x1': 220.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 200.0, 'tool': 'FILL_RECT', 'x1': 280.0}, {'x2': 240.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 3992977663L, 'y1': 240.0, 'tool': 'FILL_RECT', 'x1': 220.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 180.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 160.0, 'tool': 'FILL_CIRCLE', 'x1': 280.0}, {'x2': 240.0, 'width_units': 1.0, 'y2': 220.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 200.0, 'tool': 'FILL_CIRCLE', 'x1': 220.0}, {'x2': 300.0, 'width_units': 1.0, 'y2': 260.0, 'outline_color_rgba': 255L, 'fill_color_rgba': 4287383039L, 'y1': 240.0, 'tool': 'FILL_CIRCLE', 'x1': 280.0}]
01313 
01314       ]
01315 
01316     # No more than 9 level allowed in gcompris
01317     self.gcomprisBoard.number_of_sublevel=math.ceil(len(self.drawlist)/9.0)
01318     self.gcomprisBoard.maxlevel=min(9, math.ceil(float(len(self.drawlist))/self.gcomprisBoard.number_of_sublevel))
01319     print "Number of target=", len(self.drawlist)
01320     print "Maxlevel=", self.gcomprisBoard.maxlevel, " sublevel=", self.gcomprisBoard.number_of_sublevel
01321