import kivy from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen import os import json from kivy.clock import Clock from kivy.properties import StringProperty, NumericProperty, AliasProperty from utils import ( generate_key, load_key, encrypt_data, decrypt_data, check_server_settings, save_server_settings, test_connection, get_devices_from_server, save_route_to_file, fetch_positions_for_selected_day, process_preview_util, optimize_route_entries_util ) from datetime import date from kivy.uix.popup import Popup from kivy.uix.gridlayout import GridLayout from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from threading import Thread from kivy.clock import mainthread from kivy.uix.image import Image from kivy.uix.behaviors import ButtonBehavior from kivy.uix.progressbar import ProgressBar from config import RESOURCES_FOLDER, CREDENTIALS_FILE from selenium import webdriver from selenium.webdriver.chrome.options import Options from PIL import Image import time from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from PIL import Image import time import os import math from kivy.uix.filechooser import FileChooserIconView from kivy.uix.textinput import TextInput from widgets.pause_edit_popup import open_pauses_popup class CreateAnimationScreen(Screen): project_name = StringProperty("") preview_html_path = StringProperty("") # Path to the HTML file for preview preview_image_path = StringProperty("") # Add this line preview_image_version = NumericProperty(0) # Add this line def get_preview_image_source(self): project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name) img_path = os.path.join(project_folder, "preview.png") if os.path.exists(img_path): return img_path return "resources/images/track.png" preview_image_source = AliasProperty( get_preview_image_source, None, bind=['project_name', 'preview_image_version'] ) def on_pre_enter(self): # Update the route entries label with the actual number of entries project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name) positions_path = os.path.join(project_folder, "positions.json") count = 0 if os.path.exists(positions_path): with open(positions_path, "r") as f: try: positions = json.load(f) count = len(positions) except Exception: count = 0 self.ids.route_entries_label.text = f"Your route has {count} entries," def open_rename_popup(self): from kivy.uix.popup import Popup from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.textinput import TextInput from kivy.uix.label import Label layout = BoxLayout(orientation='vertical', spacing=10, padding=10) label = Label(text="Enter new project name:") input_field = TextInput(text=self.project_name, multiline=False) btn_save = Button(text="Save", background_color=(0.008, 0.525, 0.290, 1)) btn_cancel = Button(text="Cancel") layout.add_widget(label) layout.add_widget(input_field) layout.add_widget(btn_save) layout.add_widget(btn_cancel) popup = Popup( title="Rename Project", content=layout, size_hint=(0.92, None), size=(0, 260), auto_dismiss=False ) def do_rename(instance): new_name = input_field.text.strip() if new_name and new_name != self.project_name: if self.rename_project_folder(self.project_name, new_name): self.project_name = new_name popup.dismiss() self.on_pre_enter() # Refresh label else: label.text = "Rename failed (name exists?)" else: label.text = "Please enter a new name." btn_save.bind(on_press=do_rename) btn_cancel.bind(on_press=lambda x: popup.dismiss()) popup.open() def rename_project_folder(self, old_name, new_name): import os old_path = os.path.join(RESOURCES_FOLDER, "projects", old_name) new_path = os.path.join(RESOURCES_FOLDER, "projects", new_name) if os.path.exists(old_path) and not os.path.exists(new_path): os.rename(old_path, new_path) return True return False def optimize_route_entries(self): # Create the popup and UI elements layout = BoxLayout(orientation='vertical', spacing=10, padding=10) label = Label(text="Processing route entries...") progress = ProgressBar(max=100, value=0) layout.add_widget(label) layout.add_widget(progress) popup = Popup( title="Optimizing Route", content=layout, size_hint=(0.92, None), size=(0, 260), auto_dismiss=False ) popup.open() # Now call the utility function with these objects optimize_route_entries_util( self.project_name, RESOURCES_FOLDER, label, progress, popup, Clock, on_save=lambda: self.on_pre_enter() ) def preview_route(self): # Show processing popup layout = BoxLayout(orientation='vertical', spacing=10, padding=10) label = Label(text="Processing route preview...") progress = ProgressBar(max=100, value=0) layout.add_widget(label) layout.add_widget(progress) popup = Popup( title="Previewing Route", content=layout, size_hint=(0.8, None), size=(0, 180), auto_dismiss=False ) popup.open() def set_preview_image_path(path): self.preview_image_path = path self.preview_image_version += 1 # Force AliasProperty to update self.property('preview_image_source').dispatch(self) self.ids.preview_image.reload() # Schedule the processing function Clock.schedule_once( lambda dt: process_preview_util( self.project_name, RESOURCES_FOLDER, label, progress, popup, self.ids.preview_image, set_preview_image_path, Clock ), 0.5 ) def open_pauses_popup(self): open_pauses_popup(self, self.project_name, RESOURCES_FOLDER, on_save_callback=self.on_pre_enter)