From 3cefd7c251ae1a82352c491ef178be0c9b72cb0d Mon Sep 17 00:00:00 2001 From: florent Date: Sun, 11 Sep 2011 15:14:24 +0000 Subject: add pygame activity template --- diff --git a/creactigame/__init__.py b/creactigame/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/__init__.py diff --git a/creactigame/_templates/+package+/__init__.py b/creactigame/_templates/+package+/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/+package+/__init__.py diff --git a/creactigame/_templates/+package+/activity.py_tmpl b/creactigame/_templates/+package+/activity.py_tmpl new file mode 100644 index 0000000..62a9a8b --- /dev/null +++ b/creactigame/_templates/+package+/activity.py_tmpl @@ -0,0 +1,134 @@ +# python import +import logging +from gettext import gettext as _ + + + +# gtk import +import gtk + +# pygame import +import pygame + +# sugar import +from sugar.activity import activity +from sugar.graphics.toolbutton import ToolButton + +# sugargame import +import sugargame.canvas + +# get application logger +logger = logging.getLogger('{{package}}') + + +class {{package.capitalize()}}Game(object): + + def __init__(self): + # Set up a clock for managing the frame rate. + self.clock = pygame.time.Clock() + # pos + self.x = -100 + self.y = 100 + # .. + self.vx = 10 + self.vy = 0 + # pause flag + self.paused = False + + def set_paused(self, paused): + self.paused = paused + + # Called to save the state of the game to the Journal. + def write_file(self, file_path): + pass + + # Called to load the state of the game from the Journal. + def read_file(self, file_path): + pass + + # The main game loop. + def run(self): + # run flag + self.running = True + # get screen + screen = pygame.display.get_surface() + # game loop + while self.running: + # Pump GTK messages. + while gtk.events_pending(): + gtk.main_iteration() + # Pump PyGame messages. + for event in pygame.event.get(): + if event.type == pygame.QUIT: + return + elif event.type == pygame.VIDEORESIZE: + pygame.display.set_mode(event.size, pygame.RESIZABLE) + # Move the ball + if not self.paused: + # .. + self.x += self.vx + if self.x > screen.get_width() + 100: + self.x = -100 + # .. + self.y += self.vy + if self.y > screen.get_height() - 100: + self.y = screen.get_height() - 100 + self.vy = -self.vy + # .. + self.vy += 5; + # Clear Display + screen.fill((255,255,255)) #255 for white + # Draw the ball + pygame.draw.circle(screen, (255,0,0), (self.x, self.y), 100) + # Flip Display + pygame.display.flip() + # Try to stay at 30 FPS + self.clock.tick(30) + + +class {{package.capitalize()}}Activity(activity.Activity): + + def __init__(self, handle): + super({{package.capitalize()}}Activity, self).__init__(handle) + # .. + self.paused = False + # Create the game instance. + self.game = {{package.capitalize()}}Game() + # Build the activity toolbar. + self.build_toolbar() + # Build the Pygame canvas. + self._pygamecanvas = sugargame.canvas.PygameCanvas(self) + # Note that set_canvas implicitly calls read_file when resuming from the Journal. + self.set_canvas(self._pygamecanvas) + # Start the game running (self.game.run is called when the activity constructor returns). + self._pygamecanvas.run_pygame(self.game.run) + + def build_toolbar(self): + stop_play = ToolButton('media-playback-stop') + stop_play.set_tooltip(_("Stop")) + stop_play.set_accelerator(_('space')) + stop_play.connect('clicked', self._stop_play_cb) + toolbar = gtk.Toolbar() + toolbar.insert(stop_play, 0) + toolbox = activity.ActivityToolbox(self) + toolbox.add_toolbar(_("Pygame"), toolbar) + toolbox.show_all() + self.set_toolbox(toolbox) + + def _stop_play_cb(self, button): + # Pause or unpause the game. + self.paused = not self.paused + self.game.set_paused(self.paused) + # Update the button to show the next action. + if self.paused: + button.set_icon('media-playback-start') + button.set_tooltip(_("Start")) + else: + button.set_icon('media-playback-stop') + button.set_tooltip(_("Stop")) + + def read_file(self, file_path): + self.game.read_file(file_path) + + def write_file(self, file_path): + self.game.write_file(file_path) diff --git a/creactigame/_templates/MANIFEST_tmpl b/creactigame/_templates/MANIFEST_tmpl new file mode 100644 index 0000000..2e6128f --- /dev/null +++ b/creactigame/_templates/MANIFEST_tmpl @@ -0,0 +1,16 @@ +prune ./docs +prune ./po +recursive-exclude *.swp +recursive-exclude *.pyc +activity +activity/activity-{{package}}.svg +activity/activity.info +{{package}} +{{package}}/activity.py +locale +locale/en +locale/en/LC_MESSAGES +locale/fr +locale/fr/LC_MESSAGES +MANIFEST +setup.py diff --git a/creactigame/_templates/activity/activity-+package+.svg b/creactigame/_templates/activity/activity-+package+.svg new file mode 100755 index 0000000..bdfad6f --- /dev/null +++ b/creactigame/_templates/activity/activity-+package+.svg @@ -0,0 +1,232 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/creactigame/_templates/activity/activity.info_tmpl b/creactigame/_templates/activity/activity.info_tmpl new file mode 100755 index 0000000..2107b3f --- /dev/null +++ b/creactigame/_templates/activity/activity.info_tmpl @@ -0,0 +1,7 @@ +[Activity] +name = {{project.capitalize()}} +activity_version = 1 +service_name = org.laptop.{{project.capitalize()}}Activity +icon = activity-{{package}} +class = {{project}}.activity.{{project.capitalize()}}Activity +license = gplv3 diff --git a/creactigame/_templates/docs/Makefile b/creactigame/_templates/docs/Makefile new file mode 100644 index 0000000..c869fd6 --- /dev/null +++ b/creactigame/_templates/docs/Makefile @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/piloter-magento-avec-openerp.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/piloter-magento-avec-openerp.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/piloter-magento-avec-openerp" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/piloter-magento-avec-openerp" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/creactigame/_templates/docs/build/blank b/creactigame/_templates/docs/build/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/docs/build/blank diff --git a/creactigame/_templates/docs/source/+package+/index.rst b/creactigame/_templates/docs/source/+package+/index.rst new file mode 100644 index 0000000..ed52021 --- /dev/null +++ b/creactigame/_templates/docs/source/+package+/index.rst @@ -0,0 +1,7 @@ +.. _activity: + + +Write The Doc +============= + +here diff --git a/creactigame/_templates/docs/source/_static/blank b/creactigame/_templates/docs/source/_static/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/docs/source/_static/blank diff --git a/creactigame/_templates/docs/source/_templates/blank b/creactigame/_templates/docs/source/_templates/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/docs/source/_templates/blank diff --git a/creactigame/_templates/docs/source/conf.py_tmpl b/creactigame/_templates/docs/source/conf.py_tmpl new file mode 100644 index 0000000..29c6cba --- /dev/null +++ b/creactigame/_templates/docs/source/conf.py_tmpl @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- +# +# piloter-magento-avec-openerp documentation build configuration file, created by +# sphinx-quickstart on Thu Apr 21 21:04:43 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.todo'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'{{package.capitalize()}} - Activity Doc' +copyright = u'2011, The Developer' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '1.0' +# The full version, including alpha/beta/rc tags. +release = '1.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = '{{package}}-doc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ( + 'index', + u'{{package}}-doc', + u'The Developer', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ( + 'index', + '{{package}}-doc', + u'{{package.capitalize()}} - Activity Doc', + [u'The Developer'], + 1) +] diff --git a/creactigame/_templates/docs/source/index.rst_tmpl b/creactigame/_templates/docs/source/index.rst_tmpl new file mode 100644 index 0000000..9b18813 --- /dev/null +++ b/creactigame/_templates/docs/source/index.rst_tmpl @@ -0,0 +1,28 @@ +.. _index: + +{{package.capitalize()}} - Activity Doc +======================================= + + +.. image:: sugar.png + :alt: Sugar + + +.. sidebar:: Document Info + + Auteur : The Developer, juillet 2011 + + Licence : Creative Commons 3.0 By-Sa + + +.. toctree:: + :maxdepth: 2 + + {{package}}/index + + +Indices and tables +================== + +* :ref:`search` + diff --git a/creactigame/_templates/docs/source/sugar.png b/creactigame/_templates/docs/source/sugar.png new file mode 100644 index 0000000..fae049e --- /dev/null +++ b/creactigame/_templates/docs/source/sugar.png Binary files differ diff --git a/creactigame/_templates/locale/en/LC_MESSAGES/blank b/creactigame/_templates/locale/en/LC_MESSAGES/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/locale/en/LC_MESSAGES/blank diff --git a/creactigame/_templates/locale/fr/LC_MESSAGES/blank b/creactigame/_templates/locale/fr/LC_MESSAGES/blank new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/creactigame/_templates/locale/fr/LC_MESSAGES/blank diff --git a/creactigame/_templates/po/app.fil_tmpl b/creactigame/_templates/po/app.fil_tmpl new file mode 100644 index 0000000..c9eb29b --- /dev/null +++ b/creactigame/_templates/po/app.fil_tmpl @@ -0,0 +1 @@ +../{{package}}/activity.py diff --git a/creactigame/_templates/po/create_pot.sh_tmpl b/creactigame/_templates/po/create_pot.sh_tmpl new file mode 100644 index 0000000..847847b --- /dev/null +++ b/creactigame/_templates/po/create_pot.sh_tmpl @@ -0,0 +1,8 @@ +#/bin/sh +# gen pot file +python mki18n.py -p --domain=org.laptop.{{package.capitalize()}}Activity +# set utf-8 charset +sed 's/CHARSET/utf-8/g' -i messages.pot +# gen dummy po files +cp messages.pot org.laptop.{{package.capitalize()}}Activity_en.po +cp messages.pot org.laptop.{{package.capitalize()}}Activity_fr.po diff --git a/creactigame/_templates/po/gen_mo.sh_tmpl b/creactigame/_templates/po/gen_mo.sh_tmpl new file mode 100644 index 0000000..4436a49 --- /dev/null +++ b/creactigame/_templates/po/gen_mo.sh_tmpl @@ -0,0 +1,2 @@ +#/bin/sh +python mki18n.py -m -e --domain=org.laptop.{{package.capitalize()}}Activity --moTarget=../locale diff --git a/creactigame/_templates/po/mki18n.py b/creactigame/_templates/po/mki18n.py new file mode 100644 index 0000000..f4156d6 --- /dev/null +++ b/creactigame/_templates/po/mki18n.py @@ -0,0 +1,459 @@ +#! /usr/bin/env python +# -*- coding: iso-8859-1 -*- +# +# PYTHON MODULE: MKI18N.PY +# ========= +# +# Abstract: Make Internationalization (i18n) files for an application. +# +# Copyright Pierre Rouleau. 2003. Released to public domain. +# +# Last update: Saturday, November 8, 2003. @ 15:55:18. +# +# File: ROUP2003N01::C:/dev/python/mki18n.py +# +# RCS $Header: //software/official/MKS/MKS_SI/TV_NT/dev/Python/rcs/mki18n.py 1.5 2003/11/05 19:40:04 PRouleau Exp $ +# +# Update history: +# +# - File created: Saturday, June 7, 2003. by Pierre Rouleau +# - 10/06/03 rcs : RCS Revision 1.1 2003/06/10 10:06:12 PRouleau +# - 10/06/03 rcs : RCS Initial revision +# - 23/08/03 rcs : RCS Revision 1.2 2003/06/10 10:54:27 PRouleau +# - 23/08/03 P.R.: [code:fix] : The strings encoded in this file are encode in iso-8859-1 format. Added the encoding +# notification to Python to comply with Python's 2.3 PEP 263. +# - 23/08/03 P.R.: [feature:new] : Added the '-e' switch which is used to force the creation of the empty English .mo file. +# - 22/10/03 P.R.: [code] : incorporated utility functions in here to make script self sufficient. +# - 05/11/03 rcs : RCS Revision 1.4 2003/10/22 06:39:31 PRouleau +# - 05/11/03 P.R.: [code:fix] : included the unixpath() in this file. +# - 08/11/03 rcs : RCS Revision 1.5 2003/11/05 19:40:04 PRouleau +# +# RCS $Log: $ +# +# +# ----------------------------------------------------------------------------- +""" +mki18n allows you to internationalize your software. You can use it to +create the GNU .po files (Portable Object) and the compiled .mo files +(Machine Object). + +mki18n module can be used from the command line or from within a script (see +the Usage at the end of this page). + + Table of Contents + ----------------- + + makePO() -- Build the Portable Object file for the application -- + catPO() -- Concatenate one or several PO files with the application domain files. -- + makeMO() -- Compile the Portable Object files into the Machine Object stored in the right location. -- + printUsage -- Displays how to use this script from the command line -- + + Scriptexecution -- Runs when invoked from the command line -- + + +NOTE: this module uses GNU gettext utilities. + +You can get the gettext tools from the following sites: + + - `GNU FTP site for gettetx`_ where several versions (0.10.40, 0.11.2, 0.11.5 and 0.12.1) are available. + Note that you need to use `GNU libiconv`_ to use this. Get it from the `GNU + libiconv ftp site`_ and get version 1.9.1 or later. Get the Windows .ZIP + files and install the packages inside c:/gnu. All binaries will be stored + inside c:/gnu/bin. Just put c:/gnu/bin inside your PATH. You will need + the following files: + + - `gettext-runtime-0.12.1.bin.woe32.zip`_ + - `gettext-tools-0.12.1.bin.woe32.zip`_ + - `libiconv-1.9.1.bin.woe32.zip`_ + + +.. _GNU libiconv: http://www.gnu.org/software/libiconv/ +.. _GNU libiconv ftp site: http://www.ibiblio.org/pub/gnu/libiconv/ +.. _gettext-runtime-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-runtime-0.12.1.bin.woe32.zip +.. _gettext-tools-0.12.1.bin.woe32.zip: ftp://ftp.gnu.org/gnu/gettext/gettext-tools-0.12.1.bin.woe32.zip +.. _libiconv-1.9.1.bin.woe32.zip: http://www.ibiblio.org/pub/gnu/libiconv/libiconv-1.9.1.bin.woe32.zip + +""" +# ----------------------------------------------------------------------------- +# Module Import +# ------------- +# +import os +import sys +# import wx +# ----------------------------------------------------------------------------- +# Global variables +# ---------------- +# + +__author__ = "Pierre Rouleau" +__version__= "$Revision: 1.5 $" + +# ----------------------------------------------------------------------------- + +def getlanguageDict(): + languageDict = { + 'en': '', + 'fr': '' + } + """ + for lang in [x for x in dir(wx) if x.startswith("LANGUAGE")]: + i = wx.Locale(wx.LANGUAGE_DEFAULT).GetLanguageInfo(getattr(wx, lang)) + if i: + languageDict[i.CanonicalName] = i.Description + """ + return languageDict + +# ----------------------------------------------------------------------------- +# m a k e P O ( ) -- Build the Portable Object file for the application -- +# ^^^^^^^^^^^^^^^ +# +def makePO(applicationDirectoryPath, applicationDomain=None, verbose=0) : + """Build the Portable Object Template file for the application. + + makePO builds the .pot file for the application stored inside + a specified directory by running xgettext for all application source + files. It finds the name of all files by looking for a file called 'app.fil'. + If this file does not exists, makePo raises an IOError exception. + By default the application domain (the application + name) is the same as the directory name but it can be overridden by the + 'applicationDomain' argument. + + makePO always creates a new file called messages.pot. If it finds files + of the form app_xx.po where 'app' is the application name and 'xx' is one + of the ISO 639 two-letter language codes, makePO resynchronizes those + files with the latest extracted strings (now contained in messages.pot). + This process updates all line location number in the language-specific + .po files and may also create new entries for translation (or comment out + some). The .po file is not changed, instead a new file is created with + the .new extension appended to the name of the .po file. + + By default the function does not display what it is doing. Set the + verbose argument to 1 to force it to print its commands. + """ + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + if not os.path.exists('app.fil'): + raise IOError(2,'No module file: app.fil') + + # Steps: + # Use xgettext to parse all application modules + # The following switches are used: + # + # -s : sort output by string content (easier to use when we need to merge several .po files) + # --files-from=app.fil : The list of files is taken from the file: app.fil + # --output= : specifies the name of the output file (using a .pot extension) + cmd = 'xgettext -s --no-wrap --files-from=app.fil --output=messages.pot' + if verbose: print cmd + os.system(cmd) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if langCode == 'en': + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + cmd = 'msgmerge -s --no-wrap "%s" messages.pot > "%s.new"' % (langPOfileName, langPOfileName) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# c a t P O ( ) -- Concatenate one or several PO files with the application domain files. -- +# ^^^^^^^^^^^^^ +# +def catPO(applicationDirectoryPath, listOf_extraPo, applicationDomain=None, targetDir=None, verbose=0) : + """Concatenate one or several PO files with the application domain files. + """ + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if langCode == 'en': + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + fileList = '' + for fileName in listOf_extraPo: + fileList += ("%s_%s.po " % (fileName,langCode)) + cmd = "msgcat -s --no-wrap %s %s > %s.cat" % (langPOfileName, fileList, langPOfileName) + if verbose: print cmd + os.system(cmd) + if targetDir is None: + pass + else: + mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode) + cmd = "msgfmt --output-file=%s/%s.mo %s_%s.po.cat" % (mo_targetDir,applicationName,applicationName,langCode) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# m a k e M O ( ) -- Compile the Portable Object files into the Machine Object stored in the right location. -- +# ^^^^^^^^^^^^^^^ +# +def makeMO(applicationDirectoryPath,targetDir='./locale',applicationDomain=None, verbose=0, forceEnglish=0) : + """Compile the Portable Object files into the Machine Object stored in the right location. + + makeMO converts all translated language-specific PO files located inside + the application directory into the binary .MO files stored inside the + LC_MESSAGES sub-directory for the found locale files. + + makeMO searches for all files that have a name of the form 'app_xx.po' + inside the application directory specified by the first argument. The + 'app' is the application domain name (that can be specified by the + applicationDomain argument or is taken from the directory name). The 'xx' + corresponds to one of the ISO 639 two-letter language codes. + + makeMo stores the resulting files inside a sub-directory of `targetDir` + called xx/LC_MESSAGES where 'xx' corresponds to the 2-letter language + code. + """ + if targetDir is None: + targetDir = './locale' + if verbose: + print "Target directory for .mo files is: %s" % targetDir + + if applicationDomain is None: + applicationName = fileBaseOf(applicationDirectoryPath,withPath=0) + else: + applicationName = applicationDomain + currentDir = os.getcwd() + os.chdir(applicationDirectoryPath) + + languageDict = getlanguageDict() + + for langCode in languageDict.keys(): + if (langCode == 'en') and (forceEnglish==0): + pass + else: + langPOfileName = "%s_%s.po" % (applicationName , langCode) + if os.path.exists(langPOfileName): + mo_targetDir = "%s/%s/LC_MESSAGES" % (targetDir,langCode) + if not os.path.exists(mo_targetDir): + mkdir(mo_targetDir) + cmd = 'msgfmt --output-file="%s/%s.mo" "%s_%s.po"' % (mo_targetDir,applicationName,applicationName,langCode) + if verbose: print cmd + os.system(cmd) + os.chdir(currentDir) + +# ----------------------------------------------------------------------------- +# p r i n t U s a g e -- Displays how to use this script from the command line -- +# ^^^^^^^^^^^^^^^^^^^ +# +def printUsage(errorMsg=None) : + """Displays how to use this script from the command line.""" + print """ + ################################################################################## + # mki18n : Make internationalization files. # + # Uses the GNU gettext system to create PO (Portable Object) files # + # from source code, coimpile PO into MO (Machine Object) files. # + # Supports C,C++,Python source files. # + # # + # Usage: mki18n {OPTION} [appDirPath] # + # # + # Options: # + # -e : When -m is used, forces English .mo file creation # + # -h : prints this help # + # -m : make MO from existing PO files # + # -p : make PO, update PO files: Creates a new messages.pot # + # file. Creates a dom_xx.po.new for every existing # + # language specific .po file. ('xx' stands for the ISO639 # + # two-letter language code and 'dom' stands for the # + # application domain name). mki18n requires that you # + # write a 'app.fil' file which contains the list of all # + # source code to parse. # + # -v : verbose (prints comments while running) # + # --domain=appName : specifies the application domain name. By default # + # the directory name is used. # + # --moTarget=dir : specifies the directory where .mo files are stored. # + # If not specified, the target is './locale' # + # # + # You must specify one of the -p or -m option to perform the work. You can # + # specify the path of the target application. If you leave it out mki18n # + # will use the current directory as the application main directory. # + # # + ##################################################################################""" + if errorMsg: + print "\n ERROR: %s" % errorMsg + +# ----------------------------------------------------------------------------- +# f i l e B a s e O f ( ) -- Return base name of filename -- +# ^^^^^^^^^^^^^^^^^^^^^^^ +# +def fileBaseOf(filename,withPath=0) : + """fileBaseOf(filename,withPath) ---> string + + Return base name of filename. The returned string never includes the extension. + Use os.path.basename() to return the basename with the extension. The + second argument is optional. If specified and if set to 'true' (non zero) + the string returned contains the full path of the file name. Otherwise the + path is excluded. + + [Example] + >>> fn = 'd:/dev/telepath/tvapp/code/test.html' + >>> fileBaseOf(fn) + 'test' + >>> fileBaseOf(fn) + 'test' + >>> fileBaseOf(fn,1) + 'd:/dev/telepath/tvapp/code/test' + >>> fileBaseOf(fn,0) + 'test' + >>> fn = 'abcdef' + >>> fileBaseOf(fn) + 'abcdef' + >>> fileBaseOf(fn,1) + 'abcdef' + >>> fn = "abcdef." + >>> fileBaseOf(fn) + 'abcdef' + >>> fileBaseOf(fn,1) + 'abcdef' + """ + pos = filename.rfind('.') + if pos > 0: + filename = filename[:pos] + if withPath: + return filename + else: + return os.path.basename(filename) +# ----------------------------------------------------------------------------- +# m k d i r ( ) -- Create a directory (and possibly the entire tree) -- +# ^^^^^^^^^^^^^ +# +def mkdir(directory) : + """Create a directory (and possibly the entire tree). + + The os.mkdir() will fail to create a directory if one of the + directory in the specified path does not exist. mkdir() + solves this problem. It creates every intermediate directory + required to create the final path. Under Unix, the function + only supports forward slash separator, but under Windows and MacOS + the function supports the forward slash and the OS separator (backslash + under windows). + """ + + # translate the path separators + directory = unixpath(directory) + # build a list of all directory elements + aList = filter(lambda x: len(x)>0, directory.split('/')) + theLen = len(aList) + # if the first element is a Windows-style disk drive + # concatenate it with the first directory + if aList[0].endswith(':'): + if theLen > 1: + aList[1] = aList[0] + '/' + aList[1] + del aList[0] + theLen -= 1 + # if the original directory starts at root, + # make sure the first element of the list + # starts at root too + if directory[0] == '/': + aList[0] = '/' + aList[0] + # Now iterate through the list, check if the + # directory exists and if not create it + theDir = '' + for i in range(theLen): + theDir += aList[i] + if not os.path.exists(theDir): + os.mkdir(theDir) + theDir += '/' + +# ----------------------------------------------------------------------------- +# u n i x p a t h ( ) -- Return a path name that contains Unix separator. -- +# ^^^^^^^^^^^^^^^^^^^ +# +def unixpath(thePath) : + r"""Return a path name that contains Unix separator. + + [Example] + >>> unixpath(r"d:\test") + 'd:/test' + >>> unixpath("d:/test/file.txt") + 'd:/test/file.txt' + >>> + """ + thePath = os.path.normpath(thePath) + if os.sep == '/': + return thePath + else: + return thePath.replace(os.sep,'/') + +# ----------------------------------------------------------------------------- + +# S c r i p t e x e c u t i o n -- Runs when invoked from the command line -- +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# +if __name__ == "__main__": + import getopt # command line parsing + argc = len(sys.argv) + if argc == 1: + printUsage('Missing argument: specify at least one of -m or -p (or both).') + sys.exit(1) + # If there is some arguments, parse the command line + validOptions = "ehmpv" + validLongOptions = ['domain=', 'moTarget='] + option = {} + option['forceEnglish'] = 0 + option['mo'] = 0 + option['po'] = 0 + option['verbose'] = 0 + option['domain'] = None + option['moTarget'] = None + try: + optionList,pargs = getopt.getopt(sys.argv[1:],validOptions,validLongOptions) + except getopt.GetoptError, e: + printUsage(e[0]) + sys.exit(1) + for (opt,val) in optionList: + if (opt == '-h'): + printUsage() + sys.exit(0) + elif (opt == '-e'): option['forceEnglish'] = 1 + elif (opt == '-m'): option['mo'] = 1 + elif (opt == '-p'): option['po'] = 1 + elif (opt == '-v'): option['verbose'] = 1 + elif (opt == '--domain'): option['domain'] = val + elif (opt == '--moTarget'): option['moTarget'] = val + if len(pargs) == 0: + appDirPath = os.getcwd() + if option['verbose']: + print "No project directory given. Using current one: %s" % appDirPath + elif len(pargs) == 1: + appDirPath = pargs[0] + else: + printUsage('Too many arguments (%u). Use double quotes if you have space in directory name' % len(pargs)) + sys.exit(1) + if option['domain'] is None: + # If no domain specified, use the name of the target directory + option['domain'] = fileBaseOf(appDirPath) + if option['verbose']: + print "Application domain used is: '%s'" % option['domain'] + if option['po']: + try: + makePO(appDirPath,option['domain'],option['verbose']) + except IOError, e: + printUsage(e[1] + '\n You must write a file app.fil that contains the list of all files to parse.') + if option['mo']: + makeMO(appDirPath,option['moTarget'],option['domain'],option['verbose'],option['forceEnglish']) + sys.exit(1) + + +# ----------------------------------------------------------------------------- + diff --git a/creactigame/_templates/setup.py b/creactigame/_templates/setup.py new file mode 100644 index 0000000..8c17051 --- /dev/null +++ b/creactigame/_templates/setup.py @@ -0,0 +1,19 @@ +#!/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 +# (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 bundlebuilder + +bundlebuilder.start() diff --git a/creactigame/_templates/sugargame/__init__.py b/creactigame/_templates/sugargame/__init__.py new file mode 100644 index 0000000..439eb0c --- /dev/null +++ b/creactigame/_templates/sugargame/__init__.py @@ -0,0 +1 @@ +__version__ = '1.1' diff --git a/creactigame/_templates/sugargame/canvas.py b/creactigame/_templates/sugargame/canvas.py new file mode 100644 index 0000000..980cb73 --- /dev/null +++ b/creactigame/_templates/sugargame/canvas.py @@ -0,0 +1,62 @@ +import os +import gtk +import gobject +import pygame +import event + +CANVAS = None + +class PygameCanvas(gtk.EventBox): + + """ + mainwindow is the activity intself. + """ + def __init__(self, mainwindow, pointer_hint = True): + gtk.EventBox.__init__(self) + + global CANVAS + assert CANVAS == None, "Only one PygameCanvas can be created, ever." + CANVAS = self + + # Initialize Events translator before widget gets "realized". + self.translator = event.Translator(mainwindow, self) + + self._mainwindow = mainwindow + + self.set_flags(gtk.CAN_FOCUS) + + self._socket = gtk.Socket() + self.add(self._socket) + self.show_all() + + def run_pygame(self, main_fn): + # Run the main loop after a short delay. The reason for the delay is that the + # Sugar activity is not properly created until after its constructor returns. + # If the Pygame main loop is called from the activity constructor, the + # constructor never returns and the activity freezes. + gobject.idle_add(self._run_pygame_cb, main_fn) + + def _run_pygame_cb(self, main_fn): + assert pygame.display.get_surface() is None, "PygameCanvas.run_pygame can only be called once." + + # Preinitialize Pygame with the X window ID. + assert pygame.display.get_init() == False, "Pygame must not be initialized before calling PygameCanvas.run_pygame." + os.environ['SDL_WINDOWID'] = str(self._socket.get_id()) + pygame.init() + + # Restore the default cursor. + self._socket.window.set_cursor(None) + + # Initialize the Pygame window. + r = self.get_allocation() + pygame.display.set_mode((r.width, r.height), pygame.RESIZABLE) + + # Hook certain Pygame functions with GTK equivalents. + self.translator.hook_pygame() + + # Run the Pygame main loop. + main_fn() + return False + + def get_pygame_widget(self): + return self._socket diff --git a/creactigame/_templates/sugargame/event.py b/creactigame/_templates/sugargame/event.py new file mode 100644 index 0000000..4cc3be8 --- /dev/null +++ b/creactigame/_templates/sugargame/event.py @@ -0,0 +1,243 @@ +import gtk +import gobject +import pygame +import pygame.event +import logging + +class _MockEvent(object): + def __init__(self, keyval): + self.keyval = keyval + +class Translator(object): + key_trans = { + 'Alt_L': pygame.K_LALT, + 'Alt_R': pygame.K_RALT, + 'Control_L': pygame.K_LCTRL, + 'Control_R': pygame.K_RCTRL, + 'Shift_L': pygame.K_LSHIFT, + 'Shift_R': pygame.K_RSHIFT, + 'Super_L': pygame.K_LSUPER, + 'Super_R': pygame.K_RSUPER, + 'KP_Page_Up' : pygame.K_KP9, + 'KP_Page_Down' : pygame.K_KP3, + 'KP_End' : pygame.K_KP1, + 'KP_Home' : pygame.K_KP7, + 'KP_Up' : pygame.K_KP8, + 'KP_Down' : pygame.K_KP2, + 'KP_Left' : pygame.K_KP4, + 'KP_Right' : pygame.K_KP6, + + } + + mod_map = { + pygame.K_LALT: pygame.KMOD_LALT, + pygame.K_RALT: pygame.KMOD_RALT, + pygame.K_LCTRL: pygame.KMOD_LCTRL, + pygame.K_RCTRL: pygame.KMOD_RCTRL, + pygame.K_LSHIFT: pygame.KMOD_LSHIFT, + pygame.K_RSHIFT: pygame.KMOD_RSHIFT, + } + + def __init__(self, mainwindow, inner_evb): + """Initialise the Translator with the windows to which to listen""" + self._mainwindow = mainwindow + self._inner_evb = inner_evb + + # Enable events + # (add instead of set here because the main window is already realized) + self._mainwindow.add_events( + gtk.gdk.KEY_PRESS_MASK | \ + gtk.gdk.KEY_RELEASE_MASK \ + ) + + self._inner_evb.set_events( + gtk.gdk.POINTER_MOTION_MASK | \ + gtk.gdk.POINTER_MOTION_HINT_MASK | \ + gtk.gdk.BUTTON_MOTION_MASK | \ + gtk.gdk.BUTTON_PRESS_MASK | \ + gtk.gdk.BUTTON_RELEASE_MASK + ) + + self._mainwindow.set_flags(gtk.CAN_FOCUS) + self._inner_evb.set_flags(gtk.CAN_FOCUS) + + # Callback functions to link the event systems + self._mainwindow.connect('unrealize', self._quit_cb) + self._inner_evb.connect('key_press_event', self._keydown_cb) + self._inner_evb.connect('key_release_event', self._keyup_cb) + self._inner_evb.connect('button_press_event', self._mousedown_cb) + self._inner_evb.connect('button_release_event', self._mouseup_cb) + self._inner_evb.connect('motion-notify-event', self._mousemove_cb) + self._inner_evb.connect('expose-event', self._expose_cb) + self._inner_evb.connect('configure-event', self._resize_cb) + + # Internal data + self.__stopped = False + self.__keystate = [0] * 323 + self.__button_state = [0,0,0] + self.__mouse_pos = (0,0) + self.__repeat = (None, None) + self.__held = set() + self.__held_time_left = {} + self.__held_last_time = {} + self.__tick_id = None + + def hook_pygame(self): + pygame.key.get_pressed = self._get_pressed + pygame.key.set_repeat = self._set_repeat + pygame.mouse.get_pressed = self._get_mouse_pressed + pygame.mouse.get_pos = self._get_mouse_pos + + def _expose_cb(self, event, widget): + if pygame.display.get_init(): + pygame.event.post(pygame.event.Event(pygame.VIDEOEXPOSE)) + return True + + def _resize_cb(self, widget, event): + evt = pygame.event.Event(pygame.VIDEORESIZE, + size=(event.width,event.height), width=event.width, height=event.height) + pygame.event.post(evt) + return False # continue processing + + def _quit_cb(self, data=None): + self.__stopped = True + pygame.event.post(pygame.event.Event(pygame.QUIT)) + + def _keydown_cb(self, widget, event): + key = event.keyval + if key in self.__held: + return True + else: + if self.__repeat[0] is not None: + self.__held_last_time[key] = pygame.time.get_ticks() + self.__held_time_left[key] = self.__repeat[0] + self.__held.add(key) + + return self._keyevent(widget, event, pygame.KEYDOWN) + + def _keyup_cb(self, widget, event): + key = event.keyval + if self.__repeat[0] is not None: + if key in self.__held: + # This is possibly false if set_repeat() is called with a key held + del self.__held_time_left[key] + del self.__held_last_time[key] + self.__held.discard(key) + + return self._keyevent(widget, event, pygame.KEYUP) + + def _keymods(self): + mod = 0 + for key_val, mod_val in self.mod_map.iteritems(): + mod |= self.__keystate[key_val] and mod_val + return mod + + def _keyevent(self, widget, event, type): + key = gtk.gdk.keyval_name(event.keyval) + if key is None: + # No idea what this key is. + return False + + keycode = None + if key in self.key_trans: + keycode = self.key_trans[key] + elif hasattr(pygame, 'K_'+key.upper()): + keycode = getattr(pygame, 'K_'+key.upper()) + elif hasattr(pygame, 'K_'+key.lower()): + keycode = getattr(pygame, 'K_'+key.lower()) + elif key == 'XF86Start': + # view source request, specially handled... + self._mainwindow.view_source() + else: + print 'Key %s unrecognized' % key + + if keycode is not None: + if type == pygame.KEYDOWN: + mod = self._keymods() + self.__keystate[keycode] = type == pygame.KEYDOWN + if type == pygame.KEYUP: + mod = self._keymods() + ukey = unichr(gtk.gdk.keyval_to_unicode(event.keyval)) + if ukey == '\000': + ukey = '' + evt = pygame.event.Event(type, key=keycode, unicode=ukey, mod=mod) + self._post(evt) + + return True + + def _get_pressed(self): + return self.__keystate + + def _get_mouse_pressed(self): + return self.__button_state + + def _mousedown_cb(self, widget, event): + self.__button_state[event.button-1] = 1 + return self._mouseevent(widget, event, pygame.MOUSEBUTTONDOWN) + + def _mouseup_cb(self, widget, event): + self.__button_state[event.button-1] = 0 + return self._mouseevent(widget, event, pygame.MOUSEBUTTONUP) + + def _mouseevent(self, widget, event, type): + evt = pygame.event.Event(type, button=event.button, pos=(event.x, event.y)) + self._post(evt) + return True + + def _mousemove_cb(self, widget, event): + # From http://www.learningpython.com/2006/07/25/writing-a-custom-widget-using-pygtk/ + # if this is a hint, then let's get all the necessary + # information, if not it's all we need. + if event.is_hint: + x, y, state = event.window.get_pointer() + else: + x = event.x + y = event.y + state = event.state + + rel = (x - self.__mouse_pos[0], y - self.__mouse_pos[1]) + self.__mouse_pos = (x, y) + + self.__button_state = [ + state & gtk.gdk.BUTTON1_MASK and 1 or 0, + state & gtk.gdk.BUTTON2_MASK and 1 or 0, + state & gtk.gdk.BUTTON3_MASK and 1 or 0, + ] + + evt = pygame.event.Event(pygame.MOUSEMOTION, + pos=self.__mouse_pos, rel=rel, buttons=self.__button_state) + self._post(evt) + return True + + def _tick_cb(self): + cur_time = pygame.time.get_ticks() + for key in self.__held: + delta = cur_time - self.__held_last_time[key] + self.__held_last_time[key] = cur_time + + self.__held_time_left[key] -= delta + if self.__held_time_left[key] <= 0: + self.__held_time_left[key] = self.__repeat[1] + self._keyevent(None, _MockEvent(key), pygame.KEYDOWN) + + return True + + def _set_repeat(self, delay=None, interval=None): + if delay is not None and self.__repeat[0] is None: + self.__tick_id = gobject.timeout_add(10, self._tick_cb) + elif delay is None and self.__repeat[0] is not None: + gobject.source_remove(self.__tick_id) + self.__repeat = (delay, interval) + + def _get_mouse_pos(self): + return self.__mouse_pos + + def _post(self, evt): + try: + pygame.event.post(evt) + except pygame.error, e: + if str(e) == 'Event queue full': + print "Event queue full!" + pass + else: + raise e diff --git a/creactigame/template.py b/creactigame/template.py new file mode 100644 index 0000000..f70de3a --- /dev/null +++ b/creactigame/template.py @@ -0,0 +1,8 @@ +from paste.script import templates +from tempita import paste_script_template_renderer + +class CreactigameTemplate(templates.Template): + summary = 'An activty template for a sugar app' + required_templates = [] + _template_dir = '_templates' + template_renderer = staticmethod(paste_script_template_renderer) diff --git a/setup.py b/setup.py index 5fddbbc..a56fe76 100644 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ setup( [paste.paster_create_template] creactivity = creactivity.template:CreactivityTemplate creactiweb = creactiweb.template:CreactiwebTemplate + creactigame = creactigame.template:CreactigameTemplate """, keywords = [], ) -- cgit v0.9.1