Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TurtleArtActivity.py180
-rw-r--r--tacanvas.py94
-rw-r--r--taturtle.py7
-rw-r--r--tawindow.py29
4 files changed, 189 insertions, 121 deletions
diff --git a/TurtleArtActivity.py b/TurtleArtActivity.py
index 93a367a..cae2498 100644
--- a/TurtleArtActivity.py
+++ b/TurtleArtActivity.py
@@ -56,6 +56,7 @@ from taexporthtml import save_html
from taexportlogo import save_logo
from tautils import data_to_file, data_to_string, data_from_string, get_path
from tawindow import TurtleArtWindow
+from taturtle import Turtle
SERVICE = 'org.laptop.TurtleArtActivity'
IFACE = SERVICE
@@ -460,7 +461,7 @@ class TurtleArtActivity(activity.Activity):
f.write(code)
f.close()
except Exception, e:
- print("Couldn't dump code to view source: " + str(e))
+ _logger.error("Couldn't dump code to view source: " + str(e))
return tafile
# Sharing-related callbacks
@@ -473,7 +474,9 @@ class TurtleArtActivity(activity.Activity):
return
self.initiating = True
- self.waiting_for_blocks = False
+ self.waiting_for_turtles = False
+ self.turtle_dictionary = \
+ {profile.get_nick_name():profile.get_color().to_string()}
_logger.debug('I am sharing...')
self.conn = self._shared_activity.telepathy_conn
@@ -496,8 +499,6 @@ class TurtleArtActivity(activity.Activity):
return
self.initiating = False
- _logger.debug('I joined a shared activity.')
-
self.conn = self._shared_activity.telepathy_conn
self.tubes_chan = self._shared_activity.telepathy_tubes_chan
self.text_chan = self._shared_activity.telepathy_text_chan
@@ -511,8 +512,8 @@ class TurtleArtActivity(activity.Activity):
reply_handler=self._list_tubes_reply_cb,
error_handler=self._list_tubes_error_cb)
- # joiner should request current state from sharer
- self.waiting_for_blocks = True
+ # Joiner should request current state from sharer.
+ self.waiting_for_turtles = True
def _list_tubes_reply_cb(self, tubes):
for tube_info in tubes:
@@ -536,75 +537,137 @@ class TurtleArtActivity(activity.Activity):
self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, \
group_iface=self.text_chan[telepathy.CHANNEL_INTERFACE_GROUP])
- # we'll use a chat tube to send serialized stacks back and forth
+ # We'll use a chat tube to send serialized stacks back and forth.
self.chattube = ChatTube(tube_conn, self.initiating, \
self.event_received_cb)
- # now that we have the tube, we can ask for an initialization
- if self.waiting_for_blocks:
- self.send_event("i")
+ # Now that we have the tube, we can ask for the turtle dictionary.
+ if self.waiting_for_turtles:
+ _logger.debug("Sending a request for the turtle dictionary")
+ # we need to send our own nick and colors
+ colors = profile.get_color().to_string()
+ _logger.debug("t|"+data_to_string([self.tw.nick,colors]))
+ self.send_event("t|%s" % \
+ (data_to_string([self.tw.nick,colors])))
def event_received_cb(self, text):
""" Handle the receiving of events in share """
+ _logger.debug(text)
- """ DEPRECIATED
- Events are sent as a tuple
- cmd:data
- where cmd is a mouse or keyboard event and data are x,y coordinates
- or a keysroke
"""
- # maybe we can use a stack to share events to new-comers?
- # self._share += "text + "\n"
- if text[0] == 'p': # button press
- e, x, y, mask = text.split(":")
- # _logger.debug("receiving button press: "+x+" "+y+" "+mask)
- if mask == 'T':
- self.tw.button_press(True, int(x), int(y), False)
- else:
- self.tw.button_press(False, int(x), int(y), False)
- elif text[0] == 'r': # block release
- e, x, y = text.split(":")
- # _logger.debug("receiving button release: " + x + " " + y)
- self.tw.button_release(int(x), int(y), False)
- elif text[0] == 'm': # mouse move
- e, x, y = text.split(":")
- _logger.debug("receiving move: " + x + " " + y)
- self.tw.mouse_move(0, 0, False, int(x), int(y))
- elif text[0] == 'k': # typing
- e, mask, keyname = text.split(":", 3)
- # _logger.debug("recieving key press: " + mask + " " + keyname)
- if mask == 'T':
- self.tw.key_press(True, keyname, False)
- else:
- self.tw.key_press(False, keyname, False)
- elif text[0] == 'i': # request for current state
- # sharer should send current state to joiner
+ Events are sent as a tuple, nick|cmd, where nick is a turle name
+ and cmd is a turtle event. Everyone gets the turtle dictionary from
+ the sharer and watches for 't' events, which indicate that a new
+ turtle has joined.
+
+ """
+ # Save active Turtle
+ save_active_turtle = self.tw.active_turtle
+ if text[0] == 't': # request for turtle dictionary
+ e = text.split("|", 2)
+ text = e[1]
+ if text > 0:
+ [nick, colors] = data_from_string(text)
+ if nick != self.tw.nick:
+ # There may not be a turtle dictionary.
+ if hasattr(self, "turtle_dictionary"):
+ self.turtle_dictionary[nick] = colors
+ else:
+ self.turtle_dictionary = {nick:colors}
+ # Add new turtle for the joiner.
+ self.tw.canvas.set_turtle(nick, colors)
+ # Sharer should send turtle dictionary.
if self.initiating:
- _logger.debug("serialize the project and send to joiner")
- text = data_to_string(self.tw.assemble_data_to_save(True, True))
- self.send_event("I:" + text)
- self.tw.show_palette()
- elif text[0] == 'I': # receiving current state
- if self.waiting_for_blocks:
- _logger.debug("receiving project from sharer")
- e, text = text.split(":", 2)
+ text = data_to_string(self.turtle_dictionary)
+ self.send_event("T|" + text)
+ elif text[0] == 'T': # Receiving the turtle dictionary.
+ if self.waiting_for_turtles:
+ e = text.split("|", 2)
+ text = e[1]
if len(text) > 0:
- self.tw.new_project()
- self.tw.process_data(data_from_string(text))
- # all caught up
- self.waiting_for_blocks = False
+ self.turtle_dictionary = data_from_string(text)
+ for nick in self.turtle_dictionary:
+ if nick != self.tw.nick:
+ colors = self.turtle_dictionary[nick]
+ # add new turtle for the joiner
+ self.tw.canvas.set_turtle(nick, colors)
+ self.waiting_for_turtles = False
+ elif text[0] == 'f': # move a turtle forward
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, x] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.forward(x, False)
+ elif text[0] == 'a': # move a turtle in an arc
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, [a, r]] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.arc(a, r, False)
+ elif text[0] == 'r': # rotate turtle
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, h] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.seth(h, False)
+ elif text[0] == 'x': # set turtle xy position
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, [x, y]] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.setxy(x, y, False)
+ elif text[0] == 'c': # set turtle pen color
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, x] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.setcolor(x, False)
+ elif text[0] == 's': # set turtle pen shade
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, x] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.setshade(x, False)
+ elif text[0] == 'w': # set turtle pen width
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, x] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.setpensize(x, False)
+ elif text[0] == 'p': # set turtle pen state
+ e = text.split("|", 2)
+ text = e[1]
+ if len(text) > 0:
+ [nick, x] = data_from_string(text)
+ if nick != self.tw.nick:
+ self.tw.canvas.set_turtle(nick)
+ self.tw.canvas.setpen(x, False)
+ # Restore active Turtle
+ self.tw.canvas.set_turtle(self.tw.turtles.get_turtle_key(
+ save_active_turtle))
def send_event(self, entry):
""" Send event through the tube. """
- # nick = profile.get_nick_name()
- # nick = nick.upper()
if hasattr(self, 'chattube') and self.chattube is not None:
self.chattube.SendText(entry)
def __visibility_notify_cb(self, window, event):
""" Callback method for when the activity's visibility changes. """
if event.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED:
- # _logger.debug("I am not visible so I should free the audio")
self.tw.lc.ag = None
elif event.state in \
[gtk.gdk.VISIBILITY_UNOBSCURED, gtk.gdk.VISIBILITY_PARTIAL]:
@@ -949,8 +1012,7 @@ class TurtleArtActivity(activity.Activity):
if FILE.readline() == version:
newversion = False
except:
- _logger.debug("Writing new version data...")
- _logger.debug("...and creating a tamyblock.py Journal entry")
+ _logger.debug("Creating a tamyblock.py Journal entry")
# Make sure there is a copy of tamyblock.py in the Journal
if newversion:
@@ -1044,7 +1106,7 @@ class TurtleArtActivity(activity.Activity):
tar_fd.close()
# Otherwise, assume it is a .ta file
else:
- print "trying to open a .ta file:" + file_path
+ _logger.debug("trying to open a .ta file:" + file_path)
self.tw.load_files(file_path, run_it)
# run the activity
diff --git a/tacanvas.py b/tacanvas.py
index 7398008..a6c0056 100644
--- a/tacanvas.py
+++ b/tacanvas.py
@@ -23,9 +23,8 @@ import gtk
from math import sin, cos, pi
from sprites import Sprite
from tasprite_factory import SVG
-from tautils import image_to_base64
+from tautils import image_to_base64, data_to_string
import pango
-
from taconstants import CANVAS_LAYER, DEFAULT_TURTLE
def wrap100(n):
@@ -98,39 +97,38 @@ class TurtleGraphics:
self.svg = SVG()
self.svg.set_fill_color('none')
self.tw.svg_string = ''
- self.clearscreen()
+ self.clearscreen(False)
- def clearscreen(self):
+ def clearscreen(self, share=True):
rect = gtk.gdk.Rectangle(0, 0, self.width, self.height)
self.gc.set_foreground(self.bgcolor)
self.canvas.images[0].draw_rectangle(self.gc, True, *rect)
self.invalt(0, 0, self.width, self.height)
- self.setpensize(5)
- self.setcolor(0)
+ self.setpensize(5, share)
+ self.setcolor(0, share)
self.settextcolor(70)
self.settextsize(48)
- self.setshade(50)
- self.pendown = True
+ self.setshade(50, share)
+ self.setpen(True, share)
for turtle_key in iter(self.tw.turtles.dict):
self.set_turtle(turtle_key)
self.tw.active_turtle.set_color(0)
self.tw.active_turtle.set_shade(50)
self.tw.active_turtle.set_pen_size(5)
self.tw.active_turtle.set_pen_state(True)
- self.xcor, self.ycor, self.heading = 0, 0, 0
- self.move_turtle()
- self.turn_turtle()
+ self.seth(0, share)
+ self.setxy(0, 0, share)
self.set_turtle(DEFAULT_TURTLE)
self.tw.svg_string = ''
self.svg.reset_min_max()
- def forward(self, n):
- n *= self.tw.coord_scale
+ def forward(self, n, share=True):
+ nn = n*self.tw.coord_scale
self.gc.set_foreground(self.fgcolor)
oldx, oldy = self.xcor, self.ycor
try:
- self.xcor += n*sin(self.heading*DEGTOR)
- self.ycor += n*cos(self.heading*DEGTOR)
+ self.xcor += nn*sin(self.heading*DEGTOR)
+ self.ycor += nn*cos(self.heading*DEGTOR)
except:
pass
if self.pendown:
@@ -142,14 +140,20 @@ class TurtleGraphics:
self.height/2-self.ycor)
self.tw.svg_string += "\"\n"
self.tw.svg_string += self.svg.style()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("f|%s" % \
+ (data_to_string([self.tw.nick, int(n)])))
- def seth(self, n):
+ def seth(self, n, share=True):
try:
self.heading = n
except:
pass
self.heading %= 360
self.turn_turtle()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("r|%s" % \
+ (data_to_string([self.tw.nick, int(self.heading)])))
def right(self, n):
try:
@@ -158,8 +162,11 @@ class TurtleGraphics:
pass
self.heading %= 360
self.turn_turtle()
+ if self.tw.sharing():
+ self.tw.activity.send_event("r|%s" % \
+ (data_to_string([self.tw.nick, int(self.heading)])))
- def arc(self, a, r):
+ def arc(self, a, r, share=True):
self.gc.set_foreground(self.fgcolor)
r *= self.tw.coord_scale
try:
@@ -171,6 +178,9 @@ class TurtleGraphics:
pass
self.move_turtle()
self.turn_turtle()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("a|%s" % \
+ (data_to_string([self.tw.nick, [int(a),int(r)]])))
def rarc(self, a, r):
if r < 0:
@@ -236,7 +246,7 @@ class TurtleGraphics:
self.tw.svg_string += "\"\n"
self.tw.svg_string += self.svg.style()
- def setxy(self, x, y):
+ def setxy(self, x, y, share=True):
x *= self.tw.coord_scale
y *= self.tw.coord_scale
try:
@@ -244,8 +254,11 @@ class TurtleGraphics:
except:
pass
self.move_turtle()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("x|%s" % \
+ (data_to_string([self.tw.nick, [int(x), int(y)]])))
- def setpensize(self, ps):
+ def setpensize(self, ps, share=True):
try:
if ps < 0:
ps = 0
@@ -256,8 +269,11 @@ class TurtleGraphics:
self.gc.set_line_attributes(int(self.pensize*self.tw.coord_scale),
gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER)
self.svg.set_stroke_width(self.pensize)
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("w|%s" % \
+ (data_to_string([self.tw.nick, int(ps)])))
- def setcolor(self, c):
+ def setcolor(self, c, share=True):
try:
self.color = c
self.tcolor = c
@@ -266,6 +282,9 @@ class TurtleGraphics:
self.tw.active_turtle.set_color(c)
self.set_fgcolor()
self.set_textcolor()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("c|%s" % \
+ (data_to_string([self.tw.nick, int(c)])))
def settextcolor(self, c):
try:
@@ -280,7 +299,7 @@ class TurtleGraphics:
except:
pass
- def setshade(self, s):
+ def setshade(self, s, share=True):
try:
self.shade = s
except:
@@ -288,16 +307,21 @@ class TurtleGraphics:
self.tw.active_turtle.set_shade(s)
self.set_fgcolor()
self.set_textcolor()
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("s|%s" % \
+ (data_to_string([self.tw.nick, int(s)])))
def fillscreen(self, c, s):
oldc, olds = self.color, self.shade
- self.setcolor(c); self.setshade(s)
+ self.setcolor(c, False)
+ self.setshade(s, False)
rect = gtk.gdk.Rectangle(0, 0, self.width, self.height)
self.gc.set_foreground(self.fgcolor)
self.bgrgb = self.fgrgb[:]
self.canvas.images[0].draw_rectangle(self.gc, True, *rect)
self.invalt(0, 0, self.width, self.height)
- self.setcolor(oldc); self.setshade(olds)
+ self.setcolor(oldc, False)
+ self.setshade(olds, False)
self.tw.svg_string = ''
self.svg.reset_min_max()
@@ -319,8 +343,11 @@ class TurtleGraphics:
r, g, b = calc_shade(r, sh), calc_shade(g, sh), calc_shade(b, sh)
self.tw.textcolor = self.cm.alloc_color(r, g, b)
- def setpen(self, bool):
+ def setpen(self, bool, share=True):
self.pendown = bool
+ if self.tw.sharing() and share:
+ self.tw.activity.send_event("p|%s" % \
+ (data_to_string([self.tw.nick, bool])))
def draw_pixbuf(self, pixbuf, a, b, x, y, w, h, path):
w *= self.tw.coord_scale
@@ -390,25 +417,22 @@ class TurtleGraphics:
int(h))
self.tw.area.invalidate_rect(rect, False)
- def set_turtle(self, k):
+ def set_turtle(self, k, colors=None):
if not self.tw.turtles.dict.has_key(k):
# if it is a new turtle, start it in the center of the screen
- self.tw.active_turtle = self.tw.turtles.get_turtle(k, True)
- self.xcor = 0
- self.ycor = 0
- self.heading = 0
- self.move_turtle()
- self.turn_turtle()
+ self.tw.active_turtle = self.tw.turtles.get_turtle(k, True, colors)
+ self.seth(0, False)
+ self.setxy(0, 0, False)
self.tw.active_turtle.set_pen_state(True)
self.tw.active_turtle = self.tw.turtles.get_turtle(k, False)
tx, ty = self.tw.active_turtle.get_xy()
self.xcor = tx + 30 - self.width/2
self.ycor = self.height/2 - ty - 30
self.heading = self.tw.active_turtle.get_heading()
- self.setcolor(self.tw.active_turtle.get_color())
- self.setshade(self.tw.active_turtle.get_shade())
- self.setpensize(self.tw.active_turtle.get_pen_size())
- self.pendown = self.tw.active_turtle.get_pen_state()
+ self.setcolor(self.tw.active_turtle.get_color(), False)
+ self.setshade(self.tw.active_turtle.get_shade(), False)
+ self.setpensize(self.tw.active_turtle.get_pen_size(), False)
+ self.setpen(self.tw.active_turtle.get_pen_state(), False)
def svg_close(self):
if self.tw.svg_string == '':
diff --git a/taturtle.py b/taturtle.py
index 9c8fe26..b6fc6a9 100644
--- a/taturtle.py
+++ b/taturtle.py
@@ -43,14 +43,17 @@ class Turtles:
self.sprite_list = sprite_list
self.default_pixbufs = []
- def get_turtle(self, k, append=False):
+ def get_turtle(self, k, append=False, colors=None):
""" Find a turtle """
if self.dict.has_key(k):
return self.dict[k]
elif append is False:
return None
else:
- Turtle(self, k)
+ if colors == None:
+ Turtle(self, k)
+ else:
+ Turtle(self, k, colors.split(','))
return self.dict[k]
def get_turtle_key(self, turtle):
diff --git a/tawindow.py b/tawindow.py
index 7d46cf1..1c02feb 100644
--- a/tawindow.py
+++ b/tawindow.py
@@ -84,10 +84,12 @@ class TurtleArtWindow():
parent.show_all()
self.running_sugar = True
self.activity = parent
+ self.nick = profile.get_nick_name()
else:
self.window.show_all()
self.running_sugar = False
self.activity = None
+ self.nick = None
self._setup_events()
self.keypress = ""
self.keyvalue = 0
@@ -217,7 +219,7 @@ class TurtleArtWindow():
self.toolbar_shapes[_name].type = 'toolbar'
self.toolbar_shapes['stopiton'].hide()
- def _sharing(self):
+ def sharing(self):
""" Is a chattube available for sharing? """
if self.running_sugar and hasattr(self.activity, 'chattube') and\
self.activity.chattube is not None:
@@ -635,11 +637,6 @@ class TurtleArtWindow():
self.window.grab_focus()
x, y = xy(event)
self.button_press(event.get_state()&gtk.gdk.CONTROL_MASK, x, y)
- if self._sharing():
- if event.get_state()&gtk.gdk.CONTROL_MASK:
- self.activity.send_event("p:%d:%d:T" % (x, y))
- else:
- self.activity.send_event("p:%d:%d:F" % (x, y))
return True
def button_press(self, mask, x, y, verbose=False):
@@ -1206,21 +1203,9 @@ class TurtleArtWindow():
""" Button release """
x, y = xy(event)
self.button_release(x, y)
- if self._sharing():
- self.activity.send_event("r:" + str(x) + ":" + str(y))
return True
def button_release(self, x, y, verbose=False):
- if self.dx != 0 or self.dy != 0:
- if self._sharing():
- if verbose:
- print "processing move: %d %d" % (self.dx, self.dy)
- self.activity.send_event("m:%d:%d" % (self.dx, self.dy))
- self.dx = 0
- self.dy = 0
- if verbose:
- print "processing remote button release: %d, %d" % (x, y)
-
# We may have been moving the turtle
if self.selected_turtle is not None:
(tx, ty) = self.selected_turtle.get_xy()
@@ -1526,9 +1511,6 @@ class TurtleArtWindow():
alt_mask = False
alt_flag = 'F'
self._key_press(alt_mask, keyname, keyunicode)
- if keyname is not None and self._sharing():
- self.activity.send_event("k:%s:%s:%s" % (alt_flag, keyname,
- str(keyunicode)))
return keyname
def _key_press(self, alt_mask, keyname, keyunicode, verbose=False):
@@ -1541,10 +1523,7 @@ class TurtleArtWindow():
# First, process Alt keys.
if alt_mask and self.selected_blk is not None:
- if keyname == "i" and self._sharing():
- self.activity.waiting_for_blocks = True
- self.activity.send_event("i") # request sync for sharing
- elif keyname == "p":
+ if keyname == "p":
self.hideshow_button()
elif keyname == 'q':
exit()