Merge branch 'develop'

This commit is contained in:
misyaguziya
2024-01-08 15:34:52 +09:00
42 changed files with 1728 additions and 498 deletions

3
.gitignore vendored
View File

@@ -4,4 +4,5 @@ config.json
memo.txt
VRCT.spec
*.pyc
logs/
logs/
.venv/

View File

@@ -58,7 +58,7 @@ VRCTはあなたの会話を以下でサポートをします。
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (メイン開発)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI多言語対応)
- [レラ](https://github.com/soumt-r) (翻訳:韓国語)
- [どね]() (ロゴデザイン)
- [どね](https://twitter.com/done_vrc) (ロゴデザイン)
---

View File

@@ -58,7 +58,7 @@ Initial setup, basic functions, and other features are also described.
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (Main Development)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI multilingual support)
- [レラ](https://github.com/soumt-r) (Translation:Korean)
- [どね]() (Logo Design)
- [どね](https://twitter.com/done_vrc) (Logo Design)
---

View File

@@ -16,5 +16,5 @@ rmdir /s /q %local_path%%folder_tmp%
if %restart% == True (
START "" %local_path%%exe_name%
)
pause
del /f "%~dp0%~nx0"

227
config.py
View File

@@ -5,7 +5,6 @@ from json import load as json_load
from json import dump as json_dump
import tkinter as tk
from tkinter import font
from languages import selectable_languages
from models.translation.translation_languages import translatorEngine
from models.transcription.transcription_utils import getInputDevices, getDefaultInputDevice
from utils import generatePercentageStringsList, isUniqueStrings
@@ -39,6 +38,10 @@ class Config:
def VERSION(self):
return self._VERSION
@property
def ENABLE_SPEAKER2CHATBOX(self):
return self._ENABLE_SPEAKER2CHATBOX
@property
def LOCAL_PATH(self):
return self._LOCAL_PATH
@@ -63,6 +66,30 @@ class Config:
def DOCUMENTS_URL(self):
return self._DOCUMENTS_URL
@property
def TRANSPARENCY_RANGE(self):
return self._TRANSPARENCY_RANGE
@property
def APPEARANCE_THEME_LIST(self):
return self._APPEARANCE_THEME_LIST
@property
def UI_SCALING_LIST(self):
return self._UI_SCALING_LIST
@property
def TEXTBOX_UI_SCALING_RANGE(self):
return self._TEXTBOX_UI_SCALING_RANGE
@property
def MESSAGE_BOX_RATIO_RANGE(self):
return self._MESSAGE_BOX_RATIO_RANGE
@property
def SELECTABLE_UI_LANGUAGES_DICT(self):
return self._SELECTABLE_UI_LANGUAGES_DICT
@property
def MAX_MIC_ENERGY_THRESHOLD(self):
return self._MAX_MIC_ENERGY_THRESHOLD
@@ -207,7 +234,7 @@ class Config:
@TRANSPARENCY.setter
def TRANSPARENCY(self, value):
if isinstance(value, int) and 0 <= value <= 100:
if isinstance(value, int) and self.TRANSPARENCY_RANGE[0] <= value <= self.TRANSPARENCY_RANGE[1]:
self._TRANSPARENCY = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@@ -218,7 +245,7 @@ class Config:
@APPEARANCE_THEME.setter
def APPEARANCE_THEME(self, value):
if value in ["Light", "Dark", "System"]:
if value in self.APPEARANCE_THEME_LIST:
self._APPEARANCE_THEME = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@@ -229,7 +256,7 @@ class Config:
@UI_SCALING.setter
def UI_SCALING(self, value):
if value in generatePercentageStringsList(start=40,end=200, step=10):
if value in self.UI_SCALING_LIST:
self._UI_SCALING = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@@ -240,10 +267,21 @@ class Config:
@TEXTBOX_UI_SCALING.setter
def TEXTBOX_UI_SCALING(self, value):
if isinstance(value, int) and 50 <= value <= 200:
if isinstance(value, int) and self.TEXTBOX_UI_SCALING_RANGE[0] <= value <= self.TEXTBOX_UI_SCALING_RANGE[1]:
self._TEXTBOX_UI_SCALING = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('MESSAGE_BOX_RATIO')
def MESSAGE_BOX_RATIO(self):
return self._MESSAGE_BOX_RATIO
@MESSAGE_BOX_RATIO.setter
def MESSAGE_BOX_RATIO(self, value):
if isinstance(value, int) and self.MESSAGE_BOX_RATIO_RANGE[0] <= value <= self.MESSAGE_BOX_RATIO_RANGE[1]:
self._MESSAGE_BOX_RATIO = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('FONT_FAMILY')
def FONT_FAMILY(self):
@@ -265,10 +303,34 @@ class Config:
@UI_LANGUAGE.setter
def UI_LANGUAGE(self, value):
if value in list(selectable_languages.keys()):
if value in list(self.SELECTABLE_UI_LANGUAGES_DICT.keys()):
self._UI_LANGUAGE = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY')
def ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY(self):
return self._ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY
@ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY.setter
def ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY(self, value):
if isinstance(value, bool):
self._ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('MAIN_WINDOW_GEOMETRY')
def MAIN_WINDOW_GEOMETRY(self):
return self._MAIN_WINDOW_GEOMETRY
@MAIN_WINDOW_GEOMETRY.setter
def MAIN_WINDOW_GEOMETRY(self, value):
if isinstance(value, dict) and set(value.keys()) == set(self.MAIN_WINDOW_GEOMETRY.keys()):
for key, value in value.items():
if isinstance(value, str):
self._MAIN_WINDOW_GEOMETRY[key] = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.MAIN_WINDOW_GEOMETRY)
@property
@json_serializable('CHOICE_MIC_HOST')
def CHOICE_MIC_HOST(self):
@@ -447,19 +509,6 @@ class Config:
self._AUTH_KEYS[key] = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.AUTH_KEYS)
@property
@json_serializable('MESSAGE_FORMAT')
def MESSAGE_FORMAT(self):
return self._MESSAGE_FORMAT
@MESSAGE_FORMAT.setter
def MESSAGE_FORMAT(self, value):
if isinstance(value, str):
if isUniqueStrings(["[message]", "[translation]"], value) is False:
value = "[message]([translation])"
self._MESSAGE_FORMAT = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('ENABLE_AUTO_CLEAR_MESSAGE_BOX')
def ENABLE_AUTO_CLEAR_MESSAGE_BOX(self):
@@ -471,6 +520,28 @@ class Config:
self._ENABLE_AUTO_CLEAR_MESSAGE_BOX = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('ENABLE_SEND_ONLY_TRANSLATED_MESSAGES')
def ENABLE_SEND_ONLY_TRANSLATED_MESSAGES(self):
return self._ENABLE_SEND_ONLY_TRANSLATED_MESSAGES
@ENABLE_SEND_ONLY_TRANSLATED_MESSAGES.setter
def ENABLE_SEND_ONLY_TRANSLATED_MESSAGES(self, value):
if isinstance(value, bool):
self._ENABLE_SEND_ONLY_TRANSLATED_MESSAGES = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('SEND_MESSAGE_BUTTON_TYPE')
def SEND_MESSAGE_BUTTON_TYPE(self):
return self._SEND_MESSAGE_BUTTON_TYPE
@SEND_MESSAGE_BUTTON_TYPE.setter
def SEND_MESSAGE_BUTTON_TYPE(self, value):
if isinstance(value, str):
self._SEND_MESSAGE_BUTTON_TYPE = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('ENABLE_NOTICE_XSOVERLAY')
def ENABLE_NOTICE_XSOVERLAY(self):
@@ -493,17 +564,77 @@ class Config:
self._ENABLE_SEND_MESSAGE_TO_VRC = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
# [deprecated]
# @property
# @json_serializable('STARTUP_OSC_ENABLED_CHECK')
# def STARTUP_OSC_ENABLED_CHECK(self):
# return self._STARTUP_OSC_ENABLED_CHECK
@property
@json_serializable('SEND_MESSAGE_FORMAT')
def SEND_MESSAGE_FORMAT(self):
return self._SEND_MESSAGE_FORMAT
@SEND_MESSAGE_FORMAT.setter
def SEND_MESSAGE_FORMAT(self, value):
if isinstance(value, str):
if isUniqueStrings(["[message]"], value) is False:
value = "[message]"
self._SEND_MESSAGE_FORMAT = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('SEND_MESSAGE_FORMAT_WITH_T')
def SEND_MESSAGE_FORMAT_WITH_T(self):
return self._SEND_MESSAGE_FORMAT_WITH_T
@SEND_MESSAGE_FORMAT_WITH_T.setter
def SEND_MESSAGE_FORMAT_WITH_T(self, value):
if isinstance(value, str):
if isUniqueStrings(["[message]", "[translation]"], value) is False:
value = "[message]([translation])"
self._SEND_MESSAGE_FORMAT_WITH_T = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('RECEIVED_MESSAGE_FORMAT')
def RECEIVED_MESSAGE_FORMAT(self):
return self._RECEIVED_MESSAGE_FORMAT
@RECEIVED_MESSAGE_FORMAT.setter
def RECEIVED_MESSAGE_FORMAT(self, value):
if isinstance(value, str):
if isUniqueStrings(["[message]"], value) is False:
value = "[message]"
self._RECEIVED_MESSAGE_FORMAT = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('RECEIVED_MESSAGE_FORMAT_WITH_T')
def RECEIVED_MESSAGE_FORMAT_WITH_T(self):
return self._RECEIVED_MESSAGE_FORMAT_WITH_T
@RECEIVED_MESSAGE_FORMAT_WITH_T.setter
def RECEIVED_MESSAGE_FORMAT_WITH_T(self, value):
if isinstance(value, str):
if isUniqueStrings(["[message]", "[translation]"], value) is False:
value = "[message]([translation])"
self._RECEIVED_MESSAGE_FORMAT_WITH_T = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
# Speaker2Chatbox------------------
@property
@json_serializable('ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC')
def ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC(self):
return self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC
@ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC.setter
def ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC(self, value):
if isinstance(value, bool):
if self._ENABLE_SPEAKER2CHATBOX is True:
self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = value
else:
self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = False
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
# Speaker2Chatbox------------------
# @STARTUP_OSC_ENABLED_CHECK.setter
# def STARTUP_OSC_ENABLED_CHECK(self, value):
# if isinstance(value, bool):
# self._STARTUP_OSC_ENABLED_CHECK = value
# saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('ENABLE_LOGGER')
@@ -529,7 +660,8 @@ class Config:
def init_config(self):
# Read Only
self._VERSION = "2.0.1"
self._VERSION = "2.0.2"
self._ENABLE_SPEAKER2CHATBOX = False # Speaker2Chatbox
self._LOCAL_PATH = os_path.dirname(sys.argv[0])
self._PATH_CONFIG = os_path.join(self._LOCAL_PATH, "config.json")
self._PATH_LOGS = os_path.join(self._LOCAL_PATH, "logs")
@@ -537,6 +669,17 @@ class Config:
self._GITHUB_URL = "https://api.github.com/repos/misyaguziya/VRCT/releases/latest"
self._BOOTH_URL = "https://misyaguziya.booth.pm/"
self._DOCUMENTS_URL = "https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246"
self._TRANSPARENCY_RANGE = (50, 100)
self._APPEARANCE_THEME_LIST = ["Light", "Dark", "System"]
self._UI_SCALING_LIST = generatePercentageStringsList(start=40, end=200, step=10)
self._TEXTBOX_UI_SCALING_RANGE = (50, 200)
self._MESSAGE_BOX_RATIO_RANGE = (1, 99)
self._SELECTABLE_UI_LANGUAGES_DICT = {
"en": "English",
"ja": "日本語",
"ko": "한국어"
# If you want to add a new language and key, please append it here.
}
self._MAX_MIC_ENERGY_THRESHOLD = 2000
self._MAX_SPEAKER_ENERGY_THRESHOLD = 4000
@@ -568,11 +711,19 @@ class Config:
## Config Window
self._TRANSPARENCY = 100
self._APPEARANCE_THEME = "System"
self._APPEARANCE_THEME = "Dark"
self._UI_SCALING = "100%"
self._TEXTBOX_UI_SCALING = 100
self._MESSAGE_BOX_RATIO = 10
self._FONT_FAMILY = "Yu Gothic UI"
self._UI_LANGUAGE = "en"
self._ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY = True
self._MAIN_WINDOW_GEOMETRY = {
"x_pos": "0",
"y_pos": "0",
"width": "870",
"height": "640",
}
self._CHOICE_MIC_HOST = getDefaultInputDevice()["host"]["name"]
self._CHOICE_MIC_DEVICE = getDefaultInputDevice()["device"]["name"]
self._INPUT_MIC_ENERGY_THRESHOLD = 300
@@ -594,11 +745,16 @@ class Config:
"Bing": None,
"Google": None,
}
self._MESSAGE_FORMAT = "[message]([translation])"
self._SEND_MESSAGE_FORMAT = "[message]"
self._SEND_MESSAGE_FORMAT_WITH_T = "[message]([translation])"
self._RECEIVED_MESSAGE_FORMAT = "[message]"
self._RECEIVED_MESSAGE_FORMAT_WITH_T = "[message]([translation])"
self._ENABLE_AUTO_CLEAR_MESSAGE_BOX = True
self._ENABLE_SEND_ONLY_TRANSLATED_MESSAGES = False
self._SEND_MESSAGE_BUTTON_TYPE = "show"
self._ENABLE_NOTICE_XSOVERLAY = False
self._ENABLE_SEND_MESSAGE_TO_VRC = True
# self._STARTUP_OSC_ENABLED_CHECK = True # [deprecated]
self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = False # Speaker2Chatbox
self._ENABLE_LOGGER = False
self._IS_CONFIG_WINDOW_COMPACT_MODE = False
@@ -607,8 +763,13 @@ class Config:
with open(self.PATH_CONFIG, 'r', encoding="utf-8") as fp:
config = json_load(fp)
old_message_format = None
for key in config.keys():
if key == "MESSAGE_FORMAT":
old_message_format = config[key]
setattr(self, key, config[key])
if old_message_format is not None:
setattr(self, "SEND_MESSAGE_FORMAT_WITH_T", old_message_format)
with open(self.PATH_CONFIG, 'w', encoding="utf-8") as fp:
config = {}

View File

