示例#1
0
def test_move_shapes(shapes_store: ShapesStore, shapes: Dict[str, Shape]):
    shapes_store.add_shapes(*shapes.values())

    res = shapes_store.move_shapes(Point(10, 10), Point(-100, 100))
    assert res['moved'] == [
        Polyline(Point(-100, 100),
                 Point(-90, 110),
                 Point(-80, 100),
                 color=Color(48, 210, 111))
    ]
    assert res['before_move'] == [*shapes.values()]
    assert len(shapes_store._controller.result) == 3

    shapes_store.add_shapes(
        Rectangle(Point(-10, 3490), 20, 20, Color(255, 255, 255)))
    # Getting the previously moved polyline back
    shapes_store.move_shapes(Point(-100, 100), Point(10, 10))
    res = shapes_store.move_shapes(Point(0, 3500), Point(-1000, -1000))
    assert res['moved'] == [
        Rectangle(Point(-1000, -4500), 1, 50000, Color(255, 255, 255)),
        Rectangle(Point(-1010, -1010), 20, 20, Color(255, 255, 255))
    ]
    assert res['before_move'] == [
        shapes['dot'], shapes['line'], shapes['rectangle'], shapes['circle'],
        Rectangle(Point(-10, 3490), 20, 20, Color(255, 255, 255)),
        shapes['polyline']
    ]
    assert len(shapes_store._controller.result) == 8
示例#2
0
class Controller:
    """
    Main class of this application. Holds all crucial pieces together.
    It represents an observer in the observer design pattern.
    """
    def __init__(self):
        self._gui = MainWindow(self)
        self._command_engine = CommandEngine(self)
        self._printer = CanvasPrinter(self._gui.canvas)
        self._shapes = ShapesStore(self)

        # import CliParser this late to avoid import loop
        from app.parsers.cli_parser import CliParser
        self._cli_parser = CliParser(self, RgbColorParser())

    def add_shapes(self, *shapes: Shape):
        for shape in shapes:
            self.print_to_history(str(shape))
        self._shapes.add_shapes(*shapes)

    def move_shapes(self,
                    move_from: Point,
                    move_to: Point,
                    divergence: bool = False) -> Dict[str, List[Shape]]:
        return self._shapes.move_shapes(move_from, move_to, divergence)

    def replace_shapes_store(self, shapes: List[Shape]):
        self._shapes = ShapesStore(self, shapes)
        self.update()

    def remove_last_shape(self):
        self._shapes.remove_last_shape()

    def remove_shapes_at(self,
                         point: Point,
                         divergence: bool = False) -> Dict[str, List[Shape]]:
        return self._shapes.remove_shapes_at(point, divergence)

    def preview_shape(self, shape: Shape):
        self._shapes.set_preview(shape)

    def end_preview(self):
        self._shapes.set_preview(None)

    def parse_command(self, command_text: str):
        command = self._cli_parser.parse_input(command_text)
        self.execute_command(command, command_text=command_text)

    def execute_command(self,
                        command: Command,
                        from_redo: bool = False,
                        command_text: str = None):
        history_line = ' > ' + (command_text or str(command))
        self._gui.print_lines_to_history(history_line)
        self._command_engine.execute_command(command, from_redo=from_redo)

    def remove_last_command(self):
        self._command_engine.remove_last_command()

    def print_to_history(self, lines: str):
        self._gui.print_lines_to_history(lines)

    def delete_from_history(self, number_of_lines: int = 1):
        self._gui.delete_from_history(number_of_lines)

    def shapes_at(self,
                  point: Point = None,
                  divergence: bool = False) -> List[Shape]:
        return self._shapes.shapes_at(point, divergence)

    def print_shapes_to_history(self, point: Point):
        for shape in self.shapes_at(point):
            self.print_to_history(str(shape))

    def print_all_shapes(self, printer: Printer = None) -> List[Shape]:
        return self._shapes.print_all(printer or self._printer)

    def update(self):
        self._printer.update(self)

    def undo(self):
        self._command_engine.undo()

    def redo(self):
        self._command_engine.redo()

    def enable_undo(self):
        self._gui.enable_undo()

    def enable_redo(self):
        self._gui.enable_redo()

    def disable_undo(self):
        self._gui.disable_undo()

    def disable_redo(self):
        self._gui.disable_redo()

    def save_dialog(self, path_to_file: str):
        self._gui.save_dialog(path_to_file)

    def load_dialog(self, path_to_file: str):
        self._gui.load_dialog(path_to_file)

    def save(self, file: str):
        commands = self._command_engine.get_all_commands()
        with open(file, 'w+', encoding='utf-8') as f:
            [f.write(str(c) + '\n') for c in commands['undos']]

        self._gui.set_status('File saved!')

    def load(self, file: str):
        with open(file, 'r', encoding='utf-8') as f:
            # Getting rid of the newline `\n` at the end of every line
            commands = [line[:-1] for line in f.readlines()]
            for command_text in commands:
                command = self._cli_parser.parse_input(command_text)
                self.execute_command(command, command_text=command_text)

        self._gui.set_status('File loaded!')

    def run_app(self):
        # Run the whole app
        self._gui.show()

    def clear_dialog(self) -> bool:
        return self._gui.clear_dialog()

    def restart(self):
        self._shapes.restart()

    def quit(self):
        self._gui.close()