Untitled

 avatar
unknown
plain_text
13 days ago
6.7 kB
6
Indexable
class ManualRotationScreen(ctk.CTkToplevel):
    def __init__(self, parent, dark_mode: bool, language='EN', settings_menu=None):  # Add settings_menu parameter
        super().__init__(parent)
        self.language = getattr(parent, 'LANGUAGE', 'EN')
        self.settings_menu = settings_menu  # Store settings menu reference
        
        # Global cooldown flag
        self._global_cooldown = False
        
        # Use CircularProgress's class-level turntable reference
        self.turntable = CircularProgress._turntable
        self.bin_config = BinConfiguration()
        
        # 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 colors to match main screen
        self.dark_mode = dark_mode
        self.bg_color = '#1c1c1e' if dark_mode else '#f5f5f7'
        self.configure(fg_color=self.bg_color)

        # Create title label
        self.title_label = ctk.CTkLabel(
            self,
            text=TRANSLATIONS[self.language].get('manual_rotation', 'Manual Rotation'),
            font=("Dongle", 40, "bold"),
            text_color='white' if dark_mode else 'black'
        )
        self.title_label.place(relx=0.5, rely=0.18, anchor='center')
        
        # Create circles frame with transparent background
        self.circles_frame = ctk.CTkFrame(self, fg_color="transparent")
        self.circles_frame.place(relx=0.5, rely=0.5, anchor='center')
        
        # Add padding frame with transparent background
        self.padding_frame = ctk.CTkFrame(self.circles_frame, fg_color="transparent")
        self.padding_frame.pack(padx=50)
        
        # Create list to track circle widgets
        self.circle_widgets = []

        # Create Grey Circles for each bin
        for bin_config in self.bin_config.bins:
            container = ctk.CTkFrame(self.padding_frame, fg_color="transparent")
            container.pack(side='left', padx=15)

            progress = RotationCircleButton(
                container,
                bin_id=bin_config['id'],
                size=220,
                language=language,
                dark_mode=dark_mode,
                command=lambda bid=bin_config['id']: self._rotate_to_position(bid)
            )
            progress.pack()
            progress.set_dark_mode(dark_mode)
            
            # Store circle widgets
            self.circle_widgets.append(progress)

        # Add close button
        self.close_button = ctk.CTkLabel(
            self,
            text="×",  
            width=40,
            height=40,
            text_color='white' if dark_mode else 'black',
            font=("Arial", 32, "bold"),
            cursor="hand2"
        )
        self.close_button.place(relx=0.995, rely=0.01, anchor="ne")
        self.close_button.bind("<Button-1>", self.handle_close)
        self.close_button.bind("<Enter>", lambda e: self.close_button.configure(text_color="#ff3b30"))
        self.close_button.bind("<Leave>", lambda e: self.close_button.configure(
            text_color='white' if dark_mode else 'black'
        ))

        # Bind click event to the main window
        self.bind('<Button-1>', self.check_click_location)
        
        # Bind destruction event
        self.bind("<Destroy>", self.on_destroy)

    def handle_close(self, event=None):
        """Handle closing the screen"""
        if self.settings_menu and self.settings_menu.is_open:
            self.settings_menu.close_menu()
        self._enable_global_cooldown()
        self.destroy()

    def check_click_location(self, event):
        """Check if click is outside the circles"""
        clicked_widget = event.widget.winfo_containing(event.x_root, event.y_root)
        
        # Check if clicked widget is one of our circles or their containers
        for circle in self.circle_widgets:
            if clicked_widget is circle or clicked_widget in circle.winfo_children():
                return
                
        # If we get here, the click was outside the circles
        self.handle_close()

    def _enable_global_cooldown(self):
        """Enable global cooldown for button presses"""
        self._global_cooldown = True
        # Find all CircularProgress instances and disable them temporarily
        for instance in CircularProgress._instances:
            if not instance._destroyed:
                instance.can_press = False
                # Re-enable after delay
                instance.after(1000, lambda inst=instance: setattr(inst, 'can_press', True))

    def on_destroy(self, event):
        """Handle destruction of the window"""
        if event.widget is self:
            self._enable_global_cooldown()

    def _rotate_to_position(self, bin_id):
        """Rotate to the specified bin position"""
        print(f"Starting rotation to {bin_id}")
        
        if not self.turntable or not self.turntable.is_initialized:
            print("No turntable controller available or not initialized")
            MessageDialog(
                self.winfo_toplevel(),
                TRANSLATIONS[self.language].get('please_wait', 'Please wait'),
                self.dark_mode
            )
            return
            
        # Create loading screen
        loading_screen = LoadingScreen(
            self.winfo_toplevel(),
            message=TRANSLATIONS[self.language].get('moving_bin', 'Moving to position...'),
            dark_mode=self.dark_mode,
            language=self.language
        )
        
        def perform_rotation():
            try:
                # Calculate target position
                target_position = self.turntable.positions[bin_id]
                
                # Calculate and execute movement
                steps, direction = self.turntable._calculate_steps(target_position)
                self.turntable._move_motor(steps, direction)
                self.turntable.current_position = target_position
                
                # Close loading screen after movement completes
                self.after(500, loading_screen.close)
                
            except Exception as e:
                print(f"Error during rotation: {e}")
                self.after(0, loading_screen.close)
        
        # Run rotation in separate thread
        thread = threading.Thread(target=perform_rotation, daemon=True)
        thread.start()
Leave a Comment