~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/redraw-activity/redraw.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#  gcompris - redraw
 
2
#
 
3
# Copyright (C) 2003, 2008 Bruno Coudoin
 
4
#
 
5
#   This program is free software; you can redistribute it and/or modify
 
6
#   it under the terms of the GNU General Public License as published by
 
7
#   the Free Software Foundation; either version 3 of the License, or
 
8
#   (at your option) any later version.
 
9
#
 
10
#   This program is distributed in the hope that it will be useful,
 
11
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
#   GNU General Public License for more details.
 
14
#
 
15
#   You should have received a copy of the GNU General Public License
 
16
#   along with this program; if not, see <http://www.gnu.org/licenses/>.
 
17
#
 
18
from gcompris import gcompris_gettext as _
 
19
# PythonTest Board module
 
20
import goocanvas
 
21
import gcompris
 
22
import gcompris.utils
 
23
import gcompris.skin
 
24
import gcompris.bonus
 
25
import gcompris.sound
 
26
import gtk
 
27
import gtk.gdk
 
28
import copy
 
29
import math
 
30
 
 
31
class Gcompris_redraw:
 
32
  """The Re-drawing activity"""
 
33
 
 
34
 
 
35
  def __init__(self, gcomprisBoard):
 
36
 
 
37
    self.gcomprisBoard = gcomprisBoard
 
38
 
 
39
    # These are used to let us restart only after the bonus is displayed.
 
40
    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
 
41
    self.board_paused  = 0;
 
42
    self.gamewon       = 0;
 
43
 
 
44
    # TOOL SELECTION
 
45
    self.tools = [
 
46
      ["RECT",           "anim/tool-rectangle.png",       "anim/tool-rectangle_on.png",          gcompris.CURSOR_RECT],
 
47
      ["FILL_RECT",      "anim/tool-filledrectangle.png", "anim/tool-filledrectangle_on.png",    gcompris.CURSOR_FILLRECT],
 
48
      ["CIRCLE",         "anim/tool-circle.png",          "anim/tool-circle_on.png",             gcompris.CURSOR_CIRCLE],
 
49
      ["FILL_CIRCLE",    "anim/tool-filledcircle.png",    "anim/tool-filledcircle_on.png",       gcompris.CURSOR_FILLCIRCLE],
 
50
      ["LINE",           "anim/tool-line.png",            "anim/tool-line_on.png",               gcompris.CURSOR_LINE],
 
51
      ["DEL",            "anim/tool-del.png",             "anim/tool-del_on.png",                gcompris.CURSOR_DEL],
 
52
      ["FILL",           "anim/tool-fill.png",            "anim/tool-fill_on.png",               gcompris.CURSOR_FILL],
 
53
      ["SELECT",         "anim/tool-select.png",          "anim/tool-select_on.png",             gcompris.CURSOR_SELECT]
 
54
      ]
 
55
 
 
56
    self.current_tool=0
 
57
 
 
58
    # COLOR SELECTION
 
59
    self.color_fill = 0xA0
 
60
    self.color_stroke = 0xFF
 
61
    self.colors = [ 0x00000000L,
 
62
                    0xFF000000L,
 
63
                    0xFFFF0c00L,
 
64
                    0xB9BC0D00L,
 
65
                    0x33FF0000L,
 
66
                    0x83189100L,
 
67
                    0xC2C2C200L,
 
68
                    0x1010FF00L]
 
69
 
 
70
    self.current_color = 0
 
71
    self.current_step = 0
 
72
 
 
73
    self.current_drawing = []
 
74
    self.image_target    = []
 
75
 
 
76
    # Define the coord of each drawing area
 
77
    self.drawing_area = [140.0, 20.0, 420.0, 500.0]
 
78
    self.target_area  = [440.0, 20.0, 720.0, 500.0]
 
79
 
 
80
    # Global used for the select event
 
81
    self.in_select_ofx = -1
 
82
    self.in_select_ofy = -1
 
83
 
 
84
    # The error root item
 
85
    self.root_erroritem = []
 
86
 
 
87
    # Set it to 1 to let you create new forms
 
88
    # Once set, draw your shape in the right area. Then clic on OK to display
 
89
    # the data for the form (in the console). Then copy the data in the list at the end of
 
90
    # this file in init_item_list
 
91
    # Set self.editing_mode = None to forbid drawing in the right area
 
92
    self.editing_mode = None
 
93
    #self.editing_mode = 1
 
94
 
 
95
 
 
96
  def start(self):
 
97
    self.gcomprisBoard.level=1
 
98
    self.gcomprisBoard.maxlevel=1
 
99
    self.gcomprisBoard.sublevel=1
 
100
    self.gcomprisBoard.number_of_sublevel=1
 
101
 
 
102
    gcompris.bar_set(gcompris.BAR_LEVEL)
 
103
    gcompris.set_default_background(self.gcomprisBoard.canvas.get_root_item())
 
104
    gcompris.bar_set_level(self.gcomprisBoard)
 
105
    gcompris.bar_location(4, -1, 0.6)
 
106
 
 
107
    # Create our rootitem. We put each canvas item in it so at the end we
 
108
    # only have to kill it. The canvas deletes all the items it contains automaticaly.
 
109
    self.rootitem = goocanvas.Group(parent =  self.gcomprisBoard.canvas.get_root_item())
 
110
 
 
111
    item = goocanvas.Image(
 
112
      parent = self.rootitem,
 
113
      pixbuf = gcompris.utils.load_pixmap(self.gcomprisBoard.name + "/" +
 
114
                                          self.gcomprisBoard.icon_name),
 
115
      )
 
116
    bounds = item.get_bounds()
 
117
    scale = 60.0 / (bounds.x2 - bounds.x1)
 
118
    item.scale(scale, scale)
 
119
    item.set_properties(x = (gcompris.BOARD_WIDTH - 65) / scale,
 
120
                        y = 5 / scale)
 
121
 
 
122
    self.draw_tools()
 
123
    self.draw_colors()
 
124
    self.draw_drawing_area(20)
 
125
 
 
126
    self.init_item_list()
 
127
    self.display_current_level()
 
128
 
 
129
    self.pause(0);
 
130
 
 
131
  def end(self):
 
132
    # Remove the root item removes all the others inside it
 
133
    gcompris.set_cursor(gcompris.CURSOR_DEFAULT);
 
134
    self.rootitem.remove()
 
135
    self.root_drawingitem.remove()
 
136
    self.root_targetitem.remove()
 
137
    # Delete error previous mark if any
 
138
    if(self.root_erroritem):
 
139
      self.root_erroritem.remove()
 
140
 
 
141
 
 
142
 
 
143
  def pause(self, pause):
 
144
 
 
145
    self.board_paused = pause
 
146
 
 
147
    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
 
148
    # the game is won
 
149
    if(self.gamewon == 1 and pause == 0):
 
150
      self.root_targetitem.props.visibility = goocanvas.ITEM_VISIBLE
 
151
      self.gamewon = 0
 
152
 
 
153
    return
 
154
 
 
155
 
 
156
  def ok(self):
 
157
    # Save a copy of the target drawing future comparison
 
158
    target  = list(self.image_target)
 
159
    target2 = list(self.image_target)
 
160
 
 
161
    # Save a copy of the drawing cause we need to remove empty items
 
162
    source = list(self.current_drawing)
 
163
 
 
164
    # Remove all empty items
 
165
    while 1:
 
166
      try:
 
167
        source.remove ([])
 
168
      except:
 
169
        break
 
170
 
 
171
    if self.editing_mode != None :
 
172
      print("To add item in this activity, Copy the following data in init_item_list in redraw.py (near the end)")
 
173
      print("-------------------------------------------------------------------------------")
 
174
      print source
 
175
      print("-------------------------------------------------------------------------------")
 
176
 
 
177
    # Need to check if target image equals drawing image
 
178
    for i in source:
 
179
      for j in target:
 
180
        if i == j:
 
181
          target.remove(j)
 
182
 
 
183
    for i in target2:
 
184
      for j in source:
 
185
        if i == j:
 
186
          source.remove(j)
 
187
 
 
188
    if(len(target) == 0 and len(source) == 0):
 
189
      # This is a WIN
 
190
      self.erase_drawing_area()
 
191
      self.increment_level()
 
192
      self.gamewon = 1
 
193
      gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.FLOWER)
 
194
      self.display_current_level()
 
195
      self.root_targetitem.props.visibility = goocanvas.ITEM_INVISIBLE
 
196
 
 
197
    else:
 
198
      # Delete previous mark if any
 
199
      if(self.root_erroritem):
 
200
        self.root_erroritem.remove()
 
201
 
 
202
      # Create our rootitem for error items mark
 
203
      self.root_erroritem = goocanvas.Group(
 
204
        parent = self.gcomprisBoard.canvas.get_root_item())
 
205
 
 
206
      self.display_error(target, 1)
 
207
      self.display_error(source, 0)
 
208
 
 
209
 
 
210
  # display where there is errors
 
211
  # if in_target is set then error are displayed in the target area
 
212
  def display_error(self, target, in_target):
 
213
 
 
214
    # Bad Icon Width and Height / 2
 
215
    icw=8
 
216
    ich=8
 
217
 
 
218
    if self.gcomprisBoard.mode == 'symmetrical' and in_target:
 
219
      target = self.get_symmetry(target)
 
220
 
 
221
    # The images target are always drawn on the drawing area to ease the final comparison
 
222
    if in_target:
 
223
      xofset = self.target_area[0] - self.drawing_area[0]
 
224
    else:
 
225
      xofset = 0
 
226
 
 
227
    for t in target:
 
228
      if(t.has_key('points')):
 
229
        goocanvas.Image(
 
230
          parent = self.root_erroritem,
 
231
          pixbuf = gcompris.utils.load_pixmap("redraw/mini_bad.png"),
 
232
          x = t['points'][0] + (t['points'][2]-t['points'][0])/2 - icw + xofset,
 
233
          y = t['points'][1] + (t['points'][3]-t['points'][1])/2 -ich
 
234
          )
 
235
      elif(t.has_key('width')):
 
236
        goocanvas.Image(
 
237
          parent = self.root_erroritem,
 
238
          pixbuf = gcompris.utils.load_pixmap("redraw/mini_bad.png"),
 
239
          x = t['x'] + t['width']/2 - icw + xofset,
 
240
          y = t['y'] + t['height']/2 - ich
 
241
          )
 
242
      elif(t.has_key('radius_x')):
 
243
        goocanvas.Image(
 
244
          parent = self.root_erroritem,
 
245
          pixbuf = gcompris.utils.load_pixmap("redraw/mini_bad.png"),
 
246
          x = t['center_x'] -icw + xofset,
 
247
          y = t['center_y'] -ich
 
248
          )
 
249
 
 
250
 
 
251
  # Called by gcompris when the user click on the level icon
 
252
  def set_level(self, level):
 
253
    self.gcomprisBoard.level=level;
 
254
    self.gcomprisBoard.sublevel=1;
 
