From e6f1790e6ac8a249330e534b1c62957d23908279 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Sat, 13 Feb 2010 01:21:31 +0000 Subject: skins scale properly --- diff --git a/sprites.py b/sprites.py index 752bb20..a361ba0 100644 --- a/sprites.py +++ b/sprites.py @@ -169,15 +169,10 @@ class Sprite: _h = self.images[i].get_height() else: _w, _h = self.images[i].get_size() - if len(self.images) == 1: - self._width = _w + self._dx[0] - self._height = _h + self._dy[0] + if i == 0: # Always reset width and height when base image changes. + self._width = _w + dx + self._height = _h + dy else: - if isinstance(self.images[i], gtk.gdk.Pixbuf): - _w = self.images[i].get_width() - _h = self.images[i].get_height() - else: - _w, _h = self.images[i].get_size() if _w + dx > self._width: self._width = _w + dx if _h + dy > self._height: diff --git a/tablock.py b/tablock.py index 30ecda8..e78b6ca 100644 --- a/tablock.py +++ b/tablock.py @@ -19,6 +19,7 @@ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN #THE SOFTWARE. +import gtk from taconstants import * from tasprite_factory import SVG, svg_str_to_pixbuf import sprites @@ -97,6 +98,7 @@ class Block: self.ey = 0 self._ei = 0 self._font_size = [6.0, 4.5] + self._image = None if OLD_NAMES.has_key(self.name): self.name = OLD_NAMES[self.name] @@ -131,6 +133,19 @@ class Block: self.dx = 0 self.refresh() + # Some blocks get a skin. + def set_image(self, image, x, y): + self._image = image + self.spr.set_image(image, 1, x, y) + + # The skin might need scaling. + # Keep the original here, the scaled version stays with the sprite. + def scale_image(self, x, y, w, h): + if self._image is not None: + tmp = self._image.scale_simple(w, h, + gtk.gdk.INTERP_NEAREST) + self.spr.set_image(tmp, 1, x, y) + # We may want to rescale blocks as well. def rescale(self, scale): for i in range(len(self._font_size)): @@ -241,15 +256,8 @@ class Block: self.resize() def _set_margins(self): - if self._left == 0: - self._left = self.svg.margins[0] - if self._top == 0: - self._top = self.svg.margins[1] - if self._right == 0: - self._right = self.svg.margins[2] - if self._bottom == 0: - self._bottom = self.svg.margins[3] - self.spr.set_margins(self._left, self._top, self._right, self._bottom) + self.spr.set_margins(self.svg.margins[0], self.svg.margins[1], + self.svg.margins[2], self.svg.margins[3]) def _set_label_attributes(self): if self.name in CONTENT_BLOCKS: diff --git a/taconstants.py b/taconstants.py index 03ebb50..a47909d 100644 --- a/taconstants.py +++ b/taconstants.py @@ -104,7 +104,7 @@ TOP_LAYER = 1000 # Block-palette categories # -PALETTE_NAMES = ['turtle', 'pen', 'colors', 'numbers', 'flow', 'blocks', +PALETTE_NAMES = ['turtle', 'pen', 'numbers', 'flow', 'blocks', 'extras', 'portfolio', 'trash'] PALETTES = [['clean', 'forward', 'back', 'show', 'left', 'right', @@ -113,8 +113,8 @@ PALETTES = [['clean', 'forward', 'back', 'show', 'left', 'right', 'bottompos'], ['penup','pendown', 'setpensize', 'fillscreen', 'pensize', 'settextsize', 'setcolor', 'setshade', 'textsize', 'color', - 'shade'], - [ 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple'], + 'shade', 'red', 'orange', 'yellow', 'green', 'cyan', 'blue', + 'purple'], ['plus2', 'minus2', 'product2', 'division2', 'identity2', 'remainder2', 'sqrt', 'random', 'number', 'greater2', 'less2', 'equal2', 'not', 'and2', 'or2'], @@ -124,8 +124,8 @@ PALETTES = [['clean', 'forward', 'back', 'show', 'left', 'right', 'storeinbox1', 'storeinbox2', 'string', 'box1', 'box2', 'box', 'storein', 'start'], ['kbinput', 'push', 'printheap', 'keyboard', 'pop', 'clearheap', - 'myfunc', 'nop', 'sandwichtop', 'sandwichbottom', - 'addturtle', 'print', 'comment', 'width', 'height'], + 'myfunc', 'nop', 'addturtle', 'comment', 'print', 'width', + 'height','sandwichtop', 'sandwichbottom'], ['journal', 'audio', 'description', 'savepix', 'hideblocks', 'showblocks', 'fullscreen', 'picturelist', 'picture1x1a', 'picture1x1', 'picture2x2', 'picture2x1', 'picture1x2'], @@ -135,7 +135,7 @@ PALETTES = [['clean', 'forward', 'back', 'show', 'left', 'right', # Block-style attributes # -COLORS = [["#00FF00","#00A000"], ["#00FFFF","#00A0A0"], ["#00FFFF","#00A0A0"], +COLORS = [["#00FF00","#00A000"], ["#00FFFF","#00A0A0"], ["#FF00FF","#A000A0"], ["#FFC000","#A08000"], ["#FFFF00","#A0A000"], ["#FF0000","#A00000"], ["#0000FF","#0000A0"], ["#FFFF00","#A0A000"]] @@ -383,6 +383,11 @@ OLD_DOCK = ['and', 'or', 'plus', 'minus', 'division', 'product', 'remainder'] CONTENT_BLOCKS = ['number', 'string', 'description', 'audio', 'journal'] # +# These blocks get a special skin +# +BLOCKS_WITH_SKIN = ['journal', 'audio', 'description', 'nop'] + +# # Block-name dictionary used for labels # BLOCK_NAMES = { diff --git a/tautils.py b/tautils.py index 4176a0b..d7cd903 100644 --- a/tautils.py +++ b/tautils.py @@ -173,3 +173,12 @@ def round_int(n): if int(float(nn)) == nn: return int(nn) return nn + +""" +Calculate the maximum size for placing an image onto a sprite. +""" +def calc_image_size(spr): + w = spr.label_safe_width() + h = spr.label_safe_height() + return w, h + diff --git a/tawindow.py b/tawindow.py index 8ddb748..69ea594 100644 --- a/tawindow.py +++ b/tawindow.py @@ -55,7 +55,7 @@ from taturtle import Turtles, Turtle from tautils import magnitude, get_load_name, get_save_name, data_from_file,\ data_to_file, round_int, get_id, get_pixbuf_from_journal,\ movie_media_type, audio_media_type, image_media_type,\ - save_picture + save_picture, calc_image_size from tasprite_factory import SVG, svg_str_to_pixbuf, svg_from_file from sprites import Sprites, Sprite @@ -272,7 +272,8 @@ class TurtleArtWindow(): for blk in self.just_blocks(): if blk.name == 'nop': x, y = self._calc_image_offset('pythonon', blk.spr) - blk.spr.set_image(self.media_shapes['pythonon'], 1, x, y) + blk.set_image(self.media_shapes['pythonon'], x, y) + self._resize_skin(blk) self.nop = 'pythonloaded' """ @@ -363,11 +364,14 @@ class TurtleArtWindow(): dy = bot.values[0] self._restore_stack(self._find_sandwich_top(b)) bot.values[0] = dy + + # Do the resizing. for b in self.just_blocks(): b.rescale(self.block_scale) for b in self.just_blocks(): self._adjust_dock_positions(b) - # We need to re-collapsed stacks after resizing. + + # Re-collapsed stacks after resizing. for b in self.just_blocks(): if self._collapsed(b): self._collapse_stack(self._find_sandwich_top(b)) @@ -375,6 +379,11 @@ class TurtleArtWindow(): if b.name == 'sandwichtop': self._grow_stack_arm(b) + # Resize the skins on some blocks: media content and Python + for b in self.just_blocks(): + if b.name in BLOCKS_WITH_SKIN: + self._resize_skin(b) + """ Show the toolbar palettes, creating them on init_only """ @@ -451,22 +460,22 @@ class TurtleArtWindow(): # Some blocks get a skin. if name in BOX_STYLE_MEDIA: x, y = self._calc_image_offset(name+'small', - self.palettes[n][i].spr) + self.palettes[n][i].spr) self.palettes[n][i].spr.set_image(self.media_shapes[ name+'small'], 1, x, y) elif name[:8] == 'template': x, y = self._calc_image_offset(name[8:], - self.palettes[n][i].spr) + self.palettes[n][i].spr) self.palettes[n][i].spr.set_image(self.media_shapes[ name[8:]], 1, x, y) elif name[:7] == 'picture': x, y = self._calc_image_offset(name[7:], - self.palettes[n][i].spr) + self.palettes[n][i].spr) self.palettes[n][i].spr.set_image(self.media_shapes[ name[7:]], 1, x, y) elif name == 'nop': x, y = self._calc_image_offset('pythonsmall', - self.palettes[n][i].spr) + self.palettes[n][i].spr) self.palettes[n][i].spr.set_image(self.media_shapes[ 'pythonsmall'], 1, x, y) @@ -732,6 +741,11 @@ class TurtleArtWindow(): if self._collapsed(b): self._collapse_stack(self._find_sandwich_top(b)) + # And resize any skins. + for b in group: + if b.name in BLOCKS_WITH_SKIN: + self._resize_skin(b) + self.show_palette(PALETTE_NAMES.index('trash')) """ @@ -760,11 +774,16 @@ class TurtleArtWindow(): b.type = 'block' for b in group: self._adjust_dock_positions(b) + # If the stack had been collapsed before going into the trash, + # collapse it again now. for b in group: if self._collapsed(b): - # If the stack had been collapsed before going into the trash, - # collapse it again now. self._collapse_stack(self._find_sandwich_top(b)) + # And resize any skins. + for b in group: + if b.name in BLOCKS_WITH_SKIN: + self._resize_skin(b) + self.trash_stack.remove(blk) """ @@ -828,14 +847,16 @@ class TurtleArtWindow(): if name == 'nop': if self.nop == 'pythonloaded': x, y = self._calc_image_offset('pythonon',newblk.spr) - newblk.spr.set_image(self.media_shapes['pythonon'], 1, x, y) + newblk.set_image(self.media_shapes['pythonon'], x, y) else: x, y = self._calc_image_offset('pythonoff',newblk.spr) - newblk.spr.set_image(self.media_shapes['pythonoff'], 1, x, y) + newblk.set_image(self.media_shapes['pythonoff'], x, y) + self._resize_skin(newblk) elif name in BOX_STYLE_MEDIA: x, y = self._calc_image_offset(name+'off',newblk.spr) - newblk.spr.set_image(self.media_shapes[name+'off'], 1, x, y) + newblk.set_image(self.media_shapes[name+'off'], x, y) newblk.spr.set_label(' ') + self._resize_skin(newblk) newspr = newblk.spr newspr.set_layer(TOP_LAYER) @@ -870,10 +891,12 @@ class TurtleArtWindow(): argdock = argblk.docks[0] nx, ny = sx+dock[2]-argdock[2], sy+dock[3]-argdock[3] if argname == 'journal': - x, y = self._calc_image_offset('journaloff',argblk.spr) - argblk.spr.set_image(self.media_shapes['journaloff'], - 1, x, y) + x, y = self._calc_image_offset('journaloff', + argblk.spr) + argblk.set_image(self.media_shapes['journaloff'], + x, y) argblk.spr.set_label(' ') + self._resize_skin(argblk) argblk.spr.move((nx, ny)) argblk.spr.set_layer(TOP_LAYER) argblk.connections = [newblk, None] @@ -1641,10 +1664,12 @@ class TurtleArtWindow(): self._load_image_thumb(name, blk) elif blk.name == 'audio': x, y = self._calc_image_offset('audioon', blk.spr) - blk.spr.set_image(self.media_shapes['audioon'], 1, x, y) + blk.set_image(self.media_shapes['audioon'], x, y) + self._resize_skin(blk) else: x, y = self._calc_image_offset('descriptionon', blk.spr) - blk.spr.set_image(self.media_shapes['descriptionon'], 1, x, y) + blk.set_image(self.media_shapes['descriptionon'], x, y) + self._resize_skin(blk) if value == '': value = name if len(blk.values)>0: @@ -1659,26 +1684,31 @@ class TurtleArtWindow(): def _load_image_thumb(self, picture, blk): pixbuf = None x, y = self._calc_image_offset('descriptionon', blk.spr) - blk.spr.set_image(self.media_shapes['descriptionon'], 1, x, y) + blk.set_image(self.media_shapes['descriptionon'], x, y) + self._resize_skin(blk) + if self.running_sugar: - w, h = self._calc_image_size(blk.spr) + w, h = calc_image_size(blk.spr) pixbuf = get_pixbuf_from_journal(picture, w, h) else: if movie_media_type(picture): x, y = self._calc_image_offset('journalon', blk.spr) - blk.spr.set_image(self.media_shapes['journalon'], 1, x, y) + blk.set_image(self.media_shapes['journalon'], x, y) + self._resize_skin(blk) elif audio_media_type(picture): x, y = self._calc_image_offset('audioon', blk.spr) - blk.spr.set_image(self.media_shapes['audioon'], 1, x, y) + blk.set_image(self.media_shapes['audioon'], x, y) + self._resize_skin(blk) blk.name = 'audio' elif image_media_type(picture): - w, h = self._calc_image_size(blk.spr) + w, h = calc_image_size(blk.spr) pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(picture, w, h) else: blk.name = 'description' if pixbuf is not None: x, y = self._calc_image_offset('', blk.spr) - blk.spr.set_image(pixbuf, 1, x, y) + blk.set_image(pixbuf, x, y) + self._resize_skin(blk) """ Disconnect block from stack above it. @@ -2117,10 +2147,12 @@ class TurtleArtWindow(): if btype == 'nop': if self.nop == 'pythonloaded': x, y = self._calc_image_offset('pythonon', blk.spr) - blk.spr.set_image(self.media_shapes['pythonon'], 1, x, y) + blk.set_image(self.media_shapes['pythonon'], x, y) + self._resize_skin(blk) else: x, y = self._calc_image_offset('pythonoff', blk.spr) - blk.spr.set_image(self.media_shapes['pythonoff'], 1, x, y) + blk.set_image(self.media_shapes['pythonoff'], x, y) + self._resize_skin(blk) blk.spr.set_label(' ') elif btype in EXPANDABLE: if btype == 'vspace': @@ -2135,50 +2167,57 @@ class TurtleArtWindow(): elif btype in BOX_STYLE_MEDIA and len(blk.values)>0: if blk.values[0] == 'None' or blk.values[0] == None: x, y = self._calc_image_offset(btype+'off', blk.spr) - blk.spr.set_image(self.media_shapes[btype+'off'], 1, x, y) + blk.set_image(self.media_shapes[btype+'off'], x, y) + self._resize_skin(blk) elif btype == 'audio' or btype == 'description': x, y = self._calc_image_offset(btype+'on', blk.spr) - blk.spr.set_image(self.media_shapes[btype+'on'], 1, x, y) + blk.set_image(self.media_shapes[btype+'on'], x, y) + self._resize_skin(blk) elif self.running_sugar: try: dsobject = datastore.get(blk.values[0]) if not movie_media_type(dsobject.file_path[-4:]): - w, h, = self._calc_image_size(blk.spr) + w, h, = calc_image_size(blk.spr) pixbuf = get_pixbuf_from_journal(dsobject, w, h) if pixbuf is not None: x, y = self._calc_image_offset('', blk.spr) - blk.spr.set_image(pixbuf, 1, x, y) + blk.set_image(pixbuf, x, y) else: - x, y = self._calc_image_offset('journalon', blk.spr) - blk.spr.set_image(self.media_shapes['journalon'], 1, - x, y) + x, y = self._calc_image_offset('journalon', + blk.spr) + blk.set_image(self.media_shapes['journalon'], x, y) + self._resize_skin(blk) dsobject.destroy() except: print "Warning: Couldn't open dsobject (%s)" %\ (blk.values[0]) x, y = self._calc_image_offset('journaloff', blk.spr) - blk.spr.set_image(self.media_shapes['journaloff'], 1, x, y) + blk.set_image(self.media_shapes['journaloff'], x, y) + self._resize_skin(blk) else: if not movie_media_type(blk.values[0][-4:]): try: - w, h, = self._calc_image_size(blk.spr) + w, h, = calc_image_size(blk.spr) pixbuf = gtk.gdk.pixbuf_new_from_file_at_size( blk.values[0], w, h) x, y = self._calc_image_offset('', blk.spr) - blk.spr.set_image(pixbuf, 1, x, y) + blk.set_image(pixbuf, x, y) except: x, y = self._calc_image_offset('journaloff', blk.spr) - blk.spr.set_image(self.media_shapes['journaloff'],1,x,y) + blk.set_image(self.media_shapes['journaloff'], x, y) + self._resize_skin(blk) else: x, y = self._calc_image_offset('journalon', blk.spr) - blk.spr.set_image(self.media_shapes['journalon'], 1, x, y) + blk.set_image(self.media_shapes['journalon'], x, y) + self._resize_skin(blk) blk.spr.set_label(' ') blk.resize() elif btype in BOX_STYLE_MEDIA: blk.spr.set_label(' ') x, y = self._calc_image_offset(btype+'off', blk.spr) - blk.spr.set_image(self.media_shapes[btype+'off'], 1, x, y) - + blk.set_image(self.media_shapes[btype+'off'], x, y) + self._resize_skin(blk) + blk.spr.set_layer(BLOCK_LAYER) if check_dock is True: blk.connections = 'check' @@ -2422,25 +2461,54 @@ class TurtleArtWindow(): """ Calculate the postion for placing an image onto a sprite. - TODO: Rescale images? - # if iw > w or ih > h: - # print "WARNING: need to recale image" """ def _calc_image_offset(self, name, spr, iw=0, ih=0): - l, t = spr.label_left_top() + _l, _t = spr.label_left_top() if name == '': - return (l, t) - w = spr.label_safe_width() - h = spr.label_safe_height() + return _l, _t + _w = spr.label_safe_width() + _h = spr.label_safe_height() if iw == 0: iw = self.media_shapes[name].get_width() ih = self.media_shapes[name].get_height() - return int(l+(w-iw)/2), int(t+(h-ih)/2) + return int(_l+(_w-iw)/2), int(_t+(_h-ih)/2) """ - Calculate the maximum size for placing an image onto a sprite. + Calculate new image size """ - def _calc_image_size(self, spr): - w = spr.label_safe_width() - h = spr.label_safe_height() - return (w, h) + def _calc_w_h(self, name, spr): + target_w = spr.label_safe_width() + target_h = spr.label_safe_height() + if name == '': + return target_w, target_h + image_w = self.media_shapes[name].get_width() + image_h = self.media_shapes[name].get_height() + if image_w > target_w or image_h > target_h: + scale_factor = float(target_w)/image_w + new_w = target_w + new_h = image_h*scale_factor + if new_h > target_h: + scale_factor = float(target_h)/new_h + new_h = target_h + new_w = target_w*scale_factor + return int(new_w), int(new_h) + return int(target_w), int(target_h) + + """ + Resize the 'skin' when block scale changes. + """ + def _resize_skin(self, b): + if b.name == 'nop': + w, h = self._calc_w_h('pythonoff', b.spr) + x, y = self._calc_image_offset('pythonoff', b.spr, w, h) + elif b.name == 'journal': + if len(b.values) == 1 and b.values[0] is not None: + w, h = self._calc_w_h('', b.spr) + x, y = self._calc_image_offset('journaloff', b.spr, w, h) + else: + w, h = self._calc_w_h('journaloff', b.spr) + x, y = self._calc_image_offset('journaloff', b.spr, w, h) + else: + w, h = self._calc_w_h('descriptionoff', b.spr) + x, y = self._calc_image_offset('descriptionoff', b.spr, w, h) + b.scale_image(x, y, w, h) -- cgit v0.9.1