@@ -4,14 +4,16 @@ from threading import Thread
from config import config
from model import model
from view import view
from utils import get_key_by_value, isUniqueStrings
from languages import selectable_languages
from utils import getKeyByValue, isUniqueStrings, strPctToInt
import argparse
# Common
def callbackUpdateSoftware():
setMainWindowGeometry()
model.updateSoftware()
def callbackRestartSoftware():
setMainWindowGeometry()
model.reStartSoftware()
def callbackFilepathLogs():
@@ -22,6 +24,37 @@ def callbackFilepathConfigFile():
print("callbackFilepathConfigFile", config.LOCAL_PATH.replace('/', '\\'))
Popen(['explorer', config.LOCAL_PATH.replace('/', '\\')], shell=True)
def callbackQuitVrct():
setMainWindowGeometry()
def setMainWindowGeometry():
PRE_SCALING_INT = strPctToInt(view.getPreUiScaling())
NEW_SCALING_INT = strPctToInt(config.UI_SCALING)
MULTIPLY_FLOAT = (NEW_SCALING_INT / PRE_SCALING_INT)
main_window_geometry = view.getMainWindowGeometry(return_int=True)
main_window_geometry["width"] = str(int(main_window_geometry["width"] * MULTIPLY_FLOAT))
main_window_geometry["height"] = str(int(main_window_geometry["height"] * MULTIPLY_FLOAT))
main_window_geometry["x_pos"] = str(main_window_geometry["x_pos"])
main_window_geometry["y_pos"] = str(main_window_geometry["y_pos"])
config.MAIN_WINDOW_GEOMETRY = main_window_geometry
def messageFormatter(format_type:str, translation, message):
if format_type == "RECEIVED":
FORMAT_WITH_T = config.RECEIVED_MESSAGE_FORMAT_WITH_T
FORMAT = config.RECEIVED_MESSAGE_FORMAT
elif format_type == "SEND":
FORMAT_WITH_T = config.SEND_MESSAGE_FORMAT_WITH_T
FORMAT = config.SEND_MESSAGE_FORMAT
else:
raise ValueError("format_type is not found", format_type)
if len(translation) > 0:
osc_message = FORMAT_WITH_T.replace("[message]", message)
osc_message = osc_message.replace("[translation]", translation)
else:
osc_message = FORMAT.replace("[message]", message)
return osc_message
# func transcription send message
def sendMicMessage(message):
if len(message) > 0:
@@ -40,13 +73,16 @@ def sendMicMessage(message):
if config.ENABLE_TRANSCRIPTION_SEND is True:
if config.ENABLE_SEND_MESSAGE_TO_VRC is True:
if len(translation) > 0:
osc_message = config.MESSAGE_FORMAT.replace("[message]", message)
osc_message = osc_message.replace("[translation]", translation)
if config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES is True:
if config.ENABLE_TRANSLATION is False:
osc_message = messageFormatter("SEND", "", message)
else:
osc_message = messageFormatter("SEND", "", translation)
else:
osc_message = message
osc_message = messageFormatter("SEND", translation, message)
model.oscSendMessage(osc_message)
view.printToTextbox_SentMessage(message, translation)
if config.ENABLE_LOGGER is True:
if len(translation) > 0:
@@ -104,13 +140,17 @@ def receiveSpeakerMessage(message):
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
if config.ENABLE_NOTICE_XSOVERLAY is True:
if len(translation) > 0:
xsoverlay_message = config.MESSAGE_FORMAT.replace("[message]", message)
xsoverlay_message = xsoverlay_message.replace("[translation]", translation)
else:
xsoverlay_message = message
xsoverlay_message = messageFormatter("RECEIVED", translation, message)
model.notificationXSOverlay(xsoverlay_message)
# ------------Speaker2Chatbox------------
if config.ENABLE_SPEAKER2CHATBOX is True:
# send OSC message
if config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC is True:
osc_message = messageFormatter("RECEIVED", translation, message)
model.oscSendMessage(osc_message)
# ------------Speaker2Chatbox------------
# update textbox message log (Received)
view.printToTextbox_ReceivedMessage(message, translation)
if config.ENABLE_LOGGER is True:
@@ -170,11 +210,13 @@ def sendChatMessage(message):
# send OSC message
if config.ENABLE_SEND_MESSAGE_TO_VRC is True:
if len(translation) > 0:
osc_message = config.MESSAGE_FORMAT.replace("[message]", message)
osc_message = osc_message.replace("[translation]", translation)
if config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES is True:
if config.ENABLE_TRANSLATION is False:
osc_message = messageFormatter("SEND", "", message)
else:
osc_message = messageFormatter("SEND", "", translation)
else:
osc_message = message
osc_message = messageFormatter("SEND", translation, message)
model.oscSendMessage(osc_message)
# update textbox message log (Sent)
@@ -188,7 +230,7 @@ def sendChatMessage(message):
if config.ENABLE_AUTO_CLEAR_MESSAGE_BOX is True:
view.clearMessageBox()
def messageBoxPressKeyEnter(e):
def messageBoxPressKeyEnter():
model.oscStopSendTyping()
message = view.getTextFromMessageBox()
sendChatMessage(message)
@@ -277,16 +319,20 @@ def callbackToggleTranscriptionSend(is_turned_on):
config.ENABLE_TRANSCRIPTION_SEND = is_turned_on
if config.ENABLE_TRANSCRIPTION_SEND is True:
startThreadingTranscriptionSendMessage()
view.changeTranscriptionDisplayStatus("MIC_ON")
else:
stopThreadingTranscriptionSendMessage()
view.changeTranscriptionDisplayStatus("MIC_OFF")
def callbackToggleTranscriptionReceive(is_turned_on):
view.setMainWindowAllWidgetsStatusToDisabled()
config.ENABLE_TRANSCRIPTION_RECEIVE = is_turned_on
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
startThreadingTranscriptionReceiveMessage()
view.changeTranscriptionDisplayStatus("SPEAKER_ON")
else:
stopThreadingTranscriptionReceiveMessage()
view.changeTranscriptionDisplayStatus("SPEAKER_OFF")
def callbackToggleForeground(is_turned_on):
config.ENABLE_FOREGROUND = is_turned_on
@@ -319,9 +365,7 @@ def callbackCloseConfigWindow():
model.stopCheckMicEnergy()
model.stopCheckSpeakerEnergy()
view.initMicThresholdCheckButton()
# view.initProgressBar_MicEnergy() # ProgressBarに0をセットしたい
view.initSpeakerThresholdCheckButton()
# view.initProgressBar_SpeakerEnergy() # ProgressBarに0をセットしたい
if config.ENABLE_TRANSCRIPTION_SEND is True:
startThreadingTranscriptionSendMessageOnCloseConfigWindow()
@@ -366,7 +410,7 @@ def callbackSetAppearance(value):
def callbackSetUiScaling(value):
print("callbackSetUiScaling", value)
config.UI_SCALING = value
new_scaling_float = int(value.replace("%", "")) / 100
new_scaling_float = strPctToInt(value) / 100
print("callbackSetUiScaling_new_scaling_float", new_scaling_float)
view.showRestartButtonIfRequired()
@@ -375,6 +419,11 @@ def callbackSetTextboxUiScaling(value):
config.TEXTBOX_UI_SCALING = int(value)
view.setMainWindowTextboxUiSize(config.TEXTBOX_UI_SCALING/100)
def callbackSetMessageBoxRatio(value):
print("callbackSetMessageBoxRatio", int(value))
config.MESSAGE_BOX_RATIO = int(value)
view.setMainWindowMessageBoxRatio(config.MESSAGE_BOX_RATIO)
def callbackSetFontFamily(value):
print("callbackSetFontFamily", value)
config.FONT_FAMILY = value
@@ -382,11 +431,15 @@ def callbackSetFontFamily(value):
def callbackSetUiLanguage(value):
print("callbackSetUiLanguage", value)
value = get_key_by_value(selectable_languages, value)
print("callbackSetUiLanguage__after_get_key_by_value", value)
value = getKeyByValue(config.SELECTABLE_UI_LANGUAGES_DICT, value)
print("callbackSetUiLanguage__after_getKeyByValue", value)
config.UI_LANGUAGE = value
view.showRestartButtonIfRequired(locale=config.UI_LANGUAGE)
def callbackSetEnableRestoreMainWindowGeometry(value):
print("callbackSetEnableAutoClearMessageBox", value)
config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY = value
# Translation Tab
def callbackSetDeeplAuthkey(value):
print("callbackSetDeeplAuthkey", str(value))
@@ -408,7 +461,8 @@ def callbackSetDeeplAuthkey(value):
config.AUTH_KEYS = auth_keys
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
# Transcription Tab (Mic)
# Transcription Tab
# Transcription (Mic)
def callbackSetMicHost(value):
print("callbackSetMicHost", value)
config.CHOICE_MIC_HOST = value
@@ -539,10 +593,12 @@ def callbackDeleteMicWordFilter(value):
new_input_mic_word_filter_list.remove(str(value))
config.INPUT_MIC_WORD_FILTER = new_input_mic_word_filter_list
view.setLatestConfigVariable("MicMicWordFilter")
model.resetKeywordProcessor()
model.addKeywords()
except Exception:
print("There was no the target word in config.INPUT_MIC_WORD_FILTER")
# Transcription (Speaker)
def callbackSetSpeakerEnergyThreshold(value):
print("callbackSetSpeakerEnergyThreshold", value)
if value == "":
@@ -566,7 +622,6 @@ def callbackSetSpeakerDynamicEnergyThreshold(value):
else:
view.openSpeakerEnergyThresholdWidget()
def setProgressBarSpeakerEnergy(energy):
view.updateSetProgressBar_SpeakerEnergy(energy)
@@ -637,6 +692,15 @@ def callbackSetEnableAutoClearMessageBox(value):
print("callbackSetEnableAutoClearMessageBox", value)
config.ENABLE_AUTO_CLEAR_MESSAGE_BOX = value
def callbackSetEnableSendOnlyTranslatedMessages(value):
print("callbackSetEnableSendOnlyTranslatedMessages", value)
config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES = value
def callbackSetSendMessageButtonType(value):
print("callbackSetSendMessageButtonType", value)
config.SEND_MESSAGE_BUTTON_TYPE = value
view.changeMainWindowSendMessageButton(config.SEND_MESSAGE_BUTTON_TYPE)
def callbackSetEnableNoticeXsoverlay(value):
print("callbackSetEnableNoticeXsoverlay", value)
config.ENABLE_NOTICE_XSOVERLAY = value
@@ -650,26 +714,60 @@ def callbackSetEnableAutoExportMessageLogs(value):
else:
model.stopLogger()
def callbackSetMessageFormat(value):
print("callbackSetMessageFormat", value)
if len(value) > 0:
if isUniqueStrings(["[message]", "[translation]"], value) is True:
config.MESSAGE_FORMAT = value
view.clearErrorMessage()
view.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
else:
view.showErrorMessage_MessageFormat()
view.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
def callbackSetEnableSendMessageToVrc(value):
print("callbackSetEnableSendMessageToVrc", value)
config.ENABLE_SEND_MESSAGE_TO_VRC = value
# [deprecated]
# def callbackSetStartupOscEnabledCheck(value):
# print("callbackSetStartupOscEnabledCheck", value)
# config.STARTUP_OSC_ENABLED_CHECK = value
# Others (Message Formats(Send)
def callbackSetSendMessageFormat(value):
print("callbackSetSendMessageFormat", value)
if isUniqueStrings(["[message]"], value) is True:
config.SEND_MESSAGE_FORMAT = value
view.clearErrorMessage()
view.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
else:
view.showErrorMessage_SendMessageFormat()
view.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
def callbackSetSendMessageFormatWithT(value):
print("callbackSetSendMessageFormatWithT", value)
if len(value) > 0:
if isUniqueStrings(["[message]", "[translation]"], value) is True:
config.SEND_MESSAGE_FORMAT_WITH_T = value
view.clearErrorMessage()
view.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
else:
view.showErrorMessage_SendMessageFormatWithT()
view.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
# Others (Message Formats(Received)
def callbackSetReceivedMessageFormat(value):
print("callbackSetReceivedMessageFormat", value)
if isUniqueStrings(["[message]"], value) is True:
config.RECEIVED_MESSAGE_FORMAT = value
view.clearErrorMessage()
view.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
else:
view.showErrorMessage_ReceivedMessageFormat()
view.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
def callbackSetReceivedMessageFormatWithT(value):
print("callbackSetReceivedMessageFormatWithT", value)
if len(value) > 0:
if isUniqueStrings(["[message]", "[translation]"], value) is True:
config.RECEIVED_MESSAGE_FORMAT_WITH_T = value
view.clearErrorMessage()
view.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
else:
view.showErrorMessage_ReceivedMessageFormatWithT()
view.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
# ---------------------Speaker2Chatbox---------------------
def callbackSetEnableSendReceivedMessageToVrc(value):
print("callbackSetEnableSendReceivedMessageToVrc", value)
config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = value
# ---------------------Speaker2Chatbox---------------------
# Advanced Settings Tab
def callbackSetOscIpAddress(value):
@@ -684,11 +782,25 @@ def callbackSetOscPort(value):
print("callbackSetOscPort", int(value))
config.OSC_PORT = int(value)
def initSetConfigByExeArguments():
parser = argparse.ArgumentParser()
parser.add_argument("--ip")
parser.add_argument("--port")
args = parser.parse_args()
if args.ip is not None:
config.OSC_IP_ADDRESS = str(args.ip)
view.setGuiVariable_OscIpAddress(config.OSC_IP_ADDRESS)
if args.port is not None:
config.OSC_PORT = int(args.port)
view.setGuiVariable_OscPort(config.OSC_PORT)
def createMainWindow():
# create GUI
view.createGUI()
# init config
initSetConfigByExeArguments()
initSetLanguageAndCountry()
if model.authenticationTranslator(config.CHOICE_TRANSLATOR, config.AUTH_KEYS[config.CHOICE_TRANSLATOR]) is False:
@@ -702,13 +814,10 @@ def createMainWindow():
# set word filter
model.addKeywords()
# check OSC started [deprecated]
# if config.STARTUP_OSC_ENABLED_CHECK is True and config.ENABLE_SEND_MESSAGE_TO_VRC is True:
# model.checkOSCStarted(view.printToTextbox_OSCError)
# check Software Updated
if model.checkSoftwareUpdated() is True:
view.showUpdateAvailableButton()
if config.ENABLE_SPEAKER2CHATBOX is False:
if model.checkSoftwareUpdated() is True:
view.showUpdateAvailableButton()
# init logger
if config.ENABLE_LOGGER is True:
@@ -721,6 +830,7 @@ def createMainWindow():
"callback_restart_software": callbackRestartSoftware,
"callback_filepath_logs": callbackFilepathLogs,
"callback_filepath_config_file": callbackFilepathConfigFile,
"callback_quit_vrct": callbackQuitVrct,
},
window_action_registers={
@@ -759,8 +869,10 @@ def createMainWindow():
"callback_set_appearance": callbackSetAppearance,
"callback_set_ui_scaling": callbackSetUiScaling,
"callback_set_textbox_ui_scaling": callbackSetTextboxUiScaling,
"callback_set_message_box_ratio": callbackSetMessageBoxRatio,
"callback_set_font_family": callbackSetFontFamily,
"callback_set_ui_language": callbackSetUiLanguage,
"callback_set_enable_restore_main_window_geometry": callbackSetEnableRestoreMainWindowGeometry,
# Translation Tab
"callback_set_deepl_authkey": callbackSetDeeplAuthkey,
@@ -789,11 +901,21 @@ def createMainWindow():
# Others Tab
"callback_set_enable_auto_clear_chatbox": callbackSetEnableAutoClearMessageBox,
"callback_set_send_only_translated_messages": callbackSetEnableSendOnlyTranslatedMessages,
"callback_set_send_message_button_type": callbackSetSendMessageButtonType,
"callback_set_enable_notice_xsoverlay": callbackSetEnableNoticeXsoverlay,
"callback_set_enable_auto_export_message_logs": callbackSetEnableAutoExportMessageLogs,
"callback_set_message_format": callbackSetMessageFormat,
"callback_set_enable_send_message_to_vrc": callbackSetEnableSendMessageToVrc,
# "callback_set_startup_osc_enabled_check": callbackSetStartupOscEnabledCheck, # [deprecated]
# Others(Message Formats(Send)
"callback_set_send_message_format": callbackSetSendMessageFormat,
"callback_set_send_message_format_with_t": callbackSetSendMessageFormatWithT,
# Others(Message Formats(Received)
"callback_set_received_message_format": callbackSetReceivedMessageFormat,
"callback_set_received_message_format_with_t": callbackSetReceivedMessageFormatWithT,
# Speaker2Chatbox----------------
"callback_set_enable_send_received_message_to_vrc": callbackSetEnableSendReceivedMessageToVrc,
# Speaker2Chatbox----------------
# Advanced Settings Tab
"callback_set_osc_ip_address": callbackSetOscIpAddress,

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,6 +0,0 @@
selectable_languages = {
"en": "English",
"ja": "日本語",
"ko": "한국어(일부 지원)"
# 新しい言語とキーを追加する場合はここに追記してください
}

View File

@@ -82,6 +82,9 @@ config_window:
transcription_mic: Mic
transcription_speaker: Speaker
others: Others
others_send_message_formats: Message Formats(Send)
others_received_message_formats: Message Formats(Received)
others_speaker2chatbox: Speaker2Chatbox
advanced_settings: Advanced Settings
@@ -91,7 +94,7 @@ config_window:
appearance_theme:
label: Theme
desc: Change the color theme. Currently.
desc: Change the color theme.
ui_size:
label: UI Size
@@ -100,12 +103,20 @@ config_window:
label: Text Box Font Size
desc: You can adjust the font size used in the logs relative to the UI size.
message_box_ratio:
label: Message Box Size
desc: "You can change the size of the input message box. It is in ratio to the text box.\n*No exact calculations."
font_family:
label: Font Family
ui_language:
label: UI Language
to_restore_main_window_geometry:
label: Remember The Main Window Position
desc: Restore the position and size of the previous window upon startup.
deepl_auth_key:
label: DeepL Auth Key
@@ -171,6 +182,15 @@ config_window:
auto_clear_the_message_box:
label: Auto Clear The Message Box
send_only_translated_messages:
label: Send Only Translated Messages
send_message_button_type:
label: Send Message Button
hide: Hide (Use enter key to send)
show: Show
show_and_disable_enter_key: Show and disable to send when pressed enter key
notice_xsoverlay:
label: Notification XSOverlay (VR Only)
desc: Notify received messages by using XSOverlay's notification feature.
@@ -179,16 +199,43 @@ config_window:
label: Auto Export Message Logs
desc: Automatically export the conversation messages as a text file.
message_format:
label: Message Format
desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\nIt will be used in Notification XSOverlay too."
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' and '[translation]' cannot be used."
send_message_to_vrc:
label: Send Message To VRChat
desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat.
send_message_format:
label: Message Format
desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message."
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' cannot be used."
send_message_format_with_t:
label: Message Format(With translation)
desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message."
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' and '[translation]' cannot be used."
received_message_format:
label: Message Format
desc: "You can change the decoration of the received message you want to send.\n[message] will be replaced with the message.\nIt will be used in Notification XSOverlay too."
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' cannot be used."
received_message_format_with_t:
label: Message Format(With translation)
desc: It will be used in Notification XSOverlay too.
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' and '[translation]' cannot be used."
# Note: Speaker2Chatbox localization is fine only in English. Do not translate it into other languages.
# Speaker2Chatbox
send_received_message_to_vrc:
label: Send Received Message To VRChat
desc: Send the message you received from the speaker's sound to VRChat's chatbox. However, this feature is intended for users who genuinely need it. Please consult with the developer.
# Speaker2Chatbox
osc_ip_address:
label: OSC IP Address

View File

@@ -100,12 +100,20 @@ config_window:
label: テキストボックス フォントサイズ
desc: ログに表示されるフォントのサイズを、UIサイズを基準にして倍率を変えられます。
message_box_ratio:
label: メッセージ入力欄のサイズ
desc: "メッセージ入力欄のサイズを変更できます。テキストボックスとの比率となっています。\n※厳密な計算はしていません。"
font_family:
label: 使用フォント
ui_language:
label: UIの言語 / UI Language
to_restore_main_window_geometry:
label: メイン画面の位置を記憶する
desc: 起動時、前回の画面の位置とサイズを復元します。
deepl_auth_key:
label: DeepL 認証キー
@@ -167,9 +175,19 @@ config_window:
desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。
error_message: 0以上の数値を設定できます。
auto_clear_the_message_box:
label: 送信後はチャットボックスを空にする
send_only_translated_messages:
label: 翻訳後のメッセージのみ送信する
send_message_button_type:
label: メッセージ送信ボタン
hide: 非表示 (エンターキーを使って送信)
show: 表示
show_and_disable_enter_key: 表示し、エンターキーでの送信を無効
notice_xsoverlay:
label: XSOverlayでの通知受け取り機能を有効 (VR限定)
desc: 文字起こし受信されたメッセージをXSOverlayの機能を使って通知として受け取れます。
@@ -178,16 +196,36 @@ config_window:
label: 会話ログを自動的に保存する
desc: テキストファイルとしてログがlogsフォルダ内に保存されます。
message_format:
label: 送信するメッセージのフォーマット
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能でも使われます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]と[translation]という文字は使えません。"
send_message_to_vrc:
label: VRChatにメッセージを送信する
desc: "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。"
send_message_format:
label: 送信するメッセージのフォーマット
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換されます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]という文字は使えません。"
send_message_format_with_t:
label: 送信するメッセージのフォーマット(翻訳付き)
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]と[translation]という文字は使えません。"
received_message_format:
label: 送信するメッセージのフォーマット
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換されます。\n※XSOverlayでの通知受け取り機能にも使われます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]という文字は使えません。"
received_message_format_with_t:
label: 送信するメッセージのフォーマット(翻訳付き)
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能にも使われます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]と[translation]という文字は使えません。"
osc_ip_address:
label: OSC IP Address

View File