255
 
 
256
    self.erase_drawing_area()
 
257
    self.display_current_level()
 
258
 
 
259
  def repeat(self):
 
260
    pass
 
261
 
 
262
 
 
263
  def config(self):
 
264
    pass
 
265
 
 
266
  def key_press(self, keyval, commit_str, preedit_str):
 
267
    return False
 
268
 
 
269
  # Erase any displayed items (drawing and target)
 
270
  def erase_drawing_area(self):
 
271
    self.root_targetitem.remove()
 
272
    self.root_drawingitem.remove()
 
273
    if(self.root_erroritem):
 
274
      self.root_erroritem.remove()
 
275
 
 
276
  # Display the current level target
 
277
  def display_current_level(self):
 
278
    # Calc the index in drawlist
 
279
    i = (self.gcomprisBoard.level-1) * self.gcomprisBoard.number_of_sublevel+ \
 
280
        (self.gcomprisBoard.sublevel-1)
 
281
 
 
282
    if(i >= len(self.drawlist)):
 
283
      # Wrap to the first level when completed
 
284
      i = 0
 
285
 
 
286
    # Set the level in the control bar
 
287
    gcompris.bar_set_level(self.gcomprisBoard);
 
288
 
 
289
    self.draw_image_target(self.drawlist[i])
 
290
 
 
291
    self.display_sublevel()
 
292
 
 
293
    # Prepare an item for the coord display
 
294
    self.coorditem = goocanvas.Text(
 
295
      parent = self.root_targetitem,
 
296
      font = gcompris.skin.get_font("gcompris/content"),
 
297
      x = gcompris.BOARD_WIDTH / 2,
 
298
      y = gcompris.BOARD_HEIGHT - 20,
 
299
      fill_color_rgba = 0x000000FFL,
 
300
      anchor = gtk.ANCHOR_NE
 
301
      )
 
302
 
 
303
    # Create our rootitem for drawing items
 
304
    self.root_drawingitem = goocanvas.Group(
 
305
      parent = self.gcomprisBoard.canvas.get_root_item())
 
306
 
 
307
    # Reset the drawing
 
308
    self.current_drawing = []
 
309
 
 
310
  # Code that increments the sublevel and level
 
311
  # And stays at the last level
 
312
  def increment_level(self):
 
313
    self.gcomprisBoard.sublevel += 1
 
314
 
 
315
    if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
 
316
      # Try the next level
 
317
      self.gcomprisBoard.sublevel=1
 
318
      self.gcomprisBoard.level += 1
 
319
      if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel) or self.gcomprisBoard.level*self.gcomprisBoard.sublevel>=len(self.drawlist):
 
320
        self.gcomprisBoard.level = self.gcomprisBoard.maxlevel
 
321
 
 
322
 
 
323
  # display current/sublevel number
 
324
  def display_sublevel(self):
 
325
 
 
326
    goocanvas.Text(
 
327
      parent = self.root_targetitem,
 
328
      text = _("Level") + " " + str(self.gcomprisBoard.sublevel) + "/" \
 
329
        + str(self.gcomprisBoard.number_of_sublevel),
 
330
      font = gcompris.skin.get_font("gcompris/content"),
 
331
      x = gcompris.BOARD_WIDTH - 10,
 
332
      y = gcompris.BOARD_HEIGHT - 20,
 
333
      fill_color_rgba = 0x000000FFL,
 
334
      anchor = gtk.ANCHOR_NE
 
335
      )
 
336
 
 
337
  # Display the tools
 
338
  def draw_tools(self):
 
339
 
 
340
    goocanvas.Image(
 
341
      parent = self.rootitem,
 
342
      pixbuf = gcompris.utils.load_pixmap("anim/tool-selector.png"),
 
343
      x=5,
 
344
      y=5.0,
 
345
      width=30.0
 
346
      )
 
347
 
 
348
    x1=11.0
 
349
    x2=56.0
 
350
    y=30.0
 
351
    stepy=45
 
352
 
 
353
    # Display the tools
 
354
    for i in range(0,len(self.tools)):
 
355
      if(i%2 == 0):
 
356
        theX = x2
 
357
      else:
 
358
        theX = x1
 
359
 
 
360
      item = goocanvas.Image(
 
361
        parent = self.rootitem,
 
362
        pixbuf = gcompris.utils.load_pixmap(self.tools[i][1]),
 
363
        x = theX,
 
364
        y = y
 
365
        )
 
366
      item.connect("button_press_event", self.tool_item_event, i)
 
367
      if i%2:
 
368
        y += stepy
 
369
 
 
370
    # The last item is select, we select it by default
 
371
    self.current_tool = i
 
372
    self.old_tool_item = item
 
373
    self.old_tool_item.props.pixbuf = gcompris.utils.load_pixmap(self.tools[i][2])
 
374
    gcompris.set_cursor(self.tools[i][3]);
 
375
 
 
376
    # The OK Button
 
377
    item = goocanvas.Svg(parent = self.rootitem,
 
378
                         svg_handle = gcompris.skin.svg_get(),
 
379
                         svg_id = "#OK"
 
380
                         )
 
381
    item.translate(item.get_bounds().x1 * -1
 
382
                   + 20,
 
383
                   item.get_bounds().y1 * -1
 
384
                   + gcompris.BOARD_HEIGHT - 100)
 
385
 
 
386
    item.connect("button_press_event", self.ok_event)
 
387
    gcompris.utils.item_focus_init(item, None)
 
388
 
 
389
    gcompris.bar_set_level(self.gcomprisBoard)
 
390
 
 
391
 
 
392
  # Event when a tool is selected
 
393
  def tool_item_event(self, item, target, event, tool):
 
394
    if event.type == gtk.gdk.BUTTON_PRESS:
 
395
      if event.button == 1:
 
396
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
397
        # Deactivate old button
 
398
        self.old_tool_item.props.pixbuf = gcompris.utils.load_pixmap(self.tools[self.current_tool][1])
 
399
 
 
400
        # Activate new button
 
401
        self.current_tool = tool
 
402
        self.old_tool_item = item
 
403
        self.old_tool_item.props.pixbuf = gcompris.utils.load_pixmap(self.tools[self.current_tool][2])
 
404
        gcompris.set_cursor(self.tools[self.current_tool][3]);
 
405
 
 
406
  # Display the color selector
 
407
  def draw_colors(self):
 
408
 
 
409
    x1=13.0
 
410
    x2=59.0
 
411
    y=230.0
 
412
    stepy=45
 
413
 
 
414
    # Display the tools
 
415
    for i in range(0,len(self.colors)):
 
416
      if(i%2):
 
417
        theX = x2
 
418
      else:
 
419
        theX = x1
 
420
 
 
421
      item = goocanvas.Rect(
 
422
        parent = self.rootitem,
 
423
        fill_color_rgba = self.colors[i] | self.color_stroke,
 
424
        x=theX,
 
425
        y=y,
 
426
        width=30,
 
427
        height=30,
 
428
        line_width=0.0,
 
429
        stroke_color_rgba= 0x144B9DFFL
 
430
        )
 
431
      item.connect("button_press_event", self.color_item_event, i)
 
432
      if i%2:
 
433
        y += stepy
 
434
 
 
435
    # The last item is the one we select by default
 
436
    self.current_color = i
 
437
    self.old_color_item = item
 
438
    self.old_color_item.props.line_width = 4.0
 
439
    self.old_color_item.props.stroke_color_rgba = 0x16EC3DFFL
 
440
 
 
441
  # Color event
 
442
  def color_item_event(self, item, target, event, color):
 
443
    if event.type == gtk.gdk.BUTTON_PRESS:
 
444
      if event.button == 1:
 
445
        gcompris.sound.play_ogg("sounds/drip.wav")
 
446
        # Deactivate old button
 
447
        self.old_color_item.props.line_width = 0.0
 
448
        self.old_color_item.props.stroke_color_rgba = 0x144B9DFFL
 
449
 
 
450
        # Activate new button
 
451
        self.current_color = color
 
452
        self.old_color_item = item
 
453
        self.old_color_item.props.line_width = 4.0
 
454
        self.old_color_item.props.stroke_color_rgba= 0x16EC3DFFL
 
455
 
 
456
 
 
457
  # Display the drawing area
 
458
  def draw_drawing_area(self, step):
 
459
 
 
460
    self.current_step = step
 
461
 
 
462
    x1=self.drawing_area[0]
 
463
    y1=self.drawing_area[1]
 
464
    x2=self.drawing_area[2]
 
465
    y2=self.drawing_area[3]
 
466
 
 
467
    item = goocanvas.Rect(
 
468
      parent = self.rootitem,
 
469
      x = x1,
 
470
      y = y1,
 
471
      width = x2 - x1,
 
472
      height = y2 - y1,
 
473
      fill_color_rgba = 0xF0F0F0FFL,
 
474
      line_width = 2.0,
 
475
      stroke_color_rgba = 0x111199FFL
 
476
      )
 
477
    item.connect("button_press_event", self.create_item_event)
 
478
    item.connect("button_release_event", self.create_item_event)
 
479
    item.connect("motion_notify_event", self.create_item_event)
 
480
    item.connect("leave_notify_event", self.target_item_event)
 
481
 
 
482
    self.draw_grid(x1,x2,y1,y2,step)
 
483
 
 
484
    x1=self.target_area[0]
 
485
    y1=self.target_area[1]
 
486
    x2=self.target_area[2]
 
487
    y2=self.target_area[3]
 
488
 
 
489
    item =goocanvas.Rect(
 
490
      parent = self.rootitem,
 
491
      x=x1,
 
492
      y=y1,
 
493
      width=x2-x1,
 
494
      height=y2-y1,
 
495
      fill_color_rgba=0xF0F0F0FFL,
 
496
      line_width=2.0,
 
497
      stroke_color_rgba=0x111199FFL
 
498
      )
 
499
    item.connect("motion_notify_event", self.target_item_event)
 
500
    item.connect("leave_notify_event", self.target_item_event)
 
501
 
 
502
    self.draw_grid(x1,x2,y1,y2,step)
 
503
 
 
504
    #
 
505
    # Given coord are returned swapped
 
506
    # Work fine for rect and ellipse but not line
 
507
    # so that y2 > y1 and x2 > x1
 
508
    #
 
509
  def reorder_coord(self, x1, y1, x2, y2):
 
510
    p = [x1, y1, x2, y2]
 
511
    if(x1>x2):
 
512
      p[0] = x2
 
513
      p[2] = x1
 
514
    if(y1>y2):
 
515
      p[1] = y2
 
516
      p[3] = y1
 
517
    return p
 
518
 
 
519
 
 
520
  #
 
521
  # Take a drawing and return a symmetrical one
 
522
  #
 
523
  def get_symmetry(self, drawing_source):
 
524
    # Make a deepcopy of the list
 
525
    drawing  = copy.deepcopy(drawing_source)
 
526
 
 
527
    xofset = 0
 
528
 
 
529
    for item in drawing:
 
530
 
 
531
      for k, v in item.items():
 
