コード例 #1
0
    def run(self):
        """
            Keeps running until the quit button is pressed and the
            application ends. Will draw the color palette, and options, keeps
            looking for pressed elements in the screen.
        :return:
        """

        self.create_color_palette()
        self.create_options()

        self.options_context.options_size = len(self.gui_context.draw_surfaces)

        while self.options_context.keep_running:
            draw_to_surface(self.gui_context.screen, self.gui_context.draw_surfaces)

            events = pygame.event.get()

            for event in events:
                if event.type == pygame.QUIT:
                    self.options_context.keep_running = False

                mouse_position = pygame.mouse.get_pos()
                is_pressed, _, __ = pygame.mouse.get_pressed()

                if is_pressed:
                    self.handle_pressed_element([draw for draw in
                                                 self.gui_context.draw_surfaces if
                                                 draw.is_valid and
                                                 UserInterface.surface_was_pressed(
                                                     draw,
                                                     mouse_position
                                                 )])

            pygame.display.flip()
コード例 #2
0
    def _iter_flood_fill(self, surface: pygame.Surface,
                         position: Tuple[int, int]) -> pygame.Surface:

        clock = pygame.time.Clock()
        color = self.options_context.line_color
        points = [position]

        while len(points) > 0:
            (x, y), *points = points
            print(len(points), x, y)
            surface.set_at((x, y), color)

            if self.is_valid(surface, (x + 1, y)):
                points.append((x + 1, y))

            if self.is_valid(surface, (x - 1, y)):
                points.append((x - 1, y))

            if self.is_valid(surface, (x, y + 1)):
                points.append((x, y + 1))

            if self.is_valid(surface, (x, y - 1)):
                points.append((x, y - 1))

            color_context = DrawContext(surface, (0, 0))
            color_context.is_valid = False

            draw_to_surface(self.gui_context.screen,
                            [color_context, *self.gui_context.draw_surfaces])

            pygame.display.flip()
            clock.tick(100)

        return surface
コード例 #3
0
    def draw_line(self, *args, **kwargs):
        """
            The user will choose two points, the start and end of the square/rectangle:

                (x, y) - - - - - - 0
                  |                |
                  |                |
                  |                |
                  |                |
                  |                |
                  0 - - - - - - (x, y)

            Then the object will be drawn
        :param args: anything
        :param kwargs: anything
        """
        control_point: Tuple[int, int] = None
        clock = pygame.time.Clock()
        is_running = True

        while is_running:
            event = pygame.event.wait()

            if control_point is None:
                if event.type == MOUSEBUTTONDOWN:
                    mouse_position = pygame.mouse.get_pos()
                    is_pressed, _, __ = pygame.mouse.get_pressed()

                    if is_pressed:
                        control_point = mouse_position
            else:
                mouse_position = pygame.mouse.get_pos()
                square_surface: pygame.Surface = pygame.Surface(
                    DEFAULT_DIMENSION, pygame.SRCALPHA, 32)
                square_surface.convert_alpha()

                [u_l, u_r, b_l,
                 b_r] = RectangleIllustrator.transform_coordinates(
                     control_point, mouse_position)
                self._bresenham(u_l, u_r, square_surface)
                self._bresenham(u_l, b_l, square_surface)
                self._bresenham(b_l, b_r, square_surface)
                self._bresenham(u_r, b_r, square_surface)

                square_context = DrawContext(square_surface, (0, 0))
                square_context.is_valid = False
                draw_to_surface(
                    self.gui_context.screen,
                    [square_context, *self.gui_context.draw_surfaces])

                if event.type == MOUSEBUTTONDOWN:
                    is_running = False
                    self.gui_context.draw_surfaces = square_context

            clock.tick(100)
コード例 #4
0
    def draw_line(self, *args, **kwargs):
        """
            User will first select 4 control points, then will change the
            accordingly. When its everything ok, will press 'ESC' to finish
            the curve and exit

        :param args: anything
        :param kwargs: anything
        """
        control_points: List[PointContext] = []
        original_position = kwargs.get('option_position')
        is_running = True
        selected: PointContext = None
        clock = pygame.time.Clock()

        while is_running:
            context = self.draw([(p.x, p.y) for p in control_points])
            bezier_surface = context.element

            for event in pygame.event.get():
                if event.type in (QUIT, KEYDOWN):
                    is_running = False

                elif event.type == MOUSEBUTTONDOWN:
                    if event.button == 1:
                        for p in control_points:
                            if abs(p.x - event.pos[0]) < 10 and abs(p.y - event.pos[1]) < 10:
                                selected = p

                    elif event.button == 3 and event.pos != original_position and len(control_points) < 4:
                        control_points.append(PointContext(event.pos))

                elif event.type == MOUSEBUTTONUP and event.button == 1:
                    selected = None

            if selected is not None:
                selected.x, selected.y = pygame.mouse.get_pos()
                pygame.draw.circle(bezier_surface, green, (selected.x, selected.y), 10)

            for p in control_points:
                pygame.draw.circle(bezier_surface, blue, (p.x, p.y), 10)

            if len(control_points) >= 2:
                pygame.draw.lines(bezier_surface, lightgray, False, [(p.x, p.y) for p in control_points])

            draw_to_surface(self.gui_context.screen, [context, *self.gui_context.draw_surfaces])

            clock.tick(100)

        self.gui_context.draw_surfaces = self.draw([(p.x, p.y) for p in control_points])
