Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2011-10-18 20:24:06 (GMT)
committer Walter Bender <walter.bender@gmail.com>2011-10-18 20:24:06 (GMT)
commit2f0963e3d4c842a9f775100ccb27a20254eca13f (patch)
tree955a56985da836370f88cb5509e43f7f8dfd6cee
parent919e8066884eb4a520d2ccae22847909df15f464 (diff)
added custom ball combo box
-rw-r--r--FractionBounceActivity.py27
-rw-r--r--ball.py40
-rw-r--r--toolbar_utils.py44
-rw-r--r--utils.py24
4 files changed, 120 insertions, 15 deletions
diff --git a/FractionBounceActivity.py b/FractionBounceActivity.py
index bc0ba92..dfa30d7 100644
--- a/FractionBounceActivity.py
+++ b/FractionBounceActivity.py
@@ -12,6 +12,7 @@
# Boston, MA 02111-1307, USA.
import gtk
+import os
from sugar.activity import activity
from sugar import profile
@@ -36,14 +37,15 @@ from gettext import gettext as _
import logging
_logger = logging.getLogger('fractionbounce-activity')
-from toolbar_utils import image_factory, separator_factory, \
+from toolbar_utils import image_factory, separator_factory, combo_factory, \
label_factory, radio_factory, button_factory, entry_factory
-from utils import json_load, json_dump
+from utils import json_load, json_dump, chooser
from svg_utils import svg_str_to_pixbuf, generate_xo_svg
from bounce import Bounce
+BALLS = [_('basketball'), _('soccer ball'), _('user defined')]
SERVICE = 'org.sugarlabs.FractionBounceActivity'
IFACE = SERVICE
PATH = '/org/augarlabs/FractionBounceActivity'
@@ -153,6 +155,10 @@ class FractionBounceActivity(activity.Activity):
self._add_fraction_cb,
tooltip=_('add new fraction'),
accelerator='Return')
+ separator_factory(toolbar, expand=False, visible=True)
+ self._ball_selector = combo_factory(BALLS, toolbar, self._combo_cb,
+ default=_('basketball'),
+ tooltip=_('choose a ball'))
def _setup_canvas(self):
''' Create a canvas '''
@@ -164,6 +170,23 @@ class FractionBounceActivity(activity.Activity):
self.show_all()
return canvas
+ def _combo_cb(self, arg=None):
+ ''' Load a new ball based on the selector value. '''
+ if not hasattr(self, '_ball_selector'):
+ return
+ if BALLS[self._ball_selector.get_active()] == _('basketball'):
+ self.bounce_window.ball.new_ball(os.path.join(
+ activity.get_bundle_path(), 'basketball.svg'))
+ elif BALLS[self._ball_selector.get_active()] == _('soccer ball'):
+ self.bounce_window.ball.new_ball(os.path.join(
+ activity.get_bundle_path(), 'soccer.svg'))
+ else:
+ chooser(self, '', self._new_ball_from_journal)
+
+ def _new_ball_from_journal(self, dsobject):
+ ''' Load an image from the Journal. '''
+ self.bounce_window.ball.new_ball_from_image(dsobject.file_path)
+
def _fraction_cb(self, arg=None):
''' Set fraction mode '''
self.bounce_window.mode = 'fractions'
diff --git a/ball.py b/ball.py
index 3cbb3b2..66e6adf 100644
--- a/ball.py
+++ b/ball.py
@@ -11,10 +11,15 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+import gtk
+
from sprites import Sprite
from svg_utils import svg_header, svg_footer, svg_str_to_pixbuf, \
extract_svg_payload, svg_from_file
+import logging
+_logger = logging.getLogger('fractionbounce-activity')
+
SIZE = 85
ANIMATION = {10: (0, 1), 15: (1, 2), 20: (2, 1), 25: (1, 2), 30: (2, 1),
@@ -76,11 +81,11 @@ class Ball():
interaction. '''
def __init__(self, sprites, filename):
- ''' Create a ball object and Easter Egg animation from an SVG file. '''
- self.ball = Sprite(sprites, 0, 0, svg_str_to_pixbuf(
- svg_from_file(filename)))
self.current_frame = 0
self.frames = [] # Easter Egg animation
+ self.sprites = sprites
+ self.ball = Sprite(self.sprites, 0, 0, svg_str_to_pixbuf(
+ svg_from_file(filename)))
self.ball.set_layer(1)
self.ball.set_label_attributes(24)
@@ -88,13 +93,34 @@ class Ball():
ball = extract_svg_payload(file(filename, 'r'))
for i in range(8):
self.frames.append(Sprite(
- sprites, 0, 0, svg_str_to_pixbuf(
+ self.sprites, 0, 0, svg_str_to_pixbuf(
svg_header(SIZE, SIZE, 1.0) + TRANSFORMS[i] + \
ball + PUNCTURE + AIR + '</g>' + svg_footer())))
- for spr in self.frames:
- spr.set_layer(1)
- spr.move((0, -SIZE)) # move animation frames off screen
+ for frame in self.frames:
+ frame.set_layer(1)
+ frame.move((0, -SIZE)) # move animation frames off screen
+
+ def new_ball(self, filename):
+ ''' Create a ball object and Easter Egg animation from an SVG file. '''
+ self.ball.images[0] = svg_str_to_pixbuf(svg_from_file(filename))
+
+ ball = extract_svg_payload(file(filename, 'r'))
+ for i in range(8):
+ self.frames[i].images[0] = svg_str_to_pixbuf(
+ svg_header(SIZE, SIZE, 1.0) + TRANSFORMS[i] + \
+ ball + PUNCTURE + AIR + '</g>' + svg_footer())
+
+ def new_ball_from_image(self, filename):
+ ''' Just create a ball object from an image file '''
+ if filename == '':
+ _logger.debug('Image file not found.')
+ return
+ try:
+ self.ball.images[0] = gtk.gdk.pixbuf_new_from_file_at_size(
+ filename, SIZE, SIZE)
+ except:
+ _logger.debug('Could not load image from %s.', filename)
def ball_x(self):
return self.ball.get_xy()[0]
diff --git a/toolbar_utils.py b/toolbar_utils.py
index 9dea658..b75a464 100644
--- a/toolbar_utils.py
+++ b/toolbar_utils.py
@@ -15,27 +15,59 @@ import gtk
from sugar.graphics.radiotoolbutton import RadioToolButton
from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.combobox import ComboBox
+from sugar.graphics.toolcombobox import ToolComboBox
-def entry_factory(default_string, toolbar, tooltip='', max=3):
- """ Factory for adding a text box to a toolbar """
+
+def combo_factory(combo_array, toolbar, callback, cb_arg=None,
+ tooltip=None, default=None):
+ '''Factory for making a toolbar combo box'''
+ combo = ComboBox()
+ if tooltip is not None and hasattr(combo, 'set_tooltip_text'):
+ combo.set_tooltip_text(tooltip)
+ if cb_arg is not None:
+ combo.connect('changed', callback, cb_arg)
+ else:
+ combo.connect('changed', callback)
+ for i, selection in enumerate(combo_array):
+ combo.append_item(i, selection, None)
+ combo.show()
+ toolitem = gtk.ToolItem()
+ toolitem.add(combo)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(toolitem, -1)
+ toolitem.show()
+ if default is not None:
+ combo.set_active(combo_array.index(default))
+ return combo
+
+
+def entry_factory(default_string, toolbar, tooltip=None, max=3):
+ ''' Factory for adding a text box to a toolbar '''
entry = gtk.Entry()
entry.set_text(default_string)
- if hasattr(entry, 'set_tooltip_text'):
+ if tooltip is not None and hasattr(entry, 'set_tooltip_text'):
entry.set_tooltip_text(tooltip)
entry.set_width_chars(max)
entry.show()
toolitem = gtk.ToolItem()
toolitem.add(entry)
- toolbar.insert(toolitem, -1)
+ if hasattr(toolbar, 'insert'): # the main toolbar
+ toolbar.insert(toolitem, -1)
+ else: # or a secondary toolbar
+ toolbar.props.page.insert(toolitem, -1)
toolitem.show()
return entry
def button_factory(icon_name, toolbar, callback, cb_arg=None, tooltip=None,
accelerator=None):
- """Factory for making toolbar buttons"""
+ '''Factory for making toolbar buttons'''
button = ToolButton(icon_name)
- button.set_tooltip(tooltip)
+ if tooltip is not None:
+ button.set_tooltip(tooltip)
button.props.sensitive = True
if accelerator is not None:
button.props.accelerator = accelerator
diff --git a/utils.py b/utils.py
index 3ffac3d..4d8f906 100644
--- a/utils.py
+++ b/utils.py
@@ -11,6 +11,10 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+import gtk
+
+from sugar.graphics.objectchooser import ObjectChooser
+
from StringIO import StringIO
try:
USING_JSON_READWRITE = False
@@ -52,3 +56,23 @@ def json_dump(data):
_io = StringIO()
jdump(data, _io)
return _io.getvalue()
+
+
+def chooser(parent_window, filter, action):
+ """ Choose an object from the datastore and take some action """
+ chooser = None
+ try:
+ chooser = ObjectChooser(parent=parent_window, what_filter=filter)
+ except TypeError:
+ chooser = ObjectChooser(None, parent_window,
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
+ if chooser is not None:
+ try:
+ result = chooser.run()
+ if result == gtk.RESPONSE_ACCEPT:
+ dsobject = chooser.get_selected_object()
+ action(dsobject)
+ dsobject.destroy()
+ finally:
+ chooser.destroy()
+ del chooser