Merge branch 'Add_CTkScrollableDropdown' into develop

This commit is contained in:
misygauziya
2023-07-18 07:11:50 +09:00
3 changed files with 586 additions and 14 deletions

15
VRCT.py
View File

@@ -331,7 +331,6 @@ class App(CTk):
image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "config-icon-white.png"))) image=CTkImage(Image_open(os_path.join(os_path.dirname(__file__), "img", "config-icon-white.png")))
) )
self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse") self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse")
self.config_window = None
# load ui language data # load ui language data
language_yaml_data = get_localized_text(f"{self.UI_LANGUAGE}") language_yaml_data = get_localized_text(f"{self.UI_LANGUAGE}")
@@ -400,12 +399,16 @@ class App(CTk):
# delete window # delete window
self.protocol("WM_DELETE_WINDOW", self.delete_window) self.protocol("WM_DELETE_WINDOW", self.delete_window)
self.config_window = ToplevelWindowConfig(self)
def button_config_callback(self): def button_config_callback(self):
if self.config_window is None or not self.config_window.winfo_exists(): self.checkbox_translation.configure(state="disabled")
self.config_window = ToplevelWindowConfig(self) self.checkbox_transcription_send.configure(state="disabled")
self.checkbox_translation.configure(state="disabled") self.checkbox_transcription_receive.configure(state="disabled")
self.checkbox_transcription_send.configure(state="disabled") self.button_config.configure(state="disabled", fg_color=["gray92", "gray14"])
self.checkbox_transcription_receive.configure(state="disabled")
self.config_window.deiconify()
self.config_window.focus_set()
self.config_window.focus() self.config_window.focus()
def button_information_callback(self): def button_information_callback(self):

325
ctk_scrollable_dropdown.py Normal file
View File