コード例 #5
0
    def draw_line(self, *args, **kwargs):
        """
            The user will add new point with the right mouse button
            Will drag the points with the left mouse button
            And press any key on keyboard to leave
        :param args: anything
        :param kwargs: anything
        """
        control_points: List[PointContext] = []
        original_position = kwargs.get('option_position')
        is_running = True
        selected: PointContext = None
        clock = pygame.time.Clock()

        while is_running:
            context = self.draw([(p.x, p.y) for p in control_points])
            surface = context.element

            for event in pygame.event.get():
                if event.type in (QUIT, KEYDOWN):
                    is_running = False

                elif event.type == MOUSEBUTTONDOWN:
                    if event.button == 1:
                        for point in control_points:
                            if abs(point.x - event.pos[0]) < 10 and abs(
                                    point.y - event.pos[1]) < 10:
                                selected = point
                    elif event.button == 3 and event.pos != original_position:
                        control_points.append(PointContext(event.pos))

                elif event.type == MOUSEBUTTONUP and event.button == 1:
                    selected = None

            if selected is not None:
                selected.x, selected.y = pygame.mouse.get_pos()
                pygame.draw.circle(surface, green, (selected.x, selected.y),
                                   10)

            for point in control_points:
                pygame.draw.circle(surface, blue, (point.x, point.y), 10)

            draw_to_surface(self.gui_context.screen,
                            [context, *self.gui_context.draw_surfaces])

            clock.tick(100)

        self.gui_context.draw_surfaces = self.draw([(p.x, p.y)
                                                    for p in control_points])
コード例 #6
0
    def draw_circle(self, *args, **kwargs):
        """
            Will keep awaiting for two mouse clicks, the position where
            it will start and another click where the line ends
        :param args:
        :param kwargs:
        """
        control_point: Tuple[int, int] = None
        clock = pygame.time.Clock()
        is_running = True

        while is_running:
            event = pygame.event.wait()

            if control_point is None:
                if event.type == MOUSEBUTTONDOWN:
                    mouse_position = pygame.mouse.get_pos()
                    is_pressed, _, __ = pygame.mouse.get_pressed()

                    if is_pressed:
                        control_point = mouse_position
            else:
                mouse_position = pygame.mouse.get_pos()
                circle_suface: pygame.Surface = pygame.Surface(
                    DEFAULT_DIMENSION, pygame.SRCALPHA, 32)
                circle_suface.convert_alpha()

                radius = CircleIllustrator.find_radius(control_point,
                                                       mouse_position)
                self._middle_point(radius, mouse_position, circle_suface)
                line_context = DrawContext(circle_suface, (0, 0))
                line_context.is_valid = False
                draw_to_surface(
                    self.gui_context.screen,
                    [line_context, *self.gui_context.draw_surfaces])

                if event.type == MOUSEBUTTONDOWN:
                    is_running = False
                    self.gui_context.draw_surfaces = line_context

            clock.tick(100)
コード例 #7
0
    def draw_line(self, *args, **kwargs) -> None:
        """
            Will keep awaiting for two mouse clicks, the position where
            it will start and another click where the line ends
        :param args:
        :param kwargs:
        """
        control_points: List[Tuple[int, int]] = []
        clock = pygame.time.Clock()
        is_running = True

        while is_running:
            event = pygame.event.wait()

            if not len(control_points):
                if event.type == MOUSEBUTTONDOWN:
                    mouse_position = pygame.mouse.get_pos()
                    is_pressed, _, __ = pygame.mouse.get_pressed()

                    if is_pressed:
                        control_points.append(mouse_position)
            else:
                mouse_position = pygame.mouse.get_pos()
                line_surface: pygame.Surface = pygame.Surface(
                    DEFAULT_DIMENSION, pygame.SRCALPHA, 32)
                line_surface.convert_alpha()
                self._bresenham(control_points[0], mouse_position,
                                line_surface)
                line_context = DrawContext(line_surface, (0, 0))
                line_context.is_valid = False
                draw_to_surface(
                    self.gui_context.screen,
                    [line_context, *self.gui_context.draw_surfaces])

                if event.type == MOUSEBUTTONDOWN:
                    is_running = False
                    self.gui_context.draw_surfaces = line_context

            clock.tick(100)