@@ -1,188 +1,239 @@
main_window:
translation: 번역
transcription_send: 마이크 -> 챗박스
transcription_receive: 스피커 -> 로그
transcription_send: 음성인식 (마이크)
transcription_receive: 음성인식 (스피커)
foreground: 항상 위로
# language_settings: Language Settings
# your_language: Your Language
# both_direction_desc: Translate Each Other
# target_language: Target Language
language_settings: 언어 설정
your_language: 당신의 언어
both_direction_desc: 양방향으로 번역
swap_button_label: 언어 교체
target_language: 상대방의 언어
textbox_tab_all: 전체
textbox_tab_sent: 전송
textbox_tab_received: 수신
textbox_tab_system: 시스템
# textbox_system_message:
# enabled_translation: Translation feature is turned on.
# disabled_translation: Translation feature is turned off.
# enabled_voice2chatbox: Transcription from the microphone has started.
# disabled_voice2chatbox: Transcription from the microphone has been stopped.
# enabled_speaker2log: Transcription from the speaker has started.
# disabled_speaker2log: Transcription from the speaker has been stopped.
# enabled_foreground: The screen is fixed in the foreground.
# disabled_foreground: The foreground fixation has been released.
textbox_system_message:
enabled_translation: 번역 기능을 시작합니다.
disabled_translation: 번역 기능이 중지되었습니다.
enabled_voice2chatbox: 마이크에서의 음성인식을 시작합니다.
disabled_voice2chatbox: 마이크에서의 음성인식이 중지되었습니다.
enabled_speaker2log: 스피커에서의 음성인식을 시작합니다.
disabled_speaker2log: 스피커에서의 음성인식이 중지되었습니다.
enabled_foreground: 화면을 항상 위로 고정합니다.
disabled_foreground: 화면 고정이 해제되었습니다.
# auth_key_success: Auth key update completed.
# auth_key_error: Auth Key is incorrect or Usage limit reached.
auth_key_success: 인증키 갱신이 완료되었습니다.
auth_key_error: 인증 키가 잘못되었거나 API 사용 제한이 상한선에 도달했습니다.
# no_mic_device_detected_error: No mic device detected.
# no_speaker_device_detected_error: No speaker device detected.
# translation_engine_limit_error: It has automatically disabled the translation feature. Access has been temporarily restricted due to an excessive number of requests to the translation engine. Please wait for a while, restart VRCT, and try again.
no_mic_device_detected_error: 마이크 디바이스를 찾지 못했습니다.
no_speaker_device_detected_error: 스피커 디바이스를 찾지 못했습니다.
translation_engine_limit_error: 번역 기능이 자동으로 중지되었습니다. 번역 엔진에 대한 요청이 너무 많아 일시적으로 사용이 제한되고 있습니다. 잠시 기다렸다가 VRCT를 재부팅하고 다시 시도해 보세요.
# detected_by_word_filter: The word %{detected_message} has not been sent due to detection by the word filter.
detected_by_word_filter: 단어 필터에 등록된 단어 %{detected_message}(이)가 감지되어 전송하지 않았습니다.
# selected_your_language: "\"Your Language\" has set to %{your_language}."
# selected_target_language: "\"Target Language\" has set to %{target_language}."
# switched_language_preset_tab: Switched to Language Preset Tab No.%{tab_no}."
# latest_language_setting: "Currently, \"Your Language\" is set to %{your_language}, and \"Target Language\" is set to %{target_language}."
selected_your_language: "'당신의 언어'가 %{your_language}(으)로 설정되었습니다."
selected_target_language: "'상대방의 언어'가 %{target_language}(으)로 설정되었습니다."
switched_language_preset_tab: 언어 프리셋 번호 %{tab_no}로 전환되었습니다.
latest_language_setting: "현재 '당신의 언어'는 %{your_language}, '상대방의 언어'는 %{target_language}(으)로 설정되어 있습니다."
# opened_web_page_booth: Opened Booth page in your web browser.
# opened_web_page_vrct_documents: "Opened VRCT Documents page in your web browser.\nFor any issues, requests, or inquiries, please feel free to contact us through the links at the bottom of the documents page, the \"Contact Form,\" or via X (formerly Twitter)!"
opened_web_page_booth: 브라우저에서 Booth 페이지를 열었습니다.
opened_web_page_vrct_documents: "웹 브라우저에서 VRCT 문서 페이지가 열렸습니다.\n문제, 요청 또는 문의 사항이 있는 경우 문서 페이지 하단의 링크, '문의 양식' 또는 X(구 트위터)를 통해 언제든지 문의해 주세요!"
# update_available: New version is here!
update_available: 새로운 버전이 나왔습니다!
# cover_message: The functionality is temporarily disabled until the settings window is closed.
cover_message: 설정 화면이 닫힐 때까지 일시적으로 기능을 정지하고 있습니다.
# confirmation_message:
# update_software: "Download new version and restart automatically.\nIt'll take a while. Do it now?"
# deny_update_software: Do it later
# accept_update_software: Update and Restart
# updating: Now updating...
confirmation_message:
update_software: "새 버전을 다운로드하고 재부팅합니다. \n 조금 시간이 걸릴 수 있습니다. 지금 시작할까요?"
deny_update_software: 나중에 하기
accept_update_software: 업데이트 및 재부팅
updating: 업데이트 중...
# detected_over_ui_size: "Current UI Size: %{current_ui_size}\nVRCT's window size may be larger than your display size.\n* Depending on your display size, you may need to adjust it multiple times."
# deny_adjust_ui_size: "Keep it at this size"
# accept_adjust_ui_size: "Set it smaller and restart"
detected_over_ui_size: "현재 UI 크기: %{current_ui_size}\nVRCT의 창 크기가 사용자의 디스플레이 크기보다 클 수 있습니다. \n* 디스플레이 크기에 따라 여러 번 재설정해야 할 수도 있습니다."
deny_adjust_ui_size: "지금 상태를 유지"
accept_adjust_ui_size: "작게 줄이고 재부팅"
# translation_engine_limit_error: "It has automatically disabled the translation feature.\nAccess has been temporarily restricted\ndue to an excessive number of requests to the translation engine.\nPlease wait for a while, restart VRCT, and try again."
# accept_translation_engine_limit_error: Accept and close
translation_engine_limit_error: "번역 기능이 자동으로 중지되었습니다. \n번역 엔진에 대한 요청이 너무 많아 \n일시적으로 사용이 제한되었습니다. \n잠시 기다렸다가 VRCT를 재부팅한 후 다시 시도해 보십시오."
accept_translation_engine_limit_error: 확인하고 닫기
# selectable_language_window:
# title_your_language: Select Your Language
# title_target_language: Select Target Language
# go_back_button: Go Back
selectable_language_window:
title_your_language: 당신의 언어
title_target_language: 상대방의 언어
go_back_button: 돌아가기
config_window:
# config_title: Settings
# compact_mode: Compact Mode
# version: version %{version}
# restart_message: Apply changes with a restart.
# common_error_message:
# invalid_value: Invalid value.
config_title: 설정
compact_mode: 컴팩트 모드
version: 버전 %{version}
restart_message: 재부팅하여 변경 사항을 적용합니다.
common_error_message:
invalid_value: 유효하지 않은 값입니다.
side_menu_labels:
# appearance: Appearance
appearance: 모양
translation: 번역
transcription: 음성인식
transcription_mic: 마이크
transcription_speaker: 스피커
others: 기타
# advanced_settings: Advanced Settings
others_send_message_formats: 메시지 형식 (전송)
others_received_message_formats: 메시지 형식 (수신)
others_speaker2chatbox: 스피커->챗박스
advanced_settings: 고급 설정
transparency:
label: 투명도
# desc: Change the main window's transparency.
desc: 메인 화면의 투명도를 변경합니다.
appearance_theme:
label: 테마
# desc: Change the color theme. Currently, only the Dark theme is supported. The Light theme is under development.
desc: 색상 테마를 변경합니다.
ui_size:
label: UI 크기
textbox_ui_size:
label: 텍스트 박스 글자 크기
desc: 로그에 표시되는 글자 크기의 배율을 UI 크기에 따라 변경합니다.
message_box_ratio:
label: 메시지 입력란 크기
desc: "메시지 입력란의 크기를 변경합니다. 텍스트 박스와의 비율로 설정되어 있습니다. \n* 정확한 계산은 하지 않았습니다."
font_family:
label: 폰트
ui_language:
label: UI 언어 / UI Language
to_restore_main_window_geometry:
label: 메인 화면 위치 기억
desc: 시작 시 이전 화면의 위치와 크기를 복원합니다.
deepl_auth_key:
label: DeepL 인증키
mic_host:
label: 마이크 호스트/Driver
label: 마이크 호스트/드라이버
mic_device:
label: 마이크 장치
mic_dynamic_energy_threshold:
label_for_automatic: "음성 입력 최소 볼륨 (Current Setting: Automatic)"
# desc_for_automatic: "Automatically determine microphone input sensitivity."
label_for_manual: "음성 입력 최소 볼륨 (Current Setting: Manual)"
# desc_for_manual: "Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume."
# error_message: You can set it with a value between 0 to %{max}.
label_for_automatic: "음성 입력 최소 볼륨 (현재 설정: 자동)"
desc_for_automatic: "마이크의 입력 감도를 자동으로 조절합니다."
label_for_manual: "음성 입력 최소 볼륨 (현재 설정: 수동)"
desc_for_manual: "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 마이크 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다."
error_message: 0에서 %{max}까지의 숫자로만 설정할 수 있습니다.
mic_record_timeout:
label: 최대 무음 시간
# desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s))
# error_message: It cannot be greater than '%{mic_phrase_timeout_label}' with a value of 0 or more.
desc: 무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.
error_message: 0 이상에서 '%{mic_phrase_timeout_label}'보다 클 수 없습니다.
mic_phrase_timeout:
label: 최대 인식 시간
# desc: Transcription processing is performed at intervals of the specified number of seconds.
# error_message: It cannot be set lower than '%{mic_record_timeout_label}' with a value of 0 or more.
desc: 설정된 초 단위로 음성인식 처리가 이루어집니다.
error_message: 0 이상에서 '%{mic_record_timeout_label}'보다 작을 수 없습니다.
mic_max_phrase:
label: 최대 입력 절(phrases) 수
# desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat.
# error_message: You can set a number equal to or greater than 0.
desc: 인식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 VRChat으로 전송하고 로그에 표시합니다.
error_message: 0 이상의 숫자만 설정할 수 있습니다.
mic_word_filter:
label: 단어 필터
# desc: "It will not send the sentence if the word(s) included in the set list of words.\nHow to set: e.g. AAA,BBB,CCC"
desc: "등록된 단어가 감지되면 해당 문장은 전송되지 않습니다. \n ',' 쉼표로 구분하면 여러 단어를 추가할 수 있습니다. \n* 중복된 단어는 등록되지 않습니다."
add_button_label: 추가
count_desc: "현재 등록되어 있는 단어 수: %{count}"
speaker_dynamic_energy_threshold:
label_for_automatic: "음성 입력 최소 볼륨 (Current Setting: Automatic)"
# desc_for_automatic: "Automatically determine speaker input sensitivity."
label_for_manual: "음성 입력 최소 볼륨 (Current Setting: Manual)"
# desc_for_manual: "Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume."
# error_message: You can set it with a value between 0 to %{max}.
# no_device_error_message: No speaker device detected.
label_for_automatic: "음성 입력 최소 볼륨 (현재 설정: 자동)"
desc_for_automatic: "스피커의 입력 감도를 자동으로 조절합니다."
label_for_manual: "음성 입력 최소 볼륨 (현재 설정: 수동)"
desc_for_manual: "슬라이더를 움직여 입력 감도를 수동으로 조절합니다. 헤드폰 아이콘을 누르면 실제 음성의 볼륨을 확인하며 감도를 조절할 수 있습니다."
error_message: 0에서 %{max}까지의 숫자로만 설정할 수 있습니다.
no_device_error_message: 스피커 디바이스를 찾지 못했습니다.
speaker_record_timeout:
label: 최대 무음 시간
# desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))
# error_message: It cannot be greater than '%{speaker_phrase_timeout_label}' with a value of 0 or more.
desc: 무음을 감지하고 설정된 시간(초)만큼의 시간이 지나면 음성 입력이 종료된 것으로 판단합니다.
error_message: 0 이상에서 '%{speaker_phrase_timeout_label}'보다 클 수 없습니다.
speaker_phrase_timeout:
label: 최대 인식 시간
# desc: Transcription processing is performed at intervals of the specified number of seconds.
# error_message: It cannot be set lower than '%{speaker_record_timeout_label}' with a value of 0 or more.
desc: 설정된 초 단위로 음성인식 처리가 이루어집니다.
error_message: 0 이상에서 '%{speaker_record_timeout_label}'보다 작을 수 없습니다.
speaker_max_phrase:
label: 최대 입력 절(phrases) 수
# desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs.
# error_message: You can set a number equal to or greater than 0.
desc: 식된 단어 수의 하한값으로, 이 수치를 초과하는 경우에만 결과를 로그에 표시합니다.
error_message: 0 이상의 숫자만 설정할 수 있습니다.
auto_clear_the_message_box:
label: 챗박스 자동 삭제
# notice_xsoverlay:
# label: Notification XSOverlay (VR Only)
# desc: Notify received messages by using XSOverlay's notification feature.
send_only_translated_messages:
label: 번역된 메시지만 전송
# auto_export_message_logs:
# label: Auto Export Message Logs
# desc: Automatically export the conversation messages as a text file.
send_message_button_type:
label: 메시지 전송 버튼
hide: 숨김 (Enter 키를 사용하여 전송)
show: 표시
show_and_disable_enter_key: 표시 (Enter 키 전송 비활성화)
message_format:
label: 전송 형식
# desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\nIt will be used in Notification XSOverlay too."
notice_xsoverlay:
label: XSOverlay에서 알림 수신 기능 활성화 (VR 전용)
desc: 수신된 메시지를 XSOverlay의 기능을 통해 알림으로 받아볼 수 있습니다.
auto_export_message_logs:
label: 대화 로그 자동 저장
desc: logs 폴더에 텍스트 파일로 로그가 저장됩니다.
send_message_to_vrc:
label: VRChat에 메시지 전송
desc: "VRChat에 메시지를 보내지 않고 사용할 수 있는 방법이 있지만 지원되지 않습니다. VRChat에 메시지를 보내려면 이 기능을 활성화하세요."
send_message_format:
label: 메시지 형식
desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다."
example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
error_message: "[message]라는 문자는 사용할 수 없습니다."
send_message_format_with_t:
label: 메시지 형식 (번역 포함)
desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다."
example_text: 예문입니다. 글꼴, 줄 바꿈 등이 실제 표시와 다를 수 있습니다.
error_message: "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
received_message_format:
label: 메시지 형식
desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]가 메시지로 대체됩니다."
example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
error_message: "[message]라는 문자는 사용할 수 없습니다."
received_message_format_with_t:
label: 메시지 형식 (번역 포함)
desc: "메시지가 실제로 보이는 형식을 변경합니다. \n[message]는 메시지로, [translation]은 번역된 메시지로 대체됩니다.\nXSOverlay의 알림에서도 사용됩니다."
example_text: 이것은 예문입니다. 폰트, 줄바꿈 등 실제 표시와 다를 수 있습니다.
error_message: "[message]와 [translation]이라는 문자는 사용할 수 없습니다."
# send_message_to_vrc:
# label: Send Message To VRChat
# desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat.
osc_ip_address:
label: OSC IP 주소
osc_port:
label: OSC 포트
label: OSC 포트
open_config_filepath:
label: 설정 파일 열기

View File

@@ -1,8 +1,8 @@
import tempfile
from zipfile import ZipFile
from subprocess import Popen
from os import makedirs as os_makedirs
from os import path as os_path
from os import remove as os_remove
from shutil import copyfile
from datetime import datetime
from logging import getLogger, FileHandler, Formatter, INFO
@@ -12,6 +12,8 @@ from threading import Thread, Event
from requests import get as requests_get
import webbrowser
from tqdm import tqdm
from typing import Callable
from flashtext import KeywordProcessor
from models.translation.translation_translator import Translator
from models.transcription.transcription_utils import getInputDevices, getDefaultOutputDevice
@@ -265,7 +267,7 @@ class Model:
return update_flag
@staticmethod
def updateSoftware(restart:bool=True):
def updateSoftware(restart:bool=True, func=None):
filename = 'VRCT.zip'
program_name = 'VRCT.exe'
folder_name = '_internal'
@@ -277,14 +279,22 @@ class Model:
res = requests_get(config.GITHUB_URL)
assets = res.json()['assets']
url = [i["browser_download_url"] for i in assets if i["name"] == filename][0]
res = requests_get(url, stream=True)
os_makedirs(os_path.join(current_directory, tmp_directory_name), exist_ok=True)
with open(os_path.join(current_directory, tmp_directory_name, filename), 'wb') as file:
for chunk in res.iter_content(chunk_size=1024):
file.write(chunk)
with ZipFile(os_path.join(current_directory, tmp_directory_name, filename)) as zf:
zf.extractall(os_path.join(current_directory, tmp_directory_name))
os_remove(os_path.join(current_directory, tmp_directory_name, filename))
with tempfile.TemporaryDirectory() as tmp_path:
res = requests_get(url, stream=True)
file_size = int(res.headers.get('content-length', 0))
pbar = tqdm(total=file_size, unit="B", unit_scale=True)
total_chunk = 0
with open(os_path.join(tmp_path, filename), 'wb') as file:
for chunk in res.iter_content(chunk_size=1024*5):
file.write(chunk)
pbar.update(len(chunk))
if isinstance(func, Callable):
total_chunk += len(chunk)
func(total_chunk/file_size)
pbar.close()
with ZipFile(os_path.join(tmp_path, filename)) as zf:
zf.extractall(os_path.join(current_directory, tmp_directory_name))
copyfile(os_path.join(current_directory, folder_name, "batch", batch_name), os_path.join(current_directory, batch_name))
command = [os_path.join(current_directory, batch_name), program_name, folder_name, tmp_directory_name, str(restart)]
Popen(command, cwd=current_directory)

View File

@@ -6,4 +6,5 @@ deepl == 1.15.0
flashtext == 2.7
pyyaml == 6.0.1
python-i18n == 0.3.9
CTkToolTip == 0.8
CTkToolTip == 0.8
pyinstaller==6.2.0

View File

@@ -6,7 +6,7 @@ def getImageFile(file_name):
img = Image_open(os_path.join(os_path.dirname(__file__), "img", file_name))
return img
def get_key_by_value(dictionary, value):
def getKeyByValue(dictionary, value):
for key, val in dictionary.items():
if val == value:
return key
@@ -24,15 +24,18 @@ def makeEven(number, minus:bool=False):
return number if isEven(number) else number - 1
return number if isEven(number) else number + 1
def generatePercentageStringsList(start=40, end=200, step=10):
def generatePercentageStringsList(start:int, end:int, step:int):
strings = []
for percent in range(start, end + 1, step):
strings.append(f"{percent}%")
return strings
def intToPercentageStringsFormatter(value:int):
def intToPctStr(value:int):
return f"{value}%"
def strPctToInt(value:str):
return int(value.replace("%", ""))
def isUniqueStrings(unique_strings:Union[str, list], input_string:str, require=False):
import re
if isinstance(unique_strings, str):

2
venv.bat Normal file
View File

@@ -0,0 +1,2 @@
python -m venv .venv
.venv/Scripts/Activate.ps1

478
view.py
View File

