Untitled

 avatar
unknown
plain_text
2 months ago
7.8 kB
3
Indexable
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