From e59ebea703fcdbdba29d39bdd0e367fbd1753e5e Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Mon, 19 Jan 2009 00:20:37 +0000 Subject: ... --- diff --git a/Shared.py b/Activity.py index d786ad3..fa6ec09 100644 --- a/Shared.py +++ b/Activity.py @@ -1,3 +1,17 @@ +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + from sugar.activity import activity from sugar.presence import presenceservice from sugar.presence.tubeconn import TubeConnection @@ -7,14 +21,36 @@ from dbus import Interface from dbus.service import method, signal from dbus.gobject_service import ExportedGObject +from Main import * + SERVICE = 'org.freedesktop.Telepathy.Tube.Connect' IFACE = SERVICE PATH = '/org/freedesktop/Telepathy/Tube/Connect' -class Shared(activity.Activity): +TMPDIR = os.path.join(get_activity_root(), 'tmp') + +class CartoonBuilderActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self,handle) + self.connect("destroy",self.destroy_cb) + #app = cartoonbuilder(self,'/home/olpc/Activities/CartoonBuilder.activity') + bundle_path = activity.get_bundle_path() + os.chdir(bundle_path) + self.app = CartoonBuilder(True,self, bundle_path) + self.set_title('CartoonBuilder') + toolbox = activity.ActivityToolbox(self) + bgtoolbar = BGToolbar(self,self.app) + toolbox.add_toolbar(_('Background'),bgtoolbar) + bgtoolbar.show() + self.set_toolbox(toolbox) + toolbox.show() + if hasattr(self, '_jobject'): + self._jobject.metadata['title'] = 'CartoonBuilder' + title_widget = toolbox._activity_toolbar.title + title_widget.set_size_request(title_widget.get_layout().get_pixel_size()[0] + 20, -1) + self.set_canvas(self.app.main) + # mesh stuff self.pservice = presenceservice.get_instance() owner = self.pservice.get_owner() @@ -41,7 +77,6 @@ class Shared(activity.Activity): # we are creating the activity pass - def _shared_cb(self,activity): self.initiating = True self._setup() @@ -136,6 +171,16 @@ class Shared(activity.Activity): id, group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP]) self.game = ConnectGame(tube_conn, self.initiating, self) + def destroy_cb(self, data=None): + return True + + def read_file(self, filepath): + Bundle.load(filepath) + + def write_file(self, filepath): + Bundle.save(filepath) + + class ConnectGame(ExportedGObject): def __init__(self,tube, is_initiator, activity): super(ConnectGame,self).__init__(tube,PATH) @@ -174,7 +219,6 @@ class ConnectGame(ExportedGObject): def hello_cb(self, sender=None): self.tube.get_object(sender, PATH).Welcome(self.activity.app.getsdata(),dbus_interface=IFACE) - """ def getsdata(self): #self.lessonplans.set_label('getting sdata') diff --git a/Char.py b/Char.py index a6efb6f..c00b4ce 100644 --- a/Char.py +++ b/Char.py @@ -20,7 +20,7 @@ class Char: id = 0 pixbuf = None #gtk.gdk.Pixbuf() -def list(): +def themes(): return [Char()] @@ -105,5 +105,19 @@ def list(): entrypath = os.path.join(TMPDIR,entry) os.remove(entrypath) +def prepare_btn(btn, w=-1, h=-1): + for state, color in COLOR_BG_BUTTONS: + btn.modify_bg(state, gtk.gdk.color_parse(color)) + c = btn.get_child() + if c is not None: + for state, color in COLOR_FG_BUTTONS: + c.modify_fg(state, gtk.gdk.color_parse(color)) + else: + for state, color in COLOR_FG_BUTTONS: + btn.modify_fg(state, gtk.gdk.color_parse(color)) + if w>0 or h>0: + btn.set_size_request(w, h) + return btn + """ diff --git a/Ground.py b/Ground.py new file mode 100644 index 0000000..ff67c6c --- /dev/null +++ b/Ground.py @@ -0,0 +1,24 @@ +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gtk + +Size = (100, 100) + +class Ground: + id = 0 + pixbuf = None #gtk.gdk.Pixbuf() + +def themes(): + return [Ground()] diff --git a/cartoonbuilder.py b/Main.py index 06903da..ab3380b 100755..100644 --- a/cartoonbuilder.py +++ b/Main.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # 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 2 of the License, or @@ -15,7 +13,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # - ### cartoonbuilder ### ### author: Ed Stoner (ed@whsd.net) @@ -24,7 +21,6 @@ import time import StringIO import pygtk -pygtk.require('2.0') import gtk import gobject import gettext @@ -32,111 +28,21 @@ import os import zipfile import textwrap import pickle -# should really put a try in front of this -# in case there is no sound support import gst + from sugar.activity.activity import get_activity_root +from sugar.graphics.toolbutton import ToolButton +from sugar.graphics.objectchooser import ObjectChooser +import Theme from ComboBox import * from Shared import * import Char +import Ground +import Sound _ = gettext.lgettext -TRANSIMG = '50x50blank-trans.png' -BGHEIGHT = gtk.gdk.screen_height() - 450 # 425 -BGWIDTH = BGHEIGHT # 425 -IMGHEIGHT = 100 -IMGWIDTH = 100 - -BORDER_LEFT = 1 -BORDER_RIGHT = 2 -BORDER_TOP = 4 -BORDER_BOTTOM = 8 -BORDER_VERTICAL = BORDER_TOP | BORDER_BOTTOM -BORDER_HORIZONTAL = BORDER_LEFT | BORDER_RIGHT -BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL -BORDER_ALL_BUT_BOTTOM = BORDER_HORIZONTAL | BORDER_TOP -BORDER_ALL_BUT_LEFT = BORDER_VERTICAL | BORDER_RIGHT - -SLICE_BTN_WIDTH = 40 - -# Colors from the Rich's UI design - -GRAY = "#B7B7B7" # gray -PINK = "#FF0099" # pink -YELLOW = "#FFFF00" # yellow -WHITE = "#FFFFFF" -BLACK = "#000000" -BACKGROUND = "#66CC00" # light green -BUTTON_FOREGROUND = "#CCFB99" # very light green -BUTTON_BACKGROUND = "#027F01" # dark green -COLOR_FG_BUTTONS = ( - (gtk.STATE_NORMAL,"#CCFF99"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#CCFF99"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#CCFF99"), - ) # very light green -COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#027F01"), - ) -OLD_COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#014D01"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#027F01"), - (gtk.STATE_INSENSITIVE,"#027F01"), - ) - -SPANISH = u'Espa\xf1ol' -#SPANISH = 'Espanol' -LANGLIST = ['English',SPANISH] -LANG = {'English':{'character':'My Character', - 'sound':'My Sound', - 'background':'My Background', - 'lessonplan':'Lesson Plans', - 'lpdir':'lp-en'}, - SPANISH:{'character':u'Mi car\xe1cter', - 'sound':'Mi sonido', - 'background':'Mi fondo', - 'lessonplan':u'Planes de la lecci\xf3n', - 'lpdir':'lp-es'}} - -FRAME_COUNT = (gtk.gdk.screen_height() - 370) / IMGHEIGHT * 2 -TAPE_COUNT = (gtk.gdk.screen_width() - 430) / IMGWIDTH - -TMPDIR = os.path.join(get_activity_root(), 'tmp') - -def getwrappedfile(filepath,linelength): - text = [] - f = file(filepath) - for line in f: - if line == '\n': - text.append(line) - else: - for wline in textwrap.wrap(line.strip()): - text.append('%s\n' % wline) - return ''.join(text) - -def prepare_btn(btn, w=-1, h=-1): - for state, color in COLOR_BG_BUTTONS: - btn.modify_bg(state, gtk.gdk.color_parse(color)) - c = btn.get_child() - if c is not None: - for state, color in COLOR_FG_BUTTONS: - c.modify_fg(state, gtk.gdk.color_parse(color)) - else: - for state, color in COLOR_FG_BUTTONS: - btn.modify_fg(state, gtk.gdk.color_parse(color)) - if w>0 or h>0: - btn.set_size_request(w, h) - return btn - class FrameWidget(gtk.DrawingArea): def __init__(self,bgpixbuf,fgpixbuf): gtk.DrawingArea.__init__(self) @@ -167,22 +73,7 @@ class FrameWidget(gtk.DrawingArea): widget.window.draw_pixbuf(self.gc,self.fgpixbuf,0,0,0,0,-1,-1,0,0) -class cartoonbuilder: - def delete_event(self, widget, event, data=None): - return False - - def destroy(self, widget, data=None): - gtk.main_quit() - - def on_gstmessage(self, bus, message): - t = message.type - if t == gst.MESSAGE_EOS: - # END OF SOUND FILE - self.player.set_state(gst.STATE_NULL) - self.player.set_state(gst.STATE_PLAYING) - elif t == gst.MESSAGE_ERROR: - self.player.set_state(gst.STATE_NULL) - +class CartoonBuilder: def clearframe(self, widget, data=None): transpixbuf = self.gettranspixbuf(IMGWIDTH,IMGHEIGHT) self.frameimgs[self.frame_selected].set_from_pixbuf(transpixbuf) @@ -221,7 +112,7 @@ class cartoonbuilder: self.fgpixbuf = fgpixbuf self.drawmain() - def lastback(self, widget, data=None): + def _ground_cb(self, widget): if self.backnum == 0: self.backnum = len(self.backpicpaths)-1 else: @@ -229,14 +120,6 @@ class cartoonbuilder: bgimgpath = self.backpicpaths[self.backnum] self.setback(bgimgpath) - def nextback(self, widget, data=None): - if self.backnum == (len(self.backpicpaths)-1): - self.backnum = 0 - else: - self.backnum += 1 - bgimgpath = self.backpicpaths[self.backnum] - self.setback(bgimgpath) - def setback(self,imgpath): #self.mfdraw.queue_draw() #pixbuf = gtk.gdk.pixbuf_new_from_file(self.bgimgpath) @@ -257,40 +140,13 @@ class cartoonbuilder: self.loadimages() self.drawmain() - def changesound(self): - if self.soundfile: - soundname = os.path.splitext(os.path.split(self.soundfile)[1])[0] - self.player.set_property('uri', 'file://' + self.soundfile) - if self.playing: - self.player.set_state(gst.STATE_NULL) - self.player.set_state(gst.STATE_PLAYING) - else: - soundname = 'No Sound' - if self.playing: - self.player.set_state(gst.STATE_NULL) - self.soundlabel.set_text(soundname.capitalize()) - - def lastsound(self, widget, data=None): - if self.soundindex == 0: - self.soundindex = (len(self.sounds)-1) - else: - self.soundindex -= 1 - self.soundfile = self.sounds[self.soundindex] - self.changesound() - - def nextsound(self, widget, data=None): - if self.soundindex == (len(self.sounds)-1): - self.soundindex = 0 - else: - self.soundindex += 1 - self.soundfile = self.sounds[self.soundindex] - self.changesound() + def _sound_cb(self, widget): + Sound.switch(widget.props.value) def go(self, widget, data=None): self.playframenum = 0 if self.playing: - if self.soundfile: - self.player.set_state(gst.STATE_NULL) + Sound.stop() #widget.set_label('GO!') playimg = gtk.Image() #playimg.set_from_stock(gtk.STOCK_MEDIA_PLAY,gtk.ICON_SIZE_BUTTON) @@ -299,9 +155,7 @@ class cartoonbuilder: widget.set_image(playimg) self.playing = False else: - if self.soundfile: - #self.player.set_property('uri', 'file://' + self.soundfile) - self.player.set_state(gst.STATE_PLAYING) + Sound.play() #widget.set_label('STOP') stopimg = gtk.Image() #stopimg.set_from_stock(gtk.STOCK_MEDIA_STOP,gtk.ICON_SIZE_BUTTON) @@ -424,59 +278,8 @@ class cartoonbuilder: scaled_buf = pixbuf.scale_simple(width,height,gtk.gdk.INTERP_BILINEAR) return scaled_buf - """ - def showlessonplans(self, widget, data=None): - dia = gtk.Dialog(title='Lesson Plans', - parent=None, - flags=0, - buttons=None) - dia.set_default_size(500,500) - dia.show() - - #dia.vbox.pack_start(scrolled_window, True, True, 0) - notebook = gtk.Notebook() - # uncomment below to highlight tabs - notebook.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) - notebook.set_tab_pos(gtk.POS_TOP) - #notebook.set_default_size(400,400) - notebook.show() - lessonplans = {} - lpdir = os.path.join(self.mdirpath,LANG[self.language]['lpdir']) - lpentries = os.listdir(lpdir) - for entry in lpentries: - fpath = os.path.join(lpdir,entry) - lessonplans[entry] = getwrappedfile(fpath,80) - lpkeys = lessonplans.keys() - lpkeys.sort() - for lpkey in lpkeys: - lpname = lpkey.replace('_',' ').replace('0','')[:-4] - label = gtk.Label(lessonplans[lpkey]) - #if self.insugar: - # label.modify_fg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) - eb = gtk.EventBox() - eb.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) - #label.set_line_wrap(True) - label.show() - eb.add(label) - eb.show() - #tlabel = gtk.Label('Lesson Plan %s' % str(i+1)) - tlabel = gtk.Label(lpname) - tlabel.show() - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) - scrolled_window.show() - scrolled_window.add_with_viewport(eb) - notebook.append_page(scrolled_window, tlabel) - #dia.action_area.pack_start(notebook, True, True, 0) - dia.vbox.pack_start(notebook, True, True, 0) - result = dia.run() - dia.destroy() - """ - def __init__(self,insugar,toplevel_window,mdirpath): self.mdirpath = mdirpath - if not os.path.isdir(TMPDIR): - os.mkdir(TMPDIR) self.iconsdir = os.path.join(self.mdirpath,'icons') self.playing = False self.backnum = 0 @@ -501,25 +304,7 @@ class cartoonbuilder: imgdirfile.close() self.imgdirindex = 0 self.imgstartindex = 0 - self.sounds = [''] - soundfile = file(os.path.join(self.mdirpath,'config.sounds')) - for line in soundfile: - soundfilepath = line.strip() - if soundfilepath[0] != '/': - soundfilepath = os.path.join(self.mdirpath,line.strip()) - if os.path.isfile(soundfilepath): - self.sounds.append(soundfilepath) - soundfile.close() - self.soundindex = 0 - self.soundfile = self.sounds[self.soundindex] - # START GSTREAMER STUFF - self.player = gst.element_factory_make("playbin", "player") - fakesink = gst.element_factory_make('fakesink', "my-fakesink") - self.player.set_property("video-sink", fakesink) - self.bus = self.player.get_bus() - self.bus.add_signal_watch() - self.bus.connect('message', self.on_gstmessage) - # END GSTREAMER STUFF + self.fgpixbuf = self.gettranspixbuf(BGWIDTH,BGHEIGHT) @@ -528,6 +313,9 @@ class cartoonbuilder: + + + self.langoframe = gtk.EventBox() self.langoframe.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(YELLOW)) self.langoframe.show() @@ -601,7 +389,6 @@ class cartoonbuilder: upa.show() self.imgupbutton.add(upa) - prepare_btn(self.imgupbutton) self.iubhbox = gtk.HBox() self.iubhbox.show() self.iubhbox.pack_start(self.imgupbutton,True,False,0) @@ -637,7 +424,6 @@ class cartoonbuilder: downa.set_from_file(os.path.join(self.iconsdir,'big_down_arrow.png')) downa.show() self.imgdownbutton.add(downa) - prepare_btn(self.imgdownbutton) self.idbhbox = gtk.HBox() self.idbhbox.show() self.idbhbox.pack_start(self.imgdownbutton,True,False,0) @@ -724,7 +510,6 @@ class cartoonbuilder: self.clrframe.set_label('') self.clrframe.set_image(cancelimg) self.clrframe.connect('clicked', self.clearall, None) - prepare_btn(self.clrframe) self.clrframe.show() #self.cfbox.pack_start(self.clrframe,True,True,0) @@ -771,7 +556,6 @@ class cartoonbuilder: self.gobutton.set_label('') self.gobutton.set_image(playimg) self.gobutton.connect('clicked', self.go, None) - prepare_btn(self.gobutton) self.gobutton.show() self.bcontrolbox.pack_start(self.gobutton,True,True,5) @@ -799,96 +583,30 @@ class cartoonbuilder: # CHARACTER CONTROLS char_box = BigComboBox() char_box.show() - for i in Char.list(): + for i in Char.themes(): char_box.append_item(i.id, size = Char.Size, pixbuf = i.pixbuf) char_box.connect('changed', self._char_cb) self.controlbox.pack_start(char_box, False, False, 5) # BACKGROUND CONTROLS - - - self.bgbox = gtk.VBox() - self.bgbox.show() - self.bghbox = gtk.HBox() - self.bghbox.show() - self.blbutton = gtk.Button() - self.blbutton.connect('clicked',self.lastback,None) - self.blbutton.show() - bla = gtk.Image() - bla.set_from_file(os.path.join(self.iconsdir,'big_left_arrow.png')) - bla.show() - self.blbutton.add(bla) - prepare_btn(self.blbutton) - self.blbvbox = gtk.VBox() - self.blbvbox.show() - self.blbvbox.pack_start(self.blbutton,True,False,0) - self.bghbox.pack_start(self.blbvbox,True,True,5) - self.bgsmall = gtk.Image() - bgimgpath = os.path.join(self.mdirpath,'backpics/bigbg01.gif') - self.setback(bgimgpath) - self.bgsmall.show() - self.bghbox.pack_start(self.bgsmall,False,False,0) - self.brbutton = gtk.Button() - self.brbutton.connect('clicked',self.nextback,None) - self.brbutton.show() - bra = gtk.Image() - bra.set_from_file(os.path.join(self.iconsdir,'big_right_arrow.png')) - bra.show() - self.brbutton.add(bra) - prepare_btn(self.brbutton) - self.brbvbox = gtk.VBox() - self.brbvbox.show() - self.brbvbox.pack_start(self.brbutton,True,False,0) - self.bghbox.pack_start(self.brbvbox,True,True,5) - self.bgbox.pack_start(self.bghbox,True,True,0) - self.controlbox.pack_start(self.bgbox,False,False,5) + bg_box = BigComboBox() + bg_box.show() + for i in Ground.themes(): + bg_box.append_item(i.id, size = Ground.Size, + pixbuf = i.pixbuf) + bg_box.connect('changed', self._ground_cb) + self.controlbox.pack_start(bg_box, False, False, 5) # SOUND CONTROLS - self.soundbox = gtk.VBox() - self.soundbox.show() - self.soundhbox = gtk.HBox() - self.soundhbox.show() - self.slbutton = gtk.Button() - self.slbutton.connect('clicked',self.lastsound,None) - self.slbutton.show() - sla = gtk.Image() - sla.set_from_file(os.path.join(self.iconsdir,'big_left_arrow.png')) - sla.show() - self.slbutton.add(sla) - prepare_btn(self.slbutton) - self.slbvbox = gtk.VBox() - self.slbvbox.show() - self.slbvbox.pack_start(self.slbutton,True,False,0) - self.soundhbox.pack_start(self.slbvbox,True,True,5) - self.soundimg = gtk.Image() - #self.soundimg.set_from_file(os.path.join(self.iconsdir,'sound_icon.png')) - soundimgpath = os.path.join(self.iconsdir,'sound_icon.png') - sipixbuf = gtk.gdk.pixbuf_new_from_file(soundimgpath) - si_scaled_buf = sipixbuf.scale_simple(IMGWIDTH,IMGHEIGHT,gtk.gdk.INTERP_BILINEAR) - self.soundimg.set_from_pixbuf(si_scaled_buf) - self.soundimg.show() - self.soundhbox.pack_start(self.soundimg,False,False,0) - self.srbutton = gtk.Button() - self.srbutton.connect('clicked',self.nextsound,None) - self.srbutton.show() - sra = gtk.Image() - sra.set_from_file(os.path.join(self.iconsdir,'big_right_arrow.png')) - sra.show() - self.srbutton.add(sra) - prepare_btn(self.srbutton) - self.srbvbox = gtk.VBox() - self.srbvbox.show() - self.srbvbox.pack_start(self.srbutton,True,False,0) - self.soundhbox.pack_start(self.srbvbox,True,True,5) - self.soundbox.pack_start(self.soundhbox,True,True,0) - self.soundlabel = gtk.Label('No Sound') - self.soundlabel.show() - self.soundlabelhbox = gtk.HBox() - self.soundlabelhbox.show() - self.soundlabelhbox.pack_start(self.soundlabel,True,False,0) - self.soundbox.pack_start(self.soundlabelhbox,False,False,0) - self.controlbox.pack_start(self.soundbox,False,False,5) + sound_box = BigComboBox() + sound_box.show() + for i in Sound.themes(): + sound_box.append_item(i.id, size = Sound.Size, + pixbuf = i.pixbuf) + sound_box.connect('changed', self._sound_cb) + self.controlbox.pack_start(sound_box, False, False, 5) + @@ -970,83 +688,106 @@ class cartoonbuilder: def main(self): gtk.main() -try: - from sugar.graphics.toolbutton import ToolButton - from sugar.graphics.objectchooser import ObjectChooser - - class BGToolbar(gtk.Toolbar): - def __init__(self,sactivity,app): - gtk.Toolbar.__init__(self) - self.sactivity = sactivity - self.app = app - self.image = ToolButton('insert-image') - self.image.set_tooltip('Insert Image') - self.imageid = self.image.connect('clicked',self.image_cb) - self.insert(self.image,-1) - self.image.show() - - def image_cb(self, button): - chooser = ObjectChooser('Choose Image',self.sactivity, - gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) - try: - result = chooser.run() - if result == gtk.RESPONSE_ACCEPT: - jobject = chooser.get_selected_object() - if jobject and jobject.file_path: - self.app.setback(jobject.file_path) - finally: - chooser.destroy() - del chooser - - class cartoonbuilderActivity(Shared): - def __init__(self, handle): - Shared.__init__(self,handle) - self.connect("destroy",self.destroy_cb) - #app = cartoonbuilder(self,'/home/olpc/Activities/CartoonBuilder.activity') - bundle_path = activity.get_bundle_path() - os.chdir(bundle_path) - self.app = cartoonbuilder(True,self, bundle_path) - self.set_title('CartoonBuilder') - toolbox = activity.ActivityToolbox(self) - bgtoolbar = BGToolbar(self,self.app) - toolbox.add_toolbar(_('Background'),bgtoolbar) - bgtoolbar.show() - self.set_toolbox(toolbox) - toolbox.show() - if hasattr(self, '_jobject'): - self._jobject.metadata['title'] = 'CartoonBuilder' - title_widget = toolbox._activity_toolbar.title - title_widget.set_size_request(title_widget.get_layout().get_pixel_size()[0] + 20, -1) - self.set_canvas(self.app.main) - - def destroy_cb(self, data=None): - return True +class BGToolbar(gtk.Toolbar): + def __init__(self,sactivity,app): + gtk.Toolbar.__init__(self) + self.sactivity = sactivity + self.app = app + self.image = ToolButton('insert-image') + self.image.set_tooltip('Insert Image') + self.imageid = self.image.connect('clicked',self.image_cb) + self.insert(self.image,-1) + self.image.show() + + def image_cb(self, button): + chooser = ObjectChooser('Choose Image',self.sactivity, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) + try: + result = chooser.run() + if result == gtk.RESPONSE_ACCEPT: + jobject = chooser.get_selected_object() + if jobject and jobject.file_path: + self.app.setback(jobject.file_path) + finally: + chooser.destroy() + del chooser + + +""" +SPANISH = u'Espa\xf1ol' +#SPANISH = 'Espanol' +LANGLIST = ['English',SPANISH] +LANG = {'English':{'character':'My Character', + 'sound':'My Sound', + 'background':'My Background', + 'lessonplan':'Lesson Plans', + 'lpdir':'lp-en'}, + SPANISH:{'character':u'Mi car\xe1cter', + 'sound':'Mi sonido', + 'background':'Mi fondo', + 'lessonplan':u'Planes de la lecci\xf3n', + 'lpdir':'lp-es'}} - def read_file(self, filepath): - Bundle.load(filepath) - def write_file(self, filepath): - Bundle.save(filepath) +def getwrappedfile(filepath,linelength): + text = [] + f = file(filepath) + for line in f: + if line == '\n': + text.append(line) + else: + for wline in textwrap.wrap(line.strip()): + text.append('%s\n' % wline) + return ''.join(text) -except ImportError: - pass -if __name__ == "__main__": - # have to do toplevel window stuff here because Sugar does it on the OLPC - toplevel_window = gtk.Window(gtk.WINDOW_TOPLEVEL) - #mdirpath = '.' - mdirpath = os.path.abspath(os.curdir) - app = cartoonbuilder(False,toplevel_window,mdirpath) - toplevel_window.add(app.main) - toplevel_window.set_title('Cartoon Builder') - # FULLSCREEN - #toplevel_window.set_decorated(False) - #toplevel_window.fullscreen() - - toplevel_window.connect("delete_event", app.delete_event) - toplevel_window.connect("destroy", app.destroy) - #toplevel_window.set_border_width(10) - toplevel_window.show() - gtk.main() + def showlessonplans(self, widget, data=None): + dia = gtk.Dialog(title='Lesson Plans', + parent=None, + flags=0, + buttons=None) + dia.set_default_size(500,500) + dia.show() + + #dia.vbox.pack_start(scrolled_window, True, True, 0) + notebook = gtk.Notebook() + # uncomment below to highlight tabs + notebook.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + notebook.set_tab_pos(gtk.POS_TOP) + #notebook.set_default_size(400,400) + notebook.show() + lessonplans = {} + lpdir = os.path.join(self.mdirpath,LANG[self.language]['lpdir']) + lpentries = os.listdir(lpdir) + for entry in lpentries: + fpath = os.path.join(lpdir,entry) + lessonplans[entry] = getwrappedfile(fpath,80) + lpkeys = lessonplans.keys() + lpkeys.sort() + for lpkey in lpkeys: + lpname = lpkey.replace('_',' ').replace('0','')[:-4] + label = gtk.Label(lessonplans[lpkey]) + #if self.insugar: + # label.modify_fg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + eb = gtk.EventBox() + eb.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(WHITE)) + #label.set_line_wrap(True) + label.show() + eb.add(label) + eb.show() + #tlabel = gtk.Label('Lesson Plan %s' % str(i+1)) + tlabel = gtk.Label(lpname) + tlabel.show() + scrolled_window = gtk.ScrolledWindow() + scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) + scrolled_window.show() + scrolled_window.add_with_viewport(eb) + notebook.append_page(scrolled_window, tlabel) + #dia.action_area.pack_start(notebook, True, True, 0) + dia.vbox.pack_start(notebook, True, True, 0) + result = dia.run() + dia.destroy() + """ + diff --git a/Sound.py b/Sound.py new file mode 100644 index 0000000..e070d5c --- /dev/null +++ b/Sound.py @@ -0,0 +1,81 @@ +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gtk + +Size = (100, 100) + +class Sound: + id = 0 + pixbuf = None #gtk.gdk.Pixbuf() + +def themes(): + return [Sound()] + +def play(): + if self.soundfile: + #self.player.set_property('uri', 'file://' + self.soundfile) + self.player.set_state(gst.STATE_PLAYING) + +def stop(): + if self.soundfile: + self.player.set_state(gst.STATE_NULL) + +def switch(id): + self.soundfile = self.sounds[self.soundindex] + + if self.soundfile: + soundname = os.path.splitext(os.path.split(self.soundfile)[1])[0] + self.player.set_property('uri', 'file://' + self.soundfile) + if self.playing: + self.player.set_state(gst.STATE_NULL) + self.player.set_state(gst.STATE_PLAYING) + else: + soundname = 'No Sound' + if self.playing: + self.player.set_state(gst.STATE_NULL) + self.soundlabel.set_text(soundname.capitalize()) + + +def on_gstmessage(self, bus, message): + t = message.type + if t == gst.MESSAGE_EOS: + # END OF SOUND FILE + self.player.set_state(gst.STATE_NULL) + self.player.set_state(gst.STATE_PLAYING) + elif t == gst.MESSAGE_ERROR: + self.player.set_state(gst.STATE_NULL) + +def init(): + self.sounds = [''] + soundfile = file(os.path.join(self.mdirpath,'config.sounds')) + for line in soundfile: + soundfilepath = line.strip() + if soundfilepath[0] != '/': + soundfilepath = os.path.join(self.mdirpath,line.strip()) + if os.path.isfile(soundfilepath): + self.sounds.append(soundfilepath) + soundfile.close() + + self.soundfile = self.sounds[self.soundindex] + + # START GSTREAMER STUFF + self.player = gst.element_factory_make("playbin", "player") + fakesink = gst.element_factory_make('fakesink', "my-fakesink") + self.player.set_property("video-sink", fakesink) + self.bus = self.player.get_bus() + self.bus.add_signal_watch() + self.bus.connect('message', self.on_gstmessage) + # END GSTREAMER STUFF + diff --git a/Theme.py b/Theme.py new file mode 100644 index 0000000..d5483f4 --- /dev/null +++ b/Theme.py @@ -0,0 +1,66 @@ +# 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +TRANSIMG = '50x50blank-trans.png' +BGHEIGHT = gtk.gdk.screen_height() - 450 # 425 +BGWIDTH = BGHEIGHT # 425 +IMGHEIGHT = 100 +IMGWIDTH = 100 + +BORDER_LEFT = 1 +BORDER_RIGHT = 2 +BORDER_TOP = 4 +BORDER_BOTTOM = 8 +BORDER_VERTICAL = BORDER_TOP | BORDER_BOTTOM +BORDER_HORIZONTAL = BORDER_LEFT | BORDER_RIGHT +BORDER_ALL = BORDER_VERTICAL | BORDER_HORIZONTAL +BORDER_ALL_BUT_BOTTOM = BORDER_HORIZONTAL | BORDER_TOP +BORDER_ALL_BUT_LEFT = BORDER_VERTICAL | BORDER_RIGHT + +SLICE_BTN_WIDTH = 40 + +# Colors from the Rich's UI design + +GRAY = "#B7B7B7" # gray +PINK = "#FF0099" # pink +YELLOW = "#FFFF00" # yellow +WHITE = "#FFFFFF" +BLACK = "#000000" +BACKGROUND = "#66CC00" # light green +BUTTON_FOREGROUND = "#CCFB99" # very light green +BUTTON_BACKGROUND = "#027F01" # dark green +COLOR_FG_BUTTONS = ( + (gtk.STATE_NORMAL,"#CCFF99"), + (gtk.STATE_ACTIVE,"#CCFF99"), + (gtk.STATE_PRELIGHT,"#CCFF99"), + (gtk.STATE_SELECTED,"#CCFF99"), + (gtk.STATE_INSENSITIVE,"#CCFF99"), + ) # very light green +COLOR_BG_BUTTONS = ( + (gtk.STATE_NORMAL,"#027F01"), + (gtk.STATE_ACTIVE,"#CCFF99"), + (gtk.STATE_PRELIGHT,"#016D01"), + (gtk.STATE_SELECTED,"#CCFF99"), + (gtk.STATE_INSENSITIVE,"#027F01"), + ) +OLD_COLOR_BG_BUTTONS = ( + (gtk.STATE_NORMAL,"#027F01"), + (gtk.STATE_ACTIVE,"#014D01"), + (gtk.STATE_PRELIGHT,"#016D01"), + (gtk.STATE_SELECTED,"#027F01"), + (gtk.STATE_INSENSITIVE,"#027F01"), + ) + +FRAME_COUNT = (gtk.gdk.screen_height() - 370) / IMGHEIGHT * 2 +TAPE_COUNT = (gtk.gdk.screen_width() - 430) / IMGWIDTH diff --git a/activity/activity.info b/activity/activity.info index 36db43d..ca1c51d 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,7 +1,7 @@ [Activity] name = CartoonBuilder service_name = com.ywwg.CartoonBuilderActivity -class = cartoonbuilder.cartoonbuilderActivity +class = Activity.CartoonBuilderActivity icon = activity-cartoonbuilder activity_version = 1 show_launcher = yes -- cgit v0.9.1