def draw_polyline(self, point_list, line_width, line_color): # type: (Sequence[Sequence[Union[int, float]]], Union[int, float], str) -> None # noqa """ Draw line segments between a list of points. If `line_width` > 1, ends are poorly made! :param point_list: not empty (tuple or list) of ((int or float, int or float) or [int or float, int or float]) :param line_width: (int or float) > 0 :param line_color: str """ assert isinstance(point_list, (tuple, list)), type(point_list) assert len(point_list) > 0, len(point_list) if __debug__: for point in point_list: assert isinstance(point, (tuple, list)), type(point) assert len(point) == 2, len(point) assert isinstance(point[0], (int, float)), type(point[0]) assert isinstance(point[1], (int, float)), type(point[1]) assert isinstance(line_width, (int, float)), type(line_width) assert line_width > 0, line_width assert isinstance(line_color, str), type(line_color) if len(point_list) == 1: return pygamecolor = _simpleguicolor_to_pygamecolor(line_color) point_list_rounded = [_pos_round(point) for point in point_list] del point_list line_width = int(round(line_width)) if pygamecolor.a == 255: # without alpha pygame.draw.lines(self._pygame_surface, pygamecolor, False, point_list_rounded, line_width) elif pygamecolor.a > 0: # with alpha (not null) s_alpha = pygame.surface.Surface( (self._width, self._height), # pylint: disable=too-many-function-args # noqa pygame.SRCALPHA) # pylint: disable=no-member # noqa pygame.draw.lines(s_alpha, pygamecolor, False, point_list_rounded, line_width) self._pygame_surface.blit(s_alpha, (0, 0))
def draw_line(self, point1, point2, line_width, line_color): # type: (Sequence[Union[int, float]], Sequence[Union[int, float]], Union[int, float], str) -> None # noqa """ Draw a line segment from point1 to point2. :param point1: (int or float, int or float) or [int or float, int or float] :param point2: (int or float, int or float) or [int or float, int or float] :param line_width: (int or float) > 0 :param line_color: str """ assert isinstance(point1, (tuple, list)), type(point1) assert len(point1) == 2, len(point1) assert isinstance(point1[0], (int, float)), type(point1[0]) assert isinstance(point1[1], (int, float)), type(point1[1]) assert isinstance(point2, (tuple, list)), type(point2) assert len(point2) == 2, len(point2) assert isinstance(point2[0], (int, float)), type(point2[0]) assert isinstance(point2[1], (int, float)), type(point2[1]) assert isinstance(line_width, (int, float)), type(line_width) assert line_width > 0, line_width assert isinstance(line_color, str), type(line_color) pygamecolor = _simpleguicolor_to_pygamecolor(line_color) if pygamecolor.a == 255: # without alpha pygame.draw.line(self._pygame_surface, pygamecolor, _pos_round(point1), _pos_round(point2), int(round(line_width))) elif pygamecolor.a > 0: # with alpha (not null) x1, y1 = _pos_round(point1) x2, y2 = _pos_round(point2) # pylint: disable=invalid-name # noqa width = abs(x2 - x1) + line_width * 2 height = abs(y2 - y1) + line_width * 2 x_min = min(x1, x2) y_min = min(y1, y2) s_alpha = pygame.surface.Surface((width, height), pygame.SRCALPHA) # pylint: disable=too-many-function-args,no-member # noqa pygame.draw.line( s_alpha, pygamecolor, (x1 - x_min + line_width, y1 - y_min + line_width), (x2 - x_min + line_width, y2 - y_min + line_width), int(round(line_width))) self._pygame_surface.blit(s_alpha, (x_min - line_width, y_min - line_width))
def draw_point(self, position, color): # type: (Sequence[Union[int, float]], str) -> None """ Draw a point. :param position: (int or float, int or float) or [int or float, int or float] :param color: str """ assert isinstance(position, (tuple, list)), type(position) assert len(position) == 2, len(position) assert isinstance(position[0], (int, float)), type(position[0]) assert isinstance(position[1], (int, float)), type(position[1]) assert isinstance(color, str), type(color) pygamecolor = _simpleguicolor_to_pygamecolor(color) if pygamecolor.a == 255: # without alpha self._pygame_surface.set_at(_pos_round(position), pygamecolor) elif pygamecolor.a > 0: # with alpha (not null) s_alpha = pygame.surface.Surface((1, 1), pygame.SRCALPHA) # pylint: disable=too-many-function-args,no-member # noqa s_alpha.set_at((0, 0), pygamecolor) self._pygame_surface.blit(s_alpha, _pos_round(position))
def draw_text( self, # pylint: disable=too-many-arguments text, point, font_size, font_color, font_face='serif', _font_size_coef=3 / 4): # type: (str, Sequence[Union[int, float]], Union[int, float], str, str, Union[int, float]) -> None # noqa """ Draw the `text` string at the position `point`. (`point[0]` is the left of the text, `point[1]` is the bottom of the text.) If correponding font in Pygame is not founded, then use the default `pygame.font.Font`. `_font_size_coef` is used to adjust the vertical positioning. **(This paramater is not available in SimpleGUI of CodeSkulptor.)** :warning: This method can't draw multiline text. To draw multiline text, see `simplegui_lib_draw.draw_text_multi()`_ . .. _`simplegui_lib_draw.draw_text_multi()`: ../simplegui_lib_draw.html#SimpleGUICS2Pygame.simplegui_lib_draw.draw_text_multi :param text: str :param point: (int or float, int or float) or [int or float, int or float] :param font_size: (int or float) >= 0 :param font_color: str :param font_face: str == 'monospace', 'sans-serif', 'serif' :param _font_size_coef: int or float :raise: ValueError if text contains unprintable whitespace character **(Alpha color channel don't work!!!)** """ # noqa assert isinstance(text, str), type(text) assert isinstance(point, (tuple, list)), type(point) assert len(point) == 2, len(point) assert isinstance(point[0], (int, float)), type(point[0]) assert isinstance(point[1], (int, float)), type(point[1]) assert isinstance(font_size, (int, float)), type(font_size) assert font_size >= 0, font_size assert isinstance(font_color, str), type(font_color) assert isinstance(font_face, str), type(font_face) assert font_face in _SIMPLEGUIFONTFACE_TO_PYGAMEFONTNAME, font_face assert isinstance(_font_size_coef, (int, float)), type(_font_size_coef) if text == '': return if _RE_UNPRINTABLE_WHITESPACE_CHAR.search(text): raise ValueError('text may not contain non-printing characters') pygamecolor = _simpleguicolor_to_pygamecolor(font_color) font_size = int(round(font_size)) if (pygamecolor.a > 0) and (font_size > 0): pygame_surface_text = _simpleguifontface_to_pygamefont( font_face, font_size).render(text, True, pygamecolor) # if pygamecolor.a == 255: # without alpha self._pygame_surface.blit( pygame_surface_text, (point[0], (point[1] - pygame_surface_text.get_height() * _font_size_coef)))
def draw_polygon(self, point_list, line_width, line_color, fill_color=None): # type: (Sequence[Sequence[Union[int, float]]], Union[int, float], str, Optional[str]) -> None # noqa """ Draw a polygon from a list of points. A segment is automatically drawed between the last point and the first point. If `fill color` is not None then fill with this color. If `line_width` > 1, ends are poorly made! :param point_list: not empty (tuple or list) of ((int or float, int or float) or [int or float, int or float]) :param line_width: (int or float) > 0 :param line_color: str :param fill_color: None or str """ assert isinstance(point_list, (tuple, list)), type(point_list) assert len(point_list) > 0, len(point_list) if __debug__: for point in point_list: assert isinstance(point, (tuple, list)), type(point) assert len(point) == 2, len(point) assert isinstance(point[0], (int, float)), type(point[0]) assert isinstance(point[1], (int, float)), type(point[1]) assert isinstance(line_width, (int, float)), type(line_width) assert line_width >= 0, line_width assert isinstance(line_color, str), type(line_color) assert (fill_color is None) or isinstance(fill_color, str), \ type(fill_color) if len(point_list) == 1: return pygamecolor = _simpleguicolor_to_pygamecolor(line_color) pygamefillcolor = (None if fill_color is None else _simpleguicolor_to_pygamecolor(fill_color)) point_list_rounded = [_pos_round(point) for point in point_list] del point_list line_width = int(round(line_width)) if ((pygamecolor.a == 255) and ((pygamefillcolor is None) or (pygamefillcolor.a == 255))): # Without alpha if pygamefillcolor is not None: pygame.draw.polygon(self._pygame_surface, pygamefillcolor, point_list_rounded, 0) if pygamecolor != pygamefillcolor: pygame.draw.lines(self._pygame_surface, pygamecolor, True, point_list_rounded, line_width) elif ((pygamecolor.a > 0) or ((pygamefillcolor is not None) and (pygamefillcolor.a > 0))): # With one or two alpha (not null) s_alpha = pygame.surface.Surface( (self._width, self._height), # pylint: disable=too-many-function-args # noqa pygame.SRCALPHA) # pylint: disable=no-member # noqa if (pygamefillcolor is not None) and (pygamefillcolor.a > 0): pygame.draw.polygon(s_alpha, pygamefillcolor, point_list_rounded, 0) if (pygamecolor != pygamefillcolor) and (pygamecolor.a > 0): pygame.draw.lines(s_alpha, pygamecolor, True, point_list_rounded, line_width) self._pygame_surface.blit(s_alpha, (0, 0))
def draw_circle( self, # pylint: disable=too-many-arguments center_point, radius, line_width, line_color, fill_color=None): # type: (Sequence[Union[int, float]], Union[int, float], Union[int, float], str, Optional[str]) -> None # noqa """ Draw a circle. If `fill_color` != `None` then fill with this color. :param center_point: (int or float, int or float) or [int or float, int or float] :param radius: (int or float) > 0 :param line_width: (int or float) > 0 :param line_color: str :param fill_color: None or str """ assert isinstance(center_point, (tuple, list)), type(center_point) assert len(center_point) == 2, len(center_point) assert isinstance(center_point[0], (int, float)), type(center_point[0]) assert isinstance(center_point[1], (int, float)), type(center_point[1]) assert isinstance(radius, (int, float)), type(radius) assert radius > 0, radius assert isinstance(line_width, (int, float)), type(line_width) assert line_width > 0, line_width assert isinstance(line_color, str), type(line_color) assert (fill_color is None) or isinstance(fill_color, str), \ type(fill_color) line_width = (1 if line_width <= 1 else int(round(line_width))) radius = int(round(radius)) + int(round(line_width // 2)) if radius > 1: pygamecolor = _simpleguicolor_to_pygamecolor(line_color) pygamefillcolor = (None if fill_color is None else _simpleguicolor_to_pygamecolor(fill_color)) center_point_rounded = _pos_round(center_point) if ((pygamecolor.a == 255) and ((pygamefillcolor is None) or (pygamefillcolor.a == 255))): # Without alpha if pygamefillcolor is not None: pygame.draw.circle(self._pygame_surface, pygamefillcolor, center_point_rounded, radius, 0) if pygamecolor != pygamefillcolor: pygame.draw.circle(self._pygame_surface, pygamecolor, center_point_rounded, radius, min(line_width, radius)) elif ((pygamecolor.a > 0) or ((pygamefillcolor is not None) and (pygamefillcolor.a > 0))): # With one or two alpha (not null) diameter = radius * 2 s_alpha = pygame.surface.Surface( (diameter, diameter), # pylint: disable=too-many-function-args # noqa pygame.SRCALPHA) # pylint: disable=no-member # noqa if (pygamefillcolor is not None) and (pygamefillcolor.a > 0): pygame.draw.circle(s_alpha, pygamefillcolor, (radius, radius), radius, 0) if (pygamecolor != pygamefillcolor) and (pygamecolor.a > 0): pygame.draw.circle(s_alpha, pygamecolor, (radius, radius), radius, min(line_width, radius)) self._pygame_surface.blit(s_alpha, (center_point_rounded[0] - radius, center_point_rounded[1] - radius)) elif radius > 0: # == 1 self.draw_point(center_point, line_color)
def draw_arc( self, # pylint: disable=too-many-arguments center_point, radius, start_angle, end_angle, line_width, line_color): # type: (Sequence[Union[int, float]], Union[int, float], Union[int, float], Union[int, float], Union[int, float], str) -> None # noqa """ Draw an arc of circle, from `start_angle` to `end_angle`. Angles given in radians are clockwise and start from 0 at the 3 o'clock position. (Available in CodeSkulptor3 but *not in CodeSkulptor2*!) :param center_point: (int or float, int or float) or [int or float, int or float] :param radius: (int or float) > 0 :param start_angle: int or float :param end_angle: int or float :param line_width: (int or float) > 0 :param line_color: str """ assert isinstance(center_point, (tuple, list)), type(center_point) assert len(center_point) == 2, len(center_point) assert isinstance(center_point[0], (int, float)), type(center_point[0]) assert isinstance(center_point[1], (int, float)), type(center_point[1]) assert isinstance(radius, (int, float)), type(radius) assert radius > 0, radius assert isinstance(start_angle, (int, float)), (start_angle) assert isinstance(end_angle, (int, float)), type(end_angle) assert isinstance(line_width, (int, float)), type(line_width) assert line_width > 0, line_width assert isinstance(line_color, str), type(line_color) line_width = (1 if line_width <= 1 else int(round(line_width))) radius = int(round(radius)) + int(round(line_width // 2)) # Adapt Codeskulptor angles to Pygame if start_angle == end_angle: return start_angle = -start_angle end_angle = -end_angle start_angle, end_angle = end_angle, start_angle double_pi = math.pi * 2 start_angle %= double_pi end_angle %= double_pi if start_angle == end_angle: return # Draw if radius > 1: pygamecolor = _simpleguicolor_to_pygamecolor(line_color) if pygamecolor.a > 0: diameter = radius * 2 s_tmp = pygame.surface.Surface( (diameter, diameter), # pylint: disable=too-many-function-args # noqa pygame.SRCALPHA) # pylint: disable=no-member # noqa pygame.draw.arc(s_tmp, pygamecolor, s_tmp.get_rect(), start_angle, end_angle, min(line_width, radius)) self._pygame_surface.blit( s_tmp, (center_point[0] - radius, center_point[1] - radius)) elif radius > 0: # == 1 self.draw_point(center_point, line_color)