diff --git a/src/editor.py b/src/editor.py index c1a5e63..c71b9db 100644 --- a/src/editor.py +++ b/src/editor.py @@ -103,6 +103,10 @@ class Editor: self.zoom_out() elif event.key == pygame.K_BACKSPACE: self.deleted_selected_objects() + elif event.key == pygame.K_s and event.mod & (pygame.KMOD_CTRL | pygame.KMOD_META): + self.graph.save(input("Save as: ")) + elif event.key == pygame.K_l and event.mod & (pygame.KMOD_CTRL | pygame.KMOD_META): + self.graph = Graph.load(input("Load from: ")) elif event.key == pygame.K_RETURN: if len(self.selected_nodes) > 0: self.typing_text = "" if len(self.selected_nodes) > 1 else self.graph.nodes[self.selected_nodes[0]].name @@ -319,7 +323,7 @@ class Editor: pygame.draw.line(self.win, (0, 0, 0), self.world_to_screen(node_1.x, node_1.z), self.world_to_screen(node_2.x, node_2.z), self.edge_detect_radius) color = (0, 255, 255) if edge_index in self.selected_edges else (255, 0, 0) pygame.draw.line(self.win, color, self.world_to_screen(node_1.x, node_1.z), self.world_to_screen(node_2.x, node_2.z), self.line_size) - + def render_selection_rect(self): rect = self.selection_rectangle if rect != None: @@ -328,7 +332,7 @@ class Editor: width = abs(rect[0][0] - rect[1][0]) height = abs(rect[0][1] - rect[1][1]) pygame.draw.rect(self.win, (32, 32, 32), pygame.Rect(left, top, width, height), self.line_size) - + def set_zoom(self, zoom_i: int) -> None: self.zoom_i = max(0, min(len(self.ZOOMS) - 1, zoom_i)) @@ -417,7 +421,7 @@ class Editor: self.graph.nodes[node].rename_node(self.typing_text) self.typing_text = "" self.is_renaming_node = False - + def create_node(self, pos, typing_text = "") -> None: self.graph.add_node(pos[0], pos[1], typing_text) if len(self.selected_nodes) == 1: @@ -514,17 +518,17 @@ class Editor: if n != 0: self.selected_nodes.append(self.previously_created_nodes[n - 1]) self.previously_created_nodes.pop() - + def create_selection_rect(self, shifting = False): if not shifting: self.clear_selection() self.previously_created_nodes = [] mouse_pos = pygame.mouse.get_pos() self.selection_rectangle = [mouse_pos, mouse_pos] - + def expand_selection_rect(self): self.selection_rectangle[1] = pygame.mouse.get_pos() - + def release_selection_rect(self, shifting = False): if not shifting: self.clear_selection() diff --git a/src/graph/graph.py b/src/graph/graph.py index 091b19c..5af4143 100644 --- a/src/graph/graph.py +++ b/src/graph/graph.py @@ -1,9 +1,11 @@ +from __future__ import annotations from math import inf from typing import Iterator, Optional from src.graph.node import Node from src.graph.edge import Edge + class Graph: def __init__(self): self.edges: list[Edge] = [] @@ -47,7 +49,7 @@ class Graph: def get_edge_nodes(self, edge: Edge) -> tuple[Node, Node]: return self.nodes[edge.start], self.nodes[edge.end] - + def get_edge_center(self, edge_index: int) -> tuple[float, float]: edge = self.edges[edge_index] start_n = self.nodes[edge.start] @@ -94,4 +96,32 @@ class Graph: node_sequences[end] = node_sequences[start].copy() node_sequences[end].append(end) - return node_sequences[target_index] \ No newline at end of file + return node_sequences[target_index] + + def save(self, path: str) -> None: + with open(path, "w") as f: + for node in self.nodes: + f.write(f"n {node.x} {node.z} {node.name}\n") + f.write("\n") + for edge in self.edges: + f.write(f"e {edge.start} {edge.end} {edge.length}\n") + + @staticmethod + def load(path: str) -> Graph: + graph = Graph() + with open(path, "r") as f: + lines = f.read().splitlines() + for line in lines: + if len(line.strip()) == 0: + continue + + entry_type, values = line.split(" ", 1) + if entry_type == "n": + x, z, name = values.split(" ", 2) + x, z = int(x), int(z) + graph.add_node(x, z, name) + elif entry_type == "e": + start, end, length = values.split(" ", 2) + start, end, length = int(start), int(end), float(length) + graph.add_edge(start, end, length) + return graph