Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArt/tawindow.py
diff options
context:
space:
mode:
Diffstat (limited to 'TurtleArt/tawindow.py')
-rw-r--r--TurtleArt/tawindow.py289
1 files changed, 153 insertions, 136 deletions
diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py
index 731260f..97c0124 100644
--- a/TurtleArt/tawindow.py
+++ b/TurtleArt/tawindow.py
@@ -101,11 +101,12 @@ class TurtleArtWindow():
def __init__(self, canvas_window, path, parent=None, activity=None,
mycolors=None, mynick=None, turtle_canvas=None,
- running_sugar=True):
- """parent -- the GTK Window that TA runs in
- activity -- the object that instantiated this TurtleArtWindow (in
+ running_sugar=True, running_turtleart=True):
+ '''parent -- the GTK Window that TA runs in
+ activity -- the object that instantiated this TurtleArtWindow (in
GNOME, a TurtleMain instance)
- """
+ running_turtleart -- are we running TA or exported python code?
+ '''
self.parent = parent
self.turtle_canvas = turtle_canvas
self._loaded_project = ''
@@ -115,6 +116,7 @@ class TurtleArtWindow():
self.gst_available = _GST_AVAILABLE
self.running_sugar = False
self.nick = None
+ self.running_turtleart = running_turtleart
if isinstance(canvas_window, gtk.DrawingArea):
self.interactive_mode = True
self.window = canvas_window
@@ -145,6 +147,7 @@ class TurtleArtWindow():
else:
self.activity = parent
+ # loading and saving
self.path = path
self.load_save_folder = os.path.join(path, 'samples')
self.py_load_save_folder = os.path.join(path, 'pysamples')
@@ -152,6 +155,8 @@ class TurtleArtWindow():
self.used_block_list = [] # Which blocks has the user used?
self.save_folder = None
self.save_file_name = None
+
+ # dimensions
self.width = gtk.gdk.screen_width()
self.height = gtk.gdk.screen_height()
self.rect = gtk.gdk.Rectangle(0, 0, 0, 0)
@@ -174,6 +179,7 @@ class TurtleArtWindow():
self.sharing_blocks = False
self.deleting_blocks = False
+ # find out which character to use as decimal point
try:
locale.setlocale(locale.LC_NUMERIC, '')
except locale.Error:
@@ -182,8 +188,8 @@ class TurtleArtWindow():
if self.decimal_point == '' or self.decimal_point is None:
self.decimal_point = '.'
+ # settings that depend on the hardware
self.orientation = HORIZONTAL_PALETTE
-
self.hw = get_hardware()
self.lead = 1.0
if self.hw in (XO1, XO15, XO175, XO4):
@@ -208,8 +214,9 @@ class TurtleArtWindow():
self.nop = 'nop'
self.loaded = 0
self.step_time = 0
- self.hide = False
- self.palette = True
+ # show/ hide palettes depending on whether we're running in TA or not
+ self.hide = not self.running_turtleart
+ self.palette = self.running_turtleart
self.coord_scale = 1
self.buddies = []
self._saved_string = ''
@@ -247,6 +254,7 @@ class TurtleArtWindow():
self.turtle_movement_to_share = None
self.paste_offset = 20 # Don't paste on top of where you copied.
+ # common properties of all blocks (font size, decimal point, ...)
self.block_list = Blocks(font_scale_factor=self.scale,
decimal_point=self.decimal_point)
if self.interactive_mode:
@@ -254,23 +262,24 @@ class TurtleArtWindow():
else:
self.sprite_list = None
+ # canvas object that supports the basic drawing functionality
self.canvas = TurtleGraphics(self, self.width, self.height)
if self.hw == XO175 and self.canvas.width == 1024:
self.hw = XO30
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.turtles, self.default_turtle_name)
+ Turtle(self.turtles, self.turtles.get_default_turtle_name())
else:
- Turtle(self.turtles, self.default_turtle_name, mycolors.split(','))
- self.active_turtle = self.turtles.get_turtle(self.default_turtle_name)
- self.active_turtle.show()
+ Turtle(self.turtles, self.turtles.get_default_turtle_name(),
+ mycolors.split(','))
+ 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)
@@ -284,8 +293,10 @@ class TurtleArtWindow():
self.saved_pictures = []
self.block_operation = ''
- from tabasics import Palettes
- self._basic_palettes = Palettes(self)
+ # only in TA: setup basic palettes
+ if self.running_turtleart:
+ from tabasics import Palettes
+ self._basic_palettes = Palettes(self)
if self.interactive_mode:
gobject.idle_add(self._lazy_init)
@@ -293,16 +304,12 @@ class TurtleArtWindow():
self._init_plugins()
self._setup_plugins()
- def _lazy_init(self, init_palettes=True, load_toolbar_shapes=True):
- """init_palettes -- whether to initialize the palettes (should always
- be True in TA)
- load_toolbar_shapes -- passed on to _setup_misc()
- """
+ def _lazy_init(self):
self._init_plugins()
self._setup_plugins()
- self._setup_misc(load_toolbar_shapes=load_toolbar_shapes)
+ self._setup_misc()
- if init_palettes:
+ if self.running_turtleart:
self._basic_palettes.make_trash_palette()
for name in palette_init_on_start:
debug_output('initing palette %s' % (name), self.running_sugar)
@@ -347,7 +354,7 @@ class TurtleArtWindow():
pname = os.path.join(path, dirname, dirname + '.py')
if os.path.exists(pname):
plugin_files.append(dirname)
- return plugin_files
+ return plugin_files
def _init_plugins(self):
''' Try importing plugin files from the plugin dir. '''
@@ -502,11 +509,8 @@ class TurtleArtWindow():
os.path.join(self.path, path, filename + '.svg')))
break
- def _setup_misc(self, load_toolbar_shapes=True):
- ''' Misc. sprites for status, overlays, etc.
- load_toolbar_shapes -- whether to load the toolbar shapes/ icons if
- we're not in sugar (should always be True in TA)
- '''
+ def _setup_misc(self):
+ ''' Misc. sprites for status, overlays, etc. '''
self.load_media_shapes()
for i, name in enumerate(STATUS_SHAPES):
# Temporary hack to use wider shapes
@@ -534,7 +538,7 @@ class TurtleArtWindow():
self.overlay_shapes[name].hide()
self.overlay_shapes[name].type = 'overlay'
- if load_toolbar_shapes and not self.running_sugar:
+ if self.running_turtleart and not self.running_sugar:
# offset = 2 * self.width - 55 * len(TOOLBAR_SHAPES)
offset = 55 * (1 + len(palette_blocks))
for i, name in enumerate(TOOLBAR_SHAPES):
@@ -705,15 +709,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 '''
@@ -743,7 +750,7 @@ class TurtleArtWindow():
self.metric = False
self.canvas.width = self.width
self.canvas.height = self.height
- self.canvas.move_turtle()
+ self.turtles.get_active_turtle().move_turtle()
def hideshow_button(self):
''' Hide/show button '''
@@ -1710,13 +1717,13 @@ 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.canvas.set_turtle(self.turtles.get_turtle_key(t))
+ self.selected_turtle = turtle
+ self.turtles.set_turtle(self.turtles.get_turtle_key(turtle))
self._turtle_pressed(x, y)
self.update_counter = 0
return True
@@ -2429,20 +2436,22 @@ before making changes to your Turtle Blocks program'))
self._adjust_dock_positions(c)
def _turtle_pressed(self, x, y):
- (tx, ty) = self.selected_turtle.get_xy()
- w = self.selected_turtle.spr.rect.width / 2
- h = self.selected_turtle.spr.rect.height / 2
- dx = x - tx - w
- dy = y - ty - h
- # if x, y is near the edge, rotate
+ pos = self.selected_turtle.get_xy()
+ tpos = self.turtles.turtle_to_screen_coordinates(pos)
+ dx = x - tpos[0]
+ dy = y - tpos[1]
if not hasattr(self.lc, 'value_blocks'):
self.lc.find_value_blocks()
self.lc.update_values = True
- if (dx * dx) + (dy * dy) > ((w * w) + (h * h)) / 6:
- self.drag_turtle = \
- ('turn', self.canvas.heading - atan2(dy, dx) / DEGTOR, 0)
+ # Compare distance squared of drag position to sprite radius.
+ # If x, y is near the edge, rotate.
+ if (dx * dx) + (dy * dy) > self.selected_turtle.get_drag_radius():
+ self.drag_turtle = (
+ 'turn',
+ self.selected_turtle.get_heading() - atan2(dy, dx) / DEGTOR,
+ 0)
else:
- self.drag_turtle = ('move', x - tx, y - ty)
+ self.drag_turtle = ('move', x - tpos[0], y - tpos[1])
def _move_cb(self, win, event):
x, y = xy(event)
@@ -2455,18 +2464,18 @@ 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)])))
- if self.canvas.pendown:
+ self.send_event("r|%s" % (data_to_string(
+ [nick,
+ round_int(self.turtles.get_active_turtle().get_heading())])))
+ if self.turtles.get_active_turtle().get_pen_state():
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)]])))
+ self.send_event("x|%s" % (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
@@ -2493,34 +2502,37 @@ before making changes to your Turtle Blocks program'))
# First, check to see if we are dragging or rotating a turtle.
if self.selected_turtle is not None:
- dtype, dragx, dragy = self.drag_turtle
- (sx, sy) = self.selected_turtle.get_xy()
- # self.canvas.set_turtle(self.selected_turtle.get_name())
+ drag_type, dragx, dragy = self.drag_turtle
self.update_counter += 1
- if dtype == 'move':
- dx = x - dragx - sx + self.selected_turtle.spr.rect.width / 2
- dy = y - dragy - sy + self.selected_turtle.spr.rect.height / 2
+ if drag_type == 'move':
+ dx = x - dragx
+ dy = y - dragy
self.selected_turtle.spr.set_layer(TOP_LAYER)
- tx, ty = self.canvas.screen_to_turtle_coordinates(sx + dx,
- sy + dy)
- if self.canvas.pendown:
- self.canvas.setpen(False)
- self.canvas.setxy(tx, ty, share=False)
- self.canvas.setpen(True)
+ pos = self.turtles.screen_to_turtle_coordinates((dx, dy))
+ if self.selected_turtle.get_pen_state():
+ self.selected_turtle.set_pen_state(False)
+ self.selected_turtle.set_xy(pos, share=False)
+ self.selected_turtle.set_pen_state(True)
else:
- self.canvas.setxy(tx, ty, share=False)
+ self.selected_turtle.set_xy(pos, share=False)
if self.update_counter % 5:
self.lc.update_label_value(
- 'xcor', self.canvas.xcor / self.coord_scale)
+ 'xcor', self.selected_turtle.get_xy()[0] /
+ self.coord_scale)
self.lc.update_label_value(
- 'ycor', self.canvas.ycor / self.coord_scale)
+ 'ycor', self.selected_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)
+ spos = self.turtles.turtle_to_screen_coordinates(
+ self.selected_turtle.get_xy())
+ dx = x - spos[0]
+ dy = y - spos[1]
+ 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.selected_turtle.get_heading())
if self.update_counter % 20:
self.display_coordinates()
self.turtle_movement_to_share = self.selected_turtle
@@ -2677,30 +2689,26 @@ before making changes to your Turtle Blocks program'))
# We may have been moving the turtle
if self.selected_turtle is not None:
- (tx, ty) = self.selected_turtle.get_xy()
- k = self.turtles.get_turtle_key(self.selected_turtle)
-
+ pos = self.selected_turtle.get_xy()
+ spos = self.turtles.turtle_to_screen_coordinates(pos)
+ turtle_name = self.turtles.get_turtle_key(self.selected_turtle)
# Remove turtles by dragging them onto the trash palette.
- if self._in_the_trash(tx, ty):
+ if self._in_the_trash(spos[0], spos[1]):
# If it is the default turtle, just recenter it.
- if k == self.default_turtle_name:
+ if turtle_name == 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.selected_turtle.set_heading(0)
+ self.lc.update_label_value('heading', 0)
else:
self.selected_turtle.hide()
- self.turtles.remove_from_dict(k)
- self.active_turtle = None
+ self.turtles.remove_from_dict(turtle_name)
+ 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.)
+ self._move_turtle(pos[0], pos[1])
+
self.selected_turtle = None
- if self.active_turtle is None:
- self.canvas.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
@@ -2776,21 +2784,23 @@ 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.canvas.move_turtle()
+ if self.drag_turtle[0] == 'move':
+ self.turtles.get_active_turtle().move_turtle((x, y))
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... '''
@@ -3545,13 +3555,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.canvas.move_turtle()
+ pos = self.turtles.get_active_turtle().get_xy()
+ x = pos[0] + dx
+ y = pos[1] + 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
@@ -3717,8 +3729,8 @@ 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()
- self._new_block('userdefined', tx, ty)
+ pos = self.turtles.get_active_turtle().get_xy()
+ self._new_block('userdefined', pos[0], pos[1])
self.myblock[self.block_list.list.index(self.drag_group[0])] =\
self.python_code
self.set_userdefined(self.drag_group[0])
@@ -3764,7 +3776,6 @@ before making changes to your Turtle Blocks program'))
if self.running_sugar:
chooser_dialog(self.parent, 'org.laptop.Pippy',
self.load_python_code_from_journal)
- dsobject.destroy()
else:
self.load_python_code_from_file(fname=None, add_new_block=False)
@@ -3844,12 +3855,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.canvas.set_turtle(key)
- self.canvas.setxy(xcor, ycor, pendown=False)
- self.canvas.seth(heading)
- self.canvas.setcolor(color)
- self.canvas.setshade(shade)
- self.canvas.setpensize(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 '''
@@ -3952,8 +3964,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
@@ -4117,9 +4129,10 @@ before making changes to your Turtle Blocks program'))
def load_start(self, ta_file=None):
''' Start a new project with a 'start' brick '''
if ta_file is None:
- self.process_data([[0, "start", PALETTE_WIDTH + 20,
- self.toolbar_offset + PALETTE_HEIGHT + 20,
- [None, None]]])
+ self.process_data(
+ [[0, "start", PALETTE_WIDTH + 20,
+ self.toolbar_offset + PALETTE_HEIGHT + 20 + ICON_SIZE,
+ [None, None]]])
else:
self.process_data(data_from_file(ta_file))
@@ -4186,8 +4199,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
@@ -4195,12 +4207,15 @@ before making changes to your Turtle Blocks program'))
# Save default turtle as 'Yertle'
if turtle == self.nick:
turtle = DEFAULT_TURTLE
+ pos = 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))
+ pos[0], pos[1],
+ 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):
@@ -4212,9 +4227,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'
@@ -4595,7 +4612,7 @@ variable'))
raise logoerror("#emptybox")
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: