From e4252715ca37f55b2bd6702a6c2bb5ce55dd3e23 Mon Sep 17 00:00:00 2001 From: Marion Date: Fri, 09 Aug 2013 21:07:49 +0000 Subject: introduce a Color type for the pen color in block programs --- diff --git a/TurtleArt/tabasics.py b/TurtleArt/tabasics.py index 0346d0e..5eac58b 100644 --- a/TurtleArt/tabasics.py +++ b/TurtleArt/tabasics.py @@ -71,14 +71,7 @@ from gettext import gettext as _ from tapalette import (make_palette, define_logo_function) from talogo import (primitive_dictionary, logoerror) from tautils import (convert, chr_to_ord, round_int, strtype) -from taconstants import (COLORDICT, CONSTANTS) - - -def _color_to_num(c): - if COLORDICT[c][0] is None: - return(COLORDICT[c][1]) - else: - return(COLORDICT[c][0]) +from taconstants import (Color, CONSTANTS) def _num_type(x): @@ -1334,10 +1327,10 @@ variable')) def _prim_plus(self, x, y): ''' Add numbers, concat strings ''' - if x in COLORDICT: - x = _color_to_num(x) - if y in COLORDICT: - y = _color_to_num(y) + if isinstance(x, Color): + x = int(x) + if isinstance(y, Color): + y = int(y) if _num_type(x) and _num_type(y): return(x + y) elif isinstance(x, list) and isinstance(y, list): @@ -1446,8 +1439,8 @@ variable')) pass if isinstance(x, list): raise logoerror("#syntaxerror") - if x in COLORDICT: - return _color_to_num(x) + if isinstance(x, Color): + return int(x) xx = convert(x.replace(self.tw.decimal_point, '.'), float) if isinstance(xx, float): return xx @@ -1460,12 +1453,12 @@ variable')) def _make_constant(self, palette, block_name, label, constant): ''' Factory for constant blocks ''' - if constant in COLORDICT: - if COLORDICT[constant][0] is not None: - value = str(COLORDICT[constant][0]) + if isinstance(constant, Color): + if constant.color is not None: + value = str(constant.color) else: # Black or White - value = '0 tasetshade %d' % (COLORDICT[constant][1]) + value = '0 tasetshade %d' % (constant.shade) else: value = constant palette.add_block(block_name, diff --git a/TurtleArt/tablock.py b/TurtleArt/tablock.py index 8d8ed4a..1ec5e9e 100644 --- a/TurtleArt/tablock.py +++ b/TurtleArt/tablock.py @@ -24,7 +24,7 @@ import cairo from taconstants import (EXPANDABLE, EXPANDABLE_ARGS, OLD_NAMES, CONSTANTS, STANDARD_STROKE_WIDTH, BLOCK_SCALE, BOX_COLORS, - GRADIENT_COLOR, EXPANDABLE_FLOW, COLORDICT) + GRADIENT_COLOR, EXPANDABLE_FLOW, Color) from tapalette import (palette_blocks, block_colors, expandable_blocks, content_blocks, block_names, block_primitives, block_styles, special_block_colors) @@ -529,10 +529,8 @@ class Block: else: self._set_labels(i, str(v)) elif self.type == 'block' and self.name in CONSTANTS: - if CONSTANTS[self.name] in COLORDICT: - v = COLORDICT[CONSTANTS[self.name]][0] - if v is None: - v = COLORDICT[CONSTANTS[self.name]][1] + if isinstance(CONSTANTS[self.name], Color): + v = int(CONSTANTS[self.name]) else: v = CONSTANTS[self.name] self._set_labels(0, block_names[self.name][0] + ' = ' + str(v)) diff --git a/TurtleArt/tacanvas.py b/TurtleArt/tacanvas.py index 89b8ed1..d3c4b3f 100644 --- a/TurtleArt/tacanvas.py +++ b/TurtleArt/tacanvas.py @@ -28,7 +28,7 @@ import cairo import pangocairo from tautils import get_path -from taconstants import COLORDICT, TMP_SVG_PATH +from taconstants import Color, TMP_SVG_PATH def wrap100(n): @@ -208,19 +208,19 @@ class TurtleGraphics: save_rgb = self._fgrgb[:] # Special case for color blocks - if color in COLORDICT: - if COLORDICT[color][0] is None: - self._shade = COLORDICT[color][1] + if isinstance(color, Color): + if color.color is None: + self._shade = color.shade else: - self._color = COLORDICT[color][0] + self._color = color.color else: self._color = color - if shade in COLORDICT: - self._shade = COLORDICT[shade][1] + if isinstance(shade, Color): + self._shade = shade.shade else: self._shade = shade - if gray in COLORDICT: - self._gray = COLORDICT[gray][2] + if isinstance(gray, Color): + self._gray = gray.gray else: self._gray = gray diff --git a/TurtleArt/taconstants.py b/TurtleArt/taconstants.py index 835209e..b1dc43e 100644 --- a/TurtleArt/taconstants.py +++ b/TurtleArt/taconstants.py @@ -79,20 +79,60 @@ XO4 = 'xo4' UNKNOWN = 'unknown' TMP_SVG_PATH = '/tmp/turtle_output.svg' + + +class Color(object): + """ A color used in block programs (e.g., as pen color). """ + + def __init__(self, name, color=0, shade=50, gray=100): + """ name -- a string with the name of the color, e.g., 'red' + color -- the hue (0-100, or None for white, gray, and black) + shade -- the lightness (0 is black, 100 is white) + gray -- the saturation (0 is gray, 100 is fully saturated) """ + self.name = name + self.color = color + self.shade = shade + self.gray = gray + + def __int__(self): + if self.color is None: + return int(self.shade) + else: + return int(self.color) + + def __float__(self): + return float(int(self)) + + def __str__(self): + return str(self.name) + + def __repr__(self): + return '%s (%s/%d/%d)' % (str(self.name), str(self.color), + self.shade, self.gray) + + # TODO implement addition + + def is_gray(self): + """ Return True iff this color is white, gray, or black, i.e. if its + hue is not set or its saturation is zero. """ + return self.color is None or not self.gray + + + CONSTANTS = {'leftpos': None, 'toppos': None, 'rightpos': None, 'bottompos': None, 'width': None, 'height': None, - 'black': '_black', 'white': '_white', 'red': '_red', - 'orange': '_orange', 'yellow': '_yellow', 'green': '_green', - 'cyan': '_cyan', 'blue': '_blue', 'purple': '_purple', + 'black': Color('black', None, 0, 0), + 'white': Color('white', None, 100, 0), + 'red': Color('red', 0, 50, 100), + 'orange': Color('orange', 10, 50, 100), + 'yellow': Color('yellow', 20, 50, 100), + 'green': Color('green', 40, 50, 100), + 'cyan': Color('cyan', 50, 50, 100), + 'blue': Color('blue', 70, 50, 100), + 'purple': Color('purple', 90, 50, 100), 'titlex': None, 'titley': None, 'leftx': None, 'topy': None, 'rightx': None, 'bottomy': None} -COLORDICT = {'_black': [None, 0, 0], '_white': [None, 100, 0], - '_red': [0, 50, 100], '_orange': [10, 50, 100], - '_yellow': [20, 50, 100], '_green': [40, 50, 100], - '_cyan': [50, 50, 100], '_blue': [70, 50, 100], - '_purple': [90, 50, 100]} - # Blocks that are expandable EXPANDABLE_STYLE = ['boolean-style', 'compare-porch-style', 'compare-style', 'number-style-porch', 'number-style', 'basic-style-2arg', diff --git a/TurtleArt/taexportlogo.py b/TurtleArt/taexportlogo.py index f021f94..4a1ed4f 100644 --- a/TurtleArt/taexportlogo.py +++ b/TurtleArt/taexportlogo.py @@ -223,31 +223,31 @@ def _bottomy(tw): def _red(tw): - return CONSTANTS['red'] + return '_' + str(CONSTANTS['red']) def _orange(tw): - return CONSTANTS['orange'] + return '_' + str(CONSTANTS['orange']) def _yellow(tw): - return CONSTANTS['yellow'] + return '_' + str(CONSTANTS['yellow']) def _green(tw): - return CONSTANTS['green'] + return '_' + str(CONSTANTS['green']) def _cyan(tw): - return CONSTANTS['cyan'] + return '_' + str(CONSTANTS['cyan']) def _blue(tw): - return CONSTANTS['blue'] + return '_' + str(CONSTANTS['blue']) def _purple(tw): - return CONSTANTS['purple'] + return '_' + str(CONSTANTS['purple']) def _white(tw): diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py index 12882db..1df7a5b 100644 --- a/TurtleArt/taturtle.py +++ b/TurtleArt/taturtle.py @@ -28,7 +28,7 @@ import cairo from random import uniform from math import sin, cos, pi, sqrt from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS, DEFAULT_TURTLE, - COLORDICT) + Color) from tasprite_factory import SVG, svg_str_to_pixbuf from tacanvas import wrap100, COLOR_TABLE from sprites import Sprite @@ -341,25 +341,28 @@ class Turtle: def set_color(self, color=None, share=True): ''' Set the pen color for this turtle. ''' + if color is None: + color = self._pen_color # Special case for color blocks - if color is not None and color in COLORDICT: - self.set_shade(COLORDICT[color][1], share) - self.set_gray(COLORDICT[color][2], share) - if COLORDICT[color][0] is not None: - self.set_color(COLORDICT[color][0], share) - color = COLORDICT[color][0] + elif isinstance(color, Color): + self.set_shade(color.shade, share) + self.set_gray(color.gray, share) + if color.color is not None: + # TODO why do we call this function twice? + self.set_color(color.color, share) + color = color.color else: color = self._pen_color - elif color is None: - color = self._pen_color try: self._pen_color = color except (TypeError, ValueError): + # TODO these errors are never raised in the try block, right? debug_output('bad value sent to %s' % (__name__), self._turtles.turtle_window.running_sugar) return + # TODO replace these three attributes with one reference to a Color self._turtles.turtle_window.canvas.set_fgcolor(shade=self._pen_shade, gray=self._pen_gray, color=self._pen_color) diff --git a/plugins/turtle_blocks_extras/turtle_blocks_extras.py b/plugins/turtle_blocks_extras/turtle_blocks_extras.py index 8f5a94d..48a2565 100644 --- a/plugins/turtle_blocks_extras/turtle_blocks_extras.py +++ b/plugins/turtle_blocks_extras/turtle_blocks_extras.py @@ -33,7 +33,7 @@ from TurtleArt.talogo import (primitive_dictionary, logoerror, from TurtleArt.taconstants import (DEFAULT_SCALE, ICON_SIZE, CONSTANTS, MEDIA_SHAPES, SKIN_PATHS, BLOCKS_WITH_SKIN, PYTHON_SKIN, PREFIX_DICTIONARY, VOICES, - MACROS, COLORDICT) + MACROS, Color) from TurtleArt.tautils import (round_int, debug_output, get_path, data_to_string, find_group, image_to_base64, hat_on_top, listify, data_from_file) @@ -1080,20 +1080,20 @@ Journal objects')) """ Print object n """ if flag and (self.tw.hide or self.tw.step_time == 0): return - if type(n) == list: + if isinstance(n, list): self.tw.showlabel('print', n) - elif type(n) == str or type(n) == unicode: - if n in COLORDICT: - if COLORDICT[n][0] is None: - self.tw.showlabel('print', '%s %d, %s %d' % - (_('shade'), COLORDICT[n][1], - _('gray'), COLORDICT[n][2])) - else: - self.tw.showlabel('print', '%s %d, %s %d, %s %d' % - (_('color'), COLORDICT[n][0], - _('shade'), COLORDICT[n][1], - _('gray'), COLORDICT[n][2])) - elif n[0:6] == 'media_' and \ + elif isinstance(n, Color): + if n.color is None: + self.tw.showlabel('print', '%s %d, %s %d' % + (_('shade'), n.shade, + _('gray'), n.gray)) + else: + self.tw.showlabel('print', '%s %d, %s %d, %s %d' % + (_('color'), n.color, + _('shade'), n.shade, + _('gray'), n.gray)) + elif isinstance(n, basestring): + if n[0:6] == 'media_' and \ n[6:].lower not in media_blocks_dictionary: try: if self.tw.running_sugar: @@ -1111,7 +1111,7 @@ Journal objects')) self.tw.showlabel('print', n) else: self.tw.showlabel('print', n) - elif type(n) == int: + elif isinstance(n, int): self.tw.showlabel('print', n) else: self.tw.showlabel( -- cgit v0.9.1