# gcompris - pythontest # # Copyright (C) 2003, 2008 Bruno Coudoin # # 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 . # # PythonTest Board module import gobject import goocanvas import gcompris import gcompris.utils import gcompris.skin import gcompris.admin import gtk import gtk.gdk import random import cairo import pango from gcompris import gcompris_gettext as _ class Gcompris_pythontest: """Testing gcompris python class""" def __init__(self, gcomprisBoard): self.gcomprisBoard = gcomprisBoard self.gcomprisBoard.disable_im_context = True self.canvasitems = {} self.colors = {} self.colors['circle_in'] = 0x8080FFFF self.colors['circle_out'] = 0xFFFFFFFF self.colors['line'] = 0xFFFF40FF # Just for config demo self.config_colors = { 'red' : 0xFF0000FFL, 'green' : 0x00FF00FFL, 'blue' : 0x0000FFFFL } # dict .keys() list of keys has random order self.config_colors_list = [ 'red', 'green', 'blue'] self.movingline='none' # Find a number game self.solution = random.randint(0,9) print("Gcompris_pythontest __init__.") #initialisation to default values. Some of them will be replaced by #the configured values. def start(self): logged = gcompris.admin.get_current_user() # API Test, return the absolute path to this file print gcompris.utils.find_file_absolute("sounds/bleep.wav") # wordlist = gcompris.get_wordlist('wordslevel_max_pt_BR') # print wordlist # print wordlist.filename # print wordlist.level # print wordlist.locale # print wordlist.description # print wordlist.words if logged: print "User Logged in:" print " ", logged.login, logged.firstname, logged.lastname self.gcomprisBoard.level=1 self.gcomprisBoard.maxlevel=1 self.gcomprisBoard.sublevel=1 self.gcomprisBoard.number_of_sublevel=1 # 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'): gcompris.set_locale(self.config_dict['locale']) # self.colors['line'] s set in init. # I put here the configuration use color_name = self.config_dict['color_line'] self.colors['line'] = self.config_colors[color_name] gcompris.bar_set(gcompris.BAR_CONFIG) gcompris.set_default_background(self.gcomprisBoard.canvas.get_root_item()) gcompris.bar_set_level(self.gcomprisBoard) # Create our rootitem. We put each canvas item in it so at the end we # only have to kill it. The canvas deletes all the items it contains automaticaly. self.rootitem = goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item()) # distance is used to demo of gcompris.spin_int distance = eval(self.config_dict['distance_circle']) # pattern is for gcompris.radio_buttons pattern = self.config_dict['pattern'] patterns = { 'circle': goocanvas.Ellipse, 'rectangle': goocanvas.Rect } #error check if not patterns.has_key(pattern): pattern = 'circle' self.canvasitems[1] = patterns[pattern]( parent = self.rootitem, fill_color_rgba= self.colors['circle_in'], stroke_color_rgba= self.colors['circle_out'], line_width=1.0 ) self.canvasitems[1].connect("button_press_event", self.circle_item_event) self.canvasitems[1].connect("button_release_event", self.circle_item_event) self.canvasitems[1].connect("motion_notify_event", self.circle_item_event) if(pattern == 'circle'): self.canvasitems[1].set_properties( center_x = 400.0 - distance, center_y = 200.0, radius_x = 20, radius_y = 20) else: self.canvasitems[1].set_properties( x = 400.0 - distance, y = 200.0, width = 20, height = 20) self.canvasitems[2] = patterns[pattern]( parent = self.rootitem, fill_color_rgba= self.colors['circle_in'], stroke_color_rgba= self.colors['circle_out'], line_width=1.0 ) self.canvasitems[2].connect("button_press_event", self.circle_item_event) self.canvasitems[2].connect("button_release_event", self.circle_item_event) self.canvasitems[2].connect("motion_notify_event", self.circle_item_event) if(pattern == 'circle'): self.canvasitems[2].set_properties( center_x = 400.0 + distance, center_y = 200.0, radius_x = 20, radius_y = 20) else: self.canvasitems[2].set_properties( x = 400.0 + distance, y = 200.0, width = 20, height = 20) self.canvasitems[3] = goocanvas.Text( parent = self.rootitem, x=400.0, y=100.0, text=_("This is the first plugin in GCompris coded in the Python\nProgramming language."), fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) self.canvasitems[4] = goocanvas.Text( parent = self.rootitem, x=400.0, y=140.0, text=_("It is now possible to develop GCompris activities in C or in Python.\nThanks to Olivier Samys who makes this possible."), fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) self.canvasitems[5] = goocanvas.Text( parent = self.rootitem, x=400.0, y=250.0, text=_("This activity is not playable, just a test"), fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) #---------------------------------------- # A simple game. # Try to hit left shift and right shift together. The peed increases goocanvas.Rect( parent = self.rootitem, x = 20, y = gcompris.BOARD_HEIGHT-220, width = gcompris.BOARD_WIDTH-40, height = 150, fill_color_rgba=0xFF663333L, stroke_color_rgba=0xFF33CCAAL, line_width=2.0) # For the game status WIN/LOOSE self.canvasitems[6] = goocanvas.Text( parent = self.rootitem, x=gcompris.BOARD_WIDTH / 2, y=gcompris.BOARD_HEIGHT - 100, font=gcompris.skin.get_font("gcompris/content"), fill_color_rgba=0x102010FFL, anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) goocanvas.Text( parent = self.rootitem, x=400.0, y=360.0, text=("Test your reflex with the counter. Hit the 2 shifts key together.\nHit space to reset the counter and increase the speed.\nBackspace to reset the speed"), fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) # The basic tick for object moves self.timerinc = 1000 self.timer_inc = gobject.timeout_add(self.timerinc, self.timer_inc_display) self.counter_left = 0 self.counter_right = 0 self.canvasitems[7] =goocanvas.Text( parent = self.rootitem, x=gcompris.BOARD_WIDTH / 2, y=gcompris.BOARD_HEIGHT - 120, font=gcompris.skin.get_font("gcompris/content"), text="Speed="+str(self.timerinc)+" ms", fill_color="black", anchor = gtk.ANCHOR_CENTER, alignment = pango.ALIGN_CENTER ) self.textitem_left = goocanvas.Text( parent = self.rootitem, font=gcompris.skin.get_font("gcompris/content"), x=gcompris.BOARD_WIDTH / 3, y=gcompris.BOARD_HEIGHT - 100, fill_color_rgba=0xFF000FFFL ) self.textitem_right =goocanvas.Text( parent = self.rootitem, font=gcompris.skin.get_font("gcompris/content"), x=gcompris.BOARD_WIDTH / 1.5, y=gcompris.BOARD_HEIGHT - 100, fill_color_rgba=0xFF000FFFL ) self.left_continue = True self.right_continue = True print("Gcompris_pythontest start.") def end(self): gcompris.set_locale( "" ) # Remove the root item removes all the others inside it self.rootitem.remove() if self.timer_inc : gobject.source_remove(self.timer_inc) def ok(self): print("Gcompris_pythontest ok.") def repeat(self): print("Gcompris_pythontest repeat.") def key_press(self, keyval, commit_str, preedit_str): utf8char = gtk.gdk.keyval_to_unicode(keyval) strn = u'%c' % utf8char print("Gcompris_pythontest key press keyval=%i %s" % (keyval, strn)) win = False if (keyval == gtk.keysyms.Shift_L): self.left_continue = False if (keyval == gtk.keysyms.Shift_R): self.right_continue = False if(not self.left_continue and not self.right_continue): if(self.counter_left == self.counter_right): self.canvasitems[6].set_properties(text = "WIN", fill_color_rgba = 0x002EB8FFL) win=True else: self.canvasitems[6].set_properties(text = "LOOSE", fill_color_rgba = 0xFF0000FFL) if ((keyval == gtk.keysyms.BackSpace) or (keyval == gtk.keysyms.Delete)): self.timerinc = 1100 keyval = 32 if (keyval == 32): self.left_continue = True self.right_continue = True self.counter_left = 0 self.counter_right = 0 if(win): if(self.timerinc>500): self.timerinc -= 100 elif(self.timerinc>200): self.timerinc -= 50 elif(self.timerinc>10): self.timerinc -= 10 elif(self.timerinc>1): self.timerinc -= 1 if(self.timerinc<1): self.timerinc = 1 self.canvasitems[3].set_properties(text="") self.canvasitems[6].set_properties(text="") self.canvasitems[7].set_properties(text="Speed="+str(self.timerinc)+" ms") # Find a number game if str(self.solution) == strn: print "WIN" else: print "LOST" # Return True if you did process a key # Return False if you did not processed a key # (gtk need to send it to next widget) return True def pause(self, pause): print("Gcompris_pythontest pause. %i" % pause) def set_level(self, level): print("Gcompris_pythontest set level. %i" % level) # ---- End of Initialisation def timer_inc_display(self): if(self.left_continue): self.textitem_left.set_properties(text=str(self.counter_left)) self.counter_left += self.timer_inc if(self.right_continue): self.textitem_right.set_properties(text=str(self.counter_right)) self.counter_right += self.timer_inc self.timer_inc = gobject.timeout_add(self.timerinc, self.timer_inc_display) def circle_item_event(self, widget, target, event=None): if eval(self.config_dict['disable_line']): return False if event.type == gtk.gdk.BUTTON_PRESS: if event.button == 1: bounds = widget.get_bounds() self.pos_x = (bounds.x1+bounds.x2)/2 self.pos_y = (bounds.y1+bounds.y2)/2 if 'line 1' in self.canvasitems: self.canvasitems['line 1'].remove() self.canvasitems['line 1'] =goocanvas.Polyline( parent = self.rootitem, points = goocanvas.Points([(self.pos_x, self.pos_y), (event.x, event.y)]), fill_color_rgba = self.colors['line'], line_cap = cairo.LINE_CAP_ROUND, line_width = 6.0 ) self.movingline='line 1' print "Button press" return True if event.type == gtk.gdk.MOTION_NOTIFY: if event.state & gtk.gdk.BUTTON1_MASK: self.canvasitems[self.movingline].set_properties( points = goocanvas.Points([(self.pos_x, self.pos_y), (event.x, event.y)]) ) if event.type == gtk.gdk.BUTTON_RELEASE: if event.button == 1: self.movingline='line 1' print "Button release" return True return False ################################################### # Configuration system ################################################### #mandatory but unused yet def config_stop(self): pass # Configuration function. def config_start(self, profile): # keep profile in mind # profile can be Py_None self.configuring_profile = profile # init with default values self.config_dict = self.init_config() #get the configured values for that profile self.config_dict.update(gcompris.get_conf(profile, self.gcomprisBoard)) # Init configuration window: # all the configuration functions will use it # all the configuration functions returns values for their key in # the dict passed to the apply_callback # the returned value is the main GtkVBox of the window, #we can add what you want in it. bconf = gcompris.configuration_window ( \ _('%s configuration\n for profile %s') % ('Pythontest', (profile.name if profile else "") ), self.ok_callback ) # toggle box control_line = gcompris.boolean_box(bconf, _('Disable line drawing in circle'), 'disable_line', eval(self.config_dict['disable_line']) ) # sample of control in python control_line.connect("toggled", self.color_disable) # combo box self.color_choice = \ gcompris.combo_box(bconf, _('Color of the line'), self.config_colors_list, 'color_line', self.config_dict['color_line'] ) self.color_choice.set_sensitive(not eval(self.config_dict['disable_line'])) gcompris.separator(bconf) #spin button for int self.distance_box = \ gcompris.spin_int(bconf, _('Distance between circles'), 'distance_circle', 20, 200, 20, eval(self.config_dict['distance_circle']) ) gcompris.separator(bconf) #radio buttons for circle or rectangle patterns = { 'circle': _('Use circles'), 'rectangle': _('Use rectangles') } # FIXME radio button makes the configuration unstable # the problem is perhaps in the C code but since # no one use it, let's forget it for now. # gcompris.radio_buttons(bconf, _('Choice of pattern'), # 'pattern', # patterns, # self.config_dict['pattern'] # ) print "List of locales shown in gcompris.combo_locale :" print gcompris.get_locales_list() gcompris.separator(bconf) gcompris.combo_locales(bconf, self.config_dict['locale']) gcompris.separator(bconf) print "List of locales shown in gcompris.combo_locales_asset :" locales_purple = gcompris.get_locales_asset_list( "purple.ogg" ) print locales_purple gcompris.combo_locales_asset(bconf, _("Select sound locale"), self.config_dict['locale_sound'], "voices/$LOCALE/colors/red.ogg") def color_disable(self, button): self.color_choice.set_sensitive(not button.get_active()) # Callback when the "OK" button is clicked in configuration window # this get all the _changed_ values def ok_callback(self, table): if (table == None): print 'Configuration returns None' return True print "Keys and values returned by PythonTest config window:" if (len(table) == 0): print '%20s' % 'None' for key,value in table.iteritems(): print '%20s:%20s ' % (key, value) gcompris.set_board_conf(self.configuring_profile, self.gcomprisBoard, key, value) return True; def init_config(self): default_config = { 'disable_line' : 'False', 'color_line' : 'red', 'distance_circle' : '100', 'pattern' : 'circle', 'locale' : 'NULL', 'locale_sound' : 'NULL' } return default_config