@@ -5,12 +5,10 @@ from tkinter import font as tk_font
import webbrowser
import i18n
from languages import selectable_languages
from customtkinter import StringVar, IntVar, BooleanVar, END as CTK_END, get_appearance_mode
from customtkinter import StringVar, IntVar, BooleanVar, get_appearance_mode
from vrct_gui.ui_managers import ColorThemeManager, UiScalingManager
from vrct_gui import vrct_gui
from utils import callFunctionIfCallable, generatePercentageStringsList, intToPercentageStringsFormatter
from utils import callFunctionIfCallable, intToPctStr
from config import config
@@ -32,6 +30,11 @@ class View():
ui_language=config.UI_LANGUAGE,
)
if config.ENABLE_SPEAKER2CHATBOX is False:
VERSION_TEXT=i18n.t("config_window.version", version=config.VERSION)
else:
VERSION_TEXT=i18n.t("config_window.version", version=config.VERSION) + " (Speaker2Chatbox)"
self.settings = SimpleNamespace()
theme = get_appearance_mode() if config.APPEARANCE_THEME == "System" else config.APPEARANCE_THEME
all_ctm = ColorThemeManager(theme)
@@ -45,6 +48,13 @@ class View():
self.settings.main = SimpleNamespace(
ctm=all_ctm.main,
uism=all_uism.main,
geometry=SimpleNamespace(
width=config.MAIN_WINDOW_GEOMETRY["width"],
height=config.MAIN_WINDOW_GEOMETRY["height"],
x_pos=config.MAIN_WINDOW_GEOMETRY["x_pos"],
y_pos=config.MAIN_WINDOW_GEOMETRY["y_pos"],
),
to_restore_main_window_geometry=config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
**common_args
)
@@ -84,10 +94,13 @@ class View():
CALLBACK_OPEN_FILEPATH_LOGS=None,
CALLBACK_OPEN_FILEPATH_CONFIG_FILE=None,
CALLBACK_QUIT_VRCT=vrct_gui._quitVRCT,
CALLBACK_DELETE_MAIN_WINDOW=self.quitVRCT,
CALLBACK_QUIT_VRCT=None,
CALLBACK_WHEN_DETECT_WINDOW_OVERED_SIZE=self._showDisplayOverUiSizeConfirmationModal,
IS_ENTRY_MESSAGE_BOX_DISABLED=False,
# Confirmation Modal
CALLBACK_HIDE_CONFIRMATION_MODAL=None,
CALLBACK_ACCEPTED_CONFIRMATION_MODAL=None,
@@ -135,7 +148,7 @@ class View():
CALLBACK_SELECTED_LANGUAGE_PRESET_TAB=None,
VAR_LABEL_YOUR_LANGUAGE=StringVar(value=i18n.t("main_window.your_language")),
VAR_YOUR_LANGUAGE = StringVar(value="Japanese\n(Japan)"),
VAR_YOUR_LANGUAGE = StringVar(value=f"{config.SOURCE_LANGUAGE}\n({config.SOURCE_COUNTRY})"),
CALLBACK_OPEN_SELECTABLE_YOUR_LANGUAGE_WINDOW=None,
IS_OPENED_SELECTABLE_YOUR_LANGUAGE_WINDOW=False,
CALLBACK_SELECTED_YOUR_LANGUAGE=None,
@@ -145,7 +158,7 @@ class View():
CALLBACK_SWAP_LANGUAGES=None,
VAR_LABEL_TARGET_LANGUAGE=StringVar(value=i18n.t("main_window.target_language")),
VAR_TARGET_LANGUAGE = StringVar(value="English\n(United States)"),
VAR_TARGET_LANGUAGE = StringVar(value=f"{config.TARGET_LANGUAGE}\n({config.TARGET_COUNTRY})"),
CALLBACK_OPEN_SELECTABLE_TARGET_LANGUAGE_WINDOW=None,
IS_OPENED_SELECTABLE_TARGET_LANGUAGE_WINDOW=False,
CALLBACK_SELECTED_TARGET_LANGUAGE=None,
@@ -172,12 +185,12 @@ class View():
ACTIVE_SETTING_BOX_TAB_ATTR_NAME="side_menu_tab_appearance",
CALLBACK_SELECTED_SETTING_BOX_TAB=None,
VAR_ERROR_MESSAGE=StringVar(value=""),
VAR_VERSION=StringVar(value=i18n.t("config_window.version", version=config.VERSION)),
VAR_VERSION=StringVar(value=VERSION_TEXT),
VAR_CONFIG_WINDOW_TITLE=StringVar(value=i18n.t("config_window.config_title")),
VAR_CONFIG_WINDOW_COMPACT_MODE_LABEL=StringVar(value=i18n.t("config_window.compact_mode")),
VAR_CONFIG_WINDOW_RESTART_BUTTON_LABEL=StringVar(value=i18n.t("config_window.restart_message")),
CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER=intToPercentageStringsFormatter,
CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER=intToPctStr,
# Side Menu Labels
@@ -194,7 +207,7 @@ class View():
# Appearance Tab
VAR_LABEL_TRANSPARENCY=StringVar(value=i18n.t("config_window.transparency.label")),
VAR_DESC_TRANSPARENCY=StringVar(value=i18n.t("config_window.transparency.desc")),
SLIDER_RANGE_TRANSPARENCY=(50, 100),
SLIDER_RANGE_TRANSPARENCY=config.TRANSPARENCY_RANGE,
CALLBACK_SET_TRANSPARENCY=None,
VAR_TRANSPARENCY=IntVar(value=config.TRANSPARENCY),
CALLBACK_BUTTON_PRESS_TRANSPARENCY=self._closeTheCoverOfMainWindow,
@@ -202,24 +215,32 @@ class View():
VAR_LABEL_APPEARANCE_THEME=StringVar(value=i18n.t("config_window.appearance_theme.label")),
VAR_DESC_APPEARANCE_THEME=StringVar(value=i18n.t("config_window.appearance_theme.desc")),
LIST_APPEARANCE_THEME=["Light", "Dark", "System"],
LIST_APPEARANCE_THEME=config.APPEARANCE_THEME_LIST,
CALLBACK_SET_APPEARANCE_THEME=None,
VAR_APPEARANCE_THEME=StringVar(value=config.APPEARANCE_THEME),
VAR_LABEL_UI_SCALING=StringVar(value=i18n.t("config_window.ui_size.label")),
VAR_DESC_UI_SCALING=None,
LIST_UI_SCALING=generatePercentageStringsList(start=40,end=200, step=10),
LIST_UI_SCALING=config.UI_SCALING_LIST,
CALLBACK_SET_UI_SCALING=None,
VAR_UI_SCALING=StringVar(value=config.UI_SCALING),
VAR_LABEL_TEXTBOX_UI_SCALING=StringVar(value=i18n.t("config_window.textbox_ui_size.label")),
VAR_DESC_TEXTBOX_UI_SCALING=StringVar(value=i18n.t("config_window.textbox_ui_size.desc")),
SLIDER_RANGE_TEXTBOX_UI_SCALING=(50, 200),
SLIDER_RANGE_TEXTBOX_UI_SCALING=config.TEXTBOX_UI_SCALING_RANGE,
CALLBACK_SET_TEXTBOX_UI_SCALING=None,
VAR_TEXTBOX_UI_SCALING=IntVar(value=config.TEXTBOX_UI_SCALING),
CALLBACK_BUTTON_PRESS_TEXTBOX_UI_SCALING=self._closeTheCoverOfMainWindow,
CALLBACK_BUTTON_RELEASE_TEXTBOX_UI_SCALING=self._openTheCoverOfMainWindow,
VAR_LABEL_MESSAGE_BOX_RATIO=StringVar(value=i18n.t("config_window.message_box_ratio.label")),
VAR_DESC_MESSAGE_BOX_RATIO=StringVar(value=i18n.t("config_window.message_box_ratio.desc")),
SLIDER_RANGE_MESSAGE_BOX_RATIO=config.MESSAGE_BOX_RATIO_RANGE,
CALLBACK_SET_MESSAGE_BOX_RATIO=None,
VAR_MESSAGE_BOX_RATIO=IntVar(value=config.MESSAGE_BOX_RATIO),
CALLBACK_BUTTON_PRESS_MESSAGE_BOX_RATIO=self._closeTheCoverOfMainWindow,
CALLBACK_BUTTON_RELEASE_MESSAGE_BOX_RATIO=self._openTheCoverOfMainWindow,
VAR_LABEL_FONT_FAMILY=StringVar(value=i18n.t("config_window.font_family.label")),
VAR_DESC_FONT_FAMILY=None,
LIST_FONT_FAMILY=self.getAvailableFonts(),
@@ -228,10 +249,14 @@ class View():
VAR_LABEL_UI_LANGUAGE=StringVar(value=i18n.t("config_window.ui_language.label")),
VAR_DESC_UI_LANGUAGE=None,
LIST_UI_LANGUAGE=list(selectable_languages.values()),
LIST_UI_LANGUAGE=list(config.SELECTABLE_UI_LANGUAGES_DICT.values()),
CALLBACK_SET_UI_LANGUAGE=None,
VAR_UI_LANGUAGE=StringVar(value=selectable_languages[config.UI_LANGUAGE]),
VAR_UI_LANGUAGE=StringVar(value=config.SELECTABLE_UI_LANGUAGES_DICT[config.UI_LANGUAGE]),
VAR_LABEL_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=StringVar(value=i18n.t("config_window.to_restore_main_window_geometry.label")),
VAR_DESC_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=StringVar(value=i18n.t("config_window.to_restore_main_window_geometry.desc")),
CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=None,
VAR_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY=BooleanVar(value=config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY),
# Translation Tab
VAR_LABEL_DEEPL_AUTH_KEY=StringVar(value=i18n.t("config_window.deepl_auth_key.label")),
@@ -334,6 +359,21 @@ class View():
CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX=None,
VAR_ENABLE_AUTO_CLEAR_MESSAGE_BOX=BooleanVar(value=config.ENABLE_AUTO_CLEAR_MESSAGE_BOX),
VAR_LABEL_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=StringVar(value=i18n.t("config_window.send_only_translated_messages.label")),
VAR_DESC_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=None,
CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=None,
VAR_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES=BooleanVar(value=config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES),
VAR_LABEL_SEND_MESSAGE_BUTTON_TYPE=StringVar(value=i18n.t("config_window.send_message_button_type.label")),
VAR_DESC_SEND_MESSAGE_BUTTON_TYPE=None,
CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE=None,
VAR_SEND_MESSAGE_BUTTON_TYPE=StringVar(value=config.SEND_MESSAGE_BUTTON_TYPE),
KEYS_VALUES_SEND_MESSAGE_BUTTON_TYPE={
"hide": StringVar(value=i18n.t("config_window.send_message_button_type.hide")),
"show": StringVar(value=i18n.t("config_window.send_message_button_type.show")),
"show_and_disable_enter_key": StringVar(value=i18n.t("config_window.send_message_button_type.show_and_disable_enter_key")),
},
VAR_LABEL_ENABLE_NOTICE_XSOVERLAY=StringVar(value=i18n.t("config_window.notice_xsoverlay.label")),
VAR_DESC_ENABLE_NOTICE_XSOVERLAY=StringVar(value=i18n.t("config_window.notice_xsoverlay.desc")),
CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY=None,
@@ -345,32 +385,78 @@ class View():
VAR_ENABLE_AUTO_EXPORT_MESSAGE_LOGS=BooleanVar(value=config.ENABLE_LOGGER),
VAR_LABEL_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.message_format.label")),
VAR_DESC_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.message_format.desc")),
CALLBACK_SET_MESSAGE_FORMAT=None,
CALLBACK_SWAP_MESSAGE_FORMAT_REQUIRED_TEXT=self._swapMessageFormatRequiredText,
VAR_MESSAGE_FORMAT=StringVar(value=config.MESSAGE_FORMAT),
VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_0_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_1_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_2_MESSAGE_FORMAT=StringVar(value=""),
VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT=StringVar(value="[message]"),
VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT=StringVar(value="[translation]"),
CALLBACK_FOCUS_OUT_MESSAGE_FORMAT=self.callbackBindFocusOut_MessageFormat,
VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.label")),
VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.desc")),
CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC=None,
VAR_ENABLE_SEND_MESSAGE_TO_VRC=BooleanVar(value=config.ENABLE_SEND_MESSAGE_TO_VRC),
# [deprecated]
# VAR_LABEL_STARTUP_OSC_ENABLED_CHECK=StringVar(value=i18n.t("config_window.startup_osc_enabled_check.label")),
# VAR_DESC_STARTUP_OSC_ENABLED_CHECK=StringVar(value=i18n.t("config_window.startup_osc_enabled_check.desc")),
# CALLBACK_SET_STARTUP_OSC_ENABLED_CHECK=None,
# VAR_STARTUP_OSC_ENABLED_CHECK=BooleanVar(value=config.STARTUP_OSC_ENABLED_CHECK),
VAR_SECOND_TITLE_OTHERS_SEND_MESSAGE_FORMATS=StringVar(value=i18n.t("config_window.side_menu_labels.others_send_message_formats")),
VAR_LABEL_SEND_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.send_message_format.label")),
VAR_DESC_SEND_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.send_message_format.desc")),
CALLBACK_SET_SEND_MESSAGE_FORMAT=None,
VAR_SEND_MESSAGE_FORMAT=StringVar(value=config.SEND_MESSAGE_FORMAT),
VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_0_SEND_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_1_SEND_MESSAGE_FORMAT=StringVar(value=""),
VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT=StringVar(value="[message]"),
CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT=self.callbackBindFocusOut_SendMessageFormat,
VAR_LABEL_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.send_message_format_with_t.label")),
VAR_DESC_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.send_message_format_with_t.desc")),
CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T=None,
CALLBACK_SWAP_SEND_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT=self._swapSendMessageFormatWithT_RequiredText,
VAR_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=config.SEND_MESSAGE_FORMAT_WITH_T),
VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value="[message]"),
VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T=StringVar(value="[translation]"),
CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT_WITH_T=self.callbackBindFocusOut_SendMessageFormatWithT,
VAR_LABEL_RECEIVED_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.received_message_format.label")),
VAR_DESC_RECEIVED_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.received_message_format.desc")),
CALLBACK_SET_RECEIVED_MESSAGE_FORMAT=None,
VAR_RECEIVED_MESSAGE_FORMAT=StringVar(value=config.RECEIVED_MESSAGE_FORMAT),
VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT=StringVar(value=""),
VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT=StringVar(value="[message]"),
CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT=self.callbackBindFocusOut_ReceivedMessageFormat,
VAR_SECOND_TITLE_OTHERS_RECEIVED_MESSAGE_FORMATS=StringVar(value=i18n.t("config_window.side_menu_labels.others_received_message_formats")),
VAR_LABEL_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.received_message_format_with_t.label")),
VAR_DESC_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=i18n.t("config_window.received_message_format_with_t.desc")),
CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T=None,
CALLBACK_SWAP_RECEIVED_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT=self._swapReceivedMessageFormatWithT_RequiredText,
VAR_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=config.RECEIVED_MESSAGE_FORMAT_WITH_T),
VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value=""),
VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value="[message]"),
VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T=StringVar(value="[translation]"),
CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT_WITH_T=self.callbackBindFocusOut_ReceivedMessageFormatWithT,
# -------------------Speaker2Chatbox-----------
VAR_SECOND_TITLE_OTHERS_SPEAKER2CHATBOX=StringVar(value=i18n.t("config_window.side_menu_labels.others_speaker2chatbox")),
VAR_LABEL_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_received_message_to_vrc.label")),
VAR_DESC_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_received_message_to_vrc.desc")),
CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=None,
VAR_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC=BooleanVar(value=config.ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC),
# -------------------Speaker2Chatbox-----------
# Advanced Settings Tab
@@ -404,6 +490,7 @@ class View():
self.view_variable.CALLBACK_RESTART_SOFTWARE=common_registers.get("callback_restart_software", None)
self.view_variable.CALLBACK_OPEN_FILEPATH_LOGS=common_registers.get("callback_filepath_logs", None)
self.view_variable.CALLBACK_OPEN_FILEPATH_CONFIG_FILE=common_registers.get("callback_filepath_config_file", None)
self.view_variable.CALLBACK_QUIT_VRCT=common_registers.get("callback_quit_vrct", None)
if window_action_registers is not None:
@@ -429,9 +516,21 @@ class View():
self.view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB = main_window_registers.get("callback_selected_language_preset_tab", None)
def adjustedMessageBoxReturnFunction(_e):
if self.view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED is True:
return
if config.SEND_MESSAGE_BUTTON_TYPE != "show_and_disable_enter_key":
main_window_registers.get("message_box_bind_Return")()
return "break" # For deleting the next line that will be inserted when the Enter key is pressed.
def pressedSendMessageButtonFunction(_e):
main_window_registers.get("message_box_bind_Return")()
vrct_gui.entry_message_box.focus()
entry_message_box = getattr(vrct_gui, "entry_message_box")
entry_message_box.bind("<Return>", main_window_registers.get("message_box_bind_Return"))
entry_message_box.bind("<Shift-Return>", lambda _e: None) # This is to prevent message sending on Shift + Enter key press and just add a new line.
entry_message_box.bind("<Return>", adjustedMessageBoxReturnFunction)
entry_message_box.bind("<Any-KeyPress>", main_window_registers.get("message_box_bind_Any_KeyPress"))
self.view_variable.CALLBACK_CLICKED_SEND_MESSAGE_BUTTON = pressedSendMessageButtonFunction
entry_message_box.bind("<FocusIn>", main_window_registers.get("message_box_bind_FocusIn"))
@@ -461,8 +560,10 @@ class View():
self.view_variable.CALLBACK_SET_APPEARANCE = config_window_registers.get("callback_set_appearance", None)
self.view_variable.CALLBACK_SET_UI_SCALING = config_window_registers.get("callback_set_ui_scaling", None)
self.view_variable.CALLBACK_SET_TEXTBOX_UI_SCALING = config_window_registers.get("callback_set_textbox_ui_scaling", None)
self.view_variable.CALLBACK_SET_MESSAGE_BOX_RATIO = config_window_registers.get("callback_set_message_box_ratio", None)
self.view_variable.CALLBACK_SET_FONT_FAMILY = config_window_registers.get("callback_set_font_family", None)
self.view_variable.CALLBACK_SET_UI_LANGUAGE = config_window_registers.get("callback_set_ui_language", None)
self.view_variable.CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY = config_window_registers.get("callback_set_enable_restore_main_window_geometry", None)
# Translation Tab
@@ -494,12 +595,23 @@ class View():
# Others Tab
self.view_variable.CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX = config_window_registers.get("callback_set_enable_auto_clear_chatbox", None)
self.view_variable.CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES = config_window_registers.get("callback_set_send_only_translated_messages", None)
self.view_variable.CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE = config_window_registers.get("callback_set_send_message_button_type", None)
self.view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY = config_window_registers.get("callback_set_enable_notice_xsoverlay", None)
self.view_variable.CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS = config_window_registers.get("callback_set_enable_auto_export_message_logs", None)
self.view_variable.CALLBACK_SET_MESSAGE_FORMAT = config_window_registers.get("callback_set_message_format", None)
self.view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC = config_window_registers.get("callback_set_enable_send_message_to_vrc", None)
# self.view_variable.CALLBACK_SET_STARTUP_OSC_ENABLED_CHECK = config_window_registers.get("callback_set_startup_osc_enabled_check", None) #[deprecated]
self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT = config_window_registers.get("callback_set_send_message_format", None)
self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T = config_window_registers.get("callback_set_send_message_format_with_t", None)
self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT = config_window_registers.get("callback_set_received_message_format", None)
self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T = config_window_registers.get("callback_set_received_message_format_with_t", None)
# Speaker2Chatbox----------------
self.view_variable.CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = config_window_registers.get("callback_set_enable_send_received_message_to_vrc", None)
# Speaker2Chatbox----------------
# Advanced Settings Tab
self.view_variable.CALLBACK_SET_OSC_IP_ADDRESS = config_window_registers.get("callback_set_osc_ip_address", None)
@@ -510,6 +622,7 @@ class View():
self.enableConfigWindowCompactMode()
vrct_gui.config_window.setting_box_compact_mode_switch_box.select()
self.setMainWindowMessageBoxRatio(config.MESSAGE_BOX_RATIO)
if config.CHOICE_MIC_HOST == "NoHost":
self.view_variable.VAR_MIC_HOST.set("No Mic Host Detected")
@@ -527,6 +640,13 @@ class View():
)
self.replaceMicThresholdCheckButton_Disabled()
if config.ENABLE_SPEAKER2CHATBOX is False:
vrct_gui._changeConfigWindowWidgetsStatus(
status="disabled",
target_names=[
"sb__checkbox_enable_send_received_message_to_vrc",
]
)
if config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD is True:
self.closeMicEnergyThresholdWidget()
@@ -539,55 +659,137 @@ class View():
self.openSpeakerEnergyThresholdWidget()
self.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
self.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
self.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
self.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
self.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
# Insert sample conversation for testing.
# self._insertSampleConversationToTextbox()
def setMessageFormatEntryWidgets(self, message_format:str):
# Send Message Format
def setSendMessageFormat_EntryWidgets(self, message_format:str):
result = self.extractMessageFormat(message_format)
self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT.set(result.before)
self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT.set(result.after)
self.updateSendMessageFormat_ExampleTextWidget()
def updateSendMessageFormat_ExampleTextWidget(self):
message = i18n.t("config_window.send_message_format.example_text")
example_message = config.SEND_MESSAGE_FORMAT.replace("[message]", message)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT.set(example_message)
# Send Message Format With Translation
def setSendMessageFormatWithT_EntryWidgets(self, message_format:str):
result = self.extractMessageFormatWithT(message_format)
if result.is_message_first is True:
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set("[message]")
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set("[translation]")
self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set("[message]")
self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set("[translation]")
else:
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set("[translation]")
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set("[message]")
self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set("[translation]")
self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set("[message]")
self.view_variable.VAR_ENTRY_0_MESSAGE_FORMAT.set(result.before)
self.view_variable.VAR_ENTRY_1_MESSAGE_FORMAT.set(result.between)
self.view_variable.VAR_ENTRY_2_MESSAGE_FORMAT.set(result.after)
self.updateMessageFormat_ExampleTextWidget()
self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T.set(result.before)
self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T.set(result.between)
self.view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T.set(result.after)
self.updateSendMessageFormatWithT_ExampleTextWidget()
def _swapMessageFormatRequiredText(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.get()
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set(text_1)
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set(text_0)
self.updateMessageFormat_ExampleTextWidget()
def _swapSendMessageFormatWithT_RequiredText(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.get()
self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.set(text_1)
self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.set(text_0)
self.updateSendMessageFormatWithT_ExampleTextWidget()
new_message_format = self.getLatestMessageFormatFromWidget()
callFunctionIfCallable(self.view_variable.CALLBACK_SET_MESSAGE_FORMAT, new_message_format)
new_message_format = self.getLatestMessageFormatWithT_FromWidget()
callFunctionIfCallable(self.view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T, new_message_format)
def getLatestMessageFormatFromWidget(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.get()
entry_0 = self.view_variable.VAR_ENTRY_0_MESSAGE_FORMAT.get()
entry_1 = self.view_variable.VAR_ENTRY_1_MESSAGE_FORMAT.get()
entry_2 = self.view_variable.VAR_ENTRY_2_MESSAGE_FORMAT.get()
def getLatestMessageFormatWithT_FromWidget(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T.get()
entry_0 = self.view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T.get()
entry_1 = self.view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T.get()
entry_2 = self.view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T.get()
return entry_0+text_0+entry_1+text_1+entry_2
def updateMessageFormat_ExampleTextWidget(self):
message = i18n.t("config_window.message_format.example_text", locale=config.UI_LANGUAGE)
def updateSendMessageFormatWithT_ExampleTextWidget(self):
message = i18n.t("config_window.send_message_format_with_t.example_text", locale=config.UI_LANGUAGE)
translation_locale = "ja" if config.UI_LANGUAGE == "en" else "en"
translation = i18n.t("config_window.message_format.example_text", locale=translation_locale)
translation = i18n.t("config_window.send_message_format_with_t.example_text", locale=translation_locale)
example_message = config.MESSAGE_FORMAT.replace("[message]", message)
example_message = config.SEND_MESSAGE_FORMAT_WITH_T.replace("[message]", message)
example_message = example_message.replace("[translation]", translation)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT.set(example_message)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T.set(example_message)
# Received Message Format
def setReceivedMessageFormat_EntryWidgets(self, message_format:str):
result = self.extractMessageFormat(message_format)
self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT.set(result.before)
self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT.set(result.after)
self.updateReceivedMessageFormat_ExampleTextWidget()
def updateReceivedMessageFormat_ExampleTextWidget(self):
message = i18n.t("config_window.received_message_format.example_text")
example_message = config.RECEIVED_MESSAGE_FORMAT.replace("[message]", message)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT.set(example_message)
# Received Message Format With Translation
def setReceivedMessageFormatWithT_EntryWidgets(self, message_format:str):
result = self.extractMessageFormatWithT(message_format)
if result.is_message_first is True:
self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[message]")
self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[translation]")
else:
self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[translation]")
self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set("[message]")
self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.before)
self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.between)
self.view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T.set(result.after)
self.updateReceivedMessageFormatWithT_ExampleTextWidget()
def _swapReceivedMessageFormatWithT_RequiredText(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.set(text_1)
self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.set(text_0)
self.updateReceivedMessageFormatWithT_ExampleTextWidget()
new_message_format = self.getLatestReceivedMessageFormatWithT_FromWidget()
callFunctionIfCallable(self.view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T, new_message_format)
def getLatestReceivedMessageFormatWithT_FromWidget(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
entry_0 = self.view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
entry_1 = self.view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
entry_2 = self.view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T.get()
return entry_0+text_0+entry_1+text_1+entry_2
def updateReceivedMessageFormatWithT_ExampleTextWidget(self):
message = i18n.t("config_window.received_message_format_with_t.example_text", locale=config.UI_LANGUAGE)
translation_locale = "ja" if config.UI_LANGUAGE == "en" else "en"
translation = i18n.t("config_window.received_message_format_with_t.example_text", locale=translation_locale)
example_message = config.RECEIVED_MESSAGE_FORMAT_WITH_T.replace("[message]", message)
example_message = example_message.replace("[translation]", translation)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T.set(example_message)
# GUI process
@@ -603,7 +805,9 @@ class View():
vrct_gui._showGUI()
vrct_gui._startMainLoop()
def quitVRCT(self):
callFunctionIfCallable(self.view_variable.CALLBACK_QUIT_VRCT)
vrct_gui._quitVRCT()
# Common
@staticmethod
@@ -617,6 +821,25 @@ class View():
def openWebPage(url:str):
webbrowser.open_new_tab(url)
@staticmethod
def getMainWindowGeometry(return_int:bool=False):
if return_int is True:
return {
"width": vrct_gui.winfo_toplevel().winfo_width(),
"height": vrct_gui.winfo_toplevel().winfo_height(),
"x_pos": vrct_gui.winfo_toplevel().winfo_x(),
"y_pos": vrct_gui.winfo_toplevel().winfo_y(),
}
return {
"width": str(vrct_gui.winfo_toplevel().winfo_width()),
"height": str(vrct_gui.winfo_toplevel().winfo_height()),
"x_pos": str(vrct_gui.winfo_toplevel().winfo_x()),
"y_pos": str(vrct_gui.winfo_toplevel().winfo_y()),
}
def getPreUiScaling(self):
return self.restart_required_configs_pre_data.ui_scaling
# Open Webpage Functions
def openWebPage_Booth(self):
@@ -629,9 +852,16 @@ class View():
# Widget Control
# Common
# Note: The difference between _clearEntryBox and _clearTextBox
# idk why, but in CTkEntry and CTkTextbox, the first argument for the delete function is different. Otherwise, it throws an error.
@staticmethod
def _clearEntryBox(entry_widget):
entry_widget.delete(0, CTK_END)
entry_widget.delete(0, "end")
@staticmethod
def _clearTextBox(entry_widget):
entry_widget.delete("1.0", "end")
def clearErrorMessage(self):
vrct_gui._clearErrorMessage()
@@ -658,6 +888,17 @@ class View():
self.view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = False
vrct_gui._disableMainWindowSidebarCompactMode()
def changeTranscriptionDisplayStatus(self, status):
match (status):
case "MIC_ON":
vrct_gui.sls__box_your_language_mic_status__enabled.place(relx=0.1, rely=0.2, anchor="center")
case "MIC_OFF":
vrct_gui.sls__box_your_language_mic_status__enabled.place_forget()
case "SPEAKER_ON":
vrct_gui.sls__box_target_language_speaker_status__enabled.place(relx=0.1, rely=0.2, anchor="center")
case "SPEAKER_OFF":
vrct_gui.sls__box_target_language_speaker_status__enabled.place_forget()
# Config Window
def enableConfigWindowCompactMode(self):
@@ -909,6 +1150,37 @@ class View():
def setMainWindowTextboxUiSize(custom_font_size_scale:float):
vrct_gui.print_to_textbox.setTagsSettings(custom_font_size_scale=custom_font_size_scale)
def setMainWindowMessageBoxRatio(self, message_box_ratio:int):
if message_box_ratio < config.MESSAGE_BOX_RATIO_RANGE[0] or message_box_ratio > config.MESSAGE_BOX_RATIO_RANGE[1]:
raise ValueError(f"Input must be between {config.MESSAGE_BOX_RATIO_RANGE[0]} and {config.MESSAGE_BOX_RATIO_RANGE[1]} (inclusive)")
vrct_gui.main_bg_container.grid_rowconfigure(tuple(range(config.MESSAGE_BOX_RATIO_RANGE[0], config.MESSAGE_BOX_RATIO_RANGE[1]+2)), weight=1)
textbox_ratio = int((config.MESSAGE_BOX_RATIO_RANGE[1]+1) - message_box_ratio)
message_box_row = int(textbox_ratio + 1)
message_box_rowwpan = int((config.MESSAGE_BOX_RATIO_RANGE[1]+1) - textbox_ratio)
vrct_gui.main_textbox_container.grid(row=1, rowspan=textbox_ratio, column=0, sticky="nsew")
vrct_gui.main_entry_message_container.grid(row=message_box_row, rowspan=message_box_rowwpan, column=0, sticky="nsew")
new_send_message_button_width = int(self.settings.main.uism.SEND_MESSAGE_BUTTON_RATE_WIDTH * message_box_ratio)
if new_send_message_button_width > self.settings.main.uism.SEND_MESSAGE_BUTTON_MAX_WIDTH:
new_send_message_button_width = self.settings.main.uism.SEND_MESSAGE_BUTTON_MAX_WIDTH
if new_send_message_button_width < self.settings.main.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH:
new_send_message_button_width = self.settings.main.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH
vrct_gui.main_send_message_button_container.grid_columnconfigure(0, weight=0, minsize=new_send_message_button_width)
@staticmethod
def changeMainWindowSendMessageButton(status:str):
match (status):
case "hide":
vrct_gui.main_send_message_button_container.grid_remove()
vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
case "show" | "show_and_disable_enter_key":
vrct_gui.main_send_message_button_container.grid()
vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
# Function
def _adjustUiSizeAndRestart(self):
current_percentage = int(config.UI_SCALING.replace("%",""))
@@ -1096,7 +1368,11 @@ class View():
self.view_variable.VAR_SPEAKER_MAX_PHRASES.set(str(value))
def setGuiVariable_OscIpAddress(self, value):
self.view_variable.VAR_OSC_IP_ADDRESS.set(str(value))
def setGuiVariable_OscPort(self, value):
self.view_variable.VAR_OSC_PORT.set(int(value))
@@ -1122,8 +1398,14 @@ class View():
case "SpeakerMaxPhrases":
self.setGuiVariable_SpeakerMaxPhrases(config.INPUT_SPEAKER_MAX_PHRASES)
case "MessageFormat":
self.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
case "SendMessageFormat":
self.setSendMessageFormat_EntryWidgets(config.SEND_MESSAGE_FORMAT)
case "SendMessageFormatWithT":
self.setSendMessageFormatWithT_EntryWidgets(config.SEND_MESSAGE_FORMAT_WITH_T)
case "ReceivedMessageFormat":
self.setReceivedMessageFormat_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT)
case "ReceivedMessageFormatWithT":
self.setReceivedMessageFormatWithT_EntryWidgets(config.RECEIVED_MESSAGE_FORMAT_WITH_T)
case _:
raise ValueError(f"No matching case for target_name: {target_name}")
@@ -1230,10 +1512,10 @@ class View():
# Message Box
@staticmethod
def getTextFromMessageBox():
return vrct_gui.entry_message_box.get()
return vrct_gui.entry_message_box.get('1.0', "end-1c")
def clearMessageBox(self):
self._clearEntryBox(vrct_gui.entry_message_box)
self._clearTextBox(vrct_gui.entry_message_box)
@@ -1274,10 +1556,21 @@ class View():
self.clearErrorMessage()
def callbackBindFocusOut_MessageFormat(self, _e=None):
self.setLatestConfigVariable("MessageFormat")
def callbackBindFocusOut_SendMessageFormat(self, _e=None):
self.setLatestConfigVariable("SendMessageFormat")
self.clearErrorMessage()
def callbackBindFocusOut_SendMessageFormatWithT(self, _e=None):
self.setLatestConfigVariable("SendMessageFormatWithT")
self.clearErrorMessage()
def callbackBindFocusOut_ReceivedMessageFormat(self, _e=None):
self.setLatestConfigVariable("ReceivedMessageFormat")
self.clearErrorMessage()
def callbackBindFocusOut_ReceivedMessageFormatWithT(self, _e=None):
self.setLatestConfigVariable("ReceivedMessageFormatWithT")
self.clearErrorMessage()
@@ -1359,12 +1652,31 @@ class View():
)
def showErrorMessage_MessageFormat(self):
def showErrorMessage_SendMessageFormat(self):
self._showErrorMessage(
vrct_gui.config_window.sb__entry_message_format_2,
self._makeInvalidValueErrorMessage(i18n.t("config_window.message_format.error_message"))
vrct_gui.config_window.sb__entry_send_message_format_1,
self._makeInvalidValueErrorMessage(i18n.t("config_window.send_message_format.error_message"))
)
def showErrorMessage_SendMessageFormatWithT(self):
self._showErrorMessage(
vrct_gui.config_window.sb__entry_send_message_format_with_t_2,
self._makeInvalidValueErrorMessage(i18n.t("config_window.send_message_format_with_t.error_message"))
)
def showErrorMessage_ReceivedMessageFormat(self):
self._showErrorMessage(
vrct_gui.config_window.sb__entry_received_message_format_1,
self._makeInvalidValueErrorMessage(i18n.t("config_window.received_message_format.error_message"))
)
def showErrorMessage_ReceivedMessageFormatWithT(self):
self._showErrorMessage(
vrct_gui.config_window.sb__entry_received_message_format_with_t_2,
self._makeInvalidValueErrorMessage(i18n.t("config_window.received_message_format_with_t.error_message"))
)
@staticmethod
def _makeInvalidValueErrorMessage(error_message):
return i18n.t("config_window.common_error_message.invalid_value") + "\n" + error_message
@@ -1373,9 +1685,17 @@ class View():
self.view_variable.VAR_ERROR_MESSAGE.set(message)
vrct_gui._showErrorMessage(target_widget=target_widget)
@staticmethod
def extractMessageFormat(text):
split_result = text.split("[message]")
result_data = SimpleNamespace(
before = split_result[0],
after = split_result[1],
)
return result_data
@staticmethod
def extractMessageFormatWithT(text):
import re
message_index = text.find("[message]")
translation_index = text.find("[translation]")

View File

@@ -70,7 +70,6 @@ class _CreateConfirmationModal(CTkToplevel):
if modal_type == "information":
# self.modal_buttons_wrapper.grid_columnconfigure(1, weight=1, minsize=self.settings.uism.BUTTONS_BETWEEN_PADDING)
self.modal_buttons_wrapper.grid_columnconfigure((0,2), weight=1)
@@ -222,6 +221,7 @@ class _CreateConfirmationModal(CTkToplevel):
target_widget=self
)
fadeInAnimation(self, steps=5, interval=0.005, max_alpha=1)
self.lift()
self.focus_set()

View File

@@ -1,9 +1,9 @@
from types import SimpleNamespace
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont, CTkScrollableFrame
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
from time import sleep
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText, CustomizedCTkScrollableFrame
from functools import partial
from utils import isEven, makeEven
@@ -121,7 +121,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
BORDER_WIDTH=self.window_border_width
self.scroll_frame_container = CTkScrollableFrame(
self.scroll_frame_container = CustomizedCTkScrollableFrame(
self.dropdown_menu_container,
corner_radius=0,
fg_color=self.window_bg_color,
@@ -180,7 +180,6 @@ class _CreateDropdownMenuWindow(CTkToplevel):
__dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
# __dropdown_menu_value_wrapper.grid_columnconfigure(0, weight=1)
__label_widget = CTkLabel(
__dropdown_menu_value_wrapper,
text=longest_text,
@@ -190,7 +189,6 @@ class _CreateDropdownMenuWindow(CTkToplevel):
anchor="w",
text_color=self.values_text_color,
)
# setattr(self, f"l", __label_widget)
__label_widget.grid(row=1, column=0, padx=self.value_ipadx, pady=self.value_ipady, sticky="w")
@@ -198,7 +196,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
label_width = getLatestWidth(__label_widget)
label_width += self.scroll_frame_container._scrollbar.winfo_width() + (self.window_border_width*2) + (self.scrollbar_ipadx[0] + self.scrollbar_ipadx[1])
if label_width > self.new_width:
additional_width = int(label_width - self.new_width)
additional_width = int(label_width - self.new_width + self.settings.uism.MARGIN_WIDTH)
self.new_width += additional_width
# for fixing 1px bug

View File

@@ -1,9 +1,9 @@
from functools import partial
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, applyUiScalingAndFixTheBugScrollBar
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, applyUiScalingAndFixTheBugScrollBar, CustomizedCTkScrollableFrame
from utils import callFunctionIfCallable, makeEven
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont, CTkScrollableFrame
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
class _CreateSelectableLanguagesWindow(CTkToplevel):
def __init__(self, vrct_gui, settings, view_variable):
@@ -116,7 +116,7 @@ class _CreateSelectableLanguagesWindow(CTkToplevel):
self.scroll_frame_container = CTkScrollableFrame(self, corner_radius=0, fg_color=self.settings.ctm.MAIN_BG_COLOR, width=self.width_new, height=self.height_new)
self.scroll_frame_container = CustomizedCTkScrollableFrame(self, corner_radius=0, fg_color=self.settings.ctm.MAIN_BG_COLOR, width=self.width_new, height=self.height_new)
self.scroll_frame_container.grid(row=1, column=0, sticky="nsew")
applyUiScalingAndFixTheBugScrollBar(

View File

@@ -56,7 +56,7 @@ class _CreateWindowCover(CTkToplevel):
self.width_new = self.attach_window.winfo_width()
self.height_new = self.attach_window.winfo_height()
self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos))
fadeInAnimation(self, steps=5, interval=0.005, max_alpha=0.5)
fadeInAnimation(self, steps=5, interval=0.005, max_alpha=0.8)

View File

@@ -5,10 +5,13 @@ def _changeConfigWindowWidgetsStatus(config_window, settings, view_variable, sta
# target_names = []
def disableOptionmenuWidget(target_widget):
def disableLabelsWidgets(target_widget):
target_widget.label_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
if target_widget.desc_widget is not None:
target_widget.desc_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
def disableOptionmenuWidget(target_widget):
disableLabelsWidgets(target_widget)
target_widget.optionmenu_label_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
target_widget.optionmenu_img_widget.configure(image=CTkImage(settings.image_file.ARROW_LEFT_DISABLED.rotate(90), size=settings.uism.SB__OPTIONMENU_IMG_SIZE))
target_widget.optionmenu_box.unbindFunction()
@@ -32,6 +35,16 @@ def _changeConfigWindowWidgetsStatus(config_window, settings, view_variable, sta
target_widget = config_window.sb__widgets["sb__optionmenu_appearance_theme"]
disableOptionmenuWidget(target_widget)
case "sb__checkbox_enable_send_received_message_to_vrc":
if status == "disabled":
target_widget = config_window.sb__widgets["sb__checkbox_enable_send_received_message_to_vrc"]
disableLabelsWidgets(target_widget)
config_window.sb__checkbox_enable_send_received_message_to_vrc.configure(
state="disabled",
border_color=settings.ctm.SB__CHECKBOX_BORDER_DISABLED_COLOR
)
case _:
raise ValueError(f"No matching case for target_name: {target_name}")

View File

@@ -3,7 +3,7 @@ hold_state_list=[]
def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, target_names:list, to_hold_state:bool=False):
global hold_state_list
if target_names == "All":
target_names = ["translation_switch", "transcription_send_switch", "transcription_receive_switch", "foreground_switch", "quick_language_settings", "config_button", "minimize_sidebar_button", "entry_message_box"]
target_names = ["translation_switch", "transcription_send_switch", "transcription_receive_switch", "foreground_switch", "quick_language_settings", "config_button", "minimize_sidebar_button", "entry_message_box", "send_message_button"]
for item in hold_state_list:
@@ -141,11 +141,19 @@ def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, ta
case "entry_message_box":
if status == "disabled":
vrct_gui.entry_message_box.configure(state="disabled", placeholder_text_color=settings.ctm.TEXTBOX_ENTRY_PLACEHOLDER_DISABLED_COLOR, text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_DISABLED_COLOR)
vrct_gui.entry_message_box.configure(state="disabled", text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_DISABLED_COLOR)
view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED = True
elif status == "normal":
vrct_gui.entry_message_box.configure(state="normal", placeholder_text_color=settings.ctm.TEXTBOX_ENTRY_PLACEHOLDER_COLOR, text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_COLOR)
vrct_gui.entry_message_box.configure(state="normal", text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_COLOR)
view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED = False
case "send_message_button":
if status == "disabled":
vrct_gui.main_send_message_button__disabled.grid()
elif status == "normal":
vrct_gui.main_send_message_button__disabled.grid_remove()
case _:
raise ValueError(f"No matching case for target_name: {target_name}")

View File

@@ -1,6 +1,6 @@
from customtkinter import CTkFrame, CTkScrollableFrame
from customtkinter import CTkFrame
from ....ui_utils import setDefaultActiveTab, applyUiScalingAndFixTheBugScrollBar
from ....ui_utils import setDefaultActiveTab, applyUiScalingAndFixTheBugScrollBar, CustomizedCTkScrollableFrame
from ._addConfigSideMenuItem import _addConfigSideMenuItem
from ._createSettingBoxContainer import _createSettingBoxContainer
@@ -8,7 +8,7 @@ from ._createSettingBoxContainer import _createSettingBoxContainer
from .setting_box_containers.setting_box_appearance import createSettingBox_Appearance
from .setting_box_containers.setting_box_transcription import createSettingBox_Mic, createSettingBox_Speaker
from .setting_box_containers.setting_box_others import createSettingBox_Others
from .setting_box_containers.setting_box_others import createSettingBox_Others, createSettingBox_Others_SendMessageFormats, createSettingBox_Others_ReceivedMessageFormats, createSettingBox_Others_Additional
from .setting_box_containers.setting_box_advanced_settings import createSettingBox_AdvancedSettings
from .setting_box_containers.setting_box_translation import createSettingBox_Translation
@@ -38,7 +38,7 @@ def createSideMenuAndSettingsBoxContainers(config_window, settings, view_variabl
# Setting box container
config_window.main_bg_container.grid_rowconfigure(1, weight=1)
config_window.main_setting_box_scrollable_container = CTkScrollableFrame(config_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR)
config_window.main_setting_box_scrollable_container = CustomizedCTkScrollableFrame(config_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR)
config_window.main_setting_box_scrollable_container.grid(row=1, column=0, sticky="nsew")
applyUiScalingAndFixTheBugScrollBar(
@@ -106,6 +106,9 @@ def createSideMenuAndSettingsBoxContainers(config_window, settings, view_variabl
"setting_box_container_attr_name": "setting_box_container_others",
"setting_boxes": [
{ "var_section_title": None, "setting_box": createSettingBox_Others },
{ "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_SEND_MESSAGE_FORMATS, "setting_box": createSettingBox_Others_SendMessageFormats },
{ "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_RECEIVED_MESSAGE_FORMATS, "setting_box": createSettingBox_Others_ReceivedMessageFormats },
{ "var_section_title": view_variable.VAR_SECOND_TITLE_OTHERS_SPEAKER2CHATBOX, "setting_box": createSettingBox_Others_Additional },
]
},
},
@@ -131,7 +134,6 @@ def createSideMenuAndSettingsBoxContainers(config_window, settings, view_variabl
config_window=config_window,
settings=settings,
view_variable=view_variable,
# view_variable=view_variable,
side_menu_settings=sm_and_sbc_setting,
side_menu_row=side_menu_row,
all_side_menu_tab_attr_name=all_side_menu_tab_attr_name,

View File

@@ -2,10 +2,10 @@ from functools import partial
from types import SimpleNamespace
from typing import Union
from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkEntry, CTkSlider, CTkSwitch, CTkCheckBox, CTkProgressBar, CTkImage
from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkEntry, CTkSlider, CTkSwitch, CTkCheckBox, CTkProgressBar, CTkImage, CTkRadioButton
from CTkToolTip import *
from vrct_gui.ui_utils import createButtonWithImage, getLatestWidth, createOptionMenuBox, getLatestHeight, bindButtonFunctionAndColor
from vrct_gui.ui_utils import createButtonWithImage, getLatestWidth, createOptionMenuBox, getLatestHeight, bindButtonFunctionAndColor, bindEnterAndLeaveFunction, bindButtonReleaseFunction, bindButtonPressFunction
from vrct_gui import vrct_gui
from utils import isEven, callFunctionIfCallable
@@ -109,8 +109,9 @@ class _SettingBoxGenerator():
def createSettingBox_Labels(
self,
for_var_label_text, for_var_desc_text,
for_var_label_text,
labels_attr_name,
for_var_desc_text=None,
):
setting_box_frame= self._createSettingBoxFrame(labels_attr_name, for_var_label_text, for_var_desc_text, expand_label_frame=True)
@@ -203,7 +204,6 @@ class _SettingBoxGenerator():
variable=variable,
command=command,
fg_color=self.settings.ctm.SB__SWITCH_BOX_BG_COLOR,
# bg_color="red",
progress_color=self.settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
button_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
button_hover_color=self.settings.ctm.SB__SWITCH_BOX_BUTTON_HOVERED_COLOR,
@@ -217,10 +217,11 @@ class _SettingBoxGenerator():
def createSettingBoxCheckbox(self,
for_var_label_text, for_var_desc_text,
for_var_label_text,
checkbox_attr_name,
command,
variable,
for_var_desc_text=None,
):
(setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(checkbox_attr_name, for_var_label_text, for_var_desc_text)
@@ -241,9 +242,6 @@ class _SettingBoxGenerator():
hover_color=self.settings.ctm.SB__CHECKBOX_HOVER_COLOR,
checkmark_color=self.settings.ctm.SB__CHECKBOX_CHECKMARK_COLOR,
fg_color=self.settings.ctm.SB__CHECKBOX_CHECKED_COLOR,
# fg_color=self.settings.ctm.SB__SWITCH_BOX_BG_COLOR,
# bg_color="red",
# progress_color=self.settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
)
setattr(self.config_window, checkbox_attr_name, checkbox_widget)
@@ -253,6 +251,81 @@ class _SettingBoxGenerator():
# 3 Options
def createSettingBoxRadioButtons(
self,
for_var_label_text, for_var_desc_text,
radio_button_attr_name,
variable,
command,
radiobutton_keys_values=dict,
):
(setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(radio_button_attr_name, for_var_label_text, for_var_desc_text)
row=0
for key, value in radiobutton_keys_values.items():
radiobutton_wrapper = CTkFrame(setting_box_item_frame, corner_radius=6, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0, cursor="hand2")
radiobutton_wrapper.grid(row=row, column=0, sticky="ew")
row+=1
radiobutton_wrapper.grid_rowconfigure((0,2), weight=1)
setting_box_radio_button = CTkRadioButton(
radiobutton_wrapper,
textvariable=value,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__RADIO_BUTTON_FONT_SIZE, weight="normal"),
variable=variable,
value=key,
text_color=self.settings.ctm.SB__RADIOBUTTON_TEXT_COLOR,
fg_color=self.settings.ctm.SB__RADIOBUTTON_SELECTED_COLOR,
border_color=self.settings.ctm.SB__RADIOBUTTON_BORDER_COLOR,
hover=False
)
setting_box_radio_button.grid(row=1, column=0, padx=10, pady=10, sticky="ew")
if key == variable.get():
setting_box_radio_button.select()
setting_box_radio_button._canvas.unbind("<Button-1>")
setting_box_radio_button._text_label.unbind("<Button-1>")
setting_box_radio_button._text_label.grid(padx=(10,0))
def buttonPressedFunction(radiobutton_wrapper, radiobutton_widget, _e):
radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_CLICKED_COLOR)
def buttonReleasedFunction(radiobutton_wrapper, radiobutton_widget, _e):
radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_HOVERED_COLOR)
radiobutton_widget.select()
command()
def enterFunction(radiobutton_wrapper, _e):
radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__RADIOBUTTON_BG_HOVERED_COLOR)
def leaveFunction(radiobutton_wrapper, _e):
radiobutton_wrapper.configure(fg_color=self.settings.ctm.SB__BG_COLOR)
bindEnterAndLeaveFunction(
target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
enterFunction=partial(enterFunction, radiobutton_wrapper),
leaveFunction=partial(leaveFunction, radiobutton_wrapper)
)
bindButtonPressFunction(
target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
buttonPressedFunction=partial(buttonPressedFunction, radiobutton_wrapper, setting_box_radio_button)
)
bindButtonReleaseFunction(
target_widgets=[radiobutton_wrapper, setting_box_radio_button, setting_box_radio_button._bg_canvas],
buttonReleasedFunction=partial(buttonReleasedFunction, radiobutton_wrapper, setting_box_radio_button)
)
return setting_box_frame
def createSettingBoxAutoExportMessageLogs(
self,
@@ -282,6 +355,7 @@ class _SettingBoxGenerator():
button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
button_image_file=self.settings.image_file.FOLDER_OPEN_ICON,
button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
button_command=button_command,
)
@@ -540,13 +614,15 @@ class _SettingBoxGenerator():
def createSettingBoxMessageFormatEntries(self,
def createSettingBoxMessageFormatEntries_WithTranslation(self,
base_entry_attr_name,
entry_textvariable_0,
entry_textvariable_1,
entry_textvariable_2,
textvariable_0,
textvariable_1,
example_label_textvariable,
swap_button_command,
entry_bind__Any_KeyRelease,
entry_bind__FocusOut=None,
):
@@ -581,7 +657,7 @@ class _SettingBoxGenerator():
example_frame_widget.grid_columnconfigure((0,2), weight=1)
example_label_widget = CTkLabel(
example_frame_widget,
textvariable=self.view_variable.VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT,
textvariable=example_label_textvariable,
anchor="center",
justify="center",
wraplength=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH,
@@ -717,10 +793,6 @@ class _SettingBoxGenerator():
)
swap_button_label_1.grid(row=1, column=3)
def adjustedCommand():
callFunctionIfCallable(self.view_variable.CALLBACK_SWAP_MESSAGE_FORMAT_REQUIRED_TEXT)
bindButtonFunctionAndColor(
target_widgets=[
swap_button,
@@ -732,7 +804,7 @@ class _SettingBoxGenerator():
enter_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR,
leave_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR,
clicked_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR,
buttonReleasedFunction=lambda _e: adjustedCommand(),
buttonReleasedFunction=swap_button_command,
)
@@ -740,6 +812,119 @@ class _SettingBoxGenerator():
def createSettingBoxMessageFormatEntries(self,
base_entry_attr_name,
entry_textvariable_0,
entry_textvariable_1,
textvariable_0,
example_label_textvariable,
entry_bind__Any_KeyRelease,
entry_bind__FocusOut=None,
):
(setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(base_entry_attr_name)
all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
all_wrapper.grid(row=1, column=0, sticky="ew")
all_wrapper.grid_columnconfigure(0, weight=1)
example_box_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
example_box_wrapper.grid(row=0, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
entries_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
entries_wrapper.grid(row=1, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
example_box_wrapper.grid_columnconfigure((0,2), weight=1)
example_frame_widget = CTkFrame(example_box_wrapper, corner_radius=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR, width=0, height=0)
example_frame_widget.grid(row=0, column=1)
example_frame_widget.grid_rowconfigure((0,2), weight=1)
example_frame_widget.grid_columnconfigure((0,2), weight=1)
example_label_widget = CTkLabel(
example_frame_widget,
textvariable=example_label_textvariable,
anchor="center",
justify="center",
wraplength=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH,
height=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_TEXT_COLOR,
)
example_label_widget.grid(row=1, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, pady=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, sticky="ew")
self.config_window.additional_widgets.append(example_box_wrapper)
entry_textvariables = [entry_textvariable_0, entry_textvariable_1]
for i in range(2):
entry_widget = CTkEntry(
entries_wrapper,
text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
height=self.settings.uism.SB__MESSAGE_FORMAT__ENTRY_HEIGHT,
textvariable=entry_textvariables[i],
justify="center",
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
)
setattr(self.config_window, base_entry_attr_name + "_" + str(i), entry_widget)
if entry_bind__FocusOut is not None:
entry_widget.bind("<FocusOut>", entry_bind__FocusOut, "+")
label_frame_widget_0 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
label_frame_widget_0.grid_rowconfigure((0,2), weight=1)
label_frame_widget_0.grid_columnconfigure(0, weight=1)
label_widget_0 = CTkLabel(
label_frame_widget_0,
textvariable=textvariable_0,
anchor="center",
height=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.LABELS_TEXT_COLOR
)
label_widget_0.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
entries_wrapper.grid_columnconfigure((0,2), weight=1)
entries_wrapper.grid_columnconfigure(1, weight=0)
entry_widget_0 = getattr(self.config_window, base_entry_attr_name+"_0")
entry_widget_1 = getattr(self.config_window, base_entry_attr_name+"_1")
entry_widget_0.grid(row=0, column=0, sticky="ew")
entry_widget_1.grid(row=0, column=2, sticky="ew")
label_frame_widget_0.grid(row=0, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
def adjusted_command__for_entry_bind__Any_KeyRelease(_e):
message_format = entry_widget_0.get() + textvariable_0.get() + entry_widget_1.get()
entry_bind__Any_KeyRelease(message_format)
entry_widget_0.bind("<Any-KeyRelease>", adjusted_command__for_entry_bind__Any_KeyRelease)
entry_widget_1.bind("<Any-KeyRelease>", adjusted_command__for_entry_bind__Any_KeyRelease)
return setting_box_frame
def createSettingBoxButtonWithImage(
self,
for_var_label_text, for_var_desc_text,
@@ -757,7 +942,8 @@ class _SettingBoxGenerator():
button_enter_color=self.settings.ctm.SB__BUTTON_HOVERED_COLOR,
button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
button_image_file=button_image,
button_image_size=self.settings.uism.SB__OPEN_CONFIG_FILE_BUTTON_ICON_SIZE,
button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.SB__OPEN_CONFIG_FILE_BUTTON_IPADXY,
button_command=button_command,
)
@@ -803,6 +989,7 @@ class _SettingBoxGenerator():
button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
button_image_file=self.settings.image_file.ARROW_LEFT.rotate(270),
button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
button_command=open_command,
)
@@ -817,6 +1004,7 @@ class _SettingBoxGenerator():
button_clicked_color=self.settings.ctm.SB__BUTTON_CLICKED_COLOR,
button_image_file=self.settings.image_file.ARROW_LEFT.rotate(90),
button_image_size=self.settings.uism.SB__BUTTON_ICON_SIZE,
corner_radius=self.settings.uism.SB__BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.SB__BUTTON_IPADXY,
button_command=close_command,
)
@@ -1032,6 +1220,7 @@ class _SettingBoxGenerator():
button_clicked_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CLICKED_BG_COLOR,
button_image_file=self.settings.image_file.CANCEL_ICON,
button_image_size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE,
corner_radius=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY,
button_command=lambda _e: pressedDeleteButtonCommand(_e, delete_button, redo_button),
)
@@ -1044,6 +1233,7 @@ class _SettingBoxGenerator():
button_clicked_color=self.settings.ctm.SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_CLICKED_BG_COLOR,
button_image_file=self.settings.image_file.REDO_ICON,
button_image_size=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE,
corner_radius=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS,
button_ipadxy=self.settings.uism.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY,
button_command=lambda _e: pressedRedoButtonCommand(_e, delete_button, redo_button),
)
@@ -1077,106 +1267,6 @@ class _SettingBoxGenerator():
# if setting_box_type == "dropdown_menu_x_dropdown_menu":
# self.setting_box_dropdown_menu_x_dropdown_menu = CTkFrame(self.setting_box, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
# self.setting_box_dropdown_menu_x_dropdown_menu.grid(row=0, column=1, padx=(0, self.settings.uism.SB__RIGHT_PADX), rowspan=2, sticky="e")
# # Labels
# self.optionmenu_label_left = CTkLabel(
# self.setting_box_dropdown_menu_x_dropdown_menu,
# text=kwargs["left_dropdown_menu_label"],
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__OPTION_MENU_FONT_SIZE, weight="normal"),
# )
# self.optionmenu_label_left.grid(row=0, column=0)
# self.the_space_between_optionmenu = CTkLabel(
# self.setting_box_dropdown_menu_x_dropdown_menu,
# text=None,
# )
# self.the_space_between_optionmenu.grid(row=0, column=1)
# self.optionmenu_label_right = CTkLabel(
# self.setting_box_dropdown_menu_x_dropdown_menu,
# text=kwargs["right_dropdown_menu_label"],
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__OPTION_MENU_FONT_SIZE, weight="normal"),
# )
# self.optionmenu_label_right.grid(row=0, column=2)
# # Option menus
# self.createOption_DropdownMenu(
# setattr_obj,
# self.setting_box_dropdown_menu_x_dropdown_menu,
# kwargs["left_optionmenu_attr_name"],
# kwargs["left_dropdown_menu_attr_name"],
# dropdown_menu_values=kwargs["left_dropdown_menu_values"],
# width=150,
# command=kwargs["left_dropdown_menu_command"],
# variable=kwargs["left_dropdown_menu_variable"],
# )
# getattr(setattr_obj, kwargs["left_optionmenu_attr_name"]).grid(row=1, column=0)
# self.the_label_between_optionmenu = CTkLabel(
# self.setting_box_dropdown_menu_x_dropdown_menu,
# text="-->",
# # anchor="w",
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__OPTION_MENU_FONT_SIZE, weight="normal"),
# text_color=self.settings.ctm.LABELS_TEXT_COLOR
# )
# self.the_label_between_optionmenu.grid(row=1, column=1, padx=self.settings.uism.SB__RIGHT_PADX/2)
# self.createOption_DropdownMenu(
# setattr_obj,
# self.setting_box_dropdown_menu_x_dropdown_menu,
# kwargs["right_optionmenu_attr_name"],
# kwargs["right_dropdown_menu_attr_name"],
# dropdown_menu_values=kwargs["right_dropdown_menu_values"],
# width=150,
# command=kwargs["right_dropdown_menu_command"],
# variable=kwargs["right_dropdown_menu_variable"],
# )
# getattr(setattr_obj, kwargs["right_optionmenu_attr_name"]).grid(row=1, column=2)
# if setting_box_type == "radio_buttons":
# self.setting_box_radio_buttons_frame = CTkFrame(self.setting_box, corner_radius=0, width=0, height=0)
# self.setting_box_radio_buttons_frame.grid(row=0, column=1, padx=(0, self.settings.uism.SB__RIGHT_PADX), rowspan=2, sticky="e")
# RADIO_BUTTON_RIGHT_PAD = 14
# self.setting_box_radio_button_1 = CTkRadioButton(
# self.setting_box_radio_buttons_frame,
# text="lorem ipsum",
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__RADIO_BUTTON_FONT_SIZE, weight="normal")
# )
# self.setting_box_radio_button_1.grid(row=0, column=0, padx=(0,RADIO_BUTTON_RIGHT_PAD), sticky="e")
# self.setting_box_radio_button_2 = CTkRadioButton(
# self.setting_box_radio_buttons_frame,
# text="lorem ipsum",
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__RADIO_BUTTON_FONT_SIZE, weight="normal")
# )
# self.setting_box_radio_button_2.grid(row=0, column=1, padx=(0,RADIO_BUTTON_RIGHT_PAD), sticky="e")
# self.setting_box_radio_button_3 = CTkRadioButton(
# self.setting_box_radio_buttons_frame,
# text="lorem ipsum",
# font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__RADIO_BUTTON_FONT_SIZE, weight="normal")
# )
# self.setting_box_radio_button_3.grid(row=0, column=2, padx=(0,RADIO_BUTTON_RIGHT_PAD), sticky="e")
def _createPassiveButtonForProgressbarXSlider(self, setting_box_progressbar_x_slider_frame, button_command, button_image_file):
button_wrapper = createButtonWithImage(
parent_widget=setting_box_progressbar_x_slider_frame,

View File

@@ -6,6 +6,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
createSettingBoxSlider = sbg.createSettingBoxSlider
createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
# 関数名は変えるかもしれない。
# テーマ変更、フォント変更時、 Widget再生成か再起動かは検討中
@@ -21,12 +22,17 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
def slider_text_box_ui_scaling_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_TEXTBOX_UI_SCALING, value)
def slider_message_box_ratio_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MESSAGE_BOX_RATIO, value)
def optionmenu_font_family_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_FONT_FAMILY, value)
def optionmenu_ui_language_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_UI_LANGUAGE, value)
def checkbox_enable_restore_main_window_geometry_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY, checkbox_box_widget.get())
row=0
config_window.sb__transparency = createSettingBoxSlider(
@@ -82,6 +88,19 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
config_window.sb__textbox_uis_scaling.grid(row=row)
row+=1
config_window.sb__message_box_ratio = createSettingBoxSlider(
for_var_label_text=view_variable.VAR_LABEL_MESSAGE_BOX_RATIO,
for_var_desc_text=view_variable.VAR_DESC_MESSAGE_BOX_RATIO,
slider_attr_name="sb__slider_message_box_ratio",
slider_range=view_variable.SLIDER_RANGE_MESSAGE_BOX_RATIO,
command=lambda value: slider_message_box_ratio_callback(value),
variable=view_variable.VAR_MESSAGE_BOX_RATIO,
slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_MESSAGE_BOX_RATIO,
slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_MESSAGE_BOX_RATIO,
sliderTooltipFormatter=view_variable.CALLBACK_SLIDER_TOOLTIP_PERCENTAGE_FORMATTER,
)
config_window.sb__message_box_ratio.grid(row=row)
row+=1
config_window.sb__font_family = createSettingBoxDropdownMenu(
for_var_label_text=view_variable.VAR_LABEL_FONT_FAMILY,
@@ -103,5 +122,15 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
command=lambda value: optionmenu_ui_language_callback(value),
variable=view_variable.VAR_UI_LANGUAGE,
)
config_window.sb__ui_language.grid(row=row, pady=0)
config_window.sb__ui_language.grid(row=row)
row+=1
config_window.sb__enable_restore_main_window_geometry = createSettingBoxCheckbox(
for_var_label_text=view_variable.VAR_LABEL_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
checkbox_attr_name="sb__checkbox_enable_restore_main_window_geometry",
command=lambda: checkbox_enable_restore_main_window_geometry_callback(config_window.sb__checkbox_enable_restore_main_window_geometry),
variable=view_variable.VAR_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY,
)
config_window.sb__enable_restore_main_window_geometry.grid(row=row, pady=0)
row+=1

View File

@@ -1 +1,4 @@
from .createSettingBox_Others import createSettingBox_Others
from .createSettingBox_Others import createSettingBox_Others
from .createSettingBox_Others_SendMessageFormats import createSettingBox_Others_SendMessageFormats
from .createSettingBox_Others_ReceivedMessageFormats import createSettingBox_Others_ReceivedMessageFormats
from .createSettingBox_Others_Additional import createSettingBox_Others_Additional

View File

@@ -5,15 +5,19 @@ from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
createSettingBoxRadioButtons = sbg.createSettingBoxRadioButtons
createSettingBoxAutoExportMessageLogs = sbg.createSettingBoxAutoExportMessageLogs
createSettingBox_Labels = sbg.createSettingBox_Labels
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
# 元 checkbox_auto_clear_chatbox_callback
def checkbox_auto_clear_message_box_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX, checkbox_box_widget.get())
def checkbox_send_only_translated_messages_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES, checkbox_box_widget.get())
def checkbox_send_message_button_type_callback():
callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_BUTTON_TYPE, view_variable.VAR_SEND_MESSAGE_BUTTON_TYPE.get())
def checkbox_notice_xsoverlay_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY, checkbox_box_widget.get())
@@ -26,13 +30,6 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
def checkbox_enable_send_message_to_vrc_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC, checkbox_box_widget.get())
# [deprecated]
# def checkbox_startup_osc_enabled_check_callback(checkbox_box_widget):
# callFunctionIfCallable(view_variable.CALLBACK_SET_STARTUP_OSC_ENABLED_CHECK, checkbox_box_widget.get())
def entry_message_format_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MESSAGE_FORMAT, value)
row=0
config_window.sb__auto_clear_message_box = createSettingBoxCheckbox(
@@ -45,6 +42,26 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
config_window.sb__auto_clear_message_box.grid(row=row)
row+=1
config_window.sb__send_only_translated_messages = createSettingBoxCheckbox(
for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
checkbox_attr_name="sb__checkbox_send_only_translated_messages",
command=lambda: checkbox_send_only_translated_messages_callback(config_window.sb__checkbox_send_only_translated_messages),
variable=view_variable.VAR_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES,
)
config_window.sb__send_only_translated_messages.grid(row=row)
row+=1
config_window.sb__send_message_button_type = createSettingBoxRadioButtons(
for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_BUTTON_TYPE,
for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_BUTTON_TYPE,
radio_button_attr_name="sb__radiobutton_send_message_button_type",
command=lambda: checkbox_send_message_button_type_callback(),
variable=view_variable.VAR_SEND_MESSAGE_BUTTON_TYPE,
radiobutton_keys_values=view_variable.KEYS_VALUES_SEND_MESSAGE_BUTTON_TYPE,
)
config_window.sb__send_message_button_type.grid(row=row)
row+=1
config_window.sb__notice_xsoverlay = createSettingBoxCheckbox(
for_var_label_text=view_variable.VAR_LABEL_ENABLE_NOTICE_XSOVERLAY,
@@ -69,30 +86,6 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
row+=1
config_window.sb__message_format_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_MESSAGE_FORMAT,
for_var_desc_text=view_variable.VAR_DESC_MESSAGE_FORMAT,
labels_attr_name="sb__labels_message_format",
)
config_window.sb__message_format_labels.grid(row=row, pady=0)
row+=1
config_window.sb__message_format = createSettingBoxMessageFormatEntries(
base_entry_attr_name="sb__entry_message_format",
# entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
entry_textvariable_0=view_variable.VAR_ENTRY_0_MESSAGE_FORMAT,
entry_textvariable_1=view_variable.VAR_ENTRY_1_MESSAGE_FORMAT,
entry_textvariable_2=view_variable.VAR_ENTRY_2_MESSAGE_FORMAT,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT,
textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT,
entry_bind__Any_KeyRelease=lambda value: entry_message_format_callback(value),
# entry_textvariable=view_variable.VAR_MESSAGE_FORMAT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MESSAGE_FORMAT,
)
config_window.sb__message_format.grid(row=row)
row+=1
config_window.sb__enable_send_message_to_vrc = createSettingBoxCheckbox(
for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_MESSAGE_TO_VRC,
@@ -101,16 +94,4 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
variable=view_variable.VAR_ENABLE_SEND_MESSAGE_TO_VRC,
)
config_window.sb__enable_send_message_to_vrc.grid(row=row, pady=0)
row+=1
# [deprecated]
# config_window.sb__startup_osc_enabled_check = createSettingBoxCheckbox(
# for_var_label_text=view_variable.VAR_LABEL_STARTUP_OSC_ENABLED_CHECK,
# for_var_desc_text=view_variable.VAR_DESC_STARTUP_OSC_ENABLED_CHECK,
# checkbox_attr_name="sb__checkbox_startup_osc_enabled_check",
# command=lambda: checkbox_startup_osc_enabled_check_callback(config_window.sb__checkbox_startup_osc_enabled_check),
# variable=view_variable.VAR_STARTUP_OSC_ENABLED_CHECK,
# )
# config_window.sb__startup_osc_enabled_check.grid(row=row, pady=0)
# row+=1
row+=1

View File

@@ -0,0 +1,22 @@
from utils import callFunctionIfCallable
from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Others_Additional(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
def checkbox_enable_send_received_message_to_vrc_callback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC, checkbox_box_widget.get())
row=0
config_window.sb__enable_send_received_message_to_vrc = createSettingBoxCheckbox(
for_var_label_text=view_variable.VAR_LABEL_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
checkbox_attr_name="sb__checkbox_enable_send_received_message_to_vrc",
command=lambda: checkbox_enable_send_received_message_to_vrc_callback(config_window.sb__checkbox_enable_send_received_message_to_vrc),
variable=view_variable.VAR_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC,
)
config_window.sb__enable_send_received_message_to_vrc.grid(row=row, pady=0)
row+=1

View File

@@ -0,0 +1,65 @@
from utils import callFunctionIfCallable
from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Others_ReceivedMessageFormats(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBox_Labels = sbg.createSettingBox_Labels
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
def entry_received_message_format_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT, value)
def entry_received_message_format_with_t_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T, value)
def entry_swap_received_message_format_with_t_callback(_e):
callFunctionIfCallable(view_variable.CALLBACK_SWAP_RECEIVED_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
row=0
config_window.sb__received_message_format_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_RECEIVED_MESSAGE_FORMAT,
for_var_desc_text=view_variable.VAR_DESC_RECEIVED_MESSAGE_FORMAT,
labels_attr_name="sb__labels_received_message_format",
)
config_window.sb__received_message_format_labels.grid(row=row, pady=0)
row+=1
config_window.sb__received_message_format = createSettingBoxMessageFormatEntries(
base_entry_attr_name="sb__entry_received_message_format",
entry_textvariable_0=view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT,
entry_textvariable_1=view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT,
example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT,
entry_bind__Any_KeyRelease=lambda value: entry_received_message_format_callback(value),
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT,
)
config_window.sb__received_message_format.grid(row=row)
row+=1
config_window.sb__received_message_format_with_t_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_RECEIVED_MESSAGE_FORMAT_WITH_T,
for_var_desc_text=view_variable.VAR_DESC_RECEIVED_MESSAGE_FORMAT_WITH_T,
labels_attr_name="sb__labels_message_format_with_t",
)
config_window.sb__received_message_format_with_t_labels.grid(row=row, pady=0)
row+=1
config_window.sb__received_message_format_with_t = createSettingBoxMessageFormatEntries_WithTranslation(
base_entry_attr_name="sb__entry_received_message_format_with_t",
entry_textvariable_0=view_variable.VAR_ENTRY_0_RECEIVED_MESSAGE_FORMAT_WITH_T,
entry_textvariable_1=view_variable.VAR_ENTRY_1_RECEIVED_MESSAGE_FORMAT_WITH_T,
entry_textvariable_2=view_variable.VAR_ENTRY_2_RECEIVED_MESSAGE_FORMAT_WITH_T,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_RECEIVED_MESSAGE_FORMAT_WITH_T,
textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_RECEIVED_MESSAGE_FORMAT_WITH_T,
example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_RECEIVED_MESSAGE_FORMAT_WITH_T,
entry_bind__Any_KeyRelease=lambda value: entry_received_message_format_with_t_callback(value),
swap_button_command=entry_swap_received_message_format_with_t_callback,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT_WITH_T,
)
config_window.sb__received_message_format_with_t.grid(row=row, pady=0)
row+=1

