Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2013-06-25 03:29:06 (GMT)
committer Walter Bender <walter@sugarlabs.org>2013-06-25 03:29:06 (GMT)
commit040275d412029fe5dcde82cd9b6ada041db43248 (patch)
treeb4e98a20599ee6a61b732b2c5e37fa45a0d8d784
parent9486dd411e22ffdf900dd5b51b72f4a8d3631f0f (diff)
more turtle-centric refactoring
-rw-r--r--TurtleArt/tabasics.py297
-rw-r--r--TurtleArt/tacanvas.py116
-rw-r--r--TurtleArt/tacollaboration.py72
-rw-r--r--TurtleArt/talogo.py47
-rw-r--r--TurtleArt/taturtle.py546
-rw-r--r--TurtleArt/tawindow.py242
-rw-r--r--plugins/turtle_blocks_extras/turtle_blocks_extras.py316
7 files changed, 733 insertions, 903 deletions
diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py
index 6ed08dc..0d05f19 100644
--- a/TurtleArt/tabasics.py
+++ b/TurtleArt/tabasics.py
@@ -19,7 +19,7 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
-"""
+'''
This file contains the constants that by-in-large determine the
behavior of Turtle Art. Notably, the block palettes are defined
below. If you want to add a new block to Turtle Art, you could
@@ -46,8 +46,8 @@ add_block method in the Palette class.
# case, we define the _prim_uturn function to set heading += 180.
self.tw.lc.def_prim('uturn', 0, lambda self: self._prim_uturn)
def _prim_uturn(self):
- value = self.tw.active_turtle.get_heading() + 180
- self.tw.active_turtle.set_heading(value)
+ value = self.tw.turtles.get_active_turtle().get_heading() + 180
+ self.tw.turtles.get_active_turtle().set_heading(value)
if self.tw.lc.update_values:
self.tw.lc.update_label_value('heading', value)
@@ -60,7 +60,7 @@ mypaletteoff.svg and mypaletteon.svg, where 'mypalette' is the same
string as the entry you used in instantiating the Palette class. Note
that the icons should be the same size (55x55) as the others. (This is
the default icon size for Sugar toolbars.)
-"""
+'''
from time import time, sleep
from math import sqrt
@@ -82,22 +82,22 @@ def _color_to_num(c):
def _num_type(x):
- """ Is x a number type? """
+ ''' Is x a number type? '''
if isinstance(x, (int, float)):
return True
return False
def _millisecond():
- """ Current time in milliseconds """
+ ''' Current time in milliseconds '''
return time() * 1000
class Palettes():
- """ a class for creating the palettes of blocks """
+ ''' a class for creating the palettes of blocks '''
- def __init__(self, parent):
- self.tw = parent
+ def __init__(self, turtle_window):
+ self.tw = turtle_window
self._turtle_palette()
@@ -117,7 +117,7 @@ class Palettes():
# Palette definitions
def _turtle_palette(self):
- """ The basic Turtle Art turtle palette """
+ ''' The basic Turtle Art turtle palette '''
palette = make_palette('turtle',
colors=["#00FF00", "#00A000"],
@@ -131,10 +131,11 @@ class Palettes():
default=100,
logo_command='forward',
help_string=_('moves turtle forward'))
- self.tw.lc.def_prim('forward', 1,
- lambda self, x:
- primitive_dictionary['move']
- (self.tw.active_turtle.forward, x))
+ self.tw.lc.def_prim(
+ 'forward',
+ 1,
+ lambda self, x: primitive_dictionary['move'](
+ self.tw.turtles.get_active_turtle().forward, x))
palette.add_block('back',
style='basic-style-1arg',
@@ -146,7 +147,8 @@ class Palettes():
self.tw.lc.def_prim('back', 1,
lambda self, x:
primitive_dictionary['move']
- (self.tw.active_turtle.forward, x, reverse=True))
+ (self.tw.turtles.get_active_turtle().forward, x,
+ reverse=True))
primitive_dictionary['clean'] = self._prim_clear
palette.add_block('clean',
@@ -156,8 +158,10 @@ class Palettes():
logo_command='clean',
help_string=_('clears the screen and reset the \
turtle'))
- self.tw.lc.def_prim('clean', 0,
- lambda self: primitive_dictionary['clean']())
+ self.tw.lc.def_prim(
+ 'clean',
+ 0,
+ lambda self: primitive_dictionary['clean']())
primitive_dictionary['right'] = self._prim_right
palette.add_block('left',
@@ -180,8 +184,10 @@ in degrees)'))
logo_command='right',
help_string=_('turns turtle clockwise (angle in \
degrees)'))
- self.tw.lc.def_prim('right', 1,
- lambda self, x: primitive_dictionary['right'](x))
+ self.tw.lc.def_prim(
+ 'right',
+ 1,
+ lambda self, x: primitive_dictionary['right'](x))
primitive_dictionary['arc'] = self._prim_arc
palette.add_block('arc',
@@ -191,10 +197,11 @@ degrees)'))
default=[90, 100],
logo_command='taarc',
help_string=_('moves turtle along an arc'))
- self.tw.lc.def_prim('arc', 2,
- lambda self, x, y:
- primitive_dictionary['arc']
- (self.tw.active_turtle.arc, x, y))
+ self.tw.lc.def_prim(
+ 'arc',
+ 2,
+ lambda self, x, y: primitive_dictionary['arc'](
+ self.tw.turtles.get_active_turtle().arc, x, y))
define_logo_function('taarc', 'to taarc :a :r\nrepeat round :a \
[right 1 forward (0.0175 * :r)]\nend\n')
@@ -206,10 +213,11 @@ degrees)'))
default=[0, 0],
help_string=_('moves turtle to position xcor, ycor; \
(0, 0) is in the center of the screen.'))
- self.tw.lc.def_prim('setxy2', 2,
- lambda self, x, y:
- primitive_dictionary['move']
- (self.tw.active_turtle.set_xy, x, y))
+ self.tw.lc.def_prim(
+ 'setxy2',
+ 2,
+ lambda self, x, y: primitive_dictionary['move'](
+ self.tw.turtles.get_active_turtle().set_xy, x, y))
define_logo_function('tasetxy', 'to tasetxy :x :y\nsetxy :x :y\nend\n')
primitive_dictionary['set'] = self._prim_set
@@ -221,10 +229,11 @@ degrees)'))
logo_command='seth',
help_string=_('sets the heading of the turtle (0 is \
towards the top of the screen.)'))
- self.tw.lc.def_prim('seth', 1,
- lambda self, x:
- primitive_dictionary['set']
- ('heading', self.tw.active_turtle.set_heading, x))
+ self.tw.lc.def_prim(
+ 'seth',
+ 1,
+ lambda self, x: primitive_dictionary['set'](
+ 'heading', self.tw.turtles.get_active_turtle().set_heading, x))
palette.add_block('xcor',
style='box-style',
@@ -235,8 +244,10 @@ the turtle (can be used in place of a number block)'),
prim_name='xcor',
logo_command='xcor')
self.tw.lc.def_prim(
- 'xcor', 0, lambda self:
- self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale)
+ 'xcor',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_xy()[0] /
+ self.tw.coord_scale)
palette.add_block('ycor',
style='box-style',
@@ -247,8 +258,10 @@ the turtle (can be used in place of a number block)'),
prim_name='ycor',
logo_command='ycor')
self.tw.lc.def_prim(
- 'ycor', 0, lambda self:
- self.tw.active_turtle.get_xy() / self.tw.coord_scale)
+ 'ycor',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_xy() /
+ self.tw.coord_scale)
palette.add_block('heading',
style='box-style',
@@ -259,7 +272,9 @@ turtle (can be used in place of a number block)'),
prim_name='heading',
logo_command='heading')
self.tw.lc.def_prim(
- 'heading', 0, lambda self: self.tw.active_turtle.get_heading)
+ 'heading',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_heading)
palette.add_block('turtle-label',
hidden=True,
@@ -276,16 +291,17 @@ turtle (can be used in place of a number block)'),
logo_command='tasetxypenup',
help_string=_('moves turtle to position xcor, ycor; \
(0, 0) is in the center of the screen.'))
- self.tw.lc.def_prim('setxy', 2,
- lambda self, x, y:
- primitive_dictionary['move']
- (self.tw.active_turtle.set_xy, x, y,
- pendown=False))
+ self.tw.lc.def_prim(
+ 'setxy',
+ 2,
+ lambda self, x, y: primitive_dictionary['move'](
+ self.tw.turtles.get_active_turtle().set_xy, x, y,
+ pendown=False))
define_logo_function('tasetxypenup', 'to tasetxypenup :x :y\npenup\n\
setxy :x :y\npendown\nend\n')
def _pen_palette(self):
- """ The basic Turtle Art pen palette """
+ ''' The basic Turtle Art pen palette '''
palette = make_palette('pen',
colors=["#00FFFF", "#00A0A0"],
@@ -300,8 +316,10 @@ setxy :x :y\npendown\nend\n')
logo_command='tasetbackground',
help_string=_('fills the background with (color, \
shade)'))
- self.tw.lc.def_prim('fillscreen', 2,
- lambda self, x, y: self.tw.canvas.fillscreen(x, y))
+ self.tw.lc.def_prim(
+ 'fillscreen',
+ 2,
+ lambda self, x, y: self.tw.canvas.fillscreen(x, y))
palette.add_block('fillscreen2',
style='basic-style-3arg',
@@ -312,9 +330,10 @@ shade)'))
logo_command='tasetbackground',
help_string=_('fills the background with (color, \
shade)'))
- self.tw.lc.def_prim('fillscreen2', 3,
- lambda self, x, y, z:
- self.tw.canvas.fillscreen_with_gray(x, y, z))
+ self.tw.lc.def_prim(
+ 'fillscreen2',
+ 3,
+ lambda self, x, y, z: self.tw.canvas.fillscreen_with_gray(x, y, z))
define_logo_function('tasetbackground', 'to tasetbackground :color \
:shade\ntasetshade :shade\nsetbackground :color\nend\n')
@@ -327,10 +346,11 @@ shade)'))
logo_command='tasetpencolor',
help_string=_('sets color of the line drawn by the \
turtle'))
- self.tw.lc.def_prim('setcolor', 1,
- lambda self, x:
- primitive_dictionary['set']
- ('color', self.tw.active_turtle.set_color, x))
+ self.tw.lc.def_prim(
+ 'setcolor',
+ 1,
+ lambda self, x: primitive_dictionary['set'](
+ 'color', self.tw.turtles.get_active_turtle().set_color, x))
palette.add_block('setshade',
style='basic-style-1arg',
@@ -340,10 +360,11 @@ turtle'))
logo_command='tasetshade',
help_string=_('sets shade of the line drawn by the \
turtle'))
- self.tw.lc.def_prim('setshade', 1,
- lambda self, x:
- primitive_dictionary['set']
- ('shade', self.tw.active_turtle.set_shade, x))
+ self.tw.lc.def_prim(
+ 'setshade',
+ 1,
+ lambda self, x: primitive_dictionary['set'](
+ 'shade', self.tw.turtles.get_active_turtle().set_shade, x))
palette.add_block('setgray',
style='basic-style-1arg',
@@ -352,10 +373,11 @@ turtle'))
default=100,
help_string=_('sets gray level of the line drawn by \
the turtle'))
- self.tw.lc.def_prim('setgray', 1,
- lambda self, x:
- primitive_dictionary['set']
- ('gray', self.tw.active_turtle.set_gray, x))
+ self.tw.lc.def_prim(
+ 'setgray',
+ 1,
+ lambda self, x: primitive_dictionary['set'](
+ 'gray', self.tw.turtles.get_active_turtle().set_gray, x))
palette.add_block('color',
style='box-style',
@@ -365,8 +387,10 @@ in place of a number block)'),
value_block=True,
prim_name='color',
logo_command='pencolor')
- self.tw.lc.def_prim('color', 0, lambda self:
- self.tw.active_turtle.get_color)
+ self.tw.lc.def_prim(
+ 'color',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_color)
palette.add_block('shade',
style='box-style',
@@ -375,8 +399,10 @@ in place of a number block)'),
value_block=True,
prim_name='shade',
logo_command=':shade')
- self.tw.lc.def_prim('shade', 0, lambda self:
- self.tw.active_turtle.get_shade)
+ self.tw.lc.def_prim(
+ 'shade',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_shade)
palette.add_block('gray',
style='box-style',
@@ -386,7 +412,7 @@ used in place of a number block)'),
value_block=True,
prim_name='gray')
self.tw.lc.def_prim('gray', 0, lambda self:
- self.tw.active_turtle.get_gray)
+ self.tw.turtles.get_active_turtle().get_gray)
palette.add_block('penup',
style='basic-style-extended-vertical',
@@ -394,8 +420,11 @@ used in place of a number block)'),
prim_name='penup',
logo_command='penup',
help_string=_('Turtle will not draw when moved.'))
- self.tw.lc.def_prim('penup', 0,
- lambda self: self.tw.active_turtle.set_pen(False))
+ self.tw.lc.def_prim(
+ 'penup',
+ 0,
+ lambda self:
+ self.tw.turtles.get_active_turtle().set_pen_state(False))
palette.add_block('pendown',
style='basic-style-extended-vertical',
@@ -403,8 +432,11 @@ used in place of a number block)'),
prim_name='pendown',
logo_command='pendown',
help_string=_('Turtle will draw when moved.'))
- self.tw.lc.def_prim('pendown', 0,
- lambda self: self.tw.active_turtle.set_pen(True))
+ self.tw.lc.def_prim(
+ 'pendown',
+ 0,
+ lambda self:
+ self.tw.turtles.get_active_turtle().set_pen_state(True))
palette.add_block('setpensize',
style='basic-style-1arg',
@@ -414,10 +446,10 @@ used in place of a number block)'),
logo_command='setpensize',
help_string=_('sets size of the line drawn by the \
turtle'))
- self.tw.lc.def_prim('setpensize', 1,
- lambda self, x:
- primitive_dictionary['set']
- ('pensize', self.tw.active_turtle.set_pen_size, x))
+ self.tw.lc.def_prim(
+ 'setpensize', 1,
+ lambda self, x: primitive_dictionary['set']
+ ('pensize', self.tw.turtles.get_active_turtle().set_pen_size, x))
define_logo_function('tasetpensize',
'to tasetpensize :a\nsetpensize round :a\nend\n')
@@ -427,8 +459,10 @@ turtle'))
prim_name='startfill',
help_string=_('starts filled polygon (used with end \
fill block)'))
- self.tw.lc.def_prim('startfill', 0,
- lambda self: self.tw.active_turtle.start_fill())
+ self.tw.lc.def_prim(
+ 'startfill',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().start_fill())
palette.add_block('stopfill',
style='basic-style-extended-vertical',
@@ -436,8 +470,10 @@ fill block)'))
prim_name='stopfill',
help_string=_('completes filled polygon (used with \
start fill block)'))
- self.tw.lc.def_prim('stopfill', 0,
- lambda self: self.tw.active_turtle.stop_fill())
+ self.tw.lc.def_prim(
+ 'stopfill',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().stop_fill())
palette.add_block('pensize',
style='box-style',
@@ -447,12 +483,15 @@ in place of a number block)'),
value_block=True,
prim_name='pensize',
logo_command='pensize')
- self.tw.lc.def_prim('pensize', 0, lambda self: self.tw.active_turtle.get_pen_size)
+ self.tw.lc.def_prim(
+ 'pensize',
+ 0,
+ lambda self: self.tw.turtles.get_active_turtle().get_pen_size)
define_logo_function('tapensize', 'to tapensize\noutput first round \
pensize\nend\n')
def _color_palette(self):
- """ The basic Turtle Art color palette """
+ ''' The basic Turtle Art color palette '''
palette = make_palette('colors',
colors=["#00FFFF", "#00A0A0"],
@@ -545,7 +584,7 @@ make "shade 50 \n\
tasetshade :shade \n')
def _numbers_palette(self):
- """ The basic Turtle Art numbers palette """
+ ''' The basic Turtle Art numbers palette '''
palette = make_palette('numbers',
colors=["#FF00FF", "#A000A0"],
@@ -728,7 +767,7 @@ operators'))
'or', 2, lambda self, x, y: primitive_dictionary['or'](x, y))
def _flow_palette(self):
- """ The basic Turtle Art flow palette """
+ ''' The basic Turtle Art flow palette '''
palette = make_palette('flow',
colors=["#FFC000", "#A08000"],
@@ -828,7 +867,7 @@ boolean operators from Numbers palette'))
lambda self: primitive_dictionary['stopstack']())
def _blocks_palette(self):
- """ The basic Turtle Art blocks palette """
+ ''' The basic Turtle Art blocks palette '''
palette = make_palette('blocks',
colors=["#FFFF00", "#A0A000"],
@@ -989,7 +1028,7 @@ variable'))
self.tw.lc.def_prim('stack2', 0, primitive_dictionary['stack2'], True)
def _trash_palette(self):
- """ The basic Turtle Art turtle palette """
+ ''' The basic Turtle Art turtle palette '''
palette = make_palette('trash',
colors=["#FFFF00", "#A0A000"],
@@ -1014,27 +1053,30 @@ variable'))
def _prim_clear(self):
self.tw.lc.prim_clear()
- self.tw.reset_turtles()
+ self.tw.turtles.reset_turtles()
def _prim_and(self, x, y):
- """ Logical and """
+ ''' Logical and '''
return x & y
def _prim_arc(self, cmd, value1, value2):
- """ Turtle draws an arc of degree, radius """
+ ''' Turtle draws an arc of degree, radius '''
cmd(float(value1), float(value2))
if self.tw.lc.update_values:
self.tw.lc.update_label_value(
'xcor',
- self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale)
+ self.tw.turtles.get_active_turtle().get_xy()[0] /
+ self.tw.coord_scale)
self.tw.lc.update_label_value(
'ycor',
- self.tw.active_turtle.get_xy()[1] / self.tw.coord_scale)
- self.tw.lc.update_label_value('heading',
- self.tw.active_turtle.get_heading)
+ self.tw.turtles.get_active_turtle().get_xy()[1] /
+ self.tw.coord_scale)
+ self.tw.lc.update_label_value(
+ 'heading',
+ self.tw.turtles.get_active_turtle().get_heading)
def _prim_box(self, x):
- """ Retrieve value from named box """
+ ''' Retrieve value from named box '''
if isinstance(convert(x, float, False), float):
if int(float(x)) == x:
x = int(x)
@@ -1044,7 +1086,7 @@ variable'))
raise logoerror("#emptybox")
def _prim_forever(self, blklist):
- """ Do list forever """
+ ''' Do list forever '''
while True:
self.tw.lc.icall(self.tw.lc.evline, blklist[:])
yield True
@@ -1054,7 +1096,7 @@ variable'))
yield True
def _prim_if(self, boolean, blklist):
- """ If bool, do list """
+ ''' If bool, do list '''
if boolean:
self.tw.lc.icall(self.tw.lc.evline, blklist[:])
yield True
@@ -1062,7 +1104,7 @@ variable'))
yield True
def _prim_ifelse(self, boolean, list1, list2):
- """ If bool, do list1, else do list2 """
+ ''' If bool, do list1, else do list2 '''
if boolean:
self.tw.lc.ijmp(self.tw.lc.evline, list1[:])
yield True
@@ -1072,7 +1114,7 @@ variable'))
def _prim_move(self, cmd, value1, value2=None, pendown=True,
reverse=False):
- """ Turtle moves by method specified in value1 """
+ ''' Turtle moves by method specified in value1 '''
if not _num_type(value1):
raise logoerror("#notanumber")
if value2 is None:
@@ -1087,17 +1129,19 @@ variable'))
if self.tw.lc.update_values:
self.tw.lc.update_label_value(
'xcor',
- self.tw.active_turtle.get_xy()[0] / self.tw.coord_scale)
+ self.tw.turtles.get_active_turtle().get_xy()[0] /
+ self.tw.coord_scale)
self.tw.lc.update_label_value(
'ycor',
- self.tw.active_turtle.get_xy()[1] / self.tw.coord_scale)
+ self.tw.turtles.get_active_turtle().get_xy()[1] /
+ self.tw.coord_scale)
def _prim_or(self, x, y):
- """ Logical or """
+ ''' Logical or '''
return x | y
def _prim_repeat(self, num, blklist):
- """ Repeat list num times. """
+ ''' Repeat list num times. '''
if not _num_type(num):
raise logoerror("#notanumber")
num = self.tw.lc.int(num)
@@ -1110,26 +1154,27 @@ variable'))
yield True
def _prim_right(self, value, reverse=False):
- """ Turtle rotates clockwise """
+ ''' Turtle rotates clockwise '''
if not _num_type(value):
raise logoerror("#notanumber")
if reverse:
- self.tw.active_turtle.right(float(-value))
+ self.tw.turtles.get_active_turtle().right(float(-value))
else:
- self.tw.active_turtle.right(float(value))
+ self.tw.turtles.get_active_turtle().right(float(value))
if self.tw.lc.update_values:
- self.tw.lc.update_label_value('heading',
- self.tw.active_turtle.get_heading)
+ self.tw.lc.update_label_value(
+ 'heading',
+ self.tw.turtles.get_active_turtle().get_heading)
def _prim_set(self, name, cmd, value=None):
- """ Set a value and update the associated value blocks """
+ ''' Set a value and update the associated value blocks '''
if value is not None:
cmd(value)
if self.tw.lc.update_values:
self.tw.lc.update_label_value(name, value)
def _prim_setbox(self, name, x, val):
- """ Define value of named box """
+ ''' Define value of named box '''
if x is not None:
if isinstance(convert(x, float, False), float):
if int(float(x)) == x:
@@ -1143,7 +1188,7 @@ variable'))
self.tw.lc.update_label_value(name, val)
def _prim_stack(self, x):
- """ Process a named stack """
+ ''' Process a named stack '''
if isinstance(convert(x, float, False), float):
if int(float(x)) == x:
x = int(x)
@@ -1158,7 +1203,7 @@ variable'))
yield True
def _prim_stack1(self):
- """ Process Stack 1 """
+ ''' Process Stack 1 '''
if self.tw.lc.stacks['stack1'] is None:
raise logoerror("#nostack")
self.tw.lc.icall(self.tw.lc.evline,
@@ -1169,7 +1214,7 @@ variable'))
yield True
def _prim_stack2(self):
- """ Process Stack 2 """
+ ''' Process Stack 2 '''
if self.tw.lc.stacks['stack2'] is None:
raise logoerror("#nostack")
self.tw.lc.icall(self.tw.lc.evline, self.tw.lc.stacks['stack2'][:])
@@ -1179,29 +1224,29 @@ variable'))
yield True
def _prim_start(self):
- """ Start block: recenter """
+ ''' Start block: recenter '''
if self.tw.running_sugar:
self.tw.activity.recenter()
def _prim_stopstack(self):
- """ Stop execution of a stack """
+ ''' Stop execution of a stack '''
self.tw.lc.procstop = True
def _prim_wait(self, wait_time):
- """ Show the turtle while we wait """
- self.tw.active_turtle.show()
+ ''' Show the turtle while we wait '''
+ self.tw.turtles.get_active_turtle().show()
endtime = _millisecond() + wait_time * 1000.
while _millisecond() < endtime:
sleep(wait_time / 10.)
yield True
- self.tw.active_turtle.hide()
+ self.tw.turtles.get_active_turtle().hide()
self.tw.lc.ireturn()
yield True
# Math primitivies
def _prim_careful_divide(self, x, y):
- """ Raise error on divide by zero """
+ ''' Raise error on divide by zero '''
if isinstance(x, list) and _num_type(y):
z = []
for i in range(len(x)):
@@ -1225,7 +1270,7 @@ variable'))
raise logoerror("#notanumber")
def _prim_equal(self, x, y):
- """ Numeric and logical equal """
+ ''' Numeric and logical equal '''
if isinstance(x, list) and isinstance(y, list):
for i in range(len(x)):
if x[i] != y[i]:
@@ -1247,7 +1292,7 @@ variable'))
raise logoerror("#syntaxerror")
def _prim_less(self, x, y):
- """ Compare numbers and strings """
+ ''' Compare numbers and strings '''
if isinstance(x, list) or isinstance(y, list):
raise logoerror("#syntaxerror")
try:
@@ -1266,11 +1311,11 @@ variable'))
raise logoerror("#notanumber")
def _prim_more(self, x, y):
- """ Compare numbers and strings """
+ ''' Compare numbers and strings '''
return self._prim_less(y, x)
def _prim_plus(self, x, y):
- """ Add numbers, concat strings """
+ ''' Add numbers, concat strings '''
if x in COLORDICT:
x = _color_to_num(x)
if y in COLORDICT:
@@ -1294,7 +1339,7 @@ variable'))
return(xx + yy)
def _prim_minus(self, x, y):
- """ Numerical subtraction """
+ ''' Numerical subtraction '''
if _num_type(x) and _num_type(y):
return(x - y)
elif isinstance(x, list) and isinstance(y, list):
@@ -1308,7 +1353,7 @@ variable'))
raise logoerror("#notanumber")
def _prim_product(self, x, y):
- """ Numerical multiplication """
+ ''' Numerical multiplication '''
if _num_type(x) and _num_type(y):
return(x * y)
elif isinstance(x, list) and _num_type(y):
@@ -1327,7 +1372,7 @@ variable'))
raise logoerror("#notanumber")
def _prim_mod(self, x, y):
- """ Numerical mod """
+ ''' Numerical mod '''
if _num_type(x) and _num_type(y):
return(x % y)
try:
@@ -1338,7 +1383,7 @@ variable'))
raise logoerror("#syntaxerror")
def _prim_sqrt(self, x):
- """ Square root """
+ ''' Square root '''
if _num_type(x):
if x < 0:
raise logoerror("#negroot")
@@ -1351,7 +1396,7 @@ variable'))
raise logoerror("#notanumber")
def _prim_random(self, x, y):
- """ Random integer """
+ ''' Random integer '''
if _num_type(x) and _num_type(y):
return(int(round(uniform(x, y), 0)))
xx, xflag = chr_to_ord(x)
@@ -1368,13 +1413,13 @@ variable'))
raise logoerror("#notanumber")
def _prim_identity(self, x):
- """ Identity function """
+ ''' Identity function '''
return(x)
# Utilities
def _string_to_num(self, x):
- """ Try to comvert a string to a number """
+ ''' Try to comvert a string to a number '''
if isinstance(x, (int, float)):
return(x)
try:
@@ -1396,7 +1441,7 @@ variable'))
raise logoerror("#syntaxerror")
def _make_constant(self, palette, block_name, label, constant):
- """ Factory for constant blocks """
+ ''' Factory for constant blocks '''
if constant in COLORDICT:
if COLORDICT[constant][0] is not None:
value = str(COLORDICT[constant][0])
diff --git a/TurtleArt/tacanvas.py b/TurtleArt/tacanvas.py
index 1b02a31..2d88690 100644
--- a/TurtleArt/tacanvas.py
+++ b/TurtleArt/tacanvas.py
@@ -21,15 +21,13 @@
#THE SOFTWARE.
import gtk
-import gobject
-from math import sin, cos, pi
+from math import pi
import os
import pango
import cairo
import pangocairo
-from tautils import (image_to_base64, get_path, data_to_string, round_int,
- debug_output)
+from tautils import get_path
from taconstants import COLORDICT
@@ -112,21 +110,15 @@ class TurtleGraphics:
cr = gtk.gdk.CairoContext(self.canvas)
cr.set_line_cap(1) # Set the line cap to be round
self.cr_svg = None # Surface used for saving to SVG
- self.cx = 0
- self.cy = 0
self.fgrgb = [255, 0, 0]
self.bgrgb = [255, 248, 222]
- self.textsize = 48 # deprecated
self.shade = 0
- self.pen_down = False
- self.xcor = 0
- self.ycor = 0
- self.heading = 0
- self.pen_size = 5
self.color = 0
self.gray = 100
- self.fill = False
- self.poly_points = []
+ self.textsize = 48
+ self.cx = 0
+ self.cy = 0
+ self.set_pen_size(5)
def setup_svg_surface(self):
''' Set up a surface for saving to SVG '''
@@ -197,10 +189,10 @@ class TurtleGraphics:
cr.arc_negative(x, y, r, h * DEGTOR, (h - a) * DEGTOR)
cr.stroke()
- _larc(self.canvas, x, y, r, a, self.heading)
+ _larc(self.canvas, x, y, r, a, heading)
self.inval()
if self.cr_svg is not None:
- _larc(self.cr_svg, x, y, r, a, self.heading)
+ _larc(self.cr_svg, x, y, r, a, heading)
def set_pen_size(self, pen_size):
''' Set the pen size '''
@@ -215,23 +207,31 @@ class TurtleGraphics:
def fillscreen_with_gray(self, color, shade, gray):
''' Fill screen with color/shade/gray and reset to defaults '''
+ save_rgb = self.fgrgb[:]
+
# Special case for color blocks
if color in COLORDICT:
if COLORDICT[color][0] is None:
self.shade = COLORDICT[color][1]
else:
self.color = COLORDICT[color][0]
+ else:
+ self.color = color
if shade in COLORDICT:
self.shade = COLORDICT[shade][1]
+ else:
+ self.shade = shade
if gray in COLORDICT:
self.gray = COLORDICT[gray][2]
+ else:
+ self.gray = gray
if self.gray < 0:
self.gray = 0
if self.gray > 100:
self.gray = 100
- self.set_fgcolor(self)
+ self.set_fgcolor(shade=self.shade, gray=self.gray, color=self.color)
self.bgrgb = self.fgrgb[:]
def _fillscreen(cr, rgb, w, h):
@@ -244,16 +244,16 @@ class TurtleGraphics:
if self.cr_svg is not None:
_fillscreen(self.cr_svg, self.fgrgb, self.width, self.height)
- # self.tw.active_turtle.set_fill(state=False)
+ self.fgrgb = save_rgb[:]
def set_fgcolor(self, shade=None, gray=None, color=None):
''' Set the foreground color '''
if shade is not None:
- self.shade=shade
+ self.shade = shade
if gray is not None:
- self.gray=gray
+ self.gray = gray
if color is not None:
- self.color=color
+ self.color = color
sh = (wrap100(self.shade) - 50) / 50.0
rgb = COLOR_TABLE[wrap100(self.color)]
r = (rgb >> 8) & 0xff00
@@ -267,10 +267,6 @@ class TurtleGraphics:
b = calc_shade(b, sh)
self.fgrgb = [r >> 8, g >> 8, b >> 8]
- def set_pen(self, state):
- ''' Lower or raise the pen '''
- self.pen_down = state
-
def draw_surface(self, surface, x, y, w, h):
''' Draw a surface '''
@@ -285,7 +281,7 @@ class TurtleGraphics:
if self.cr_svg is not None:
_draw_surface(self.cr_svg, surface, x, y, w, h)
- def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, path, share=True):
+ def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, heading):
''' Draw a pixbuf '''
def _draw_pixbuf(cr, pixbuf, a, b, x, y, w, h, heading):
@@ -302,35 +298,13 @@ class TurtleGraphics:
cc.fill()
cc.restore()
- _draw_pixbuf(self.canvas, pixbuf, a, b, x, y, w, h, self.heading)
+ _draw_pixbuf(self.canvas, pixbuf, a, b, x, y, w, h, heading)
self.inval()
if self.cr_svg is not None:
- _draw_pixbuf(self.cr_svg, pixbuf, a, b, x, y, w, h, self.heading)
- if self.tw.sharing() and share:
- if self.tw.running_sugar:
- tmp_path = get_path(self.tw.activity, 'instance')
- else:
- tmp_path = '/tmp'
- tmp_file = os.path.join(get_path(self.tw.activity, 'instance'),
- 'tmpfile.png')
- pixbuf.save(tmp_file, 'png', {'quality': '100'})
- data = image_to_base64(tmp_file, tmp_path)
- height = pixbuf.get_height()
- width = pixbuf.get_width()
- x, y = self.screen_to_turtle_coordinates(x, y)
- event = 'P|%s' % (data_to_string([self._get_my_nick(),
- [round_int(a), round_int(b),
- round_int(x), round_int(y),
- round_int(w), round_int(h),
- round_int(width),
- round_int(height),
- data]]))
- gobject.idle_add(self.tw.send_event, event)
- os.remove(tmp_file)
-
- def draw_text(self, label, x, y, size, w, share=True):
+ _draw_pixbuf(self.cr_svg, pixbuf, a, b, x, y, w, h, heading)
+
+ def draw_text(self, label, x, y, size, w, heading):
''' Draw text '''
- w *= self.tw.coord_scale
def _draw_text(cr, label, x, y, size, w, scale, heading, rgb):
cc = pangocairo.CairoContext(cr)
@@ -354,47 +328,19 @@ class TurtleGraphics:
cc.restore()
_draw_text(self.canvas, label, x, y, size, w, self.tw.coord_scale,
- self.heading, self.fgrgb)
+ heading, self.fgrgb)
self.inval()
if self.cr_svg is not None: # and self.pendown:
_draw_text(self.cr_svg, label, x, y, size, w, self.tw.coord_scale,
- self.heading, self.fgrgb)
- if self.tw.sharing() and share:
- event = 'W|%s' % (data_to_string([self._get_my_nick(),
- [label, round_int(x),
- round_int(y), round_int(size),
- round_int(w)]]))
- self.tw.send_event(event)
-
- def turtle_to_screen_coordinates(self, x, y):
- ''' The origin of turtle coordinates is the center of the screen '''
- return self.width / 2. + x, self.invert_y_coordinate(y)
-
- def screen_to_turtle_coordinates(self, x, y):
- ''' The origin of the screen coordinates is the upper left corner '''
- return x - self.width / 2., self.invert_y_coordinate(y)
-
- def invert_y_coordinate(self, y):
- ''' Positive y goes up in turtle coordinates, down in sceeen
- coordinates '''
- return self.height / 2. - y
+ heading, self.fgrgb)
def set_rgb(self, r, g, b):
self.canvas.set_source_rgb(r, g, b)
if self.cr_svg is not None:
self.cr_svg.set_source_rgb(r, g, b)
- def set_xy(self, x, y):
- self.xcor = x
- self.ycor = y
-
- def get_xy(self):
- return self.xcor, self.ycor
-
def draw_line(self, x1, y1, x2, y2):
''' Draw a line '''
- x1, y1 = self.turtle_to_screen_coordinates(x1, y1)
- x2, y2 = self.turtle_to_screen_coordinates(x2, y2)
def _draw_line(cr, x1, y1, x2, y2):
cr.move_to(x1, y1)
@@ -439,10 +385,9 @@ class TurtleGraphics:
closest_color = i
return closest_color
- def get_pixel(self):
+ def get_pixel(self, x, y):
''' Read the pixel at x, y '''
if self.tw.interactive_mode:
- x, y = self.turtle_to_screen_coordinates(self.xcor, self.ycor)
x = int(x)
y = int(y)
w = self.tw.turtle_canvas.get_width()
@@ -470,9 +415,6 @@ class TurtleGraphics:
''' Reset svg flags '''
self.cr_svg = None
- def _get_my_nick(self):
- return self.tw.nick
-
def inval(self):
''' Invalidate a region for gtk '''
self.tw.inval_all()
diff --git a/TurtleArt/tacollaboration.py b/TurtleArt/tacollaboration.py
index 32df65b..85b54f0 100644
--- a/TurtleArt/tacollaboration.py
+++ b/TurtleArt/tacollaboration.py
@@ -200,7 +200,7 @@ class Collaboration():
return
# Save active Turtle
- save_active_turtle = self._tw.active_turtle
+ save_active_turtle = self._tw.turtles.get_active_turtle()
try:
command, payload = event_message.split('|', 2)
@@ -211,7 +211,7 @@ class Collaboration():
self._processing_methods[command](payload)
# Restore active Turtle
- self._tw.canvas.set_turtle(
+ self._tw.turtles.set_turtle(
self._tw.turtles.get_turtle_key(save_active_turtle))
def send_event(self, entry):
@@ -229,13 +229,13 @@ class Collaboration():
# Make sure it is not a "rejoin".
if not nick in self._tw.remote_turtle_dictionary:
# Add new turtle for the joiner.
- self._tw.canvas.set_turtle(nick, colors)
+ self._tw.turtles.set_turtle(nick, colors)
self._tw.label_remote_turtle(nick, colors)
self._tw.remote_turtle_dictionary[nick] = colors
else:
self._tw.remote_turtle_dictionary = self._get_dictionary()
# Add new turtle for the joiner.
- self._tw.canvas.set_turtle(nick, colors)
+ self._tw.turtles.set_turtle(nick, colors)
self._tw.label_remote_turtle(nick, colors)
# Sharer should send the updated remote turtle dictionary to everyone.
@@ -264,7 +264,7 @@ class Collaboration():
# Add new the turtle.
colors = remote_turtle_dictionary[nick]
self._tw.remote_turtle_dictionary[nick] = colors
- self._tw.canvas.set_turtle(nick, colors)
+ self._tw.turtles.set_turtle(nick, colors)
# Label the remote turtle.
self._tw.label_remote_turtle(nick, colors)
debug_output('adding %s to remote turtle dictionary' %
@@ -278,8 +278,8 @@ class Collaboration():
def send_my_xy(self):
''' Set xy location so joiner can sync turtle positions. Should be
used to sync positions after turtle drag. '''
- self._tw.canvas.set_turtle(self._get_nick())
- if self._tw.canvas.pendown:
+ self._tw.turtles.set_turtle(self._get_nick())
+ if self._tw.turtles.get_active_turtle().pendown:
self.send_event('p|%s' % (data_to_string([self._get_nick(),
False])))
put_pen_back_down = True
@@ -287,14 +287,14 @@ class Collaboration():
put_pen_back_down = False
self.send_event('x|%s' %
(data_to_string([self._get_nick(),
- [int(self._tw.canvas.xcor),
- int(self._tw.canvas.ycor)]])))
+ [int(self._tw.turtles.get_active_turtle().get_xy()[0]),
+ int(self._tw.turtles.get_active_turtle().get_xy()[1])]])))
if put_pen_back_down:
self.send_event('p|%s' % (data_to_string([self._get_nick(),
True])))
self.send_event('r|%s' %
(data_to_string([self._get_nick(),
- int(self._tw.canvas.heading)])))
+ int(self._tw.turtles.get_active_turtle().get_heading())])))
def _reskin_turtle(self, payload):
if len(payload) > 0:
@@ -307,8 +307,8 @@ class Collaboration():
file_name = base64_to_image(data, tmp_path)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(file_name,
width, height)
- self._tw.canvas.set_turtle(nick)
- self._tw.active_turtle.set_shapes([pixbuf])
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_shapes([pixbuf])
def _draw_pixbuf(self, payload):
if len(payload) > 0:
@@ -322,89 +322,89 @@ class Collaboration():
file_name = base64_to_image(data, tmp_path)
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(file_name,
width, height)
- x, y = self._tw.canvas.turtle_to_screen_coordinates(x, y)
- self._tw.canvas.draw_pixbuf(pixbuf, a, b, x, y, w, h,
+ x, y = self._tw.turtles.turtle_to_screen_coordinates(x, y)
+ self._tw.turtles.get_active_turtle().draw_pixbuf(pixbuf, a, b, x, y, w, h,
file_name, False)
def _move_forward(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.forward(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().forward(x, False)
def _move_in_arc(self, payload):
if len(payload) > 0:
[nick, [a, r]] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.arc(a, r, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().arc(a, r, False)
def _rotate_turtle(self, payload):
if len(payload) > 0:
[nick, h] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.seth(h, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_heading(h, False)
def _setxy(self, payload):
if len(payload) > 0:
[nick, [x, y]] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setxy(x, y, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_xy(x, y, False)
def _draw_text(self, payload):
if len(payload) > 0:
[nick, [label, x, y, size, w]] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.draw_text(label, x, y, size, w, False)
+ self._tw.turtles.get_active_turtle().draw_text(label, x, y, size, w, False)
def _set_pen_color(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setcolor(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_color(x, False)
def _set_pen_gray_level(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setgray(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_gray(x, False)
def _set_pen_shade(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setshade(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_shade(x, False)
def _set_pen_width(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setpensize(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_pen_size(x, False)
def _set_pen_state(self, payload):
if len(payload) > 0:
[nick, x] = data_from_string(payload)
if nick != self._tw.nick:
- self._tw.canvas.set_turtle(nick)
- self._tw.canvas.setpen(x, False)
+ self._tw.turtles.set_turtle(nick)
+ self._tw.turtles.get_active_turtle().set_pen_state(x, False)
def _fill_polygon(self, payload):
- # Check to make sure that the poly_point array is passed properly
+ # TODO: FIXME
if len(payload) > 0:
[nick, poly_points] = data_from_string(payload)
shared_poly_points = []
for i in range(len(poly_points)):
shared_poly_points.append(
- (self._tw.canvas.turtle_to_screen_coordinates
+ (self._tw.turtles.turtle_to_screen_coordinates
(poly_points[i][0], poly_points[i][1])))
- self._tw.canvas.fill_polygon(shared_poly_points)
+ self._tw.turtles.get_active_turtle().fill_polygon(shared_poly_points)
def _speak(self, payload):
if len(payload) > 0:
diff --git a/TurtleArt/talogo.py b/TurtleArt/talogo.py
index 29d05d9..b8ee4dc 100644
--- a/TurtleArt/talogo.py
+++ b/TurtleArt/talogo.py
@@ -166,7 +166,7 @@ class LogoCode:
if self.tw.gst_available:
from tagplay import stop_media
stop_media(self)
- self.tw.active_turtle.show()
+ self.tw.turtles.get_active_turtle().show()
self.tw.running_blocks = False
# If we disabled hover help, reenable it
if self._disable_help:
@@ -323,7 +323,7 @@ class LogoCode:
def _setup_cmd(self, string):
""" Execute the psuedocode. """
- self.hidden_turtle = self.tw.active_turtle
+ self.hidden_turtle = self.tw.turtles.get_active_turtle()
self.hidden_turtle.hide() # Hide the turtle while we are running.
self.procstop = False
blklist = self._readline(string)
@@ -413,12 +413,12 @@ class LogoCode:
# In debugging modes, we pause between steps and show the turtle.
if self.tw.step_time > 0:
- self.tw.active_turtle.show()
+ self.tw.turtles.get_active_turtle().show()
endtime = _millisecond() + self.tw.step_time * 100.
while _millisecond() < endtime:
sleep(0.1)
yield True
- self.tw.active_turtle.hide()
+ self.tw.turtles.get_active_turtle().hide()
# 'Stand-alone' booleans are handled here.
if token == self.symopar:
@@ -537,7 +537,7 @@ class LogoCode:
self.hidden_turtle.show()
self.hidden_turtle = None
else:
- self.tw.active_turtle.show()
+ self.tw.turtles.get_active_turtle().show()
self.tw.running_blocks = False
return False
except logoerror, e:
@@ -689,11 +689,13 @@ class LogoCode:
def x2tx(self):
""" Convert screen coordinates to turtle coordinates """
- return int(self.tw.canvas.width / 2) + int(self.tw.canvas.xcor)
+ return int(self.tw.canvas.width / 2) + \
+ int(self.tw.turtles.get_active_turtle().get_xy()[0])
def y2ty(self):
""" Convert screen coordinates to turtle coordinates """
- return int(self.tw.canvas.height / 2) - int(self.tw.canvas.ycor)
+ return int(self.tw.canvas.height / 2) - \
+ int(self.tw.turtles.get_active_turtle().get_xy()[1])
def wpercent(self):
""" width as a percentage of screen coordinates """
@@ -742,20 +744,23 @@ class LogoCode:
w *= self.tw.coord_scale
h *= self.tw.coord_scale
if center:
- self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0,
- self.x2tx() - int(w / 2),
- self.y2ty() - int(h / 2), w, h,
- self.filepath)
+ self.tw.turtles.get_active_turtle().draw_pixbuf(
+ self.pixbuf, 0, 0,
+ self.x2tx() - int(w / 2),
+ self.y2ty() - int(h / 2), w, h,
+ self.filepath)
elif offset:
- self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0,
- self.x2tx(),
- self.y2ty() - h,
- w, h, self.filepath)
+ self.tw.turtles.get_active_turtle().draw_pixbuf(
+ self.pixbuf, 0, 0,
+ self.x2tx(),
+ self.y2ty() - h,
+ w, h, self.filepath)
else:
- self.tw.canvas.draw_pixbuf(self.pixbuf, 0, 0,
- self.x2tx(),
- self.y2ty(),
- w, h, self.filepath)
+ self.tw.turtles.get_active_turtle().draw_pixbuf(
+ self.pixbuf, 0, 0,
+ self.x2tx(),
+ self.y2ty(),
+ w, h, self.filepath)
def insert_desc(self, mimetype=None, description=None):
""" Description text only (at current x, y) """
@@ -786,8 +791,8 @@ class LogoCode:
else:
text = self.filepath
if text is not None:
- self.tw.canvas.draw_text(text, self.x2tx(), self.y2ty(),
- self.body_height, w)
+ self.tw.turtles.get_active_turtle().draw_text(
+ text, self.x2tx(), self.y2ty(), self.body_height, w)
def media_wait(self):
""" Wait for media to stop playing """
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index 992af95..b6e2e68 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -19,16 +19,22 @@
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
-from random import uniform
-from math import sin, cos, pi, sqrt
+import os
+
import gtk
+import gobject
import cairo
-from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS)
-from tasprite_factory import (SVG, svg_str_to_pixbuf)
-from tacanvas import (wrap100, COLOR_TABLE, COLORDICT)
+from random import uniform
+from math import sin, cos, pi, sqrt
+
+from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS, DEFAULT_TURTLE,
+ COLORDICT)
+from tasprite_factory import SVG, svg_str_to_pixbuf
+from tacanvas import wrap100, COLOR_TABLE
from sprites import Sprite
-from tautils import debug_output, data_to_string, round_int
+from tautils import (debug_output, data_to_string, round_int, get_path,
+ image_to_base64)
SHAPES = 36
DEGTOR = pi / 180.
@@ -36,7 +42,7 @@ RTODEG = 180. / pi
def generate_turtle_pixbufs(colors):
- """ Generate pixbufs for generic turtles """
+ ''' Generate pixbufs for generic turtles '''
shapes = []
svg = SVG()
svg.set_scale(1.0)
@@ -48,79 +54,148 @@ def generate_turtle_pixbufs(colors):
class Turtles:
- def __init__(self, sprite_list):
- """ Class to hold turtles """
- self.dict = dict()
- self.sprite_list = sprite_list
- self.default_pixbufs = []
-
- def get_turtle(self, k, append=False, colors=None):
- """ Find a turtle """
- if k in self.dict:
- return self.dict[k]
+ def __init__(self, turtle_window):
+ ''' Class to hold turtles '''
+ self.turtle_window = turtle_window
+ self.sprite_list = turtle_window.sprite_list
+ self.width = turtle_window.width
+ self.height = turtle_window.height
+ self.dict = {}
+ self._default_pixbufs = []
+ self._active_turtle = None
+ self._default_turtle_name = DEFAULT_TURTLE
+
+ def get_turtle(self, turtle_name, append=False, colors=None):
+ ''' Find a turtle '''
+ if turtle_name in self.dict:
+ return self.dict[turtle_name]
elif not append:
return None
else:
if colors is None:
- Turtle(self, k)
+ Turtle(self, turtle_name)
elif isinstance(colors, (list, tuple)):
- Turtle(self, k, colors)
+ Turtle(self, turtle_name, colors)
else:
- Turtle(self, k, colors.split(','))
- return self.dict[k]
+ Turtle(self, turtle_name, colors.split(','))
+ return self.dict[turtle_name]
def get_turtle_key(self, turtle):
- """ Find a turtle's name """
- for k in iter(self.dict):
- if self.dict[k] == turtle:
- return k
+ ''' Find a turtle's name '''
+ for turtle_name in iter(self.dict):
+ if self.dict[turtle_name] == turtle:
+ return turtle_name
return None
def turtle_count(self):
- """ How many turtles are there? """
+ ''' How many turtles are there? '''
return(len(self.dict))
- def add_to_dict(self, k, turtle):
- """ Add a new turtle """
- self.dict[k] = turtle
+ def add_to_dict(self, turtle_name, turtle):
+ ''' Add a new turtle '''
+ self.dict[turtle_name] = turtle
- def remove_from_dict(self, k):
- """ Delete a turtle """
- if k in self.dict:
- del(self.dict[k])
+ def remove_from_dict(self, turtle_name):
+ ''' Delete a turtle '''
+ if turtle_name in self.dict:
+ del(self.dict[turtle_name])
def show_all(self):
- """ Make all turtles visible """
- for k in iter(self.dict):
- self.dict[k].show()
+ ''' Make all turtles visible '''
+ for turtle_name in iter(self.dict):
+ self.dict[turtle_name].show()
def spr_to_turtle(self, spr):
- """ Find the turtle that corresponds to sprite spr. """
- for k in iter(self.dict):
- if spr == self.dict[k].spr:
- return self.dict[k]
+ ''' Find the turtle that corresponds to sprite spr. '''
+ for turtle_name in iter(self.dict):
+ if spr == self.dict[turtle_name].spr:
+ return self.dict[turtle_name]
return None
def get_pixbufs(self):
- """ Get the pixbufs for the default turtle shapes. """
- if self.default_pixbufs == []:
- self.default_pixbufs = generate_turtle_pixbufs(
+ ''' Get the pixbufs for the default turtle shapes. '''
+ if self._default_pixbufs == []:
+ self._default_pixbufs = generate_turtle_pixbufs(
["#008000", "#00A000"])
- return(self.default_pixbufs)
+ return(self._default_pixbufs)
+
+ def turtle_to_screen_coordinates(self, x, y):
+ ''' The origin of turtle coordinates is the center of the screen '''
+ return self.width / 2.0 + x, self.invert_y_coordinate(y)
+
+ def screen_to_turtle_coordinates(self, x, y):
+ ''' The origin of the screen coordinates is the upper left corner '''
+ return x - self.width / 2.0, self.invert_y_coordinate(y)
+
+ def invert_y_coordinate(self, y):
+ ''' Positive y goes up in turtle coordinates, down in sceeen
+ coordinates '''
+ return self.height / 2.0 - y
+
+ def reset_turtles(self):
+ for turtle_name in iter(self.dict):
+ self.set_turtle(turtle_name)
+ if not self._active_turtle.get_remote():
+ self._active_turtle.set_color(0)
+ self._active_turtle.set_shade(50)
+ self._active_turtle.set_gray(100)
+ self._active_turtle.set_pen_size(5)
+ self._active_turtle.reset_shapes()
+ self._active_turtle.set_heading(0.0)
+ self._active_turtle.set_pen_state(False)
+ self._active_turtle.move_turtle((0.0, 0.0))
+ self._active_turtle.set_pen_state(True)
+ self._active_turtle.set_fill(False)
+ self._active_turtle.hide()
+ self.set_turtle(self._default_turtle_name)
+
+ def set_turtle(self, turtle_name, colors=None):
+ ''' Select the current turtle and associated pen status '''
+ if turtle_name not in self.dict:
+ # if it is a new turtle, start it in the center of the screen
+ self._active_turtle = self.get_turtle(turtle_name, True, colors)
+ self._active_turtle.set_heading(0.0, False)
+ self._active_turtle.set_xy(0.0, 0.0, False, pendown=False)
+ self._active_turtle.set_pen_state(True)
+ elif colors is not None:
+ self._active_turtle = self.get_turtle(turtle_name, False)
+ self._active_turtle.set_turtle_colors(colors)
+ else:
+ self._active_turtle = self.get_turtle(turtle_name, False)
+ self._active_turtle.show()
+ tx, ty = self._active_turtle.get_xy()
+ self._active_turtle.set_color(share=False)
+ self._active_turtle.set_gray(share=False)
+ self._active_turtle.set_shade(share=False)
+ self._active_turtle.set_pen_size(share=False)
+ self._active_turtle.set_pen_state(share=False)
+
+ def set_default_turtle_name(self, name):
+ self._default_turtle_name = name
+
+ def get_default_turtle_name(self):
+ return self._default_turtle_name
+
+ def set_active_turtle(self, active_turtle):
+ self._active_turtle = active_turtle
+
+ def get_active_turtle(self):
+ return self._active_turtle
class Turtle:
- def __init__(self, turtle_window, turtles, key, turtle_colors=None):
- """ The turtle is not a block, just a sprite with an orientation """
- self.tw = turtle_window
- self.x = 0.0
- self.y = 0.0
+ def __init__(self, turtles, turtle_name, turtle_colors=None):
+ ''' The turtle is not a block, just a sprite with an orientation '''
+ self.turtles = turtles
self.hidden = False
self.shapes = []
self.custom_shapes = False
self.type = 'turtle'
- self.name = key
+ self.name = turtle_name
+ self.remote = False
+ self.x = 0.0
+ self.y = 0.0
self.heading = 0.0
self.pen_shade = 50
self.pen_color = 0
@@ -131,15 +206,15 @@ class Turtle:
self.pen_poly_points = []
self.label_block = None
- self._prep_shapes(key, turtles, turtle_colors)
+ self._prep_shapes(turtle_name, self.turtles, turtle_colors)
# Choose a random angle from which to attach the turtle label.
if turtles.sprite_list is not None:
- self.spr = Sprite(turtles.sprite_list, 0, 0, self.shapes[0])
+ self.spr = Sprite(self.turtles.sprite_list, 0, 0, self.shapes[0])
angle = uniform(0, pi * 4 / 3.0) # 240 degrees
w = self.shapes[0].get_width()
r = w * 0.67
- # Restrict angle the the sides 30-150; 210-330
+ # Restrict the angle to the sides: 30-150; 210-330
if angle > pi * 2 / 3.0:
angle += pi / 2.0 # + 90
self.label_xy = [int(r * sin(angle)),
@@ -150,7 +225,13 @@ class Turtle:
int(r * cos(angle) + w / 2.0)]
else:
self.spr = None
- turtles.add_to_dict(key, self)
+ self.turtles.add_to_dict(turtle_name, self)
+
+ def set_remote(self):
+ self.remote = True
+
+ def get_remote(self):
+ return self.remote
def _prep_shapes(self, name, turtles=None, turtle_colors=None):
# If the turtle name is an int, we'll use a palette color as the
@@ -183,7 +264,7 @@ class Turtle:
self.set_heading(self.heading, share=False)
def set_shapes(self, shapes, i=0):
- """ Reskin the turtle """
+ ''' Reskin the turtle '''
n = len(shapes)
if n == 1 and i > 0: # set shape[i]
if i < len(self.shapes):
@@ -193,7 +274,7 @@ class Turtle:
else: # rotate shapes
if n != 1:
debug_output("%d images passed to set_shapes: ignoring" % (n),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
if self.heading == 0.0: # rotate the shapes
images = []
w, h = shapes[0].get_width(), shapes[0].get_height()
@@ -202,11 +283,11 @@ class Turtle:
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, nw, nh)
context = cairo.Context(surface)
context = gtk.gdk.CairoContext(context)
- context.translate(nw / 2., nh / 2.)
+ context.translate(nw / 2.0, nh / 2.0)
context.rotate(i * 10 * pi / 180.)
- context.translate(-nw / 2., -nh / 2.)
- context.set_source_pixbuf(shapes[0], (nw - w) / 2.,
- (nh - h) / 2.)
+ context.translate(-nw / 2.0, -nh / 2.0)
+ context.set_source_pixbuf(shapes[0], (nw - w) / 2.0,
+ (nh - h) / 2.0)
context.rectangle(0, 0, nw, nh)
context.fill()
images.append(surface)
@@ -218,18 +299,18 @@ class Turtle:
self.show()
def reset_shapes(self):
- """ Reset the shapes to the standard turtle """
+ ''' Reset the shapes to the standard turtle '''
if self.custom_shapes:
self.shapes = generate_turtle_pixbufs(self.colors)
self.custom_shapes = False
def set_heading(self, heading, share=True):
- """ Set the turtle heading (one shape per 360/SHAPES degrees) """
+ ''' Set the turtle heading (one shape per 360/SHAPES degrees) '''
try:
self.heading = heading
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
self.heading %= 360
@@ -240,13 +321,13 @@ class Turtle:
except IndexError:
self.spr.set_shape(self.shapes[0])
- if self.tw.sharing() and share:
- event = 'r|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'r|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.heading)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_color(self, color=None, share=True):
- """ Set the pen color for this turtle. """
+ ''' Set the pen color for this turtle. '''
# Special case for color blocks
if color is not None and color in COLORDICT:
self.set_shade(COLORDICT[color][1], share)
@@ -261,26 +342,26 @@ class Turtle:
self.pen_color = color
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
- self.tw.canvas.set_fgcolor(shade=self.pen_shade,
- gray=self.pen_gray,
- color=self.pen_color)
+ self.turtles.turtle_window.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
- if self.tw.sharing() and share:
- event = 'c|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'c|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.pen_color)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_gray(self, gray=None, share=True):
- """ Set the pen gray level for this turtle. """
+ ''' Set the pen gray level for this turtle. '''
if gray is not None:
try:
self.pen_gray = gray
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
if self.pen_gray < 0:
@@ -288,62 +369,60 @@ class Turtle:
if self.pen_gray > 100:
self.pen_gray = 100
- self.tw.canvas.set_fgcolor(shade=self.pen_shade,
- gray=self.pen_gray,
- color=self.pen_color)
+ self.turtles.turtle_window.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
- if self.tw.sharing() and share:
- event = 'g|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'g|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.pen_gray)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_shade(self, shade=None, share=True):
- """ Set the pen shade for this turtle. """
+ ''' Set the pen shade for this turtle. '''
if shade is not None:
try:
self.pen_shade = shade
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
- self.tw.canvas.set_fgcolor(shade=self.pen_shade,
- gray=self.pen_gray,
- color=self.pen_color)
+ self.turtles.turtle_window.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
- if self.tw.sharing() and share:
- event = 's|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 's|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.pen_shade)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_pen_size(self, pen_size=None, share=True):
- """ Set the pen size for this turtle. """
+ ''' Set the pen size for this turtle. '''
if pen_size is not None:
try:
self.pen_size = max(0, pen_size)
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
- self.tw.canvas.set_pen_size(self.pen_size)
+ self.turtles.turtle_window.canvas.set_pen_size(self.pen_size)
- if self.tw.sharing() and share:
- event = 'w|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'w|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.pen_size)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_pen_state(self, pen_state=None, share=True):
- """ Set the pen state (down==True) for this turtle. """
+ ''' Set the pen state (down==True) for this turtle. '''
if pen_state is not None:
self.pen_state = pen_state
- self.tw.canvas.set_pen(self.pen_state)
-
- if self.tw.sharing() and share:
- event = 'p|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'p|%s' % (data_to_string([self.turtles.turtle_window.nick,
self._pen_state]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_fill(self, state=False):
self.pen_fill = state
@@ -363,16 +442,16 @@ class Turtle:
if len(self.poly_points) == 0:
return
- self.tw.canvas.fill_polygon(self.poly_points)
+ self.turtles.turtle_window.canvas.fill_polygon(self.poly_points)
- if self.tw.sharing() and share:
+ if self.turtles.turtle_window.sharing() and share:
shared_poly_points = []
for p in self.poly_points:
shared_poly_points.append(
- (self.tw.canvas.screen_to_turtle_coordinates(p[0], p[1])))
- event = 'F|%s' % (data_to_string([self.tw.nick,
- shared_poly_points]))
- self.tw.send_event(event)
+ (self.turtles.screen_to_turtle_coordinates(p[0], p[1])))
+ event = 'F|%s' % (data_to_string(
+ [self.turtles.turtle_window.nick, shared_poly_points]))
+ self.turtles.turtle_window.send_event(event)
self.poly_points = []
def hide(self):
@@ -393,171 +472,149 @@ class Turtle:
def move_turtle(self, pos=None):
if pos is None:
- x, y = self.tw.canvas.get_xy()
- else:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(pos[0], pos[1])
- if self.tw.interactive_mode:
- self.move((self.tw.canvas.cx + x - self.spr.rect.width / 2.,
- self.tw.canvas.cy + y - self.spr.rect.height / 2.))
+ x, y = self.get_xy()
else:
- self.move((self.tw.canvas.cx + x, self.tw.canvas.cy + y))
+ x, y = pos[0], pos[1]
+
+ self.x, self.y = x, y
+ self.move((x, y))
def move(self, pos):
- self.x, self.y = pos[0], pos[1]
- if not self.hidden and self.spr is not None:
- self.spr.move((int(pos[0]), int(pos[1])))
- if self.label_block is not None:
- self.label_block.spr.move((int(pos[0] + self.label_xy[0]),
- int(pos[1] + self.label_xy[1])))
- return(self.x, self.y)
+ # self.x, self.y = pos[0], pos[1]
+ x, y = self.turtles.turtle_to_screen_coordinates(pos[0], pos[1])
- def get_name(self):
- return self.name
+ if self.turtles.turtle_window.interactive_mode:
+ x -= self.spr.rect.width / 2.0
+ y -= self.spr.rect.height / 2.0
- def get_xy(self):
+ if not self.hidden and self.spr is not None:
+ self.spr.move((int(x), int(y)))
+ if self.label_block is not None:
+ self.label_block.spr.move((int(x + self.label_xy[0]),
+ int(y + self.label_xy[1])))
return(self.x, self.y)
- def get_heading(self):
- return(self.heading)
-
- def get_color(self):
- return(self.pen_color)
-
- def get_gray(self):
- return(self.pen_gray)
-
- def get_shade(self):
- return(self.pen_shade)
-
- def get_pen_size(self):
- return(self.pen_size)
-
- def get_pen_state(self):
- return(self.pen_state)
-
- def get_fill(self):
- return(self.pen_fill)
-
- def get_poly_points(self):
- return(self.poly_points)
-
def right(self, degrees, share=True):
''' Rotate turtle clockwise '''
try:
self.heading += degrees
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
self.heading %= 360
- if self.tw.sharing() and share:
- event = 'r|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'r|%s' % (data_to_string([self.turtles.turtle_window.nick,
round_int(self.heading)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def forward(self, distance, share=True):
- scaled_distance = distance * self.tw.coord_scale
+ scaled_distance = distance * self.turtles.turtle_window.coord_scale
- self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
- self.tw.canvas.fgrgb[1] / 255.,
- self.tw.canvas.fgrgb[2] / 255.)
+ self.turtles.turtle_window.canvas.set_rgb(
+ self.turtles.turtle_window.canvas.fgrgb[0] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[1] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[2] / 255.)
- oldx, oldy = self.tw.canvas.get_xy()
+ oldx, oldy = self.get_xy()
try:
xcor = oldx + scaled_distance * sin(self.heading * DEGTOR)
ycor = oldy + scaled_distance * cos(self.heading * DEGTOR)
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
- self.tw.canvas.set_xy(xcor, ycor)
if self.pen_state:
- self.tw.canvas.draw_line(oldx, oldy, xcor, ycor)
+ x1, y1 = self.turtles.turtle_to_screen_coordinates(oldx, oldy)
+ x2, y2 = self.turtles.turtle_to_screen_coordinates(xcor, ycor)
+ self.turtles.turtle_window.canvas.draw_line(x1, y1, x2, y2)
if self.pen_fill:
if self.poly_points == []:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy)
+ x, y = self.turtles.turtle_to_screen_coordinates(oldx, oldy)
self.poly_points.append(('move', x, y))
- x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor)
+ x, y = self.turtles.turtle_to_screen_coordinates(xcor, ycor)
self.poly_points.append(('line', x, y))
self.move_turtle((xcor, ycor))
- if self.tw.sharing() and share:
- event = 'f|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'f|%s' % (data_to_string([self.turtles.turtle_window.nick,
int(distance)]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def set_xy(self, x, y, share=True, pendown=True):
- oldx, oldy = self.tw.canvas.get_xy()
+ oldx, oldy = self.get_xy()
try:
- xcor = x * self.tw.coord_scale
- ycor = y * self.tw.coord_scale
- self.tw.canvas.set_xy(x, y)
+ xcor = x * self.turtles.turtle_window.coord_scale
+ ycor = y * self.turtles.turtle_window.coord_scale
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
if self.pen_state and pendown:
- self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
- self.tw.canvas.fgrgb[1] / 255.,
- self.tw.canvas.fgrgb[2] / 255.)
- self.tw.canvas.draw_line(oldx, oldy, xcor, ycor)
+ self.turtles.turtle_window.canvas.set_rgb(
+ self.turtles.turtle_window.canvas.fgrgb[0] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[1] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[2] / 255.)
+ x1, y1 = self.turtles.turtle_to_screen_coordinates(oldx, oldy)
+ x2, y2 = self.turtles.turtle_to_screen_coordinates(xcor, ycor)
+ self.turtles.turtle_window.canvas.draw_line(x1, y1, x2, y2)
if self.pen_fill:
if self.poly_points == []:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy)
+ x, y = self.turtles.turtle_to_screen_coordinates(oldx, oldy)
self.poly_points.append(('move', x, y))
- x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor)
+ x, y = self.turtles.turtle_to_screen_coordinates(xcor, ycor)
self.poly_points.append(('line', x, y))
self.move_turtle((xcor, ycor))
- if self.tw.sharing() and share:
- event = 'x|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'x|%s' % (data_to_string([self.turtles.turtle_window.nick,
[round_int(x), round_int(y)]]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def arc(self, a, r, share=True):
''' Draw an arc '''
if self.pen_state:
- self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
- self.tw.canvas.fgrgb[1] / 255.,
- self.tw.canvas.fgrgb[2] / 255.)
+ self.turtles.turtle_window.canvas.set_rgb(
+ self.turtles.turtle_window.canvas.fgrgb[0] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[1] / 255.,
+ self.turtles.turtle_window.canvas.fgrgb[2] / 255.)
try:
if a < 0:
- self.larc(-a, r)
+ xcor, ycor = self.larc(-a, r)
else:
- self.rarc(a, r)
+ xcor, ycor = self.rarc(a, r)
except (TypeError, ValueError):
debug_output('bad value sent to %s' % (__name__),
- self.tw.running_sugar)
+ self.turtles.turtle_window.running_sugar)
return
- xcor, ycor = self.tw.canvas.get_xy()
self.move_turtle((xcor, ycor))
- if self.tw.sharing() and share:
- event = 'a|%s' % (data_to_string([self.tw.nick,
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'a|%s' % (data_to_string([self.turtles.turtle_window.nick,
[round_int(a), round_int(r)]]))
- self.tw.send_event(event)
+ self.turtles.turtle_window.send_event(event)
def rarc(self, a, r):
''' draw a clockwise arc '''
- r *= self.tw.coord_scale
+ r *= self.turtles.turtle_window.coord_scale
if r < 0:
r = -r
a = -a
- xcor, ycor = self.tw.canvas.get_xy()
+ xcor, ycor = self.get_xy()
cx = xcor + r * cos(self.heading * DEGTOR)
cy = ycor - r * sin(self.heading * DEGTOR)
if self.pen_state:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy)
- self.tw.canvas.rarc(x, y, r, a, self.heading)
+ x, y = self.turtles.turtle_to_screen_coordinates(cx, cy)
+ self.turtles.turtle_window.canvas.rarc(x, y, r, a, self.heading)
if self.pen_fill:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y)
+ x, y = self.turtles.turtle_to_screen_coordinates(x, y)
if self.poly_points == []:
self.poly_points.append(('move', x, y))
self.poly_points.append(('rarc', x, y, r,
@@ -565,24 +622,24 @@ class Turtle:
(self.heading - 180 + a) * DEGTOR))
self.right(a, False)
- self.tw.canvas.set_xy(cx - r * cos(self.heading * DEGTOR),
- cy + r * sin(self.heading * DEGTOR))
+ return cx - r * cos(self.heading * DEGTOR), \
+ cy + r * sin(self.heading * DEGTOR)
def larc(self, a, r):
''' draw a counter-clockwise arc '''
- r *= self.tw.coord_scale
+ r *= self.turtles.turtle_window.coord_scale
if r < 0:
r = -r
a = -a
- xcor, ycor = self.tw.canvas.get_xy()
+ xcor, ycor = self.get_xy()
cx = xcor - r * cos(self.heading * DEGTOR)
cy = ycor + r * sin(self.heading * DEGTOR)
if self.pen_state:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy)
- self.tw.canvas.larc(x, y, r, a, self.heading)
+ x, y = self.turtles.turtle_to_screen_coordinates(cx, cy)
+ self.turtles.turtle_window.canvas.larc(x, y, r, a, self.heading)
if self.pen_fill:
- x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y)
+ x, y = self.turtles.turtle_to_screen_coordinates(x, y)
if self.poly_points == []:
self.poly_points.append(('move', x, y))
self.poly_points.append(('larc', x, y, r,
@@ -590,5 +647,86 @@ class Turtle:
(self.heading - a) * DEGTOR))
self.right(-a, False)
- self.tw.canvas.set_xy(cx + r * cos(self.heading * DEGTOR),
- cy - r * sin(self.heading * DEGTOR))
+ return cx + r * cos(self.heading * DEGTOR), \
+ cy - r * sin(self.heading * DEGTOR)
+
+ def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, path, share=True):
+ ''' Draw a pixbuf '''
+
+ self.turtles.turtle_window.canvas.draw_pixbuf(
+ pixbuf, a, b, x, y, w, h, self.heading)
+
+ if self.turtles.turtle_window.sharing() and share:
+ if self.turtles.turtle_window.running_sugar:
+ tmp_path = get_path(self.turtles.turtle_window.activity,
+ 'instance')
+ else:
+ tmp_path = '/tmp'
+ tmp_file = os.path.join(
+ get_path(self.turtles.turtle_window.activity, 'instance'),
+ 'tmpfile.png')
+ pixbuf.save(tmp_file, 'png', {'quality': '100'})
+ data = image_to_base64(tmp_file, tmp_path)
+ height = pixbuf.get_height()
+ width = pixbuf.get_width()
+
+ x, y = self.screen_to_turtle_coordinates(x, y)
+
+ event = 'P|%s' % (data_to_string([self.turtles.turtle_window.nick,
+ [round_int(a), round_int(b),
+ round_int(x), round_int(y),
+ round_int(w), round_int(h),
+ round_int(width),
+ round_int(height),
+ data]]))
+ gobject.idle_add(self.turtles.turtle_window.send_event, event)
+
+ os.remove(tmp_file)
+
+ def draw_text(self, label, x, y, size, w, share=True):
+ ''' Draw text '''
+ w *= self.turtles.turtle_window.coord_scale
+ self.turtles.turtle_window.canvas.draw_text(label, x, y, size, w,
+ self.heading)
+
+ if self.turtles.turtle_window.sharing() and share:
+ event = 'W|%s' % (data_to_string([self.turtles.turtle_window.nick,
+ [label, round_int(x),
+ round_int(y), round_int(size),
+ round_int(w)]]))
+ self.turtles.turtle_window.send_event(event)
+
+ def get_name(self):
+ return self.name
+
+ def get_xy(self):
+ return(self.x, self.y)
+
+ def get_heading(self):
+ return(self.heading)
+
+ def get_color(self):
+ return(self.pen_color)
+
+ def get_gray(self):
+ return(self.pen_gray)
+
+ def get_shade(self):
+ return(self.pen_shade)
+
+ def get_pen_size(self):
+ return(self.pen_size)
+
+ def get_pen_state(self):
+ return(self.pen_state)
+
+ def get_fill(self):
+ return(self.pen_fill)
+
+ def get_poly_points(self):
+ return(self.poly_points)
+
+ def get_pixel(self):
+ x, y = self.get_xy()
+ x, y = self.turtle_to_screen_coordinates(x, y)
+ return self.turtles.turtle_window.canvas.get_pixel(x, y)
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 79a8db2..e4c2873 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -260,18 +260,17 @@ class TurtleArtWindow():
if self.interactive_mode:
self.sprite_list.set_cairo_context(self.canvas.canvas)
- self.turtles = Turtles(self.sprite_list)
- if self.nick is None:
- self.default_turtle_name = DEFAULT_TURTLE
- else:
- self.default_turtle_name = self.nick
+ self.turtles = Turtles(self)
+ if self.nick is not None:
+ self.turtles.set_default_turtle_name(self.nick)
if mycolors is None:
- Turtle(self, self.turtles, self.default_turtle_name)
+ Turtle(self.turtles, self.turtles.get_default_turtle_name())
else:
- Turtle(self, self.turtles, self.default_turtle_name,
+ Turtle(self.turtles, self.turtles.get_default_turtle_name(),
mycolors.split(','))
- self.active_turtle = self.turtles.get_turtle(self.default_turtle_name)
- self.active_turtle.show()
+ self.turtles.set_active_turtle(self.turtles.get_turtle(
+ self.turtles.get_default_turtle_name()))
+ self.turtles.get_active_turtle().show()
self.canvas.clearscreen(False)
@@ -706,15 +705,18 @@ class TurtleArtWindow():
def draw_overlay(self, overlay):
''' Draw a coordinate grid onto the canvas. '''
- save_heading = self.canvas.heading
- self.canvas.heading = 0
- w = self.overlay_shapes[overlay].rect[2]
- h = self.overlay_shapes[overlay].rect[3]
+ width = self.overlay_shapes[overlay].rect[2]
+ height = self.overlay_shapes[overlay].rect[3]
+ if self.running_sugar:
+ y_offset = 0
+ else:
+ y_offset = ICON_SIZE
self.canvas.draw_surface(
self.overlay_shapes[overlay].cached_surfaces[0],
- (self.canvas.width - w) / 2.,
- (self.canvas.height - h) / 2., w, h)
- self.canvas.heading = save_heading
+ (self.canvas.width - width) / 2.0,
+ (self.canvas.height - height + y_offset) / 2.0,
+ width,
+ height)
def update_overlay_position(self, widget, event):
''' Reposition the overlays when window size changes '''
@@ -744,7 +746,7 @@ class TurtleArtWindow():
self.metric = False
self.canvas.width = self.width
self.canvas.height = self.height
- self.active_turtle.move_turtle()
+ self.turtles.get_active_turtle().move_turtle()
def hideshow_button(self):
''' Hide/show button '''
@@ -1711,14 +1713,16 @@ before making changes to your Turtle Blocks program'))
def _look_for_a_turtle(self, spr, x, y):
# Next, look for a turtle
- t = self.turtles.spr_to_turtle(spr)
- if t is not None:
+ turtle = self.turtles.spr_to_turtle(spr)
+ if turtle is not None:
# If turtle is shared, ignore click
- if self.remote_turtle(t.get_name()):
+ if self.remote_turtle(turtle.get_name()):
return True
- self.selected_turtle = t
- self.set_turtle(self.turtles.get_turtle_key(t))
+ self.selected_turtle = turtle
+ print self.turtles.get_turtle_key(turtle)
+ self.turtles.set_turtle(self.turtles.get_turtle_key(turtle))
self._turtle_pressed(x, y)
+ print x, y
self.update_counter = 0
return True
return False
@@ -2430,19 +2434,29 @@ before making changes to your Turtle Blocks program'))
self._adjust_dock_positions(c)
def _turtle_pressed(self, x, y):
+ x, y = self.turtles.screen_to_turtle_coordinates(x, y)
+ print 'xy', x, y
(tx, ty) = self.selected_turtle.get_xy()
+ print 'txy', tx, ty
w = self.selected_turtle.spr.rect.width / 2
h = self.selected_turtle.spr.rect.height / 2
dx = x - tx - w
dy = y - ty - h
+ print 'dxy', dx, dy
# if x, y is near the edge, rotate
if not hasattr(self.lc, 'value_blocks'):
self.lc.find_value_blocks()
self.lc.update_values = True
+ print 'a > b?', (dx * dx) + (dy * dy), ((w * w) + (h * h)) / 6
if (dx * dx) + (dy * dy) > ((w * w) + (h * h)) / 6:
- self.drag_turtle = \
- ('turn', self.canvas.heading - atan2(dy, dx) / DEGTOR, 0)
+ print 'turn'
+ self.drag_turtle = (
+ 'turn',
+ self.selected_turtle.get_heading()
+ - atan2(dy, dx) / DEGTOR,
+ 0)
else:
+ print 'move', x - tx, y - ty
self.drag_turtle = ('move', x - tx, y - ty)
def _move_cb(self, win, event):
@@ -2456,18 +2470,19 @@ before making changes to your Turtle Blocks program'))
''' Share turtle movement and rotation after button up '''
if self.sharing():
nick = self.turtle_movement_to_share.get_name()
- self.send_event("r|%s" %
- (data_to_string([nick,
- round_int(self.canvas.heading)])))
+ self.send_event("r|%s" % (data_to_string([nick,
+ round_int(
+ self.turtles.get_active_turtle().get_heading())])))
if self.canvas.pen_down:
self.send_event('p|%s' % (data_to_string([nick, False])))
put_pen_back_down = True
else:
put_pen_back_down = False
self.send_event("x|%s" %
- (data_to_string([nick,
- [round_int(self.canvas.xcor),
- round_int(self.canvas.ycor)]])))
+ (data_to_string(
+ [nick,
+ [round_int(self.turtles.get_active_turtle().get_xy()[0]),
+ round_int(self.turtles.get_active_turtle().get_xy()[1])]])))
if put_pen_back_down:
self.send_event('p|%s' % (data_to_string([nick, True])))
self.turtle_movement_to_share = None
@@ -2502,26 +2517,31 @@ before making changes to your Turtle Blocks program'))
dx = x - dragx - sx + self.selected_turtle.spr.rect.width / 2
dy = y - dragy - sy + self.selected_turtle.spr.rect.height / 2
self.selected_turtle.spr.set_layer(TOP_LAYER)
- tx, ty = self.canvas.screen_to_turtle_coordinates(sx + dx,
- sy + dy)
- if self.active_turtle.get_pen_state():
- self.active_turtle.set_pen_state(False)
- self.active_turtle.set_xy(tx, ty, share=False)
- self.active_turtle.set_pen_state(True)
+ tx, ty = self.turtles.screen_to_turtle_coordinates(sx + dx,
+ sy + dy)
+ debug_output('DRAG %f, %f' % (tx, ty), self.running_sugar)
+ if self.turtles.get_active_turtle().get_pen_state():
+ self.turtles.get_active_turtle().set_pen_state(False)
+ self.turtles.get_active_turtle().set_xy(tx, ty, share=False)
+ self.turtles.get_active_turtle().set_pen_state(True)
else:
- self.active_turtle.set_xy(tx, ty, share=False)
+ self.turtles.get_active_turtle().set_xy(tx, ty, share=False)
if self.update_counter % 5:
self.lc.update_label_value(
- 'xcor', self.canvas.xcor / self.coord_scale)
+ 'xcor', self.turtles.get_active_turtle().get_xy()[0] /
+ self.coord_scale)
self.lc.update_label_value(
- 'ycor', self.canvas.ycor / self.coord_scale)
+ 'ycor', self.turtles.get_active_turtle().get_xy()[1] /
+ self.coord_scale)
else:
dx = x - sx - self.selected_turtle.spr.rect.width / 2
dy = y - sy - self.selected_turtle.spr.rect.height / 2
- self.canvas.seth(int(dragx + atan2(dy, dx) / DEGTOR + 5) /
- 10 * 10, share=False)
+ self.turtles.get_active_turtle().set_heading(
+ int(dragx + atan2(dy, dx) / DEGTOR + 5) / 10 * 10,
+ share=False)
if self.update_counter % 5:
- self.lc.update_label_value('heading', self.canvas.heading)
+ self.lc.update_label_value(
+ 'heading', self.turtles.get_active_turtle().get_heading())
if self.update_counter % 20:
self.display_coordinates()
self.turtle_movement_to_share = self.selected_turtle
@@ -2684,24 +2704,24 @@ before making changes to your Turtle Blocks program'))
# Remove turtles by dragging them onto the trash palette.
if self._in_the_trash(tx, ty):
# If it is the default turtle, just recenter it.
- if k == self.default_turtle_name:
+ if k == self.turtles.get_default_turtle_name():
self._move_turtle(0, 0)
- self.canvas.heading = 0
- self.canvas.turn_turtle()
- self.lc.update_label_value('heading', self.canvas.heading)
+ self.turtles.get_active_turtle().set_heading(0)
+ # self.canvas.turn_turtle()
+ self.lc.update_label_value('heading', 0)
else:
self.selected_turtle.hide()
self.turtles.remove_from_dict(k)
- self.active_turtle = None
+ self.turtles.set_active_turtle(None)
else:
self._move_turtle(
- tx - self.canvas.width / 2. +
- self.active_turtle.spr.rect.width / 2.,
- self.canvas.height / 2. - ty -
- self.active_turtle.spr.rect.height / 2.)
+ tx - self.canvas.width / 2.0 +
+ self.turtles.get_active_turtle().spr.rect.width / 2.0,
+ self.canvas.height / 2.0 - ty -
+ self.turtles.get_active_turtle().spr.rect.height / 2.0)
self.selected_turtle = None
- if self.active_turtle is None:
- self.set_turtle(self.default_turtle_name)
+ if self.turtles.get_active_turtle() is None:
+ self.turtles.set_turtle(self.turtles.get_default_turtle_name())
self.display_coordinates()
return
@@ -2777,21 +2797,20 @@ before making changes to your Turtle Blocks program'))
turtle.label_block.spr.set_label(name[0:4] + '…')
else:
turtle.label_block.spr.set_label(name)
+ turtle.set_remote()
turtle.show()
def _move_turtle(self, x, y):
''' Move the selected turtle to (x, y). '''
- self.canvas.xcor = x
- self.canvas.ycor = y
- self.active_turtle.move_turtle()
+ self.turtles.get_active_turtle().move_turtle()
if self.interactive_mode:
self.display_coordinates()
if self.running_sugar:
self.selected_turtle.spr.set_layer(TURTLE_LAYER)
- self.lc.update_label_value('xcor',
- self.canvas.xcor / self.coord_scale)
- self.lc.update_label_value('ycor',
- self.canvas.ycor / self.coord_scale)
+ self.lc.update_label_value(
+ 'xcor', self.turtles.get_active_turtle().get_xy()[0] / self.coord_scale)
+ self.lc.update_label_value(
+ 'ycor', self.turtles.get_active_turtle().get_xy()[1] / self.coord_scale)
def _click_block(self, x, y):
''' Click block: lots of special cases to handle... '''
@@ -3546,13 +3565,15 @@ before making changes to your Turtle Blocks program'))
def _jog_turtle(self, dx, dy):
''' Jog turtle '''
if dx == -1 and dy == -1:
- self.canvas.xcor = 0
- self.canvas.ycor = 0
+ x = 0
+ y = 0
else:
- self.canvas.xcor += dx
- self.canvas.ycor += dy
- self.active_turtle = self.turtles.spr_to_turtle(self.selected_spr)
- self.active_turtle.move_turtle()
+ x, y = self.turtles.get_active_turtle().get_xy()
+ x += dx
+ y += dy
+ self.turtles.set_active_turtle(
+ self.turtles.spr_to_turtle(self.selected_spr))
+ self.turtles.get_active_turtle().move_turtle(x, y)
self.display_coordinates()
self.selected_turtle = None
@@ -3718,7 +3739,7 @@ before making changes to your Turtle Blocks program'))
if add_new_block:
# add a new block for this code at turtle position
- (tx, ty) = self.active_turtle.get_xy()
+ (tx, ty) = self.turtles.get_active_turtle().get_xy()
self._new_block('userdefined', tx, ty)
self.myblock[self.block_list.list.index(self.drag_group[0])] =\
self.python_code
@@ -3845,13 +3866,13 @@ before making changes to your Turtle Blocks program'))
def load_turtle(self, blk, key=1):
''' Restore a turtle from its saved state '''
tid, name, xcor, ycor, heading, color, shade, pensize = blk
- self.set_turtle(key)
- self.active_turtle.setxy(xcor, ycor, pendown=False)
- self.active_turtle.set_heading(heading)
- self.active_turtle.set_color(color)
- self.active_turtle.set_shade(shade)
- self.active_turtle.set_gray(100)
- self.active_turtle.set_pen_size(pensize)
+ self.turtles.set_turtle(key)
+ self.turtles.get_active_turtle().set_xy(xcor, ycor, pendown=False)
+ self.turtles.get_active_turtle().set_heading(heading)
+ self.turtles.get_active_turtle().set_color(color)
+ self.turtles.get_active_turtle().set_shade(shade)
+ self.turtles.get_active_turtle().set_gray(100)
+ self.turtles.get_active_turtle().set_pen_size(pensize)
def load_block(self, b, offset=0):
''' Restore individual blocks from saved state '''
@@ -3954,8 +3975,8 @@ before making changes to your Turtle Blocks program'))
btype = OLD_NAMES[btype]
blk = Block(self.block_list, self.sprite_list, btype,
- b[2] + self.canvas.cx + offset,
- b[3] + self.canvas.cy + offset,
+ b[2] + offset,
+ b[3] + offset,
'block', values, self.block_scale)
# If it was an unknown block type, we need to match the number
@@ -4188,8 +4209,7 @@ before making changes to your Turtle Blocks program'))
if not save_project:
sx += 20
sy += 20
- data.append((blk.id, name, sx - self.canvas.cx,
- sy - self.canvas.cy, connections))
+ data.append((blk.id, name, sx, sy, connections))
if save_turtle:
for turtle in iter(self.turtles.dict):
# Don't save remote turtles
@@ -4197,12 +4217,15 @@ before making changes to your Turtle Blocks program'))
# Save default turtle as 'Yertle'
if turtle == self.nick:
turtle = DEFAULT_TURTLE
+ x, y = self.turtles.get_active_turtle().get_xy()
data.append(
(-1,
- ['turtle', turtle],
- self.canvas.xcor, self.canvas.ycor,
- self.canvas.heading, self.canvas.color,
- self.canvas.shade, self.canvas.pensize))
+ ['turtle', turtle],
+ x, y,
+ self.turtles.get_active_turtle().get_heading(),
+ self.turtles.get_active_turtle().get_color(),
+ self.turtles.get_active_turtle().get_shade(),
+ self.turtles.get_active_turtle().get_pen_size()))
return data
def display_coordinates(self, clear=False):
@@ -4214,9 +4237,11 @@ before making changes to your Turtle Blocks program'))
elif self.interactive_mode:
self.parent.set_title('')
else:
- x = round_int(float(self.canvas.xcor) / self.coord_scale)
- y = round_int(float(self.canvas.ycor) / self.coord_scale)
- h = round_int(self.canvas.heading)
+ x = round_int(float(self.turtles.get_active_turtle().get_xy()[0]) /
+ self.coord_scale)
+ y = round_int(float(self.turtles.get_active_turtle().get_xy()[1]) /
+ self.coord_scale)
+ h = round_int(self.turtles.get_active_turtle().get_heading())
if self.running_sugar:
if int(x) == x and int(y) == y and int(h) == h:
formatting = '(%d, %d) %d'
@@ -4659,50 +4684,3 @@ variable'))
(b1x, b1y) = block1.spr.get_xy()
(b2x, b2y) = block2.spr.get_xy()
return ((b1x + d1x) - (b2x + d2x), (b1y + d1y) - (b2y + d2y))
-
- def reset_turtles(self):
- for turtle_key in iter(self.turtles.dict):
- # Don't reset remote turtles
- if not self.remote_turtle(turtle_key):
- self.set_turtle(turtle_key)
- self.active_turtle.set_color(0)
- self.active_turtle.set_shade(50)
- self.active_turtle.set_gray(100)
- self.active_turtle.set_pen_size(5)
- self.active_turtle.reset_shapes()
- self.active_turtle.set_heading(0.0)
- self.active_turtle.set_pen_state(False)
- self.active_turtle.move((0.0, 0.0))
- self.active_turtle.set_pen_state(True)
- self.active_turtle.set_fill(False)
- self.active_turtle.hide()
- self.set_turtle(self.default_turtle_name)
-
- def set_turtle(self, key, colors=None):
- ''' Select the current turtle and associated pen status '''
- if key not in self.turtles.dict:
- # if it is a new turtle, start it in the center of the screen
- self.active_turtle = self.turtles.get_turtle(k, True, colors)
- self.active_turtle.set_heading(0.0, False)
- self.active_turtle.set_xy(0.0, 0.0, False, pendown=False)
- self.active_turtle.set_pen_state(True)
- elif colors is not None:
- self.active_turtle = self.turtles.get_turtle(key, False)
- self.active_turtle.set_turtle_colors(colors)
- else:
- self.active_turtle = self.turtles.get_turtle(key, False)
- self.active_turtle.show()
- tx, ty = self.active_turtle.get_xy()
- x, y = self.canvas.screen_to_turtle_coordinates(tx, ty)
- self.canvas.set_xy(x, y)
- if self.interactive_mode:
- x, y = self.canvas.get_xy()
- debug_output('%f %f' % (x, y), self.running_sugar)
- self.canvas.set_xy(x + self.active_turtle.spr.rect.width / 2.,
- y - self.active_turtle.spr.rect.height / 2.)
- self.heading = self.active_turtle.get_heading()
- self.active_turtle.set_color(share=False)
- self.active_turtle.set_gray(share=False)
- self.active_turtle.set_shade(share=False)
- self.active_turtle.set_pen_size(share=False)
- self.active_turtle.set_pen_state(share=False)
diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
index fcbfafe..b9b359e 100644
--- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py
+++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py
@@ -60,8 +60,8 @@ class Turtle_blocks_extras(Plugin):
""" a class for defining the extra palettes that distinguish Turtle Blocks
from Turtle Art """
- def __init__(self, parent):
- self.tw = parent
+ def __init__(self, turtle_window):
+ self.tw = turtle_window
def setup(self):
SKIN_PATHS.append('plugins/turtle_blocks_extras/images')
@@ -207,22 +207,6 @@ Journal'))
lambda self, x:
primitive_dictionary['show'](x, False))
- # deprecated
- primitive_dictionary['write'] = self._prim_write
- palette.add_block('write',
- hidden=True,
- colors=["#A0FF00", "#80A000"],
- style='basic-style-1arg',
- label=_('show'),
- default=[_('text'), 32],
- prim_name='write',
- logo_command='label',
- help_string=_('draws text or show media from the \
-Journal'))
- self.tw.lc.def_prim('write', 2,
- lambda self, x, y:
- primitive_dictionary['write'](x, y))
-
primitive_dictionary['setscale'] = self._prim_setscale
palette.add_block('setscale',
style='basic-style-1arg',
@@ -690,7 +674,7 @@ module found in the Journal'))
help_string=_('chooses which turtle to command'))
self.tw.lc.def_prim('turtle', 1,
lambda self, x:
- self.tw.canvas.set_turtle(x))
+ self.tw.turtles.set_turtle(x))
primitive_dictionary['activeturtle'] = self._prim_active_turtle
palette.add_block('activeturtle',
@@ -969,101 +953,6 @@ Journal objects'))
logo_command='bottomy')
self.tw.lc.def_prim('bottomy', 0, lambda self: CONSTANTS['bottomy'])
- # deprecated blocks
-
- primitive_dictionary['t1x1'] = self._prim_t1x1
- palette.add_block('template1x1',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='portfolio-style-1x1',
- label=' ',
- prim_name='t1x1',
- default=[_('Title'), 'None'],
- special_name=_('presentation 1x1'),
- string_or_number=True,
- help_string=_('presentation template: select \
-Journal object (with description)'))
- self.tw.lc.def_prim('t1x1', 2,
- lambda self, a, b:
- primitive_dictionary['t1x1'](a, b))
-
- primitive_dictionary['t1x1a'] = self._prim_t1x1a
- palette.add_block('template1x1a',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='portfolio-style-1x1',
- label=' ',
- prim_name='t1x1a',
- default=[_('Title'), 'None'],
- special_name=_('presentation 1x1'),
- string_or_number=True,
- help_string=_('presentation template: select \
-Journal object (no description)'))
- self.tw.lc.def_prim('t1x1a', 2,
- lambda self, a, b:
- primitive_dictionary['t1x1a'](a, b))
-
- primitive_dictionary['2x1'] = self._prim_t2x1
- palette.add_block('template2x1',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='portfolio-style-2x1',
- label=' ',
- prim_name='t2x1',
- default=[_('Title'), 'None', 'None'],
- special_name=_('presentation 2x1'),
- string_or_number=True,
- help_string=_("presentation template: select two \
-Journal objects"))
- self.tw.lc.def_prim('t2x1', 3,
- lambda self, a, b, c:
- primitive_dictionary['t2x1'](a, b, c))
-
- primitive_dictionary['1x2'] = self._prim_t1x2
- palette.add_block('template1x2',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='portfolio-style-1x2',
- label=' ',
- prim_name='t1x2',
- default=[_('Title'), 'None', 'None'],
- special_name=_('presentation 1x2'),
- string_or_number=True,
- help_string=_("presentation template: select two \
-Journal objects"))
- self.tw.lc.def_prim('t1x2', 3,
- lambda self, a, b, c:
- primitive_dictionary['t1x2'](a, b, c))
-
- primitive_dictionary['t2x2'] = self._prim_t2x2
- palette.add_block('template2x2',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='portfolio-style-2x2',
- label=' ',
- prim_name='t2x2',
- default=[_('Title'), 'None', 'None', 'None', 'None'],
- special_name=_('presentation 2x2'),
- string_or_number=True,
- help_string=_("presentation template: select four \
-Journal objects"))
- self.tw.lc.def_prim('t2x2', 5,
- lambda self, a, b, c, d, e:
- primitive_dictionary['t2x2'](a, b, c, d, e))
-
- palette.add_block('templatelist',
- hidden=True,
- colors=["#0606FF", "#0606A0"],
- style='bullet-style',
- label=' ',
- prim_name='bullet',
- default=[_('Title'), '∙ '],
- special_name=_('presentation bulleted list'),
- string_or_number=True,
- help_string=_('presentation template: list of \
-bullets'))
- self.tw.lc.def_prim('bullet', 1, self._prim_list, True)
-
def _myblocks_palette(self):
''' User-defined macros are saved as a json-encoded file;
these get loaded into a palette on startup '''
@@ -1244,13 +1133,13 @@ bullets'))
def _prim_readpixel(self):
""" Read r, g, b, a from the canvas and push b, g, r to the stack """
- r, g, b, a = self.tw.canvas.get_pixel()
+ r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
self.tw.lc.heap.append(b)
self.tw.lc.heap.append(g)
self.tw.lc.heap.append(r)
def _prim_active_turtle(self):
- return(self.tw.active_turtle.name)
+ return(self.tw.turtles.get_active_turtle().get_name())
def _prim_reskin(self, media):
""" Reskin the turtle with an image from a file """
@@ -1282,13 +1171,13 @@ bullets'))
debug_output("Couldn't open skin %s" % (self.tw.lc.filepath),
self.tw.running_sugar)
if pixbuf is not None:
- self.tw.active_turtle.set_shapes([pixbuf])
- pen_state = self.tw.active_turtle.get_pen_state()
+ self.tw.turtles.get_active_turtle().set_shapes([pixbuf])
+ pen_state = self.tw.turtles.get_active_turtle().get_pen_state()
if pen_state:
- self.tw.canvas.setpen(False)
- self.tw.canvas.forward(0)
+ self.tw.turtles.get_active_turtle().set_pen_state(False)
+ self.tw.turtles.get_active_turtle().forward(0)
if pen_state:
- self.tw.canvas.setpen(True)
+ self.tw.turtles.get_active_turtle().set_pen_state(True)
if self.tw.sharing():
if self.tw.running_sugar:
@@ -1428,7 +1317,7 @@ bullets'))
def _prim_see(self):
""" Read r, g, b from the canvas and return a corresponding palette
color """
- r, g, b, a = self.tw.canvas.get_pixel()
+ r, g, b, a = self.tw.turtles.get_active_turtle().get_pixel()
color_index = self.tw.canvas.get_color_index(r, g, b)
if self.tw.lc.update_values:
self.tw.lc.update_label_value('see', color_index)
@@ -1498,7 +1387,7 @@ bullets'))
x, y = self.tw.lc.x2tx(), self.tw.lc.y2ty()
if center:
y -= self.tw.canvas.textsize
- self.tw.canvas.draw_text(string, x, y,
+ self.tw.turtles.get_active_turtle().draw_text(string, x, y,
int(self.tw.canvas.textsize *
self.tw.lc.scale / 100.),
self.tw.canvas.width - x)
@@ -1507,17 +1396,17 @@ bullets'))
x, y = self.tw.lc.x2tx(), self.tw.lc.y2ty()
if center:
y -= self.tw.canvas.textsize
- self.tw.canvas.draw_text(string, x, y,
+ self.tw.turtles.get_active_turtle().draw_text(string, x, y,
int(self.tw.canvas.textsize *
self.tw.lc.scale / 100.),
self.tw.canvas.width - x)
def _prim_showlist(self, sarray):
""" Display list of media objects """
- x = self.tw.canvas.xcor / self.tw.coord_scale
- y = self.tw.canvas.ycor / self.tw.coord_scale
+ x = self.tw.turtles.get_active_turtle.get_xy()[0] / self.tw.coord_scale
+ y = self.tw.turtles.get_active_turtle.get_xy()[1] / self.tw.coord_scale
for s in sarray:
- self.tw.canvas.setxy(x, y, pendown=False)
+ self.tw.turtles.get_active_turtle().set_xy(x, y, pendown=False)
self._prim_show(s)
y -= int(self.tw.canvas.textsize * self.tw.lead)
@@ -1576,7 +1465,7 @@ bullets'))
# Place the block at the active turtle (x, y) and move the turtle
# into position to place the next block in the stack.
# TODO: Add expandable argument
- x, y = self.tw.active_turtle.get_xy()
+ x, y = self.tw.turtles.get_active_turtle().get_xy()
if isinstance(blkname, list):
name = blkname[0]
if len(blkname) > 1:
@@ -1596,8 +1485,8 @@ bullets'))
dy = int(self._find_block(name, x, y))
# Reposition turtle to end of flow
- self.tw.canvas.ycor -= dy
- self.tw.canvas.move_turtle()
+ self.tw.turtles.get_active_turtle().get_xy()[1] -= dy
+ self.tw.turtles.get_active_turtle().move_turtle()
def _make_block(self, name, x, y, defaults):
if defaults is None:
@@ -1664,170 +1553,3 @@ bullets'))
self.tw.show_toolbar_palette(palette_name_to_index(arg))
else:
raise logoerror("#syntaxerror")
-
- # Deprecated blocks
-
- def _prim_t1x1(self, title, media):
- """ title, one image, and description """
- xo = self.tw.calc_position('t1x1')[2]
- x = -(self.tw.canvas.width / 2) + xo
- y = self.tw.canvas.height / 2
- self.tw.canvas.setxy(x, y, pendown=False)
- # save the text size so we can restore it later
- save_text_size = self.tw.canvas.textsize
- # set title text
- self.tw.canvas.settextsize(self.title_height)
- self._prim_show(title)
- # calculate and set scale for media blocks
- myscale = 45 * (self.tw.canvas.height - self.title_height * 2) \
- / self.tw.canvas.height
- self._prim_setscale(myscale)
- # set body text size
- self.tw.canvas.settextsize(self.tw.lc.body_height)
- # render media object
- # leave some space below the title
- y -= int(self.title_height * 2 * self.tw.lead)
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media)
- if self.tw.running_sugar:
- x = 0
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media.replace('media_', 'descr_'))
- # restore text size
- self.tw.canvas.settextsize(save_text_size)
-
- def _prim_t2x1(self, title, media1, media2):
- """ title, two images (horizontal), two descriptions """
- xo = self.tw.calc_position('t2x1')[2]
- x = -(self.tw.canvas.width / 2) + xo
- y = self.tw.canvas.height / 2
- self.tw.canvas.setxy(x, y, pendown=False)
- # save the text size so we can restore it later
- save_text_size = self.tw.canvas.textsize
- # set title text
- self.tw.canvas.settextsize(self.title_height)
- self._prim_show(title)
- # calculate and set scale for media blocks
- myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \
- self.tw.canvas.height
- self._prim_setscale(myscale)
- # set body text size
- self.tw.canvas.settextsize(self.tw.lc.body_height)
- # render four quadrents
- # leave some space below the title
- y -= int(self.title_height * 2 * self.tw.lead)
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1)
- x = 0
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media2)
- y = -self.title_height
- if self.tw.running_sugar:
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media2.replace('media_', 'descr_'))
- x = -(self.tw.canvas.width / 2) + xo
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1.replace('media_', 'descr_'))
- # restore text size
- self.tw.canvas.settextsize(save_text_size)
-
- def _prim_t1x2(self, title, media1, media2):
- """ title, two images (vertical), two desciptions """
- xo = self.tw.calc_position('t1x2')[2]
- x = -(self.tw.canvas.width / 2) + xo
- y = self.tw.canvas.height / 2
- self.tw.canvas.setxy(x, y, pendown=False)
- # save the text size so we can restore it later
- save_text_size = self.tw.canvas.textsize
- # set title text
- self.tw.canvas.settextsize(self.title_height)
- self._prim_show(title)
- # calculate and set scale for media blocks
- myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \
- self.tw.canvas.height
- self._prim_setscale(myscale)
- # set body text size
- self.tw.canvas.settextsize(self.tw.lc.body_height)
- # render four quadrents
- # leave some space below the title
- y -= int(self.title_height * 2 * self.tw.lead)
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1)
- if self.tw.running_sugar:
- x = 0
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1.replace('media_', 'descr_'))
- y = -self.title_height
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media2.replace('media_', 'descr_'))
- x = -(self.tw.canvas.width / 2) + xo
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media2)
- # restore text size
- self.tw.canvas.settextsize(save_text_size)
-
- def _prim_t2x2(self, title, media1, media2, media3, media4):
- """ title and four images """
- xo = self.tw.calc_position('t2x2')[2]
- x = -(self.tw.canvas.width / 2) + xo
- y = self.tw.canvas.height / 2
- self.tw.canvas.setxy(x, y, pendown=False)
- # save the text size so we can restore it later
- save_text_size = self.tw.canvas.textsize
- # set title text
- self.tw.canvas.settextsize(self.title_height)
- self._prim_show(title)
- # calculate and set scale for media blocks
- myscale = 45 * (self.tw.canvas.height - self.title_height * 2) / \
- self.tw.canvas.height
- self._prim_setscale(myscale)
- # set body text size
- self.tw.canvas.settextsize(self.tw.lc.body_height)
- # render four quadrents
- # leave some space below the title
- y -= int(self.title_height * 2 * self.tw.lead)
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1)
- x = 0
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media2)
- y = -self.title_height
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media4)
- x = -(self.tw.canvas.width / 2) + xo
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media3)
- # restore text size
- self.tw.canvas.settextsize(save_text_size)
-
- def _prim_t1x1a(self, title, media1):
- """ title, one media object """
- xo = self.tw.calc_position('t1x1a')[2]
- x = -(self.tw.canvas.width / 2) + xo
- y = self.tw.canvas.height / 2
- self.tw.canvas.setxy(x, y, pendown=False)
- # save the text size so we can restore it later
- save_text_size = self.tw.canvas.textsize
- # set title text
- self.tw.canvas.settextsize(self.title_height)
- self._prim_show(title)
- # calculate and set scale for media blocks
- myscale = 90 * (self.tw.canvas.height - self.title_height * 2) / \
- self.tw.canvas.height
- self._prim_setscale(myscale)
- # set body text size
- self.tw.canvas.settextsize(self.tw.lc.body_height)
- # render media object
- # leave some space below the title
- y -= int(self.title_height * 2 * self.tw.lead)
- self.tw.canvas.setxy(x, y, pendown=False)
- self._prim_show(media1)
- # restore text size
- self.tw.canvas.settextsize(save_text_size)
-
- def _prim_write(self, string, fsize):
- """ Write string at size """
- x = self.tw.canvas.width / 2 + int(self.tw.canvas.xcor)
- y = self.tw.canvas.height / 2 - int(self.tw.canvas.ycor)
- self.tw.canvas.draw_text(string, x, y - 15, int(fsize),
- self.tw.canvas.width)