[gcompris] lang-activity: better exercise, overall improvements.



commit b77a9ade08834bb4b60c4af5ff8326350b985a8a
Author: Bruno Coudoin <bcoudoin rcsmobility com>
Date:   Mon May 6 00:37:21 2013 +0200

    lang-activity: better exercise, overall improvements.

 src/lang-activity/lang.py       |  166 +++++++++++++++++++++------------------
 src/lang-activity/langFindit.py |   44 +++++++----
 src/lang-activity/langLib.py    |   36 +++++++--
 3 files changed, 145 insertions(+), 101 deletions(-)
---
diff --git a/src/lang-activity/lang.py b/src/lang-activity/lang.py
index a1d4e8c..0ab8a84 100644
--- a/src/lang-activity/lang.py
+++ b/src/lang-activity/lang.py
@@ -19,7 +19,7 @@
 import gtk
 import gtk.gdk
 import gcompris
-import gcompris.utils
+import gcompris.bonus
 import gcompris.skin
 import gcompris.sound
 import goocanvas
@@ -29,47 +29,14 @@ from gcompris import gcompris_gettext as _
 from langLib import *
 from langFindit import *
 
-class MissingImage:
-  """This is used to display a missing image"""
-
-  def __init__(self, rootitem, langActivity):
-    self.missingroot = goocanvas.Group( parent = rootitem )
-    width = 280
-    height = 240
-    item = goocanvas.Rect( parent = self.missingroot,
-                           x = gcompris.BOARD_WIDTH  / 2 - width / 2,
-                           y = gcompris.BOARD_HEIGHT / 2 - height / 2,
-                           width = width,
-                           height = height,
-                           radius_x = 5,
-                           radius_y = 5,
-                           stroke_color_rgba = 0x666666FFL,
-                           fill_color_rgba = 0x33333366L,
-                           line_width = 2.0 )
-    item.connect("button_press_event", langActivity.next_event, None)
-    self.missingtext = goocanvas.Text(
-      parent = self.missingroot,
-      x = gcompris.BOARD_WIDTH / 2,
-      y = gcompris.BOARD_HEIGHT / 2,
-      fill_color = "black",
-      font = gcompris.skin.get_font("gcompris/subtitle"),
-      text = _("Missing Image"),
-      anchor = gtk.ANCHOR_CENTER,
-      alignment = pango.ALIGN_CENTER
-      )
-
-  def hide(self):
-    self.missingroot.props.visibility = goocanvas.ITEM_INVISIBLE
-
-  def show(self, triplet):
-    self.missingroot.props.visibility = goocanvas.ITEM_VISIBLE
-
-
 class Gcompris_lang:
   """Empty gcompris python class"""
 
   def __init__(self, gcomprisBoard):
-    print "lang init"
+    # These are used to let us restart only after the bonus is displayed.
+    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
+    self.board_paused  = 0;
+    self.gamewon       = 0;
 
     # Save the gcomprisBoard, it defines everything we need
     # to know from the core
@@ -79,26 +46,22 @@ class Gcompris_lang:
     gcomprisBoard.disable_im_context = True
 
   def start(self):
-    print "lang start"
     self.saved_policy = gcompris.sound.policy_get()
     gcompris.sound.policy_set(gcompris.sound.PLAY_AND_INTERRUPT)
 
     # init config to default values
     self.config_dict = self.init_config()
 
-    print "init self.config_dict :", self.config_dict
-
     # change configured values
-    print "gcompris.get_board_conf() : ", gcompris.get_board_conf()
     self.config_dict.update(gcompris.get_board_conf())
 
-    print "self.config_dict final :", self.config_dict
-
     if self.config_dict.has_key('locale_sound'):
       gcompris.set_locale(self.config_dict['locale_sound'])
 
     # Set the buttons we want in the bar
-    gcompris.bar_set(gcompris.BAR_LEVEL|gcompris.BAR_REPEAT|gcompris.BAR_CONFIG)
+    handle = gcompris.utils.load_svg("lang/repeat.svg")
+    gcompris.bar_set_repeat_icon(handle)
+    gcompris.bar_set(gcompris.BAR_LEVEL|gcompris.BAR_REPEAT_ICON|gcompris.BAR_CONFIG)
     gcompris.bar_location(gcompris.BOARD_WIDTH / 2 - 100, -1, 0.6)
 
     # Set a background image