532
 
 
533
        if k == 'points' :
 
534
          item[k] = (self.drawing_area[2] - (v[0] - self.drawing_area[0])+xofset, v[1],
 
535
                     self.drawing_area[2] - (v[2] - self.drawing_area[0])+xofset, v[3])
 
536
        elif k == 'x':
 
537
          item[k] = self.drawing_area[2] - (v - self.drawing_area[0])  + xofset - item['width']
 
538
        elif k == 'center_x':
 
539
          item[k] = self.drawing_area[2] - (v - self.drawing_area[0])  + xofset
 
540
 
 
541
    return drawing
 
542
 
 
543
  # Draw the image target
 
544
  # depending on self.gcomprisBoard.level drawing is 'normal' or 'symmetric'
 
545
  #
 
546
  def draw_image_target(self, drawing):
 
547
 
 
548
    # Save the drawing in image_target for future comparison
 
549
    self.image_target = drawing
 
550
 
 
551
    # Create our rootitem for target items
 
552
    self.root_targetitem = goocanvas.Group(
 
553
      parent = self.gcomprisBoard.canvas.get_root_item())
 
554
 
 
555
    if self.gcomprisBoard.mode == 'symmetrical':
 
556
      drawing = self.get_symmetry(drawing)
 
557
 
 
558
    # The images target are always drawn on the drawing area to ease the final comparison
 
559
    xofset = self.target_area[0] - self.drawing_area[0]
 
560
    for i in drawing:
 
561
      #
 
562
      # Can specify the item type to draw via a real GTK type or a TOOL string
 
563
      if(i.has_key('type')):
 
564
        item =  i['type']();
 
565
        self.root_targetitem.add_child (item, -1)
 
566
        item.connect("motion_notify_event", self.target_item_event)
 
567
 
 
568
      elif(i.has_key('tool')):
 
569
        if(i['tool'] == "RECT"):
 
570
          item =  goocanvas.Rect();
 
571
          self.root_targetitem.add_child (item, -1)
 
572
        elif(i['tool'] == "FILL_RECT"):
 
573
          item =  goocanvas.Rect();
 
574
          self.root_targetitem.add_child (item, -1)
 
575
        elif(i['tool'] == "CIRCLE"):
 
576
          item =  goocanvas.Ellipse();
 
577
          self.root_targetitem.add_child (item, -1)
 
578
        elif(i['tool'] == "FILL_CIRCLE"):
 
579
          item =  goocanvas.Ellipse();
 
580
          self.root_targetitem.add_child (item, -1)
 
581
        elif(i['tool'] == "LINE"):
 
582
          item =  goocanvas.Polyline();
 
583
          self.root_targetitem.add_child (item, -1)
 
584
        else:
 
585
          print ("ERROR: incorrect type in draw_image_target", i)
 
586
        item.connect("motion_notify_event", self.target_item_event)
 
587
 
 
588
      for k, v in i.items():
 
589
        if k == 'fill_color' :
 
590
          item.props.fill_color = v
 
591
        elif k == 'fill_color_rgba' :
 
592
          item.props.fill_color_rgba = v
 
593
        elif k == 'height' :
 
594
          item.props.height = v
 
595
        elif k == 'stroke_color' :
 
596
          item.props.stroke_color = v
 
597
        elif k == 'stroke_color_rgba' :
 
598
          item.props.stroke_color_rgba = v
 
599
        elif k == 'points' :
 
600
          item.props.points = goocanvas.Points([(v[0]+xofset, v[1]),
 
601
                                                (v[2]+xofset, v[3])])
 
602
        elif k == 'line_width' :
 
603
          item.props.line_width = v
 
604
        elif k == 'width_pixels' :
 
605
          item.props.width_pixels = v
 
606
        elif k == 'width' :
 
607
          item.props.width = v
 
608
        elif k == 'x' :
 
609
          item.props.x = v + xofset
 
610
        elif k == 'y' :
 
611
          item.props.y = v
 
612
        elif k == 'center_x' :
 
613
          item.props.center_x = v + xofset
 
614
        elif k == 'center_y' :
 
615
          item.props.center_y = v
 
616
        elif k == 'radius_x' :
 
617
          item.props.radius_x = v
 
618
        elif k == 'radius_y' :
 
619
          item.props.radius_y = v
 
620
 
 
621
  #
 
622
  # Draw the grid
 
623
  #
 
624
  def draw_grid(self, x1, x2, y1, y2, step):
 
625
 
 
626
    # Coord of the written numbers
 
627
    if(x1<self.target_area[0]):
 
628
      x_text = x1 - 25
 
629
    else:
 
630
      x_text = x2 + 5
 
631
 
 
632
    y_text = y1 - 15
 
633
 
 
634
    # We manage a 2 colors grid
 
635
    ci = 0
 
636
    ca = 0x1D0DFFFFL
 
637
    cb = 0xEEAAAAFFL
 
638
 
 
639
    for i in range(int(x1), int(x2), int(step)):
 
640
      if(ci%2):
 
641
        color = ca
 
642
      else:
 
643
        color = cb
 
644
      ci += 1
 
645
 
 
646
      item = goocanvas.Polyline(
 
647
        parent = self.rootitem,
 
648
        points = goocanvas.Points([(i , y1), (i , y2)]),
 
649
        stroke_color_rgba = color,
 
650
        line_width = 1.0,
 
651
        )
 
652
      # Text number
 
653
      goocanvas.Text(
 
654
        parent = self.rootitem,
 
655
        text = int((i-x1) / step),
 
656
        font = gcompris.skin.get_font("gcompris/board/tiny"),
 
657
        x = i,
 
658
        y = y_text,
 
659
        fill_color_rgba = 0x000000FFL
 
660
        )
 
661
 
 
662
      # Clicking on lines let you create object
 
663
      if(x1<self.target_area[0]):
 
664
        item.connect("button_press_event", self.create_item_event)
 
665
        item.connect("button_release_event", self.create_item_event)
 
666
        item.connect("motion_notify_event", self.create_item_event)
 
667
      else:
 
668
        item.connect("motion_notify_event", self.target_item_event)
 
669
 
 
670
    for i in range(int(y1), int(y2), int(step)):
 
671
      if(ci%2):
 
672
        color = ca
 
673
      else:
 
674
        color = cb
 
675
      ci += 1
 
676
 
 
677
      item = goocanvas.Polyline(
 
678
        parent = self.rootitem,
 
679
        points = goocanvas.Points([(x1, i), (x2 , i)]),
 
680
        stroke_color_rgba = color,
 
681
        line_width = 1.0,
 
682
        )
 
683
 
 
684
      # Text number
 
685
      goocanvas.Text(
 
686
        parent = self.rootitem,
 
687
        text = int((i-y1) / step),
 
688
        font = gcompris.skin.get_font("gcompris/board/tiny"),
 
689
        x = x_text,
 
690
        y = i,
 
691
        fill_color_rgba=0x000000FFL
 
692
        )
 
693
 
 
694
      # Clicking on lines let you create object
 
695
      if(x1<self.target_area[0]):
 
696
        item.connect("button_press_event", self.create_item_event)
 
697
        item.connect("button_release_event", self.create_item_event)
 
698
        item.connect("motion_notify_event", self.create_item_event)
 
699
 
 
700
  # Given x,y return a new x,y snapped to the grid
 
701
  def snap_to_grid(self, x, y):
 
702
    result = []
 
703
    tmp = round(((x+(self.current_step)) -
 
704
               self.drawing_area[0])/self.current_step) - 1
 
705
    result.append(float(self.drawing_area[0] + tmp*self.current_step))
 
706
 
 
707
    tmp = round(((y+(self.current_step)) -
 
708
               self.drawing_area[1])/self.current_step) - 1
 
709
    result.append(float(self.drawing_area[1] + tmp*self.current_step))
 
710
    return result
 
711
 
 
712
 
 
713
  # Event when a click on any item. Perform the move
 
714
  def move_item_event(self, item, target, event, item_index):
 
715
 
 
716
    if self.tools[self.current_tool][0] != "SELECT":
 
717
      return False
 
718
 
 
719
    if (event.type == gtk.gdk.BUTTON_PRESS
 
720
        and event.button == 1):
 
721
      gcompris.sound.play_ogg("sounds/smudge.wav")
 
722
 
 
723
      x = event.x
 
724
      y = event.y
 
725
 
 
726
      # Save the ofset between the mouse pointer and the
 
727
      # upper left corner of the object
 
728
      if(self.current_drawing[item_index].has_key('center_x')):
 
729
        self.in_select_ofx = x - self.current_drawing[item_index]['center_x']
 
730
        self.in_select_ofy = y - self.current_drawing[item_index]['center_y']
 
731
      else:
 
732
        bounds = item.get_bounds()
 
733
        self.in_select_ofx = x - bounds.x1
 
734
        self.in_select_ofy = y - bounds.y1
 
735
 
 
736
      return True
 
737
 
 
738
    if event.type == gtk.gdk.BUTTON_RELEASE:
 
739
      if event.button == 1:
 
740
        gcompris.sound.play_ogg("sounds/smudge.wav")
 
741
        return True
 
742
 
 
743
    if event.state & gtk.gdk.BUTTON1_MASK:
 
744
      x = event.x
 
745
      y = event.y
 
746
 
 
747
      # Workaround for bad line positionning
 
748
      if(self.current_drawing[item_index].has_key('points')):
 
749
        item.props.line_width = 1.0
 
750
 
 
751
      bounds = item.get_bounds()
 
752
 
 
753
      if(self.current_drawing[item_index].has_key('center_x')):
 
754
        x = x - self.in_select_ofx - item.props.radius_x
 
755
        y = y - self.in_select_ofy - item.props.radius_y
 
756
      else:
 
757
        x -= self.in_select_ofx
 
758
        y -= self.in_select_ofy
 
759
 
 
760
      x,y = self.snap_to_grid(x,y)
 
761
 
 
762
      # Check drawing boundaries
 
763
      if(x < self.drawing_area[0]):
 
764
        x = self.drawing_area[0]
 
765
      if(x > (self.drawing_area[2]-(bounds.x2-bounds.x1))):
 
766
        x = self.drawing_area[2]-(bounds.x2-bounds.x1)
 
767
        # We need to realign x cause the bounds values are not precise enough
 
768
        x,n = self.snap_to_grid(x,y)
 
769
      if(y < self.drawing_area[1]):
 
770
        y = self.drawing_area[1]
 
771
      if(y > (self.drawing_area[3]-(bounds.y2-bounds.y1))):
 
772
        y = self.drawing_area[3]-(bounds.y2-bounds.y1)
 
773
        # We need to realign y cause the bounds values are not precise enough
 
774
        n,y = self.snap_to_grid(x,y)
 
775
 
 
776
      # Need to update current_drawing
 
777
      if(self.current_drawing[item_index].has_key('center_x')):
 
778
        new_x = x + item.props.radius_x
 
779
        new_y = y + item.props.radius_y
 
780
        self.current_drawing[item_index]['center_x'] = new_x
 
