Update ui.py

testing
KRSHH 2025-03-26 12:14:29 +05:30
parent 66248a37b4
commit 2b2caf6aba
1 changed files with 92 additions and 36 deletions

View File

@ -7,6 +7,7 @@ from cv2_enumerate_cameras import enumerate_cameras # Add this import
from PIL import Image, ImageOps from PIL import Image, ImageOps
import time import time
import json import json
import tkinterdnd2 as tkdnd
import modules.globals import modules.globals
import modules.metadata import modules.metadata
from modules.face_analyser import ( from modules.face_analyser import (
@ -79,7 +80,7 @@ target_label_dict_live = {}
img_ft, vid_ft = modules.globals.file_types img_ft, vid_ft = modules.globals.file_types
def init(start: Callable[[], None], destroy: Callable[[], None], lang: str) -> ctk.CTk: def init(start: Callable[[], None], destroy: Callable[[], None], lang: str) -> tkdnd.TkinterDnD.Tk:
global ROOT, PREVIEW, _ global ROOT, PREVIEW, _
lang_manager = LanguageManager(lang) lang_manager = LanguageManager(lang)
@ -134,50 +135,71 @@ def load_switch_states():
pass pass
def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> tkdnd.TkinterDnD.Tk:
global source_label, target_label, status_label, show_fps_switch global source_label, target_label, status_label, show_fps_switch
load_switch_states() load_switch_states()
ctk.deactivate_automatic_dpi_awareness() ctk.deactivate_automatic_dpi_awareness()
ctk.set_appearance_mode("system") ctk.set_appearance_mode("dark")
ctk.set_default_color_theme(resolve_relative_path("ui.json")) ctk.set_default_color_theme(resolve_relative_path("ui.json"))
root = ctk.CTk() # Initialize TkinterDnD.Tk
root = tkdnd.TkinterDnD.Tk()
root.minsize(ROOT_WIDTH, ROOT_HEIGHT) root.minsize(ROOT_WIDTH, ROOT_HEIGHT)
root.title( root.title(
f"{modules.metadata.name} {modules.metadata.version} {modules.metadata.edition}" f"{modules.metadata.name} {modules.metadata.version} {modules.metadata.edition}"
) )
root.configure()
# Set dark colors for the root window - universal approach
root.configure(bg="#1a1a1a")
root.protocol("WM_DELETE_WINDOW", lambda: destroy()) root.protocol("WM_DELETE_WINDOW", lambda: destroy())
source_label = ctk.CTkLabel(root, text=None) # Create a single frame with dark color to contain everything
content_frame = ctk.CTkFrame(root, fg_color="#1e1e1e", corner_radius=0)
content_frame.pack(fill="both", expand=True, padx=10, pady=10)
# Use content_frame as the parent for all UI elements
source_label = ctk.CTkLabel(content_frame, text=None)
source_label.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.25) source_label.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.25)
target_label = ctk.CTkLabel(root, text=None) source_label.drop_target_register(tkdnd.DND_FILES)
source_label.dnd_bind("<<Drop>>", lambda event: handle_drop_source(event))
target_label = ctk.CTkLabel(content_frame, text=None)
target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25) target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25)
target_label.drop_target_register(tkdnd.DND_FILES)
target_label.dnd_bind("<<Drop>>", lambda event: handle_drop_target(event))
select_face_button = ctk.CTkButton( select_face_button = ctk.CTkButton(
root, text=_("Select a face"), cursor="hand2", command=lambda: select_source_path() content_frame, text=_("Select a face"), cursor="hand2", command=lambda: select_source_path()
) )
select_face_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1) select_face_button.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
select_face_button.drop_target_register(tkdnd.DND_FILES)
select_face_button.dnd_bind("<<Drop>>", lambda event: handle_drop_source(event))
swap_faces_button = ctk.CTkButton( swap_faces_button = ctk.CTkButton(
root, text="", cursor="hand2", command=lambda: swap_faces_paths() content_frame, text="", cursor="hand2", command=lambda: swap_faces_paths()
) )
swap_faces_button.place(relx=0.45, rely=0.4, relwidth=0.1, relheight=0.1) swap_faces_button.place(relx=0.45, rely=0.4, relwidth=0.1, relheight=0.1)
select_target_button = ctk.CTkButton( select_target_button = ctk.CTkButton(
root, content_frame,
text=_("Select a target"), text=_("Select a target"),
cursor="hand2", cursor="hand2",
command=lambda: select_target_path(), command=lambda: select_target_path(),
) )
select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1) select_target_button.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
select_target_button.drop_target_register(tkdnd.DND_FILES)
select_target_button.dnd_bind("<<Drop>>", lambda event: handle_drop_target(event))
keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps) keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps)
keep_fps_checkbox = ctk.CTkSwitch( keep_fps_checkbox = ctk.CTkSwitch(
root, content_frame,
text=_("Keep fps"), text=_("Keep fps"),
variable=keep_fps_value, variable=keep_fps_value,
cursor="hand2", cursor="hand2",
@ -190,7 +212,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
keep_frames_value = ctk.BooleanVar(value=modules.globals.keep_frames) keep_frames_value = ctk.BooleanVar(value=modules.globals.keep_frames)
keep_frames_switch = ctk.CTkSwitch( keep_frames_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Keep frames"), text=_("Keep frames"),
variable=keep_frames_value, variable=keep_frames_value,
cursor="hand2", cursor="hand2",
@ -203,7 +225,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui["face_enhancer"]) enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui["face_enhancer"])
enhancer_switch = ctk.CTkSwitch( enhancer_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Face Enhancer"), text=_("Face Enhancer"),
variable=enhancer_value, variable=enhancer_value,
cursor="hand2", cursor="hand2",
@ -216,7 +238,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
keep_audio_value = ctk.BooleanVar(value=modules.globals.keep_audio) keep_audio_value = ctk.BooleanVar(value=modules.globals.keep_audio)
keep_audio_switch = ctk.CTkSwitch( keep_audio_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Keep audio"), text=_("Keep audio"),
variable=keep_audio_value, variable=keep_audio_value,
cursor="hand2", cursor="hand2",
@ -229,7 +251,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces) many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces)
many_faces_switch = ctk.CTkSwitch( many_faces_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Many faces"), text=_("Many faces"),
variable=many_faces_value, variable=many_faces_value,
cursor="hand2", cursor="hand2",
@ -242,7 +264,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
color_correction_value = ctk.BooleanVar(value=modules.globals.color_correction) color_correction_value = ctk.BooleanVar(value=modules.globals.color_correction)
color_correction_switch = ctk.CTkSwitch( color_correction_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Fix Blueish Cam"), text=_("Fix Blueish Cam"),
variable=color_correction_value, variable=color_correction_value,
cursor="hand2", cursor="hand2",
@ -253,13 +275,9 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
) )
color_correction_switch.place(relx=0.6, rely=0.70) color_correction_switch.place(relx=0.6, rely=0.70)
# nsfw_value = ctk.BooleanVar(value=modules.globals.nsfw_filter)
# nsfw_switch = ctk.CTkSwitch(root, text='NSFW filter', variable=nsfw_value, cursor='hand2', command=lambda: setattr(modules.globals, 'nsfw_filter', nsfw_value.get()))
# nsfw_switch.place(relx=0.6, rely=0.7)
map_faces = ctk.BooleanVar(value=modules.globals.map_faces) map_faces = ctk.BooleanVar(value=modules.globals.map_faces)
map_faces_switch = ctk.CTkSwitch( map_faces_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Map faces"), text=_("Map faces"),
variable=map_faces, variable=map_faces,
cursor="hand2", cursor="hand2",
@ -273,7 +291,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_fps_value = ctk.BooleanVar(value=modules.globals.show_fps) show_fps_value = ctk.BooleanVar(value=modules.globals.show_fps)
show_fps_switch = ctk.CTkSwitch( show_fps_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Show FPS"), text=_("Show FPS"),
variable=show_fps_value, variable=show_fps_value,
cursor="hand2", cursor="hand2",
@ -286,7 +304,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
mouth_mask_var = ctk.BooleanVar(value=modules.globals.mouth_mask) mouth_mask_var = ctk.BooleanVar(value=modules.globals.mouth_mask)
mouth_mask_switch = ctk.CTkSwitch( mouth_mask_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Mouth Mask"), text=_("Mouth Mask"),
variable=mouth_mask_var, variable=mouth_mask_var,
cursor="hand2", cursor="hand2",
@ -296,7 +314,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_mouth_mask_box_var = ctk.BooleanVar(value=modules.globals.show_mouth_mask_box) show_mouth_mask_box_var = ctk.BooleanVar(value=modules.globals.show_mouth_mask_box)
show_mouth_mask_box_switch = ctk.CTkSwitch( show_mouth_mask_box_switch = ctk.CTkSwitch(
root, content_frame,
text=_("Show Mouth Mask Box"), text=_("Show Mouth Mask Box"),
variable=show_mouth_mask_box_var, variable=show_mouth_mask_box_var,
cursor="hand2", cursor="hand2",
@ -307,22 +325,22 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
show_mouth_mask_box_switch.place(relx=0.6, rely=0.55) show_mouth_mask_box_switch.place(relx=0.6, rely=0.55)
start_button = ctk.CTkButton( start_button = ctk.CTkButton(
root, text=_("Start"), cursor="hand2", command=lambda: analyze_target(start, root) content_frame, text=_("Start"), cursor="hand2", command=lambda: analyze_target(start, root)
) )
start_button.place(relx=0.15, rely=0.80, relwidth=0.2, relheight=0.05) start_button.place(relx=0.15, rely=0.80, relwidth=0.2, relheight=0.05)
stop_button = ctk.CTkButton( stop_button = ctk.CTkButton(
root, text=_("Destroy"), cursor="hand2", command=lambda: destroy() content_frame, text=_("Destroy"), cursor="hand2", command=lambda: destroy()
) )
stop_button.place(relx=0.4, rely=0.80, relwidth=0.2, relheight=0.05) stop_button.place(relx=0.4, rely=0.80, relwidth=0.2, relheight=0.05)
preview_button = ctk.CTkButton( preview_button = ctk.CTkButton(
root, text=_("Preview"), cursor="hand2", command=lambda: toggle_preview() content_frame, text=_("Preview"), cursor="hand2", command=lambda: toggle_preview()
) )
preview_button.place(relx=0.65, rely=0.80, relwidth=0.2, relheight=0.05) preview_button.place(relx=0.65, rely=0.80, relwidth=0.2, relheight=0.05)
# --- Camera Selection --- # --- Camera Selection ---
camera_label = ctk.CTkLabel(root, text=_("Select Camera:")) camera_label = ctk.CTkLabel(content_frame, text=_("Select Camera:"))
camera_label.place(relx=0.1, rely=0.86, relwidth=0.2, relheight=0.05) camera_label.place(relx=0.1, rely=0.86, relwidth=0.2, relheight=0.05)
available_cameras = get_available_cameras() available_cameras = get_available_cameras()
@ -331,7 +349,7 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
if not camera_names or camera_names[0] == "No cameras found": if not camera_names or camera_names[0] == "No cameras found":
camera_variable = ctk.StringVar(value="No cameras found") camera_variable = ctk.StringVar(value="No cameras found")
camera_optionmenu = ctk.CTkOptionMenu( camera_optionmenu = ctk.CTkOptionMenu(
root, content_frame,
variable=camera_variable, variable=camera_variable,
values=["No cameras found"], values=["No cameras found"],
state="disabled", state="disabled",
@ -339,13 +357,13 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
else: else:
camera_variable = ctk.StringVar(value=camera_names[0]) camera_variable = ctk.StringVar(value=camera_names[0])
camera_optionmenu = ctk.CTkOptionMenu( camera_optionmenu = ctk.CTkOptionMenu(
root, variable=camera_variable, values=camera_names content_frame, variable=camera_variable, values=camera_names
) )
camera_optionmenu.place(relx=0.35, rely=0.86, relwidth=0.25, relheight=0.05) camera_optionmenu.place(relx=0.35, rely=0.86, relwidth=0.25, relheight=0.05)
live_button = ctk.CTkButton( live_button = ctk.CTkButton(
root, content_frame,
text=_("Live"), text=_("Live"),
cursor="hand2", cursor="hand2",
command=lambda: webcam_preview( command=lambda: webcam_preview(
@ -365,11 +383,11 @@ def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.C
live_button.place(relx=0.65, rely=0.86, relwidth=0.2, relheight=0.05) live_button.place(relx=0.65, rely=0.86, relwidth=0.2, relheight=0.05)
# --- End Camera Selection --- # --- End Camera Selection ---
status_label = ctk.CTkLabel(root, text=None, justify="center") status_label = ctk.CTkLabel(content_frame, text=None, justify="center")
status_label.place(relx=0.1, rely=0.9, relwidth=0.8) status_label.place(relx=0.1, rely=0.9, relwidth=0.8)
donate_label = ctk.CTkLabel( donate_label = ctk.CTkLabel(
root, text="Deep Live Cam", justify="center", cursor="hand2" content_frame, text="Deep Live Cam", justify="center", cursor="hand2"
) )
donate_label.place(relx=0.1, rely=0.95, relwidth=0.8) donate_label.place(relx=0.1, rely=0.95, relwidth=0.8)
donate_label.configure( donate_label.configure(
@ -797,7 +815,6 @@ def webcam_preview(root: ctk.CTk, camera_index: int):
) )
def get_available_cameras(): def get_available_cameras():
"""Returns a list of available camera names and indices.""" """Returns a list of available camera names and indices."""
if platform.system() == "Windows": if platform.system() == "Windows":
@ -1003,7 +1020,6 @@ def create_source_target_popup_for_webcam(
close_button.place(relx=0.7, rely=0.92, relwidth=0.2, relheight=0.05) close_button.place(relx=0.7, rely=0.92, relwidth=0.2, relheight=0.05)
def clear_source_target_images(map: list): def clear_source_target_images(map: list):
global source_label_dict_live, target_label_dict_live global source_label_dict_live, target_label_dict_live
@ -1204,3 +1220,43 @@ def update_webcam_target(
else: else:
update_pop_live_status("Face could not be detected in last upload!") update_pop_live_status("Face could not be detected in last upload!")
return map return map
# New drop handler functions
def handle_drop_source(event):
"""Handle files dropped on source button or label"""
file_path = event.data
# On Windows, file paths may be enclosed in {}
if file_path.startswith("{") and file_path.endswith("}"):
file_path = file_path[1:-1]
if is_image(file_path):
modules.globals.source_path = file_path
global RECENT_DIRECTORY_SOURCE
RECENT_DIRECTORY_SOURCE = os.path.dirname(modules.globals.source_path)
image = render_image_preview(modules.globals.source_path, (200, 200))
source_label.configure(image=image)
else:
update_status("Please drop an image file for the source.")
def handle_drop_target(event):
"""Handle files dropped on target button or label"""
file_path = event.data
# On Windows, file paths may be enclosed in {}
if file_path.startswith("{") and file_path.endswith("}"):
file_path = file_path[1:-1]
if is_image(file_path) or is_video(file_path):
modules.globals.target_path = file_path
global RECENT_DIRECTORY_TARGET
RECENT_DIRECTORY_TARGET = os.path.dirname(modules.globals.target_path)
if is_image(file_path):
image = render_image_preview(modules.globals.target_path, (200, 200))
target_label.configure(image=image)
elif is_video(file_path):
video_frame = render_video_preview(file_path, (200, 200))
target_label.configure(image=video_frame)
else:
update_status("Please drop an image or video file for the target.")