@@ -0,0 +1,325 @@
"""
CustomTkinter Scrollable Dropdown Menu
Author: Akash Bora
License: MIT
This is a custom dropdown menu for customtkinter.
Homepage: https://github.com/Akascape/CTkScrollableDropdown
Advanced Scrollable Dropdown class for customtkinter widgets
Author: Akash Bora
"""
import customtkinter
import sys
import time
class CTkScrollableDropdown(customtkinter.CTkToplevel):
def __init__(self, attach, x=None, y=None, button_color=None, height: int = 200, width: int = None,
fg_color=None, button_height: int = 20, justify="center", scrollbar_button_color=None,
scrollbar=True, scrollbar_button_hover_color=None, frame_border_width=2, values=[],
command=None, image_values=[], alpha: float = 0.97, frame_corner_radius=20, double_click=False,
resize=True, frame_border_color=None, text_color=None, autocomplete=False, **button_kwargs):
super().__init__(takefocus=1)
self.transient(self.master)
self.alpha = alpha
self.attach = attach
self.corner = frame_corner_radius
self.padding = 0
self.focus_something = False
self.disable = True
if sys.platform.startswith("win"):
self.after(100, lambda: self.overrideredirect(True))
self.transparent_color = self._apply_appearance_mode(self._fg_color)
self.attributes("-transparentcolor", self.transparent_color)
elif sys.platform.startswith("darwin"):
self.overrideredirect(True)
self.transparent_color = 'systemTransparent'
self.attributes("-transparent", True)
self.focus_something = True
else:
self.overrideredirect(True)
self.transparent_color = '#000001'
self.corner = 0
self.padding = 18
self.withdraw()
self.hide = True
self.attach.bind('<Configure>', lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind('<Configure>', lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind("<Triple-Button-1>", lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind("<Button-3>", lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind("<Button-2>", lambda e: self._withdraw() if not self.disable else None, add="+")
self.attributes('-alpha', 0)
self.disable = False
self.fg_color = customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] if fg_color is None else fg_color
self.scroll_button_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_color"] if scrollbar_button_color is None else scrollbar_button_color
self.scroll_hover_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_hover_color"] if scrollbar_button_hover_color is None else scrollbar_button_hover_color
self.frame_border_color = customtkinter.ThemeManager.theme["CTkFrame"]["border_color"] if frame_border_color is None else frame_border_color
self.button_color = customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"] if button_color is None else button_color
self.text_color = customtkinter.ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else text_color
if scrollbar is False:
self.scroll_button_color = self.fg_color
self.scroll_hover_color = self.fg_color
self.frame = customtkinter.CTkScrollableFrame(self, bg_color=self.transparent_color, fg_color=self.fg_color,
scrollbar_button_hover_color=self.scroll_hover_color,
corner_radius=self.corner, border_width=frame_border_width,
scrollbar_button_color=self.scroll_button_color,
border_color=self.frame_border_color)
self.frame._scrollbar.grid_configure(padx=3)
self.frame.pack(expand=True, fill="both")
self.dummy_entry = customtkinter.CTkEntry(self.frame, fg_color="transparent", border_width=0, height=1, width=1)
self.no_match = customtkinter.CTkLabel(self.frame, text="No Match")
self.height = height
self.height_new = height
self.width = width
self.command = command
self.fade = False
self.resize = resize
self.autocomplete = autocomplete
self.var_update = customtkinter.StringVar()
self.appear = False
if justify.lower()=="left":
self.justify = "w"
elif justify.lower()=="right":
self.justify = "e"
else:
self.justify = "c"
self.button_height = button_height
self.values = values
self.button_num = len(self.values)
self.image_values = None if len(image_values)!=len(self.values) else image_values
self.resizable(width=False, height=False)
self._init_buttons(**button_kwargs)
# Add binding for different ctk widgets
if double_click or self.attach.winfo_name().startswith("!ctkentry") or self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach.bind('<Double-Button-1>', lambda e: self._iconify(), add="+")
else:
self.attach.bind('<Button-1>', lambda e: self._iconify(), add="+")
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._canvas.tag_bind("right_parts", "<Button-1>", lambda e: self._iconify())
self.attach._canvas.tag_bind("dropdown_arrow", "<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
if self.attach.winfo_name().startswith("!ctkoptionmenu"):
self.attach._canvas.bind("<Button-1>", lambda e: self._iconify())
self.attach._text_label.bind("<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
self.update_idletasks()
self.x = x
self.y = y
if self.autocomplete:
self.bind_autocomplete()
# self.deiconify()
self.withdraw()
self.attributes("-alpha", self.alpha)
def _withdraw(self):
if self.hide is False: self.withdraw()
self.hide = True
def _update(self, a, b, c):
self.live_update(self.attach._entry.get())
def bind_autocomplete(self, ):
def appear(x):
self.appear = True
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._entry.configure(textvariable=self.var_update)
self.attach._entry.bind("<Key>", appear)
self.attach.set(self.values[0])
self.var_update.trace_add('write', self._update)
if self.attach.winfo_name().startswith("!ctkentry"):
self.attach.configure(textvariable=self.var_update)
self.attach.bind("<Key>", appear)
self.var_update.trace_add('write', self._update)
def fade_out(self):
for i in range(100,0,-10):
if not self.winfo_exists():
break
self.attributes("-alpha", i/100)
self.update()
time.sleep(1/100)
def fade_in(self):
for i in range(0,100,10):
if not self.winfo_exists():
break
self.attributes("-alpha", i/100)
self.update()
time.sleep(1/100)
def _init_buttons(self, **button_kwargs):
self.i = 0
self.widgets = {}
for row in self.values:
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=row,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
image=self.image_values[i] if self.image_values is not None else None,
anchor=self.justify,
command=lambda k=row: self._attach_key_press(k), **button_kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.hide = False
def destroy_popup(self):
self.destroy()
self.disable = True
def place_dropdown(self):
self.x_pos = self.attach.winfo_rootx() if self.x is None else self.x + self.attach.winfo_rootx()
self.y_pos = self.attach.winfo_rooty() + self.attach.winfo_reqheight() + 5 if self.y is None else self.y + self.attach.winfo_rooty()
self.width_new = self.attach.winfo_width() if self.width is None else self.width
if self.resize:
if self.button_num==1:
self.height_new = self.button_height * self.button_num + 45
else:
self.height_new = self.button_height * self.button_num + 35
if self.height_new>self.height:
self.height_new = self.height
self.geometry('{}x{}+{}+{}'.format(self.width_new, self.height_new,
self.x_pos, self.y_pos))
self.fade_in()
self.attributes('-alpha', self.alpha)
def _iconify(self):
if self.disable: return
if self.hide:
self._deiconify()
self.place_dropdown()
if self.focus_something:
self.dummy_entry.pack()
self.dummy_entry.focus_set()
self.after(100, self.dummy_entry.pack_forget)
self.hide = False
self.focus_set()
self.focus()
else:
self.withdraw()
self.hide = True
def _attach_key_press(self, k):
self.fade = True
if self.command:
self.command(k)
self.fade = False
self.fade_out()
self.withdraw()
self.hide = True
def live_update(self, string=None):
if not self.appear: return
if self.disable: return
if self.fade: return
if string:
self._deiconify()
i=1
for key in self.widgets.keys():
s = self.widgets[key].cget("text")
if not s.startswith(string):
self.widgets[key].pack_forget()
else:
self.widgets[key].pack(fill="x", pady=2, padx=(self.padding, 0))
i+=1
if i==1:
self.no_match.pack(fill="x", pady=2, padx=(self.padding, 0))
else:
self.no_match.pack_forget()
self.button_num = i
self.place_dropdown()
else:
self.no_match.pack_forget()
self.button_num = len(self.values)
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
self.place_dropdown()
self.frame._parent_canvas.yview_moveto(0.0)
self.appear = False
def insert(self, value, **kwargs):
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=value,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
anchor=self.justify,
command=lambda k=value: self._attach_key_press(k), **kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.values.append(value)
def _deiconify(self):
if len(self.values)>0:
self.deiconify()
def popup(self, x=None, y=None):
self.x = x
self.y = y
self.hide = True
self._iconify()
def configure(self, **kwargs):
if "height" in kwargs:
self.height = kwargs.pop("height")
self.height_new = self.height
if "alpha" in kwargs:
self.alpha = kwargs.pop("alpha")
if "width" in kwargs:
self.width = kwargs.pop("width")
if "fg_color" in kwargs:
self.frame.configure(fg_color=kwargs.pop("fg_color"))
if "values" in kwargs:
self.values = kwargs.pop("values")
self.image_values = None
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
if "image_values" in kwargs:
self.image_values = kwargs.pop("image_values")
self.image_values = None if len(self.image_values)!=len(self.values) else self.image_values
if self.image_values is not None:
i=0
for key in self.widgets.keys():
self.widgets[key].configure(image=self.image_values[i])
i+=1
if "button_color" in kwargs:
for key in self.widgets.keys():
self.widgets[key].configure(fg_color=kwargs.pop("button_color"))
for key in self.widgets.keys():
self.widgets[key].configure(**kwargs)

View File

@@ -1,7 +1,7 @@
from time import sleep from time import sleep
from queue import Queue from queue import Queue
from os import path as os_path from os import path as os_path
from tkinter import DoubleVar, IntVar from tkinter import DoubleVar, IntVar
from tkinter import font as tk_font from tkinter import font as tk_font
import customtkinter import customtkinter
from customtkinter import CTkToplevel, CTkTabview, CTkFont, CTkLabel, CTkSlider, CTkOptionMenu, StringVar, CTkEntry, CTkCheckBox, CTkProgressBar from customtkinter import CTkToplevel, CTkTabview, CTkFont, CTkLabel, CTkSlider, CTkOptionMenu, StringVar, CTkEntry, CTkCheckBox, CTkProgressBar
@@ -12,10 +12,16 @@ from audio_utils import get_input_device_list, get_output_device_list, get_defau
from audio_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder from audio_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder
from languages import translation_lang, transcription_lang, selectable_languages from languages import translation_lang, transcription_lang, selectable_languages
from ctk_scrollable_dropdown import CTkScrollableDropdown
SCROLLABLE_DROPDOWN = True
class ToplevelWindowConfig(CTkToplevel): class ToplevelWindowConfig(CTkToplevel):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs) super().__init__(parent, *args, **kwargs)
self.withdraw()
self.parent = parent self.parent = parent
# self.geometry(f"{350}x{270}") # self.geometry(f"{350}x{270}")
# self.resizable(False, False) # self.resizable(False, False)
@@ -48,18 +54,24 @@ class ToplevelWindowConfig(CTkToplevel):
self.parent.TRANSPARENCY = value self.parent.TRANSPARENCY = value
save_json(self.parent.PATH_CONFIG, "TRANSPARENCY", self.parent.TRANSPARENCY) save_json(self.parent.PATH_CONFIG, "TRANSPARENCY", self.parent.TRANSPARENCY)
def optionmenu_theme_callback(self, choice): def optionmenu_appearance_theme_callback(self, choice):
self.optionmenu_appearance_theme.set(choice)
customtkinter.set_appearance_mode(choice) customtkinter.set_appearance_mode(choice)
self.parent.APPEARANCE_THEME = choice self.parent.APPEARANCE_THEME = choice
save_json(self.parent.PATH_CONFIG, "APPEARANCE_THEME", self.parent.APPEARANCE_THEME) save_json(self.parent.PATH_CONFIG, "APPEARANCE_THEME", self.parent.APPEARANCE_THEME)
def optionmenu_ui_scaling_callback(self, choice): def optionmenu_ui_scaling_callback(self, choice):
self.optionmenu_ui_scaling.set(choice)
new_scaling_float = int(choice.replace("%", "")) / 100 new_scaling_float = int(choice.replace("%", "")) / 100
customtkinter.set_widget_scaling(new_scaling_float) customtkinter.set_widget_scaling(new_scaling_float)
self.parent.UI_SCALING = choice self.parent.UI_SCALING = choice
save_json(self.parent.PATH_CONFIG, "UI_SCALING", self.parent.UI_SCALING) save_json(self.parent.PATH_CONFIG, "UI_SCALING", self.parent.UI_SCALING)
def optionmenu_font_family_callback(self, choice): def optionmenu_font_family_callback(self, choice):
self.optionmenu_font_family.set(choice)
# tab menu # tab menu
self.tabview_config._segmented_button.configure(font=CTkFont(family=choice)) self.tabview_config._segmented_button.configure(font=CTkFont(family=choice))
@@ -74,6 +86,7 @@ class ToplevelWindowConfig(CTkToplevel):
self.label_font_family.configure(font=CTkFont(family=choice)) self.label_font_family.configure(font=CTkFont(family=choice))
self.optionmenu_font_family.configure(font=CTkFont(family=choice)) self.optionmenu_font_family.configure(font=CTkFont(family=choice))
self.optionmenu_font_family._dropdown_menu.configure(font=CTkFont(family=choice)) self.optionmenu_font_family._dropdown_menu.configure(font=CTkFont(family=choice))
self.scrollableDropdown_font_family.configure(font=CTkFont(family=choice))
self.label_ui_language.configure(font=CTkFont(family=choice)) self.label_ui_language.configure(font=CTkFont(family=choice))
self.optionmenu_ui_language.configure(font=CTkFont(family=choice)) self.optionmenu_ui_language.configure(font=CTkFont(family=choice))
self.optionmenu_ui_language._dropdown_menu.configure(font=CTkFont(family=choice)) self.optionmenu_ui_language._dropdown_menu.configure(font=CTkFont(family=choice))
@@ -167,6 +180,9 @@ class ToplevelWindowConfig(CTkToplevel):
save_json(self.parent.PATH_CONFIG, "FONT_FAMILY", self.parent.FONT_FAMILY) save_json(self.parent.PATH_CONFIG, "FONT_FAMILY", self.parent.FONT_FAMILY)
def optionmenu_ui_language_callback(self, choice): def optionmenu_ui_language_callback(self, choice):
self.optionmenu_ui_language.set(choice)
self.withdraw()
pre_language_yaml_data = get_localized_text(f"{self.parent.UI_LANGUAGE}") pre_language_yaml_data = get_localized_text(f"{self.parent.UI_LANGUAGE}")
self.parent.UI_LANGUAGE = get_key_by_value(selectable_languages, choice) self.parent.UI_LANGUAGE = get_key_by_value(selectable_languages, choice)
language_yaml_data = get_localized_text(f"{self.parent.UI_LANGUAGE}") language_yaml_data = get_localized_text(f"{self.parent.UI_LANGUAGE}")
@@ -179,15 +195,18 @@ class ToplevelWindowConfig(CTkToplevel):
# add tabview textbox # add tabview textbox
self.parent.add_tabview_logs(language_yaml_data) self.parent.add_tabview_logs(language_yaml_data)
self.add_tabview_config(language_yaml_data, selectable_languages) self.add_tabview_config(language_yaml_data, selectable_languages)
# 翻訳予定 # 翻訳予定
# window information # window information
# try: # try:
# self.parent.information_window.textbox_information.configure(font=customtkinter.CTkFont(family=choice)) # self.parent.information_window.textbox_information.configure(font=customtkinter.CTkFont(family=choice))
# except: # except:
# pass # pass
self.deiconify()
def optionmenu_translation_translator_callback(self, choice): def optionmenu_translation_translator_callback(self, choice):
self.optionmenu_translation_translator.set(choice)
if self.parent.translator.authentication(choice, self.parent.AUTH_KEYS[choice]) is False: if self.parent.translator.authentication(choice, self.parent.AUTH_KEYS[choice]) is False:
print_textbox(self.parent.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.parent.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.parent.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.parent.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
@@ -217,33 +236,47 @@ class ToplevelWindowConfig(CTkToplevel):
save_json(self.parent.PATH_CONFIG, "OUTPUT_TARGET_LANG", self.parent.OUTPUT_TARGET_LANG) save_json(self.parent.PATH_CONFIG, "OUTPUT_TARGET_LANG", self.parent.OUTPUT_TARGET_LANG)
def optionmenu_translation_input_source_language_callback(self, choice): def optionmenu_translation_input_source_language_callback(self, choice):
self.optionmenu_translation_input_source_language.set(choice)
self.parent.INPUT_SOURCE_LANG = choice self.parent.INPUT_SOURCE_LANG = choice
save_json(self.parent.PATH_CONFIG, "INPUT_SOURCE_LANG", self.parent.INPUT_SOURCE_LANG) save_json(self.parent.PATH_CONFIG, "INPUT_SOURCE_LANG", self.parent.INPUT_SOURCE_LANG)
def optionmenu_translation_input_target_language_callback(self, choice): def optionmenu_translation_input_target_language_callback(self, choice):
self.optionmenu_translation_input_target_language.set(choice)
self.parent.INPUT_TARGET_LANG = choice self.parent.INPUT_TARGET_LANG = choice
save_json(self.parent.PATH_CONFIG, "INPUT_TARGET_LANG", self.parent.INPUT_TARGET_LANG) save_json(self.parent.PATH_CONFIG, "INPUT_TARGET_LANG", self.parent.INPUT_TARGET_LANG)
def optionmenu_translation_output_source_language_callback(self, choice): def optionmenu_translation_output_source_language_callback(self, choice):
self.optionmenu_translation_output_source_language.set(choice)
self.parent.OUTPUT_SOURCE_LANG = choice self.parent.OUTPUT_SOURCE_LANG = choice
save_json(self.parent.PATH_CONFIG, "OUTPUT_SOURCE_LANG", self.parent.OUTPUT_SOURCE_LANG) save_json(self.parent.PATH_CONFIG, "OUTPUT_SOURCE_LANG", self.parent.OUTPUT_SOURCE_LANG)
def optionmenu_translation_output_target_language_callback(self, choice): def optionmenu_translation_output_target_language_callback(self, choice):
self.optionmenu_translation_output_target_language.set(choice)
self.parent.OUTPUT_TARGET_LANG = choice self.parent.OUTPUT_TARGET_LANG = choice
save_json(self.parent.PATH_CONFIG, "OUTPUT_TARGET_LANG", self.parent.OUTPUT_TARGET_LANG) save_json(self.parent.PATH_CONFIG, "OUTPUT_TARGET_LANG", self.parent.OUTPUT_TARGET_LANG)
def optionmenu_input_mic_host_callback(self, choice): def optionmenu_input_mic_host_callback(self, choice):
self.optionmenu_input_mic_host.set(choice)
self.parent.CHOICE_MIC_HOST = choice self.parent.CHOICE_MIC_HOST = choice
save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_HOST", self.parent.CHOICE_MIC_HOST) save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_HOST", self.parent.CHOICE_MIC_HOST)
self.optionmenu_input_mic_device.configure(values=[device["name"] for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST]]) self.optionmenu_input_mic_device.configure(values=[device["name"] for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST]])
def optionmenu_input_mic_device_callback(self, choice): def optionmenu_input_mic_device_callback(self, choice):
self.optionmenu_input_mic_device.set(choice)
self.parent.CHOICE_MIC_DEVICE = choice self.parent.CHOICE_MIC_DEVICE = choice
save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_DEVICE", self.parent.CHOICE_MIC_DEVICE) save_json(self.parent.PATH_CONFIG, "CHOICE_MIC_DEVICE", self.parent.CHOICE_MIC_DEVICE)
self.checkbox_input_mic_threshold_check.deselect() self.checkbox_input_mic_threshold_check.deselect()
self.checkbox_input_mic_threshold_check_callback() self.checkbox_input_mic_threshold_check_callback()
def optionmenu_input_mic_voice_language_callback(self, choice): def optionmenu_input_mic_voice_language_callback(self, choice):
self.optionmenu_input_mic_voice_language.set(choice)
self.parent.INPUT_MIC_VOICE_LANGUAGE = choice self.parent.INPUT_MIC_VOICE_LANGUAGE = choice
save_json(self.parent.PATH_CONFIG, "INPUT_MIC_VOICE_LANGUAGE", self.parent.INPUT_MIC_VOICE_LANGUAGE) save_json(self.parent.PATH_CONFIG, "INPUT_MIC_VOICE_LANGUAGE", self.parent.INPUT_MIC_VOICE_LANGUAGE)
@@ -303,6 +336,7 @@ class ToplevelWindowConfig(CTkToplevel):
def optionmenu_input_speaker_device_callback(self, choice): def optionmenu_input_speaker_device_callback(self, choice):
speaker_device = [device for device in get_output_device_list() if device["name"] == choice][0] speaker_device = [device for device in get_output_device_list() if device["name"] == choice][0]
if get_default_output_device()["index"] == speaker_device["index"]: if get_default_output_device()["index"] == speaker_device["index"]:
self.optionmenu_input_speaker_device.set(choice)
self.parent.CHOICE_SPEAKER_DEVICE = choice self.parent.CHOICE_SPEAKER_DEVICE = choice
save_json(self.parent.PATH_CONFIG, "CHOICE_SPEAKER_DEVICE", self.parent.CHOICE_SPEAKER_DEVICE) save_json(self.parent.PATH_CONFIG, "CHOICE_SPEAKER_DEVICE", self.parent.CHOICE_SPEAKER_DEVICE)
else: else:
@@ -311,6 +345,8 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_speaker_device.configure(variable=StringVar(value=self.parent.CHOICE_SPEAKER_DEVICE)) self.optionmenu_input_speaker_device.configure(variable=StringVar(value=self.parent.CHOICE_SPEAKER_DEVICE))
def optionmenu_input_speaker_voice_language_callback(self, choice): def optionmenu_input_speaker_voice_language_callback(self, choice):
self.optionmenu_input_speaker_voice_language.set(choice)
self.parent.INPUT_SPEAKER_VOICE_LANGUAGE = choice self.parent.INPUT_SPEAKER_VOICE_LANGUAGE = choice
save_json(self.parent.PATH_CONFIG, "INPUT_SPEAKER_VOICE_LANGUAGE", self.parent.INPUT_SPEAKER_VOICE_LANGUAGE) save_json(self.parent.PATH_CONFIG, "INPUT_SPEAKER_VOICE_LANGUAGE", self.parent.INPUT_SPEAKER_VOICE_LANGUAGE)
@@ -406,7 +442,8 @@ class ToplevelWindowConfig(CTkToplevel):
self.parent.checkbox_translation.configure(state="normal") self.parent.checkbox_translation.configure(state="normal")
self.parent.checkbox_transcription_send.configure(state="normal") self.parent.checkbox_transcription_send.configure(state="normal")
self.parent.checkbox_transcription_receive.configure(state="normal") self.parent.checkbox_transcription_receive.configure(state="normal")
self.parent.config_window.destroy() self.parent.button_config.configure(state="normal", fg_color=["#3B8ED0", "#1F6AA5"])
self.parent.config_window.withdraw()
def entry_message_format_callback(self, event): def entry_message_format_callback(self, event):
value = self.entry_message_format.get() value = self.entry_message_format.get()
@@ -479,13 +516,28 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_appearance_theme = CTkOptionMenu( self.optionmenu_appearance_theme = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_ui), self.tabview_config.tab(config_tab_title_ui),
values=["Light", "Dark", "System"], values=["Light", "Dark", "System"],
command=self.optionmenu_theme_callback, command=self.optionmenu_appearance_theme_callback,
variable=StringVar(value=self.parent.APPEARANCE_THEME), variable=StringVar(value=self.parent.APPEARANCE_THEME),
font=CTkFont(family=self.parent.FONT_FAMILY), font=CTkFont(family=self.parent.FONT_FAMILY),
) )
self.optionmenu_appearance_theme.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_appearance_theme.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_appearance_theme._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_appearance_theme._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown appearance theme
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_appearance_theme = CTkScrollableDropdown(
self.optionmenu_appearance_theme,
values=["Light", "Dark", "System"],
justify="left",
button_color="transparent",
command=self.optionmenu_appearance_theme_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_appearance_theme.bind(
"<Leave>",
lambda e: self.scrollableDropdown_appearance_theme._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_appearance_theme.frame._parent_frame)) else None,
)
## optionmenu UI scaling ## optionmenu UI scaling
row += 1 row += 1
self.label_ui_scaling = CTkLabel( self.label_ui_scaling = CTkLabel(
@@ -505,6 +557,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_ui_scaling.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_ui_scaling.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_ui_scaling._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_ui_scaling._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown ui scaling
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_ui_scaling = CTkScrollableDropdown(
self.optionmenu_ui_scaling,
values=["80%", "90%", "100%", "110%", "120%"],
justify="left",
button_color="transparent",
command=self.optionmenu_ui_scaling_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_ui_scaling.bind(
"<Leave>",
lambda e: self.scrollableDropdown_ui_scaling._iconify() if not str(e.widget).startswith(str(self.scrollableDropdown_ui_scaling.frame._parent_frame)) else None,
)
## optionmenu font family ## optionmenu font family
row += 1 row += 1
self.label_font_family = CTkLabel( self.label_font_family = CTkLabel(
@@ -517,13 +584,25 @@ class ToplevelWindowConfig(CTkToplevel):
font_families = list(tk_font.families()) font_families = list(tk_font.families())
self.optionmenu_font_family = CTkOptionMenu( self.optionmenu_font_family = CTkOptionMenu(
self.tabview_config.tab(config_tab_title_ui), self.tabview_config.tab(config_tab_title_ui),
values=font_families,
command=self.optionmenu_font_family_callback,
variable=StringVar(value=self.parent.FONT_FAMILY), variable=StringVar(value=self.parent.FONT_FAMILY),
font=CTkFont(family=self.parent.FONT_FAMILY), font=CTkFont(family=self.parent.FONT_FAMILY),
) )
self.optionmenu_font_family.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_font_family.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_font_family._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown font family
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_font_family = CTkScrollableDropdown(
self.optionmenu_font_family,
values=font_families,
justify="left",
button_color="transparent",
command=self.optionmenu_font_family_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_font_family.bind(
"<Leave>",
lambda e: self.scrollableDropdown_font_family._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_font_family.frame._parent_frame)) else None,
)
## optionmenu ui language ## optionmenu ui language
row += 1 row += 1
@@ -545,6 +624,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_ui_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_ui_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_ui_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_ui_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown ui language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_ui_language = CTkScrollableDropdown(
self.optionmenu_ui_language,
values=selectable_languages_values,
justify="left",
button_color="transparent",
command=self.optionmenu_ui_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_ui_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_ui_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_ui_language.frame._parent_frame)) else None,
)
# tab Translation # tab Translation
## optionmenu translation translator ## optionmenu translation translator
row = 0 row = 0
@@ -567,6 +661,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_translation_translator.grid(row=row, column=1, columnspan=3, padx=padx, pady=pady, sticky="nsew") self.optionmenu_translation_translator.grid(row=row, column=1, columnspan=3, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_translation_translator._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_translation_translator._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown translation translator
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_translator = CTkScrollableDropdown(
self.optionmenu_translation_translator,
values=list(self.parent.translator.translator_status.keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_translation_translator_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_translation_translator.bind(
"<Leave>",
lambda e: self.scrollableDropdown_translation_translator._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_translation_translator.frame._parent_frame)) else None,
)
## optionmenu translation input language ## optionmenu translation input language
row +=1 row +=1
self.label_translation_input_language = CTkLabel( self.label_translation_input_language = CTkLabel(
@@ -588,6 +697,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_translation_input_source_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_translation_input_source_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_translation_input_source_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_translation_input_source_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown translation input source language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_input_source_language = CTkScrollableDropdown(
self.optionmenu_translation_input_source_language,
values=list(translation_lang[self.parent.CHOICE_TRANSLATOR].keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_translation_input_source_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_translation_input_source_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_translation_input_source_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_translation_input_source_language.frame._parent_frame)) else None,
)
## label translation input arrow ## label translation input arrow
self.label_translation_input_arrow = CTkLabel( self.label_translation_input_arrow = CTkLabel(
self.tabview_config.tab(config_tab_title_translation), self.tabview_config.tab(config_tab_title_translation),
@@ -608,6 +732,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_translation_input_target_language.grid(row=row, column=3, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_translation_input_target_language.grid(row=row, column=3, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_translation_input_target_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_translation_input_target_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown translation input target language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_input_target_language = CTkScrollableDropdown(
self.optionmenu_translation_input_target_language,
values=list(translation_lang[self.parent.CHOICE_TRANSLATOR].keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_translation_input_target_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_translation_input_target_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_translation_input_target_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_translation_input_target_language.frame._parent_frame)) else None,
)
## optionmenu translation output language ## optionmenu translation output language
row +=1 row +=1
self.label_translation_output_language = CTkLabel( self.label_translation_output_language = CTkLabel(
@@ -629,6 +768,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_translation_output_source_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_translation_output_source_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_translation_output_source_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_translation_output_source_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown translation output source language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_output_source_language = CTkScrollableDropdown(
self.optionmenu_translation_output_source_language,
values=list(translation_lang[self.parent.CHOICE_TRANSLATOR].keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_translation_output_source_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_translation_output_source_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_translation_output_source_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_translation_output_source_language.frame._parent_frame)) else None,
)
## label translation output arrow ## label translation output arrow
self.label_translation_output_arrow = CTkLabel( self.label_translation_output_arrow = CTkLabel(
self.tabview_config.tab(config_tab_title_translation), self.tabview_config.tab(config_tab_title_translation),
@@ -649,6 +803,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_translation_output_target_language.grid(row=row, column=3, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_translation_output_target_language.grid(row=row, column=3, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_translation_output_target_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_translation_output_target_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown translation output target language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_translation_output_target_language = CTkScrollableDropdown(
self.optionmenu_translation_output_target_language,
values=list(translation_lang[self.parent.CHOICE_TRANSLATOR].keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_translation_output_target_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_translation_output_target_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_translation_output_target_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_translation_output_target_language.frame._parent_frame)) else None,
)
# tab Transcription # tab Transcription
## optionmenu input mic device's host ## optionmenu input mic device's host
row = 0 row = 0
@@ -671,6 +840,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_mic_host.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_input_mic_host.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_input_mic_host._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_input_mic_host._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown input mic device's host
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_mic_host = CTkScrollableDropdown(
self.optionmenu_input_mic_host,
values=[host for host in get_input_device_list().keys()],
justify="left",
button_color="transparent",
command=self.optionmenu_input_mic_host_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_input_mic_host.bind(
"<Leave>",
lambda e: self.scrollableDropdown_input_mic_host._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_input_mic_host.frame._parent_frame)) else None,
)
## optionmenu input mic device ## optionmenu input mic device
row += 1 row += 1
self.label_input_mic_device = CTkLabel( self.label_input_mic_device = CTkLabel(
@@ -690,6 +874,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_mic_device.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_input_mic_device.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_input_mic_device._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_input_mic_device._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown input mic device
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_mic_device = CTkScrollableDropdown(
self.optionmenu_input_mic_device,
values=[device["name"] for device in get_input_device_list()[self.parent.CHOICE_MIC_HOST]],
justify="left",
button_color="transparent",
command=self.optionmenu_input_mic_device_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_input_mic_device.bind(
"<Leave>",
lambda e: self.scrollableDropdown_input_mic_device._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_input_mic_device.frame._parent_frame)) else None,
)
## optionmenu input mic voice language ## optionmenu input mic voice language
row +=1 row +=1
self.label_input_mic_voice_language = CTkLabel( self.label_input_mic_voice_language = CTkLabel(
@@ -709,6 +908,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_mic_voice_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_input_mic_voice_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_input_mic_voice_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_input_mic_voice_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown input mic voice language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_voice_language = CTkScrollableDropdown(
self.optionmenu_input_mic_voice_language,
values=list(transcription_lang.keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_input_mic_voice_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_input_voice_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_input_voice_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_input_voice_language.frame._parent_frame)) else None,
)
## slider input mic energy threshold ## slider input mic energy threshold
row +=1 row +=1
self.label_input_mic_energy_threshold = CTkLabel( self.label_input_mic_energy_threshold = CTkLabel(
@@ -861,6 +1075,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_speaker_device.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_input_speaker_device.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_input_speaker_device._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_input_speaker_device._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown input speaker device
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_speaker_device = CTkScrollableDropdown(
self.optionmenu_input_speaker_device,
values=[device["name"] for device in get_output_device_list()],
justify="left",
button_color="transparent",
command=self.optionmenu_input_speaker_device_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_input_speaker_device.bind(
"<Leave>",
lambda e: self.scrollableDropdown_input_speaker_device._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_input_speaker_device.frame._parent_frame)) else None,
)
## optionmenu input speaker voice language ## optionmenu input speaker voice language
row +=1 row +=1
self.label_input_speaker_voice_language = CTkLabel( self.label_input_speaker_voice_language = CTkLabel(
@@ -880,6 +1109,21 @@ class ToplevelWindowConfig(CTkToplevel):
self.optionmenu_input_speaker_voice_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew") self.optionmenu_input_speaker_voice_language.grid(row=row, column=1, columnspan=1, padx=padx, pady=pady, sticky="nsew")
self.optionmenu_input_speaker_voice_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY)) self.optionmenu_input_speaker_voice_language._dropdown_menu.configure(font=CTkFont(family=self.parent.FONT_FAMILY))
## scrollableDropdown input speaker voice language
if SCROLLABLE_DROPDOWN:
self.scrollableDropdown_input_speaker_voice_language = CTkScrollableDropdown(
self.optionmenu_input_speaker_voice_language,
values=list(transcription_lang.keys()),
justify="left",
button_color="transparent",
command=self.optionmenu_input_speaker_voice_language_callback,
font=CTkFont(family=self.parent.FONT_FAMILY),
)
self.scrollableDropdown_input_speaker_voice_language.bind(
"<Leave>",
lambda e: self.scrollableDropdown_input_speaker_voice_language._withdraw() if not str(e.widget).startswith(str(self.scrollableDropdown_input_speaker_voice_language.frame._parent_frame)) else None,
)
## entry input speaker energy threshold ## entry input speaker energy threshold
row +=1 row +=1
self.label_input_speaker_energy_threshold = CTkLabel( self.label_input_speaker_energy_threshold = CTkLabel(