From f2ea57b9402db5d66cf859e1e974e9127de18614 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Mon, 06 May 2013 21:54:52 +0000 Subject: first pass at adding macro save/load support --- diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py index 81eba2d..0d88a9d 100644 --- a/TurtleArt/tabasics.py +++ b/TurtleArt/tabasics.py @@ -107,6 +107,11 @@ class Palettes(): self._blocks_palette() + palette = make_palette('macros', + colors=["#FFC000", "#A08000"], + help_string=\ + _('Palette of user-defined operators')) + self._trash_palette() # Palette definitions diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index 906a7d8..14c0190 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -40,7 +40,9 @@ except ImportError: import os import subprocess +import errno +from random import uniform from math import atan2, pi DEGTOR = 2 * pi / 360 @@ -68,7 +70,7 @@ from tautils import (magnitude, get_load_name, get_save_name, data_from_file, calc_image_size, get_path, hide_button_hit, show_button_hit, chooser, arithmetic_check, xy, find_block_to_run, find_top_block, journal_check, find_group, find_blk_below, data_to_string, find_start_stack, - get_hardware, debug_output, error_output, convert, + get_hardware, debug_output, error_output, convert, find_hat, find_bot_block, restore_clamp, collapse_clamp, data_from_string, increment_name, get_screen_dpi) from tasprite_factory import (SVG, svg_str_to_pixbuf, svg_from_file) @@ -142,6 +144,8 @@ class TurtleArtWindow(): self.mouse_y = 0 self.update_counter = 0 self.running_blocks = False + self.saving_macro = False + self.macros_path = '' try: locale.setlocale(locale.LC_NUMERIC, '') @@ -1862,6 +1866,34 @@ before making changes to your Turtle Blocks program')) for blk in self.drag_group: if blk.status != 'collapsed': blk.spr.set_layer(TOP_LAYER) + if self.saving_macro: + for blk in self.drag_group: + if blk.status != 'collapsed': + blk.highlight() + self.block_operation = 'copying' + data = self.assemble_data_to_save(False, False) + i = find_hat(data) + if i is not None and data[i][4][1] is not None: + try: + name = str(data[data[i][4][1]][1][1]) + except: + name = 'macro%d' % (int(uniform(0, 10000))) + debug_output('saving macro %s' % (name), + self.running_sugar) + if not os.path.exists(self.macros_path): + try: + os.makedirs(self.macros_path) + except OSError, exc: + if exc.errno == errno.EEXIST: + pass + else: + raise + data_to_file(data, os.path.join(self.macros_path, + '%s.tb' % (name))) + self.parent.get_window().set_cursor( + gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) + self.saving_macro = False + if self.running_sugar and \ (self.activity.copying or self.activity.sharing_blocks): for blk in self.drag_group: diff --git a/icons/macrosoff.svg b/icons/macrosoff.svg new file mode 100644 index 0000000..7d9a28c --- /dev/null +++ b/icons/macrosoff.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/icons/macroson.svg b/icons/macroson.svg new file mode 100644 index 0000000..bb8852d --- /dev/null +++ b/icons/macroson.svg @@ -0,0 +1,70 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/turtleblocks.py b/turtleblocks.py index ed2ebce..d8b256c 100755 --- a/turtleblocks.py +++ b/turtleblocks.py @@ -30,6 +30,7 @@ import getopt import sys import os import os.path +import glob import cStringIO import errno import ConfigParser @@ -48,10 +49,12 @@ sys.argv[1:] = [] # Execution of import gst cannot see '--help' or '-h' import gettext from TurtleArt.taconstants import (OVERLAY_LAYER, DEFAULT_TURTLE_COLORS, - TAB_LAYER, SUFFIX) -from TurtleArt.tautils import (data_to_string, data_from_string, get_save_name) + TAB_LAYER, SUFFIX, MACROS) +from TurtleArt.tautils import (data_to_string, data_from_string, listify, + data_from_file, get_save_name, hat_on_top) from TurtleArt.tawindow import TurtleArtWindow from TurtleArt.taexportlogo import save_logo +from TurtleArt.tapalette import make_palette from util.menubuilder import MenuBuilder @@ -63,6 +66,7 @@ class TurtleMain(): '/usr/local/share/sugar/activities/TurtleArt.activity' _ICON_SUBPATH = 'images/turtle.png' _GNOME_PLUGIN_SUBPATH = 'gnome_plugins' + _MACROS_SUBPATH = 'macros' def __init__(self): self._abspath = os.path.abspath('.') @@ -105,6 +109,7 @@ class TurtleMain(): self._init_gnome_plugins() self._setup_gtk() self._build_window() + self._load_user_macros() self._run_gnome_plugins() self._start_gtk() @@ -166,6 +171,37 @@ class TurtleMain(): if not exists(dpath): makedirs(dpath) + def _load_user_macros(self): + ''' User-defined macros are saved as a json-encoded file; + these get loaded into a palette on startup ''' + macros_path = os.path.join(self._execdirname, self._MACROS_SUBPATH) + self.tw.macros_path = macros_path + if os.path.exists(macros_path): + files = glob.glob(os.path.join(macros_path, '*.tb')) + print 'creating macros palette' + if len(files) > 0: + palette = make_palette('macros', + colors=["#FFC000", "#A08000"], + help_string=\ +_('Palette of user-defined operators')) + + for tafile in files: + data = data_from_file(tafile) + name = os.path.basename(tafile)[:-3] + print 'loading macro %s' % (name) + MACROS['user-defined-' + name] = hat_on_top(listify(data)) + palette.add_block('user-defined-' + name, + style='basic-style-extended-vertical', + label=name) + + def _do_save_macro_cb(self, widget): + if self.saving_macro: + self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)) + self.tw.saving_macro = False + else: + self.win.get_window().set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1)) + self.tw.saving_macro = True + def _start_gtk(self): ''' Get a main window set up. ''' self.win.connect('configure_event', self.tw.update_overlay_position) @@ -216,6 +252,7 @@ class TurtleMain(): self.current_palette = 0 self.scale = 2.0 self.tw = None + self.saving_macro = False self.init_complete = False def _parse_command_line(self): @@ -385,6 +422,8 @@ class TurtleMain(): menu = gtk.Menu() MenuBuilder.make_menu_item(menu, _('Copy'), self._do_copy_cb) MenuBuilder.make_menu_item(menu, _('Paste'), self._do_paste_cb) + MenuBuilder.make_menu_item(menu, _('Save stack'), + self._do_save_macro_cb) edit_menu = MenuBuilder.make_sub_menu(menu, _('Edit')) menu = gtk.Menu() -- cgit v0.9.1