Untitled
class WasteAlertScreen(ctk.CTkToplevel): def __init__(self, parent, waste_type: str, color: str, dark_mode: bool, progress_circle=None, language='EN'): super().__init__(parent) self.waste_type = waste_type self.language = language self.progress_circle = progress_circle self.dark_mode = dark_mode # Make it fullscreen and disable all close operations self.overrideredirect(True) self.geometry(f"{self.winfo_screenwidth()}x{self.winfo_screenheight()}+0+0") self.protocol("WM_DELETE_WINDOW", lambda: None) self.attributes('-topmost', True) # Set background color based on dark mode bg_color = '#1c1c1e' if dark_mode else '#f5f5f7' border_color = '#2c2c2e' if dark_mode else '#e5e5e7' # Matches the ring color self.configure(fg_color=bg_color) # Create main container with padding self.container = ctk.CTkFrame(self, fg_color=bg_color, corner_radius=0) self.container.pack(fill='both', expand=True, padx=30, pady=30) # Add a border around the alert box self.border_frame = ctk.CTkFrame(self.container, fg_color=border_color, corner_radius=10) self.border_frame.pack(fill='both', expand=True, padx=10, pady=10) # Create colored alert box inside the border self.alert_box = ctk.CTkFrame(self.border_frame, fg_color=color, corner_radius=8) self.alert_box.pack(fill='both', expand=True, padx=5, pady=5) # Determine text color based on waste type and dark mode text_color = '#000000' if waste_type in ["Gelber Sack", "Recycling"] and dark_mode else ('#ffffff' if dark_mode else '#000000') # Get the translated waste type name translated_waste_type = waste_type for de_key, en_value in TRANSLATIONS['EN'].items(): if en_value == waste_type and de_key in TRANSLATIONS['DE']: translated_waste_type = TRANSLATIONS[language][de_key] break # Add the message label with correct translation message_text = TRANSLATIONS[language]['bin_full_message'].format(waste_type=translated_waste_type) self.message_label = ctk.CTkLabel(self.alert_box, text=message_text, font=('Dongle', 30), text_color=text_color) self.message_label.place(relx=0.5, rely=0.35, anchor='center') # Add icon try: is_light_bg = waste_type in ["Gelber Sack", "Recycling"] or not dark_mode icon_suffix = "-b" if is_light_bg else "-w" icon_image = ctk.CTkImage( light_image=Image.open(f"icons/circle-alert{icon_suffix}.png"), dark_image=Image.open(f"icons/circle-alert{icon_suffix}.png"), size=(55, 55) ) self.icon_button = ctk.CTkButton( self.alert_box, image=icon_image, text="", width=60, height=60, fg_color="transparent", hover_color=color, command=self.handle_empty_bin ) self.icon_button.place(relx=0.5, rely=0.55, anchor='center') except Exception as e: print(f"Error loading icon: {e}") self.icon_button = ctk.CTkButton( self.alert_box, text="?", width=60, height=60, fg_color="transparent", hover_color=color, command=self.handle_empty_bin ) self.icon_button.place(relx=0.5, rely=0.55, anchor='center') def handle_empty_bin(self): if not self.progress_circle: self.after(100, self.destroy) return # Find existing TurntableController instance turntable = None root = self.winfo_toplevel() for widget in root.winfo_children(): if isinstance(widget, ctk.CTkFrame): # Main frame for child in widget.winfo_children(): if isinstance(child, ClassificationPrompt): if hasattr(child, 'turntable'): turntable = child.turntable break if not turntable: print("Error: Turntable controller not found") self.after(100, self.destroy) return if not turntable.is_initialized: # Show initialization message MessageDialog( self.winfo_toplevel(), TRANSLATIONS[self.language]['please_wait'], self.dark_mode ) return # Close current alert screen self.destroy() # Create loading screen loading_screen = LoadingScreen( self.winfo_toplevel(), message=TRANSLATIONS[self.language]['calibrating'], dark_mode=self.dark_mode, language=self.language ) def perform_measurement(): try: # Move turntable to selected bin turntable.move_to_bin(self.progress_circle.bin_id) # Wait for movement queue to be empty (movement complete) turntable.movement_queue.join() # Measure fill level using hardware controller fill_level = turntable.hardware.measure_fill_level() # Update JSON with measured fill level if fill_level is not None: levels = load_fill_levels() levels[self.progress_circle.bin_id] = float(fill_level) save_fill_levels(levels) # Update main window circles CircularProgress.update_all_instances() # Move back to home position turntable.move_to_home() # Schedule UI updates on main thread root.after(0, lambda: handle_measurement_complete(fill_level)) except Exception as e: print(f"Error during measurement: {e}") root.after(0, loading_screen.destroy) root.after(0, lambda: MessageDialog( root, "Error measuring fill level. Please try again.", self.dark_mode )) def handle_measurement_complete(fill_level): loading_screen.destroy() if fill_level is not None: if fill_level < 20: # Consider bin empty if less than 20% full print(f"{self.progress_circle.bin_id} verified as emptied - new fill level: {fill_level}%") MessageDialog( root, f"Bin verified as emptied - {fill_level:.1f}% full", self.dark_mode ) self.progress_circle._alert_shown = False else: print(f"{self.progress_circle.bin_id} may not be fully emptied - fill level: {fill_level}%") MessageDialog( root, f"Warning: Bin may not be fully emptied - {fill_level:.1f}% full", self.dark_mode ) # Start measurement in separate thread thread = threading.Thread(target=perform_measurement) thread.daemon = True thread.start()
Leave a Comment