View File

@@ -0,0 +1,66 @@
from utils import callFunctionIfCallable
from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Others_SendMessageFormats(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBox_Labels = sbg.createSettingBox_Labels
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
def entry_send_message_format_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT, value)
def entry_send_message_format_with_t_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T, value)
def entry_swap_message_format_with_t_callback(_e):
callFunctionIfCallable(view_variable.CALLBACK_SWAP_SEND_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
row=0
config_window.sb__send_message_format_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_FORMAT,
for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_FORMAT,
labels_attr_name="sb__labels_send_message_format",
)
config_window.sb__send_message_format_labels.grid(row=row, pady=0)
row+=1
config_window.sb__message_format = createSettingBoxMessageFormatEntries(
base_entry_attr_name="sb__entry_send_message_format",
entry_textvariable_0=view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT,
entry_textvariable_1=view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT,
example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT,
entry_bind__Any_KeyRelease=lambda value: entry_send_message_format_callback(value),
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT,
)
config_window.sb__message_format.grid(row=row)
row+=1
config_window.sb__send_message_format_with_t_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_SEND_MESSAGE_FORMAT_WITH_T,
for_var_desc_text=view_variable.VAR_DESC_SEND_MESSAGE_FORMAT_WITH_T,
labels_attr_name="sb__labels_send_message_format_with_t",
)
config_window.sb__send_message_format_with_t_labels.grid(row=row, pady=0)
row+=1
config_window.sb__message_format_with_t = createSettingBoxMessageFormatEntries_WithTranslation(
base_entry_attr_name="sb__entry_send_message_format_with_t",
entry_textvariable_0=view_variable.VAR_ENTRY_0_SEND_MESSAGE_FORMAT_WITH_T,
entry_textvariable_1=view_variable.VAR_ENTRY_1_SEND_MESSAGE_FORMAT_WITH_T,
entry_textvariable_2=view_variable.VAR_ENTRY_2_SEND_MESSAGE_FORMAT_WITH_T,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_SEND_MESSAGE_FORMAT_WITH_T,
textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_SEND_MESSAGE_FORMAT_WITH_T,
example_label_textvariable=view_variable.VAR_LABEL_EXAMPLE_TEXT_SEND_MESSAGE_FORMAT_WITH_T,
entry_bind__Any_KeyRelease=lambda value: entry_send_message_format_with_t_callback(value),
swap_button_command=entry_swap_message_format_with_t_callback,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT_WITH_T,
)
config_window.sb__message_format_with_t.grid(row=row, pady=0)
row+=1

