Make this more elegant and Modernvcombine the lists for videos and folder and show the type and also make this adaptable to all resolutions and window sizes  here is the code import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import os
import subprocess
import threading
import concurrent.futures
import queue
import sys

def select_input_folders():
    while True:
        folder = filedialog.askdirectory(title="Select Input Folder (Cancel to finish)")
        if folder:
            if folder not in input_folders:
                input_folders.append(folder)
                input_folders_listbox.insert(tk.END, folder)
            else:
                messagebox.showwarning("Duplicate Folder", f"The folder '{folder}' is already selected.")
        else:
            break

def remove_selected_folders():
    selected_indices = list(input_folders_listbox.curselection())
    selected_indices.reverse()  # Remove from the end to avoid index shifting
    for index in selected_indices:
        folder = input_folders_listbox.get(index)
        input_folders.remove(folder)
        input_folders_listbox.delete(index)

def select_input_videos():
    videos = filedialog.askopenfilenames(title="Select Video Files",
                                        filetypes=[("Video Files", "*.mp4 *.avi *.mov *.mkv *.flv *.wmv")])
    if videos:
        for video in videos:
            if video not in input_videos:
                input_videos.append(video)
                input_videos_listbox.insert(tk.END, video)
            else:
                messagebox.showwarning("Duplicate Video", f"The video '{video}' is already selected.")

def remove_selected_videos():
    selected_indices = list(input_videos_listbox.curselection())
    selected_indices.reverse()  # Remove from the end to avoid index shifting
    for index in selected_indices:
        video = input_videos_listbox.get(index)
        input_videos.remove(video)
        input_videos_listbox.delete(index)

def select_output_folder():
    folder = filedialog.askdirectory(title="Select Output Folder")
    if folder:
        output_folder_var.set(folder)
        output_entry.config(state='readonly')

def sanitize_name(name):
    """Sanitize the folder or file name to remove or replace problematic characters."""
    return "".join(c if c.isalnum() or c in (' ', '_', '-') else "_" for c in name).replace(" ", "_")

def process_videos_thread():
    """Run the video processing in a separate thread."""
    threading.Thread(target=process_videos, daemon=True).start()

