Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@walter-laptop.(none)>2010-01-21 22:04:23 (GMT)
committer Walter Bender <walter@walter-laptop.(none)>2010-01-21 22:04:23 (GMT)
commit90a696e3e66ad1b6a3865218fb19e1093f0337b8 (patch)
treeefe72763ddabfd0d7fe7ccdc741feec15a077ed6
parentedce59893cdb5c317adc9f9ffbe2fdfca40f0891 (diff)
adding Turtle class
-rw-r--r--block.py138
-rw-r--r--constants.py21
-rwxr-xr-xsprite_factory.py13
-rw-r--r--taproject.py77
-rw-r--r--tasetup.py34
-rw-r--r--taturtle.py12
-rw-r--r--tawindow.py197
-rw-r--r--turtlex.py78
8 files changed, 314 insertions, 256 deletions
diff --git a/block.py b/block.py
index 74b995c..c12a8e4 100644
--- a/block.py
+++ b/block.py
@@ -19,21 +19,17 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
from constants import *
import sprite_factory
import sprites
+from gettext import gettext as _
#
# A class for the list of blocks and everything they share in common
#
class Blocks:
- def __init__(self, sprite_list):
+ def __init__(self):
self.list = []
- self.sprites = sprite_list
def get_block(self, i):
if i < 0 or i > len(self.list)-1:
@@ -47,53 +43,47 @@ class Blocks:
def append_to_list(self,block):
self.list.append(block)
- def insert_in_list(self,block,i):
- if i < 0:
- self.list.insert(0, block)
- elif i > len(self.list)-1:
- self.list.append(block)
- else:
- self.list.insert(i, block)
-
def remove_from_list(self, block):
if block in self.list:
self.list.remove(block)
#
- # block and spr utilities
+ # sprite utilities
#
def spr_to_block(self, spr):
for b in self.list:
if spr == b.spr:
return b
+ return None
#
# A class for the individual blocks
#
class Block:
- def __init__(self, blocks, proto_name, x, y, labels=[],
+ def __init__(self, block_list, sprite_list, proto_name, x, y, labels=[],
colors=["#00FF00","#00A000"], scale=2.0):
- self.blocks = blocks
self.spr = None
self.shape = None
self.selected_shape = None
- self._new_block_from_prototype(proto_name, labels, colors, scale, x, y)
- self.blocks.append_to_list(self)
+ self.name = proto_name
+ self.docks = None
+ self.connections = None
+ self._new_block_from_prototype(sprite_list, proto_name, labels, colors,
+ scale, x, y)
+ block_list.append_to_list(self)
#
# TODO:
- # save arguments
- # dock and connection info
- # highlight image
# Logo code
# HTML code
# debug code
# etc.
- def _new_block_from_prototype(self, name, labels, colors, scale, x, y):
+ def _new_block_from_prototype(self, sprite_list, name, labels, colors,
+ scale, x, y):
if len(labels) == 0:
- print "%s (%d %d)" % (name, x, y)
+ print "new block: %s (%d %d)" % (name, x, y)
else:
- print "%s %s (%d %d)" % (name, labels[0], x, y)
+ print "new block: %s %s (%d %d)" % (name, labels[0], x, y)
svg = sprite_factory.SVG()
if name in TURTLE_PALETTE:
@@ -118,96 +108,72 @@ class Block:
svg.set_slot(True)
if name in BASIC_STYLE:
svg.expand(40,0)
- self._make_basic_block(svg, x, y)
- self.docks = (('flow',True,37,5),('flow',False,37,44))
- print "created new basic block: %s" % (str(self.spr))
+ self._make_basic_block(sprite_list, svg, x, y)
+ self.docks = (('flow',True,37,5),('flow',False,37,39))
elif name in BASIC_STYLE_HEAD:
svg.expand(40,0)
svg.set_slot(False)
- self._make_basic_block(svg, x, y)
- self.docks = (('start',True,50,0), ('flow',False,49,55))
- print "created new basic block head: %s" % (str(self.spr))
+ self._make_basic_block(sprite_list, svg, x, y)
+ self.docks = (('start',True,37,0), ('flow',False,37,39))
elif name in BASIC_STYLE_HEAD_1ARG:
svg.expand(40,0)
svg.set_slot(False)
- self._make_basic_block(svg, x, y)
- self.docks = (('start',True,50,0), ('string',False,21,38),
- ('flow',False,75,75))
- print "created new basic block head: %s" % (str(self.spr))
+ self._make_basic_block(sprite_list, svg, x, y)
+ self.docks = (('start',True,37,0), ('string',False,42,12),
+ ('flow',False,37,44))
elif name in BASIC_STYLE_TAIL:
svg.expand(40,0)
svg.set_tab(False)
- self._make_basic_block(svg, x, y)
+ self._make_basic_block(sprite_list, svg, x, y)
self.docks = (('flow',True,37,5),('unavailable',False,0,0))
- print "created new basic block tail: %s" % (str(self.spr))
elif name in BASIC_STYLE_1ARG:
- svg.expand(20,0)
+ ex = 25
+ ey = 0
+ svg.expand(ex,ey)
svg.set_innie([True])
- self._make_basic_block(svg, x, y)
- self.docks = (('flow',True,37,5), ('num',False,74,21),
- ('flow',False,37,44))
- print "created new basic block 1 arg: %s" % (str(self.spr))
+ self._make_basic_block(sprite_list, svg, x, y)
+ self.docks = (('flow',True,37,5), ('num',False,42+ex*scale,12),
+ ('flow',False,37,44+ey))
elif name in BASIC_STYLE_2ARG:
- svg.expand(20,0)
+ ex = 25
+ ey = 0
+ svg.expand(ex,ey)
svg.set_innie([True,True])
- self._make_basic_block(svg, x, y)
- self.docks = (('flow',True,37,5), ('num',False,74,21),
- ('num',False,74,58), ('flow',False,37,81))
- print "created new basic block 2 args: %s" % (str(self.spr))
+ self._make_basic_block(sprite_list, svg, x, y)
+ self.docks = (('flow',True,37,5), ('num',False,42+ex*scale,12),
+ ('num',False,42+ex*scale,54), ('flow',False,37,81))
elif name in BOX_STYLE:
svg.expand(50,0)
- self._make_basic_box(svg, x, y)
- self.docks = (('num',True,0,12),('numend',False,105,12))
- print "created new box block: %s" % (str(self.spr))
+ self._make_basic_box(sprite_list, svg, x, y)
+ self.docks = (('num',True,0,12),('unavailable',False,105,12))
else:
svg.expand(40,0)
- self._make_basic_block(svg, x, y)
+ self._make_basic_block(sprite_list, svg, x, y)
print "don't know how to create a block for %s" % (name)
if len(labels) > 0:
- self.spr.set_label(labels[0])
+ self.spr.set_label(_(labels[0]))
for label in labels:
self.spr.set_label(label, labels.index(label))
self.type = 'block'
+ if DEFAULTS.has_key(name):
+ self.defaults = DEFAULTS[name]
+ else:
+ self.defaults = []
- def _make_basic_block(self, svg, x, y):
- self.shape = svg_str_to_pixbuf(svg.basic_block())
+ def _make_basic_block(self, sprite_list, svg, x, y):
+ self.shape = sprite_factory.svg_str_to_pixbuf(svg.basic_block())
svg.set_stroke_width(SELECTED_STROKE_WIDTH)
svg.set_stroke_color(SELECTED_COLOR)
- self.selected_shape = svg_str_to_pixbuf(svg.basic_block())
- self.spr = sprites.Sprite(self.blocks.sprites, x, y, self.shape)
+ self.selected_shape =\
+ sprite_factory.svg_str_to_pixbuf(svg.basic_block())
+ self.spr = sprites.Sprite(sprite_list, x, y, self.shape)
- def _make_basic_box(self, svg, x, y):
- self.shape = svg_str_to_pixbuf(svg.basic_box())
+ def _make_basic_box(self, sprite_list, svg, x, y):
+ self.shape = sprite_factory.svg_str_to_pixbuf(svg.basic_box())
svg.set_stroke_width(SELECTED_STROKE_WIDTH)
svg.set_stroke_color(SELECTED_COLOR)
- self.selected_shape = svg_str_to_pixbuf(svg.basic_box())
- self.spr = sprites.Sprite(self.blocks.sprites, x, y, self.shape)
-
-class Turtle:
- def __init__(self, blocks, orientation=0, scale=1.0):
- self.blocks = blocks
- self.spr = None
- self._new_turtle_from_prototype(orientation, scale)
- self.blocks.append_to_list(self)
- self.orientation = orientation
-
- def _new_turtle_from_prototype(self, orientation, scale):
- svg = sprite_factory.SVG()
- svg.set_scale(scale)
- svg.set_orientation(orientation)
- self.spr = sprites.Sprite(self.blocks.sprites, 0, 0,
- svg_str_to_pixbuf(svg.turtle()))
- self.type = 'turtle'
-
-#
-# Load pixbuf from SVG string
-#
-def svg_str_to_pixbuf(svg_string):
- pl = gtk.gdk.PixbufLoader('svg')
- pl.write(svg_string)
- pl.close()
- pixbuf = pl.get_pixbuf()
- return pixbuf
+ self.selected_shape = sprite_factory.svg_str_to_pixbuf(svg.basic_box())
+ self.spr = sprites.Sprite(sprite_list, x, y, self.shape)
diff --git a/constants.py b/constants.py
index 8877a78..e4cb0a0 100644
--- a/constants.py
+++ b/constants.py
@@ -17,15 +17,15 @@ from gettext import gettext as _
# sprite layers
#
-CANVAS_LAYER = 500
-TURTLE_LAYER = 550
HIDE_LAYER = 100
+CANVAS_LAYER = 500
OVERLAY_LAYER = 525
-STATUS_LAYER = 900
-TOP_LAYER = 1000
+TURTLE_LAYER = 2550
BLOCK_LAYER = 600
CATEGORY_LAYER = 700
TAB_LAYER = 710
+STATUS_LAYER = 900
+TOP_LAYER = 1000
#
# block definitions
@@ -47,7 +47,7 @@ TURTLE_PALETTE = ['clean', 'forward', 'back', 'left', 'right', 'seth', 'show',\
'set_scale', 'xcor', 'ycor', 'heading']
PEN_PALETTE = ['pen up','pen down']
NUMBER_PALETTE = ['number']
-BLOCKS_PALETTE = ['start', 'string']
+BLOCKS_PALETTE = ['start', 'string', 'store in box 1']
FLOW_PALETTE = []
MISC_PALETTE = []
PORTFOLIO_PALETTE = []
@@ -67,11 +67,12 @@ SELECTED_STROKE_WIDTH = 2.0
# default values
#
-DEFAULTS = {'forward':100, 'back':100, 'left':90, 'set xy':(0,0),
- 'arc':(90,100), 'seth':0, 'set scale':33, 'show':_('text'),
- 'set pen size':5, 'set text size':32, 'set color':0,
- 'set shade':50, 'fill screen':(60,80), 'number':100,
- 'random':(0,100), 'wait':1, 'repeat':4, 'store in':(_('box'),100)}
+DEFAULTS = {'forward':[100], 'back':[100], 'left':[90], 'right':[90],
+ 'arc':[90,100], 'seth':[0], 'set scale':[33], 'show':[_('text')],
+ 'set pen size':[5], 'set text size':[32], 'set color':[0],
+ 'set shade':[50], 'fill screen':[60,80], 'number':[100],
+ 'random':[0,100], 'wait':[1], 'repeat':[4], 'set xy':[0,0],
+ 'store in':[_('box'),100]}
#
# 'dead key' Unicode dictionaries
#
diff --git a/sprite_factory.py b/sprite_factory.py
index 8f58d92..22b9c56 100755
--- a/sprite_factory.py
+++ b/sprite_factory.py
@@ -20,6 +20,9 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
+import pygtk
+pygtk.require('2.0')
+import gtk
import os
from gettext import gettext as _
@@ -605,3 +608,13 @@ if __name__ == "__main__":
main()
+#
+# Load pixbuf from SVG string
+#
+def svg_str_to_pixbuf(svg_string):
+ pl = gtk.gdk.PixbufLoader('svg')
+ pl.write(svg_string)
+ pl.close()
+ pixbuf = pl.get_pixbuf()
+ return pixbuf
+
diff --git a/taproject.py b/taproject.py
index 2b1db79..48fd5af 100644
--- a/taproject.py
+++ b/taproject.py
@@ -53,6 +53,7 @@ except:
import block
import sprites
from constants import *
+from gettext import gettext as _
nolabel = ['audiooff', 'descriptionoff', 'journal']
shape_dict = {'journal':'texton', \
@@ -97,8 +98,8 @@ def load_files(tw, ta_file, create_new_project=True):
read_data(tw,data)
def get_load_name(tw):
- dialog = gtk.FileChooserDialog("Load...", None, \
- gtk.FILE_CHOOSER_ACTION_OPEN, \
+ dialog = gtk.FileChooserDialog("Load...", None,
+ gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_default_response(gtk.RESPONSE_OK)
return do_dialog(tw,dialog)
@@ -122,9 +123,11 @@ def clone_stack(tw,text):
io = StringIO(text)
listdata = jload(io)
data = tuplify(listdata) # json converts tuples to lists
- read_stack(tw,data)
+ # read_stack(tw,data)
+ read_data(tw,data)
# paste stack from the clipboard
+# TODO: rebase on read data
def read_stack(tw,data):
clone = []
for b in data:
@@ -142,22 +145,23 @@ def tuplify(t):
return tuple(map(tuplify, t))
def read_data(tw,data):
- blocks = []
+ sprs = []
for b in data:
if b[1]=='turtle':
load_turtle(tw,b)
- else: spr = load_spr(tw, b); blocks.append(spr)
- for i in range(len(blocks)):
+ else: spr = load_spr(tw, b); sprs.append(spr)
+ for i in range(len(sprs)):
cons=[]
for c in data[i][4]:
if c==None: cons.append(None)
- else: cons.append(blocks[c])
- blocks[i].connections = cons
+ else: cons.append(sprs[c])
+ sprs[i].connections = cons # phasing out
+ tw.block_list.spr_to_block(sprs[i]).connections = cons
def load_spr(tw,b):
media = None
btype, label = b[1],None
- if type(btype)==type((1,2)):
+ if type(btype) == type((1,2)):
btype, label = btype
if btype == 'title': # for backward compatibility
btype = 'string'
@@ -169,16 +173,13 @@ def load_spr(tw,b):
except KeyError:
print "swapping in a forward block for %s" % (btype)
proto = tw.protodict['forward']
- blk = block.Block(tw.blocks,btype,b[2]+tw.turtle.canvas.x,
- b[3]+tw.turtle.canvas.y, [btype])
+ blk = block.Block(tw.block_list, tw.sprite_list,
+ btype, b[2]+tw.turtle.canvas.x,
+ b[3]+tw.turtle.canvas.y, [label])
spr = blk.spr
- '''
- spr = sprites.Sprite(tw.sprites,b[2]+tw.turtle.canvas.x,
- b[3]+tw.turtle.canvas.y, proto.image)
- '''
- spr.type = 'block'
- spr.proto = proto
- if label is not None: spr.set_label(label)
+ spr.type = 'block' # phasing out
+ spr.proto = proto # phasing out
+ # if label is not None: spr.set_label(label) # phasing out
if media is not None and media not in nolabel:
try:
dsobject = datastore.get(media)
@@ -256,22 +257,22 @@ def save_string(tw,save_turtle=True):
return text
def assemble_data_to_save(tw,save_turtle=True):
- bs = blocks(tw)
data = []
- for i in range(len(bs)): bs[i].id=i
- for b in bs:
- name = b.proto.name
+ for i, b in enumerate(tw.block_list.list):
+ b.id = i
+ for b in tw.block_list.list:
+ name = (b.name, b.spr.labels[0])
if tw.defdict.has_key(name) or name in nolabel:
if hasattr(b,"ds_id") and b.ds_id != None:
name=(name, str(b.ds_id))
else:
- name=(name, b.labels[0])
+ name=(name, b.spr.labels[0])
if hasattr(b,'connections'):
- connections = [get_id(x) for x in b.connections]
+ connections = [get_id(tw.block_list, x) for x in b.connections]
else:
connections = None
- data.append((b.id, name, b.x-tw.turtle.canvas.x,
- b.y-tw.turtle.canvas.y, connections))
+ data.append((b.id, name, b.spr.x-tw.turtle.canvas.x,
+ b.spr.y-tw.turtle.canvas.y, connections))
if save_turtle is True:
data.append((-1,'turtle',
tw.turtle.xcor,tw.turtle.ycor,tw.turtle.heading,
@@ -292,10 +293,11 @@ def serialize_stack(tw):
return text
# find the stack under the cursor and serialize it
+# TODO: rebase on assemble data to save
def assemble_stack_to_clone(tw):
if tw.spr is None or tw.spr.type is not "block":
(x,y) = tw.window.get_pointer()
- spr = tw.sprites.find_sprite((x,y))
+ spr = tw.sprite_list.find_sprite((x,y))
if spr is not None:
print "found block of type " + spr.type
else:
@@ -312,25 +314,25 @@ def assemble_stack_to_clone(tw):
name=(name,str(b.ds_id))
else:
name=(name,b.labels[0])
- if hasattr(b,'connections'):
+ if hasattr(b,'connections') and b.connections is not None:
connections = [get_id(x) for x in b.connections]
else:
connections = None
- data.append((b.id,name,b.x-tw.turtle.canvas.x+20, \
+ data.append((b.id,name,b.x-tw.turtle.canvas.x+20,
b.y-tw.turtle.canvas.y+20,connections))
return data
def save_pict(tw,fname):
tc = tw.turtle.canvas
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, tc.width, \
+ pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, tc.width,
tc.height)
- pixbuf.get_from_drawable(tc.image, tc.image.get_colormap(), 0, 0, 0, 0, \
+ pixbuf.get_from_drawable(tc.image, tc.image.get_colormap(), 0, 0, 0, 0,
tc.width, tc.height)
pixbuf.save(fname, 'png')
-def get_id(x):
+def get_id(blocks, x):
if x==None: return None
- return x.id
+ return blocks.spr_to_block(x).id
def do_dialog(tw,dialog):
result = None
@@ -346,12 +348,14 @@ def do_dialog(tw,dialog):
dialog.destroy()
return result
-def blocks(tw): return [spr for spr in tw.sprites.list if spr.type == 'block']
+# phasing out
+def blocks(tw): return [spr for spr in tw.sprite_list.list \
+ if spr.type == 'block']
def findgroup(b):
group=[b]
for b2 in b.connections[1:]:
- if b2!=None: group.extend(findgroup(b2))
+ if b2 is not None: group.extend(findgroup(b2))
return group
def find_top_block(spr):
@@ -363,5 +367,6 @@ def find_top_block(spr):
# start a new project with a start brick
def load_start(tw):
- clone_stack(tw,str("[[0,\"start\",250,30,[null,null]]]"))
+ clone_stack(tw,"%s%s%s" % ("[[0,[\"start\",\"", _("start"),
+ "\"],250,30,[null,null]]]"))
diff --git a/tasetup.py b/tasetup.py
index 920abe3..77fc458 100644
--- a/tasetup.py
+++ b/tasetup.py
@@ -29,9 +29,6 @@ import time
from gettext import gettext as _
-# from tasprites import *
-
-import block
import sprites
from constants import *
@@ -266,21 +263,10 @@ def setup_selectors(tw,s):
tw.selbuttons.append(cat)
def setup_misc(tw):
- # tw.category_spr = Sprite(tw, 0, 0, tw.selbuttons[0].group)
- tw.category_spr = sprites.Sprite(tw.sprites, 0, 0, tw.selbuttons[0].group)
+ tw.category_spr = sprites.Sprite(tw.sprite_list, 0, 0,
+ tw.selbuttons[0].group)
tw.category_spr.type = 'category'
tw.category_spr.set_layer(CATEGORY_LAYER)
- # masks get positioned on top of other blocks
- # tw.select_mask = Sprite(tw,100,100,\
- tw.select_mask = sprites.Sprite(tw.sprites, 100, 100,\
- load_image(tw, tw.path, '', 'masknumber'))
- tw.select_mask.type = 'selectmask'
- tw.select_mask.hide()
- # tw.select_mask_string = Sprite(tw,100,100,\
- tw.select_mask_string = sprites.Sprite(tw.sprites, 100, 100,\
- load_image(tw, tw.path, '', 'maskstring'))
- tw.select_mask_string.type = 'selectmask'
- tw.select_mask_string.hide()
# used to hide the palette
tw.hidden_palette_icon = load_image(tw, tw.path, '','blocks-')
# media blocks get positioned into other blocks
@@ -293,14 +279,14 @@ def setup_misc(tw):
tw.media_shapes['pythonloaded'] = \
load_image(tw, tw.path_lang, 'sensors', 'nop-loaded')
# coordinare systems
- # tw.cartesian_coordinates_spr = Sprite(tw, tw.width/2-600, tw.height/2-450, \
- tw.cartesian_coordinates_spr = sprites.Sprite(tw.sprites, tw.width/2-600, tw.height/2-450, \
+ tw.cartesian_coordinates_spr = sprites.Sprite(tw.sprite_list,
+ tw.width/2-600, tw.height/2-450,
load_image(tw, tw.path, '', "Cartesian"))
tw.cartesian_coordinates_spr.type = 'coordinates'
tw.cartesian_coordinates_spr.set_layer(OVERLAY_LAYER)
tw.cartesian_coordinates_spr.hide()
- # tw.polar_coordinates_spr = Sprite(tw, tw.width/2-600, tw.height/2-450, \
- tw.polar_coordinates_spr = sprites.Sprite(tw.sprites, tw.width/2-600, tw.height/2-450, \
+ tw.polar_coordinates_spr = sprites.Sprite(tw.sprite_list,
+ tw.width/2-600, tw.height/2-450,
load_image(tw, tw.path, '', "polar"))
tw.polar_coordinates_spr.type = 'coordinates'
tw.polar_coordinates_spr.set_layer(OVERLAY_LAYER)
@@ -318,9 +304,8 @@ def setup_misc(tw):
tw.status_shapes['overflowerror'] = \
load_image(tw, tw.path, '', 'overflowerror')
tw.status_shapes['syntaxerror'] = load_image(tw, tw.path, '', 'syntaxerror')
- # tw.status_spr = Sprite(tw,0,(tw.height-175), \
- tw.status_spr = sprites.Sprite(tw.sprites, 0, (tw.height-175), \
- tw.status_shapes['status'])
+ tw.status_spr = sprites.Sprite(tw.sprite_list, 0, (tw.height-175),
+ tw.status_shapes['status'])
tw.status_spr.set_label("test")
# tw.status_spr.set_label_attributes(1.0, True, "left")
tw.status_spr.type = 'status'
@@ -334,8 +319,7 @@ def setup_selector(tw,name,y,blockdescriptions):
# selector tabs
offshape = load_image(tw, tw.path, 'palette', name+'off')
onshape = load_image(tw, tw.path, 'palette', name+'on')
- # spr = Sprite(tw,143,y,offshape)
- spr = sprites.Sprite(tw.sprites, 143, y, offshape)
+ spr = sprites.Sprite(tw.sprite_list, 143, y, offshape)
spr.set_layer(TAB_LAYER)
spr.offshape = offshape
spr.onshape = onshape
diff --git a/taturtle.py b/taturtle.py
index 823e8f8..7660f97 100644
--- a/taturtle.py
+++ b/taturtle.py
@@ -23,10 +23,9 @@ import gtk
from math import sin,cos,pi
class taTurtle: pass
-# from tasprites import *
from tasetup import load_image
import sprites
-import block
+import turtlex
import pango
from constants import *
@@ -59,16 +58,15 @@ color_table = (
def tNew(tw,w,h):
t = taTurtle()
t.tw, t.width, t.height = tw, w, h
- # t.canvas = Sprite(tw,0,0,gtk.gdk.Pixmap(tw.area,w,h,-1))
- t.canvas = sprites.Sprite(tw.sprites, 0, 0, gtk.gdk.Pixmap(tw.area,w,h,-1))
+ t.canvas = sprites.Sprite(tw.sprite_list, 0, 0,
+ gtk.gdk.Pixmap(tw.area,w,h,-1))
t.canvas.type = 'canvas'
t.canvas.set_layer(CANVAS_LAYER)
t.shapelist = \
[load_image(tw, tw.path, 'shapes','t'+str(i)) for i in range(36)]
- # t.spr = Sprite(tw,100,100,t.shapelist[0])
# t.spr = sprites.Sprite(tw.sprites, 100, 100, t.shapelist[0])
- t.blk = block.Turtle(tw.blocks)
- t.spr = t.blk.spr
+ t.t = turtlex.Turtle(tw.turtle_list, tw.sprite_list)
+ t.spr = t.t.spr
t.spr.type = 'turtle'
t.spr.set_layer(TURTLE_LAYER)
t.gc = t.canvas.image.new_gc()
diff --git a/tawindow.py b/tawindow.py
index 4d47560..f40da15 100644
--- a/tawindow.py
+++ b/tawindow.py
@@ -56,6 +56,7 @@ from gettext import gettext as _
import sprites
import block
+import turtlex
"""
TurtleArt Window class abstraction
@@ -129,8 +130,9 @@ class TurtleArtWindow():
"""
NEW SVG/BLOCK initializations
"""
- self.sprites = sprites.Sprites(self.window, self.area, self.gc)
- self.blocks = block.Blocks(self.sprites)
+ self.sprite_list = sprites.Sprites(self.window, self.area, self.gc)
+ self.block_list = block.Blocks()
+ self.turtle_list = turtlex.Turtles()
"""
"""
self.turtle = tNew(self,self.width,self.height)
@@ -166,7 +168,7 @@ class TurtleArtWindow():
change the icon for user-defined blocks after Python code is loaded
"""
def set_userdefined(self):
- for spr in self.sprites.list:
+ for spr in self.sprite_list.list:
if hasattr(spr,'proto') and spr.proto.name == 'nop':
setimage(spr,self.media_shapes['pythonloaded'])
self.nop = 'pythonloaded'
@@ -178,8 +180,6 @@ class TurtleArtWindow():
if self.hide is False:
for b in self._blocks(): b.set_layer(HIDE_LAYER)
self._hide_palette()
- self.select_mask.hide()
- self.select_mask_string.hide()
self.hide = True
else:
for b in self._blocks(): b.set_layer(BLOCK_LAYER)
@@ -216,11 +216,11 @@ class TurtleArtWindow():
if verbose:
print "processing remote button press: " + str(x) + " " + str(y)
self.block_operation = 'click'
- if self.selected_block != None:
+ if self.selected_block is not None:
self._unselect()
else:
self.status_spr.set_layer(HIDE_LAYER)
- spr = self.sprites.find_sprite((x,y))
+ spr = self.sprite_list.find_sprite((x,y))
print "found %s at (%d,%d)" % (str(spr),x,y)
self.x, self.y = x,y
self.dx = 0
@@ -230,6 +230,7 @@ class TurtleArtWindow():
if hasattr(spr, 'type'):
print "type: %s" % (spr.type)
if spr.type == "canvas":
+ spr.set_layer(CANVAS_LAYER)
return True
elif spr.type == 'selbutton':
self._select_category(spr)
@@ -277,8 +278,10 @@ class TurtleArtWindow():
self.selected_block.set_label('0')
# put an upper and lower bound on numbers to prevent OverflowError
- if self.selected_block.proto.name == 'number' and \
- self.selected_block.labels[0] is not None:
+ if self.block_list.spr_to_block(self.selected_block).name == 'number'\
+ and self.selected_block.labels[0] is not None:
+ # if self.selected_block.proto.name == 'number' and \
+ # self.selected_block.labels[0] is not None:
try:
i = float(self.selected_block.labels[0])
if i > 1000000:
@@ -290,10 +293,8 @@ class TurtleArtWindow():
except ValueError:
pass
- self.select_mask.hide()
- self.select_mask_string.hide()
self.selected_block.set_shape(
- self.blocks.spr_to_block(self.selected_block).shape)
+ self.block_list.spr_to_block(self.selected_block).shape)
self.selected_block = None
"""
@@ -391,7 +392,7 @@ class TurtleArtWindow():
self.block_operation = 'move'
spr = self.draggroup[0]
- if spr.type == 'block':
+ if self.block_list.spr_to_block(spr) is not None:
self.spr = spr
dragx, dragy = self.dragpos
if mdx != 0 or mdy != 0:
@@ -413,7 +414,7 @@ class TurtleArtWindow():
# move the stack
for b in self.draggroup:
b.move((b.x+dx, b.y+dy))
- elif spr.type=='turtle':
+ if self.turtle_list.spr_to_turtle(spr) is not None:
type,dragx,dragy = self.dragpos
if type == 'move':
if mdx != 0 or mdy != 0:
@@ -437,8 +438,9 @@ class TurtleArtWindow():
get_proto_from_category
"""
def _get_proto_from_category(self, x, y):
- dx, dy = x-self.category_spr.x, y-self.category_spr.y,
- pixel = self.current_category.get_pixel(self.current_category.mask,dx,dy)
+ pixel = self.current_category.get_pixel(self.current_category.mask,
+ x-self.category_spr.x,
+ y-self.category_spr.y)
index = ((pixel%256)>>3)-1
if index==0:
return 'hide'
@@ -448,10 +450,11 @@ class TurtleArtWindow():
return self.current_category.blockprotos[index]
"""
- lets help our our user by displaying a little help
+ lets help our users by displaying a little help
"""
def _show_popup(self, x, y):
- spr = self.sprites.find_sprite((x,y))
+ spr = self.sprite_list.find_sprite((x,y))
+ blk = self.block_list.spr_to_block(spr)
if spr and spr.type == 'category':
proto = self._get_proto_from_category(x, y)
if proto and proto!='hide':
@@ -477,9 +480,9 @@ class TurtleArtWindow():
self.timeout_tag[0] = 0
except:
self.timeout_tag[0] = 0
- elif spr and spr.type == 'block':
+ elif spr and blk is not None:
if self.timeout_tag[0] == 0:
- self.timeout_tag[0] = self._do_show_popup(spr.proto.name)
+ self.timeout_tag[0] = self._do_show_popup(blk.name)
self.spr = spr
else:
if self.timeout_tag[0] > 0:
@@ -682,8 +685,8 @@ class TurtleArtWindow():
if self.dx != 0 or self.dy != 0:
if self._sharing():
if verbose:
- print "processing move: " + str(self.dx) + " " + str(self.dy)
- self.activity._send_event("m:"+str(self.dx)+":"+str(self.dy))
+ print "processing move: %d %d" % (self.dx, self.dy)
+ self.activity._send_event("m:%d:%d" % (self.dx, self.dy))
self.dx = 0
self.dy = 0
@@ -692,7 +695,8 @@ class TurtleArtWindow():
if self.draggroup == None:
return
spr = self.draggroup[0]
- if spr.type == 'turtle':
+ if self.turtle_list.spr_to_turtle(spr) is not None:
+ print "clicked on a turtle"
self.turtle.xcor = self.turtle.spr.x-self.turtle.canvas.x- \
self.turtle.canvas.width/2+30
self.turtle.ycor = self.turtle.canvas.height/2-self.turtle.spr.y+ \
@@ -701,6 +705,7 @@ class TurtleArtWindow():
display_coordinates(self)
self.draggroup = None
return
+ # remove block by dragging them onto the category palette
if self.block_operation=='move' and self.category_spr.hit((x,y)):
for b in self.draggroup: b.hide()
self.draggroup = None
@@ -715,19 +720,15 @@ class TurtleArtWindow():
if self.spr.proto.name=='number':
self.selected_block = spr
self.selected_block.set_shape(
- self.blocks.spr_to_block(
+ self.block_list.spr_to_block(
self.selected_block).selected_shape)
- # self.select_mask.move((spr.x-5,spr.y-5))
- # self.select_mask.set_layer(MASK_LAYER)
self.firstkey = True
elif self.defdict.has_key(spr.proto.name):
self.selected_block = spr
if self.spr.proto.name=='string':
self.selected_block.set_shape(
- self.blocks.spr_to_block(
+ self.block_list.spr_to_block(
self.selected_block).selected_shape)
- # self.select_mask_string.move((spr.x-5,spr.y-5))
- # self.select_mask_string.set_layer(MASK_LAYER)
self.firstkey = True
elif self.spr.proto.name in self.importblocks:
self._import_from_journal(spr)
@@ -737,7 +738,7 @@ class TurtleArtWindow():
# mark block as selected
self.selected_block = spr
self.selected_block.set_shape(
- self.blocks.spr_to_block(
+ self.block_list.spr_to_block(
self.selected_block).selected_shape)
spr.set_selected(True)
self._run_stack(spr)
@@ -748,14 +749,10 @@ class TurtleArtWindow():
def _click_block(self):
if self.spr.proto.name=='number':
self.selected_block = self.spr
- self.select_mask.move((self.spr.x-5,self.spr.y-5))
- self.select_mask.set_layer(MASK_LAYER)
self.firstkey = True
elif self.defdict.has_key(self.spr.proto.name):
self.selected_block = self.spr
if self.spr.proto.name=='string':
- self.select_mask_string.move((self.spr.x-5,self.spr.y-5))
- self.select_mask_string.set_layer(MASK_LAYER)
self.firstkey = True
elif self.spr.proto.name in self.importblocks:
self._import_from_journal(self.spr)
@@ -767,7 +764,7 @@ class TurtleArtWindow():
Repaint
"""
def _expose_cb(self, win, event):
- self.sprites.redraw_sprites()
+ self.sprite_list.redraw_sprites()
return True
"""
@@ -791,31 +788,37 @@ class TurtleArtWindow():
snap_to_dock
"""
def _snap_to_dock(self):
- d=200
- me = self.draggroup[0]
- for mydockn in range(len(me.proto.docks)):
- for you in self._blocks():
- if you in self.draggroup:
+ spr = self.draggroup[0]
+ my_block = self.block_list.spr_to_block(spr)
+ d = 200
+ for my_dockn in range(len(my_block.docks)):
+ for your_block in self.block_list.list:
+ # don't link to a block to which you're already connected
+ if your_block.spr in self.draggroup:
continue
- for yourdockn in range(len(you.proto.docks)):
- thisxy = self._dock_dx_dy(you,yourdockn,me,mydockn)
- if self._magnitude(thisxy) > d:
+ # check each dock of your_block for a possible connection
+ for your_dockn in range(len(your_block.docks)):
+ this_xy = self._dock_dx_dy(your_block, your_dockn,
+ my_block, my_dockn)
+ if self._magnitude(this_xy) > d:
continue
- d = self._magnitude(thisxy)
- bestxy=thisxy
- bestyou=you
- bestyourdockn=yourdockn
- bestmydockn=mydockn
+ print "found a match? %d" % (your_dockn)
+ d = self._magnitude(this_xy)
+ best_xy = this_xy
+ best_you = your_block
+ best_your_dockn = your_dockn
+ best_my_dockn = my_dockn
+ break
if d<200:
for b in self.draggroup:
- b.move((b.x+bestxy[0],b.y+bestxy[1]))
- blockindock=bestyou.connections[bestyourdockn]
- if blockindock!=None:
- for b in findgroup(blockindock):
+ b.move((b.x+best_xy[0],b.y+best_xy[1]))
+ block_in_dock = best_you.connections[best_your_dockn]
+ if block_in_dock is not None:
+ for b in findgroup(block_in_dock):
b.hide()
- bestyou.connections[bestyourdockn]=me
- me.connections[bestmydockn]=bestyou
-
+ best_you.connections[best_your_dockn] = my_block.spr
+ if my_block.connections is not None:
+ my_block.connections[best_my_dockn] = best_you.spr
"""
import from Journal
@@ -823,7 +826,7 @@ class TurtleArtWindow():
def _import_from_journal(self, spr):
if hasattr(self, "activity"): # this should be a method: _inside_sugar()
chooser = ObjectChooser('Choose image', None,\
- gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
try:
result = chooser.run()
if result == gtk.RESPONSE_ACCEPT:
@@ -856,7 +859,7 @@ class TurtleArtWindow():
filter out blocks
"""
def _blocks(self):
- return [spr for spr in self.sprites.list if spr.type == 'block']
+ return [spr for spr in self.sprite_list.list if spr.type == 'block']
"""
block selector pressed
@@ -878,7 +881,7 @@ class TurtleArtWindow():
return True
#
- # Create new instance of the block
+ # Create new instance of a block
#
# load alternative image of nop block if python code is loaded
@@ -887,31 +890,40 @@ class TurtleArtWindow():
# TODO: handle python-loaded case
# newspr = Sprite(self,x-20,y-20,self.media_shapes['pythonloaded'])
else:
- # newspr = Sprite(self,x-20,y-20,proto.image)
- newblk = block.Block(self.blocks,proto.name,x-20,y-20,[proto.name])
+ newblk = block.Block(self.block_list, self.sprite_list, proto.name,
+ x-20, y-20, [proto.name])
newspr = newblk.spr
newspr.set_layer(TOP_LAYER)
self.dragpos = 20,20
- newspr.type = 'block'
- newspr.proto = proto
+ newspr.type = 'block' # phasing this out
+ newspr.proto = proto # phasing this out
if self.defdict.has_key(newspr.proto.name):
- newspr.labels[0]=self.defdict[newspr.proto.name]
- newspr.connections = [None]*len(proto.docks)
- for i in range(len(proto.defaults)):
- dock = proto.docks[i+1]
+ newspr.labels[0]=self.defdict[newblk.name]
+ newspr.connections = [None]*len(proto.docks) # phasing this out
+ newblk.connections = [None]*len(newblk.docks)
+ print "new %s" % (newblk.connections)
+ for i in range(len(newblk.defaults)):
+ dock = newblk.docks[i+1]
+ print dock
argproto = self.protodict[self.valdict[dock[0]]]
+ print argproto
argdock = argproto.docks[0]
+ print argdock
nx,ny = newspr.x+dock[2]-argdock[2],newspr.y+dock[3]-argdock[3]
- # argspr = Sprite(self,nx,ny,argproto.image)
- argblk = block.Block(self.blocks,argproto.name,nx,ny)
+ argblk = block.Block(self.block_list, self.sprite_list,
+ argproto.name, nx, ny)
argspr = argblk.spr
argspr.type = 'block'
argspr.proto = argproto
- argspr.set_label(str(proto.defaults[i]))
+ argspr.set_label(str(newblk.defaults[i]))
argspr.set_layer(TOP_LAYER)
- argspr.connections = [newspr,None]
- newspr.connections[i+1] = argspr
+ argspr.connections = [newspr,None] # phasing this out
+ argblk.connections = [newspr,None]
+ newspr.connections[i+1] = argspr # phasing this out
+ newblk.connections[i+1] = argspr
+ print "%s %s" % (argblk.name, argblk.connections)
+ print "%s %s" % (newblk.name, newblk.connections)
self.draggroup = findgroup(newspr)
self.block_operation = 'new'
@@ -969,45 +981,46 @@ class TurtleArtWindow():
dock_dx_dy
"""
def _dock_dx_dy(self, block1, dock1n, block2, dock2n):
- dock1 = block1.proto.docks[dock1n]
- dock2 = block2.proto.docks[dock2n]
- d1type,d1dir,d1x,d1y=dock1[0:4]
- d2type,d2dir,d2x,d2y=dock2[0:4]
+ dock1 = block1.docks[dock1n]
+ dock2 = block2.docks[dock2n]
+ d1type, d1dir, d1x, d1y = dock1[0:4]
+ d2type, d2dir, d2x, d2y = dock2[0:4]
if (d2type!='num') or (dock2n!=0):
- try:
- if block1.connections[dock1n] != None:
+ if block1.connections is not None and dock1n < block1.connections\
+ and block1.connections[dock1n] is not None:
return (100,100)
- if block2.connections[dock2n] != None:
+ if block2.connections is not None and dock2n < block2.connections\
+ and block2.connections[dock2n] is not None:
return (100,100)
- except IndexError:
- print "Index Error %s %s" % (str(dock1n),str(dock2n))
- if block1==block2: return (100,100)
- if d1type!=d2type:
+ if block1 == block2:
+ return (100,100)
+ if d1type != d2type:
# some blocks can take strings or nums
- if block1.proto.name in ('write', 'plus2', 'equal', 'less', 'greater', \
- 'template1', 'template2', 'template3', \
- 'template4', 'template6', 'template7', 'nop', \
- 'print', 'stack'):
- if block1.proto.name == 'write' and d1type == 'string':
+ if block1.name in ('write', 'plus2', 'equal', 'less', 'greater',
+ 'template1', 'template2', 'template3',
+ 'template4', 'template6', 'template7', 'nop',
+ 'print', 'stack'):
+ if block1.name == 'write' and d1type == 'string':
if d2type == 'num' or d2type == 'string':
pass
else:
if d2type == 'num' or d2type == 'string':
pass
# some blocks can take strings, nums, or Journal
- elif block1.proto.name in ('show', 'push', 'storein', 'storeinbox1', \
- 'storeinbox2'):
+ elif block1.name in ('show', 'push', 'storein', 'storeinbox1',
+ 'storeinbox2'):
if d2type == 'num' or d2type == 'string' or d2type == 'journal':
pass
# some blocks can take media, audio, movies, of descriptions
- elif block1.proto.name in ('containter'):
+ elif block1.name in ('containter'):
if d1type == 'audiooff' or d1type == 'journal':
pass
else:
return (100,100)
- if d1dir==d2dir:
+ if d1dir == d2dir:
return (100,100)
- return (block1.x+d1x)-(block2.x+d2x),(block1.y+d1y)-(block2.y+d2y)
+ return ((block1.spr.x+d1x)-(block2.spr.x+d2x),
+ (block1.spr.y+d1y)-(block2.spr.y+d2y))
"""
magnitude
diff --git a/turtlex.py b/turtlex.py
new file mode 100644
index 0000000..f6e160a
--- /dev/null
+++ b/turtlex.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+#Copyright (c) 2010 Walter Bender
+
+#Permission is hereby granted, free of charge, to any person obtaining a copy
+#of this software and associated documentation files (the "Software"), to deal
+#in the Software without restriction, including without limitation the rights
+#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+#copies of the Software, and to permit persons to whom the Software is
+#furnished to do so, subject to the following conditions:
+
+#The above copyright notice and this permission notice shall be included in
+#all copies or substantial portions of the Software.
+
+#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+#THE SOFTWARE.
+
+from constants import *
+import sprite_factory
+import sprites
+from gettext import gettext as _
+
+#
+# A class for the list of blocks and everything they share in common
+#
+class Turtles:
+ def __init__(self):
+ self.list = []
+
+ def get_turtle(self, i):
+ if i < 0 or i > len(self.list)-1:
+ return(None)
+ else:
+ return(self.list[i])
+
+ def length_of_list(self):
+ return(len(self.list))
+
+ def append_to_list(self, turtle):
+ self.list.append(turtle)
+
+ def remove_from_list(self, turtle):
+ if block in self.list:
+ self.list.remove(turtle)
+
+ #
+ # sprite utilities
+ #
+ def spr_to_turtle(self, spr):
+ for b in self.list:
+ if spr == b.spr:
+ return b
+ return None
+
+#
+# A class for the individual turtles
+#
+class Turtle:
+ # The turtle is not a block, just a sprite with an orientation
+ def __init__(self, turtle_list, sprite_list, orientation=0, scale=1.0):
+ self.spr = None
+ self.orientation = orientation
+ svg = sprite_factory.SVG()
+ svg.set_scale(scale)
+ svg.set_orientation(orientation)
+ self.spr = sprites.Sprite(sprite_list, 0, 0,
+ sprite_factory.svg_str_to_pixbuf(svg.turtle()))
+ self.type = 'turtle'
+ turtle_list.append_to_list(self)
+ print "created turtle: %s" % (str(self.spr))
+
+ #
+ # TODO: generate orientations
+ #