diff --git a/src/config.py b/src/config.py new file mode 100644 index 0000000..31e3804 --- /dev/null +++ b/src/config.py @@ -0,0 +1,27 @@ +import json +import os.path + + +class Config: + LAST_OPENED_FILE = "" + AUTOSAVE_INTERVAL = 5 * 60 * 1000 + + def __init__(self, path: str): + self._path: str = path + + self.load() + + def load(self) -> None: + if os.path.exists(self._path): + with open(self._path, "r") as f: + config = json.load(f) + + self.LAST_OPENED_FILE = config["last_opened_file"] + self.AUTOSAVE_INTERVAL = config["autosave_interval"] + + def save(self) -> None: + with open(self._path, "w") as f: + json.dump({ + "last_opened_file": self.LAST_OPENED_FILE, + "autosave_interval": self.AUTOSAVE_INTERVAL + }, f, indent=4) diff --git a/src/editor.py b/src/editor.py index 167dcb3..8c20d27 100644 --- a/src/editor.py +++ b/src/editor.py @@ -6,6 +6,7 @@ from typing import Optional import platformdirs import pygame +from src.config import Config from src.image_handler import ImageHandler from src.graph.graph import Graph @@ -16,16 +17,18 @@ class Editor: WIDTH: int = 800 HEIGHT: int = 600 MAP_SIZE: int = 1024 - CACHE_DIR: str = platformdirs.user_cache_dir(appname=APP_NAME, appauthor=APP_AUTHOR) + CACHE_DIR: str = platformdirs.user_cache_dir(appname=APP_NAME, appauthor=APP_AUTHOR, ensure_exists=True) + CONFIG_DIR: str = platformdirs.user_config_dir(appname=APP_NAME, appauthor=APP_AUTHOR, ensure_exists=True) + CONFIG_PATH: str = os.path.join(CONFIG_DIR, "config.json") MAPS_DIR: str = os.path.join(CACHE_DIR, "maps") AUTOSAVE_PATH: str = os.path.join(CACHE_DIR, "AUTOSAVE.txt") - AUTOSAVE_INTERVAL: int = 5 * 60 * 1000 AUTOSAVE_EVENT: int = pygame.event.custom_type() ZOOMS: tuple[float] = (0.25, 0.5, 1, 2, 4) CROSSHAIR_SIZE: int = 10 def __init__(self): pygame.init() + self.config: Config = Config(self.CONFIG_PATH) self.width: int = self.WIDTH self.height: int = self.HEIGHT self.win: pygame.Surface = pygame.display.set_mode([self.width, self.height], pygame.RESIZABLE) @@ -58,7 +61,13 @@ class Editor: self.original_move_pos: tuple[int, int] = None self.move_old_poses: dict[int, tuple[int, int]] = None self.dirty: bool = False - pygame.time.set_timer(self.AUTOSAVE_EVENT, self.AUTOSAVE_INTERVAL) + pygame.time.set_timer(self.AUTOSAVE_EVENT, self.config.AUTOSAVE_INTERVAL) + + if os.path.exists(self.AUTOSAVE_PATH): + self.load(self.AUTOSAVE_PATH, False) + self.dirty = True + elif self.config.LAST_OPENED_FILE != "": + self.load(self.config.LAST_OPENED_FILE) def mainloop(self) -> None: self.state = State.LOADING @@ -80,13 +89,18 @@ class Editor: self.render() self.clock.tick(30) + def quit(self) -> None: + if self.dirty: + self.save(self.AUTOSAVE_PATH, False) + self.state = State.STOPPING + def process_events(self) -> None: events = pygame.event.get() keys = pygame.key.get_pressed() for event in events: if event.type == pygame.QUIT: - self.state = State.STOPPING + self.quit() elif event.type == pygame.WINDOWRESIZED: self.width = event.x self.height = event.y @@ -107,7 +121,7 @@ class Editor: self.clear_selection() self.previously_created_nodes = [] else: - self.state = State.STOPPING + self.quit() elif event.key == pygame.K_PAGEUP: self.zoom_in() elif event.key == pygame.K_PAGEDOWN: @@ -156,7 +170,8 @@ class Editor: elif self.selection_rectangle != None: self.release_selection_rect(keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]) elif event.type == self.AUTOSAVE_EVENT: - self.graph.save(self.AUTOSAVE_PATH) + if self.dirty: + self.save(self.AUTOSAVE_PATH, False) if keys[pygame.K_LEFT]: self.center[0] -= 4 / self.zoom @@ -599,12 +614,32 @@ class Editor: self.original_move_pos = None self.move_old_poses = None - def save(self) -> None: - self.graph.save(input("Save as: ")) + def save(self, path: Optional[str] = None, save_config: bool = True) -> None: + last_path = self.config.LAST_OPENED_FILE + if path is None: + path = input(f"Save as ({last_path}): ") + if len(path.strip()) == 0: + path = last_path + + self.graph.save(path) + if save_config: + self.config.LAST_OPENED_FILE = path + self.config.save() + if os.path.exists(self.AUTOSAVE_PATH): + os.remove(self.AUTOSAVE_PATH) self.dirty = False - def load(self) -> None: - self.graph = Graph.load(input("Load from: ")) + def load(self, path: Optional[str] = None, save_config: bool = True) -> None: + last_path = self.config.LAST_OPENED_FILE + if path is None: + path = input(f"Load from ({last_path}): ") + if len(path.strip()) == 0: + path = last_path + + self.graph = Graph.load(path) + if save_config: + self.config.LAST_OPENED_FILE = path + self.config.save() self.dirty = False