updated to view frame

This commit is contained in:
2025-06-06 11:07:35 +03:00
parent 29126f8d92
commit fca26d6557
9 changed files with 9022 additions and 23399 deletions

170
main.py
View File

@@ -20,6 +20,7 @@ from threading import Thread
from kivy.clock import mainthread from kivy.clock import mainthread
from kivy.uix.image import Image from kivy.uix.image import Image
from kivy.uix.behaviors import ButtonBehavior from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.progressbar import ProgressBar
kivy.require("2.0.0") kivy.require("2.0.0")
from kivy.core.window import Window from kivy.core.window import Window
@@ -90,6 +91,7 @@ class SettingsScreen(Screen):
self.manager.current = "home" self.manager.current = "home"
except Exception as e: except Exception as e:
self.ids.result_label.text = f"Failed to save settings: {str(e)}" self.ids.result_label.text = f"Failed to save settings: {str(e)}"
# get trip from server screen
class GetTripFromServer(Screen): class GetTripFromServer(Screen):
server_info_text = StringProperty("LOADING DATA...") server_info_text = StringProperty("LOADING DATA...")
@@ -348,7 +350,7 @@ class GetTripFromServer(Screen):
"""Handle the Get trip server data button press.""" """Handle the Get trip server data button press."""
selected_device = self.ids.devices_spinner.text selected_device = self.ids.devices_spinner.text
start_date = self.ids.start_date_picker_button.text start_date = self.ids.start_date_picker_button.text
end_date = self.ids.end_date_picker.text end_date = self.ids.end_date_picker_button.text
if selected_device == "Loading devices..." or selected_device == "No devices found": if selected_device == "Loading devices..." or selected_device == "No devices found":
print("No valid device selected.") print("No valid device selected.")
@@ -378,7 +380,7 @@ class GetTripFromServer(Screen):
settings = check_server_settings() settings = check_server_settings()
device_name = self.ids.devices_spinner.text device_name = self.ids.devices_spinner.text
start_date = self.ids.start_date_picker_button.text start_date = self.ids.start_date_picker_button.text
end_date = self.ids.end_date_picker.text end_date = self.ids.end_date_picker_button.text
start_hour = self.ids.start_hour_button.text start_hour = self.ids.start_hour_button.text
end_hour = self.ids.end_hour_button.text end_hour = self.ids.end_hour_button.text
@@ -451,7 +453,6 @@ class RegisterScreen(Screen):
self.ids.result_label.text = "User created successfully!" self.ids.result_label.text = "User created successfully!"
# Navigate back to the login screen # Navigate back to the login screen
self.manager.current = "login" self.manager.current = "login"
def user_exists(self, username, email): def user_exists(self, username, email):
"""Check if a username or email already exists in the credentials.enc file.""" """Check if a username or email already exists in the credentials.enc file."""
try: try:
@@ -469,10 +470,21 @@ class RegisterScreen(Screen):
class CreateAnimationScreen(Screen): class CreateAnimationScreen(Screen):
project_name = StringProperty("") project_name = StringProperty("")
preview_html_path = StringProperty("") # Path to the HTML file for preview
def on_pre_enter(self): def on_pre_enter(self):
# This will be called when the screen is shown # Update the route entries label with the actual number of entries
pass 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): def open_rename_popup(self):
from kivy.uix.popup import Popup from kivy.uix.popup import Popup
@@ -514,6 +526,154 @@ class CreateAnimationScreen(Screen):
return True return True
return False return False
def optimize_route_entries(self):
# Show popup with progress bar
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()
def process_entries(dt):
project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name)
positions_path = os.path.join(project_folder, "positions.json")
if not os.path.exists(positions_path):
label.text = "positions.json not found!"
progress.value = 100
return
with open(positions_path, "r") as f:
positions = json.load(f)
# Detect duplicate positions at the start
start_remove = 0
if positions:
first = positions[0]
for pos in positions:
if pos['latitude'] == first['latitude'] and pos['longitude'] == first['longitude']:
start_remove += 1
else:
break
if start_remove > 0:
start_remove -= 1
# Detect duplicate positions at the end
end_remove = 0
if positions:
last = positions[-1]
for pos in reversed(positions):
if pos['latitude'] == last['latitude'] and pos['longitude'] == last['longitude']:
end_remove += 1
else:
break
if end_remove > 0:
end_remove -= 1
progress.value = 100
label.text = (
f"Entries removable at start: {start_remove}\n"
f"Entries removable at end: {end_remove}"
)
btn_save = Button(text="Save optimized file", background_color=(0.008, 0.525, 0.290, 1))
btn_cancel = Button(text="Cancel")
btn_box = BoxLayout(orientation='horizontal', spacing=10, size_hint_y=None, height=44)
btn_box.add_widget(btn_save)
btn_box.add_widget(btn_cancel)
layout.add_widget(btn_box)
def save_optimized(instance):
new_positions = positions[start_remove:len(positions)-end_remove if end_remove > 0 else None]
with open(positions_path, "w") as f:
json.dump(new_positions, f, indent=2)
label.text = "File optimized and saved!"
btn_save.disabled = True
btn_cancel.disabled = True
def close_and_refresh(dt):
popup.dismiss()
self.on_pre_enter() # Refresh the screen
Clock.schedule_once(close_and_refresh, 1)
btn_save.bind(on_press=save_optimized)
btn_cancel.bind(on_press=lambda x: popup.dismiss())
Clock.schedule_once(process_entries, 0.5)
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 process_preview(dt):
try:
import folium
import webbrowser
project_folder = os.path.join(RESOURCES_FOLDER, "projects", self.project_name)
positions_path = os.path.join(project_folder, "positions.json")
html_path = os.path.join(project_folder, "preview.html")
if not os.path.exists(positions_path):
label.text = "positions.json not found!"
progress.value = 100
return
with open(positions_path, "r") as f:
positions = json.load(f)
if not positions:
label.text = "No positions to preview."
progress.value = 100
return
# Get coordinates
coords = [(pos['latitude'], pos['longitude']) for pos in positions]
# Center map on first point
m = folium.Map(location=coords[0], zoom_start=14)
folium.PolyLine(coords, color="blue", weight=4.5, opacity=1).add_to(m)
folium.Marker(coords[0], tooltip="Start", icon=folium.Icon(color="green")).add_to(m)
folium.Marker(coords[-1], tooltip="End", icon=folium.Icon(color="red")).add_to(m)
m.save(html_path)
# Set the path for the WebView
self.preview_html_path = "file://" + os.path.abspath(html_path)
label.text = "Preview ready!"
progress.value = 100
def close_popup(dt):
popup.dismiss()
Clock.schedule_once(close_popup, 1)
except Exception as e:
label.text = f"Error: {e}"
progress.value = 100
def close_popup(dt):
popup.dismiss()
Clock.schedule_once(close_popup, 2)
Clock.schedule_once(process_preview, 0.5)
class HomeScreen(Screen): class HomeScreen(Screen):
def on_pre_enter(self): def on_pre_enter(self):
"""Load existing projects/trips when the screen is entered.""" """Load existing projects/trips when the screen is entered."""