def process_videos():
    output_folder = output_folder_var.get()

    if not input_folders and not input_videos:
        messagebox.showerror("Error", "Please select at least one input folder or video.")
        return
    if not output_folder:
        messagebox.showerror("Error", "Please select an output folder.")
        return

    # Get selected format
    selected_format = format_var.get().lower()
    if selected_format not in ['jpg', 'png']:
        messagebox.showerror("Error", "Please select a valid format (JPG or PNG).")
        return

    # Ensure the output directory exists
    os.makedirs(output_folder, exist_ok=True)

    # Disable the process button and input selection buttons to prevent multiple clicks
    set_buttons_state(tk.DISABLED)

    # Initialize progress bars
    total_tasks = len(input_folders) + len(input_videos)
    total_folders = len(input_folders)
    total_videos = len(input_videos)
    if total_tasks == 0:
        messagebox.showerror("Error", "No tasks to process.")
        set_buttons_state(tk.NORMAL)
        return

    progress_bar.config(maximum=total_tasks)
    progress_bar['value'] = 0
    status_label.config(text="Starting processing...")

    # Queues to receive progress updates
    progress_queue = queue.Queue()

    # Lists to collect errors
    errors = []

    # Define worker functions
    def worker_folder(folder):
        base_name = os.path.basename(os.path.normpath(folder))
        sanitized_base = sanitize_name(base_name)
        unique_output_dir = os.path.join(output_folder, f"{sanitized_base}_{base_name}")
        os.makedirs(unique_output_dir, exist_ok=True)
        try:
            # Run the video2image command with the unique output directory and selected format
            subprocess.run(
                ['video2image', '-i', folder, '-o', unique_output_dir, '-f', selected_format],
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            progress_queue.put(("success", f"Folder: {folder}"))
        except subprocess.CalledProcessError as e:
            error_msg = f"Failed to process folder: {folder}\nError: {e.stderr.decode().strip()}"
            progress_queue.put(("error", error_msg))
        except Exception as ex:
            error_msg = f"An unexpected error occurred while processing folder: {folder}\nError: {ex}"
            progress_queue.put(("error", error_msg))

    def worker_video(video):
        base_name = os.path.basename(video)
        name_without_ext = os.path.splitext(base_name)[0]
        sanitized_name = sanitize_name(name_without_ext)
        unique_output_dir = os.path.join(output_folder, f"{sanitized_name}_{name_without_ext}")
        os.makedirs(unique_output_dir, exist_ok=True)
        try:
            # Run the video2image command with the unique output directory and selected format
            subprocess.run(
                ['video2image', '-i', video, '-o', unique_output_dir, '-f', selected_format],
                check=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            progress_queue.put(("success", f"Video: {video}"))
        except subprocess.CalledProcessError as e:
            error_msg = f"Failed to process video: {video}\nError: {e.stderr.decode().strip()}"
            progress_queue.put(("error", error_msg))
        except Exception as ex:
            error_msg = f"An unexpected error occurred while processing video: {video}\nError: {ex}"
            progress_queue.put(("error", error_msg))

    # Create separate executors for folders and videos
    folder_executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
    video_executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)

    # Submit folder tasks
    folder_futures = [folder_executor.submit(worker_folder, folder) for folder in input_folders]

    # Submit video tasks
    video_futures = [video_executor.submit(worker_video, video) for video in input_videos]

    total_processed = 0

    # Function to periodically check the queue
    def check_queue():
        nonlocal total_processed
        try:
            while True:
                status, info = progress_queue.get_nowait()
                if status == "success":
                    progress_bar['value'] += 1
                    total_processed += 1
                    status_label.config(text=f"Processed: {info}")
                elif status == "error":
                    errors.append(info)
                    progress_bar['value'] += 1
                    total_processed += 1
                    status_label.config(text=f"Error: {info}")

                if total_processed >= total_tasks:
                    folder_executor.shutdown(wait=False)
                    video_executor.shutdown(wait=False)
                    finalize_processing()
        except queue.Empty:
            pass
        if total_processed < total_tasks:
            root.after(100, check_queue)

    # Start checking the queue
    root.after(100, check_queue)

    def finalize_processing():
        set_buttons_state(tk.NORMAL)
        if errors:
            error_message = "\n\n".join(errors)
            messagebox.showerror("Processing Completed with Errors", error_message)
        else:
            messagebox.showinfo("Success", "All videos and folders have been successfully processed.")
        progress_bar['value'] = 0
        status_label.config(text="Processing completed.")

def set_buttons_state(state):
    process_button.config(state=state)
    select_input_folders_button.config(state=state)
    select_input_videos_button.config(state=state)
    select_output_button.config(state=state)
    remove_folders_button.config(state=state if input_folders else tk.DISABLED)
    remove_videos_button.config(state=state if input_videos else tk.DISABLED)

# Initialize the main window
root = tk.Tk()
root.title("Video to Image Converter")
root.geometry("1000x700")
root.resizable(True, True)  # Allow resizing for better usability

# Egyptian Space Ascension Theme Colors
BACKGROUND_COLOR = "#0b0c10"  # Dark background
FRAME_COLOR = "#1f2833"
BUTTON_COLOR = "#c5c6c7"
TEXT_COLOR = "#66fcf1"
PROGRESS_COLOR = "#45a29e"

root.configure(bg=BACKGROUND_COLOR)

# Initialize the lists to store input folders and videos
input_folders = []
input_videos = []

# Variables to store output folder path and format selection
output_folder_var = tk.StringVar()
format_var = tk.StringVar(value="JPG")  # Default to JPG

# Style configuration
style = ttk.Style(root)
style.theme_use('clam')  # Use 'clam' for better customization

# Customize styles
style.configure("TButton",
                foreground=BACKGROUND_COLOR,
                background=BUTTON_COLOR,
                font=("Helvetica", 10, "bold"),
                borderwidth=1)
style.map("TButton",
          background=[('active', '#45a29e')])

style.configure("TLabel",
                foreground=TEXT_COLOR,
                background=BACKGROUND_COLOR,
                font=("Helvetica", 10))

style.configure("TLabelFrame",
                foreground=TEXT_COLOR,
                background=FRAME_COLOR,
                font=("Helvetica", 12, "bold"),
                labelbackground=FRAME_COLOR)

style.configure("Horizontal.TProgressbar",
                troughcolor=FRAME_COLOR,
                background=PROGRESS_COLOR)

# Define a custom style for readonly Entry
style.configure("Readonly.TEntry",
                fieldbackground=FRAME_COLOR,
                foreground=TEXT_COLOR)

# Frame for Input Folders
input_folders_frame = ttk.LabelFrame(root, text="Input Folders")
input_folders_frame.pack(fill="both", expand=True, padx=20, pady=10)

# Listbox to display selected input folders
input_folders_listbox = tk.Listbox(input_folders_frame, selectmode=tk.MULTIPLE, height=10, 
                                   bg=FRAME_COLOR, fg=TEXT_COLOR, selectbackground=PROGRESS_COLOR, selectforeground=BACKGROUND_COLOR)
input_folders_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0,5), pady=5)

# Scrollbar for the folders listbox
folders_scroll = ttk.Scrollbar(input_folders_frame, orient=tk.VERTICAL, command=input_folders_listbox.yview)
folders_scroll.pack(side=tk.RIGHT, fill=tk.Y)
input_folders_listbox.config(yscrollcommand=folders_scroll.set)

# Frame for Input Folders Buttons
input_folders_button_frame = ttk.Frame(root)
input_folders_button_frame.pack(fill='x', padx=20, pady=(0,10))