View File

@@ -6,18 +6,16 @@ from utils import callFunctionIfCallable
from ..ui_utils import createButtonWithImage, getImagePath, bindButtonFunctionAndColor
def createMainWindowWidgets(vrct_gui, settings, view_variable):
vrct_gui.protocol("WM_DELETE_WINDOW", lambda: callFunctionIfCallable(view_variable.CALLBACK_QUIT_VRCT))
vrct_gui.protocol("WM_DELETE_WINDOW", lambda: callFunctionIfCallable(view_variable.CALLBACK_DELETE_MAIN_WINDOW))
vrct_gui.iconbitmap(getImagePath("vrct_logo_mark_black.ico"))
vrct_gui.title("VRCT")
# vrct_gui.minsize(200, 200)
# Main Container
vrct_gui.grid_columnconfigure(0, weight=1)
vrct_gui.grid_rowconfigure(0, weight=1)
# vrct_gui.grid_columnconfigure(0, weight=1, minsize=settings.uism.MAIN_AREA_MIN_WIDTH)
vrct_gui.configure(fg_color=settings.ctm.MAIN_BG_COLOR)
@@ -122,4 +120,4 @@ def createMainWindowWidgets(vrct_gui, settings, view_variable):
createTextbox(settings, vrct_gui, view_variable)
createEntryMessageBox(settings, vrct_gui)
createEntryMessageBox(settings, vrct_gui, view_variable)

