Untitled

 avatar
unknown
plain_text
24 days ago
8.0 kB
3
Indexable
class ManualRotationScreen(ctk.CTkToplevel):
    def __init__(self, parent, dark_mode: bool, language='EN'):
        super().__init__(parent)
        self.language = getattr(parent, 'LANGUAGE', 'EN')
        
        # 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>", lambda e: self.destroy())
        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)

    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.destroy()

    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()

class RotationCircleButton(CircularProgress):
    def __init__(self, parent, bin_id, command=None, size=200, language='EN', **kwargs):
        # Calculate base_color based on parent's dark mode
        parent_dark_mode = getattr(parent.winfo_toplevel(), 'DARK_MODE', False)
        base_color = '#141416' if parent_dark_mode else '#ebebed'
        
        super().__init__(
            parent, 
            bin_id=bin_id, 
            size=size, 
            base_color=base_color
        )
        
        # Configure the canvas background to match the base color
        self.configure(bg=base_color)
        
        self.command = command
        self.language = language
        self.last_press_time = 0
        self.press_cooldown = 3.0  # 3 second cooldown
        self.can_press = True
        
        # Override bin colors to use grey scheme
        self.bin_config = {
            'id': bin_id,
            'name': self.bin_config['name'],
            'color': '#e5e5ea' if parent_dark_mode else '#8e8e93',
            'color_dark': '#8e8e93' if parent_dark_mode else '#e5e5ea',
            'is_default': True
        }
        
        # Unbind parent class events and bind our own
        self.unbind('<Button-1>')
        self.unbind('<ButtonRelease-1>')
        self.bind('<Button-1>', self._handle_click)
        self.bind('<ButtonRelease-1>', self._handle_release)

    def _handle_click(self, event):
        current_time = time.time()
        if self.can_press and current_time - self.last_press_time >= self.press_cooldown:
            self.is_pressed = True
            self.press_animation_active = True
            self.can_press = False
            self.last_press_time = current_time
            
            if self.command:
                self.after(100, self.command)
                
            self.after(int(self.press_cooldown * 1000), self._enable_press)

    def _handle_release(self, event):
        self.on_release(event)
        
    def _enable_press(self):
        """Re-enable press after cooldown"""
        self.can_press = True
            
    def set_dark_mode(self, is_dark):
        base_color = '#141416' if is_dark else '#ebebed'
        self.configure(bg=base_color)
        # Update bin colors when dark mode changes
        self.bin_config['color'] = '#e5e5ea' if is_dark else '#8e8e93'
        self.bin_config['color_dark'] = '#8e8e93' if is_dark else '#e5e5ea'
        super().set_dark_mode(is_dark)
Editor is loading...
Leave a Comment