: BoxLayout: orientation: "vertical" padding: [16, 24, 16, 16] spacing: 14 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size Widget: size_hint_y: 0.10 # Spacer at the top Image: source: "resources/images/track.png" # <-- updated path size_hint: (1, 0.28) # Smaller logo for phones allow_stretch: True keep_ratio: True Widget: size_hint_y: 0.05 # Spacer TextInput: id: username_input hint_text: "Username" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: password_input hint_text: "Password" multiline: False password: True font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 Widget: size_hint_y: 0.02 # Small spacer BoxLayout: orientation: "horizontal" size_hint_y: None height: 48 spacing: 10 Button: text: "Login" font_size: 18 size_hint_x: 0.5 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: root.login() Button: text: "Register" font_size: 18 size_hint_x: 0.5 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: app.root.current = "register" Widget: size_hint_y: 0.08 # Spacer Label: id: result_label text: "" font_size: 15 size_hint_y: None height: 28 color: 1, 1, 1, 1 : BoxLayout: orientation: "vertical" padding: [16, 24, 16, 16] spacing: 14 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size Widget: size_hint_y: 0.08 Image: source: "resources/images/track.png" size_hint: (1, 0.22) allow_stretch: True keep_ratio: True Label: text: "Register" font_size: 22 color: 1, 1, 1, 1 size_hint_y: None height: 36 TextInput: id: set_username_input hint_text: "Username" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: set_email_input hint_text: "Email" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: set_password_input hint_text: "Password" multiline: False password: True font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: confirm_password_input hint_text: "Confirm Password" multiline: False password: True font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 Widget: size_hint_y: 0.02 BoxLayout: orientation: "horizontal" size_hint_y: None height: 48 spacing: 10 Button: text: "Register" font_size: 18 size_hint_x: 0.5 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: root.create_user() Button: text: "Back" font_size: 18 size_hint_x: 0.5 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: app.root.current = "login" Widget: size_hint_y: 0.06 Label: id: result_label text: "" font_size: 15 size_hint_y: None height: 28 color: 1, 1, 1, 1 : BoxLayout: orientation: 'vertical' padding: [8, 8, 8, 8] spacing: 8 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 # Match app background Rectangle: pos: self.pos size: self.size Label: text: "Your Trips" font_size: 20 size_hint_y: None height: 40 color: 1, 1, 1, 1 ScrollView: do_scroll_x: False GridLayout: id: projects_list cols: 1 size_hint_y: None height: self.minimum_height spacing: 4 Button: text: "Create New Trip" size_hint_y: None height: 48 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 font_size: 16 on_press: root.create_new_project() : BoxLayout: orientation: "vertical" padding: [12, 0, 12, 12] spacing: 18 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size # Responsive Server info row BoxLayout: id: server_info_box orientation: 'horizontal' if self.width > 400 else 'vertical' size_hint_y: None height: 40 if self.width > 400 else 80 spacing: 10 padding: [10, 10, 10, 10] canvas.before: Color: rgba: root.server_box_color Rectangle: pos: self.pos size: self.size Label: id: server_info_label text: root.server_info_text font_size: 15 size_hint_x: 0.7 if server_info_box.orientation == 'horizontal' else 1 size_hint_y: 1 halign: 'left' valign: 'middle' text_size: self.size Button: text: "Settings" size_hint_x: 0.3 if server_info_box.orientation == 'horizontal' else 1 size_hint_y: 1 font_size: 15 background_color: 0.341, 0.235, 0.980, 1 on_press: app.root.current = "settings" # Device and date selection BoxLayout: orientation: "vertical" size_hint_y: None height: 300 spacing: 14 padding: 14 canvas.before: Color: rgba: 0.2, 0.2, 0.2, 1 Rectangle: pos: self.pos size: self.size Label: text: "Select device and date" font_size: 15 size_hint_y: None height: 22 Spinner: id: devices_spinner text: "Loading devices..." values: [] size_hint_y: None height: 38 font_size: 15 on_text: root.on_device_selected(self.text) BoxLayout: orientation: "horizontal" size_hint_y: None height: 38 spacing: 8 Label: text: "Start" font_size: 13 size_hint_x: 0.18 Button: id: start_date_picker_button text: "Start Date" size_hint_x: 0.42 font_size: 13 on_press: root.open_date_picker('start') Button: id: start_hour_button text: "00" size_hint_x: 0.18 font_size: 13 on_press: root.open_hour_picker('start') BoxLayout: orientation: "horizontal" size_hint_y: None height: 38 spacing: 8 Label: text: "End" font_size: 13 size_hint_x: 0.18 Button: id: end_date_picker_button text: "End Date" size_hint_x: 0.42 font_size: 13 on_press: root.open_date_picker('end') Button: id: end_hour_button text: "23" size_hint_x: 0.18 font_size: 13 on_press: root.open_hour_picker('end') # Responsive button row BoxLayout: id: trip_button_box orientation: 'horizontal' if self.width > 400 else 'vertical' size_hint_y: None height: 38 if self.width > 400 else 90 spacing: 10 Button: id: get_trip_data_button text: "Get trip data" font_size: 15 background_color: 0.341, 0.235, 0.980, 1 on_press: root.get_trip_server_data() # Route info and save BoxLayout: orientation: "vertical" size_hint_y: None height: 120 spacing: 14 padding: 14 canvas.before: Color: rgba: 0.15, 0.15, 0.15, 1 Rectangle: pos: self.pos size: self.size Label: id: points_count_label text: "Points: 0" font_size: 15 size_hint_y: None height: 24 BoxLayout: orientation: "horizontal" size_hint_y: None height: 38 spacing: 8 Label: text: "Route:" font_size: 15 size_hint_x: 0.25 TextInput: id: route_name_input hint_text: "Route name" multiline: False font_size: 15 size_hint_x: 0.5 # Responsive save button row BoxLayout: id: save_button_box orientation: 'horizontal' if self.width > 400 else 'vertical' size_hint_x: 0.25 size_hint_y: None height: 38 if self.width > 400 else 90 spacing: 10 Button: text: "Save" font_size: 15 background_color: 0.008, 0.525, 0.290, 1 on_press: root.save_route() # Result label Label: id: result_label text: "" font_size: 15 size_hint_y: None height: 28 # Add empty space before the back button Widget: size_hint_y: None height: 40 # Back button Button: text: "Back to Home" size_hint_y: None height: 48 font_size: 15 background_color: 0.341, 0.235, 0.980, 1 on_press: app.root.current = "home" : BoxLayout: orientation: "vertical" padding: [16, 24, 16, 16] spacing: 14 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size Image: source: "resources/images/track.png" size_hint: (1, 0.22) allow_stretch: True keep_ratio: True TextInput: id: server_url_input hint_text: "Traccar Server URL" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: username_input hint_text: "Username" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: password_input hint_text: "Password" multiline: False password: True font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 TextInput: id: token_input hint_text: "Token" multiline: False font_size: 18 height: 44 size_hint_y: None size_hint_x: 1 padding: [12, 12, 12, 12] background_normal: '' background_color: 0.15, 0.15, 0.18, 1 foreground_color: 1, 1, 1, 1 BoxLayout: orientation: "horizontal" size_hint_y: None height: 48 spacing: 10 Button: text: "Test Connection" font_size: 16 size_hint_x: 0.5 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: root.test_connection() Button: text: "Save Settings" font_size: 16 size_hint_x: 0.5 background_color: 0.008, 0.525, 0.290, 1 color: 1, 1, 1, 1 on_press: root.save_settings() Label: id: result_label text: "Waiting to test connection..." font_size: 15 size_hint_y: None height: 28 color: 1, 1, 1, 1 halign: "center" valign: "middle" text_size: self.size padding: [0, 8] Button: text: "Return to Home" size_hint_y: None height: 48 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 font_size: 16 on_press: app.root.current = "home" : BoxLayout: orientation: "vertical" padding: 20 spacing: 18 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size # Project title Label: text: root.project_name if root.project_name else "Create Animation" font_size: 22 color: 1, 1, 1, 1 size_hint_y: None height: 36 # Rename 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: "Edit or change\nthe name of the project" font_size: 16 color: 1, 1, 1, 1 size_hint_x: 0.7 halign: "left" valign: "middle" text_size: self.size Button: text: "Rename" 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.open_rename_popup() # 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() # Pauses frame BoxLayout: id: pauses_frame orientation: "horizontal" spacing: 10 padding: 10 size_hint_y: None height: 60 canvas.before: Color: rgba: 0.15, 0.15, 0.18, 1 Rectangle: pos: self.pos size: self.size Label: id: pauses_label text: "Pauses" font_size: 16 halign: "left" valign: "middle" color: 1, 1, 1, 1 size_hint_x: 0.7 text_size: self.width, None Button: id: pauses_edit_btn text: "Edit" size_hint_x: 0.3 width: 120 font_size: 16 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 on_press: root.open_pauses_popup() # Preview frame (label + button on first row, image on second row) BoxLayout: orientation: "vertical" size_hint_y: None height: 255 # Adjust as needed for your image size padding: [5, 5, 5, 5] spacing: 10 canvas.before: Color: rgba: 0.15, 0.15, 0.18, 1 Rectangle: pos: self.pos size: self.size BoxLayout: orientation: "horizontal" size_hint_y: None height: 30 spacing: 5 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() Image: id: preview_image source: root.preview_image_source allow_stretch: False keep_ratio: True size_hint_y: None height: 202 size_hint_x: 1 # Progressive 3D Animation 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: "Generate progressive 3D animation\nBuilds trip point by point" font_size: 16 color: 1, 1, 1, 1 size_hint_x: 0.7 halign: "left" valign: "middle" text_size: self.size Button: text: "Generate\n3D Trip" size_hint_x: 0.3 font_size: 14 background_color: 0.2, 0.8, 0.4, 1 color: 1, 1, 1, 1 halign: "center" valign: "middle" text_size: self.size on_press: root.generate_progressive_3d_animation() # Google Earth Animation 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: "Generate Google Earth flythrough\nCinematic aerial view" font_size: 16 color: 1, 1, 1, 1 size_hint_x: 0.7 halign: "left" valign: "middle" text_size: self.size Button: text: "Generate\nFlythrough" size_hint_x: 0.3 font_size: 14 background_color: 0.1, 0.8, 0.1, 1 color: 1, 1, 1, 1 halign: "center" valign: "middle" text_size: self.size on_press: root.generate_google_earth_animation() # Blender Animation 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: "Generate cinema-quality animation\nProfessional 3D rendering" font_size: 16 color: 1, 1, 1, 1 size_hint_x: 0.7 halign: "left" valign: "middle" text_size: self.size Button: text: "Generate\nCinema" size_hint_x: 0.3 font_size: 14 background_color: 0.9, 0.6, 0.2, 1 color: 1, 1, 1, 1 halign: "center" valign: "middle" text_size: self.size on_press: root.generate_blender_animation() Widget: size_hint_y: 1 Button: text: "Back to Home" size_hint_y: None height: 50 background_color: 0.341, 0.235, 0.980, 1 color: 1, 1, 1, 1 font_size: 16 on_press: app.root.current = "home" : BoxLayout: orientation: "vertical" spacing: 8 padding: 8 canvas.before: Color: rgba: 0.11, 0.10, 0.15, 1 Rectangle: pos: self.pos size: self.size