View File

@@ -317,4 +317,23 @@ def createSidebarLanguagesSettings(settings, main_window, view_variable):
open_selectable_language_window_command=callbackOpenSelectableTargetLanguageWindow,
variable=view_variable.VAR_TARGET_LANGUAGE
)
main_window.sls__box_target_language.grid(row=4, column=0, sticky="ew")
main_window.sls__box_target_language.grid(row=4, column=0, sticky="ew")
# Set Transcription ON/OFF Indicator Widgets
main_window.sls__box_your_language_mic_status__enabled = CTkLabel(
main_window.sls__box_your_language,
text=None,
height=0,
corner_radius=0,
image=CTkImage(settings.image_file.MIC_ICON_DISABLED, size=settings.uism.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE),
)
main_window.sls__box_target_language_speaker_status__enabled = CTkLabel(
main_window.sls__box_target_language,
text=None,
height=0,
corner_radius=0,
image=CTkImage(settings.image_file.HEADPHONES_ICON_DISABLED, size=settings.uism.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE),
)

View File

@@ -1,23 +1,26 @@
from customtkinter import CTkFont, CTkFrame, CTkEntry
from customtkinter import CTkFont, CTkFrame, CTkTextbox, CTkLabel, CTkImage
def createEntryMessageBox(settings, main_window):
main_window.main_entry_message_container = CTkFrame(main_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
main_window.main_entry_message_container.grid(row=2, column=0, sticky="ew")
from ...ui_utils import bindButtonFunctionAndColor
from utils import callFunctionIfCallable
def createEntryMessageBox(settings, main_window, view_variable):
main_window.main_entry_message_container = CTkFrame(main_window.main_bg_container, corner_radius=settings.uism.TEXTBOX_ENTRY_CORNER_RADIUS, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
main_window.main_entry_message_container.grid(row=2, column=0, sticky="nsew")
main_window.main_entry_message_container.grid_columnconfigure(0, weight=1)
main_window.entry_message_box = CTkEntry(
main_window.main_entry_message_container.grid_rowconfigure(0, weight=1)
main_window.entry_message_box = CTkTextbox(
main_window.main_entry_message_container,
corner_radius=settings.uism.TEXTBOX_ENTRY_CORNER_RADIUS,
border_color=settings.ctm.TEXTBOX_ENTRY_BORDER_COLOR,
fg_color=settings.ctm.TEXTBOX_ENTRY_BG_COLOR,
text_color=settings.ctm.TEXTBOX_ENTRY_TEXT_COLOR,
placeholder_text="Enter your message...",
placeholder_text_color=settings.ctm.TEXTBOX_ENTRY_PLACEHOLDER_COLOR,
height=settings.uism.TEXTBOX_ENTRY_HEIGHT,
border_width=settings.uism.TEXTBOX_ENTRY_BORDER_SIZE,
height=0,
font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.TEXTBOX_ENTRY_FONT_SIZE, weight="normal"),
)
main_window.entry_message_box.grid(row=0, column=0, padx=settings.uism.TEXTBOX_ENTRY_PADX, pady=settings.uism.TEXTBOX_ENTRY_PADY, sticky="nsew")
main_window.entry_message_box._entry.grid(padx=settings.uism.TEXTBOX_ENTRY_IPADX, pady=settings.uism.TEXTBOX_ENTRY_IPADY)
def messageBoxAnyKeyPress(e):
@@ -32,3 +35,58 @@ def createEntryMessageBox(settings, main_window):
main_window.entry_message_box.bind("<Any-KeyPress>", messageBoxAnyKeyPress)
main_window.main_send_message_button_container = CTkFrame(main_window.main_entry_message_container, corner_radius=settings.uism.SEND_MESSAGE_BUTTON_CORNER_RADIUS, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, width=0, height=0)
main_window.main_send_message_button_container.grid(row=0, column=1, padx=(0, settings.uism.TEXTBOX_ENTRY_PADX), pady=settings.uism.TEXTBOX_ENTRY_PADY, sticky="nsew")
main_window.main_send_message_button_container.grid_columnconfigure(0, weight=0, minsize=settings.uism.SEND_MESSAGE_BUTTON_MIN_WIDTH)
main_window.main_send_message_button_container.grid_rowconfigure(0, weight=1)
main_window.main_send_message_button = CTkFrame(main_window.main_send_message_button_container, corner_radius=0, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, height=0, width=0)
main_window.main_send_message_button.grid(row=0, column=0, sticky="nsew")
main_window.main_send_message_button.configure(cursor="hand2")
main_window.main_send_message_button.grid_columnconfigure((0,2), weight=1)
main_window.main_send_message_button.grid_rowconfigure((0,2), weight=1)
main_window.main_send_message_button_image = CTkLabel(
main_window.main_send_message_button,
text=None,
height=0,
image=CTkImage((settings.image_file.SEND_MESSAGE_ICON),size=(settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE,settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE)),
)
main_window.main_send_message_button_image.grid(row=1, column=1)
bindButtonFunctionAndColor(
target_widgets=[main_window.main_send_message_button, main_window.main_send_message_button_image],
enter_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR,
leave_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR,
clicked_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR,
buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_SEND_MESSAGE_BUTTON, _e),
)
main_window.main_send_message_button__disabled = CTkFrame(main_window.main_send_message_button_container, corner_radius=0, fg_color=settings.ctm.SEND_MESSAGE_BUTTON_BG_COLOR, height=0, width=0)
main_window.main_send_message_button__disabled.grid(row=0, column=0, sticky="nsew")
main_window.main_send_message_button__disabled.grid_columnconfigure((0,2), weight=1)
main_window.main_send_message_button__disabled.grid_rowconfigure((0,2), weight=1)
main_window.main_send_message_button_image__disabled = CTkLabel(
main_window.main_send_message_button__disabled,
text=None,
height=0,
image=CTkImage((settings.image_file.SEND_MESSAGE_ICON_DISABLED),size=(settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE,settings.uism.SEND_MESSAGE_BUTTON_IMAGE_SIZE)),
)
main_window.main_send_message_button_image__disabled.grid(row=1, column=1)
main_window.main_send_message_button__disabled.grid_remove()

View File

@@ -59,7 +59,7 @@ def createTextbox(settings, main_window, view_variable):
# Text box
main_window.main_bg_container.grid_rowconfigure(1, weight=1)
main_window.main_textbox_container = CTkFrame(main_window.main_bg_container, corner_radius=0, fg_color=settings.ctm.MAIN_BG_COLOR, width=0, height=0)
main_window.main_textbox_container.grid(row=1, column=0, sticky="nsew")
main_window.main_textbox_container.grid(row=1, column=0, columnspan=2, sticky="nsew")
main_window.main_textbox_container.grid_columnconfigure(0,weight=1)
main_window.main_textbox_container.grid_rowconfigure(0,weight=1)
@@ -142,6 +142,7 @@ def createTextbox(settings, main_window, view_variable):
fg_color=settings.ctm.TEXTBOX_BG_COLOR,
text_color="lime", # Textbox's text_color is set when printing. so this is for prevent from non-setting text_color like the gloves used in food factories are blue.
wrap="word",
height=0,
))
textbox_widget = getattr(main_window, textbox_setting["textbox_attr_name"])
textbox_widget.grid(row=0, column=0, padx=settings.uism.TEXTBOX_PADX, pady=0, sticky="nsew")