View File

@@ -1,2 +1,5 @@
kivy kivy
cryptography cryptography
kiwy-garden
folium
webview

View File

@@ -1 +1 @@
gAAAAABoQZq2xnxplxk3VFNb72evhmJ-mN3KLdQxrLvjkV_j4fzn_x1Lp2wxx3lZcQ0D6VYPPX5TVlKIcSxL3TMApYdxSONz_Gjj8yx7Fbn_7z5UO8dDVjOtR7-eVnyyCCFVeb6wmz47 gAAAAABoQpPZACNsq8I-7nR2jxmpdGK7_yMb0uOaFZp4j21eRvFiCZ0VnPUx8t331lh-TDHUBEfM_sLVdo0ZmZY9DjjVVDr4T3uJx8HwzZLVZmj9jiy8ICtau6OaPvk8Q_RYTAbMXqi7

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -575,8 +575,9 @@
font_size: 22 font_size: 22
color: 1, 1, 1, 1 color: 1, 1, 1, 1
size_hint_y: None size_hint_y: None
height: 36 height: 20
# Rename frame (already present)
BoxLayout: BoxLayout:
orientation: "horizontal" orientation: "horizontal"
size_hint_y: None size_hint_y: None
@@ -591,10 +592,13 @@
size: self.size size: self.size
Label: Label:
text: "Edit or change the name of the project" text: "Edit or change\nthe name of the project"
font_size: 16 font_size: 16
color: 1, 1, 1, 1 color: 1, 1, 1, 1
size_hint_x: 0.7 size_hint_x: 0.7
halign: "left"
valign: "middle"
text_size: self.size
Button: Button:
text: "Rename" text: "Rename"
@@ -604,6 +608,101 @@
color: 1, 1, 1, 1 color: 1, 1, 1, 1
on_press: root.open_rename_popup() on_press: root.open_rename_popup()
# New optimize route frame
BoxLayout:
orientation: "horizontal"
size_hint_y: None
height: 60
padding: [10, 10, 10, 10]
spacing: 10
canvas.before:
Color:
rgba: 0.15, 0.15, 0.18, 1
Rectangle:
pos: self.pos
size: self.size
Label:
id: route_entries_label
text: "Your route has [number of entries]"
font_size: 16
color: 1, 1, 1, 1
size_hint_x: 0.7
halign: "left"
valign: "middle"
text_size: self.size
Button:
text: "Optimize\ntrip"
size_hint_x: 0.3
font_size: 16
background_color: 0.008, 0.525, 0.290, 1
color: 1, 1, 1, 1
halign: "center"
valign: "middle"
text_size: self.size
on_press: root.optimize_route_entries()
# Preview frame
BoxLayout:
orientation: "horizontal"
size_hint_y: None
height: 60
padding: [10, 10, 10, 10]
spacing: 10
canvas.before:
Color:
rgba: 0.15, 0.15, 0.18, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "Preview your route"
font_size: 16
color: 1, 1, 1, 1
size_hint_x: 0.7
halign: "left"
valign: "middle"
text_size: self.size
Button:
text: "Preview"
size_hint_x: 0.3
font_size: 16
background_color: 0.341, 0.235, 0.980, 1
color: 1, 1, 1, 1
on_press: root.preview_route()
# HTML preview frame
BoxLayout:
orientation: "vertical"
size_hint_y: None
height: 220
padding: [10, 10, 10, 10]
spacing: 10
canvas.before:
Color:
rgba: 0.13, 0.13, 0.15, 1
Rectangle:
pos: self.pos
size: self.size
# Use Kivy garden's WebView if available, else fallback to Image
WebView:
id: html_preview
url: root.preview_html_path if root.preview_html_path else ""
size_hint: 1, 1
# If WebView is not available, comment this and use Image below
# If you don't have WebView, use this as a fallback:
# Image:
# id: html_preview_img
# source: "resources/images/track.png"
# allow_stretch: True
# keep_ratio: True
# size_hint: 1, 1
Widget: Widget:
size_hint_y: 1 size_hint_y: 1