Untitled

 avatar
unknown
plain_text
4 months ago
4.5 kB
2
Indexable
class LoadingScreen(ctk.CTkToplevel):
    def __init__(self, parent, message="", dark_mode=False, language='EN'):
        super().__init__(parent)
        
        # Basic setup
        self._destroyed = False
        
        # Window setup
        self.overrideredirect(True)
        self.geometry(f"{self.winfo_screenwidth()}x{self.winfo_screenheight()}+0+0")
        self.attributes('-topmost', True)
        
        # Colors
        bg_color = '#1c1c1e' if dark_mode else '#f5f5f7'
        text_color = 'white' if dark_mode else 'black'
        self.configure(fg_color=bg_color)
        
        # Create a single main frame
        self.main_frame = ctk.CTkFrame(
            self,
            fg_color=bg_color,
            corner_radius=0,
            width=self.winfo_screenwidth(),
            height=self.winfo_screenheight()
        )
        self.main_frame.pack(expand=True, fill="both")
        
        # Create a fixed-size center container
        self.center_container = ctk.CTkFrame(
            self.main_frame,
            fg_color=bg_color,
            width=600,
            height=400
        )
        self.center_container.place(relx=0.5, rely=0.5, anchor="center")
        self.center_container.pack_propagate(False)
        
        # GIF display area
        self.gif_label = ctk.CTkLabel(
            self.center_container,
            text="",
            width=200,
            height=200
        )
        self.gif_label.pack(pady=(40, 20))
        
        # Message container with fixed dimensions
        self.message_container = ctk.CTkFrame(
            self.center_container,
            fg_color=bg_color,
            width=550,  # Wide enough for long messages
            height=100  # Tall enough for wrapped text
        )
        self.message_container.pack(pady=0)
        self.message_container.pack_propagate(False)
        
        # Message label with proper wrapping
        self.message_label = ctk.CTkLabel(
            self.message_container,
            text=message,
            font=("Dongle", 32),
            text_color=text_color,
            wraplength=500  # Allow text to wrap within container
        )
        self.message_label.place(relx=0.5, rely=0.5, anchor="center")
        
        # Load and start animation
        self._setup_animation(dark_mode)
    
    def _setup_animation(self, dark_mode):
        try:
            suffix = "-w" if dark_mode else "-b"
            self.gif = Image.open(f"icons/loading{suffix}.gif")
            self.frames = []
            
            try:
                while True:
                    frame = self.gif.convert('RGBA')
                    frame = frame.resize((200, 200), Image.Resampling.LANCZOS)
                    ctk_frame = ctk.CTkImage(
                        light_image=frame,
                        dark_image=frame,
                        size=(200, 200)
                    )
                    self.frames.append(ctk_frame)
                    self.gif.seek(self.gif.tell() + 1)
            except EOFError:
                pass
            
            if self.frames:
                self.current_frame = 0
                self._animate()
                
        except Exception as e:
            print(f"Animation error: {e}")
    
    def _animate(self):
        if not self._destroyed and self.frames:
            try:
                self.gif_label.configure(image=self.frames[self.current_frame])
                self.current_frame = (self.current_frame + 1) % len(self.frames)
                self.after(50, self._animate)
            except Exception as e:
                print(f"Animation error: {e}")
    
    def update_message(self, message):
        """Update the message text safely"""
        if not self._destroyed:
            # Update message text
            self.message_label.configure(text=message)
            # Force UI update
            self.message_container.update_idletasks()
    
    def close(self):
        """Close the loading screen safely"""
        if not self._destroyed:
            self._destroyed = True
            self.destroy()

def show_loading_screen(parent, message="", duration=None, dark_mode=False, language='EN'):
    """Helper function to show loading screen"""
    screen = LoadingScreen(parent, message, dark_mode, language)
    if duration:
        screen.after(int(duration * 1000), screen.close)
    return screen
Editor is loading...
Leave a Comment