View File

@@ -12,7 +12,6 @@ class SplashWindow(CTkToplevel):
sw=self.winfo_screenwidth()
# sh=self.winfo_screenheight()
pw=int(sw/4)

View File

@@ -35,6 +35,10 @@ def _darkTheme(base_color):
TEXTBOX_ENTRY_PLACEHOLDER_COLOR = base_color.DARK_500_COLOR,
TEXTBOX_ENTRY_PLACEHOLDER_DISABLED_COLOR = base_color.DARK_700_COLOR,
SEND_MESSAGE_BUTTON_BG_COLOR = base_color.DARK_850_COLOR,
SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR = base_color.DARK_900_COLOR,
# Sidebar
SIDEBAR_BG_COLOR = base_color.DARK_850_COLOR,
@@ -211,10 +215,17 @@ def _darkTheme(base_color):
SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_350_COLOR,
SB__CHECKBOX_BORDER_COLOR = base_color.DARK_600_COLOR,
SB__CHECKBOX_BORDER_DISABLED_COLOR = base_color.DARK_800_COLOR,
SB__CHECKBOX_HOVER_COLOR = base_color.DARK_800_COLOR,
SB__CHECKBOX_CHECKED_COLOR = base_color.PRIMARY_700_COLOR,
SB__CHECKBOX_CHECKMARK_COLOR = base_color.DARK_BASIC_TEXT_COLOR,
SB__RADIOBUTTON_TEXT_COLOR = base_color.DARK_300_COLOR,
SB__RADIOBUTTON_BORDER_COLOR = base_color.DARK_600_COLOR,
SB__RADIOBUTTON_SELECTED_COLOR = base_color.PRIMARY_400_COLOR,
SB__RADIOBUTTON_BG_HOVERED_COLOR = base_color.DARK_825_COLOR,
SB__RADIOBUTTON_BG_CLICKED_COLOR = base_color.DARK_900_COLOR,
SB__ENTRY_TEXT_COLOR = base_color.DARK_300_COLOR,
SB__ENTRY_BG_COLOR = base_color.DARK_863_COLOR,
SB__ENTRY_BORDER_COLOR = base_color.DARK_775_COLOR,
@@ -300,6 +311,8 @@ def _darkTheme(base_color):
ARROW_LEFT = getImageFileFromUiUtils("arrow_left_white.png"),
ARROW_LEFT_DISABLED = getImageFileFromUiUtils("arrow_left_disabled.png"),
SEND_MESSAGE_ICON = getImageFileFromUiUtils("send_message_icon_white.png"),
SEND_MESSAGE_ICON_DISABLED = getImageFileFromUiUtils("send_message_icon_black.png"),
REFRESH_UPDATE_ICON = getImageFileFromUiUtils("refresh_update_icon.png"),
REFRESH_ICON = getImageFileFromUiUtils("refresh_icon.png"),
HELP_ICON = getImageFileFromUiUtils("help_icon_white.png"),

View File

@@ -35,6 +35,10 @@ def _lightTheme(base_color):
TEXTBOX_ENTRY_PLACEHOLDER_COLOR = base_color.LIGHT_600_COLOR,
TEXTBOX_ENTRY_PLACEHOLDER_DISABLED_COLOR = base_color.LIGHT_400_COLOR,
SEND_MESSAGE_BUTTON_BG_COLOR = base_color.LIGHT_300_COLOR,
SEND_MESSAGE_BUTTON_BG_HOVERED_COLOR = base_color.LIGHT_325_COLOR,
SEND_MESSAGE_BUTTON_BG_CLICKED_COLOR = base_color.LIGHT_350_COLOR,
# Sidebar
SIDEBAR_BG_COLOR = base_color.LIGHT_250_COLOR,
@@ -204,10 +208,17 @@ def _lightTheme(base_color):
SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_200_COLOR,
SB__CHECKBOX_BORDER_COLOR = base_color.LIGHT_600_COLOR,
SB__CHECKBOX_BORDER_DISABLED_COLOR = base_color.LIGHT_300_COLOR,
SB__CHECKBOX_HOVER_COLOR = base_color.LIGHT_350_COLOR,
SB__CHECKBOX_CHECKED_COLOR = base_color.PRIMARY_250_COLOR,
SB__CHECKBOX_CHECKMARK_COLOR = base_color.LIGHT_BASIC_TEXT_COLOR,
SB__RADIOBUTTON_TEXT_COLOR = base_color.LIGHT_900_COLOR,
SB__RADIOBUTTON_BORDER_COLOR = base_color.LIGHT_600_COLOR,
SB__RADIOBUTTON_SELECTED_COLOR = base_color.PRIMARY_400_COLOR,
SB__RADIOBUTTON_BG_HOVERED_COLOR = base_color.LIGHT_300_COLOR,
SB__RADIOBUTTON_BG_CLICKED_COLOR = base_color.LIGHT_325_COLOR,
SB__ENTRY_TEXT_COLOR = base_color.LIGHT_900_COLOR,
SB__ENTRY_BG_COLOR = base_color.LIGHT_300_COLOR,
SB__ENTRY_BORDER_COLOR = base_color.LIGHT_400_COLOR,
@@ -294,6 +305,8 @@ def _lightTheme(base_color):
ARROW_LEFT = getImageFileFromUiUtils("arrow_left_black.png"),
ARROW_LEFT_DISABLED = getImageFileFromUiUtils("arrow_left_disabled.png"),
SEND_MESSAGE_ICON = getImageFileFromUiUtils("send_message_icon_black.png"),
SEND_MESSAGE_ICON_DISABLED = getImageFileFromUiUtils("send_message_icon_white.png"),
REFRESH_UPDATE_ICON = getImageFileFromUiUtils("refresh_update_icon.png"),
REFRESH_ICON = getImageFileFromUiUtils("refresh_icon.png"),
HELP_ICON = getImageFileFromUiUtils("help_icon_black.png"),

View File

@@ -50,11 +50,17 @@ class UiScalingManager():
self.main.TEXTBOX_FONT_SIZE__MAIN_TEXT_FONT = self._calculateUiSize(16)
self.main.TEXTBOX_ENTRY_FONT_SIZE = self._calculateUiSize(16)
self.main.TEXTBOX_ENTRY_CORNER_RADIUS = self._calculateUiSize(4)
self.main.TEXTBOX_ENTRY_BORDER_SIZE = self._calculateUiSize(2, is_allowed_odd=True)
self.main.TEXTBOX_ENTRY_HEIGHT = self._calculateUiSize(40)
self.main.TEXTBOX_ENTRY_PADX = self.main.TEXTBOX_PADX
self.main.TEXTBOX_ENTRY_PADY = self._calculateUiSize(10)
self.main.TEXTBOX_ENTRY_IPADX = self._calculateUiSize(14)
self.main.TEXTBOX_ENTRY_IPADY = (self._calculateUiSize(2, True), self._calculateUiSize(3, True))
self.main.SEND_MESSAGE_BUTTON_CORNER_RADIUS = self.main.TEXTBOX_ENTRY_CORNER_RADIUS
self.main.SEND_MESSAGE_BUTTON_IMAGE_SIZE = self._calculateUiSize(20)
self.main.SEND_MESSAGE_BUTTON_MIN_WIDTH = self._calculateUiSize(40)
self.main.SEND_MESSAGE_BUTTON_RATE_WIDTH = self._calculateUiSize(6)
self.main.SEND_MESSAGE_BUTTON_MAX_WIDTH = self._calculateUiSize(100)
# Sidebar
@@ -86,6 +92,9 @@ class UiScalingManager():
self.main.SLS__PRESET_TAB_NUMBER_CORNER_RADIUS = self._calculateUiSize(6)
self.main.SLS__PRESET_TAB_NUMBER_ADJUSTED_HEIGHT = self._calculateUiSize(36)
self.main.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(14))
self.main.SLS__BOX_SECTION_TITLE_FONT_SIZE = self._calculateUiSize(16)
self.main.SLS__BOX_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(10)
self.main.SLS__BOX_IPADX = self._calculateUiSize(10)
@@ -160,6 +169,8 @@ class UiScalingManager():
self.confirmation_modal.BUTTONS_IPADX = self._calculateUiSize(10)
self.confirmation_modal.BUTTONS_IPADY = self._calculateUiSize(6)
# Dropdown Menu Window
self.config_window.MARGIN_WIDTH = self._calculateUiSize(16)
# Config Window
self.config_window.DEFAULT_WIDTH = self._calculateUiSize(1080)
@@ -296,6 +307,7 @@ class UiScalingManager():
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADX = (self._calculateUiSize(8), 0)
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_TEXT_IPADY = self._calculateUiSize(6)
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IMG_SIZE = self._calculateUiSize(14)
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_CORNER_RADIUS = self._calculateUiSize(4)
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_IPADXY = self._calculateUiSize(6)
self.config_window.ADD_AND_DELETE_ABLE_LIST__VALUES_ACTION_BUTTON_PADX = (self._calculateUiSize(6), self._calculateUiSize(8))
@@ -322,9 +334,9 @@ class UiScalingManager():
self.config_window.SB__BUTTON_IPADXY = self._calculateUiSize(16)
self.config_window.SB__BUTTON_ICON_SIZE = self._calculateUiSize(24)
self.config_window.SB__BUTTON_CORNER_RADIUS = self.config_window.BUTTONS_CORNER_RADIUS
self.config_window.SB__OPEN_CONFIG_FILE_BUTTON_IPADXY = self._calculateUiSize(10)
self.config_window.SB__OPEN_CONFIG_FILE_BUTTON_ICON_SIZE = self._calculateUiSize(20)
def _calculateUiSize(self, default_size, is_allowed_odd:bool=False, is_zero_allowed:bool=False):

View File

@@ -0,0 +1,79 @@
# Override customtkinter's CTkScrollableFrame for scrolling speed up
from customtkinter import CTkScrollableFrame, CTkFont
from typing import Union, Tuple, Optional
import sys
try:
from typing import Literal
except ImportError:
from typing_extensions import Literal
class CustomizedCTkScrollableFrame(CTkScrollableFrame):
def __init__(
self,
master: any,
width: int = 200,
height: int = 200,
corner_radius: Optional[Union[int, str]] = None,
border_width: Optional[Union[int, str]] = None,
bg_color: Union[str, Tuple[str, str]] = "transparent",
fg_color: Optional[Union[str, Tuple[str, str]]] = None,
border_color: Optional[Union[str, Tuple[str, str]]] = None,
scrollbar_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
scrollbar_button_color: Optional[Union[str, Tuple[str, str]]] = None,
scrollbar_button_hover_color: Optional[Union[str, Tuple[str, str]]] = None,
label_fg_color: Optional[Union[str, Tuple[str, str]]] = None,
label_text_color: Optional[Union[str, Tuple[str, str]]] = None,
label_text: str = "",
label_font: Optional[Union[tuple, CTkFont]] = None,
label_anchor: str = "center",
orientation: Literal["vertical", "horizontal"] = "vertical"
):
super().__init__(
master,
width,
height,
corner_radius,
border_width,
bg_color,
fg_color,
border_color,
scrollbar_fg_color,
scrollbar_button_color,
scrollbar_button_hover_color,
label_fg_color,
label_text_color,
label_text,
label_font,
label_anchor,
orientation,
)
def _mouse_wheel_all(self, event):
if self.check_if_master_is_canvas(event.widget):
if sys.platform.startswith("win"):
if self._shift_pressed:
if self._parent_canvas.xview() != (0.0, 1.0):
self._parent_canvas.xview("scroll", -int(event.delta / 6), "units")
else:
if self._parent_canvas.yview() != (0.0, 1.0):
self._parent_canvas.yview("scroll", -int(event.delta / 2), "units")
elif sys.platform == "darwin":
if self._shift_pressed:
if self._parent_canvas.xview() != (0.0, 1.0):
self._parent_canvas.xview("scroll", -event.delta, "units")
else:
if self._parent_canvas.yview() != (0.0, 1.0):
self._parent_canvas.yview("scroll", -event.delta, "units")
else:
if self._shift_pressed:
if self._parent_canvas.xview() != (0.0, 1.0):
self._parent_canvas.xview("scroll", -event.delta, "units")
else:
if self._parent_canvas.yview() != (0.0, 1.0):
self._parent_canvas.yview("scroll", -event.delta, "units")

View File

@@ -1 +1,2 @@
from .ui_utils import *
from .ui_utils import *
from .CustomizedCTkScrollableFrame import CustomizedCTkScrollableFrame

View File

@@ -43,11 +43,21 @@ class VRCT_GUI(CTk):
def _showGUI(self):
self.attributes("-alpha", 0)
self.deiconify()
self.geometry("{}x{}".format(
self.settings.main.uism.MAIN_AREA_MIN_WIDTH + self.settings.main.uism.SIDEBAR_MIN_WIDTH,
self.winfo_height()
))
setGeometryToCenterOfScreen(root_widget=self)
if self.settings.main.to_restore_main_window_geometry is True:
self.geometry("{}x{}+{}+{}".format(
self.settings.main.geometry.width,
self.settings.main.geometry.height,
self.settings.main.geometry.x_pos,
self.settings.main.geometry.y_pos,
))
else:
self.geometry("{}x{}".format(
self.settings.main.uism.MAIN_AREA_MIN_WIDTH + self.settings.main.uism.SIDEBAR_MIN_WIDTH,
self.winfo_height()
))
setGeometryToCenterOfScreen(root_widget=self)
if self._view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE is True:
self._enableMainWindowSidebarCompactMode()
fadeInAnimation(self, steps=5, interval=0.008)