781
        self.current_drawing[item_index]['center_y'] = new_y
 
782
        item.props.center_x = new_x
 
783
        item.props.center_y = new_y
 
784
      elif(self.current_drawing[item_index].has_key('x')):
 
785
        # It's a rectangle
 
786
        ox = x - self.current_drawing[item_index]['x']
 
787
        oy = y - self.current_drawing[item_index]['y']
 
788
        self.current_drawing[item_index]['x'] += ox
 
789
        self.current_drawing[item_index]['y'] += oy
 
790
        item.props.x += ox
 
791
        item.props.y += oy
 
792
      else:
 
793
        # It can only be a line
 
794
        ox = x - min(self.current_drawing[item_index]['points'][0], self.current_drawing[item_index]['points'][2])
 
795
        oy = y - min(self.current_drawing[item_index]['points'][1], self.current_drawing[item_index]['points'][3])
 
796
        nx1 = self.current_drawing[item_index]['points'][0] + ox
 
797
        ny1 = self.current_drawing[item_index]['points'][1] + oy
 
798
        nx2 = self.current_drawing[item_index]['points'][2] + ox
 
799
        ny2 = self.current_drawing[item_index]['points'][3] + oy
 
800
        self.current_drawing[item_index]['points'] = (nx1, ny1, nx2, ny2)
 
801
        item.props.points = goocanvas.Points([(nx1, ny1),
 
802
                                              (nx2, ny2)])
 
803
 
 
804
      # Workaround for bad line positionning
 
805
      if(self.current_drawing[item_index].has_key('points')):
 
806
        item.props.line_width = 8.0
 
807
 
 
808
      return True
 
809
 
 
810
    return False
 
811
 
 
812
  # Event when a click on an item happen on fill in type object
 
813
  def fillin_item_event(self, item, target, event, drawing_item_index):
 
814
    if event.type == gtk.gdk.BUTTON_PRESS:
 
815
      if event.button == 1:
 
816
        if self.tools[self.current_tool][0] == "FILL":
 
817
          item.props.fill_color_rgba = self.colors[self.current_color] | self.color_fill
 
818
          # Reset the item in our list
 
819
          self.current_drawing[drawing_item_index]['fill_color_rgba'] = \
 
820
              self.colors[self.current_color] | self.color_fill
 
821
          gcompris.sound.play_ogg("sounds/paint1.wav")
 
822
          return True
 
823
    return False
 
824
 
 
825
  # Event when a click on an item happen on border fill type object
 
826
  def fillout_item_event(self, item, target, event, drawing_item_index):
 
827
    if event.type == gtk.gdk.BUTTON_PRESS:
 
828
      if event.button == 1:
 
829
        if self.tools[self.current_tool][0] == "FILL":
 
830
          item.props.stroke_color_rgba = self.colors[self.current_color] | self.color_stroke
 
831
          # Reset the item in our list
 
832
          self.current_drawing[drawing_item_index]['stroke_color_rgba'] = \
 
833
              self.colors[self.current_color] | self.color_stroke
 
834
          gcompris.sound.play_ogg("sounds/paint1.wav")
 
835
          return True
 
836
    return False
 
837
 
 
838
  # Del an item and internal struct cleanup
 
839
  def del_item(self, item, drawing_item_index):
 
840
    item.remove()
 
841
    # Warning, do not realy delete it or we bug the index of other items
 
842
    self.current_drawing[drawing_item_index] = []
 
843
 
 
844
  # Event when a click on an item happen
 
845
  def del_item_event(self, item, target, event, drawing_item_index):
 
846
    if (event.button == 1 and self.tools[self.current_tool][0] == "DEL") \
 
847
          or (event.button == 3):
 
848
      self.del_item(item, drawing_item_index);
 
849
      gcompris.sound.play_ogg("sounds/eraser1.wav",
 
850
      "sounds/eraser2.wav")
 
851
      return True
 
852
    return False
 
853
 
 
854
  #
 
855
  # Display the mouse coord in the drawing or target area
 
856
  # type:
 
857
  # 1 = in drawing area
 
858
  # 2 = in target area
 
859
  # 3 = out of both area
 
860
  #
 
861
  def display_coord(self, x, y, type):
 
862
    if(type == 1):
 
863
      xl = self.drawing_area[0]
 
864
    else:
 
865
      xl = self.target_area[0]
 
866
 
 
867
    yl = self.drawing_area[1]
 
868
 
 
869
    x = int(round(((x+(self.current_step/2)) - xl)/self.current_step) - 1)
 
870
    y = int(round(((y+(self.current_step/2)) - yl)/self.current_step) - 1)
 
871
 
 
872
    if(type == 3):
 
873
      self.coorditem.props.text = ""
 
874
    else:
 
875
      self.coorditem.props.text = _("Coordinate") + " = (" + str(x) + "/" + str(y) + ")"
 
876
 
 
877
 
 
878
  # Event when an event on the target area happen
 
879
  def target_item_event(self, item, target, event):
 
880
 
 
881
    if event.type == gtk.gdk.LEAVE_NOTIFY:
 
882
      self.display_coord(event.x,event.y, 3)
 
883
    else:
 
884
      self.display_coord(event.x,event.y, 2)
 
885
 
 
886
 
 
887
  # Event when an event on the drawing area happen
 
888
  def create_item_event(self, item, target, event):
 
889
 
 
890
    if event.type == gtk.gdk.LEAVE_NOTIFY:
 
891
      self.display_coord(event.x,event.y, 3)
 
892
    else:
 
893
      self.display_coord(event.x, event.y, 1)
 
894
 
 
895
 
 
896
    if event.type == gtk.gdk.BUTTON_PRESS:
 
897
      # Delete error previous mark if any
 
898
      if(self.root_erroritem):
 
899
        self.root_erroritem.remove()
 
900
 
 
901
      if event.button != 1:
 
902
        return False
 
903
 
 
904
      self.newitem = None
 
905
 
 
906
      if (self.tools[self.current_tool][0] == "DEL" or
 
907
          self.tools[self.current_tool][0] == "SELECT" or
 
908
          self.tools[self.current_tool][0] == "FILL"):
 
909
        # This event is treated in del_item_event to avoid
 
910
        # operating on background item and grid
 
911
        return False
 
912
 
 
913
      elif self.tools[self.current_tool][0] == "LINE":
 
914
 
 
915
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
916
 
 
917
        x,y = self.snap_to_grid(event.x,event.y)
 
918
        self.pos_x = x
 
919
        self.pos_y = y
 
920
 
 
921
        self.newitem = goocanvas.Polyline(
 
922
          parent = self.root_drawingitem,
 
923
          points = goocanvas.Points([(self.pos_x, self.pos_y),
 
924
                                     (x, y)]),
 
925
          stroke_color_rgba = self.colors[self.current_color] | self.color_stroke,
 
926
          line_width = 8.0
 
927
          )
 
928
        self.newitem.connect("button_press_event",
 
929
                             self.fillout_item_event, len(self.current_drawing))
 
930
        self.newitem.connect("button_press_event",
 
931
                             self.move_item_event, len(self.current_drawing))
 
932
        self.newitem.connect("button_release_event",
 
933
                             self.move_item_event, len(self.current_drawing))
 
934
        self.newitem.connect("motion_notify_event",
 
935
                             self.move_item_event, len(self.current_drawing))
 
936
 
 
937
        # Add the new item in our list
 
938
        self.current_drawing.append({'tool': self.tools[self.current_tool][0],
 
939
                                     'points':(self.pos_x, self.pos_y, x, y),
 
940
                                     'stroke_color_rgba' : self.colors[self.current_color] | self.color_stroke,
 
941
                                     'line_width':8.0})
 
942
 
 
943
      elif self.tools[self.current_tool][0] == "RECT":
 
944
 
 
945
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
946
 
 
947
        x,y = self.snap_to_grid(event.x,event.y)
 
948
        self.pos_x = x
 
949
        self.pos_y = y
 
950
 
 
951
        self.newitem =goocanvas.Rect(
 
952
          parent = self.root_drawingitem,
 
953
          x=self.pos_x,
 
954
          y=self.pos_y,
 
955
          width=0,
 
956
          height=0,
 
957
          stroke_color_rgba = self.colors[self.current_color] | self.color_stroke,
 
958
          line_width=4.0
 
959
          )
 
960
        self.newitem.connect("button_press_event",
 
961
                             self.fillout_item_event, len(self.current_drawing))
 
962
        self.newitem.connect("button_press_event",
 
963
                             self.move_item_event, len(self.current_drawing))
 
964
        self.newitem.connect("button_release_event",
 
965
                             self.move_item_event, len(self.current_drawing))
 
966
        self.newitem.connect("motion_notify_event",
 
967
                             self.move_item_event, len(self.current_drawing))
 
968
 
 
969
        # Add the new item in our list
 
970
        self.current_drawing.append({'tool': self.tools[self.current_tool][0],
 
971
                                     'x':self.pos_x,
 
972
                                     'y':self.pos_y,
 
973
                                     'width':x,
 
974
                                     'height':y,
 
975
                                     'stroke_color_rgba':self.colors[self.current_color] | self.color_stroke,
 
976
                                     'line_width':4.0})
 
977
 
 
978
      elif self.tools[self.current_tool][0] == "FILL_RECT":
 
979
 
 
980
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
981
 
 
982
        x,y = self.snap_to_grid(event.x,event.y)
 
983
        self.pos_x = x
 
984
        self.pos_y = y
 
985
 
 
986
        self.newitem = goocanvas.Rect(
 
987
          parent = self.root_drawingitem,
 
988
          x = self.pos_x,
 
989
          y = self.pos_y,
 
990
          width = 0,
 
991
          height = 0,
 
992
          fill_color_rgba = self.colors[self.current_color] | self.color_fill,
 
993
          stroke_color_rgba = 0x000000FFL,
 
994
          line_width = 1.0
 
995
          )
 
996
        self.newitem.connect("button_press_event",
 
997
                             self.fillin_item_event, len(self.current_drawing))
 
998
        self.newitem.connect("button_press_event",
 
999
                             self.move_item_event, len(self.current_drawing))
 
1000
        self.newitem.connect("button_release_event",
 
1001
                             self.move_item_event, len(self.current_drawing))
 
1002
        self.newitem.connect("motion_notify_event",
 
1003
                             self.move_item_event, len(self.current_drawing))
 
1004
 
 
1005
        # Add the new item in our list
 
1006
        self.current_drawing.append({'tool': self.tools[self.current_tool][0],
 
1007
                                     'x':self.pos_x,
 
1008
                                     'y':self.pos_y,
 
1009
                                     'width':0,
 
1010
                                     'height':0,
 
1011
                                     'fill_color_rgba':self.colors[self.current_color] | self.color_fill,
 
1012
                                     'stroke_color_rgba':0x000000FFL,
 
1013
                                     'line_width':1.0})
 
1014
 
 
1015
      elif self.tools[self.current_tool][0] == "CIRCLE":
 
