From b8ea5b4e550eb115415a1f4544605d5c649e2496 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Sat, 08 Feb 2014 19:33:26 +0000 Subject: make PaletteView class to simplify palette management --- diff --git a/TurtleArt/tapaletteview.py b/TurtleArt/tapaletteview.py new file mode 100644 index 0000000..213ee17 --- /dev/null +++ b/TurtleArt/tapaletteview.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +#Copyright (c) 2014, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +_SKIN_IMAGE = 1 +_MARGIN = 5 +_BUTTON_SIZE = 32 + +from tautils import find_group, debug_output +from tablock import Block +from tapalette import (palette_names, palette_blocks, hidden_proto_blocks, + block_styles) +from taconstants import (PALETTE_SCALE, ICON_SIZE, PYTHON_SKIN, XO1, + HORIZONTAL_PALETTE, PALETTE_WIDTH, PALETTE_HEIGHT, + CATEGORY_LAYER, TOP_LAYER, PROTO_LAYER) +from tasprite_factory import SVG, svg_str_to_pixbuf +from sprites import Sprite + + +def _width_and_height(blk): + ''' What are the width and height of a stack? ''' + minx = 10000 + miny = 10000 + maxx = -10000 + maxy = -10000 + for gblk in find_group(blk): + (x, y) = gblk.spr.get_xy() + w, h = gblk.spr.get_dimensions() + if x < minx: + minx = x + if y < miny: + miny = y + if x + w > maxx: + maxx = x + w + if y + h > maxy: + maxy = y + h + return(maxx - minx, maxy - miny) + + +class PaletteView(): + ''' Palette View class abstraction ''' + + def __init__(self, turtle_window, n): + ''' + This class handles the display of block palettes + ''' + self.blocks = [] + self.backgrounds = [None, None] + + self._turtle_window = turtle_window + self._palette_index = n + self._visible = False + self._populated = False + + if not n < len(palette_names): + # Shouldn't happen, but hey... + debug_output('palette index %d is out of range' % n, + self._turtle_window.running_sugar) + self._name = 'undefined' + else: + self._name = palette_names[n] + + def create(self, regenerate=True, show=False): + if not self._name == 'undefined': + # Create proto blocks for each palette entry + self._create_proto_blocks() + + save_selected = self._turtle_window.selected_palette + self.layout_palette(regenerate=regenerate, + show=(show or + save_selected == self._palette_index)) + + def show(self): + ''' Show palette background and proto blocks. If needed, display + shift button. ''' + orientation = self._turtle_window.orientation + if self.backgrounds[orientation] is not None: + self.backgrounds[orientation].set_layer(CATEGORY_LAYER) + + for blk in self.blocks: + if blk.get_visibility(): + blk.spr.set_layer(PROTO_LAYER) + else: + blk.spr.hide() + + self.display_palette_shift_buttons() + + def hide(self): + ''' Hide the palette. ''' + for background in self.backgrounds: + if background is not None: + background.hide() + + for blk in self.blocks: + blk.spr.hide() + + self._hide_palette_shift_buttons() + + if self._trash_palette(): + for blk in self._turtle_window.trash_stack: + for gblk in find_group(blk): + gblk.spr.hide() + + def move(self, x, y): + ''' Move the palette. ''' + buttons = self._turtle_window.palette_button + + for blk in self.blocks: + blk.spr.move((x + blk.spr.save_xy[0], y + blk.spr.save_xy[1])) + + for button in buttons: + button.move((x + button.save_xy[0], y + button.save_xy[1])) + + for spr in self.backgrounds: + if spr is not None: + spr.move((x + spr.save_xy[0], y + spr.save_xy[1])) + + if self._trash_palette(): + for blk in self._turtle_window.trash_stack: + for gblk in find_group(blk): + gblk.spr.move((x + gblk.spr.save_xy[0], + y + gblk.spr.save_xy[1])) + + def shift(self): + ''' Shift blocks on the palette. ''' + buttons = self._turtle_window.palette_button + orientation = self._turtle_window.orientation + + x, y = self.backgrounds[orientation].get_xy() + w, h = self.backgrounds[orientation].get_dimensions() + bx, by = self.blocks[0].spr.get_xy() + if orientation == 0: + width = self._turtle_window.width + + if bx != _BUTTON_SIZE: + dx = w - width + else: + dx = width - w + dy = 0 + else: + height = self._turtle_window.height + offset = self._turtle_window.toolbar_offset + + dx = 0 + if by != offset + _BUTTON_SIZE + _MARGIN: + dy = h - height + ICON_SIZE + else: + dy = height - h - ICON_SIZE + + for blk in self.blocks: + if blk.get_visibility(): + blk.spr.move_relative((dx, dy)) + + buttons[orientation].set_layer(TOP_LAYER) + if dx < 0 or dy < 0: + buttons[orientation + 5].set_layer(TOP_LAYER) + buttons[orientation + 3].hide() + else: + buttons[orientation + 5].hide() + buttons[orientation + 3].set_layer(TOP_LAYER) + + def _create_proto_blocks(self): + ''' + Create the proto blocks that will populate this palette. + Reload the palette, but reuse the existing blocks. + If a block doesn't exist, add it. + ''' + for blk in self.blocks: + blk.spr.hide() + + preexisting_blocks = self.blocks[:] + self.blocks = [] + for name in palette_blocks[self._palette_index]: + # Did we already create this block? + preexisting_block = False + for blk in preexisting_blocks: + if blk.name == name: + self.blocks.append(blk) + preexisting_block = True + break + + # If not, create it now. + if not preexisting_block: + self.blocks.append(Block(self._turtle_window.block_list, + self._turtle_window.sprite_list, + name, 0, 0, 'proto', [], + PALETTE_SCALE)) + if name in hidden_proto_blocks: + self.blocks[-1].set_visibility(False) + else: + self.blocks[-1].spr.set_layer(PROTO_LAYER) + self.blocks[-1].unhighlight() + self.blocks[-1].resize() + + # Some proto blocks get a skin. + if name in block_styles['box-style-media']: + self._proto_skin(name + 'small', self.blocks[-1].spr) + elif name in PYTHON_SKIN: + self._proto_skin('pythonsmall', self.blocks[-1].spr) + elif len(self.blocks[-1].spr.labels) > 0: + self.blocks[-1].refresh() + + def _proto_skin(self, name, spr): + ''' Utility for creating proto block skins ''' + x, y = self._turtle_window._calc_image_offset(name, spr) + spr.set_image(self._turtle_window.media_shapes[name], _SKIN_IMAGE, + x, y) + + def _float_palette(self, spr): + ''' We sometimes let the palette move with the canvas. ''' + if self._turtle_window.running_sugar and \ + not self._turtle_window.hw in [XO1]: + spr.move_relative( + (self._turtle_window.activity.hadj_value, + self._turtle_window.activity.vadj_value)) + + def _trash_palette(self): + return 'trash' in palette_names and \ + self._palette_index == palette_names.index('trash') + + def layout_palette(self, regenerate=False, show=True): + ''' Layout prototypes in a palette. ''' + + offset = self._turtle_window.toolbar_offset + buttons = self._turtle_window.palette_button + orientation = self._turtle_window.orientation + w = PALETTE_WIDTH + h = PALETTE_HEIGHT + + if orientation == HORIZONTAL_PALETTE: + x, y, max_w = self._horizontal_layout( + _BUTTON_SIZE, offset + _MARGIN, self.blocks) + if self._trash_palette(): + blocks = [] # self.blocks[:] + for blk in self._turtle_window.trash_stack: + blocks.append(blk) + x, y, max_w = self._horizontal_layout(x + max_w, y, blocks) + w = x + max_w + _BUTTON_SIZE + _MARGIN + if show: + buttons[2].move((w - _BUTTON_SIZE, offset)) + buttons[4].move((_BUTTON_SIZE, offset)) + buttons[6].move((_BUTTON_SIZE, offset)) + else: + x, y, max_h = self._vertical_layout( + _MARGIN, offset + _BUTTON_SIZE + _MARGIN, self.blocks) + if self._trash_palette(): + blocks = [] # self.blocks[:] + for blk in self._turtle_window.trash_stack: + blocks.append(blk) + x, y, max_h = self._vertical_layout(x, y + max_h, blocks) + h = y + max_h + _BUTTON_SIZE + _MARGIN - offset + if show: + buttons[2].move((PALETTE_WIDTH - _BUTTON_SIZE, offset)) + buttons[3].move((0, offset + _BUTTON_SIZE)) + buttons[5].move((0, offset + _BUTTON_SIZE)) + + self._make_background(0, offset, w, h, regenerate) + + if show: + for blk in self.blocks: + if blk.get_visibility(): + blk.spr.set_layer(PROTO_LAYER) + else: + blk.spr.hide() + + buttons[2].save_xy = buttons[2].get_xy() + self._float_palette(buttons[2]) + self.backgrounds[orientation].set_layer(CATEGORY_LAYER) + self.display_palette_shift_buttons() + + if self._trash_palette(): + for blk in self._turtle_window.trash_stack: + for gblk in find_group(blk): + gblk.spr.set_layer(PROTO_LAYER) + + svg = SVG() + self.backgrounds[orientation].set_shape( + svg_str_to_pixbuf(svg.palette(w, h))) + + def _make_background(self, x, y, w, h, regenerate=False): + ''' Make the background sprite for the palette. ''' + orientation = self._turtle_window.orientation + + if regenerate and not self.backgrounds[orientation] is None: + self.backgrounds[orientation].hide() + self.backgrounds[orientation] = None + + if self.backgrounds[orientation] is None: + svg = SVG() + self.backgrounds[orientation] = \ + Sprite(self._turtle_window.sprite_list, x, y, + svg_str_to_pixbuf(svg.palette(w, h))) + self.backgrounds[orientation].save_xy = (x, y) + + self._float_palette(self.backgrounds[orientation]) + + if orientation == 0 and w > self._turtle_window.width: + self.backgrounds[orientation].type = \ + 'category-shift-horizontal' + elif orientation == 1 and \ + h > self._turtle_window.height - ICON_SIZE: + self.backgrounds[orientation].type = \ + 'category-shift-vertical' + else: + self.backgrounds[orientation].type = 'category' + + ''' + if self._trash_palette(): + svg = SVG() + self.backgrounds[orientation].set_shape( + svg_str_to_pixbuf(svg.palette(w, h))) + ''' + + def _horizontal_layout(self, x, y, blocks): + ''' Position prototypes in a horizontal palette. ''' + offset = self._turtle_window.toolbar_offset + max_w = 0 + + for blk in blocks: + if not blk.get_visibility(): + continue + + w, h = _width_and_height(blk) + if y + h > PALETTE_HEIGHT + offset: + x += int(max_w + 3) + y = offset + 3 + max_w = 0 + + (bx, by) = blk.spr.get_xy() + dx = x - bx + dy = y - by + for g in find_group(blk): + g.spr.move_relative((int(dx), int(dy))) + g.spr.save_xy = g.spr.get_xy() + self._float_palette(g.spr) + y += int(h + 3) + if w > max_w: + max_w = w + + return x, y, max_w + + def _vertical_layout(self, x, y, blocks): + ''' Position prototypes in a vertical palette. ''' + row = [] + row_w = 0 + max_h = 0 + + for blk in blocks: + if not blk.get_visibility(): + continue + + w, h = _width_and_height(blk) + if x + w > PALETTE_WIDTH: + # Recenter row. + dx = int((PALETTE_WIDTH - row_w) / 2) + for r in row: + for g in find_group(r): + g.spr.move_relative((dx, 0)) + g.spr.save_xy = (g.spr.save_xy[0] + dx, + g.spr.save_xy[1]) + row = [] + row_w = 0 + x = 4 + y += int(max_h + 3) + max_h = 0 + + row.append(blk) + row_w += (4 + w) + + (bx, by) = blk.spr.get_xy() + dx = int(x - bx) + dy = int(y - by) + for g in find_group(blk): + g.spr.move_relative((dx, dy)) + g.spr.save_xy = g.spr.get_xy() + self._float_palette(g.spr) + + x += int(w + 4) + if h > max_h: + max_h = h + + # Recenter last row. + dx = int((PALETTE_WIDTH - row_w) / 2) + for r in row: + for g in find_group(r): + g.spr.move_relative((dx, 0)) + g.spr.save_xy = (g.spr.save_xy[0] + dx, g.spr.save_xy[1]) + + return x, y, max_h + + def _hide_palette_shift_buttons(self): + buttons = self._turtle_window.palette_button + for i in range(4): + buttons[i + 3].hide() + + def display_palette_shift_buttons(self): + ''' Palettes too wide (or tall) for the screen get a shift button. ''' + self._hide_palette_shift_buttons() + + buttons = self._turtle_window.palette_button + orientation = self._turtle_window.orientation + + if self.backgrounds[orientation].type == 'category-shift-horizontal': + buttons[3].set_layer(CATEGORY_LAYER) + elif self.backgrounds[orientation].type == 'category-shift-vertical': + buttons[4].set_layer(CATEGORY_LAYER) diff --git a/TurtleArt/tawindow.py b/TurtleArt/tawindow.py index f92d9d7..dcc4b18 100644 --- a/TurtleArt/tawindow.py +++ b/TurtleArt/tawindow.py @@ -52,20 +52,19 @@ from taconstants import (HORIZONTAL_PALETTE, VERTICAL_PALETTE, BLOCK_SCALE, MEDIA_SHAPES, STATUS_SHAPES, OVERLAY_SHAPES, TOOLBAR_SHAPES, TAB_LAYER, RETURN, OVERLAY_LAYER, CATEGORY_LAYER, BLOCKS_WITH_SKIN, ICON_SIZE, - PALETTE_SCALE, PALETTE_WIDTH, SKIN_PATHS, MACROS, + PALETTE_WIDTH, SKIN_PATHS, MACROS, Color, KEY_DICT, TOP_LAYER, BLOCK_LAYER, OLD_NAMES, DEFAULT_TURTLE, TURTLE_LAYER, EXPANDABLE, NO_IMPORT, TEMPLATES, PYTHON_SKIN, PALETTE_HEIGHT, STATUS_LAYER, OLD_DOCK, EXPANDABLE_ARGS, XO1, XO15, XO175, XO30, XO4, TITLEXY, CONTENT_ARGS, CONSTANTS, EXPAND_SKIN, PROTO_LAYER, - EXPANDABLE_FLOW, SUFFIX, TMP_SVG_PATH, TMP_ODP_PATH, - Color, KEY_DICT) + EXPANDABLE_FLOW, SUFFIX, TMP_SVG_PATH, TMP_ODP_PATH) from tapalette import (palette_names, palette_blocks, expandable_blocks, block_names, content_blocks, default_values, special_names, block_styles, help_strings, - hidden_proto_blocks, string_or_number_args, - make_palette, palette_name_to_index, - palette_init_on_start, palette_i18n_names) + string_or_number_args, make_palette, + palette_name_to_index, palette_init_on_start, + palette_i18n_names) from talogo import (LogoCode, logoerror) from tacanvas import TurtleGraphics from tablock import (Blocks, Block, Media, media_blocks_dictionary) @@ -83,6 +82,7 @@ from tautils import (magnitude, get_load_name, get_save_name, data_from_file, increment_name, get_screen_dpi) from tasprite_factory import (SVG, svg_str_to_pixbuf, svg_from_file) from tapalette import block_primitives +from tapaletteview import PaletteView from sprites import (Sprites, Sprite) if _GST_AVAILABLE: @@ -243,9 +243,8 @@ class TurtleArtWindow(): self.status_spr = None self.status_shapes = {} self.toolbar_spr = None - self.palette_sprs = [] - self.palettes = [] self.palette_button = [] + self.palette_views = [] self.trash_stack = [] self.selected_palette = None self.previous_palette = None @@ -907,7 +906,7 @@ class TurtleArtWindow(): self.show_toolbar_palette(n) self.palette_button[self.orientation].set_layer(TAB_LAYER) self.palette_button[2].set_layer(TAB_LAYER) - self._display_palette_shift_button(n) + self.palette_views[n].display_palette_shift_buttons() if not self.running_sugar or not self.activity.has_toolbarbox: self.toolbar_spr.set_layer(CATEGORY_LAYER) self.palette = True @@ -924,26 +923,12 @@ class TurtleArtWindow(): def move_palettes(self, x, y): ''' Move the palettes. ''' - for p in self.palettes: - for blk in p: - blk.spr.move((x + blk.spr.save_xy[0], y + blk.spr.save_xy[1])) - for spr in self.palette_button: - spr.move((x + spr.save_xy[0], y + spr.save_xy[1])) - for p in self.palette_sprs: - if p[0] is not None: - p[0].move((x + p[0].save_xy[0], y + p[0].save_xy[1])) - if p[1] is not None: - p[1].move((x + p[1].save_xy[0], y + p[1].save_xy[1])) + for palette in self.palette_views: + palette.move(x, y) self.status_spr.move((x + self.status_spr.save_xy[0], y + self.status_spr.save_xy[1])) - # To do: set save_xy for blocks in Trash - for blk in self.trash_stack: - for gblk in find_group(blk): - gblk.spr.move((x + gblk.spr.save_xy[0], - y + gblk.spr.save_xy[1])) - def hideblocks(self): ''' Callback from 'hide blocks' block ''' if not self.interactive_mode: @@ -985,34 +970,6 @@ class TurtleArtWindow(): int(blocks[0].font_size[0] * pango.SCALE * self.entry_scale)) self._text_entry.modify_font(font_desc) - def _shift_toolbar_palette(self, n): - ''' Shift blocks on specified palette ''' - x, y = self.palette_sprs[n][self.orientation].get_xy() - w, h = self.palette_sprs[n][self.orientation].get_dimensions() - bx, by = self.palettes[n][0].spr.get_xy() - if self.orientation == 0: - if bx != _BUTTON_SIZE: - dx = w - self.width - else: - dx = self.width - w - dy = 0 - else: - dx = 0 - if by != self.toolbar_offset + _BUTTON_SIZE + _MARGIN: - dy = h - self.height + ICON_SIZE - else: - dy = self.height - h - ICON_SIZE - for blk in self.palettes[n]: - if blk.get_visibility(): - blk.spr.move_relative((dx, dy)) - self.palette_button[self.orientation].set_layer(TOP_LAYER) - if dx < 0 or dy < 0: - self.palette_button[self.orientation + 5].set_layer(TOP_LAYER) - self.palette_button[self.orientation + 3].hide() - else: - self.palette_button[self.orientation + 5].hide() - self.palette_button[self.orientation + 3].set_layer(TOP_LAYER) - def show_toolbar_palette(self, n, init_only=False, regenerate=False, show=True): ''' Show the toolbar palettes, creating them on init_only ''' @@ -1024,7 +981,7 @@ class TurtleArtWindow(): self._create_the_selectors() # Create the empty palettes that we'll then populate with prototypes. - if self.palette_sprs == []: + if self.palette_views == []: self._create_the_empty_palettes() # At initialization of the program, we don't actually populate @@ -1052,34 +1009,12 @@ class TurtleArtWindow(): self.selectors[i].set_layer(TAB_LAYER) # Show the palette with the current orientation. - if self.palette_sprs[n][self.orientation] is not None: - self.palette_sprs[n][self.orientation].set_layer( + if self.palette_views[n].backgrounds[self.orientation] is not None: + self.palette_views[n].backgrounds[self.orientation].set_layer( CATEGORY_LAYER) - self._display_palette_shift_button(n) - - # Create 'proto' blocks for each palette entry - self._create_proto_blocks(n) + self.palette_views[n].display_palette_shift_buttons() - if show or save_selected == n: - self._layout_palette(n, regenerate=regenerate) - else: - self._layout_palette(n, regenerate=regenerate, show=False) - for blk in self.palettes[n]: - if blk.get_visibility(): - if hasattr(blk.spr, 'set_layer'): - blk.spr.set_layer(PROTO_LAYER) - else: - debug_output('WARNING: block sprite is None' % (blk.name), - self.running_sugar) - else: - blk.spr.hide() - if 'trash' in palette_names and \ - n == palette_names.index('trash'): - for blk in self.trash_stack: - # Deprecated - for gblk in find_group(blk): - if gblk.status != 'collapsed': - gblk.spr.set_layer(TAB_LAYER) + self.palette_views[n].create(regenerate=regenerate, show=show) if not show: if not save_selected == n: @@ -1092,7 +1027,7 @@ class TurtleArtWindow(): if (not self.running_sugar or not self.activity.has_toolbarbox) and \ self.selectors == []: return - if self.palette_sprs == []: + if self.palette_views == []: return save_selected = self.selected_palette @@ -1100,37 +1035,14 @@ class TurtleArtWindow(): self.selected_palette = n self.previous_palette = self.selected_palette - if save_selected == n: - self._layout_palette(n, regenerate=True) - else: - self._layout_palette(n, regenerate=True, show=False) - - for blk in self.palettes[n]: - if blk.get_visibility(): - if hasattr(blk.spr, 'set_layer'): - blk.spr.set_layer(PROTO_LAYER) - else: - debug_output('WARNING: block sprite is None' % (blk.name), - self.running_sugar) - else: - blk.spr.hide() + self.palette_views[n].layout_palette(regenerate=True, + show=(save_selected == n)) if not save_selected == n: self._hide_previous_palette(palette=n) self.selected_palette = save_selected self.previous_palette = save_previous - def _display_palette_shift_button(self, n): - ''' Palettes too wide (or tall) for the screen get a shift button ''' - for i in range(4): - self.palette_button[i + 3].hide() - if self.palette_sprs[n][self.orientation].type == \ - 'category-shift-horizontal': - self.palette_button[3].set_layer(CATEGORY_LAYER) - elif self.palette_sprs[n][self.orientation].type == \ - 'category-shift-vertical': - self.palette_button[4].set_layer(CATEGORY_LAYER) - def _create_the_selectors(self): ''' Create the palette selector buttons: only when running old-style Sugar toolbars or from GNOME ''' @@ -1185,13 +1097,8 @@ class TurtleArtWindow(): def _create_the_empty_palettes(self): ''' Create the empty palettes to be populated by prototype blocks. ''' - if len(self.palettes) == 0: - for i in range(len(palette_blocks)): - self.palettes.append([]) - - # Create empty palette backgrounds - for i in palette_names: - self.palette_sprs.append([None, None]) + for i in range(len(palette_names)): + self.palette_views.append(PaletteView(self, i)) # Create the palette orientation button self.palette_button.append( @@ -1268,57 +1175,6 @@ class TurtleArtWindow(): self.palette_button[3 + i].type = 'palette' self.palette_button[3 + i].hide() - def _create_proto_blocks(self, n): - ''' Create the protoblocks that will populate a palette. ''' - # Reload the palette, but reuse the existing blocks - # If a block doesn't exist, add it - - if not n < len(self.palettes): - debug_output( - '_create_proto_blocks: palette index %d is out of range' % - (n), self.running_sugar) - return - - for blk in self.palettes[n]: - blk.spr.hide() - old_blocks = self.palettes[n][:] - self.palettes[n] = [] - for name in palette_blocks[n]: - found_block = False - for oblk in old_blocks: - if oblk.name == name: - self.palettes[n].append(oblk) - found_block = True - break - if not found_block: - self.palettes[n].append( - Block(self.block_list, self.sprite_list, name, 0, 0, - 'proto', [], PALETTE_SCALE)) - if name in hidden_proto_blocks: - self.palettes[n][-1].set_visibility(False) - else: - if hasattr(self.palettes[n][-1].spr, 'set_layer'): - self.palettes[n][-1].spr.set_layer(PROTO_LAYER) - self.palettes[n][-1].unhighlight() - self.palettes[n][-1].resize() - else: - debug_output('WARNING: block sprite is None' % - (self.palettes[n][-1].name), - self.running_sugar) - - # Some proto blocks get a skin. - if name in block_styles['box-style-media']: - self._proto_skin(name + 'small', n, -1) - elif name[:8] == 'template': # Deprecated - self._proto_skin(name[8:], n, -1) - elif name[:7] == 'picture': # Deprecated - self._proto_skin(name[7:], n, -1) - elif name in PYTHON_SKIN: - self._proto_skin('pythonsmall', n, -1) - if len(self.palettes[n][-1].spr.labels) > 0: - self.palettes[n][-1].refresh() - return - def _hide_toolbar_palette(self): ''' Hide the toolbar palettes ''' self._hide_previous_palette() @@ -1337,15 +1193,7 @@ class TurtleArtWindow(): palette = self.previous_palette # Hide previously selected palette if palette is not None: - if not palette < len(self.palettes): - debug_output( - '_hide_previous_palette: index %d is out of range' % - (palette), self.running_sugar) - return - for proto in self.palettes[palette]: - proto.spr.hide() - if self.palette_sprs[palette][self.orientation] is not None: - self.palette_sprs[palette][self.orientation].hide() + self.palette_views[palette].hide() if not self.running_sugar or not self.activity.has_toolbarbox: self.selectors[palette].set_shape( self.selector_shapes[palette][0]) @@ -1353,155 +1201,6 @@ class TurtleArtWindow(): and not self.activity.has_toolbarbox: self.activity.palette_buttons[palette].set_icon( palette_names[palette] + 'off') - if 'trash' in palette_names and \ - palette == palette_names.index('trash'): - for blk in self.trash_stack: - for gblk in find_group(blk): - gblk.spr.hide() - - def _horizontal_layout(self, x, y, blocks): - ''' Position prototypes in a horizontal palette. ''' - max_w = 0 - for blk in blocks: - if not blk.get_visibility(): - continue - w, h = self._width_and_height(blk) - if y + h > PALETTE_HEIGHT + self.toolbar_offset: - x += int(max_w + 3) - y = self.toolbar_offset + 3 - max_w = 0 - (bx, by) = blk.spr.get_xy() - dx = x - bx - dy = y - by - for g in find_group(blk): - g.spr.move_relative((int(dx), int(dy))) - g.spr.save_xy = g.spr.get_xy() - if self.running_sugar and not self.hw in [XO1]: - g.spr.move_relative((self.activity.hadj_value, - self.activity.vadj_value)) - y += int(h + 3) - if w > max_w: - max_w = w - return x, y, max_w - - def _vertical_layout(self, x, y, blocks): - ''' Position prototypes in a vertical palette. ''' - row = [] - row_w = 0 - max_h = 0 - for blk in blocks: - if not blk.get_visibility(): - continue - w, h = self._width_and_height(blk) - if x + w > PALETTE_WIDTH: - # Recenter row. - dx = int((PALETTE_WIDTH - row_w) / 2) - for r in row: - for g in find_group(r): - g.spr.move_relative((dx, 0)) - g.spr.save_xy = (g.spr.save_xy[0] + dx, - g.spr.save_xy[1]) - row = [] - row_w = 0 - x = 4 - y += int(max_h + 3) - max_h = 0 - row.append(blk) - row_w += (4 + w) - (bx, by) = blk.spr.get_xy() - dx = int(x - bx) - dy = int(y - by) - for g in find_group(blk): - g.spr.move_relative((dx, dy)) - g.spr.save_xy = g.spr.get_xy() - if self.running_sugar and not self.hw in [XO1]: - g.spr.move_relative((self.activity.hadj_value, - self.activity.vadj_value)) - x += int(w + 4) - if h > max_h: - max_h = h - # Recenter last row. - dx = int((PALETTE_WIDTH - row_w) / 2) - for r in row: - for g in find_group(r): - g.spr.move_relative((dx, 0)) - g.spr.save_xy = (g.spr.save_xy[0] + dx, g.spr.save_xy[1]) - return x, y, max_h - - def _layout_palette(self, n, regenerate=False, show=True): - ''' Layout prototypes in a palette. ''' - if n is not None: - if self.orientation == HORIZONTAL_PALETTE: - x, y = _BUTTON_SIZE, self.toolbar_offset + _MARGIN - x, y, max_w = self._horizontal_layout(x, y, self.palettes[n]) - if 'trash' in palette_names and \ - n == palette_names.index('trash'): - x, y, max_w = self._horizontal_layout(x + max_w, y, - self.trash_stack) - w = x + max_w + _BUTTON_SIZE + _MARGIN - self._make_palette_spr(n, 0, self.toolbar_offset, - w, PALETTE_HEIGHT, regenerate) - if show: - self.palette_button[2].move( - (w - _BUTTON_SIZE, self.toolbar_offset)) - self.palette_button[4].move( - (_BUTTON_SIZE, self.toolbar_offset)) - self.palette_button[6].move( - (_BUTTON_SIZE, self.toolbar_offset)) - else: - x, y = _MARGIN, self.toolbar_offset + _BUTTON_SIZE + _MARGIN - x, y, max_h = self._vertical_layout(x, y, self.palettes[n]) - if 'trash' in palette_names and \ - n == palette_names.index('trash'): - x, y, max_h = self._vertical_layout(x, y + max_h, - self.trash_stack) - h = y + max_h + _BUTTON_SIZE + _MARGIN - self.toolbar_offset - self._make_palette_spr(n, 0, self.toolbar_offset, - PALETTE_WIDTH, h, regenerate) - if show: - self.palette_button[2].move((PALETTE_WIDTH - _BUTTON_SIZE, - self.toolbar_offset)) - self.palette_button[3].move( - (0, self.toolbar_offset + _BUTTON_SIZE)) - self.palette_button[5].move( - (0, self.toolbar_offset + _BUTTON_SIZE)) - if show: - self.palette_button[2].save_xy = \ - self.palette_button[2].get_xy() - if self.running_sugar and not self.hw in [XO1]: - self.palette_button[2].move_relative( - (self.activity.hadj_value, self.activity.vadj_value)) - self.palette_sprs[n][self.orientation].set_layer( - CATEGORY_LAYER) - self._display_palette_shift_button(n) - - def _make_palette_spr(self, n, x, y, w, h, regenerate=False): - ''' Make the background for the palette. ''' - if regenerate and not self.palette_sprs[n][self.orientation] is None: - self.palette_sprs[n][self.orientation].hide() - self.palette_sprs[n][self.orientation] = None - if self.palette_sprs[n][self.orientation] is None: - svg = SVG() - self.palette_sprs[n][self.orientation] = \ - Sprite(self.sprite_list, x, y, svg_str_to_pixbuf( - svg.palette(w, h))) - self.palette_sprs[n][self.orientation].save_xy = (x, y) - if self.running_sugar and not self.hw in [XO1]: - self.palette_sprs[n][self.orientation].move_relative( - (self.activity.hadj_value, self.activity.vadj_value)) - if self.orientation == 0 and w > self.width: - self.palette_sprs[n][self.orientation].type = \ - 'category-shift-horizontal' - elif self.orientation == 1 and h > self.height - ICON_SIZE: - self.palette_sprs[n][self.orientation].type = \ - 'category-shift-vertical' - else: - self.palette_sprs[n][self.orientation].type = 'category' - if 'trash' in palette_names and \ - n == palette_names.index('trash'): - svg = SVG() - self.palette_sprs[n][self.orientation].set_shape( - svg_str_to_pixbuf(svg.palette(w, h))) def _buttonpress_cb(self, win, event): ''' Button press ''' @@ -1864,10 +1563,10 @@ before making changes to your program')) return i = palette_names.index('myblocks') palette_blocks[i].remove(blk.name) - for pblk in self.palettes[i]: + for pblk in self.palette_views[i].blocks: if pblk.name == blk.name: pblk.spr.hide() - self.palettes[i].remove(pblk) + self.palette_views[i].blocks.remove(pblk) break self.show_toolbar_palette(i, regenerate=True) @@ -1917,7 +1616,7 @@ before making changes to your program')) palette_names[i] + 'on') self.show_palette(i) elif spr.name == _('shift'): - self._shift_toolbar_palette(self.selected_palette) + self.palette_views[self.selected_palette].shift() else: self.set_orientation(1 - self.orientation) elif spr.type == 'toolbar': @@ -1928,10 +1627,11 @@ before making changes to your program')) self.orientation = orientation self.palette_button[self.orientation].set_layer(TAB_LAYER) self.palette_button[1 - self.orientation].hide() - spr = self.palette_sprs[self.selected_palette][1 - self.orientation] + o = 1 - self.orientation + spr = self.palette_views[self.selected_palette].backgrounds[o] if spr is not None: spr.hide() - self._layout_palette(self.selected_palette) + self.palette_views[self.selected_palette].layout_palette() self.show_palette(self.selected_palette) def _update_action_names(self, name): @@ -2022,7 +1722,7 @@ before making changes to your program')) block_names[new] = name i = palette_name_to_index(palette) - for blk in self.palettes[i]: + for blk in self.palette_views[i].blocks: if blk.name == old: blk.name = new blk.spr.labels[label] = name @@ -2174,10 +1874,10 @@ before making changes to your program')) i = palette_name_to_index('blocks') if name in palette_blocks[i]: palette_blocks[i].remove(name) - for blk in self.palettes[i]: + for blk in self.palette_views[i].blocks: if blk.name == name: blk.spr.hide() - self.palettes[i].remove(blk) + self.palette_views[i].blocks.remove(blk) self.show_toolbar_palette(i, regenerate=True) if name in block_styles[style]: block_styles[style].remove(name) @@ -2254,10 +1954,11 @@ before making changes to your program')) def _in_the_trash(self, x, y): ''' Is x, y over a palette? ''' - if self.selected_palette is not None and \ - self.palette_sprs[self.selected_palette][self.orientation]\ - .hit((x, y)): - return True + n = self.selected_palette + if n is not None: + spr = self.palette_views[n].backgrounds[self.orientation] + if spr.hit((x, y)): + return True return False def _block_pressed(self, x, y, blk): @@ -3730,7 +3431,7 @@ before making changes to your program')) print 'selected palette is None' return True else: - p = self.palettes[self.selected_palette] + p = self.palette_views[self.selected_palette].blocks i = 0 if self._highlighted_blk is not None: self._highlighted_blk.unhighlight() @@ -4725,7 +4426,7 @@ before making changes to your program')) if '.odp' not in name: name = name + '.odp' if name is not None: - res = subprocess.check_output( + subprocess.check_output( ['cp', TMP_ODP_PATH, os.path.join(datapath, name)]) @@ -4952,8 +4653,10 @@ before making changes to your program')) def _proto_skin(self, name, n, i): ''' Utility for calculating proto skin images ''' - x, y = self._calc_image_offset(name, self.palettes[n][i].spr) - self.palettes[n][i].spr.set_image(self.media_shapes[name], 1, x, y) + x, y = self._calc_image_offset(name, + self.palette_views[n].blocks[i].spr) + self.palette_views[n].blocks[i].spr.set_image( + self.media_shapes[name], 1, x, y) def _block_skin(self, name, blk): ''' Some blocks get a skin ''' @@ -4989,7 +4692,7 @@ before making changes to your program')) if isinstance(label, unicode): label = label.encode('utf-8') i = palette_name_to_index(palette) - for blk in self.palettes[i]: + for blk in self.palette_views[i].blocks: blk_label = blk.spr.labels[0] if isinstance(blk.name, unicode): blk.name = blk.name.encode('utf-8') -- cgit v0.9.1