Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS12
-rw-r--r--ReflectionActivity.py19
-rw-r--r--activity/activity.info4
-rw-r--r--game.py95
-rw-r--r--icons/my-colors.svg8
-rw-r--r--toolbar_utils.py4
6 files changed, 117 insertions, 25 deletions
diff --git a/NEWS b/NEWS
index ee60ba5..9a6d8ae 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,17 @@
NEWS
+8
+
+ENHANCEMENTS:
+* Paint by dragging across dots
+* Long press cycles through dots
+* New translations
+
+7
+
+ENHANCEMENTS:
+* New translations
+
6
ENHANCEMENTS:
diff --git a/ReflectionActivity.py b/ReflectionActivity.py
index 4a25ea7..318413f 100644
--- a/ReflectionActivity.py
+++ b/ReflectionActivity.py
@@ -24,7 +24,8 @@ if _have_toolbox:
from sugar.activity.widgets import ActivityToolbarButton
from sugar.activity.widgets import StopButton
-from toolbar_utils import button_factory, label_factory, separator_factory
+from toolbar_utils import button_factory, label_factory, separator_factory, \
+ radio_factory
from utils import json_load, json_dump
import telepathy
@@ -110,6 +111,12 @@ class ReflectionActivity(activity.Activity):
toolbox.set_current_toolbar(1)
self.toolbar = games_toolbar
+ my_colors = radio_factory(
+ 'my-colors', self.toolbar, self._my_colors_cb, group=None)
+
+ radio_factory('toolbar-colors', self.toolbar,
+ self._roygbiv_colors_cb, group=my_colors)
+
self._new_game_button_h = button_factory(
'new-game-horizontal', self.toolbar, self._new_game_cb,
cb_arg='horizontal',
@@ -143,6 +150,16 @@ class ReflectionActivity(activity.Activity):
toolbox.toolbar.insert(stop_button, -1)
stop_button.show()
+ def _my_colors_cb(self, button=None):
+ if hasattr(self, '_game'):
+ self._game.roygbiv = False
+ self._game.new_game()
+
+ def _roygbiv_colors_cb(self, button=None):
+ if hasattr(self, '_game'):
+ self._game.roygbiv = True
+ self._game.new_game()
+
def _new_game_cb(self, button=None, orientation='horizontal'):
''' Start a new game. '''
self._game.new_game(orientation)
diff --git a/activity/activity.info b/activity/activity.info
index 3d6a491..8543e6e 100644
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -1,8 +1,10 @@
[Activity]
name = Reflection
-activity_version = 6
+activity_version = 8
license = GPLv3
bundle_id = org.sugarlabs.RelfectionActivity
exec = sugar-activity ReflectionActivity.ReflectionActivity
icon = activity-reflection
show_launcher = yes
+summary = draw patterns of reflective symmetry
+
diff --git a/game.py b/game.py
index 8544586..acf0419 100644
--- a/game.py
+++ b/game.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-#Copyright (c) 2011 Walter Bender
+#Copyright (c) 2011-12 Walter Bender
# 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
@@ -12,6 +12,7 @@
import gtk
+import gobject
import cairo
from random import uniform
@@ -29,6 +30,7 @@ except ImportError:
from sprites import Sprites, Sprite
+
# Grid dimensions must be even
TEN = 10
SIX = 6
@@ -39,10 +41,17 @@ class Game():
def __init__(self, canvas, parent=None, colors=['#A0FFA0', '#FF8080']):
self._activity = parent
- self._colors = ['#FFFFFF']
- self._colors.append(colors[0])
+ self._colors = [colors[0]]
self._colors.append(colors[1])
+ self._colors.append('#FFFFFF')
self._colors.append('#000000')
+ self._colors.append('#FF0000')
+ self._colors.append('#FF8000')
+ self._colors.append('#FFFF00')
+ self._colors.append('#00FF00')
+ self._colors.append('#00FFFF')
+ self._colors.append('#0000FF')
+ self._colors.append('#FF00FF')
self._canvas = canvas
if parent is not None:
@@ -51,9 +60,12 @@ class Game():
self._canvas.set_flags(gtk.CAN_FOCUS)
self._canvas.add_events(gtk.gdk.BUTTON_PRESS_MASK)
+ self._canvas.add_events(gtk.gdk.BUTTON_RELEASE_MASK)
+ self._canvas.add_events(gtk.gdk.POINTER_MOTION_MASK)
self._canvas.connect("expose-event", self._expose_cb)
self._canvas.connect("button-press-event", self._button_press_cb)
-
+ self._canvas.connect("button-release-event", self._button_release_cb)
+ self._canvas.connect("motion-notify-event", self._mouse_move_cb)
self._width = gtk.gdk.screen_width()
self._height = gtk.gdk.screen_height() - (GRID_CELL_SIZE * 1.5)
self._scale = self._width / (10 * DOT_SIZE * 1.2)
@@ -62,6 +74,10 @@ class Game():
self._orientation = 'horizontal'
self.we_are_sharing = False
self.playing_with_robot = False
+ self._press = False
+ self.last_spr = None
+ self._timer = None
+ self.roygbiv = False
# Generate the sprites we'll need...
self._sprites = Sprites(self._canvas)
@@ -74,8 +90,8 @@ class Game():
Sprite(self._sprites,
xoffset + x * (self._dot_size + self._space),
y * (self._dot_size + self._space),
- self._new_dot(self._colors[0])))
- self._dots[-1].type = 0 # not set
+ self._new_dot(self._colors[2])))
+ self._dots[-1].type = 2 # not set
self._dots[-1].set_label_attributes(40)
self.vline = Sprite(self._sprites,
@@ -94,9 +110,8 @@ class Game():
def _all_clear(self):
''' Things to reinitialize when starting up a new game. '''
for dot in self._dots:
- if dot.type > 0:
- dot.type = 0
- dot.set_shape(self._new_dot(self._colors[0]))
+ dot.type = 2
+ dot.set_shape(self._new_dot(self._colors[2]))
dot.set_label('')
self._set_orientation()
@@ -113,6 +128,7 @@ class Game():
self.hline.set_layer(1000)
self.vline.set_layer(1000)
+ '''
if self._orientation == 'horizontal':
self._set_label(
_('Click on the dots to make a horizontal reflection.'))
@@ -122,6 +138,7 @@ class Game():
else:
self._set_label(
_('Click on the dots to make a bilateral reflection.'))
+ '''
def _initiating(self):
return self._activity.initiating
@@ -135,7 +152,10 @@ class Game():
# Fill in a few dots to start
for i in range(int(TEN * SIX / 2)):
n = int(uniform(0, TEN * SIX))
- self._dots[n].type = int(uniform(0, 4))
+ if self.roygbiv:
+ self._dots[n].type = int(uniform(2, len(self._colors)))
+ else:
+ self._dots[n].type = int(uniform(0, 4))
self._dots[n].set_shape(self._new_dot(
self._colors[self._dots[n].type]))
@@ -167,26 +187,59 @@ class Game():
def _button_press_cb(self, win, event):
win.grab_focus()
x, y = map(int, event.get_coords())
+ self._press = True
spr = self._sprites.find_sprite((x, y), inverse=True)
if spr == None:
- return
+ return True
+ self.last_spr = spr
if spr.type is not None:
- spr.type += 1
+ if not self._timer is None:
+ gobject.source_remove(self._timer)
+ self._increment_dot(spr)
+ return True
+
+ def _button_release_cb(self, win, event):
+ self._press = False
+ if not self._timer is None:
+ gobject.source_remove(self._timer)
+
+ def _increment_dot(self, spr):
+ spr.type += 1
+ if self.roygbiv:
+ if spr.type >= len(self._colors):
+ spr.type = 2
+ else:
spr.type %= 4
- spr.set_shape(self._new_dot(self._colors[spr.type]))
+ spr.set_shape(self._new_dot(self._colors[spr.type]))
- if self.playing_with_robot:
- self._robot_play(spr)
+ if self.playing_with_robot:
+ self._robot_play(spr)
- self._test_game_over()
+ self._test_game_over()
- if self.we_are_sharing:
- _logger.debug('sending a click to the share')
- self._parent.send_dot_click(self._dots.index(spr),
- spr.type)
- return True
+ if self.we_are_sharing:
+ _logger.debug('sending a click to the share')
+ self._parent.send_dot_click(self._dots.index(spr), spr.type)
+
+ self._timer = gobject.timeout_add(1000, self._increment_dot, spr)
+
+ def _mouse_move_cb(self, win, event):
+ """ Drag a tile with the mouse. """
+ if not self._press:
+ return
+ x, y = map(int, event.get_coords())
+ spr = self._sprites.find_sprite((x, y), inverse=True)
+ if spr == self.last_spr:
+ return True
+ if spr is None:
+ return True
+ if spr.type is not None:
+ self.last_spr = spr
+ if not self._timer is None:
+ gobject.source_remove(self._timer)
+ self._increment_dot(spr)
def _robot_play(self, dot):
''' Robot reflects dot clicked. '''
diff --git a/icons/my-colors.svg b/icons/my-colors.svg
new file mode 100644
index 0000000..ff589f2
--- /dev/null
+++ b/icons/my-colors.svg
@@ -0,0 +1,8 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 55 55" height="55px" version="1.1" viewBox="0 0 55 55" width="55px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px"><g display="block" id="toolbar_x5F_colors">
+ <g>
+ <circle cx="15.63" cy="39.5" fill="#FFFFFF" r="10" stroke="#FFFFFF" stroke-width="2.25"/>
+ <circle cx="39.834" cy="39.5" fill="#808080" r="10" stroke="#FFFFFF" stroke-width="2.25"/>
+ <circle cx="15.167" cy="15.5" fill="#000000" r="10" stroke="#FFFFFF" stroke-width="2.25"/>
+ <circle cx="39.666" cy="15.5" r="10" stroke="#A0A0A0" stroke-width="2.25"/>
+ </g>
+</g></svg>
diff --git a/toolbar_utils.py b/toolbar_utils.py
index 94e6883..d17f959 100644
--- a/toolbar_utils.py
+++ b/toolbar_utils.py
@@ -83,11 +83,11 @@ def button_factory(icon_name, toolbar, callback, cb_arg=None, tooltip=None,
return button
-def radio_factory(name, toolbar, callback, cb_arg=None, tooltip=None,
+def radio_factory(icon_name, toolbar, callback, cb_arg=None, tooltip=None,
group=None):
''' Add a radio button to a toolbar '''
button = RadioToolButton(group=group)
- button.set_named_icon(name)
+ button.set_named_icon(icon_name)
if callback is not None:
if cb_arg is None:
button.connect('clicked', callback)