from kivy.uix.screenmanager import Screen from kivy.uix.boxlayout import BoxLayout from kivy.uix.label import Label from kivy.uix.button import Button from kivy.uix.popup import Popup from kivy.uix.image import Image from kivy.uix.behaviors import ButtonBehavior from kivy.clock import Clock import os import json from config import RESOURCES_FOLDER, CREDENTIALS_FILE from utils import encrypt_data, decrypt_data, check_server_settings, save_server_settings, test_connection class IconButton(ButtonBehavior, Image): pass class HomeScreen(Screen): def on_pre_enter(self): """Load existing projects/trips when the screen is entered.""" self.load_existing_projects() def load_existing_projects(self): projects_folder = os.path.join(RESOURCES_FOLDER, "projects") archive_folder = os.path.join(RESOURCES_FOLDER, "trip_archive") if not os.path.exists(projects_folder): os.makedirs(projects_folder) if not os.path.exists(archive_folder): os.makedirs(archive_folder) self.ids.projects_list.clear_widgets() for project in os.listdir(projects_folder): row = BoxLayout( orientation="horizontal", size_hint_y=None, height=44, spacing=6, padding=(8, 6) ) from kivy.graphics import Color, Line, RoundedRectangle with row.canvas.before: Color(0.11, 0.10, 0.15, 1) row.bg_rect = RoundedRectangle(pos=row.pos, size=row.size, radius=[6]) Color(0.341, 0.235, 0.980, 1) row.border_line = Line(rounded_rectangle=[row.x, row.y, row.width, row.height, 6], width=1) # Use a closure to bind the correct row instance def make_update_bg_rect(r): def update_bg_rect(instance, value): r.bg_rect.pos = r.pos r.bg_rect.size = r.size r.border_line.rounded_rectangle = [r.x, r.y, r.width, r.height, 6] return update_bg_rect row.bind(pos=make_update_bg_rect(row), size=make_update_bg_rect(row)) project_label = Label( text=project, size_hint_x=0.64, color=(1, 1, 1, 1), font_size=15, shorten=True, shorten_from='right' ) edit_button = IconButton( source="resources/images/edit.png", size_hint_x=0.18, allow_stretch=True, keep_ratio=True ) edit_button.bind(on_press=lambda instance, p=project: self.edit_project(p)) delete_button = IconButton( source="resources/images/delete.png", size_hint_x=0.18, allow_stretch=True, keep_ratio=True ) delete_button.bind(on_press=lambda instance, p=project: self.confirm_delete_project(p)) row.add_widget(project_label) row.add_widget(edit_button) row.add_widget(delete_button) self.ids.projects_list.add_widget(row) def open_project(self, project_name): """Handle opening an existing project/trip.""" print(f"Opening project: {project_name}") self.ids.result_label.text = f"Opened project: {project_name}" def create_new_project(self): """Navigate to the GetTripFromServer screen to create a new project/trip.""" self.manager.current = "get_trip_from_server" def edit_project(self, project_name): # Set the project name on the CreateAnimationScreen before switching create_anim_screen = self.manager.get_screen("create_animation") create_anim_screen.project_name = project_name self.manager.current = "create_animation" # delete or archive project def confirm_delete_project(self, project_name): from kivy.uix.popup import Popup from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.label import Label layout = BoxLayout(orientation='vertical', spacing=10, padding=10) label = Label(text=f"Delete project '{project_name}'?\nChoose an option:") btn_delete = Button(text="Delete Completely", background_color=(1, 0, 0, 1)) btn_archive = Button(text="Archive Trip", background_color=(0.341, 0.235, 0.980, 1)) btn_cancel = Button(text="Cancel") popup = Popup(title="Delete Project", content=layout, size_hint=(None, None), size=(400, 250), auto_dismiss=False) layout.add_widget(label) layout.add_widget(btn_delete) layout.add_widget(btn_archive) layout.add_widget(btn_cancel) def do_delete(instance): self.delete_project(project_name) popup.dismiss() self.load_existing_projects() def do_archive(instance): self.archive_project(project_name) popup.dismiss() self.load_existing_projects() btn_delete.bind(on_press=do_delete) btn_archive.bind(on_press=do_archive) btn_cancel.bind(on_press=lambda x: popup.dismiss()) popup.open() def delete_project(self, project_name): import shutil folder_path = os.path.join(RESOURCES_FOLDER, "projects", project_name) if os.path.exists(folder_path): shutil.rmtree(folder_path) def archive_project(self, project_name): import shutil src_file = os.path.join(RESOURCES_FOLDER, "projects", project_name, "positions.json") archive_folder = os.path.join(RESOURCES_FOLDER, "trip_archive") if not os.path.exists(archive_folder): os.makedirs(archive_folder) dst_file = os.path.join(archive_folder, f"{project_name}.json") if os.path.exists(src_file): shutil.copy2(src_file, dst_file) # Optionally, delete the project folder after archiving self.delete_project(project_name)