Files
traccar_animation/screens/home_screen.py
2025-06-06 16:02:50 +03:00

152 lines
6.0 KiB
Python

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)