# Button to select input folders
select_input_folders_button = ttk.Button(input_folders_button_frame, text="Select Input Folders", command=select_input_folders)
select_input_folders_button.pack(side=tk.LEFT, padx=5, pady=5)

# Button to remove selected input folders
remove_folders_button = ttk.Button(input_folders_button_frame, text="Remove Selected Folders", command=remove_selected_folders, state=tk.DISABLED)
remove_folders_button.pack(side=tk.LEFT, padx=5, pady=5)

# Frame for Input Videos
input_videos_frame = ttk.LabelFrame(root, text="Input Videos")
input_videos_frame.pack(fill="both", expand=True, padx=20, pady=10)

# Listbox to display selected input videos
input_videos_listbox = tk.Listbox(input_videos_frame, selectmode=tk.MULTIPLE, height=10, 
                                  bg=FRAME_COLOR, fg=TEXT_COLOR, selectbackground=PROGRESS_COLOR, selectforeground=BACKGROUND_COLOR)
input_videos_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0,5), pady=5)

# Scrollbar for the videos listbox
videos_scroll = ttk.Scrollbar(input_videos_frame, orient=tk.VERTICAL, command=input_videos_listbox.yview)
videos_scroll.pack(side=tk.RIGHT, fill=tk.Y)
input_videos_listbox.config(yscrollcommand=videos_scroll.set)

# Frame for Input Videos Buttons
input_videos_button_frame = ttk.Frame(root)
input_videos_button_frame.pack(fill='x', padx=20, pady=(0,10))

# Button to select input videos
select_input_videos_button = ttk.Button(input_videos_button_frame, text="Select Input Videos", command=select_input_videos)
select_input_videos_button.pack(side=tk.LEFT, padx=5, pady=5)

# Button to remove selected input videos
remove_videos_button = ttk.Button(input_videos_button_frame, text="Remove Selected Videos", command=remove_selected_videos, state=tk.DISABLED)
remove_videos_button.pack(side=tk.LEFT, padx=5, pady=5)

# Frame for Output Folder
output_frame = ttk.LabelFrame(root, text="Output Folder")
output_frame.pack(fill="both", expand=True, padx=20, pady=10)

# Entry widget to display selected output folder with custom style
output_entry = ttk.Entry(output_frame, textvariable=output_folder_var, width=80, state='readonly', style="Readonly.TEntry")
output_entry.pack(side=tk.LEFT, padx=(0, 5), expand=True, fill=tk.X)

# Button to select output folder
select_output_button = ttk.Button(output_frame, text="Select Output Folder", command=select_output_folder)
select_output_button.pack(side=tk.LEFT, padx=5, pady=5)

# Frame for Format Selection
format_frame = ttk.LabelFrame(root, text="Select Format")
format_frame.pack(fill="both", expand=True, padx=20, pady=10)

# Dropdown menu for format selection
format_dropdown = ttk.Combobox(format_frame, textvariable=format_var, state="readonly",
                               values=["JPG", "PNG"], width=10, font=("Helvetica", 10))
format_dropdown.pack(padx=10, pady=10)
format_dropdown.current(0)  # Set default to JPG

# Progress Frame
progress_frame = ttk.Frame(root)
progress_frame.pack(fill='x', padx=20, pady=10)

progress_label = ttk.Label(progress_frame, text="Processing Progress:")
progress_label.pack(anchor='w')

progress_bar = ttk.Progressbar(progress_frame, orient='horizontal', length=960,
                               mode='determinate', style="Horizontal.TProgressbar")
progress_bar.pack(pady=5, fill='x')

# Status Label
status_label = ttk.Label(root, text="Ready.", relief='sunken', anchor='w')
status_label.pack(fill='x', padx=20, pady=(0,10), ipady=2)

# Process Button
process_button = ttk.Button(root, text="Process", command=process_videos_thread)
process_button.pack(pady=10, ipadx=10, ipady=5)

def on_input_folders_change(*args):
    """Enable or disable the remove folders button based on folder selection."""
    if input_folders:
        remove_folders_button.config(state=tk.NORMAL)
    else:
        remove_folders_button.config(state=tk.DISABLED)

def on_input_videos_change(*args):
    """Enable or disable the remove videos button based on video selection."""
    if input_videos:
        remove_videos_button.config(state=tk.NORMAL)
    else:
        remove_videos_button.config(state=tk.DISABLED)

# Monitor changes in the input_folders and input_videos lists to update the remove buttons state
def monitor_input_lists():
    """Periodically check if input lists are empty to enable/disable the remove buttons."""
    on_input_folders_change()
    on_input_videos_change()
    root.after(500, monitor_input_lists)

monitor_input_lists()

# Function to apply custom styling for Egyptian Space Ascension Theme
def apply_custom_theme():
    # Set a custom font for all widgets
    default_font = ("Segoe UI", 10)
    root.option_add("*Font", default_font)

    # Configure other style options as needed
    # For more advanced theming, consider using images or additional styling packages
    pass

apply_custom_theme()

# Run the GUI loop
root.mainloop()