1016
 
 
1017
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
1018
 
 
1019
        x,y = self.snap_to_grid(event.x,event.y)
 
1020
        self.pos_x = x
 
1021
        self.pos_y = y
 
1022
 
 
1023
        self.newitem = goocanvas.Ellipse(
 
1024
          parent = self.root_drawingitem,
 
1025
          center_x = self.pos_x,
 
1026
          center_y = self.pos_y,
 
1027
          radius_x = 0,
 
1028
          radius_y = 0,
 
1029
          stroke_color_rgba = self.colors[self.current_color] | self.color_stroke,
 
1030
          line_width = 5.0
 
1031
          )
 
1032
        self.newitem.connect("button_press_event",
 
1033
                             self.fillout_item_event, len(self.current_drawing))
 
1034
        self.newitem.connect("button_press_event",
 
1035
                             self.move_item_event, len(self.current_drawing))
 
1036
        self.newitem.connect("button_release_event",
 
1037
                             self.move_item_event, len(self.current_drawing))
 
1038
        self.newitem.connect("motion_notify_event",
 
1039
                             self.move_item_event, len(self.current_drawing))
 
1040
 
 
1041
        # Add the new item in our list
 
1042
        self.current_drawing.append({'tool': self.tools[self.current_tool][0],
 
1043
                                     'center_x':self.pos_x,
 
1044
                                     'center_y':self.pos_y,
 
1045
                                     'radius_x':0,
 
1046
                                     'radius_y':0,
 
1047
                                     'stroke_color_rgba':self.colors[self.current_color] | self.color_stroke,
 
1048
                                     'line_width':5.0})
 
1049
 
 
1050
      elif self.tools[self.current_tool][0] == "FILL_CIRCLE":
 
1051
 
 
1052
        gcompris.sound.play_ogg("sounds/bleep.wav")
 
1053
 
 
1054
        x,y = self.snap_to_grid(event.x,event.y)
 
1055
        self.pos_x = x
 
1056
        self.pos_y = y
 
1057
 
 
1058
        self.newitem = goocanvas.Ellipse(
 
1059
          parent = self.root_drawingitem,
 
1060
          center_x = self.pos_x,
 
1061
          center_y = self.pos_y,
 
1062
          radius_x = 0,
 
1063
          radius_y = 0,
 
1064
          fill_color_rgba = self.colors[self.current_color] | self.color_fill,
 
1065
          stroke_color_rgba = 0x000000FFL,
 
1066
          line_width = 1.0
 
1067
          )
 
1068
        self.newitem.connect("button_press_event",
 
1069
                             self.fillin_item_event, len(self.current_drawing))
 
1070
        self.newitem.connect("button_press_event",
 
1071
                             self.move_item_event, len(self.current_drawing))
 
1072
        self.newitem.connect("button_release_event",
 
1073
                             self.move_item_event, len(self.current_drawing))
 
1074
        self.newitem.connect("motion_notify_event",
 
1075
                             self.move_item_event, len(self.current_drawing))
 
1076
 
 
1077
        # Add the new item in our list
 
1078
        self.current_drawing.append({'tool': self.tools[self.current_tool][0],
 
1079
                                     'center_x':self.pos_x,
 
1080
                                     'center_y':self.pos_y,
 
1081
                                     'radius_x':0,
 
1082
                                     'radius_y':0,
 
1083
                                     'fill_color_rgba':self.colors[self.current_color] | self.color_fill,
 
1084
                                     'stroke_color_rgba':0x000000FFL,
 
1085
                                     'line_width':1.0})
 
1086
      if self.newitem != 0:
 
1087
        self.newitem.connect("button_press_event", self.create_item_event)
 
1088
        self.newitem.connect("button_release_event", self.create_item_event)
 
1089
        self.newitem.connect("motion_notify_event", self.create_item_event)
 
1090
        self.newitem.connect("button_press_event", self.del_item_event, len(self.current_drawing)-1)
 
1091
 
 
1092
      return True
 
1093
 
 
1094
    #
 
1095
    # MOTION EVENT
 
1096
    # ------------
 
1097
    if event.type == gtk.gdk.MOTION_NOTIFY:
 
1098
      if event.state & gtk.gdk.BUTTON1_MASK:
 
1099
        x = event.x
 
1100
        y = event.y
 
1101
        x,y = self.snap_to_grid(event.x,event.y)
 
1102
 
 
1103
        # Check drawing boundaries
 
1104
        if(event.x<self.drawing_area[0]):
 
1105
          x = self.drawing_area[0]
 
1106
        if(event.x>self.drawing_area[2]):
 
1107
          x = self.drawing_area[2]
 
1108
        if(event.y<self.drawing_area[1]):
 
1109
          y = self.drawing_area[1]
 
1110
        if(event.y>self.drawing_area[3]):
 
1111
          y = self.drawing_area[3]
 
1112
 
 
1113
        if self.tools[self.current_tool][0] == "LINE":
 
1114
          self.newitem.props.points = goocanvas.Points([(self.pos_x, self.pos_y),
 
1115
                                                        (x, y)])
 
1116
          # Reset the item in our list
 
1117
          self.current_drawing[len(self.current_drawing)-1]['points'] = ( self.pos_x, self.pos_y, x, y)
 
1118
 
 
1119
        elif (self.tools[self.current_tool][0] == "RECT" or
 
1120
              self.tools[self.current_tool][0] == "FILL_RECT"):
 
1121
          if(x - self.pos_x < 0):
 
1122
            self.newitem.props.x = x
 
1123
          else:
 
1124
            self.newitem.props.x = self.pos_x
 
1125
 
 
1126
          if(y - self.pos_y < 0):
 
1127
            self.newitem.props.y = y
 
1128
          else:
 
1129
            self.newitem.props.y = self.pos_y
 
1130
 
 
1131
          self.newitem.props.width = abs(x - self.pos_x)
 
1132
          self.newitem.props.height = abs(y - self.pos_y)
 
1133
 
 
1134
          self.current_drawing[len(self.current_drawing)-1]['x'] = \
 
1135
              self.newitem.props.x
 
1136
          self.current_drawing[len(self.current_drawing)-1]['y'] = \
 
1137
              self.newitem.props.y
 
1138
          self.current_drawing[len(self.current_drawing)-1]['width'] = \
 
1139
              self.newitem.props.width
 
1140
          self.current_drawing[len(self.current_drawing)-1]['height'] = \
 
1141
              self.newitem.props.height
 
1142
 
 
1143
        elif (self.tools[self.current_tool][0] == "CIRCLE" or
 
1144
              self.tools[self.current_tool][0] == "FILL_CIRCLE"):
 
1145
          self.newitem.props.radius_x = abs(x - self.pos_x)/2
 
1146
          self.newitem.props.center_x = self.pos_x + (x - self.pos_x)/2
 
1147
          self.newitem.props.radius_y = abs(y - self.pos_y)/2
 
1148
          self.newitem.props.center_y = self.pos_y + (y - self.pos_y)/2
 
1149
 
 
1150
          self.current_drawing[len(self.current_drawing)-1]['radius_x'] = \
 
1151
              self.newitem.props.radius_x
 
1152
          self.current_drawing[len(self.current_drawing)-1]['center_x'] = \
 
1153
              self.newitem.props.center_x
 
1154
          self.current_drawing[len(self.current_drawing)-1]['radius_y'] = \
 
1155
              self.newitem.props.radius_y
 
1156
          self.current_drawing[len(self.current_drawing)-1]['center_y'] = \
 
1157
              self.newitem.props.center_y
 
1158
 
 
1159
 
 
1160
    #
 
1161
    # MOUSE DRAG STOP
 
1162
    # ---------------
 
1163
    if event.type == gtk.gdk.BUTTON_RELEASE:
 
1164
      if event.button == 1:
 
1165
        # We have to remove empty created items (the kid did not drag enough)
 
1166
        if self.tools[self.current_tool][0] == "LINE":
 
1167
          bounds = self.current_drawing[len(self.current_drawing)-1]['points']
 
1168
          if (bounds[0] == bounds[2]) and (bounds[1] == bounds[3]):
 
1169
            # Oops, empty line
 
1170
            self.del_item(self.newitem, len(self.current_drawing)-1)
 
1171
          else:
 
1172
            gcompris.sound.play_ogg("sounds/line_end.wav")
 
1173
            # We need to reord the coord in increasing order to allow later comparison
 
1174
            # I use a trick, I do x1*x1+y1 and x2*x2+y2, put the lower as the A point
 
1175
            i = bounds[0]*bounds[0] + bounds[1]
 
1176
            j = bounds[2]*bounds[2] + bounds[3]
 
1177
            if(i<=j):
 
1178
              self.current_drawing[len(self.current_drawing)-1]['points'] = (bounds[0], bounds[1],
 
1179
                                                                             bounds[2], bounds[3])
 
1180
            else:
 
1181
              self.current_drawing[len(self.current_drawing)-1]['points'] = (bounds[2], bounds[3],
 
1182
                                                                             bounds[0], bounds[1])
 
1183
 
 
1184
        elif (self.tools[self.current_tool][0] == "RECT" or
 
1185
              self.tools[self.current_tool][0] == "FILL_RECT"):
 
1186
          # It's a rect
 
1187
          width = self.current_drawing[len(self.current_drawing)-1]['width']
 
1188
          height = self.current_drawing[len(self.current_drawing)-1]['height']
 
1189
          if (width == 0) or (height == 0):
 
1190
            # Oups, empty rect
 
1191
            self.del_item(self.newitem, len(self.current_drawing)-1)
 
1192
        elif (self.tools[self.current_tool][0] == "CIRCLE" or
 
1193
              self.tools[self.current_tool][0] == "FILL_CIRCLE"):
 
1194
          # It's an ellipse
 
1195
          radius_x = self.current_drawing[len(self.current_drawing)-1]['radius_x']
 
1196
          radius_y = self.current_drawing[len(self.current_drawing)-1]['radius_y']
 
1197
          if (radius_x == 0) or (radius_y == 0):
 
1198
            # Oups, empty rect
 
1199
            self.del_item(self.newitem, len(self.current_drawing)-1)
 
1200
          else:
 
1201
            gcompris.sound.play_ogg("sounds/line_end.wav")
 
1202
 
 
1203
        return True
 
1204
    return False
 
1205
 
 
1206
 
 
1207
  # The list of items (data) for this game
 
1208
  def init_item_list(self):
 
1209
 
 
1210
    if self.gcomprisBoard.mode == 'normal':
 
1211
      self.drawlist = \
 
