Untitled

 avatar
unknown
plain_text
5 months ago
6.8 kB
4
Indexable
class SettingsMenu(ctk.CTkFrame):
    def __init__(self, parent, dark_mode):
        # Calculate window dimensions
        window_width = parent.winfo_width()
        window_height = parent.winfo_height()
        
        # Initialize with required dimensions
        super().__init__(
            parent, 
            fg_color='#1c1c1e' if dark_mode else '#f5f5f7',
            width=window_width,
            height=window_height
        )
        
        self.parent = parent
        self.dark_mode = dark_mode
        self.is_open = False
        self.animation_running = False
        self.current_width = 0
        self.target_width = window_width  # Make menu cover full width
        
        # Add border color based on dark mode
        self.border_color = '#2c2c2e' if dark_mode else '#e5e5e7'
        self.configure(border_width=2, border_color=self.border_color)
        
        # Place the frame initially off-screen
        self.place(relx=1, rely=0, anchor='ne')
        
        # Add menu content
        self.create_menu_content()
        
        # Create settings button
        try:
            is_light_bg = not dark_mode
            icon_suffix = "-b" if is_light_bg else "-w"
            
            icon_image = ctk.CTkImage(
                light_image=Image.open(f"icons/settings{icon_suffix}.png"),
                dark_image=Image.open(f"icons/settings{icon_suffix}.png"),
                size=(30, 30)
            )
            self.settings_button = ctk.CTkButton(
                self.parent,
                image=icon_image,
                text="",
                width=30,
                height=30,
                fg_color="transparent",
                hover_color='#2c2c2e' if dark_mode else '#e5e5e7',
                command=self.toggle_menu
            )
            self.settings_button.place(relx=0.97, rely=0.05, anchor='center')
        
        except Exception as e:
            print(f"Error loading settings icon: {e}")
            self.settings_button = ctk.CTkButton(
                self.parent,
                text="⚙",
                width=30,
                height=30,
                fg_color="transparent",
                hover_color='#2c2c2e' if dark_mode else '#e5e5e7',
                command=self.toggle_menu
            )
            self.settings_button.place(relx=0.97, rely=0.04, anchor='center')
        
        # Create semi-transparent overlay
        self.overlay = ctk.CTkFrame(
            self.parent,
            fg_color='black',
            corner_radius=0
        )
        # Set transparency through alpha
        self.overlay.configure(fg_color='gray10' if dark_mode else 'gray90')
        self.overlay.attributes('-alpha', 0.1)  # Set transparency level
        self.overlay.bind("<Button-1>", self.close_menu)

    def create_menu_content(self):
        """Create the content of the settings menu"""
        # Title
        title = ctk.CTkLabel(
            self,
            text="Settings",
            font=("Dongle", 24, "bold"),
            text_color='white' if self.dark_mode else 'black'
        )
        title.pack(pady=(20, 10), padx=20, anchor='w')
        
        # Create a frame for the content
        content_frame = ctk.CTkFrame(
            self,
            fg_color="transparent",
        )
        content_frame.pack(fill='both', expand=True, padx=20, pady=10)
        
        # Add sections with separators
        sections = [
            "General Settings",
            "User Preferences",
            "System Configuration",
            "Display Options",
            "Language Settings",
            "Security Settings",
            "About"
        ]
        
        for i, text in enumerate(sections):
            # Add separator before text (except for first item)
            if i > 0:
                separator = ctk.CTkFrame(
                    content_frame,
                    height=2,
                    fg_color=self.border_color
                )
                separator.pack(fill='x', pady=(15, 15))
            
            # Add text
            label = ctk.CTkLabel(
                content_frame,
                text=text,
                font=("Dongle", 18),
                text_color='white' if self.dark_mode else 'black'
            )
            label.pack(anchor='w', pady=5)
    
    def disable_all_buttons(self):
        # Disable all buttons and sliders in the main window
        for widget in self.parent.winfo_children():
            if isinstance(widget, (ctk.CTkButton, ctk.CTkSlider)):
                widget.configure(state="disabled")
        # Keep settings button enabled
        self.settings_button.configure(state="normal")
    
    def enable_all_buttons(self):
        # Re-enable all buttons and sliders
        for widget in self.parent.winfo_children():
            if isinstance(widget, (ctk.CTkButton, ctk.CTkSlider)):
                widget.configure(state="normal")
    
    def toggle_menu(self):
        if not self.animation_running:
            if self.is_open:
                self.close_menu()
            else:
                self.open_menu()
    
    def open_menu(self, event=None):
        if not self.is_open and not self.animation_running:
            self.is_open = True
            self.animation_running = True
            self.disable_all_buttons()
            
            # Show overlay
            self.overlay.place(x=0, y=0, relwidth=1, relheight=1)
            self.lift()  # Bring menu to front
            self.animate_open()
    
    def close_menu(self, event=None):
        if self.is_open and not self.animation_running:
            self.is_open = False
            self.animation_running = True
            self.enable_all_buttons()
            self.overlay.place_forget()
            self.animate_closed()
    
    def animate_open(self):
        if self.current_width < self.target_width:
            self.current_width += 40
            x_pos = -self.current_width
            self.place(relx=1, rely=0, x=x_pos, y=0, anchor='ne')
            self.after(16, self.animate_open)
        else:
            self.current_width = self.target_width
            self.animation_running = False
    
    def animate_closed(self):
        if self.current_width > 0:
            self.current_width -= 40
            x_pos = -self.current_width
            self.place(relx=1, rely=0, x=x_pos, y=0, anchor='ne')
            self.after(16, self.animate_closed)
        else:
            self.current_width = 0
            self.animation_running = False
            self.place(relx=1, rely=0, anchor='ne')
Editor is loading...
Leave a Comment