# gcompris - louis_braille.py # # Copyright (C) 2011 Bruno Coudoin | Srishti Sethi # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # louis_braille activity. import gtk import gtk.gdk import gcompris import gcompris.utils import gcompris.skin import gcompris.bonus import goocanvas import pango import random import ConfigParser from BrailleChar import * from gcompris import gcompris_gettext as _ COLOR_ON = 0XFF0000FFL COLOR_OFF= 0XFFFFFFFFL CIRCLE_FILL = "white" CELL_WIDTH = 30 LOUIS_BRAILLE_NAME = ['L','O','U','I','S','B','R','A','I','L','L','E'] class Gcompris_louis_braille: """Empty gcompris python class""" def __init__(self, gcomprisBoard): # Save the gcomprisBoard, it defines everything we need # to know from the core self.gcomprisBoard = gcomprisBoard self.gcomprisBoard.level=1 self.gcomprisBoard.sublevel=1 self.gcomprisBoard.number_of_sublevel=1 self.gcomprisBoard.maxlevel = 12 # Needed to get key_press gcomprisBoard.disable_im_context = True def start(self): # Set the buttons we want in the bar gcompris.bar_set (0) # Set a background image gcompris.set_background(self.gcomprisBoard.canvas.get_root_item(), "louis_braille/background.svgz") #Initialize variables self.won = 0 self.counter = 0 self.gamewon = 0 self.item = 0 self.groupitem_array = [] self.coorditem_array = [] self.read_data() self.display_story() def read_data(self): '''Load the activity data''' config = ConfigParser.RawConfigParser() p = gcompris.get_properties() filename = gcompris.DATA_DIR + '/' + self.gcomprisBoard.name + '/activity.desktop' try: gotit = config.read(filename) if not gotit: gcompris.utils.dialog(_("Cannot find the file '{filename}'").format(filename=filename),None) return False except ConfigParser.Error as error: gcompris.utils.dialog(_("Failed to parse data set '{filename}' with error:\n{error}"). format(filename=filename, error=error), None) return False self.dataset = config return True def display_game(self): gcompris.bar_location(gcompris.BOARD_WIDTH - 120, -1, 0.8) self.rootitem = goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item()) n_lines = 11 self.reordering = Reordering(self, n_lines) # Insert the lines in the correct order for index in range(n_lines): self.reordering.add_line( _(str(self.dataset.get(str(index + 1), "story"))) ) ok = goocanvas.Svg(parent = self.rootitem, svg_handle = gcompris.skin.svg_get(), svg_id = "#OK", tooltip = _("Click to confirm your sequence") ) ok.translate(200,-70) ok.connect("button_press_event", self.ok_event) gcompris.utils.item_focus_init(ok, None) def display_story(self): gcompris.bar_location(gcompris.BOARD_WIDTH - 140, 350, 0.8) self.rootitem = goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item()) goocanvas.Rect( parent = self.rootitem, x = 50, y = 20, width = 700, height = 95, radius_x = 10, radius_y = 10, stroke_color_rgba = 0x666666FFL, fill_color_rgba = 0x33333333L, line_width = 2.0 ) # Previous Button ok = goocanvas.Svg( parent = self.rootitem, svg_handle = gcompris.skin.svg_get(), svg_id = "#PREVIOUS", ) ok.translate(-300,50) ok.connect("button_press_event", self.previous_event, None) gcompris.utils.item_focus_init(ok, None) # Next Button ok = goocanvas.Svg(parent = self.rootitem, svg_handle = gcompris.skin.svg_get(), svg_id = "#NEXT", ) ok.translate(75,-58) ok.connect("button_press_event", self.next_event, None) gcompris.utils.item_focus_init(ok, None) # Display name of louis braille for index in range(5): BrailleChar(self.rootitem,(index+1) *(CELL_WIDTH + 20)+30, 20, 50, LOUIS_BRAILLE_NAME[index] ,COLOR_ON, COLOR_OFF, CIRCLE_FILL, CIRCLE_FILL, True,False ,False, None) for index in range(5,12): BrailleChar(self.rootitem,(index+1) *(CELL_WIDTH + 20)+65, 20, 50, LOUIS_BRAILLE_NAME[index] ,COLOR_ON, COLOR_OFF, CIRCLE_FILL, CIRCLE_FILL,True,False ,False, None) # Displaying the YEAR self.year_item = \ goocanvas.Text(parent = self.rootitem, x = 420.0, y = 400.0, fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER, font = gcompris.skin.get_font("gcompris/title") ) # Rectangle for YEAR self.year_rect = \ goocanvas.Rect(parent=self.rootitem, x = 40, y = 425, width = 720, height = 85, stroke_color = "orange", fill_color = "white", line_width = 2.0) self.year_rect.lower(None) # Rectangle for STORY goocanvas.Rect(parent=self.rootitem, x = 20, y = 425, width = 760, height = 85, stroke_color = "orange", fill_color = "white", line_width = 2.0) # Displaying the STORY self.storyitem = \ goocanvas.Text(parent = self.rootitem, x=400.0, y=465.0, fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER, width = 750, font = gcompris.skin.get_font("gcompris/subtitle") ) self.imageitem = \ goocanvas.Image(parent = self.rootitem, x = 300, y = 120, ) self.imageitem.connect("button_press_event", self.next_event, None) self.display_image() def display_image(self): pixbuf = \ gcompris.utils.load_pixmap( (str(self.dataset.get(str(self.gcomprisBoard.level), "image"))) ) self.imageitem.set_properties(pixbuf = pixbuf) story = _(self.dataset.get( str(self.gcomprisBoard.level), "story")) self.storyitem.set_properties(text = story) year = _(self.dataset.get( str(self.gcomprisBoard.level) , "year")) self.year_item.set_properties(text = year) bounds = self.year_item.get_bounds() gapx = 10 gapy = 4 self.year_rect.set_properties( x = bounds.x1 - gapx, y = bounds.y1 - gapy, width = (bounds.x2 - bounds.x1) + gapx * 2, height = (bounds.y2 - bounds.y1) + gapy * 2, ) def ok_event(self, event ,target ,item): if ( self.reordering.is_done() ): gcompris.bonus.display(gcompris.bonus.WIN,gcompris.bonus.TUX) self.gamewon = 1 else : self.reordering.is_not_done() def refresh_level(self): if ( self.gcomprisBoard.level == 1 ): self.end() self.display_story() elif ( self.gcomprisBoard.level != 12 ): self.display_image() else: self.end() self.display_game() def previous_event(self, event, target,item, dummy): if (self.gcomprisBoard.level == 1): self.gcomprisBoard.level = self.gcomprisBoard.maxlevel else : self.gcomprisBoard.level -= 1 self.refresh_level() def next_event(self, event, target, item, dummy): if (self.gcomprisBoard.level == self.gcomprisBoard.maxlevel): self.gcomprisBoard.level = 1 else : self.gcomprisBoard.level += 1 self.refresh_level() def end(self): # Remove the root item removes all the others inside it self.rootitem.remove() def ok(self): pass def repeat(self): pass def config(self): pass def key_press(self, keyval, commit_str, preedit_str): utf8char = gtk.gdk.keyval_to_unicode(keyval) strn = u'%c' % utf8char def pause(self, pause): if(self.gamewon == 1): self.gcomprisBoard.level = 1 self.end() self.start() def set_level(self, level): pass class Reordering: """This class manages the reordering activity""" def __init__(self, louisbraille, max_item): self.louisbraille = louisbraille self.rootitem = louisbraille.rootitem self.index = 0 self.randoms = range(max_item) random.shuffle(self.randoms) self.orders = range(max_item) def dump(self): for index, item in enumerate(self.orders): print index, item.get_data("index") # Return True if all the items are properly placed def is_done(self): for index, item in enumerate(self.orders): group_index = item.get_data("index") if ( group_index != index ): return False return True # To indicate correct and wrong lines def is_not_done(self): for index , item in enumerate (self.orders): group_index = item.get_data("index") rectbox = item.get_data("rectbox") if ( group_index != index ): rectbox.set_property("fill_color_rgba", 0xed6d6deeL) else : rectbox.set_property("fill_color_rgba", 0x80e072eeL) # Reset the lines to the original color, no good or bad position mark def reset_selection(self): for index , item in enumerate (self.orders): group_index = item.get_data("index") rectbox = item.get_data("rectbox") rectbox.set_property("fill_color_rgba", 0xEEEEEEEEL) def add_line(self, text): position = self.randoms[ self.index ] y = (position + 0.5) * 43 group_item = goocanvas.Group(parent = self.rootitem, y = y) # Save in the item itself where is its correct position group_item.set_data("index", self.index) # Create Rounded Rectangles for each story rect_box = goocanvas.Rect(parent = group_item, x = 30, y = 0, width = 640, height = 40, radius_x = 5, radius_y = 5, stroke_color = "black", fill_color_rgba = 0xEEEEEEEEL, line_width = 2.0) group_item.set_data("rectbox", rect_box) self.orders[ position ] = group_item # Displaying the STORY goocanvas.Text(parent = group_item, x = 350.0, y = 20, text = text, fill_color = "black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER, font = 'SANS 9', width = 635, ) group_item.connect("button_press_event", self.component_drag) group_item.connect("motion_notify_event", self.component_drag) group_item.connect("button_release_event", self.component_drag) self.index += 1 # Return the index in self.orders of the given group def get_group_index(self, group): return self.orders.index(group) def move_group(self, from_index, to_index): from_item = self.orders[from_index] (from_x, from_y) = from_item.get_properties('x', 'y') to_item = self.orders[to_index] to_x = to_item.get_data('xref') to_y = to_item.get_data('yref') from_item.set_properties(x = to_x, y = to_y) to_item.set_data("xref", from_x) to_item.set_data("yref", from_y) self.orders[from_index], self.orders[to_index] = self.orders[to_index], self.orders[from_index] def swap_with_group_near(self, group, y): for index, item in enumerate(self.orders): bounds = item.get_bounds() if ( group != item and y < bounds.y2 and y > bounds.y1 ): self.move_group( index, self.get_group_index(group) ) return def component_drag(self, widget, target, event): groupitem = target.get_parent() groupitem.raise_(None) if event.type == gtk.gdk.BUTTON_PRESS: self.reset_selection() bounds = groupitem.get_bounds() self.offset_y = event.y # We save the x and y coord in xref and yref for future use (x, y) = groupitem.get_properties('x', 'y') groupitem.set_data("xref", x) groupitem.set_data("yref", y) elif ( event.type == gtk.gdk.MOTION_NOTIFY and event.state & gtk.gdk.BUTTON1_MASK ): groupitem.translate(0, event.y - self.offset_y) (x, y) = self.louisbraille.gcomprisBoard.canvas.\ convert_from_item_space(groupitem, event.x, event.y) self.swap_with_group_near(groupitem, y) elif event.type == gtk.gdk.BUTTON_RELEASE: groupitem.set_transform(None) to_x = groupitem.get_data('xref') to_y = groupitem.get_data('yref') groupitem.set_properties(x = to_x, y = to_y) return True