@@ -112,19 +75,30 @@ class Gcompris_lang:
 
     self.langLib = LangLib(gcompris.DATA_DIR + "/lang/lang.xml")
     self.chapters = self.langLib.getChapters()
-    # FIXME Do not manage Chapter yet
-    self.currentChapterId = 0
+
+    if self.gcomprisBoard.mode == "":
+      gcompris.utils.dialog("ERROR, missing 'mode' in the xml menu to specify the chapter",
+                            None)
+      return
+    self.currentChapterName = self.gcomprisBoard.mode
 
     # Manage levels (a level is a lesson in the lang model)
     self.gcomprisBoard.level = 1
-    self.gcomprisBoard.maxlevel = \
-        len ( self.chapters.getChapters()[self.currentChapterId].getLessons() )
+    try:
+      self.gcomprisBoard.maxlevel = \
+          len ( self.chapters.getChapters()[self.currentChapterName].getLessons() )
+    except:
+      gcompris.utils.dialog("ERROR, missing chapter '" + self.currentChapterName + "'",
+                            None)
+      return
     gcompris.bar_set_level(self.gcomprisBoard)
 
+    self.currentExerciseModes = []
     self.currentExercise = None
-    self.currentLesson = self.langLib.getLesson(self.currentChapterId,
+    self.currentLesson = self.langLib.getLesson(self.currentChapterName,
                                                 self.gcomprisBoard.level - 1)
     self.displayLesson( self.currentLesson )
+    self.pause(0);
 
   def end(self):
     gcompris.sound.policy_set(self.saved_policy)
@@ -135,11 +109,14 @@ class Gcompris_lang:
 
 
   def ok(self):
-    print("lang ok.")
+    pass
 
 
   def repeat(self):
-    self.playVoice( self.currentLesson.getTriplets()[self.currentTripletId] )
+    if self.currentExercise:
+      self.currentExercise.repeat()
+    else:
+      self.playVoice( self.currentLesson.getTriplets()[self.currentTripletId] )
 
   def init_config(self):
     default_config = { 'locale_sound' : 'NULL' }
@@ -169,7 +146,7 @@ class Gcompris_lang:
 
     gcompris.combo_locales_asset(bconf, _("Select locale"),
                                  self.config_dict['locale_sound'],
-                                 "voices/$LOCALE/colors/red.ogg")
+                                 "lang/abcdarium/audio/$LOCALE/red.ogg")
 
   # Callback when the "OK" button is clicked in configuration window
   # this get all the _changed_ values
@@ -186,16 +163,33 @@ class Gcompris_lang:
 
 
   def key_press(self, keyval, commit_str, preedit_str):
-    utf8char = gtk.gdk.keyval_to_unicode(keyval)
-    strn = u'%c' % utf8char
+    if self.currentExercise:
+      return
 
-    print("Gcompris_lang key press keyval=%i %s" % (keyval, strn))
+    if keyval == gtk.keysyms.Left or keyval == gtk.keysyms.Up:
+      self.previous_event(keyval)
+    elif keyval == gtk.keysyms.Right or keyval == gtk.keysyms.Down:
+      self.next_event(keyval)
 
   def pause(self, pause):
-    print("lang pause. %i" % pause)
+    self.board_paused = pause
+
+    # When the bonus is displayed, it call us first
+    # with pause(1) and then with pause(0)
+    # the game is won
+    if(self.gamewon == 1 and pause == 0):
+      self.gamewon = 0
+      self.next_level()
+
+    return
+
 
 
   def next_level(self):
+    if self.currentExercise:
+      self.currentExercise.stop()
+      self.currentExercise = None
+
     if self.gcomprisBoard.level < self.gcomprisBoard.maxlevel:
       self.set_level(self.gcomprisBoard.level + 1)
     else:
@@ -208,8 +202,9 @@ class Gcompris_lang:
 
     if self.currentExercise:
       self.currentExercise.stop()
+      self.currentExercise = None
 
-    self.currentLesson = self.langLib.getLesson(self.currentChapterId,
+    self.currentLesson = self.langLib.getLesson(self.currentChapterName,
                                                 self.gcomprisBoard.level - 1)
     self.displayLesson( self.currentLesson )
 
@@ -290,7 +285,6 @@ class Gcompris_lang:
       )
 
     # The triplet area
-    self.missingImage = MissingImage(self.lessonroot, self)
     self.imageitem = goocanvas.Image( parent = self.lessonroot )
     self.imageitem.connect("button_press_event", self.next_event, None)
     self.descriptionitem = goocanvas.Text(
@@ -307,16 +301,28 @@ class Gcompris_lang:
 
   def playVoice(self, triplet):
     if triplet.voice:
-      gcompris.sound.play_ogg("voices/$LOCALE/" + triplet.voice)
+      gcompris.sound.play_ogg(triplet.voice)
+
+  def runExercise(self):
+    if len(self.currentExerciseModes):
+      self.currentExercise = Findit(self, self.rootitem, self.currentLesson,
+                                    self.currentExerciseModes.pop())
+      self.currentExercise.start()
+      return True
+    return False
 
   def displayImage(self, triplet):
 
     if len(self.tripletSeen) == len(self.currentLesson.getTriplets()):
       self.clearLesson()
-      self.currentExercise = Findit(self, self.rootitem, self.currentLesson)
-      self.currentExercise.start()
+      # We will run the exercise 3 times in different modes
+      self.currentExerciseModes = [Findit.WITH_IMAGE,
+                                   Findit.WITH_QUESTION|Findit.WITH_IMAGE,
+                                   Findit.WITH_QUESTION|Findit.WITH_TEXT|Findit.WITH_IMAGE]
+      self.runExercise()
       return
 
+    # Display the next triplet
     self.tripletSeen.add(triplet)
     self.playVoice( triplet )
     self.descriptionitem.set_properties (
@@ -326,31 +332,35 @@ class Gcompris_lang:
       text = str(self.currentTripletId + 1) + "/" \
         + str( len( self.currentLesson.getTriplets() ) ),
       )
-    if triplet.image:
-      self.missingImage.hide()
-      self.imageitem.props.visibility = goocanvas.ITEM_VISIBLE
-      pixbuf = gcompris.utils.load_pixmap(gcompris.DATA_DIR + "/lang/" +
-                                          triplet.image)
-      center_x =  pixbuf.get_width()/2
-      center_y =  pixbuf.get_height()/2
-      self.imageitem.set_properties(pixbuf = pixbuf,
-                                    x = gcompris.BOARD_WIDTH  / 2 - center_x,
-                                    y = gcompris.BOARD_HEIGHT / 2 - center_y )
-    else:
-      self.imageitem.props.visibility = goocanvas.ITEM_INVISIBLE
-      self.missingImage.show(triplet)
-
-  def previous_event(self, event, target,item, dummy):
+    self.imageitem.props.visibility = goocanvas.ITEM_VISIBLE
+    pixbuf = gcompris.utils.load_pixmap(gcompris.DATA_DIR + "/" +
+                                        triplet.image)
+    center_x =  pixbuf.get_width()/2
+    center_y =  pixbuf.get_height()/2
+    self.imageitem.set_properties(pixbuf = pixbuf,
+                                  x = gcompris.BOARD_WIDTH  / 2 - center_x,
+                                  y = gcompris.BOARD_HEIGHT / 2 - center_y )
+
+  def previous_event(self, event=None, target=None, item=None, dummy=None):
     self.currentTripletId -= 1
     if self.currentTripletId < 0:
       self.currentTripletId = len( self.currentLesson.getTriplets() ) - 1
     self.displayImage( self.currentLesson.getTriplets()[self.currentTripletId] )
 
-  def next_event(self, event, target, item, dummy):
+  def next_event(self, event=None, target=None, item=None, dummy=None):
     self.currentTripletId += 1
     if self.currentTripletId >= len( self.currentLesson.getTriplets() ):
       self.currentTripletId = 0
     self.displayImage( self.currentLesson.getTriplets()[self.currentTripletId] )
 
+  def win(self):
+    if not self.runExercise():
+      self.gamewon = 1
+      gcompris.bonus.display(gcompris.bonus.WIN, gcompris.bonus.FLOWER)
+
+  def loose(self):
+    self.gamewon = 0
+    gcompris.bonus.display(gcompris.bonus.LOOSE, gcompris.bonus.FLOWER)
+
 
 
diff --git a/src/lang-activity/langFindit.py b/src/lang-activity/langFindit.py
index 85faf2e..8cf8c02 100644
--- a/src/lang-activity/langFindit.py
+++ b/src/lang-activity/langFindit.py
@@ -32,7 +32,7 @@ from langLib import *
 class SpotTarget:
   """Display a triplet"""
 
-  def __init__(self, parentitem, x, y, triplet, callback):
+  def __init__(self, parentitem, x, y, triplet, callback, mode):
       rootitem = goocanvas.Group( parent = parentitem )
       self.width = 380
       self.height = 100
@@ -60,7 +60,8 @@ class SpotTarget:
 
       # The text description
       textx = 120
-      item = goocanvas.Text(
+      if mode & Findit.WITH_TEXT:
+        item = goocanvas.Text(
           parent = rootitem,
           x = x + textx,
           y = y + 10,
@@ -71,16 +72,17 @@ class SpotTarget:
           alignment = pango.ALIGN_LEFT,
           width = self.width - textx - 10
           )
-      item.connect("button_press_event", callback, triplet)
-      item.connect("enter_notify_event",
-                   (lambda s,e,t,i: i.set_properties(fill_color_rgba = fill_color_on)),
-                   itembg )
-      item.connect("leave_notify_event",
-                   (lambda s,e,t,i: i.set_properties(fill_color_rgba = fill_color_off)),
-                   itembg )
+        item.connect("button_press_event", callback, triplet)
+        item.connect("enter_notify_event",
+                     (lambda s,e,t,i: i.set_properties(fill_color_rgba = fill_color_on)),
+                     itembg )
+        item.connect("leave_notify_event",
+                     (lambda s,e,t,i: i.set_properties(fill_color_rgba = fill_color_off)),
+                     itembg )
+
       # The image
-      if triplet.image:
-          pixbuf = gcompris.utils.load_pixmap(gcompris.DATA_DIR + "/lang/" +
+      if triplet.image and (mode & Findit.WITH_IMAGE):
+          pixbuf = gcompris.utils.load_pixmap(gcompris.DATA_DIR + "/" +
                                               triplet.image)
           item = goocanvas.Image( parent = rootitem,
                                   pixbuf = pixbuf,
@@ -102,9 +104,14 @@ class Findit:
     """An exercice that given a lesson asks the children to find"""
     """the good anwer from a source text, a target text or a voice"""
 
-    def __init__(self, lang, parentitem, lesson):
+    WITH_QUESTION = 0x4
+    WITH_TEXT = 0x2
+    WITH_IMAGE = 0x1
+
+    def __init__(self, lang, parentitem, lesson, mode):
         self.lang = lang
         self.lesson = lesson
+        self.mode = mode
         self.triplets = list(lesson.getTriplets())
         random.shuffle(self.triplets)
         self.rootitem = goocanvas.Group( parent = parentitem )
@@ -116,7 +123,7 @@ class Findit:
 
         if self.currentIndex >= len(self.triplets):
             self.stop()
-            self.lang.next_level()
+            self.lang.win()
             return
 
         self.gameroot = goocanvas.Group( parent = self.rootitem )
@@ -125,7 +132,8 @@ class Findit:
         self.lang.playVoice(self.tripletToFind)
         self.currentIndex += 1
         # Display the triplet to find
-        goocanvas.Text(
+        if self.mode & Findit.WITH_QUESTION:
+          goocanvas.Text(
             parent = self.gameroot,
             x = gcompris.BOARD_WIDTH / 2,
             y = 100,
@@ -149,7 +157,9 @@ class Findit:
         triplets2.insert(random.randint(0, numberOfItem-1),
                          self.tripletToFind)
         for i in range(0, numberOfItem):
-            spot = SpotTarget(self.gameroot, x, y, triplets2[i], self.ok)
+            spot = SpotTarget(self.gameroot, x, y,
+                              triplets2[i], self.ok,
+                              self.mode)
             y += spot.height + 20
             if (i+1) % 2 == 0:
                 y = y_start
@@ -164,4 +174,8 @@ class Findit:
             self.start()
         else:
             self.triplets.append(self.tripletToFind)
+            self.lang.loose()
 
+    def repeat(self):
+      self.lang.playVoice(self.tripletToFind)
+  
diff --git a/src/lang-activity/langLib.py b/src/lang-activity/langLib.py
index 3cf09bf..c8ef019 100644
--- a/src/lang-activity/langLib.py
+++ b/src/lang-activity/langLib.py
@@ -17,6 +17,7 @@
 #
 # lang activity.
 
+import gcompris.utils
 import xml.dom.minidom
 
 def isNode(e, name):
@@ -29,19 +30,35 @@ class Triplet:
         self.image = None
         self.voice = None
         self.type = None
+        self.valid = True
         self.parse(elem)
 
     def parse(self, elem):
         for e in elem.childNodes:
             if isNode(e, "image"):
-                self.image = e.firstChild.nodeValue if e.firstChild else None
+                if e.firstChild:
+                    self.image = e.firstChild.nodeValue
+                else:
+                    self.valid = False
             elif isNode(e, "description"):
                 self.description = e.firstChild.nodeValue if e.firstChild else None
             elif isNode(e, "voice"):
-                self.voice = e.firstChild.nodeValue if e.firstChild else None
+                if e.firstChild:
+                    self.voice = e.firstChild.nodeValue
+                else:
+                    self.valid = False
             elif isNode(e, "type"):
                 self.type = e.firstChild.nodeValue if e.firstChild else None
 
+        if self.valid:
+            if not gcompris.utils.find_file_absolute(self.image):
+                self.valid = False
+            elif not gcompris.utils.find_file_absolute(self.voice):
+                self.valid = False
+
+    def isValid(self):
+        return self.valid
+
     def dump(self):
         print "    Triplet "+ self.description + " / " \
             + str(self.image) + " / " + str(self.voice) \
@@ -61,7 +78,9 @@ class Lesson:
             elif isNode(e, "description"):
                 self.description = e.firstChild.nodeValue if e.firstChild else None
             elif isNode(e, "Triplet"):
-                self.triplets.append( Triplet(e) )
+                triplet = Triplet(e)
+                if triplet.isValid():
+                    self.triplets.append( triplet )
 
     def getTriplets(self):
         return self.triplets
@@ -82,7 +101,7 @@ class Chapter:
     def parse(self, elem):
         for e in elem.childNodes:
             if isNode(e, "name"):
-                self.name = e.firstChild.nodeValue
+                self.name = e.firstChild.nodeValue if e.firstChild else None
             elif isNode(e, "description"):
                 self.description = e.firstChild.nodeValue if e.firstChild else None
             elif isNode(e, "Lesson"):
@@ -98,12 +117,13 @@ class Chapter:
 
 class Chapters:
     def __init__(self, doc):
-        self.chapters = []
+        self.chapters = {}
         self.parse(doc)
 
     def parse(self, doc):
         for elem in doc:
-            self.chapters.append( Chapter(elem) )
+            chapter = Chapter(elem)
+            self.chapters[chapter.name] = chapter
 
     def getChapters(self):
         return self.chapters
@@ -125,5 +145,5 @@ class LangLib:
     def getChapters(self):
         return self.chapters
 
-    def getLesson(self, chapterIndex, lessonIndex):
-        return self.chapters.getChapters()[chapterIndex].getLessons()[lessonIndex]
+    def getLesson(self, chapterName, lessonIndex):
+        return self.chapters.getChapters()[chapterName].getLessons()[lessonIndex]


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]