1212
                    [
 
1213
        # Two stripes
 
1214
      [{'width': 280.0, 'line_width': 1.0, 'height': 20.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 80.0, 'tool': 'FILL_RECT', 'x': 140.0},
 
1215
       {'width': 280.0, 'line_width': 1.0, 'height': 20.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 420.0, 'tool': 'FILL_RECT', 'x': 140.0}]
 
1216
      ,
 
1217
      # Top centered box
 
1218
      [{'width': 160.0, 'height': 40.0, 'line_width': 1.0, 'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 40.0, 'x': 200.0, 'tool': 'FILL_RECT'}]
 
1219
      ,
 
1220
      # 4 small corners
 
1221
      [{'width': 40.0, 'height': 40.0,  'line_width': 1.0,'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 40.0, 'x': 160.0, 'tool': 'FILL_RECT'},
 
1222
       {'width': 400.0-360.0, 'height': 80.0-40.0,  'line_width': 1.0,'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 40.0, 'x': 360.0, 'tool': 'FILL_RECT'},
 
1223
       {'width': 200.0-160.0, 'height': 480.0-440.0, 'line_width': 1.0, 'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 440.0, 'x': 160.0, 'tool': 'FILL_RECT'},
 
1224
       {'width': 400.0-360.0, 'height': 480.0-440.0,  'line_width': 1.0,'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 440.0, 'x': 360.0, 'tool': 'FILL_RECT'}]
 
1225
      ,
 
1226
      # 4 non filled Rects organised in rect and shifted
 
1227
      [{'width': 200.0-180.0, 'height': 360.0-200.0, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 4.0, 'y': 200.0, 'x': 180.0, 'tool': 'RECT'},
 
1228
       {'width': 340.0-180.0, 'height': 400.0-380.0, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 4.0, 'y':380.0, 'x': 180.0, 'tool': 'RECT'},
 
1229
       {'width': 380.0-360.0, 'height': 400.0-240.0, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 4.0, 'y': 240.0, 'x': 360.0, 'tool': 'RECT'},
 
1230
       {'width': 380.0-220.0, 'height': 220.0-200.0, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 4.0, 'y': 200.0, 'x': 220.0, 'tool': 'RECT'}]
 
1231
      ,
 
1232
      # Letter A
 
1233
      [{'tool': 'LINE', 'points': (200.0, 120.0, 280.0, 120.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1234
       {'tool': 'LINE', 'points': (280.0, 120.0, 280.0,240.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1235
       {'tool': 'LINE', 'points': (200.0, 120.0, 200.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1236
       {'tool': 'LINE', 'points': (200.0, 180.0, 280.0, 180.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1237
      ,
 
1238
      # Letter B
 
1239
      [{'tool': 'LINE', 'points': (240.0, 240.0, 320.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1240
       {'tool': 'LINE', 'points': (300.0, 180.0, 320.0,200.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1241
       {'tool': 'LINE', 'points': (300.0, 180.0, 320.0, 160.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1242
       {'tool': 'LINE', 'points': (240.0, 180.0, 300.0, 180.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1243
       {'tool': 'LINE', 'points': (320.0, 100.0, 320.0, 160.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1244
       {'tool':'LINE', 'points': (240.0, 100.0, 320.0, 100.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1245
       {'tool': 'LINE', 'points': (240.0, 100.0, 240.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1246
       {'tool': 'LINE', 'points': (320.0, 200.0, 320.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1247
      ,
 
1248
      # A door
 
1249
      [{'width': 360.0-200.0, 'height': 360.0-180.0, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 4.0, 'y': 180.0, 'x': 200.0, 'tool': 'RECT'},
 
1250
       {'radius_x': 20, 'radius_y': 20, 'line_width': 1.0, 'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'center_y': 280.0+20, 'center_x': 300.0+20, 'tool': 'FILL_CIRCLE'},
 
1251
       {'width': 320.0-240.0, 'height': 260.0-200.0, 'line_width': 1.0, 'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'y': 200.0, 'x': 240.0, 'tool': 'FILL_RECT'}],
 
1252
      # A top left kind of target
 
1253
      [{'radius_x': 50, 'radius_y': 50, 'stroke_color_rgba': 0x1010FFFFL, 'center_y': 40.0+50, 'center_x': 160.0+50, 'tool': 'CIRCLE', 'line_width': 5.0},
 
1254
       {'radius_x': 30, 'radius_y': 30, 'line_width': 1.0, 'fill_color_rgba': 0x1010FFA0L, 'stroke_color_rgba': 255L, 'center_y': 60.0+30, 'center_x': 180.0+30, 'tool': 'FILL_CIRCLE'}]
 
1255
      ,
 
1256
      # 4 Huge Diagonal lines
 
1257
      [{'tool': 'LINE', 'points': (140.0, 260.0, 260.0, 20.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1258
       {'tool': 'LINE', 'points': (140.0, 260.0, 260.0, 500.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1259
       {'tool': 'LINE', 'points': (260.0, 500.0, 420.0, 260.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1260
       {'tool': 'LINE', 'points': (260.0, 20.0, 420.0, 260.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1261
      ,
 
1262
      # Balloon
 
1263
      [{'tool': 'LINE', 'points': (220.0, 240.0, 220.0, 340.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1264
       {'radius_x': 40, 'line_width': 1.0, 'radius_y': 50, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 140.0+50, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+40},
 
1265
       {'radius_x': 40, 'line_width': 1.0, 'radius_y': 50, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 80.0+50, 'tool': 'FILL_CIRCLE', 'center_x': 300.0+40},
 
1266
       {'tool': 'LINE', 'points': (340.0, 180.0, 340.0, 280.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1267
      ,
 
1268
      # Watch
 
1269
      [{'radius_x': 100, 'radius_y': 100, 'stroke_color_rgba': 0x1010FFFFL, 'line_width': 5.0, 'center_y': 140.0+100, 'tool': 'CIRCLE', 'center_x': 180.0+100},
 
1270
       {'tool': 'LINE', 'points': (280.0, 160.0, 280.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1271
       {'tool': 'LINE', 'points': (280.0, 240.0, 320.0, 200.0), 'line_width': 8.0, 'stroke_color_rgba': 352271359L},
 
1272
       {'tool': 'LINE', 'points': (220.0, 280.0, 280.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 4294905087L}]
 
1273
      ,
 
1274
      # Colored pyramid
 
1275
      [{'width': 280.0-260.0, 'line_width': 1.0, 'height': 120.0-100.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 100.0, 'x': 260.0, 'tool': 'FILL_RECT'},
 
1276
       {'width': 300.0-240.0, 'line_width': 1.0, 'height': 140.0-120.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 120.0,  'x': 240.0, 'tool': 'FILL_RECT'},
 
1277
       {'width': 320.0-220.0, 'line_width': 1.0, 'height': 160.0-140.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 140.0, 'tool': 'FILL_RECT', 'x': 220.0},
 
1278
       {'width': 340.0-200.0, 'line_width': 1.0, 'height': 180.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1279
       {'width': 360.0-180.0, 'line_width': 1.0, 'height': 200.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xC2C2C2A0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 180.0}]
 
1280
      ,
 
1281
      # Colored Rectangle bigger and bigger
 
1282
      [{'width': 180.0-140.0, 'line_width': 1.0, 'height': 60.0-20.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 20.0, 'tool': 'FILL_RECT', 'x': 140.0},
 
1283
       {'width': 240.0-180.0, 'line_width': 1.0, 'height': 120.0-60.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 60.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1284
       {'width': 320.0-240.0, 'line_width': 1.0, 'height': 200.0-120.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 120.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1285
       {'width': 420.0-320.0, 'line_width': 1.0, 'height': 300.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 320.0}]
 
1286
      ,
 
1287
      # Tree
 
1288
      [{'width': 420.0-140.0, 'line_width': 1.0, 'height': 500.0-460.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x000000A0L, 'y': 460.0, 'tool': 'FILL_RECT', 'x': 140.0},
 
1289
       {'width': 260.0-240.0, 'line_width': 1.0, 'height': 460.0-360.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 360.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1290
       {'radius_x': 70, 'line_width': 1.0, 'radius_y': 40, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 280.0+40, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+70}]
 
1291
      ,
 
1292
      # bipbip (big non flying bird)
 
1293
      [{'width': 280.0-260.0, 'line_width': 1.0, 'height': 320.0-120.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 120.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1294
       {'width': 300.0-260.0, 'line_width': 1.0, 'height': 120.0-80.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 80.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1295
       {'width': 320.0-300.0, 'line_width': 1.0, 'height': 120.0-100.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 100.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1296
       {'width': 280.0-200.0, 'line_width': 1.0, 'height': 380.0-320.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 320.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1297
       {'width': 220.0-200.0, 'line_width': 1.0, 'height': 320.0-300.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 300.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1298
       {'width': 260.0-240.0, 'line_width': 1.0, 'height': 460.0-380.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 380.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1299
       {'width': 280.0-260.0, 'line_width': 1.0, 'height': 460.0-440.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 440.0, 'tool': 'FILL_RECT', 'x': 260.0}]
 
1300
      ,
 
1301
      # Dog
 
1302
      [{'width': 180.0-160.0, 'line_width': 1.0, 'height': 200.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 160.0},
 
1303
       {'width': 340.0-180.0, 'line_width': 1.0, 'height': 240.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1304
       {'width': 200.0-180.0, 'line_width': 1.0, 'height': 280.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1305
       {'width': 340.0-320.0,'line_width': 1.0, 'height': 280.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 320.0},
 
1306
       {'width': 380.0-320.0, 'line_width': 1.0, 'height': 200.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 320.0}]
 
1307
      ,
 
1308
      # Fish
 
1309
      [{'radius_x': 90, 'line_width': 1.0, 'radius_y': 60, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'center_y': 160.0+60, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+90},
 
1310
       {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 200.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 320.0+10},
 
1311
       {'width': 180.0-160.0, 'line_width': 1.0, 'height': 260.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 160.0}]
 
1312
      ,
 
1313
      # Balloon (human)
 
1314
      [{'radius_x': 90, 'line_width': 1.0, 'radius_y': 100, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 100.0+100, 'tool': 'FILL_CIRCLE', 'center_x': 200.0+90},
 
1315
       {'radius_x': 50, 'line_width': 1.0, 'radius_y': 30, 'stroke_color_rgba': 255L, 'stroke_color_rgba': 4294905087L, 'center_y': 320.0, 'tool': 'FILL_RECT', 'center_x': 240.0},
 
1316
       {'tool': 'LINE', 'points': (220.0, 260.0, 260.0, 320.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L},
 
1317
       {'tool': 'LINE', 'points': (320.0, 320.0, 360.0, 260.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L}]
 
1318
      ,
 
1319
      # House
 
1320
      [{'width': 360.0-200.0, 'line_width': 1.0, 'height': 340.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1321
       {'width': 280.0-240.0, 'line_width': 1.0, 'height': 340.0-280.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 280.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1322
       {'width': 340.0-300.0, 'line_width': 1.0, 'height': 300.0-260.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 260.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1323
       {'tool': 'LINE', 'points': (200.0, 240.0, 280.0, 160.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L},
 
1324
       {'tool': 'LINE', 'points': (280.0, 160.0, 360.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L}]
 
1325
      ,
 
1326
      # Truck
 
1327
      [{'radius_x': 20, 'line_width': 1.0, 'radius_y': 20, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 240.0+20, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+20},
 
1328
       {'radius_x': 20, 'line_width': 1.0, 'radius_y': 20, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 240.0+20, 'tool': 'FILL_CIRCLE', 'center_x': 280.0+20},
 
1329
       {'width': 220.0-160.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 160.0},
 
1330
       {'width': 300.0-220.0, 'line_width': 1.0, 'height': 260.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 220.0},
 
1331
       {'width': 320.0-300.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1332
       {'width': 280.0-240.0, 'line_width': 1.0, 'height': 260.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 240.0}]
 
1333
      ,
 
1334
      # Fire truck
 
1335
      [{'radius_x': 20, 'line_width': 1.0, 'radius_y': 20, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 260.0+20, 'tool': 'FILL_CIRCLE', 'center_x': 160.0+20},
 
1336
       {'radius_x': 20, 'line_width': 1.0, 'radius_y': 20, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 260.0+20, 'tool': 'FILL_CIRCLE', 'center_x': 320.0+20},
 
1337
       {'width': 380.0-160.0, 'line_width': 1.0, 'height': 280.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 160.0},
 
1338
       {'tool': 'LINE', 'points': (160.0, 200.0, 340.0, 180.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1339
       {'width': 200.0-180.0, 'line_width': 1.0, 'height': 220.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1340
       {'width': 360.0-320.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 320.0},
 
1341
       {'width': 300.0-280.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 280.0}]
 
1342
      ,
 
1343
      # Billard
 
1344
      [
 
1345
        {'line_width': 8.0, 'points': (180.0, 80.0, 180.0, 440.0), 'tool': 'LINE', 'stroke_color_rgba': 0x1010FFFFL},
 
1346
        {'line_width': 8.0, 'points': (180.0, 460.0, 380.0, 460.0), 'tool': 'LINE', 'stroke_color_rgba': 0x1010FFFFL},
 
1347
        {'line_width': 8.0, 'points': (380.0, 80.0, 380.0, 440.0), 'tool': 'LINE', 'stroke_color_rgba': 0x1010FFFFL},
 
1348
        {'line_width': 8.0, 'points': (180.0, 60.0, 380.0, 60.0), 'tool': 'LINE', 'stroke_color_rgba': 0x1010FFFFL},
 
1349
        {'line_width': 8.0, 'points': (280.0, 320.0, 280.0, 420.0), 'tool': 'LINE', 'stroke_color_rgba': 2199425535L},
 
1350
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 300.0+10, 'center_x': 260.0+10, 'tool': 'FILL_CIRCLE'},
 
1351
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'center_y': 100.0+10, 'center_x': 240.0+10, 'tool': 'FILL_CIRCLE'},
 
1352
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 100.0+10, 'center_x': 260.0+10, 'tool': 'FILL_CIRCLE'},
 
1353
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 100.0+10, 'center_x': 280.0+10, 'tool': 'FILL_CIRCLE'},
 
1354
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x000000A0L, 'center_y': 100.0+10, 'center_x': 300.0+10, 'tool': 'FILL_CIRCLE'},
 
1355
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xb9bc0dffL, 'center_y': 120.0+10, 'center_x': 260.0+10, 'tool': 'FILL_CIRCLE'},
 
1356
        {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 120.0+10, 'center_x': 280.0+10, 'tool': 'FILL_CIRCLE'}
 
1357
        ]
 
1358
      ,
 
1359
      # Clara (my daughter)
 
1360
      [{'width': 240.0-220.0, 'line_width': 1.0, 'height': 480.0-400.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 400.0, 'x': 220.0, 'tool': 'FILL_RECT'},
 
1361
       {'width': 320.0-300.0, 'line_width': 1.0, 'height': 480.0-400.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 400.0, 'x': 300.0, 'tool': 'FILL_RECT'},
 
1362
       {'width': 220.0-160.0, 'line_width': 1.0, 'height': 200.0-180.0,'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 180.0, 'x': 160.0, 'tool': 'FILL_RECT'},
 
1363
       {'width': 380.0-320.0, 'line_width': 1.0, 'height': 200.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 180.0, 'x': 320.0, 'tool': 'FILL_RECT'},
 
1364
       {'width': 380.0-360.0, 'line_width': 1.0, 'height': 180.0-120.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 120.0, 'x': 360.0, 'tool': 'FILL_RECT'},
 
1365
       {'width': 180.0-160.0, 'line_width': 1.0, 'height': 260.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 200.0, 'x': 160.0, 'tool': 'FILL_RECT'},
 
1366
       {'radius_x': 50, 'line_width': 1.0, 'radius_y': 50, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 60.0+50, 'center_x': 220.0+50, 'tool': 'FILL_CIRCLE'},
 
1367
       {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00a0L, 'center_y': 100.0+10, 'center_x': 240.0+10, 'tool': 'FILL_CIRCLE'},
 
1368
       {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00a0L, 'center_y': 100.0+10, 'center_x': 280.0+10, 'tool': 'FILL_CIRCLE'},
 
1369
       {'line_width': 8.0, 'points': (260.0, 140.0, 280.0, 140.0), 'tool': 'LINE', 'stroke_color_rgba': 0xFF0000A0L},
 
1370
       {'width': 300.0-240.0, 'line_width': 1.0, 'height': 180.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 160.0, 'x': 240.0, 'tool': 'FILL_RECT'},
 
1371
       {'width': 320.0-220.0, 'line_width': 1.0, 'height': 320.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 180.0, 'x': 220.0, 'tool': 'FILL_RECT'},
 
1372
       {'width': 340.0-200.0, 'line_width': 1.0, 'height': 400.0-320.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 320.0, 'x': 200.0, 'tool': 'FILL_RECT'}]
 
1373
      ,
 
1374
      # Bicycle
 
1375
      [{'radius_x': 40, 'radius_y': 40, 'stroke_color_rgba': 4287383039L, 'line_width': 5.0, 'center_y': 260.0+40, 'tool': 'CIRCLE', 'center_x': 160.0+40},
 
1376
       {'radius_x': 40, 'radius_y': 40, 'stroke_color_rgba': 4287383039L, 'line_width': 5.0, 'center_y': 260.0+40, 'tool': 'CIRCLE', 'center_x': 320.0+40},
 
1377
       {'tool': 'LINE', 'points': (200.0, 300.0, 280.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1378
       {'tool': 'LINE', 'points': (280.0,300.0, 340.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1379
       {'tool': 'LINE', 'points': (240.0, 240.0, 340.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1380
       {'tool': 'LINE', 'points': (200.0, 300.0, 240.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1381
       {'tool': 'LINE', 'points': (240.0, 220.0, 240.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 2199425535L},
 
1382
       {'tool': 'LINE', 'points': (220.0, 220.0, 260.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 2199425535L},
 
1383
       {'tool': 'LINE', 'points': (340.0, 200.0, 340.0, 240.0), 'line_width': 8.0, 'stroke_color_rgba': 2199425535L},
 
1384
       {'tool': 'LINE', 'points': (320.0, 200.0, 340.0, 200.0), 'line_width': 8.0, 'stroke_color_rgba': 2199425535L},
 
1385
       {'tool': 'LINE', 'points': (340.0, 240.0, 360.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L}]
 
1386
      ,
 
1387
      # Sea boat and sun
 
1388
      [{'width': 420.0-140.0, 'line_width': 1.0, 'height': 500.0-420.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00a0L, 'y': 420.0, 'tool': 'FILL_RECT', 'x': 140.0},
 
1389
       {'radius_x': 50, 'line_width': 1.0, 'radius_y': 50, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'center_y': 60.0+50, 'tool': 'FILL_CIRCLE', 'center_x': 160.0+50},
 
1390
       {'radius_x': 50, 'line_width': 1.0, 'radius_y': 20, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 160.0+20, 'tool': 'FILL_CIRCLE', 'center_x': 260.0+50},
 
1391
       {'radius_x': 30, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 200.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 300.0+30},
 
1392
       {'radius_x': 20,'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba':0x1010FFA0L, 'center_y': 140.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 360.0+20},
 
1393
       {'tool': 'LINE','points': (220.0, 400.0, 240.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1394
       {'tool': 'LINE', 'points': (240.0, 420.0, 280.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1395
       {'tool': 'LINE', 'points': (280.0, 420.0, 300.0, 400.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1396
       {'tool': 'LINE', 'points': (220.0, 400.0, 300.0, 400.0), 'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1397
       {'tool': 'LINE', 'points': (260.0, 280.0, 260.0, 400.0),'line_width': 8.0, 'stroke_color_rgba': 0xFF0000A0L},
 
1398
       {'tool': 'LINE', 'points':(260.0, 280.0, 300.0, 380.0), 'line_width': 8.0, 'stroke_color_rgba': 2199425535L},
 
1399
       {'tool': 'LINE', 'points': (260.0, 380.0, 300.0, 380.0), 'line_width': 8.0,'stroke_color_rgba': 2199425535L}]
 
1400
 
 
1401
      ]
 
1402
    else:
 
1403
      # Symmetrical items
 
1404
      self.drawlist = \
 
1405
      [
 
1406
        # 3 white box in triangle
 
1407
        [{'width': 420.0-380.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 380.0},
 
1408
         {'width': 380.0-340.0, 'line_width': 1.0, 'height': 220.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 340.0},
 
1409
         {'width': 380.0-340.0, 'line_width': 1.0, 'height': 300.0-260.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 260.0, 'tool': 'FILL_RECT', 'x': 340.0}]
 
1410
        ,
 
1411
        # Colored pyramid
 
1412
        [{'width': 420.0-140.0, 'line_width': 1.0, 'height': 460.0-420.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xC2C2C2A0L, 'y': 420.0, 'tool': 'FILL_RECT', 'x': 140.0},
 
1413
         {'width': 420.0-180.0, 'line_width': 1.0, 'height': 420.0-380.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 380.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1414
         {'width': 420.0-220.0, 'line_width': 1.0, 'height': 380.0-340.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 340.0, 'tool': 'FILL_RECT', 'x': 220.0},
 
1415
         {'width': 420.0-260.0, 'line_width': 1.0, 'height': 340.0-300.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 300.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1416
         {'width': 420.0-300.0, 'line_width': 1.0, 'height': 300.0-260.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 260.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1417
         {'width': 420.0-340.0, 'line_width': 1.0, 'height': 260.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x000000A0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 340.0},
 
1418
         {'width': 420.0-380.0, 'line_width': 1.0, 'height': 220.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x000000A0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 380.0}]
 
1419
        ,
 
1420
        # Butterfly
 
1421
        [{'width': 420.0-380.0, 'line_width': 1.0, 'height': 380.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 380.0},
 
1422
         {'tool': 'LINE', 'points': (360.0, 80.0, 400.0, 180.0), 'line_width': 8.0, 'stroke_color_rgba': 707406591L},
 
1423
         {'radius_x': 100, 'line_width': 1.0, 'radius_y': 170, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 100.0+170, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+100},
 
1424
         {'radius_x': 50, 'line_width': 1.0, 'radius_y': 100, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'center_y': 180.0+100, 'tool': 'FILL_CIRCLE', 'center_x': 260.0+50}]
 
1425
        ,
 
1426
        # Robot
 
1427
        [{'width': 420.0-340.0, 'line_width': 1.0, 'height': 360.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 340.0},
 
1428
         {'width': 380.0-340.0, 'line_width': 1.0, 'height': 500.0-360.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 360.0, 'tool': 'FILL_RECT', 'x': 340.0},
 
1429
         {'width': 340.0-260.0, 'line_width': 1.0, 'height': 200.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1430
         {'width': 300.0-260.0, 'line_width': 1.0, 'height': 280.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1431
         {'width': 420.0-380.0, 'line_width': 1.0, 'height': 160.0-140.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 140.0, 'tool': 'FILL_RECT', 'x': 380.0},
 
1432
         {'width': 420.0-360.0, 'line_width': 1.0, 'height': 140.0-60.0,  'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00a0L, 'y': 60.0, 'tool': 'FILL_RECT', 'x': 360.0},
 
1433
         {'width': 420.0-400.0, 'line_width': 1.0, 'height': 120.0-100.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xb9bc0dffL, 'y': 100.0, 'tool': 'FILL_RECT', 'x': 400.0},
 
1434
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 80.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 380.0+10}]
 
1435
        ,
 
1436
        # Arrow
 
1437
        [{'width': 420.0-300.0, 'line_width': 1.0, 'height': 260.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1438
         {'tool': 'LINE', 'points': (180.0, 240.0, 300.0, 140.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L},
 
1439
         {'tool': 'LINE', 'points': (180.0, 240.0, 180.0, 260.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L},
 
1440
         {'tool': 'LINE', 'points': (180.0, 260.0, 300.0, 360.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L},
 
1441
         {'tool': 'LINE', 'points': (300.0, 140.0, 300.0, 360.0), 'line_width': 8.0, 'stroke_color_rgba': 4287383039L}]
 
1442
        ,
 
1443
        # House
 
1444
        [{'width': 420.0-200.0, 'line_width': 1.0, 'height': 460.0-440.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 440.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1445
         {'width': 220.0-200.0, 'line_width': 1.0, 'height': 440.0-280.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 280.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1446
         {'width': 420.0-200.0, 'line_width': 1.0, 'height': 280.0-260.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'y': 260.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1447
         {'width': 420.0-380.0, 'line_width': 1.0, 'height': 440.0-360.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 360.0, 'tool': 'FILL_RECT', 'x': 380.0},
 
1448
         {'width': 360.0-240.0, 'line_width': 1.0, 'height': 400.0-300.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 300.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1449
         {'tool': 'LINE', 'points': (200.0, 260.0, 420.0, 100.0), 'line_width': 8.0, 'stroke_color_rgba': 4294905087L}]
 
1450
        ,
 
1451
        # Plane
 
1452
        [{'width': 420.0-360.0, 'line_width': 1.0, 'height': 380.0-140.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 140.0, 'tool': 'FILL_RECT', 'x': 360.0},
 
1453
         {'width': 360.0-180.0, 'line_width': 1.0, 'height': 280.0-220.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 220.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1454
         {'width': 260.0-240.0, 'line_width': 1.0, 'height': 220.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x000000A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1455
         {'tool': 'LINE', 'points': (180.0, 200.0, 320.0, 200.0), 'line_width': 8.0, 'stroke_color_rgba': 4283674623L},
 
1456
         {'width': 420.0-400.0, 'line_width': 1.0, 'height': 420.0-360.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 360.0, 'tool': 'FILL_RECT', 'x': 400.0},
 
1457
         {'width': 420.0-380.0, 'line_width': 1.0, 'height': 180.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 380.0}]
 
1458
        ,
 
1459
        # bipbip (big non flying bird)
 
1460
        [{'width': 280.0-260.0, 'line_width': 1.0, 'height': 320.0-120.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 120.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1461
         {'width': 300.0-260.0, 'line_width': 1.0, 'height': 120.0-80.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 80.0, 'tool': 'FILL_RECT', 'x': 260.0},
 
1462
         {'width': 320.0-300.0, 'line_width': 1.0, 'height': 120.0-100.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 100.0, 'tool': 'FILL_RECT', 'x': 300.0},
 
1463
         {'width': 280.0-200.0, 'line_width': 1.0, 'height': 380.0-320.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 320.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1464
         {'width': 220.0-200.0, 'line_width': 1.0, 'height': 320.0-300.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 300.0, 'tool': 'FILL_RECT', 'x': 200.0},
 
1465
         {'width': 260.0-240.0, 'line_width': 1.0, 'height': 460.0-380.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 380.0, 'tool': 'FILL_RECT', 'x': 240.0},
 
1466
         {'width': 280.0-260.0, 'line_width': 1.0, 'height': 460.0-440.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'y': 440.0, 'tool': 'FILL_RECT', 'x': 260.0}]
 
1467
        ,
 
1468
        # Dog
 
1469
        [{'width': 180.0-160.0, 'line_width': 1.0, 'height': 200.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 160.0},
 
1470
         {'width': 340.0-180.0, 'line_width': 1.0, 'height': 240.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1471
         {'width': 200.0-180.0, 'line_width': 1.0, 'height': 280.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 180.0},
 
1472
         {'width': 340.0-320.0, 'line_width': 1.0, 'height': 280.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 320.0},
 
1473
         {'width': 380.0-320.0, 'line_width': 1.0, 'height': 200.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x831891A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 320.0}]
 
1474
        ,
 
1475
        # Fish
 
1476
        [{'radius_x': 90, 'line_width': 1.0, 'radius_y': 60, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'center_y': 160.0+60, 'tool': 'FILL_CIRCLE', 'center_x': 180.0+90},
 
1477
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x1010FFA0L, 'center_y': 200.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 320.0+10},
 
1478
         {'width': 180.0-160.0, 'line_width': 1.0, 'height': 260.0-180.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xffff0cA0L, 'y': 180.0, 'tool': 'FILL_RECT', 'x': 160.0}]
 
1479
        ,
 
1480
        # Boat
 
1481
        [{'tool': 'LINE', 'points': (260.0, 340.0, 420.0, 340.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1482
         {'tool': 'LINE', 'points': (220.0, 260.0, 260.0, 340.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1483
         {'tool': 'LINE', 'points': (220.0, 260.0, 420.0, 260.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1484
         {'tool': 'LINE', 'points': (340.0, 260.0, 360.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1485
         {'tool': 'LINE', 'points': (360.0, 220.0, 420.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1486
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 280.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 300.0+10},
 
1487
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 280.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 340.0+10},
 
1488
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'center_y': 280.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 380.0+10}]
 
1489
        ,
 
1490
        # Spaceship
 
1491
        [{'tool': 'LINE', 'points': (220.0, 400.0, 340.0, 400.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1492
         {'tool': 'LINE', 'points': (340.0, 400.0, 360.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1493
         {'tool': 'LINE', 'points': (360.0, 320.0, 360.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1494
         {'tool': 'LINE', 'points': (340.0, 300.0, 360.0, 320.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1495
         {'tool': 'LINE', 'points': (340.0, 100.0, 340.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1496
         {'tool': 'LINE', 'points': (200.0, 420.0, 220.0, 400.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1497
         {'tool': 'LINE', 'points': (200.0, 320.0, 200.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1498
         {'tool': 'LINE', 'points': (200.0, 320.0, 220.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1499
         {'tool': 'LINE', 'points': (220.0, 100.0, 220.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1500
         {'tool': 'LINE', 'points': (220.0, 100.0, 280.0, 20.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1501
         {'tool': 'LINE', 'points': (280.0, 20.0, 340.0, 100.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1502
         {'tool': 'LINE', 'points': (220.0, 100.0, 340.0, 100.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1503
         {'tool': 'LINE', 'points': (220.0, 120.0, 340.0, 120.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1504
         {'tool': 'LINE', 'points': (220.0, 300.0, 340.0, 300.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1505
         {'tool': 'LINE', 'points': (280.0, 300.0, 280.0, 420.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1506
        ,
 
1507
        # Question mark
 
1508
        [{'tool': 'LINE', 'points': (280.0, 260.0, 280.0, 440.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1509
         {'tool': 'LINE', 'points': (280.0, 260.0, 340.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1510
         {'tool': 'LINE', 'points': (340.0, 160.0, 340.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1511
         {'tool': 'LINE', 'points': (280.0, 120.0, 340.0, 160.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1512
         {'tool': 'LINE', 'points': (220.0, 160.0, 280.0, 120.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1513
         {'tool': 'LINE', 'points': (220.0, 160.0, 220.0, 200.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1514
         {'tool': 'LINE', 'points': (220.0, 200.0, 260.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL}]
 
1515
        ,
 
1516
        # Flying toy (cerf volant in french)
 
1517
        [{'tool': 'LINE', 'points': (160.0, 140.0, 260.0, 100.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1518
         {'tool': 'LINE', 'points': (160.0, 140.0, 160.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1519
         {'tool': 'LINE', 'points': (160.0, 220.0, 260.0, 380.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1520
         {'tool': 'LINE', 'points': (260.0, 380.0, 360.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1521
         {'tool': 'LINE', 'points': (360.0, 140.0, 360.0, 220.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1522
         {'tool': 'LINE', 'points': (260.0, 100.0, 360.0, 140.0), 'line_width': 8.0, 'stroke_color_rgba': 0x1010FFFFL},
 
1523
         {'tool': 'LINE', 'points': (220.0, 500.0, 260.0, 380.0), 'line_width': 8.0, 'stroke_color_rgba': 707406591L},
 
1524
         {'width': 240.0-220.0, 'line_width': 1.0, 'height': 180.0-160.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 160.0, 'tool': 'FILL_RECT', 'x': 220.0},
 
1525
         {'width': 300.0-280.0, 'line_width': 1.0, 'height': 220.0-200.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 200.0, 'tool': 'FILL_RECT', 'x': 280.0},
 
1526
         {'width': 240.0-220.0, 'line_width': 1.0, 'height': 260.0-240.0, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0xFF0000A0L, 'y': 240.0, 'tool': 'FILL_RECT', 'x': 220.0},
 
1527
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 160.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 280.0+10},
 
1528
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 200.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 220.0+10},
 
1529
         {'radius_x': 10, 'line_width': 1.0, 'radius_y': 10, 'stroke_color_rgba': 255L, 'fill_color_rgba': 0x33FF00A0L, 'center_y': 240.0+10, 'tool': 'FILL_CIRCLE', 'center_x': 280.0+10}]
 
1530
 
 
1531
      ]
 
1532
 
 
1533
    # No more than 9 level allowed in gcompris
 
1534
    self.gcomprisBoard.number_of_sublevel=math.ceil(len(self.drawlist)/9.0)
 
1535
    self.gcomprisBoard.maxlevel=min(9, math.ceil(float(len(self.drawlist))/self.gcomprisBoard.number_of_sublevel))
 
1536
 
 
1537
  def ok_event(self, widget, target, event=None):
 
1538
    self.ok()