Merge branch 'develop'

This commit is contained in:
misyaguziya
2024-01-26 22:59:08 +09:00
45 changed files with 1653 additions and 431 deletions

7
.gitignore vendored
View File

@@ -1,8 +1,11 @@
build/
dist/
config.json
/config.json
memo.txt
VRCT.spec
*.pyc
logs/
.venv/
.venv/
weight/
.vscode
error.log

View File

@@ -6,7 +6,7 @@
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| [English](./README.md) | **日本語** |
| [English](./README.md) | **日本語** | [한국어](./README.kr.md) |
<h3>
VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。

65
README.kr.md Normal file
View File

@@ -0,0 +1,65 @@
<div align="center">
![](docs/vrct_logo.png)
[![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases)
[![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases)
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| [English](./README.md) | [日本語](./README.jp.md) | **한국어** |
<h3>
VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다.
</h3>
![](docs/main_window.png)
<div align="left">
# 다운로드 및 설치
원하는 곳에서 다운로드 할 수 있어요.
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
다운로드 후 exe를 실행하기만 하면 됩니다.
# VRCT가 뭔가요?
VRCT는 서로 다른 언어를 사용하는 사람들끼리 대화를 할 수 있도록 채팅이나 음성 번역을 통해 대화를 지원하는 소프트웨어에요.
이 기능들은 VRChat 내에서 사용하도록 설계되었어요.
※ 지원 대상에서 제외되지만, 영화 감상 등 다른 용도로도 사용되고 있습니다.
VRCT는 다음과 같이 당신의 대화를 도와드려요.
- 💬 **VRChat으로의 채팅 전송 기능**
- 🌐 **번역 기능**
- 🎙 **마이크 음성인식 기능**
- 🔈 **스피커 음성인식 기능**
# 문서 (일본어)
초기 설정과 기본 기능 및 기타 기능에 대해 설명되어 있어요.
- [Documents Link](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# 사용법 (Youtube)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
# python으로 실행하고 싶은 경우
1. 다음 버전의 python을 설치합니다.
`python version 3.11.5`
2. 패키지를 설치하고 main.py를 실행합니다.
```bash
./install.bat
python main.py
```
## Author
- [みしゃ(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) (로고 디자인)
---
VRCT는 VRChat의 어떠한 승인도 받지 않았으며, VRChat 또는 VRChat의 개발 또는 관리에 공식적으로 관여하는 사람의 견해나 의견을 반영하지 않습니다. VRChat 및 모든 관련 재산은 미국 VRChat, Inc의 상표 또는 등록상표입니다.

View File

@@ -6,7 +6,7 @@
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| **English** | [日本語](./README.jp.md) |
| **English** | [日本語](./README.jp.md) | [한국어](./README.kr.md) |
<h3>
VRCT is software that supports VRChat conversations with translation and transcription.

View File

@@ -1,2 +1,2 @@
pyinstaller --windowed --clean --noconfirm --icon="./img/vrct_logo_mark_black.ico" --add-data "./img;img/" --add-data "./locales;locales/" --add-data "./batch;batch/" --name VRCT --exclude-module numpy --exclude-module pandas --exclude-module matplotlib --exclude-module PyQt5 main.py
pyinstaller --windowed --clean --noconfirm --icon="./img/vrct_logo_mark_black.ico" --add-data "./img;img/" --add-data "./locales;locales/" --add-data "./batch;batch/" --name VRCT --add-data ".venv\Lib\site-packages\customtkinter;customtkinter/" --exclude-module pandas --exclude-module matplotlib --exclude-module PyQt5 main.py
"C:\Program Files (x86)\NSIS\makensis.exe" installer/installer.nsi

121
config.py
View File

@@ -5,7 +5,7 @@ from json import load as json_load
from json import dump as json_dump
import tkinter as tk
from tkinter import font
from models.translation.translation_languages import translatorEngine
from models.translation.translation_languages import translation_lang
from models.transcription.transcription_utils import getInputDevices, getDefaultInputDevice
from utils import generatePercentageStringsList, isUniqueStrings
@@ -43,8 +43,12 @@ class Config:
return self._ENABLE_SPEAKER2CHATBOX
@property
def LOCAL_PATH(self):
return self._LOCAL_PATH
def ENABLE_SPEAKER2CHATBOX(self):
return self._ENABLE_SPEAKER2CHATBOX
@property
def PATH_LOCAL(self):
return self._PATH_LOCAL
@property
def PATH_CONFIG(self):
@@ -90,6 +94,10 @@ class Config:
def SELECTABLE_UI_LANGUAGES_DICT(self):
return self._SELECTABLE_UI_LANGUAGES_DICT
@property
def SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT(self):
return self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT
@property
def MAX_MIC_ENERGY_THRESHOLD(self):
return self._MAX_MIC_ENERGY_THRESHOLD
@@ -172,13 +180,31 @@ class Config:
self._TARGET_LANGUAGE = value
@property
def CHOICE_TRANSLATOR(self):
return self._CHOICE_TRANSLATOR
def CHOICE_INPUT_TRANSLATOR(self):
return self._CHOICE_INPUT_TRANSLATOR
@CHOICE_TRANSLATOR.setter
def CHOICE_TRANSLATOR(self, value):
if value in translatorEngine:
self._CHOICE_TRANSLATOR = value
@CHOICE_INPUT_TRANSLATOR.setter
def CHOICE_INPUT_TRANSLATOR(self, value):
if value in list(translation_lang.keys()):
self._CHOICE_INPUT_TRANSLATOR= value
@property
def CHOICE_OUTPUT_TRANSLATOR(self):
return self._CHOICE_OUTPUT_TRANSLATOR
@CHOICE_OUTPUT_TRANSLATOR.setter
def CHOICE_OUTPUT_TRANSLATOR(self, value):
if value in list(translation_lang.keys()):
self._CHOICE_OUTPUT_TRANSLATOR = value
@property
def IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION(self):
return self._IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION
@IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION.setter
def IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION(self, value):
if isinstance(value, bool):
self._IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = value
# Save Json Data
## Main Window
@@ -193,6 +219,28 @@ class Config:
self._SELECTED_TAB_NO = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('SELECTED_TAB_YOUR_TRANSLATOR_ENGINES')
def SELECTED_TAB_YOUR_TRANSLATOR_ENGINES(self):
return self._SELECTED_TAB_YOUR_TRANSLATOR_ENGINES
@SELECTED_TAB_YOUR_TRANSLATOR_ENGINES.setter
def SELECTED_TAB_YOUR_TRANSLATOR_ENGINES(self, value):
if isinstance(value, dict):
self._SELECTED_TAB_YOUR_TRANSLATOR_ENGINES = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('SELECTED_TAB_TARGET_TRANSLATOR_ENGINES')
def SELECTED_TAB_TARGET_TRANSLATOR_ENGINES(self):
return self._SELECTED_TAB_TARGET_TRANSLATOR_ENGINES
@SELECTED_TAB_TARGET_TRANSLATOR_ENGINES.setter
def SELECTED_TAB_TARGET_TRANSLATOR_ENGINES(self, value):
if isinstance(value, dict):
self._SELECTED_TAB_TARGET_TRANSLATOR_ENGINES = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('SELECTED_TAB_YOUR_LANGUAGES')
def SELECTED_TAB_YOUR_LANGUAGES(self):
@@ -509,6 +557,29 @@ class Config:
self._AUTH_KEYS[key] = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.AUTH_KEYS)
@property
@json_serializable('USE_TRANSLATION_FEATURE')
def USE_TRANSLATION_FEATURE(self):
return self._USE_TRANSLATION_FEATURE
@USE_TRANSLATION_FEATURE.setter
def USE_TRANSLATION_FEATURE(self, value):
if isinstance(value, bool):
self._USE_TRANSLATION_FEATURE = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('WEIGHT_TYPE')
def WEIGHT_TYPE(self):
return self._WEIGHT_TYPE
@WEIGHT_TYPE.setter
def WEIGHT_TYPE(self, value):
# if isinstance(value, str) and value in self.SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT:
if isinstance(value, str):
self._WEIGHT_TYPE = 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):
@@ -660,11 +731,11 @@ class Config:
def init_config(self):
# Read Only
self._VERSION = "2.0.2"
self._VERSION = "2.1.0"
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")
self._PATH_LOCAL = os_path.dirname(sys.argv[0])
self._PATH_CONFIG = os_path.join(self._PATH_LOCAL, "config.json")
self._PATH_LOGS = os_path.join(self._PATH_LOCAL, "logs")
os_makedirs(self._PATH_LOGS, exist_ok=True)
self._GITHUB_URL = "https://api.github.com/repos/misyaguziya/VRCT/releases/latest"
self._BOOTH_URL = "https://misyaguziya.booth.pm/"
@@ -680,6 +751,11 @@ class Config:
"ko": "한국어"
# If you want to add a new language and key, please append it here.
}
self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = {
# {Save json str}: {i18n_placeholder} pairs
"Small": "Small",
"Large": "Large",
}
self._MAX_MIC_ENERGY_THRESHOLD = 2000
self._MAX_SPEAKER_ENERGY_THRESHOLD = 4000
@@ -688,15 +764,27 @@ class Config:
self._ENABLE_TRANSCRIPTION_SEND = False
self._ENABLE_TRANSCRIPTION_RECEIVE = False
self._ENABLE_FOREGROUND = False
self._CHOICE_TRANSLATOR = translatorEngine[0]
self._CHOICE_INPUT_TRANSLATOR = "CTranslate2"
self._CHOICE_OUTPUT_TRANSLATOR = "CTranslate2"
self._SOURCE_LANGUAGE = "Japanese"
self._SOURCE_COUNTRY = "Japan"
self._TARGET_LANGUAGE = "English"
self._TARGET_COUNTRY = "United States"
self._IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = False
# Save Json Data
## Main Window
self._SELECTED_TAB_NO = "1"
self._SELECTED_TAB_YOUR_TRANSLATOR_ENGINES = {
"1":"CTranslate2",
"2":"CTranslate2",
"3":"CTranslate2",
}
self._SELECTED_TAB_TARGET_TRANSLATOR_ENGINES = {
"1":"CTranslate2",
"2":"CTranslate2",
"3":"CTranslate2",
}
self._SELECTED_TAB_YOUR_LANGUAGES = {
"1":"Japanese\n(Japan)",
"2":"Japanese\n(Japan)",
@@ -741,10 +829,9 @@ class Config:
self._OSC_PORT = 9000
self._AUTH_KEYS = {
"DeepL_API": None,
"DeepL": None,
"Bing": None,
"Google": None,
}
self._USE_TRANSLATION_FEATURE = True
self._WEIGHT_TYPE = "Small"
self._SEND_MESSAGE_FORMAT = "[message]"
self._SEND_MESSAGE_FORMAT_WITH_T = "[message]([translation])"
self._RECEIVED_MESSAGE_FORMAT = "[message]"

View File

@@ -21,8 +21,8 @@ def callbackFilepathLogs():
Popen(['explorer', config.PATH_LOGS.replace('/', '\\')], shell=True)
def callbackFilepathConfigFile():
print("callbackFilepathConfigFile", config.LOCAL_PATH.replace('/', '\\'))
Popen(['explorer', config.LOCAL_PATH.replace('/', '\\')], shell=True)
print("callbackFilepathConfigFile", config.PATH_LOCAL.replace('/', '\\'))
Popen(['explorer', config.PATH_LOCAL.replace('/', '\\')], shell=True)
def callbackQuitVrct():
setMainWindowGeometry()
@@ -55,6 +55,12 @@ def messageFormatter(format_type:str, translation, message):
osc_message = FORMAT.replace("[message]", message)
return osc_message
def changeToCTranslate2Process():
config.CHOICE_INPUT_TRANSLATOR = "CTranslate2"
config.CHOICE_OUTPUT_TRANSLATOR = "CTranslate2"
updateTranslationEngineAndEngineList()
view.printToTextbox_TranslationEngineLimitError()
# func transcription send message
def sendMicMessage(message):
if len(message) > 0:
@@ -65,11 +71,9 @@ def sendMicMessage(message):
elif config.ENABLE_TRANSLATION is False:
pass
else:
translation = model.getInputTranslate(message)
if translation is False:
config.ENABLE_TRANSLATION = False
translation = ""
view.translationEngineLimitErrorProcess()
translation, success = model.getInputTranslate(message)
if success is False:
changeToCTranslate2Process()
if config.ENABLE_TRANSCRIPTION_SEND is True:
if config.ENABLE_SEND_MESSAGE_TO_VRC is True:
@@ -132,11 +136,9 @@ def receiveSpeakerMessage(message):
if config.ENABLE_TRANSLATION is False:
pass
else:
translation = model.getOutputTranslate(message)
if translation is False:
config.ENABLE_TRANSLATION = False
translation = ""
view.translationEngineLimitErrorProcess()
translation, success = model.getOutputTranslate(message)
if success is False:
changeToCTranslate2Process()
if config.ENABLE_TRANSCRIPTION_RECEIVE is True:
if config.ENABLE_NOTICE_XSOVERLAY is True:
@@ -202,11 +204,9 @@ def sendChatMessage(message):
if config.ENABLE_TRANSLATION is False:
pass
else:
translation = model.getInputTranslate(message)
if translation is False:
config.ENABLE_TRANSLATION = False
translation = ""
view.translationEngineLimitErrorProcess()
translation, success = model.getInputTranslate(message)
if success is False:
changeToCTranslate2Process()
# send OSC message
if config.ENABLE_SEND_MESSAGE_TO_VRC is True:
@@ -249,7 +249,22 @@ def messageBoxFocusOut(e):
if config.ENABLE_SEND_MESSAGE_TO_VRC is True:
model.oscStopSendTyping()
# func select languages
def updateTranslationEngineAndEngineList():
engine = config.CHOICE_INPUT_TRANSLATOR
engines = model.findTranslationEngines(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
if engine not in engines:
engine = engines[0]
config.CHOICE_INPUT_TRANSLATOR = engine
config.CHOICE_OUTPUT_TRANSLATOR = engine
view.updateSelectableTranslationEngineList(engines)
view.setGuiVariable_SelectedTranslationEngine(engine)
def initSetTranslateEngine():
engine = config.SELECTED_TAB_YOUR_TRANSLATOR_ENGINES[config.SELECTED_TAB_NO]
config.CHOICE_INPUT_TRANSLATOR = engine
engine = config.SELECTED_TAB_TARGET_TRANSLATOR_ENGINES[config.SELECTED_TAB_NO]
config.CHOICE_OUTPUT_TRANSLATOR = engine
def initSetLanguageAndCountry():
select = config.SELECTED_TAB_YOUR_LANGUAGES[config.SELECTED_TAB_NO]
language, country = model.getLanguageAndCountry(select)
@@ -259,7 +274,18 @@ def initSetLanguageAndCountry():
language, country = model.getLanguageAndCountry(select)
config.TARGET_LANGUAGE = language
config.TARGET_COUNTRY = country
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
def setYourTranslateEngine(select):
engines = config.SELECTED_TAB_YOUR_TRANSLATOR_ENGINES
engines[config.SELECTED_TAB_NO] = select
config.SELECTED_TAB_YOUR_TRANSLATOR_ENGINES = engines
config.CHOICE_INPUT_TRANSLATOR = select
def setTargetTranslateEngine(select):
engines = config.SELECTED_TAB_TARGET_TRANSLATOR_ENGINES
engines[config.SELECTED_TAB_NO] = select
config.SELECTED_TAB_TARGET_TRANSLATOR_ENGINES = engines
config.CHOICE_OUTPUT_TRANSLATOR = select
def setYourLanguageAndCountry(select):
languages = config.SELECTED_TAB_YOUR_LANGUAGES
@@ -268,7 +294,7 @@ def setYourLanguageAndCountry(select):
language, country = model.getLanguageAndCountry(select)
config.SOURCE_LANGUAGE = language
config.SOURCE_COUNTRY = country
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
updateTranslationEngineAndEngineList()
view.printToTextbox_selectedYourLanguages(select)
def setTargetLanguageAndCountry(select):
@@ -278,7 +304,7 @@ def setTargetLanguageAndCountry(select):
language, country = model.getLanguageAndCountry(select)
config.TARGET_LANGUAGE = language
config.TARGET_COUNTRY = country
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
updateTranslationEngineAndEngineList()
view.printToTextbox_selectedTargetLanguages(select)
def swapYourLanguageAndTargetLanguage():
@@ -293,18 +319,34 @@ def swapYourLanguageAndTargetLanguage():
def callbackSelectedLanguagePresetTab(selected_tab_no):
config.SELECTED_TAB_NO = selected_tab_no
view.updateGuiVariableByPresetTabNo(config.SELECTED_TAB_NO)
engines = config.SELECTED_TAB_YOUR_TRANSLATOR_ENGINES
engine = engines[config.SELECTED_TAB_NO]
config.CHOICE_INPUT_TRANSLATOR = engine
engines = config.SELECTED_TAB_TARGET_TRANSLATOR_ENGINES
engine = engines[config.SELECTED_TAB_NO]
config.CHOICE_OUTPUT_TRANSLATOR = engine
languages = config.SELECTED_TAB_YOUR_LANGUAGES
select = languages[config.SELECTED_TAB_NO]
language, country = model.getLanguageAndCountry(select)
config.SOURCE_LANGUAGE = language
config.SOURCE_COUNTRY = country
languages = config.SELECTED_TAB_TARGET_LANGUAGES
select = languages[config.SELECTED_TAB_NO]
language, country = model.getLanguageAndCountry(select)
config.TARGET_LANGUAGE = language
config.TARGET_COUNTRY = country
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
view.printToTextbox_changedLanguagePresetTab(config.SELECTED_TAB_NO)
updateTranslationEngineAndEngineList()
def callbackSelectedTranslationEngine(selected_translation_engine):
print("callbackSelectedTranslationEngine", selected_translation_engine)
setYourTranslateEngine(selected_translation_engine)
setTargetTranslateEngine(selected_translation_engine)
view.setGuiVariable_SelectedTranslationEngine(config.CHOICE_OUTPUT_TRANSLATOR)
# command func
def callbackToggleTranslation(is_turned_on):
@@ -437,14 +479,54 @@ def callbackSetUiLanguage(value):
view.showRestartButtonIfRequired(locale=config.UI_LANGUAGE)
def callbackSetEnableRestoreMainWindowGeometry(value):
print("callbackSetEnableAutoClearMessageBox", value)
print("callbackSetEnableRestoreMainWindowGeometry", value)
config.ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY = value
# Translation Tab
def callbackSetDeeplAuthkey(value):
print("callbackSetDeeplAuthkey", str(value))
def callbackSetUseTranslationFeature(value):
print("callbackSetUseTranslationFeature", value)
config.USE_TRANSLATION_FEATURE = value
if config.USE_TRANSLATION_FEATURE is True:
view.useTranslationFeatureProcess("Normal")
if model.checkCTranslatorCTranslate2ModelWeight():
config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = False
def callback():
model.changeTranslatorCTranslate2Model()
th_callback = Thread(target=callback)
th_callback.daemon = True
th_callback.start()
else:
config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = True
view.useTranslationFeatureProcess("Restart")
else:
config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = False
view.useTranslationFeatureProcess("Disable")
view.showRestartButtonIfRequired()
def callbackSetCtranslate2WeightType(value):
print("callbackSetCtranslate2WeightType", value)
config.WEIGHT_TYPE = str(value)
view.updateSelectedCtranslate2WeightType(config.WEIGHT_TYPE)
view.setWidgetsStatus_changeWeightType_Pending()
if model.checkCTranslatorCTranslate2ModelWeight():
config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = False
def callback():
model.changeTranslatorCTranslate2Model()
view.useTranslationFeatureProcess("Normal")
view.setWidgetsStatus_changeWeightType_Done()
th_callback = Thread(target=callback)
th_callback.daemon = True
th_callback.start()
else:
config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION = True
view.useTranslationFeatureProcess("Restart")
view.setWidgetsStatus_changeWeightType_Done()
view.showRestartButtonIfRequired()
def callbackSetDeeplAuthKey(value):
print("callbackSetDeeplAuthKey", str(value))
if len(value) == 39:
result = model.authenticationTranslator(choice_translator="DeepL_API", auth_key=value)
result = model.authenticationTranslatorDeepLAuthKey(auth_key=value)
if result is True:
key = value
view.printToTextbox_AuthenticationSuccess()
@@ -454,12 +536,11 @@ def callbackSetDeeplAuthkey(value):
auth_keys = config.AUTH_KEYS
auth_keys["DeepL_API"] = key
config.AUTH_KEYS = auth_keys
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
elif len(value) == 0:
auth_keys = config.AUTH_KEYS
auth_keys["DeepL_API"] = None
config.AUTH_KEYS = auth_keys
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
updateTranslationEngineAndEngineList()
# Transcription Tab
# Transcription (Mic)
@@ -795,21 +876,27 @@ def initSetConfigByExeArguments():
config.OSC_PORT = int(args.port)
view.setGuiVariable_OscPort(config.OSC_PORT)
def createMainWindow():
def createMainWindow(splash):
splash.toProgress(1)
# create GUI
view.createGUI()
splash.toProgress(2)
# init config
initSetConfigByExeArguments()
initSetTranslateEngine()
initSetLanguageAndCountry()
if model.authenticationTranslator(config.CHOICE_TRANSLATOR, config.AUTH_KEYS[config.CHOICE_TRANSLATOR]) is False:
# error update Auth key
auth_keys = config.AUTH_KEYS
auth_keys[config.CHOICE_TRANSLATOR] = None
config.AUTH_KEYS = auth_keys
view.printToTextbox_AuthenticationError()
config.CHOICE_TRANSLATOR = model.findTranslationEngine(config.SOURCE_LANGUAGE, config.TARGET_LANGUAGE)
if config.AUTH_KEYS["DeepL_API"] is not None:
if model.authenticationTranslatorDeepLAuthKey(auth_key=config.AUTH_KEYS["DeepL_API"]) is False:
# error update Auth key
auth_keys = config.AUTH_KEYS
auth_keys["DeepL_API"] = None
config.AUTH_KEYS = auth_keys
view.printToTextbox_AuthenticationError()
# set Translation Engine
updateTranslationEngineAndEngineList()
# set word filter
model.addKeywords()
@@ -823,6 +910,8 @@ def createMainWindow():
if config.ENABLE_LOGGER is True:
model.startLogger()
splash.toProgress(3) # Last one.
# set UI and callback
view.register(
common_registers={
@@ -853,6 +942,9 @@ def createMainWindow():
"callback_swap_languages": swapYourLanguageAndTargetLanguage,
"callback_selected_language_preset_tab": callbackSelectedLanguagePresetTab,
"callback_selected_translation_engine": callbackSelectedTranslationEngine,
"message_box_bind_Return": messageBoxPressKeyEnter,
"message_box_bind_Any_KeyPress": messageBoxPressKeyAny,
"message_box_bind_FocusIn": messageBoxFocusIn,
@@ -875,7 +967,9 @@ def createMainWindow():
"callback_set_enable_restore_main_window_geometry": callbackSetEnableRestoreMainWindowGeometry,
# Translation Tab
"callback_set_deepl_authkey": callbackSetDeeplAuthkey,
"callback_set_use_translation_feature": callbackSetUseTranslationFeature,
"callback_set_ctranslate2_weight_type": callbackSetCtranslate2WeightType,
"callback_set_deepl_auth_key": callbackSetDeeplAuthKey,
# Transcription Tab (Mic)
"callback_set_mic_host": callbackSetMicHost,

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
img/VRCT_starting_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 855 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,4 +1,4 @@
python.exe -m pip install --upgrade pip
pip install -r requirements.txt
pip install git+https://github.com/misyaguziya/translators
pip install git+https://github.com/misyaguziya/deepl-translate
pip install git+https://github.com/misyaguziya/custom_speech_recognition

View File

@@ -22,7 +22,7 @@ VIAddVersionKey "FileDescription" "Communication tool with translation & transcr
Unicode true
; アプリケーション名
Name "VRCT Setup"
Name "VRCT"
; 作成されるインストーラ
OutFile "VRCT_Setup.exe"
@@ -38,8 +38,8 @@ XPStyle on
; ページ
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "..\LICENSE"
;!insertmacro MUI_PAGE_DIRECTORY
Page custom OptionPage OptionPageLeave
Page custom OptionPage1 OptionPageLeave1
Page custom OptionPage2 OptionPageLeave2
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
; アンインストーラ ページ
@@ -60,17 +60,27 @@ Var Checkbox_InstallShortcut
Var Dialog_Options
Var InstallDocs
Var InstallShortcut
Var Label_DescriptionOptions
Var DropList_Language
Var Set_Langage
Var DownloadWeight
Var RadioButton_Download
Var RadioButton_NotDownload
Var Label_Translation_subtitle_1
Var Label_Translation_subtitle_2
Var subFont
; 初期化時コールバック
Function .onInit
; オプション値を初期化します。
StrCpy $InstallDocs ${BST_CHECKED}
StrCpy $InstallShortcut ${BST_CHECKED}
StrCpy $DropList_Language "English"
StrCpy $DownloadWeight ${BST_CHECKED}
FunctionEnd
; オプション ページ
Function OptionPage
; オプション ページ 1
Function OptionPage1
!insertmacro MUI_HEADER_TEXT "オプション (Options)" "オプションを設定してください。 (Please set the options.)"
; nsDialogsを作成します。
nsDialogs::Create 1018
; 作成されたnsDialogsを変数に代入します。
@@ -81,15 +91,10 @@ Function OptionPage
Abort
${EndIf}
; ラベルを作成します。
${NSD_CreateLabel} 0 0 100% 12u "オプションを選択してください。"
; ラベルを変数に代入します。
Pop $Label_DescriptionOptions
${NSD_CreateCheckbox} 0 13u 100% 12u "ドキュメントをインストールする(&D)"
${NSD_CreateCheckbox} 0 0u 100% 12u "ドキュメントをインストールする (Install documents)"
Pop $Checkbox_InstallDocs
${NSD_CreateCheckbox} 0 26u 100% 12u "デスクトップにショートカットを作成(&D)"
${NSD_CreateCheckbox} 0 13u 100% 12u "デスクトップにショートカットを作成 (Install shortcut on desktop)"
Pop $Checkbox_InstallShortcut
${If} $InstallDocs == ${BST_CHECKED}
@@ -103,12 +108,68 @@ Function OptionPage
nsDialogs::Show
FunctionEnd
; オプション ページ退出コールバック
Function OptionPageLeave
; オプション ページ 1 退出コールバック
Function OptionPageLeave1
${NSD_GetState} $Checkbox_InstallDocs $InstallDocs
${NSD_GetState} $Checkbox_InstallShortcut $InstallShortcut
FunctionEnd
; オプション ページ 2
Function OptionPage2
CreateFont $subFont "MS UI Gothic" "8" "400"
!insertmacro MUI_HEADER_TEXT "初期設定 (Initial Settings)" "後から変更可能です。 (Changeable later.)"
; nsDialogsを作成します。
nsDialogs::Create 1018
; 作成されたnsDialogsを変数に代入します。
Pop $Dialog_Options
${If} $Dialog_Options == error
; ダイアログの作成に失敗した場合には終了します。
Abort
${EndIf}
; ComboBoxを作成します。
${NSD_CreateLabel} 0 20u 30% 12u "UIの言語 (Language)"
${NSD_CreateDropList} 33% 20u 33% 12u ""
Pop $DropList_Language
# ラジオボタンを追加しWEIGHTをDownloadするか選択する
${NSD_CreateLabel} 0 70u 30% 12u "翻訳機能 (Translation)"
${NSD_CreateLabel} 0 83u 30% 8u "言語モデルをダウンロード"
Pop $Label_Translation_subtitle_1
SendMessage $Label_Translation_subtitle_1 ${WM_SETFONT} $subFont 0
SetCtlColors $Label_Translation_subtitle_1 0x696969 0xF0F0F0
${NSD_CreateLabel} 0 92u 30% 8u "(Download language model)"
Pop $Label_Translation_subtitle_2
SendMessage $Label_Translation_subtitle_2 ${WM_SETFONT} $subFont 0
SetCtlColors $Label_Translation_subtitle_2 0x696969 0xF0F0F0
${NSD_CreateRadioButton} 33% 70u 33% 12u "使用する (Use)"
Pop $RadioButton_Download
${NSD_CreateRadioButton} 66% 70u 33% 12u "使用しない (Don't use)"
Pop $RadioButton_NotDownload
${NSD_CB_AddString} $DropList_Language "English"
${NSD_CB_AddString} $DropList_Language "日本語"
${NSD_CB_AddString} $DropList_Language "한국어"
${NSD_CB_SelectString} $DropList_Language "English"
${If} $DownloadWeight == ${BST_CHECKED}
; チェックが入力済の場合、チェックボックスにチェックを入れます。
${NSD_Check} $RadioButton_Download
${EndIf}
nsDialogs::Show
FunctionEnd
; オプション ページ 2 退出コールバック
Function OptionPageLeave2
${NSD_GetText} $DropList_Language $DropList_Language
${NSD_GetState} $RadioButton_Download $DownloadWeight
FunctionEnd
; デフォルト セクション
Section
; If VRCT is already running, display a warning message and exit
@@ -150,6 +211,26 @@ Section
CreateShortCut "$DESKTOP\VRCT.lnk" "$INSTDIR\VRCT.exe"
${EndIf}
; ComboBoxの選択値から言語を判定しconfig.jsonを$INSTDIRに作成
${If} $DropList_Language == "English"
StrCpy $Set_Langage "en"
${ElseIf} $DropList_Language == "日本語"
StrCpy $Set_Langage "ja"
${ElseIf} $DropList_Language == "한국어"
StrCpy $Set_Langage "ko"
${EndIf}
${If} $DownloadWeight == 1
StrCpy $DownloadWeight "true"
${Else}
StrCpy $DownloadWeight "false"
${EndIf}
StrCpy $1 '{"UI_LANGUAGE": "$Set_Langage", "USE_TRANSLATION_FEATURE": $DownloadWeight}'
FileOpen $0 "$INSTDIR\config.json" w
FileWrite $0 $1
FileClose $0
; スタート メニューにショートカットを登録
CreateDirectory "$SMPROGRAMS\VRCT"
SetOutPath "$INSTDIR"

View File

@@ -55,7 +55,7 @@ en:
# tab Parameter
label_ip_address: "OSC IP address"
label_port: "OSC Port"
label_authkey: "DeepL Auth Key"
label_auth_key: "DeepL Auth Key"
label_message_format: "Message Format"
# tab Others
@@ -121,7 +121,7 @@ ja:
# tab Parameter
# label_ip_address: ""
# label_port: ""
# label_authkey: ""
# label_auth_key: ""
label_message_format: "送信するメッセージのフォーマット"
# tab Others
@@ -186,7 +186,7 @@ ko:
# tab Parameter
label_ip_address: "OSC IP 주소"
label_port: "OSC 포트"
label_authkey: "DeepL 인증키"
label_auth_key: "DeepL 인증키"
label_message_format: "전송 형식"
# tab Others

View File

@@ -6,9 +6,11 @@ main_window:
language_settings: Language Settings
your_language: Your Language
both_direction_desc: Translate Each Other
translate_each_other_label: Translate Each Other
swap_button_label: Swap Languages
target_language: Target Language
translator: Translator
translator_ctranslate2: Internal (Default)
textbox_tab_all: All
textbox_tab_sent: Sent
@@ -30,7 +32,7 @@ main_window:
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.
translation_engine_limit_error: It has automatically changed the translation engine. Access has been temporarily restricted due to an excessive number of requests to the translation engine. If you want to use the same translation engine, please wait for a while, restart VRCT, and try again.
detected_by_word_filter: The word %{detected_message} has not been sent due to detection by the word filter.
@@ -57,10 +59,6 @@ main_window:
accept_adjust_ui_size: "Set it smaller and restart"
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
selectable_language_window:
title_your_language: Select Your Language
title_target_language: Select Target Language
@@ -82,8 +80,8 @@ 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_send_message_formats: Message Formats (Send)
others_received_message_formats: Message Formats (Received)
others_speaker2chatbox: Speaker2Chatbox
advanced_settings: Advanced Settings
@@ -117,8 +115,19 @@ config_window:
label: Remember The Main Window Position
desc: Restore the position and size of the previous window upon startup.
use_translation_feature:
label: Use Translation Feature
desc: You can't use the translation feature while this is turned off. Instead, the VRCT startup becomes a little faster. This is for users who don't need the translation feature and only use VRCT as a chatbox and transcription tool.
ctranslate2_weight_type:
label: Select Internal Translation Model
desc: You can choose the translation model to use for the internal translation engine.
small: "Basic model (%{capacity})"
large: "High accuracy model (%{capacity})"
deepl_auth_key:
label: DeepL Auth Key
desc: Please select %{translator} on the main screen with DeepL_API when using. ※Some languages may not be supported.
mic_host:
label: Mic Host/Driver
@@ -211,7 +220,7 @@ config_window:
error_message: "The characters '[message]' cannot be used."
send_message_format_with_t:
label: Message Format(With translation)
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."
@@ -223,7 +232,7 @@ config_window:
error_message: "The characters '[message]' cannot be used."
received_message_format_with_t:
label: Message Format(With translation)
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."

View File

@@ -6,9 +6,11 @@ main_window:
language_settings: 言語設定
your_language: あなたの言語
both_direction_desc: 双方向に翻訳
translate_each_other_label: 双方向に翻訳
swap_button_label: 言語を入れ替え
target_language: 相手の言語
translator: 翻訳エンジン
translator_ctranslate2: オフライン翻訳 (Default)
textbox_tab_all: 全て
textbox_tab_sent: 送信
@@ -30,7 +32,7 @@ main_window:
no_mic_device_detected_error: マイクデバイスが検出されませんでした。
no_speaker_device_detected_error: スピーカーデバイスが検出されませんでした。
translation_engine_limit_error: 翻訳機能を自動的に停止しました。翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。しばらく待ってから、VRCTの再起動をしてもう一度試してみてください。
translation_engine_limit_error: 翻訳エンジンを自動的に変更しました。対象翻訳エンジンへのリクエストが多すぎるため、一時的にアクセスが制限されています。同じ翻訳エンジンを使用したい場合はしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。
detected_by_word_filter: ワードフィルターに登録されている単語 %{detected_message} が検出されたため送信しませんでした。
@@ -40,7 +42,7 @@ main_window:
latest_language_setting: 現在「あなたの言語」は %{your_language}、「相手の言語」は %{target_language} に設定されています。
opened_web_page_booth: お使いのブラウザで、Boothのページを開きました。
opened_web_page_vrct_documents: "お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。\n不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX(元Twitter)にて気軽にご連絡ください!"
opened_web_page_vrct_documents: "お使いのブラウザで、VRCTのドキュメントを開きました。使用方法などはそちらに記載されています。\n不具合、ご要望、その他お問い合わせはドキュメント最下部にあるLinks、「お問合せフォーム」もしくはX (元Twitter) にて気軽にご連絡ください!"
update_available: 新しいバージョンが出ました!
@@ -57,10 +59,6 @@ main_window:
accept_adjust_ui_size: 小さく設定して再起動
translation_engine_limit_error: "翻訳機能を自動的に停止しました。\n翻訳エンジンへのリクエストが多すぎるため\n一時的にアクセスが制限されています。\nしばらく待ってから、VRCTの再起動をしてもう一度試してみてください。"
accept_translation_engine_limit_error: 了承して閉じる
selectable_language_window:
title_your_language: あなたの言語
title_target_language: 相手の言語
@@ -114,8 +112,19 @@ config_window:
label: メイン画面の位置を記憶する
desc: 起動時、前回の画面の位置とサイズを復元します。
use_translation_feature:
label: 翻訳機能を使用する
desc: "オフにしている間は、翻訳機能を使わない代わり、VRCTの起動が少し速くなります。\n翻訳機能を必要とせず、VRCTをチャット送信と文字起こしツールとしてのみ使用するユーザー用です。"
ctranslate2_weight_type:
label: オフライン翻訳のタイプ
desc: 翻訳エンジン(オフライン翻訳)で翻訳する際に、使用する翻訳モデルを選択できます。
small: "通常モデル (%{capacity})"
large: "高精度モデル (%{capacity})"
deepl_auth_key:
label: DeepL 認証キー
desc: "使用の際は、メイン画面にある %{translator} をDeepL_APIに変更してください。\n※対応していない言語もあります。"
mic_host:
label: マイク(ホスト/ドライバー)
@@ -190,7 +199,7 @@ config_window:
notice_xsoverlay:
label: XSOverlayでの通知受け取り機能を有効 (VR限定)
desc: 文字起こし(受信)されたメッセージをXSOverlayの機能を使って通知として受け取れます。
desc: 文字起こし (受信) されたメッセージをXSOverlayの機能を使って通知として受け取れます。
auto_export_message_logs:
label: 会話ログを自動的に保存する

View File

@@ -6,9 +6,11 @@ main_window:
language_settings: 언어 설정
your_language: 당신의 언어
both_direction_desc: 양방향으로 번역
translate_each_other_label: 양방향으로 번역
swap_button_label: 언어 교체
target_language: 상대방의 언어
translator: 번역 엔진
translator_ctranslate2: 오프라인 번역 (기본값)
textbox_tab_all: 전체
textbox_tab_sent: 전송
@@ -30,7 +32,7 @@ main_window:
no_mic_device_detected_error: 마이크 디바이스를 찾지 못했습니다.
no_speaker_device_detected_error: 스피커 디바이스를 찾지 못했습니다.
translation_engine_limit_error: 번역 기능이 자동으로 중지되었습니다. 번역 엔진에 대한 요청이 너무 많아 일시적으로 사용이 제한되고 있습니다. 잠시 기다렸다가 VRCT를 재부팅하 다시 시도해 보세요.
translation_engine_limit_error: 번역 엔진을 자동으로 변경했습니다. 대상 번역 엔진에 대한 요청이 너무 많아 일시적으로 접근이 제한되습니다. 해당 번역 엔진을 사용하려면 잠시 기다린 후 VRCT를 재부팅하 다시 시도해 보시기 바랍니다
detected_by_word_filter: 단어 필터에 등록된 단어 %{detected_message}(이)가 감지되어 전송하지 않았습니다.
@@ -57,10 +59,6 @@ main_window:
accept_adjust_ui_size: "작게 줄이고 재부팅"
translation_engine_limit_error: "번역 기능이 자동으로 중지되었습니다. \n번역 엔진에 대한 요청이 너무 많아 \n일시적으로 사용이 제한되었습니다. \n잠시 기다렸다가 VRCT를 재부팅한 후 다시 시도해 보십시오."
accept_translation_engine_limit_error: 확인하고 닫기
selectable_language_window:
title_your_language: 당신의 언어
title_target_language: 상대방의 언어
@@ -117,11 +115,22 @@ config_window:
label: 메인 화면 위치 기억
desc: 시작 시 이전 화면의 위치와 크기를 복원합니다.
use_translation_feature:
label: 번역 기능 사용
desc: "번역 기능이 꺼져 있는 동안에는 번역을 하지 않는 대신 VRCT가 조금 더 빠르게 실행됩니다. \n 번역 기능이 필요하지 않고 VRCT를 채팅 전송 및 음성 인식 도구로만 사용하는 사용자를 위한 기능입니다."
ctranslate2_weight_type:
label: 번역 모델
desc: "오프라인 번역 시의 번역 모델을 변경합니다."
small: "일반 모델 (%{capacity})"
large: "정밀 모델 (%{capacity})"
deepl_auth_key:
label: DeepL 인증키
mic_host:
label: 마이크 호스트/드라이버
# desc:
mic_device:
label: 마이크 장치

View File

@@ -7,8 +7,14 @@ if __name__ == "__main__":
splash = SplashWindow()
splash.showSplash()
from config import config
from models.translation.utils import downloadCTranslate2Weight
if config.USE_TRANSLATION_FEATURE is True:
downloadCTranslate2Weight(config.PATH_LOCAL, config.WEIGHT_TYPE, splash.updateDownloadProgress)
splash.toProgress(0)
import controller
controller.createMainWindow()
controller.createMainWindow(splash)
splash.destroySplash()
controller.showMainWindow()

145
model.py
View File

@@ -22,8 +22,9 @@ from models.transcription.transcription_recorder import SelectedMicRecorder, Sel
from models.transcription.transcription_recorder import SelectedMicEnergyRecorder, SelectedSpeakeEnergyRecorder
from models.transcription.transcription_transcriber import AudioTranscriber
from models.xsoverlay.notification import xsoverlayForVRCT
from models.translation.translation_languages import translatorEngine, translation_lang
from models.translation.translation_languages import translation_lang
from models.transcription.transcription_languages import transcription_lang
from models.translation.utils import checkCTranslate2Weight
from config import config
class threadFnc(Thread):
@@ -45,15 +46,6 @@ class threadFnc(Thread):
self.fnc(*self._args, **self._kwargs)
class Model:
# Languages available for both transcription and translation
SUPPORTED_LANGUAGES = [
'Afrikaans', 'Arabic', 'Basque', 'Bulgarian', 'Catalan', 'Chinese', 'Croatian',
'Czech', 'Danish', 'Dutch', 'English', 'Filipino', 'Finnish', 'French', 'German',
'Greek', 'Hebrew', 'Hindi', 'Hungarian', 'Indonesian', 'Italian', 'Japanese',
'Korean', 'Lithuanian', 'Malay', 'Norwegian', 'Polish', 'Portuguese', 'Romanian',
'Russian', 'Serbian', 'Slovak', 'Slovenian', 'Spanish', 'Swedish', 'Thai', 'Turkish',
'Ukrainian', 'Vietnamese'
]
_instance = None
def __new__(cls):
@@ -73,23 +65,22 @@ class Model:
self.speaker_energy_recorder = None
self.speaker_energy_plot_progressbar = None
self.translator = Translator()
if config.USE_TRANSLATION_FEATURE is True:
self.translator.changeCTranslate2Model(config.PATH_LOCAL, config.WEIGHT_TYPE)
self.keyword_processor = KeywordProcessor()
def resetTranslator(self):
del self.translator
self.translator = Translator()
def checkCTranslatorCTranslate2ModelWeight(self):
return checkCTranslate2Weight(config.PATH_LOCAL, config.WEIGHT_TYPE)
def changeTranslatorCTranslate2Model(self):
self.translator.changeCTranslate2Model(config.PATH_LOCAL, config.WEIGHT_TYPE)
def resetKeywordProcessor(self):
del self.keyword_processor
self.keyword_processor = KeywordProcessor()
def authenticationTranslator(self, choice_translator=None, auth_key=None):
if choice_translator is None:
choice_translator = config.CHOICE_TRANSLATOR
if auth_key is None:
auth_key = config.AUTH_KEYS[choice_translator]
result = self.translator.authentication(choice_translator, auth_key)
def authenticationTranslatorDeepLAuthKey(self, auth_key):
result = self.translator.authenticationDeepLAuthKey(auth_key)
return result
def startLogger(self):
@@ -108,13 +99,21 @@ class Model:
self.logger.disabled = True
self.logger = None
@staticmethod
def getListLanguageAndCountry():
def getListLanguageAndCountry(self):
transcription_langs = list(transcription_lang.keys())
tl_keys = translation_lang.keys()
translation_langs = []
for tl_key in tl_keys:
for lang in translation_lang[tl_key]["source"]:
translation_langs.append(lang)
translation_langs = list(set(translation_langs))
supported_langs = list(filter(lambda x: x in transcription_langs, translation_langs))
langs = []
for lang in model.SUPPORTED_LANGUAGES:
for lang in supported_langs:
for country in transcription_lang[lang]:
langs.append(f"{lang}\n({country})")
return langs
return sorted(langs)
@staticmethod
def getLanguageAndCountry(select):
@@ -123,84 +122,70 @@ class Model:
country = parts[1][1:-1]
return language, country
def findTranslationEngine(self, source_lang, target_lang):
def findTranslationEngines(self, source_lang, target_lang):
compatible_engines = []
for engine in translatorEngine:
source_languages = translation_lang.get(engine, {}).get("source", {})
target_languages = translation_lang.get(engine, {}).get("target", {})
if source_lang in source_languages and target_lang in target_languages:
for engine in list(translation_lang.keys()):
languages = translation_lang.get(engine, {}).get("source", {})
if source_lang in languages and target_lang in languages:
compatible_engines.append(engine)
engine_name = compatible_engines[0]
if engine_name == "DeepL" and config.AUTH_KEYS["DeepL_API"] is not None:
if self.authenticationTranslator(engine_name, config.AUTH_KEYS["DeepL_API"]) is True:
engine_name = "DeepL_API"
elif engine_name == "DeepL_API" and config.AUTH_KEYS["DeepL_API"] is None:
engine_name = "DeepL"
return engine_name
if "DeepL_API" in compatible_engines:
if config.AUTH_KEYS["DeepL_API"] is None:
compatible_engines.remove('DeepL_API')
return compatible_engines
def getInputTranslate(self, message):
translator_name=config.CHOICE_TRANSLATOR
translation_success_flag = True
translator_name=config.CHOICE_INPUT_TRANSLATOR
source_language=config.SOURCE_LANGUAGE
target_language=config.TARGET_LANGUAGE
target_country = config.TARGET_COUNTRY
if translator_name == "DeepL_API":
if target_language == "English":
if target_country in ["United States", "Canada", "Philippines"]:
target_language = "English American"
else:
target_language = "English British"
elif target_language == "Portuguese":
if target_country in ["Portugal"]:
target_language = "Portuguese European"
else:
target_language = "Portuguese Brazilian"
elif translator_name == "DeepL":
if target_language in ["English American", "English British"]:
target_language = "English"
elif target_language in ["Portuguese European", "Portuguese Brazilian"]:
target_language = "Portuguese"
translation = self.translator.translate(
translator_name=translator_name,
source_language=source_language,
target_language=target_language,
target_country=target_country,
message=message
)
return translation
# 翻訳失敗時のフェールセーフ処理
if translation is False:
translation_success_flag = False
translation = self.translator.translate(
translator_name="CTranslate2",
source_language=source_language,
target_language=target_language,
target_country=target_country,
message=message
)
return translation, translation_success_flag
def getOutputTranslate(self, message):
translator_name=config.CHOICE_TRANSLATOR
translation_success_flag = True
translator_name=config.CHOICE_OUTPUT_TRANSLATOR
source_language=config.TARGET_LANGUAGE
target_language=config.SOURCE_LANGUAGE
target_country = config.SOURCE_COUNTRY
if translator_name == "DeepL_API":
if target_language == "English":
if target_country in ["United States", "Canada", "Philippines"]:
target_language = "English American"
else:
target_language = "English British"
elif target_language == "Portuguese":
if target_country in ["Portugal"]:
target_language = "Portuguese European"
else:
target_language = "Portuguese Brazilian"
elif translator_name == "DeepL":
if target_language in ["English American", "English British"]:
target_language = "English"
elif target_language in ["Portuguese European", "Portuguese Brazilian"]:
target_language = "Portuguese"
target_country=config.SOURCE_COUNTRY
translation = self.translator.translate(
translator_name=translator_name,
source_language=source_language,
target_language=target_language,
target_country=target_country,
message=message
)
return translation
# 翻訳失敗時のフェールセーフ処理
if translation is False:
translation_success_flag = False
translation = self.translator.translate(
translator_name="CTranslate2",
source_language=source_language,
target_language=target_language,
target_country=target_country,
message=message
)
return translation, translation_success_flag
def addKeywords(self):
for f in config.INPUT_MIC_WORD_FILTER:
@@ -273,7 +258,7 @@ class Model:
folder_name = '_internal'
tmp_directory_name = 'tmp'
batch_name = 'update.bat'
current_directory = config.LOCAL_PATH
current_directory = config.PATH_LOCAL
try:
res = requests_get(config.GITHUB_URL)
@@ -306,7 +291,7 @@ class Model:
program_name = 'VRCT.exe'
folder_name = '_internal'
batch_name = 'restart.bat'
current_directory = config.LOCAL_PATH
current_directory = config.PATH_LOCAL
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]
Popen(command, cwd=current_directory)
@@ -492,4 +477,4 @@ class Model:
def notificationXSOverlay(self, message):
xsoverlayForVRCT(content=f"{message}")
model = Model()
model = Model()

View File

@@ -1,35 +1,40 @@
translatorEngine = ["DeepL", "DeepL_API", "Google", "Bing"]
translation_lang = {}
dict_deepl_languages = {
"Japanese":"JA",
"English":"EN",
"Korean":"KO",
"Bulgarian":"BG",
"Chinese":"ZH",
"Czech":"CS",
"Danish":"DA",
"Dutch":"NL",
"Estonian":"ET",
"Finnish":"FI",
"French":"FR",
"German":"DE",
"Greek":"EL",
"Hungarian":"HU",
"Italian":"IT",
"Latvian":"LV",
"Lithuanian":"LT",
"Polish":"PL",
"Portuguese":"PT",
"Romanian":"RO",
"Russian":"RU",
"Slovak":"SK",
"Slovenian":"SL",
"Spanish":"ES",
"Swedish":"SV",
"Indonesian":"ID",
"Ukrainian":"UK",
"Turkish":"TR",
"Norwegian":"NB",
'Arabic':'ar',
'Bulgarian':'bg',
'Czech':'cs',
'Danish':'da',
'German':'de',
'Greek':'el',
'English':'en',
'Spanish':'es',
'Estonian':'et',
'Finnish':'fi',
'French':'fr',
'Irish':'ga',
'Croatian':'hr',
'Hungarian':'hu',
'Indonesian':'id',
'Icelandic':'is',
'Italian':'it',
'Japanese':'ja',
'Korean':'ko',
'Lithuanian':'lt',
'Latvian':'lv',
'Maltese':'mt',
'Bokmal':'nb',
'Dutch':'nl',
'Norwegian':'no',
'Polish':'pl',
'Portuguese':'pt',
'Romanian':'ro',
'Russian':'ru',
'Slovak':'sk',
'Slovenian':'sl',
'Swedish':'sv',
'Turkish':'tr',
'Ukrainian':'uk',
'Chinese':'zh',
}
translation_lang["DeepL"] = {
"source":dict_deepl_languages,
@@ -240,4 +245,133 @@ dict_bing_languages = {
translation_lang["Bing"] = {
"source":dict_bing_languages,
"target":dict_bing_languages,
}
dict_papago_languages = {
'German': 'de',
'English': 'en',
'Spanish':'es',
'French': 'fr',
'Hindi': 'hi',
'Indonesian': 'id',
'Italian': 'it',
'Japanese': 'ja',
'Korean': 'ko',
'Portuguese': 'pt',
'Russian': 'ru',
'Thai': 'th',
'Vietnamese': 'vi',
'Chinese':'zh-CN',
}
translation_lang["Papago"] = {
"source":dict_papago_languages,
"target":dict_papago_languages,
}
dict_ctranslate2_languages = {
'English': 'en',
'Chinese': 'zh',
'German': 'de',
'Spanish': 'es',
'Russian': 'ru',
'Korean': 'ko',
'French': 'fr',
'Japanese': 'ja',
'Portuguese': 'pt',
'Turkish': 'tr',
'Polish': 'pl',
'Catalan': 'ca',
'Dutch': 'nl',
'Arabic': 'ar',
'Swedish': 'sv',
'Italian': 'it',
'Indonesian': 'id',
'Hindi': 'hi',
'Finnish': 'fi',
'Vietnamese': 'vi',
'Hebrew': 'he',
'Ukrainian': 'uk',
'Greek': 'el',
'Malay': 'ms',
'Czech': 'cs',
'Romanian': 'ro',
'Danish': 'da',
'Hungarian': 'hu',
'Tamil': 'ta',
'Norwegian': 'no',
'Thai': 'th',
'Urdu': 'ur',
'Croatian': 'hr',
'Bulgarian': 'bg',
'Lithuanian': 'lt',
'Latin': 'la',
'Maori': 'mi',
'Malayalam': 'ml',
'Welsh': 'cy',
'Slovak': 'sk',
'Telugu': 'te',
'Persian': 'fa',
'Latvian': 'lv',
'Bengali': 'bn',
'Serbian': 'sr',
'Azerbaijani': 'az',
'Slovenian': 'sl',
'Kannada': 'kn',
'Estonian': 'et',
'Macedonian': 'mk',
'Breton': 'br',
'Basque': 'eu',
'Icelandic': 'is',
'Armenian': 'hy',
'Nepali': 'ne',
'Mongolian': 'mn',
'Bosnian': 'bs',
'Kazakh': 'kk',
'Albanian': 'sq',
'Swahili': 'sw',
'Galician': 'gl',
'Marathi': 'mr',
'Punjabi': 'pa',
'Sinhala': 'si',
'Khmer': 'km',
'Shona': 'sn',
'Yoruba': 'yo',
'Somali': 'so',
'Afrikaans': 'af',
'Occitan': 'oc',
'Georgian': 'ka',
'Belarusian': 'be',
'Tajik': 'tg',
'Sindhi': 'sd',
'Gujarati': 'gu',
'Amharic': 'am',
'Yiddish': 'yi',
'Lao': 'lo',
'Uzbek': 'uz',
'Faroese': 'fo',
'Haitian creole': 'ht',
'Pashto': 'ps',
'Turkmen': 'tk',
'Nynorsk': 'nn',
'Maltese': 'mt',
'Sanskrit': 'sa',
'Luxembourgish': 'lb',
'Myanmar': 'my',
'Tibetan': 'bo',
'Filipino': 'tl',
'Malagasy': 'mg',
'Assamese': 'as',
'Tatar': 'tt',
'Hawaiian': 'haw',
'Lingala': 'ln',
'Hausa': 'ha',
'Bashkir': 'ba',
'Javanese': 'jw',
'Sundanese': 'su'
}
translation_lang["CTranslate2"] = {
"source":dict_ctranslate2_languages,
"target":dict_ctranslate2_languages,
}

View File

@@ -1,43 +1,75 @@
import os
from deepl import Translator as deepl_Translator
from deepl_translate import translate as deepl_web_Translator
from translators import translate_text as other_web_Translator
from .translation_languages import translation_lang
from .utils import ctranslate2_weights
import ctranslate2
import transformers
# Translator
class Translator():
def __init__(self):
pass
self.translator_status = {}
self.deepl_client = None
self.ctranslate2_translator = None
self.ctranslate2_tokenizer = None
def authentication(self, translator_name, authkey=None):
def authenticationDeepLAuthKey(self, authkey):
result = True
match translator_name:
case "DeepL_API":
try:
self.deepl_client = deepl_Translator(authkey)
self.deepl_client.translate_text(" ", target_lang="EN-US")
except Exception:
result = False
try:
self.deepl_client = deepl_Translator(authkey)
self.deepl_client.translate_text(" ", target_lang="EN-US")
except Exception:
self.deepl_client = None
result = False
return result
def translate(self, translator_name, source_language, target_language, message):
def changeCTranslate2Model(self, path, model_type):
directory_name = ctranslate2_weights[model_type]["directory_name"]
tokenizer = ctranslate2_weights[model_type]["tokenizer"]
weight_path = os.path.join(path, "weight", directory_name)
self.ctranslate2_translator = ctranslate2.Translator(
weight_path,
device="cpu",
device_index=0,
compute_type="int8",
inter_threads=1,
intra_threads=4
)
self.ctranslate2_tokenizer = transformers.AutoTokenizer.from_pretrained(tokenizer)
def translate(self, translator_name, source_language, target_language, target_country, message):
try:
result = ""
source_language=translation_lang[translator_name]["source"][source_language]
target_language=translation_lang[translator_name]["target"][target_language]
match translator_name:
case "DeepL":
result = deepl_web_Translator(
source_language=source_language,
target_language=target_language,
text=message
result = other_web_Translator(
query_text=message,
translator="deepl",
from_language=source_language,
to_language=target_language,
)
case "DeepL_API":
result = self.deepl_client.translate_text(
message,
source_lang=source_language,
target_lang=target_language,
).text
if self.deepl_client is None:
result = False
else:
if target_language == "English":
if target_country in ["United States", "Canada", "Philippines"]:
target_language = "English American"
else:
target_language = "English British"
elif target_language == "Portuguese":
if target_country in ["Portugal"]:
target_language = "Portuguese European"
else:
target_language = "Portuguese Brazilian"
result = self.deepl_client.translate_text(
message,
source_lang=source_language,
target_lang=target_language,
).text
case "Google":
result = other_web_Translator(
query_text=message,
@@ -52,6 +84,20 @@ class Translator():
from_language=source_language,
to_language=target_language,
)
case "Papago":
result = other_web_Translator(
query_text=message,
translator="papago",
from_language=source_language,
to_language=target_language,
)
case "CTranslate2":
self.ctranslate2_tokenizer.src_lang = source_language
source = self.ctranslate2_tokenizer.convert_ids_to_tokens(self.ctranslate2_tokenizer.encode(message))
target_prefix = [self.ctranslate2_tokenizer.lang_code_to_token[target_language]]
results = self.ctranslate2_translator.translate_batch([source], target_prefix=[target_prefix])
target = results[0].hypotheses[0][1:]
result = self.ctranslate2_tokenizer.decode(self.ctranslate2_tokenizer.convert_tokens_to_ids(target))
except Exception:
import traceback
with open('error.log', 'a') as f:

View File

@@ -0,0 +1,86 @@
import tempfile
from zipfile import ZipFile
from os import path as os_path
from os import makedirs as os_makedirs
from requests import get as requests_get
from typing import Callable
import hashlib
ctranslate2_weights = {
"Small": { # M2M-100 418M-parameter model
"url": "https://bit.ly/33fM1AO",
"directory_name": "m2m100_418m",
"tokenizer": "facebook/m2m100_418M",
"hash": {
"model.bin": "e7c26a9abb5260abd0268fbe3040714070dec254a990b4d7fd3f74c5230e3acb",
"sentencepiece.model": "d8f7c76ed2a5e0822be39f0a4f95a55eb19c78f4593ce609e2edbc2aea4d380a",
"shared_vocabulary.txt": "bd440aa21b8ca3453fc792a0018a1f3fe68b3464aadddd4d16a4b72f73c86d8c",
}
},
"Large": { # M2M-100 1.2B-parameter model
"url": "https://bit.ly/3GYiaed",
"directory_name": "m2m100_12b",
"tokenizer": "facebook/m2m100_1.2b",
"hash": {
"model.bin": "abb7bf4ba7e5e016b6e3ed480c752459b2f783ac8fca372e7587675e5bf3a919",
"sentencepiece.model": "d8f7c76ed2a5e0822be39f0a4f95a55eb19c78f4593ce609e2edbc2aea4d380a",
"shared_vocabulary.txt": "bd440aa21b8ca3453fc792a0018a1f3fe68b3464aadddd4d16a4b72f73c86d8c",
}
},
}
def calculate_file_hash(file_path, block_size=65536):
hash_object = hashlib.sha256()
with open(file_path, 'rb') as file:
for block in iter(lambda: file.read(block_size), b''):
hash_object.update(block)
return hash_object.hexdigest()
def checkCTranslate2Weight(path, weight_type="Small"):
directory_name = 'weight'
current_directory = path
weight_directory_name = ctranslate2_weights[weight_type]["directory_name"]
hash_data = ctranslate2_weights[weight_type]["hash"]
files = ["model.bin", "sentencepiece.model", "shared_vocabulary.txt"]
# check already downloaded
already_downloaded = False
if all(os_path.exists(os_path.join(current_directory, directory_name, weight_directory_name, file)) for file in files):
# check hash
for file in files:
original_hash = hash_data[file]
current_hash = calculate_file_hash(os_path.join(current_directory, directory_name, weight_directory_name, file))
if original_hash != current_hash:
break
already_downloaded = True
return already_downloaded
def downloadCTranslate2Weight(path, weight_type="Small", func=None):
url = ctranslate2_weights[weight_type]["url"]
filename = 'weight.zip'
directory_name = 'weight'
current_directory = path
if checkCTranslate2Weight(path, weight_type):
return
try:
os_makedirs(os_path.join(current_directory, directory_name), exist_ok=True)
print(os_path.join(current_directory, directory_name))
with tempfile.TemporaryDirectory() as tmp_path:
res = requests_get(url, stream=True)
file_size = int(res.headers.get('content-length', 0))
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)
if isinstance(func, Callable):
total_chunk += len(chunk)
func(total_chunk/file_size)
with ZipFile(os_path.join(tmp_path, filename)) as zf:
zf.extractall(os_path.join(current_directory, directory_name))
except Exception as e:
print("error:downloadCTranslate2Weight()", e)

View File

@@ -7,4 +7,7 @@ flashtext == 2.7
pyyaml == 6.0.1
python-i18n == 0.3.9
CTkToolTip == 0.8
pyinstaller==6.2.0
pyinstaller==6.2.0
transformers[torch]
sentencepiece==0.1.99
ctranslate2==3.21.0

204
view.py
View File

@@ -28,6 +28,7 @@ class View():
ui_scaling=config.UI_SCALING,
font_family=config.FONT_FAMILY,
ui_language=config.UI_LANGUAGE,
is_reset_button_displayed_for_translation=config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION,
)
if config.ENABLE_SPEAKER2CHATBOX is False:
@@ -35,6 +36,8 @@ class View():
else:
VERSION_TEXT=i18n.t("config_window.version", version=config.VERSION) + " (Speaker2Chatbox)"
self.TEXT_TRANSLATOR_CTRANSLATE2 = i18n.t("main_window.translator") + ": " + i18n.t("main_window.translator_ctranslate2")
self.settings = SimpleNamespace()
theme = get_appearance_mode() if config.APPEARANCE_THEME == "System" else config.APPEARANCE_THEME
all_ctm = ColorThemeManager(theme)
@@ -87,6 +90,12 @@ class View():
**common_args
)
self.settings.dropdown_menu_window = SimpleNamespace(
# ctm=all_ctm.dropdown_menu_window,
uism=all_uism.dropdown_menu_window,
**common_args
)
self.view_variable = SimpleNamespace(
# Common
CALLBACK_RESTART_SOFTWARE=None,
@@ -153,9 +162,10 @@ class View():
IS_OPENED_SELECTABLE_YOUR_LANGUAGE_WINDOW=False,
CALLBACK_SELECTED_YOUR_LANGUAGE=None,
VAR_LABEL_BOTH_DIRECTION_DESC=StringVar(value=i18n.t("main_window.both_direction_desc")),
VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON=StringVar(value=i18n.t("main_window.swap_button_label")),
VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON=StringVar(value=""),
CALLBACK_SWAP_LANGUAGES=None,
CALLBACK_ENTERED_SWAP_LANGUAGES_BUTTON=self._enteredSwapLanguagesButton,
CALLBACK_LEAVED_SWAP_LANGUAGES_BUTTON=self._leavedSwapLanguagesButton,
VAR_LABEL_TARGET_LANGUAGE=StringVar(value=i18n.t("main_window.target_language")),
VAR_TARGET_LANGUAGE = StringVar(value=f"{config.TARGET_LANGUAGE}\n({config.TARGET_COUNTRY})"),
@@ -163,6 +173,8 @@ class View():
IS_OPENED_SELECTABLE_TARGET_LANGUAGE_WINDOW=False,
CALLBACK_SELECTED_TARGET_LANGUAGE=None,
VAR_SELECTED_TRANSLATION_ENGINE = StringVar(value="Translator: INIT"),
CALLBACK_SELECTED_TRANSLATION_ENGINE = None,
VAR_LABEL_TEXTBOX_ALL=StringVar(value=i18n.t("main_window.textbox_tab_all")),
VAR_LABEL_TEXTBOX_SENT=StringVar(value=i18n.t("main_window.textbox_tab_sent")),
@@ -259,8 +271,24 @@ class View():
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")),
VAR_DESC_DEEPL_AUTH_KEY=None,
VAR_LABEL_USE_TRANSLATION_FEATURE=StringVar(value=i18n.t("config_window.use_translation_feature.label")),
VAR_DESC_USE_TRANSLATION_FEATURE=StringVar(value=i18n.t("config_window.use_translation_feature.desc")),
CALLBACK_SET_USE_TRANSLATION_FEATURE=None,
VAR_USE_TRANSLATION_FEATURE=BooleanVar(value=config.USE_TRANSLATION_FEATURE),
VAR_LABEL_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.ctranslate2_weight_type.label")),
VAR_DESC_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=i18n.t("config_window.ctranslate2_weight_type.desc")),
DICT_CTRANSLATE2_WEIGHT_TYPE=self.getSelectableCtranslate2WeightTypeDict(),
CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE=None,
VAR_CTRANSLATE2_WEIGHT_TYPE=StringVar(value=self.getSelectableCtranslate2WeightTypeDict()[config.WEIGHT_TYPE]),
VAR_LABEL_DEEPL_AUTH_KEY=StringVar(value=i18n.t( "config_window.deepl_auth_key.label")),
VAR_DESC_DEEPL_AUTH_KEY=StringVar(
value=i18n.t(
"config_window.deepl_auth_key.desc",
translator=i18n.t("main_window.translator")
)
),
CALLBACK_SET_DEEPL_AUTH_KEY=None,
VAR_DEEPL_AUTH_KEY=StringVar(value=config.AUTH_KEYS["DeepL_API"]),
@@ -515,6 +543,7 @@ class View():
self.view_variable.CALLBACK_SELECTED_LANGUAGE_PRESET_TAB = main_window_registers.get("callback_selected_language_preset_tab", None)
self.view_variable.CALLBACK_SELECTED_TRANSLATION_ENGINE = main_window_registers.get("callback_selected_translation_engine", None)
def adjustedMessageBoxReturnFunction(_e):
if self.view_variable.IS_ENTRY_MESSAGE_BOX_DISABLED is True:
@@ -567,7 +596,9 @@ class View():
# Translation Tab
self.view_variable.CALLBACK_SET_DEEPL_AUTHKEY = config_window_registers.get("callback_set_deepl_authkey", None)
self.view_variable.CALLBACK_SET_USE_TRANSLATION_FEATURE = config_window_registers.get("callback_set_use_translation_feature", None)
self.view_variable.CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE = config_window_registers.get("callback_set_ctranslate2_weight_type", None)
self.view_variable.CALLBACK_SET_DEEPL_AUTH_KEY = config_window_registers.get("callback_set_deepl_auth_key", None)
# Transcription Tab (Mic)
self.view_variable.CALLBACK_SET_MIC_HOST = config_window_registers.get("callback_set_mic_host", None)
@@ -624,6 +655,13 @@ class View():
self.setMainWindowMessageBoxRatio(config.MESSAGE_BOX_RATIO)
if config.USE_TRANSLATION_FEATURE is True:
self.useTranslationFeatureProcess("Normal")
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
else:
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
self.useTranslationFeatureProcess("Disable")
if config.CHOICE_MIC_HOST == "NoHost":
self.view_variable.VAR_MIC_HOST.set("No Mic Host Detected")
@@ -841,6 +879,47 @@ class View():
def getPreUiScaling(self):
return self.restart_required_configs_pre_data.ui_scaling
@staticmethod
def getSelectableCtranslate2WeightTypeDict():
return {
config._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT["Small"]: i18n.t("config_window.ctranslate2_weight_type.small", capacity="418MB"),
config._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT["Large"]: i18n.t("config_window.ctranslate2_weight_type.large", capacity="1.2GB"),
}
def useTranslationFeatureProcess(self, state:str):
def changeWidget_UseTranslationFeature():
vrct_gui.sls__box_translation_optionmenu_wrapper.grid()
vrct_gui.compact_mode_translation_frame.grid()
vrct_gui.translation_frame.grid()
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
def changeWidget_DontUseTranslationFeature():
vrct_gui.sls__box_translation_optionmenu_wrapper.grid_remove()
vrct_gui.compact_mode_translation_frame.grid_remove()
vrct_gui.translation_frame.grid_remove()
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
if state == "Normal":
self.setLatestCTranslate2WeightType()
self.openCtranslate2WeightTypeWidget()
self.setTranslationSwitchStatus("normal", release_locked_state=True)
changeWidget_UseTranslationFeature()
elif state == "Disable":
view.closeCtranslate2WeightTypeWidget()
view.setTranslationSwitchStatus("disabled", to_lock_state=True)
changeWidget_DontUseTranslationFeature()
elif state == "Restart":
view.setLatestCTranslate2WeightType()
view.setTranslationSwitchStatus("disabled", to_lock_state=True)
changeWidget_UseTranslationFeature()
vrct_gui.update()
vrct_gui.config_window.lift()
# Open Webpage Functions
def openWebPage_Booth(self):
self.openWebPage(config.BOOTH_URL)
@@ -879,6 +958,9 @@ class View():
def setMainWindowAllWidgetsStatusToDisabled():
vrct_gui._changeMainWindowWidgetsStatus("disabled", "All")
@staticmethod
def setTranslationSwitchStatus(status:str, to_lock_state:bool=False, release_locked_state:bool=False):
vrct_gui._changeMainWindowWidgetsStatus(status, ["translation_switch"], to_lock_state, release_locked_state)
def enableMainWindowSidebarCompactMode(self):
self.view_variable.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = True
@@ -899,6 +981,15 @@ class View():
case "SPEAKER_OFF":
vrct_gui.sls__box_target_language_speaker_status__enabled.place_forget()
def updateSelectableTranslationEngineList(self, selectable_translation_engines_list):
translation_dict = {item: item for item in selectable_translation_engines_list}
translation_dict["CTranslate2"] = i18n.t("main_window.translator_ctranslate2")
vrct_gui.translation_engine_dropdown_menu_window.updateDropdownMenuValues(
dropdown_menu_widget_id="translation_engine_dropdown_menu",
dropdown_menu_values=translation_dict,
)
# Config Window
def enableConfigWindowCompactMode(self):
@@ -911,13 +1002,19 @@ class View():
additional_widget.grid()
self._closeMicWordFilterList()
def showRestartButton(self):
self._showRestartButton()
def hideRestartButton(self):
self._hideRestartButton()
def showRestartButtonIfRequired(self, locale:Union[None,str]=None):
is_restart_required = not (
self.restart_required_configs_pre_data.appearance_theme == config.APPEARANCE_THEME and
self.restart_required_configs_pre_data.ui_scaling == config.UI_SCALING and
self.restart_required_configs_pre_data.font_family == config.FONT_FAMILY and
self.restart_required_configs_pre_data.ui_language == config.UI_LANGUAGE
self.restart_required_configs_pre_data.ui_language == config.UI_LANGUAGE and
self.restart_required_configs_pre_data.is_reset_button_displayed_for_translation == config.IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION
)
if locale is None:
@@ -946,6 +1043,44 @@ class View():
vrct_gui.config_window.setting_box_compact_mode_switch_box.configure(state="normal")
@staticmethod
def setWidgetsStatus_changeWeightType_Pending():
vrct_gui.config_window.sb__switch_use_translation_feature.configure(state="disabled")
vrct_gui._changeConfigWindowWidgetsStatus(
status="disabled",
target_names=[
"sb__switch_use_translation_feature",
"sb__optionmenu_ctranslate2_weight_type",
]
)
@staticmethod
def setWidgetsStatus_changeWeightType_Done():
vrct_gui.config_window.sb__switch_use_translation_feature.configure(state="normal")
vrct_gui._changeConfigWindowWidgetsStatus(
status="normal",
target_names=[
"sb__switch_use_translation_feature",
"sb__optionmenu_ctranslate2_weight_type",
]
)
def updateSelectedCtranslate2WeightType(self, selected_weight_type:str):
self.view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE.set(self.getSelectableCtranslate2WeightTypeDict()[selected_weight_type])
def setLatestCTranslate2WeightType(self):
selected_weight_type = self.getSelectableCtranslate2WeightTypeDict()[config.WEIGHT_TYPE]
self.view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE.set(selected_weight_type)
def openCtranslate2WeightTypeWidget(self):
vrct_gui.config_window.sb__use_translation_feature.grid(pady=0)
vrct_gui.config_window.sb__ctranslate2_weight_type.grid()
def closeCtranslate2WeightTypeWidget(self):
vrct_gui.config_window.sb__use_translation_feature.grid(pady=(0,1))
vrct_gui.config_window.sb__ctranslate2_weight_type.grid_remove()
def openMicEnergyThresholdWidget(self):
self.view_variable.VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD.set(i18n.t("config_window.mic_dynamic_energy_threshold.label_for_manual"))
@@ -1123,7 +1258,7 @@ class View():
self._clearEntryBox(vrct_gui.config_window.sb__entry_mic_word_filter_list)
# Widget Control (Whole)
# Widget Control
def foregroundOnIfForegroundEnabled(self):
if config.ENABLE_FOREGROUND:
self.foregroundOn()
@@ -1181,6 +1316,19 @@ class View():
vrct_gui.main_send_message_button_container.grid()
vrct_gui.config_window.after(200, vrct_gui.config_window.lift)
def _enteredSwapLanguagesButton(self):
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.swap_button_label"))
vrct_gui.sls__both_direction_desc.configure(
text_color=self.settings.main.ctm.SLS__BOX_ARROWS_SWAP_BUTTON_TEXT_COLOR,
)
def _leavedSwapLanguagesButton(self):
if config.USE_TRANSLATION_FEATURE is True:
self.view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON.set(i18n.t("main_window.translate_each_other_label"))
vrct_gui.sls__both_direction_desc.configure(
text_color=self.settings.main.ctm.SLS__BOX_ARROWS_TEXT_COLOR,
)
# Function
def _adjustUiSizeAndRestart(self):
current_percentage = int(config.UI_SCALING.replace("%",""))
@@ -1195,21 +1343,6 @@ class View():
def translationEngineLimitErrorProcess(self):
# turn off translation switch.
vrct_gui.translation_switch_box.deselect()
vrct_gui.translation_frame.markToggleManually(False)
# disable translation feature.
vrct_gui._changeMainWindowWidgetsStatus("disabled", ["translation_switch"], to_hold_state=True)
# print system message that mention to stopped translation feature.
view.printToTextbox_TranslationEngineLimitError()
view.showTheLimitOfTranslationEngineConfirmationModal()
# Show Modal
def _showDisplayOverUiSizeConfirmationModal(self):
self.foregroundOffIfForegroundEnabled()
@@ -1247,23 +1380,6 @@ class View():
def showTheLimitOfTranslationEngineConfirmationModal(self):
self.foregroundOffIfForegroundEnabled()
self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set("")
vrct_gui.main_window_cover.show()
self.view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL=self._hideInformationModal
self.view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL=self._hideInformationModal
self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.translation_engine_limit_error"))
self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_translation_engine_limit_error"))
vrct_gui.information_modal.show(hide_title_bar=False, close_when_focusout=False)
# Hide Modal
def _hideInformationModal(self):
vrct_gui.information_modal.hide()
@@ -1332,6 +1448,13 @@ class View():
# Set GuiVariable (view_variable)
def setGuiVariable_SelectedTranslationEngine(self, value):
if value == "CTranslate2":
self.view_variable.VAR_SELECTED_TRANSLATION_ENGINE.set(self.TEXT_TRANSLATOR_CTRANSLATE2)
value = self.TEXT_TRANSLATOR_CTRANSLATE2
else:
self.view_variable.VAR_SELECTED_TRANSLATION_ENGINE.set(i18n.t("main_window.translator") + ": " + value)
def setGuiVariable_MicEnergyThreshold(self, value):
self.view_variable.VAR_MIC_ENERGY_THRESHOLD__SLIDER.set(int(value))
self.view_variable.VAR_MIC_ENERGY_THRESHOLD__ENTRY.set(str(value))
@@ -1449,9 +1572,6 @@ class View():
self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.translation_engine_limit_error"))
# def printToTextbox_OSCError(self): [Deprecated]
# self._printToTextbox_Info("OSC is not enabled, please enable OSC and rejoin. or turn off the \"Send Message To VRChat\" setting")
def printToTextbox_DetectedByWordFilter(self, detected_message):
self._printToTextbox_Info(i18n.t("main_window.textbox_system_message.detected_by_word_filter", detected_message=detected_message))

View File

@@ -1,9 +1,10 @@
from typing import Union
from types import SimpleNamespace
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont
from time import sleep
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText, CustomizedCTkScrollableFrame
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText, getLongestText_Dict, CustomizedCTkScrollableFrame
from functools import partial
from utils import isEven, makeEven
@@ -90,7 +91,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
def updateDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values):
def updateDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list],):
self.dropdown_menu_widgets[dropdown_menu_widget_id].widget.destroy()
self.createDropdownMenuBox(
dropdown_menu_widget_id=dropdown_menu_widget_id,
@@ -105,7 +106,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
)
def createDropdownMenuBox(self, dropdown_menu_widget_id, dropdown_menu_values, command, wrapper_widget, attach_widget, dropdown_menu_min_width=None, dropdown_menu_height=None, max_display_length=None):
def createDropdownMenuBox(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list], command, wrapper_widget, attach_widget, dropdown_menu_min_width=None, dropdown_menu_height=None, max_display_length=None):
self.attach_widget = attach_widget
self.wrapper_widget = wrapper_widget
@@ -166,9 +167,12 @@ class _CreateDropdownMenuWindow(CTkToplevel):
self.dropdown_menu_container.grid_remove()
def _createDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values, command):
def _createDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values:Union[dict, list], command):
if isinstance(dropdown_menu_values, list):
longest_text = getLongestText(dropdown_menu_values)
elif isinstance(dropdown_menu_values, dict):
longest_text = getLongestText_Dict(dropdown_menu_values)
longest_text = getLongestText(dropdown_menu_values)
self.dropdown_menu_values_wrapper = CTkFrame(self.scroll_frame_container, corner_radius=0, fg_color=self.window_bg_color)
self.dropdown_menu_values_wrapper.grid(row=0, column=0, sticky="nsew")
self.dropdown_menu_values_wrapper.grid_columnconfigure(0, weight=1)
@@ -220,19 +224,31 @@ class _CreateDropdownMenuWindow(CTkToplevel):
row=0
for dropdown_menu_value in dropdown_menu_values:
IS_LIST_TYPE = False
if isinstance(dropdown_menu_values, list):
for_in_values = dropdown_menu_values
IS_LIST_TYPE = True
elif isinstance(dropdown_menu_values, dict):
for_in_values = dropdown_menu_values.keys()
IS_LIST_TYPE = False
row=0
for dropdown_menu_value in for_in_values:
dropdown_menu_value_wrapper = CTkFrame(self.dropdown_menu_values_wrapper, corner_radius=0, fg_color=self.values_bg_color, width=0, height=0, cursor="hand2")
dropdown_menu_value_wrapper.grid(row=row, column=0, pady=self.value_pady, sticky="nsew")
setattr(self, f"{dropdown_menu_widget_id}__{row}", dropdown_menu_value_wrapper)
if IS_LIST_TYPE is True:
dropdown_menu_value_text = dropdown_menu_value
else:
dropdown_menu_value_text = dropdown_menu_values[dropdown_menu_value]
dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
label_widget = CTkLabel(
dropdown_menu_value_wrapper,
text=dropdown_menu_value,
text=dropdown_menu_value_text,
height=0,
corner_radius=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.value_font_size, weight="normal"),
@@ -252,7 +268,11 @@ class _CreateDropdownMenuWindow(CTkToplevel):
command(value)
self._withdraw()
callback = partial(optimizedCommand, dropdown_menu_value)
if IS_LIST_TYPE is True:
callback = partial(optimizedCommand, dropdown_menu_value_text)
else:
callback = partial(optimizedCommand, dropdown_menu_value)
bindButtonReleaseFunction([dropdown_menu_value_wrapper, label_widget], callback)
row+=1
@@ -267,7 +287,10 @@ class _CreateDropdownMenuWindow(CTkToplevel):
if self.active_dropdown_menu_widget is not None:
self.active_dropdown_menu_widget.grid_remove()
try:
self.active_dropdown_menu_widget.grid_remove()
except:
pass
target_data = self.dropdown_menu_widgets[dropdown_menu_widget_id]
self.attach_widget = target_data.attach_widget
@@ -303,9 +326,18 @@ class _CreateDropdownMenuWindow(CTkToplevel):
def _withdraw(self, e=None):
self.withdraw()
self.attach_widget.winfo_toplevel().unbind("<Configure>", self.BIND_CONFIGURE_FUNC_ID)
self.attach_widget.unbind("<Unmap>", self.BIND_UNMAP_FUNC_ID)
self.attach_widget.winfo_toplevel().unbind("<Button-1>", self.BIND_BUTTON_1_FUNC_ID)
try:
self.attach_widget.winfo_toplevel().unbind("<Configure>", self.BIND_CONFIGURE_FUNC_ID)
except Exception:
pass
try:
self.attach_widget.unbind("<Unmap>", self.BIND_UNMAP_FUNC_ID)
except Exception:
pass
try:
self.attach_widget.winfo_toplevel().unbind("<Button-1>", self.BIND_BUTTON_1_FUNC_ID)
except Exception:
pass
self.hide = True

View File

@@ -10,37 +10,75 @@ def _changeConfigWindowWidgetsStatus(config_window, settings, view_variable, sta
if target_widget.desc_widget is not None:
target_widget.desc_widget.configure(text_color=settings.ctm.LABELS_TEXT_DISABLED_COLOR)
def normalLabelsWidgets(target_widget):
target_widget.label_widget.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
if target_widget.desc_widget is not None:
target_widget.desc_widget.configure(text_color=settings.ctm.LABELS_DESC_TEXT_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()
target_widget.optionmenu_box.configure(cursor="")
def normalOptionmenuWidget(target_widget):
target_widget.optionmenu_label_widget.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
target_widget.optionmenu_img_widget.configure(image=CTkImage(settings.image_file.ARROW_LEFT.rotate(90), size=settings.uism.SB__OPTIONMENU_IMG_SIZE))
target_widget.optionmenu_box.bindFunction()
target_widget.optionmenu_box.configure(cursor="hand2")
for target_name in target_names:
match target_name:
case "sb__optionmenu_mic_host":
if status == "disabled":
target_widget = config_window.sb__widgets["sb__optionmenu_mic_host"]
disableLabelsWidgets(target_widget)
disableOptionmenuWidget(target_widget)
case "sb__optionmenu_mic_device":
if status == "disabled":
target_widget = config_window.sb__widgets["sb__optionmenu_mic_device"]
disableLabelsWidgets(target_widget)
disableOptionmenuWidget(target_widget)
case "sb__optionmenu_appearance_theme":
if status == "disabled":
target_widget = config_window.sb__widgets["sb__optionmenu_appearance_theme"]
disableLabelsWidgets(target_widget)
disableOptionmenuWidget(target_widget)
case "sb__optionmenu_ctranslate2_weight_type":
target_widget = config_window.sb__widgets["sb__optionmenu_ctranslate2_weight_type"]
if status == "disabled":
disableOptionmenuWidget(target_widget)
elif status == "normal":
normalOptionmenuWidget(target_widget)
case "sb__switch_use_translation_feature":
target_widget = config_window.sb__widgets["sb__switch_use_translation_feature"]
if status == "disabled":
target_widget.switch_box.configure(
state="disabled",
fg_color=settings.ctm.SB__SWITCH_BOX_BG_DISABLED_COLOR,
progress_color=settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR,
button_color=settings.ctm.SB__SWITCH_BOX_BUTTON_DISABLED_COLOR,
)
elif status == "normal":
target_widget.switch_box.configure(
state="normal",
fg_color=settings.ctm.SB__SWITCH_BOX_BG_COLOR,
progress_color=settings.ctm.SB__SWITCH_BOX_ACTIVE_BG_COLOR,
button_color=settings.ctm.SB__SWITCH_BOX_BUTTON_COLOR,
)
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(
target_widget.checkbox.configure(
state="disabled",
border_color=settings.ctm.SB__CHECKBOX_BORDER_DISABLED_COLOR
)

View File

@@ -1,12 +1,16 @@
from customtkinter import CTkImage
hold_state_list=[]
def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, target_names:list, to_hold_state:bool=False):
global hold_state_list
lock_state_list=[]
def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, target_names:list, to_lock_state:bool=False, release_locked_state:bool=False):
global lock_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", "send_message_button"]
if release_locked_state is True:
for item in target_names:
if item in lock_state_list:
lock_state_list.remove(item)
for item in hold_state_list:
for item in lock_state_list:
if item in target_names:
target_names.remove(item)
@@ -24,13 +28,13 @@ def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, ta
if status == "disabled":
widget_frame.configure(cursor="")
widget_label.configure(text_color=settings.ctm.SF__TEXT_DISABLED_COLOR)
widget_switch_box.configure(state="disabled", progress_color=settings.ctm.SF__SWITCH_BOX_DISABLE_BG_COLOR)
widget_switch_box.configure(state="disabled", progress_color=settings.ctm.SF__SWITCH_BOX_DISABLE_BG_COLOR, button_color=settings.ctm.SF__SWITCH_BOX_BUTTON_DISABLED_COLOR)
widget_selected_mark.configure(fg_color=settings.ctm.SF__SELECTED_MARK_DISABLE_BG_COLOR)
icon_file = disabled_icon_name
elif status == "normal":
widget_frame.configure(cursor="hand2")
widget_label.configure(text_color=settings.ctm.LABELS_TEXT_COLOR)
widget_switch_box.configure(state="normal", progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR)
widget_switch_box.configure(state="normal", progress_color=settings.ctm.SF__SWITCH_BOX_ACTIVE_BG_COLOR, button_color=settings.ctm.SF__SWITCH_BOX_BUTTON_COLOR)
widget_selected_mark.configure(fg_color=settings.ctm.SF__SELECTED_MARK_ACTIVE_BG_COLOR)
icon_file = icon_name
@@ -158,9 +162,9 @@ def _changeMainWindowWidgetsStatus(vrct_gui, settings, view_variable, status, ta
raise ValueError(f"No matching case for target_name: {target_name}")
if to_hold_state is True:
if to_lock_state is True:
for item in target_names:
if item not in hold_state_list:
hold_state_list.append(item)
if item not in lock_state_list:
lock_state_list.append(item)
vrct_gui.update()

View File

@@ -210,6 +210,8 @@ class _SettingBoxGenerator():
)
setattr(self.config_window, switch_attr_name, switch_widget)
self.config_window.sb__widgets[switch_attr_name].switch_box = switch_widget
switch_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
return setting_box_frame
@@ -245,6 +247,8 @@ class _SettingBoxGenerator():
)
setattr(self.config_window, checkbox_attr_name, checkbox_widget)
self.config_window.sb__widgets[checkbox_attr_name].checkbox = checkbox_widget
checkbox_widget.grid(row=1, column=SETTING_BOX_COLUMN, sticky="e")
return setting_box_frame

View File

@@ -8,13 +8,13 @@ def createSettingBox_AdvancedSettings(setting_box_wrapper, config_window, settin
createSettingBoxButtonWithImage = sbg.createSettingBoxButtonWithImage
def entry_ip_address_callback(value):
def entryIpAddressCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_OSC_IP_ADDRESS, value)
def entry_port_callback(value):
def entryPortCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_OSC_PORT, value)
def open_config_filepath_callback():
def openConfigFilepathCallback():
callFunctionIfCallable(view_variable.CALLBACK_OPEN_FILEPATH_CONFIG_FILE)
row=0
@@ -23,7 +23,7 @@ def createSettingBox_AdvancedSettings(setting_box_wrapper, config_window, settin
for_var_desc_text=view_variable.VAR_DESC_OSC_IP_ADDRESS,
entry_attr_name="sb__entry_ip_address",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
entry_bind__Any_KeyRelease=lambda value: entry_ip_address_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryIpAddressCallback(value),
entry_textvariable=view_variable.VAR_OSC_IP_ADDRESS,
)
config_window.sb__ip_address.grid(row=row)
@@ -35,7 +35,7 @@ def createSettingBox_AdvancedSettings(setting_box_wrapper, config_window, settin
for_var_desc_text=view_variable.VAR_DESC_OSC_PORT,
entry_attr_name="sb__entry_port",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
entry_bind__Any_KeyRelease=lambda value: entry_port_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryPortCallback(value),
entry_textvariable=view_variable.VAR_OSC_PORT,
)
config_window.sb__port.grid(row=row)
@@ -45,7 +45,7 @@ def createSettingBox_AdvancedSettings(setting_box_wrapper, config_window, settin
for_var_label_text=view_variable.VAR_LABEL_OPEN_CONFIG_FILEPATH,
for_var_desc_text=view_variable.VAR_DESC_OPEN_CONFIG_FILEPATH,
button_attr_name="sb__button_open_config_filepath",
button_command=lambda _e: open_config_filepath_callback(),
button_command=lambda _e: openConfigFilepathCallback(),
button_image=settings.image_file.FOLDER_OPEN_ICON,
)
config_window.sb__open_config_filepath.grid(row=row, pady=0)

View File

@@ -8,30 +8,29 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
createSettingBoxSlider = sbg.createSettingBoxSlider
createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
# 関数名は変えるかもしれない。
# テーマ変更、フォント変更時、 Widget再生成か再起動かは検討中
def slider_transparency_callback(value):
def sliderTransparencyCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_TRANSPARENCY, value)
def optionmenu_appearance_theme_callback(value):
def optionmenuAppearanceThemeCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_APPEARANCE, value)
def optionmenu_ui_scaling_callback(value):
def optionmenuUiScalingCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_UI_SCALING, value)
def slider_text_box_ui_scaling_callback(value):
def sliderTextBoxUiScalingCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_TEXTBOX_UI_SCALING, value)
def slider_message_box_ratio_callback(value):
def sliderMessageBoxRatioCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MESSAGE_BOX_RATIO, value)
def optionmenu_font_family_callback(value):
def optionmenuFontFamilyCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_FONT_FAMILY, value)
def optionmenu_ui_language_callback(value):
def optionmenuUiLanguageCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_UI_LANGUAGE, value)
def checkbox_enable_restore_main_window_geometry_callback(checkbox_box_widget):
def checkboxEnableRestoreMainWindowGeometryCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY, checkbox_box_widget.get())
row=0
@@ -40,7 +39,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_TRANSPARENCY,
slider_attr_name="sb__slider_transparency",
slider_range=view_variable.SLIDER_RANGE_TRANSPARENCY,
command=lambda value: slider_transparency_callback(value),
command=lambda value: sliderTransparencyCallback(value),
variable=view_variable.VAR_TRANSPARENCY,
slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_TRANSPARENCY,
slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_TRANSPARENCY,
@@ -55,7 +54,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_APPEARANCE_THEME,
optionmenu_attr_name="sb__optionmenu_appearance_theme",
dropdown_menu_values=view_variable.LIST_APPEARANCE_THEME,
command=lambda value: optionmenu_appearance_theme_callback(value),
command=lambda value: optionmenuAppearanceThemeCallback(value),
variable=view_variable.VAR_APPEARANCE_THEME,
)
config_window.sb__appearance_theme.grid(row=row)
@@ -68,7 +67,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_UI_SCALING,
optionmenu_attr_name="sb__optionmenu_ui_scaling",
dropdown_menu_values=view_variable.LIST_UI_SCALING,
command=lambda value: optionmenu_ui_scaling_callback(value),
command=lambda value: optionmenuUiScalingCallback(value),
variable=view_variable.VAR_UI_SCALING,
)
config_window.sb__ui_scaling.grid(row=row)
@@ -79,7 +78,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_TEXTBOX_UI_SCALING,
slider_attr_name="sb__slider_transparency",
slider_range=view_variable.SLIDER_RANGE_TEXTBOX_UI_SCALING,
command=lambda value: slider_text_box_ui_scaling_callback(value),
command=lambda value: sliderTextBoxUiScalingCallback(value),
variable=view_variable.VAR_TEXTBOX_UI_SCALING,
slider_bind__ButtonPress=view_variable.CALLBACK_BUTTON_PRESS_TEXTBOX_UI_SCALING,
slider_bind__ButtonRelease=view_variable.CALLBACK_BUTTON_RELEASE_TEXTBOX_UI_SCALING,
@@ -93,7 +92,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
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),
command=lambda value: sliderMessageBoxRatioCallback(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,
@@ -107,7 +106,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_FONT_FAMILY,
optionmenu_attr_name="sb__optionmenu_font_family",
dropdown_menu_values=view_variable.LIST_FONT_FAMILY,
command=lambda value: optionmenu_font_family_callback(value),
command=lambda value: optionmenuFontFamilyCallback(value),
variable=view_variable.VAR_FONT_FAMILY,
)
config_window.sb__font_family.grid(row=row)
@@ -119,7 +118,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
for_var_desc_text=view_variable.VAR_DESC_UI_LANGUAGE,
optionmenu_attr_name="sb__optionmenu_ui_language",
dropdown_menu_values=view_variable.LIST_UI_LANGUAGE,
command=lambda value: optionmenu_ui_language_callback(value),
command=lambda value: optionmenuUiLanguageCallback(value),
variable=view_variable.VAR_UI_LANGUAGE,
)
config_window.sb__ui_language.grid(row=row)
@@ -129,7 +128,7 @@ def createSettingBox_Appearance(setting_box_wrapper, config_window, settings, vi
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),
command=lambda: checkboxEnableRestoreMainWindowGeometryCallback(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)

View File

@@ -9,25 +9,25 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
createSettingBoxAutoExportMessageLogs = sbg.createSettingBoxAutoExportMessageLogs
def checkbox_auto_clear_message_box_callback(checkbox_box_widget):
def checkboxAutoClearMessageBoxCallback(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):
def checkboxSendOnlyTranslatedMessagesCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_ONLY_TRANSLATED_MESSAGES, checkbox_box_widget.get())
def checkbox_send_message_button_type_callback():
def checkboxSendMessageButtonTypeCallback():
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):
def checkboxNoticeXsoverlayCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_NOTICE_XSOVERLAY, checkbox_box_widget.get())
def checkbox_auto_export_message_logs_callback(checkbox_box_widget):
def checkboxAutoExportMessageLogsCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_AUTO_EXPORT_MESSAGE_LOGS, checkbox_box_widget.get())
def button_auto_export_message_logs_callback():
def buttonAutoExportMessageLogsCallback():
callFunctionIfCallable(view_variable.CALLBACK_OPEN_FILEPATH_LOGS)
def checkbox_enable_send_message_to_vrc_callback(checkbox_box_widget):
def checkboxEnableSendMessageToVrcCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_MESSAGE_TO_VRC, checkbox_box_widget.get())
@@ -36,7 +36,7 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
for_var_label_text=view_variable.VAR_LABEL_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
checkbox_attr_name="sb__checkbox_auto_clear_message_box",
command=lambda: checkbox_auto_clear_message_box_callback(config_window.sb__checkbox_auto_clear_message_box),
command=lambda: checkboxAutoClearMessageBoxCallback(config_window.sb__checkbox_auto_clear_message_box),
variable=view_variable.VAR_ENABLE_AUTO_CLEAR_MESSAGE_BOX,
)
config_window.sb__auto_clear_message_box.grid(row=row)
@@ -46,7 +46,7 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
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),
command=lambda: checkboxSendOnlyTranslatedMessagesCallback(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)
@@ -56,7 +56,7 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
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(),
command=lambda: checkboxSendMessageButtonTypeCallback(),
variable=view_variable.VAR_SEND_MESSAGE_BUTTON_TYPE,
radiobutton_keys_values=view_variable.KEYS_VALUES_SEND_MESSAGE_BUTTON_TYPE,
)
@@ -67,7 +67,7 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
for_var_label_text=view_variable.VAR_LABEL_ENABLE_NOTICE_XSOVERLAY,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_NOTICE_XSOVERLAY,
checkbox_attr_name="sb__checkbox_notice_xsoverlay",
command=lambda: checkbox_notice_xsoverlay_callback(config_window.sb__checkbox_notice_xsoverlay),
command=lambda: checkboxNoticeXsoverlayCallback(config_window.sb__checkbox_notice_xsoverlay),
variable=view_variable.VAR_ENABLE_NOTICE_XSOVERLAY,
)
config_window.sb__notice_xsoverlay.grid(row=row)
@@ -78,8 +78,8 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
for_var_label_text=view_variable.VAR_LABEL_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
for_var_desc_text=view_variable.VAR_DESC_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
checkbox_attr_name="sb__checkbox_auto_export_message_logs",
checkbox_command=lambda: checkbox_auto_export_message_logs_callback(config_window.sb__checkbox_auto_export_message_logs),
button_command=lambda _e: button_auto_export_message_logs_callback(),
checkbox_command=lambda: checkboxAutoExportMessageLogsCallback(config_window.sb__checkbox_auto_export_message_logs),
button_command=lambda _e: buttonAutoExportMessageLogsCallback(),
variable=view_variable.VAR_ENABLE_AUTO_EXPORT_MESSAGE_LOGS,
)
config_window.sb__auto_export_message_logs.grid(row=row)
@@ -90,7 +90,7 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
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,
checkbox_attr_name="sb__checkbox_enable_send_message_to_vrc",
command=lambda: checkbox_enable_send_message_to_vrc_callback(config_window.sb__checkbox_enable_send_message_to_vrc),
command=lambda: checkboxEnableSendMessageToVrcCallback(config_window.sb__checkbox_enable_send_message_to_vrc),
variable=view_variable.VAR_ENABLE_SEND_MESSAGE_TO_VRC,
)
config_window.sb__enable_send_message_to_vrc.grid(row=row, pady=0)

View File

@@ -6,7 +6,7 @@ def createSettingBox_Others_Additional(setting_box_wrapper, config_window, setti
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):
def checkboxEnableSendReceivedMessageToVrcCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC, checkbox_box_widget.get())
@@ -15,7 +15,7 @@ def createSettingBox_Others_Additional(setting_box_wrapper, config_window, setti
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),
command=lambda: checkboxEnableSendReceivedMessageToVrcCallback(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)

View File

@@ -8,14 +8,14 @@ def createSettingBox_Others_ReceivedMessageFormats(setting_box_wrapper, config_w
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
def entry_received_message_format_callback(value):
def entryReceivedMessageFormatCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT, value)
def entry_received_message_format_with_t_callback(value):
def entryReceivedMessageFormatWithTCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_RECEIVED_MESSAGE_FORMAT_WITH_T, value)
def entry_swap_received_message_format_with_t_callback(_e):
def entrySwapReceivedMessageFormatWithTCallback(_e):
callFunctionIfCallable(view_variable.CALLBACK_SWAP_RECEIVED_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
row=0
@@ -33,7 +33,7 @@ def createSettingBox_Others_ReceivedMessageFormats(setting_box_wrapper, config_w
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__Any_KeyRelease=lambda value: entryReceivedMessageFormatCallback(value),
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_RECEIVED_MESSAGE_FORMAT,
)
config_window.sb__received_message_format.grid(row=row)
@@ -57,8 +57,8 @@ def createSettingBox_Others_ReceivedMessageFormats(setting_box_wrapper, config_w
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__Any_KeyRelease=lambda value: entryReceivedMessageFormatWithTCallback(value),
swap_button_command=entrySwapReceivedMessageFormatWithTCallback,
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)

View File

@@ -8,14 +8,14 @@ def createSettingBox_Others_SendMessageFormats(setting_box_wrapper, config_windo
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
createSettingBoxMessageFormatEntries_WithTranslation = sbg.createSettingBoxMessageFormatEntries_WithTranslation
def entry_send_message_format_callback(value):
def entrySendMessageFormatCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT, value)
def entry_send_message_format_with_t_callback(value):
def entrySendMessageFormatWithTCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SEND_MESSAGE_FORMAT_WITH_T, value)
def entry_swap_message_format_with_t_callback(_e):
def entrySwapMessageFormatWithTCallback(_e):
callFunctionIfCallable(view_variable.CALLBACK_SWAP_SEND_MESSAGE_FORMAT_WITH_T_REQUIRED_TEXT)
@@ -34,7 +34,7 @@ def createSettingBox_Others_SendMessageFormats(setting_box_wrapper, config_windo
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__Any_KeyRelease=lambda value: entrySendMessageFormatCallback(value),
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SEND_MESSAGE_FORMAT,
)
config_window.sb__message_format.grid(row=row)
@@ -58,8 +58,8 @@ def createSettingBox_Others_SendMessageFormats(setting_box_wrapper, config_windo
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__Any_KeyRelease=lambda value: entrySendMessageFormatWithTCallback(value),
swap_button_command=entrySwapMessageFormatWithTCallback,
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)

View File

@@ -12,39 +12,40 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
createSettingBoxAddAndDeleteAbleList = sbg.createSettingBoxAddAndDeleteAbleList
def checkbox_input_mic_threshold_check_callback(is_turned_on):
def checkboxInputMicThresholdCheckCallback(is_turned_on):
callFunctionIfCallable(view_variable.CALLBACK_CHECK_MIC_THRESHOLD, is_turned_on)
def optionmenu_mic_host_callback(value):
def optionmenuMicHostCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_HOST, value)
def optionmenu_input_mic_device_callback(value):
def optionmenuInputMicDeviceCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_DEVICE, value)
def slider_input_mic_energy_threshold_callback(value):
def sliderInputMicEnergyThresholdCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_ENERGY_THRESHOLD, value)
def checkbox_input_mic_dynamic_energy_threshold_callback(checkbox_box_widget):
def checkboxInputMicDynamicEnergyThresholdCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_DYNAMIC_ENERGY_THRESHOLD, checkbox_box_widget.get())
def entry_input_mic_record_timeout_callback(value):
def entryInputMicRecordTimeoutCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_RECORD_TIMEOUT, value)
def entry_input_mic_phrase_timeout_callback(value):
def entryInputMicPhraseTimeoutCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_PHRASE_TIMEOUT, value)
def entry_input_mic_max_phrases_callback(value):
def entryInputMicMaxPhrasesCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_MAX_PHRASES, value)
def arrow_switch_mic_word_filter_list_open_callback(value):
def arrowSwitchMicWordFilterListOpenCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_OPEN)
def arrow_switch_mic_word_filter_list_close_callback(value):
def arrowSwitchMicWordFilterListCloseCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_ARROW_SWITCH_MIC_WORD_FILTER_LIST_CLOSE)
def entry_input_mic_word_filters_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_WORD_FILTER, value)
# 直接 SettingBoxGenerator.pyでcallFunctionIfCallableから呼んでいます。word filter 専用関数になっているのでそのままですが、良くはない)
# def entry_input_mic_word_filters_callback(value):
# callFunctionIfCallable(view_variable.CALLBACK_SET_MIC_WORD_FILTER, value)
row=0
@@ -54,7 +55,7 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_desc_text=view_variable.VAR_DESC_MIC_HOST,
optionmenu_attr_name="sb__optionmenu_mic_host",
dropdown_menu_values=view_variable.LIST_MIC_HOST,
command=lambda value: optionmenu_mic_host_callback(value),
command=lambda value: optionmenuMicHostCallback(value),
variable=view_variable.VAR_MIC_HOST,
)
config_window.sb__mic_host.grid(row=row)
@@ -65,7 +66,7 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_desc_text=view_variable.VAR_DESC_MIC_DEVICE,
optionmenu_attr_name="sb__optionmenu_mic_device",
dropdown_menu_values=view_variable.LIST_MIC_DEVICE,
command=lambda value: optionmenu_input_mic_device_callback(value),
command=lambda value: optionmenuInputMicDeviceCallback(value),
variable=view_variable.VAR_MIC_DEVICE,
)
config_window.sb__mic_device.grid(row=row)
@@ -75,14 +76,14 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_label_text=view_variable.VAR_LABEL_MIC_DYNAMIC_ENERGY_THRESHOLD,
for_var_desc_text=view_variable.VAR_DESC_MIC_DYNAMIC_ENERGY_THRESHOLD,
switch_attr_name="sb__checkbox_mic_dynamic_energy_threshold",
command=lambda: checkbox_input_mic_dynamic_energy_threshold_callback(config_window.sb__checkbox_mic_dynamic_energy_threshold),
command=lambda: checkboxInputMicDynamicEnergyThresholdCallback(config_window.sb__checkbox_mic_dynamic_energy_threshold),
variable=view_variable.VAR_MIC_DYNAMIC_ENERGY_THRESHOLD
)
config_window.sb__mic_dynamic_energy_threshold.grid(row=row, pady=0)
row+=1
config_window.sb__mic_energy_threshold = createSettingBoxProgressbarXSlider(
command=slider_input_mic_energy_threshold_callback,
command=sliderInputMicEnergyThresholdCallback,
progressbar_x_slider_attr_name="sb__mic_energy_threshold",
entry_attr_name="sb__progressbar_x_slider__entry_mic_energy_threshold",
@@ -97,9 +98,9 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
progressbar_attr_name="sb__progressbar_x_slider__progressbar_mic_energy_threshold",
passive_button_attr_name="sb__progressbar_x_slider__passive_button_mic_energy_threshold",
passive_button_command=lambda _e: checkbox_input_mic_threshold_check_callback(True),
passive_button_command=lambda _e: checkboxInputMicThresholdCheckCallback(True),
active_button_attr_name="sb__progressbar_x_slider__active_button_mic_energy_threshold",
active_button_command=lambda _e: checkbox_input_mic_threshold_check_callback(False),
active_button_command=lambda _e: checkboxInputMicThresholdCheckCallback(False),
button_image_file=settings.image_file.MIC_ICON,
disabled_button_attr_name="sb__progressbar_x_slider__disabled_button_mic_energy_threshold",
disabled_button_image_file=settings.image_file.MIC_ICON_DISABLED,
@@ -114,7 +115,7 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_desc_text=view_variable.VAR_DESC_MIC_RECORD_TIMEOUT,
entry_attr_name="sb__entry_mic_record_timeout",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_mic_record_timeout_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputMicRecordTimeoutCallback(value),
entry_textvariable=view_variable.VAR_MIC_RECORD_TIMEOUT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_RECORD_TIMEOUT,
)
@@ -126,7 +127,7 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_desc_text=view_variable.VAR_DESC_MIC_PHRASE_TIMEOUT,
entry_attr_name="sb__entry_mic_phrase_timeout",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_mic_phrase_timeout_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputMicPhraseTimeoutCallback(value),
entry_textvariable=view_variable.VAR_MIC_PHRASE_TIMEOUT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_PHRASE_TIMEOUT,
)
@@ -138,7 +139,7 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_desc_text=view_variable.VAR_DESC_MIC_MAX_PHRASES,
entry_attr_name="sb__entry_mic_max_phrases",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_mic_max_phrases_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputMicMaxPhrasesCallback(value),
entry_textvariable=view_variable.VAR_MIC_MAX_PHRASES,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MIC_MAX_PHRASES,
)
@@ -151,8 +152,8 @@ def createSettingBox_Mic(setting_box_wrapper, config_window, settings, view_vari
for_var_label_text=view_variable.VAR_LABEL_MIC_WORD_FILTER,
for_var_desc_text=view_variable.VAR_DESC_MIC_WORD_FILTER,
arrow_switch_attr_name="sb__arrow_switch_mic_word_filter",
open_command=lambda value: arrow_switch_mic_word_filter_list_open_callback(value),
close_command=lambda value: arrow_switch_mic_word_filter_list_close_callback(value),
open_command=lambda value: arrowSwitchMicWordFilterListOpenCallback(value),
close_command=lambda value: arrowSwitchMicWordFilterListCloseCallback(value),
var_switch_desc=view_variable.VAR_SWITCH_DESC_MIC_WORD_FILTER,
)
config_window.sb__mic_word_filter.grid(row=row, pady=0)

View File

@@ -9,24 +9,24 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
createSettingBoxEntry = sbg.createSettingBoxEntry
def checkbox_input_speaker_threshold_check_callback(is_turned_on):
def checkboxInputSpeakerThresholdCheckCallback(is_turned_on):
callFunctionIfCallable(view_variable.CALLBACK_CHECK_SPEAKER_THRESHOLD, is_turned_on)
def slider_input_speaker_energy_threshold_callback(value):
def sliderInputSpeakerEnergyThresholdCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_ENERGY_THRESHOLD, value)
def checkbox_input_speaker_dynamic_energy_threshold_callback(checkbox_box_widget):
def checkboxInputSpeakerDynamicEnergyThresholdCallback(checkbox_box_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, checkbox_box_widget.get())
def entry_input_speaker_record_timeout_callback(value):
def entryInputSpeakerRecordTimeoutCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_RECORD_TIMEOUT, value)
def entry_input_speaker_phrase_timeout_callback(value):
def entryInputSpeakerPhraseTimeoutCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_PHRASE_TIMEOUT, value)
def entry_input_speaker_max_phrases_callback(value):
def entryInputSpeakerMaxPhrasesCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_SPEAKER_MAX_PHRASES, value)
@@ -36,14 +36,14 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
for_var_label_text=view_variable.VAR_LABEL_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
for_var_desc_text=view_variable.VAR_DESC_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
switch_attr_name="sb__checkbox_speaker_dynamic_energy_threshold",
command=lambda: checkbox_input_speaker_dynamic_energy_threshold_callback(config_window.sb__checkbox_speaker_dynamic_energy_threshold),
command=lambda: checkboxInputSpeakerDynamicEnergyThresholdCallback(config_window.sb__checkbox_speaker_dynamic_energy_threshold),
variable=view_variable.VAR_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
)
config_window.sb__speaker_dynamic_energy_threshold.grid(row=row, pady=0)
row+=1
config_window.sb__speaker_energy_threshold = createSettingBoxProgressbarXSlider(
command=slider_input_speaker_energy_threshold_callback,
command=sliderInputSpeakerEnergyThresholdCallback,
progressbar_x_slider_attr_name="sb__speaker_energy_threshold",
entry_variable=view_variable.VAR_SPEAKER_ENERGY_THRESHOLD__ENTRY,
@@ -58,9 +58,9 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
progressbar_attr_name="sb__progressbar_x_slider__progressbar_speaker_energy_threshold",
passive_button_attr_name="sb__progressbar_x_slider__passive_button_speaker_energy_threshold",
passive_button_command=lambda _e: checkbox_input_speaker_threshold_check_callback(True),
passive_button_command=lambda _e: checkboxInputSpeakerThresholdCheckCallback(True),
active_button_attr_name="sb__progressbar_x_slider__active_button_speaker_energy_threshold",
active_button_command=lambda _e: checkbox_input_speaker_threshold_check_callback(False),
active_button_command=lambda _e: checkboxInputSpeakerThresholdCheckCallback(False),
button_image_file=settings.image_file.HEADPHONES_ICON,
disabled_button_attr_name="sb__progressbar_x_slider__disabled_button_speaker_energy_threshold",
disabled_button_image_file=settings.image_file.HEADPHONES_ICON_DISABLED,
@@ -75,7 +75,7 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
for_var_desc_text=view_variable.VAR_DESC_SPEAKER_RECORD_TIMEOUT,
entry_attr_name="sb__entry_speaker_record_timeout",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_speaker_record_timeout_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerRecordTimeoutCallback(value),
entry_textvariable=view_variable.VAR_SPEAKER_RECORD_TIMEOUT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_RECORD_TIMEOUT,
)
@@ -87,7 +87,7 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
for_var_desc_text=view_variable.VAR_DESC_SPEAKER_PHRASE_TIMEOUT,
entry_attr_name="sb__entry_speaker_phrase_timeout",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_speaker_phrase_timeout_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerPhraseTimeoutCallback(value),
entry_textvariable=view_variable.VAR_SPEAKER_PHRASE_TIMEOUT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_PHRASE_TIMEOUT,
)
@@ -99,7 +99,7 @@ def createSettingBox_Speaker(setting_box_wrapper, config_window, settings, view_
for_var_desc_text=view_variable.VAR_DESC_SPEAKER_MAX_PHRASES,
entry_attr_name="sb__entry_speaker_max_phrases",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_100,
entry_bind__Any_KeyRelease=lambda value: entry_input_speaker_max_phrases_callback(value),
entry_bind__Any_KeyRelease=lambda value: entryInputSpeakerMaxPhrasesCallback(value),
entry_textvariable=view_variable.VAR_SPEAKER_MAX_PHRASES,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_SPEAKER_MAX_PHRASES,
)

View File

@@ -4,21 +4,50 @@ from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Translation(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBoxSwitch = sbg.createSettingBoxSwitch
createSettingBoxDropdownMenu = sbg.createSettingBoxDropdownMenu
createSettingBoxEntry = sbg.createSettingBoxEntry
def switchUseTranslationFeatureCallback(switch_widget):
callFunctionIfCallable(view_variable.CALLBACK_SET_USE_TRANSLATION_FEATURE, switch_widget.get())
def deepl_authkey_callback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_DEEPL_AUTHKEY, value)
def optionmenuCtranslate2WeightTypeCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_CTRANSLATE2_WEIGHT_TYPE, value)
def deeplAuthKeyCallback(value):
callFunctionIfCallable(view_variable.CALLBACK_SET_DEEPL_AUTH_KEY, value)
row=0
config_window.sb__deepl_authkey = createSettingBoxEntry(
config_window.sb__use_translation_feature = createSettingBoxSwitch(
for_var_label_text=view_variable.VAR_LABEL_USE_TRANSLATION_FEATURE,
for_var_desc_text=view_variable.VAR_DESC_USE_TRANSLATION_FEATURE,
switch_attr_name="sb__switch_use_translation_feature",
command=lambda: switchUseTranslationFeatureCallback(config_window.sb__switch_use_translation_feature),
variable=view_variable.VAR_USE_TRANSLATION_FEATURE
)
config_window.sb__use_translation_feature.grid(row=row, pady=0)
row+=1
config_window.sb__ctranslate2_weight_type = createSettingBoxDropdownMenu(
for_var_label_text=view_variable.VAR_LABEL_CTRANSLATE2_WEIGHT_TYPE,
for_var_desc_text=view_variable.VAR_DESC_CTRANSLATE2_WEIGHT_TYPE,
optionmenu_attr_name="sb__optionmenu_ctranslate2_weight_type",
dropdown_menu_values=view_variable.DICT_CTRANSLATE2_WEIGHT_TYPE,
command=lambda value: optionmenuCtranslate2WeightTypeCallback(value),
variable=view_variable.VAR_CTRANSLATE2_WEIGHT_TYPE,
)
config_window.sb__ctranslate2_weight_type.grid(row=row)
row+=1
config_window.sb__deepl_auth_key = createSettingBoxEntry(
for_var_label_text=view_variable.VAR_LABEL_DEEPL_AUTH_KEY,
for_var_desc_text=view_variable.VAR_DESC_DEEPL_AUTH_KEY,
entry_attr_name="sb__entry_deepl_authkey",
entry_attr_name="sb__entry_deepl_auth_key",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_300,
entry_bind__Any_KeyRelease=lambda value: deepl_authkey_callback(value),
entry_bind__Any_KeyRelease=lambda value: deeplAuthKeyCallback(value),
entry_textvariable=view_variable.VAR_DEEPL_AUTH_KEY,
)
config_window.sb__deepl_authkey.grid(row=row, pady=0)
config_window.sb__deepl_auth_key.grid(row=row, pady=0)
row+=1

View File

@@ -1,6 +1,8 @@
from customtkinter import CTkFont, CTkFrame, CTkLabel, CTkImage
from ....ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction, switchActiveTabAndPassiveTab, switchTabsColor, createOptionMenuBox, bindButtonFunctionAndColor, bindEnterAndLeaveFunction
from ...._CreateDropdownMenuWindow import _CreateDropdownMenuWindow
from ....ui_utils import bindEnterAndLeaveColor, bindButtonPressColor, bindButtonReleaseFunction, switchActiveTabAndPassiveTab, switchTabsColor, createOptionMenuBox, bindButtonFunctionAndColor, bindEnterAndLeaveFunction, createLabelButton
from utils import callFunctionIfCallable
@@ -248,7 +250,7 @@ def createSidebarLanguagesSettings(settings, main_window, view_variable):
main_window.sls__both_direction_desc = CTkLabel(
main_window.sls__arrow_direction_swap_box,
textvariable=view_variable.VAR_LABEL_BOTH_DIRECTION_DESC,
textvariable=view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON,
height=0,
font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.SLS__BOX_ARROWS_DESC_FONT_SIZE, weight="normal"),
text_color=settings.ctm.SLS__BOX_ARROWS_TEXT_COLOR,
@@ -284,16 +286,10 @@ def createSidebarLanguagesSettings(settings, main_window, view_variable):
def adjustedCommand_Entered():
main_window.sls__both_direction_desc.configure(
textvariable=view_variable.VAR_LABEL_BOTH_DIRECTION_SWAP_BUTTON,
text_color=settings.ctm.SLS__BOX_ARROWS_SWAP_BUTTON_TEXT_COLOR,
)
callFunctionIfCallable(view_variable.CALLBACK_ENTERED_SWAP_LANGUAGES_BUTTON)
def adjustedCommand_Leaved():
main_window.sls__both_direction_desc.configure(
textvariable=view_variable.VAR_LABEL_BOTH_DIRECTION_DESC,
text_color=settings.ctm.SLS__BOX_ARROWS_TEXT_COLOR,
)
callFunctionIfCallable(view_variable.CALLBACK_LEAVED_SWAP_LANGUAGES_BUTTON)
bindEnterAndLeaveFunction(
target_widgets=[
@@ -336,4 +332,49 @@ def createSidebarLanguagesSettings(settings, main_window, view_variable):
height=0,
corner_radius=0,
image=CTkImage(settings.image_file.HEADPHONES_ICON_DISABLED, size=settings.uism.SLS__BOX_TRANSCRIPTION_STATUS_IMAGE_SIZE),
)
)
main_window.sls__box_translation_optionmenu_wrapper = CTkFrame(main_window.sls__box_frame, corner_radius=0, fg_color=settings.ctm.SLS__BG_COLOR, width=0, height=0)
main_window.sls__box_translation_optionmenu_wrapper.grid(row=5, column=0, pady=settings.uism.SLS__SELECTABLE_TRANSLATION_PADY, sticky="ew")
main_window.sls__box_translation_optionmenu_wrapper.grid_columnconfigure((0,2), weight=0, minsize=settings.uism.SLS__SELECTABLE_TRANSLATION_MIN_PADX)
main_window.sls__box_translation_optionmenu_wrapper.grid_columnconfigure(1, weight=1)
def adjustedCommand(value):
callFunctionIfCallable(view_variable.CALLBACK_SELECTED_TRANSLATION_ENGINE, value)
main_window.translation_engine_dropdown_menu_window.createDropdownMenuBox(
dropdown_menu_widget_id="translation_engine_dropdown_menu",
dropdown_menu_values=[],
command=adjustedCommand,
wrapper_widget=main_window,
attach_widget=main_window.sls__box_translation_optionmenu_wrapper,
dropdown_menu_min_width=settings.uism.SIDEBAR_MIN_WIDTH,
)
(sls__selected_translation_engine_box, label_button_label_widget) = createLabelButton(
parent_widget=main_window.sls__box_translation_optionmenu_wrapper,
label_button_bg_color=settings.ctm.SLS__BG_COLOR,
label_button_hovered_bg_color=settings.ctm.SLS__OPTIONMENU_HOVERED_BG_COLOR,
label_button_clicked_bg_color=settings.ctm.SLS__OPTIONMENU_CLICKED_BG_COLOR,
label_button_ipadx=settings.uism.SLS__SELECTABLE_TRANSLATION_IPADX,
label_button_ipady=settings.uism.SLS__SELECTABLE_TRANSLATION_IPADY,
variable=view_variable.VAR_SELECTED_TRANSLATION_ENGINE,
font_family=settings.FONT_FAMILY,
font_size=settings.uism.SLS__SELECTABLE_TRANSLATION_FONT_SIZE,
text_color=settings.ctm.LABELS_TEXT_COLOR,
label_button_clicked_command=lambda _e: main_window.translation_engine_dropdown_menu_window.show(
dropdown_menu_widget_id="translation_engine_dropdown_menu"
),
label_button_position="center",
)
sls__selected_translation_engine_box.grid(row=0, column=1, sticky="ew")

View File

@@ -1,4 +1,7 @@
from customtkinter import CTkImage, CTkLabel, CTkToplevel
import math
import time
from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame
from ..ui_utils import openImageKeepAspectRatio, getImageFileFromUiUtils, setGeometryToCenterOfScreen, fadeInAnimation
class SplashWindow(CTkToplevel):
@@ -10,22 +13,229 @@ class SplashWindow(CTkToplevel):
self.title("SplashWindow")
self.wm_attributes("-toolwindow", True)
self.is_showed_weight_download_progressbar = False
sw=self.winfo_screenwidth()
BG_HEIGHT= 220
BG_WIDTH= 450
BG_HEX_COLOR = "#292a2d"
pw=int(sw/4)
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.splash_background = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=BG_WIDTH, height=BG_HEIGHT)
self.splash_background.grid()
self.grid_columnconfigure((0,2), weight=1)
self.grid_rowconfigure((0,2), weight=1)
(img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"), pw)
label = CTkLabel(
self.progressbar_wrapper = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=0, height=0)
self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center")
self.progressbar_wrapper.rowconfigure(0, minsize=BG_HEIGHT)
PROGRESSBAR_HEIGHT = 3
PROGRESSBAR_WIDTH = 60
PROGRESSBAR_RIGHT_PADX = 38
ALL_PROGRESSBAR_WIDTH = (PROGRESSBAR_WIDTH + PROGRESSBAR_RIGHT_PADX)*3 + PROGRESSBAR_WIDTH
WHITE_HEX_COLOR = "#f2f2f2"
VRCT_HEX_COLOR = "#48a495"
column = 0
for i in range(3):
progressbar = CTkProgressBar(
self.progressbar_wrapper,
height=PROGRESSBAR_HEIGHT,
width=PROGRESSBAR_WIDTH,
corner_radius=0,
fg_color=BG_HEX_COLOR,
progress_color=WHITE_HEX_COLOR,
)
progressbar.set(0)
progressbar.grid(row=0, column=column, padx=(0,PROGRESSBAR_RIGHT_PADX))
setattr(self, "progressbar_" + str(i), progressbar)
column+=1
self.progressbar_3 = CTkProgressBar(
self.progressbar_wrapper,
height=PROGRESSBAR_HEIGHT,
width=PROGRESSBAR_WIDTH,
corner_radius=0,
fg_color=BG_HEX_COLOR,
progress_color=VRCT_HEX_COLOR,
)
self.progressbar_3.set(0)
self.progressbar_3.grid(row=0, column=column, padx=0)
self.chato_img_mask_frame = CTkFrame(self.progressbar_wrapper, corner_radius=0, fg_color=BG_HEX_COLOR, width=ALL_PROGRESSBAR_WIDTH, height=0)
self.chato_img_mask_frame.place(relx=1, rely=0.49, relheight=0.5, anchor="se")
CHATO_POSITION = int( (ALL_PROGRESSBAR_WIDTH-(PROGRESSBAR_WIDTH/2)) + 2)
(self.chato_img, self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_mark_white_square.png"), int(PROGRESSBAR_WIDTH - (PROGRESSBAR_WIDTH/5)))
self.chato_img_label = CTkLabel(
self.chato_img_mask_frame,
text=None,
height=0,
fg_color=BG_HEX_COLOR,
image=CTkImage(self.chato_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT))
)
self.chato_img_label.place(x=CHATO_POSITION, rely=1, relwidth=1, anchor="n")
(img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_starting_up.png"), 100)
self.starting_up_text_label = CTkLabel(
self,
text=None,
height=0,
fg_color="#292a2d",
fg_color=BG_HEX_COLOR,
image=CTkImage(img, size=(desired_width, height))
)
label.grid(row=1, column=1, padx=int(desired_width/7), pady=int(height/3))
self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center")
(self.vrct_second_text_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrchat_chatbox_trasnlator_transcription.png"), 280)
self.vrct_second_text_img_label = CTkLabel(
self,
text=None,
height=0,
fg_color=BG_HEX_COLOR,
image=CTkImage(self.vrct_second_text_img, size=(desired_width, height))
)
self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se")
(self.vrct_logo_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"), 280)
self.vrct_logo_img_label = CTkLabel(
self,
text=None,
height=0,
fg_color=BG_HEX_COLOR,
image=CTkImage(self.vrct_logo_img, size=(desired_width, height))
)
self.weight_download_progressbar_widget = CTkProgressBar(
self,
height=8,
corner_radius=0,
fg_color="#4b4c4f",
progress_color=VRCT_HEX_COLOR,
)
self.weight_download_progressbar_widget.set(0)
(img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_now_downloading.png"), 320)
self.weight_download_text_label = CTkLabel(
self,
text=None,
height=0,
fg_color=BG_HEX_COLOR,
image=CTkImage(img, size=(desired_width, height))
)
def toProgress(self, num:int):
if self.is_showed_weight_download_progressbar is True:
self.vrct_logo_img_label.place_forget()
self.weight_download_progressbar_widget.place_forget()
self.weight_download_text_label.place_forget()
self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center")
self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center")
self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se")
self.update()
target_progressbar_widget = getattr(self, "progressbar_" + str(num))
# This animation process' base code was made by ChatGPT.
start_time = time.time()
DURATION = 0.2
while True:
elapsed_time = time.time() - start_time
progress = min(elapsed_time / DURATION, 1.0)
eased_progress = 1 - math.pow(1 - progress, 6)
target_progressbar_widget.set(eased_progress)
self.update_idletasks()
if elapsed_time >= DURATION:
break
time.sleep(0.01)
DURATION = 0.2
if num == 3:
start_time = time.time()
while True:
elapsed_time = time.time() - start_time
progress = min(elapsed_time / DURATION, 1.0)
eased_progress = 1 - math.pow(1 - progress, 6)
# angleが45度未満の場合は0から45度に進むようにし、45度以上の場合は45度に固定
angle = min(45, 45 * eased_progress)
angle = -angle
rotated_img = self.rotateImage(self.chato_img, angle)
self.chato_img_label.configure(image=CTkImage(rotated_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT)))
rely = 1.0 - eased_progress * 0.6
self.chato_img_label.place_configure(rely=rely)
self.update()
if elapsed_time >= DURATION:
break
time.sleep(0.01)
def rotateImage(self, image, angle):
# 画像を回転させる
rotated_image = image.rotate(angle, expand=True)
return rotated_image
# This making gradient color process was made by ChatGPT.
def generateGradientColor(self, value):
# 0の時の色と1の時の色を指定
color_start = [242, 242, 242] # RGB values for #f2f2f2
color_end = [72, 164, 149] # RGB values for #48a495
# 補完色を計算
interpolated_color = [
int(start + (end - start) * value) for start, end in zip(color_start, color_end)
]
# RGB値を0から255の範囲にクリップ
interpolated_color = [max(0, min(255, val)) for val in interpolated_color]
# RGBを16進数に変換
hex_color = "#{:02x}{:02x}{:02x}".format(*interpolated_color)
return hex_color
def updateDownloadProgress(self, progress:float):
if self.is_showed_weight_download_progressbar is False:
self.vrct_second_text_img_label.place_forget()
self.progressbar_wrapper.place_forget()
self.starting_up_text_label.place_forget()
self.vrct_logo_img_label.place(relx=0.5, rely=0.4, anchor="center")
self.weight_download_progressbar_widget.place(relwidth=0.9, relx=0.5, rely=0.84, anchor="s")
self.weight_download_text_label.place(relx=0.98, rely=0.96, anchor="se")
self.is_showed_weight_download_progressbar = True
self.update()
progress_color = self.generateGradientColor(progress)
self.weight_download_progressbar_widget.configure(progress_color=progress_color)
self.weight_download_progressbar_widget.set(progress)
self.update_idletasks()
def showSplash(self):

View File

@@ -58,6 +58,7 @@ def _darkTheme(base_color):
SF__SWITCH_BOX_DISABLE_BG_COLOR = base_color.PRIMARY_800_COLOR,
SF__SWITCH_BOX_BUTTON_COLOR = base_color.DARK_400_COLOR,
SF__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.DARK_600_COLOR,
# It's not working because It overrode internally.
SF__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_350_COLOR,
@@ -90,6 +91,11 @@ def _darkTheme(base_color):
SLS__OPTIONMENU_HOVERED_BG_COLOR = base_color.DARK_875_COLOR,
SLS__OPTIONMENU_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
SLS__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.DARK_888_COLOR,
SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.DARK_650_COLOR,
SLS__DROPDOWN_MENU_BG_COLOR = base_color.DARK_888_COLOR,
SLS__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.DARK_825_COLOR,
SLS__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
CONFIG_BUTTON_BG_COLOR = base_color.DARK_850_COLOR,
CONFIG_BUTTON_HOVERED_BG_COLOR = base_color.DARK_800_COLOR,
@@ -210,8 +216,11 @@ def _darkTheme(base_color):
SB__SLIDER_TOOLTIP_TEXT_COLOR = base_color.DARK_200_COLOR,
SB__SWITCH_BOX_BG_COLOR = base_color.DARK_800_COLOR,
SB__SWITCH_BOX_BG_DISABLED_COLOR = base_color.DARK_900_COLOR,
SB__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_500_COLOR,
SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR = base_color.PRIMARY_700_COLOR,
SB__SWITCH_BOX_BUTTON_COLOR = base_color.DARK_400_COLOR,
SB__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.DARK_700_COLOR,
SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.DARK_350_COLOR,
SB__CHECKBOX_BORDER_COLOR = base_color.DARK_600_COLOR,

View File

@@ -58,6 +58,7 @@ def _lightTheme(base_color):
SF__SWITCH_BOX_DISABLE_BG_COLOR = base_color.PRIMARY_200_COLOR,
SF__SWITCH_BOX_BUTTON_COLOR = base_color.LIGHT_150_COLOR,
SF__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.LIGHT_300_COLOR,
# It's not working because It overrode internally.
SF__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_300_COLOR,
@@ -90,6 +91,11 @@ def _lightTheme(base_color):
SLS__OPTIONMENU_HOVERED_BG_COLOR = base_color.LIGHT_250_COLOR,
SLS__OPTIONMENU_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
SLS__DROPDOWN_MENU_WINDOW_BG_COLOR = base_color.LIGHT_300_COLOR,
SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR = base_color.LIGHT_700_COLOR,
SLS__DROPDOWN_MENU_BG_COLOR = base_color.LIGHT_300_COLOR,
SLS__DROPDOWN_MENU_HOVERED_BG_COLOR = base_color.LIGHT_200_COLOR,
SLS__DROPDOWN_MENU_CLICKED_BG_COLOR = base_color.LIGHT_400_COLOR,
CONFIG_BUTTON_BG_COLOR = base_color.LIGHT_250_COLOR,
CONFIG_BUTTON_HOVERED_BG_COLOR = base_color.LIGHT_350_COLOR,
@@ -203,8 +209,11 @@ def _lightTheme(base_color):
SB__SLIDER_TOOLTIP_TEXT_COLOR = base_color.LIGHT_800_COLOR,
SB__SWITCH_BOX_BG_COLOR = base_color.LIGHT_400_COLOR,
SB__SWITCH_BOX_BG_DISABLED_COLOR = base_color.LIGHT_200_COLOR,
SB__SWITCH_BOX_ACTIVE_BG_COLOR = base_color.PRIMARY_300_COLOR,
SB__SWITCH_BOX_ACTIVE_BG_DISABLED_COLOR = base_color.PRIMARY_150_COLOR,
SB__SWITCH_BOX_BUTTON_COLOR = base_color.LIGHT_300_COLOR,
SB__SWITCH_BOX_BUTTON_DISABLED_COLOR = base_color.LIGHT_150_COLOR,
SB__SWITCH_BOX_BUTTON_HOVERED_COLOR = base_color.LIGHT_200_COLOR,
SB__CHECKBOX_BORDER_COLOR = base_color.LIGHT_600_COLOR,

View File

@@ -13,6 +13,7 @@ class UiScalingManager():
self.main_window_cover = SimpleNamespace()
self.error_message_window = SimpleNamespace()
self.confirmation_modal = SimpleNamespace()
self.dropdown_menu_window = SimpleNamespace()
self._calculatedUiSizes()
@@ -66,7 +67,7 @@ class UiScalingManager():
# Sidebar
# Sidebar Features
self.main.SF__LOGO_MAX_SIZE = self._calculateUiSize(120)
self.main.SF__LOGO_PADY = (self._calculateUiSize(12),self._calculateUiSize(8))
self.main.SF__LOGO_PADY = (self._calculateUiSize(10),self._calculateUiSize(6))
self.main.SF__LOGO_HEIGHT_FOR_ADJUSTMENT = (self._calculateUiSize(6))
self.main.SF__LABELS_IPADY = self._calculateUiSize(16)
@@ -84,34 +85,34 @@ class UiScalingManager():
# Sidebar Quick Language Settings, SQLS
self.main.SLS__TITLE_FONT_SIZE = self._calculateUiSize(16)
self.main.SLS__TITLE_PADY = (self._calculateUiSize(12), self._calculateUiSize(6))
self.main.SLS__TITLE_FONT_SIZE = self._calculateUiSize(14)
self.main.SLS__TITLE_PADY = (self._calculateUiSize(10), self._calculateUiSize(4))
self.main.SLS__PRESET_TAB_NUMBER_FONT_SIZE = self._calculateUiSize(16)
self.main.SLS__PRESET_TAB_NUMBER_HEIGHT = self._calculateUiSize(30)
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_TOP_PADY = self._calculateUiSize(12)
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)
self.main.SLS__BOX_IPADY = (self._calculateUiSize(8),self._calculateUiSize(18))
self.main.SLS__BOX_IPADY = (self._calculateUiSize(8),self._calculateUiSize(14))
self.main.SLS__BOX_OPTION_MENU_FONT_SIZE = self._calculateUiSize(14)
self.main.SLS__BOX_OPTION_MENU_IPADY = self._calculateUiSize(2)
self.main.SLS__BOX_OPTION_MENU_ARROW_IMAGE_SIZE = (self._calculateUiSize(20), self._calculateUiSize(20))
self.main.SLS__BOX_OPTION_MENU_ARROW_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(20))
# self.main.SLS__BOX_OPTION_MENU_WIDTH = self._calculateUiSize(200)
self.main.SLS__BOX_ARROWS_PADY = self._calculateUiSize(4)
self.main.SLS__BOX_ARROWS_PADY = self._calculateUiSize(6)
self.main.SLS__BOX_ARROWS_SWAP_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
self.main.SLS__BOX_ARROWS_SWAP_BUTTON_PADX = self._calculateUiSize(20)
self.main.SLS__BOX_ARROWS_SWAP_BUTTON_IPADX = self._calculateUiSize(8)
self.main.SLS__BOX_ARROWS_SWAP_BUTTON_IPADY = self._calculateUiSize(6)
self.main.SLS__BOX_ARROWS_SWAP_BUTTON_IPADY = self._calculateUiSize(4)
self.main.SLS__BOX_ARROWS_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(16))
self.main.SLS__BOX_ARROWS_DESC_FONT_SIZE = self._calculateUiSize(12)
self.main.SLS__BOX_ARROWS_DESC_PADX = self._calculateUiSize(6)
self.main.SLS__BOX_TOP_PADY = self._calculateUiSize(16)
self.main.SIDEBAR_CONFIG_BUTTON_CORNER_RADIUS = self._calculateUiSize(6)
self.main.SIDEBAR_CONFIG_BUTTON_IMAGE_SIZE = self.main.SF__COMPACT_MODE_IMAGE_SIZE
@@ -140,6 +141,24 @@ class UiScalingManager():
self.main.MINIMIZE_SIDEBAR_BUTTON_ICON_SIZE_Y = self._calculateUiSize(26)
self.main.SLS__SELECTABLE_TRANSLATION_IPADX = self.dupTuple(self._calculateUiSize(10))
self.main.SLS__SELECTABLE_TRANSLATION_IPADY = self._calculateUiSize(6)
self.main.SLS__SELECTABLE_TRANSLATION_FONT_SIZE = self._calculateUiSize(12)
self.main.SLS__SELECTABLE_TRANSLATION_IMAGE_SIZE = self.dupTuple(self._calculateUiSize(10))
self.main.SLS__SELECTABLE_TRANSLATION_PADY = self._calculateUiSize(4)
self.main.SLS__SELECTABLE_TRANSLATION_MIN_PADX = self._calculateUiSize(8)
self.main.SLS__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS = self._calculateUiSize(4)
self.main.SLS__DROPDOWN_MENU_WINDOW_BORDER_WIDTH = self._calculateUiSize(0, is_allowed_odd=True)
self.main.SLS__DROPDOWN_MENU_SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
self.main.SLS__DROPDOWN_MENU_SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH
self.main.SLS__DROPDOWN_MENU_VALUE_IPADX = (self._calculateUiSize(8), 0)
self.main.SLS__DROPDOWN_MENU_VALUE_IPADY = self.dupTuple(self._calculateUiSize(8))
self.main.SLS__DROPDOWN_MENU_VALUE_PADY = 0
self.main.SLS__DROPDOWN_MENU_VALUE_FONT_SIZE = self._calculateUiSize(14)
self.main.SLS__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH = self._calculateUiSize(200)
# Selectable Language Window
self.selectable_language_window.TOP_BAR_MIN_HEIGHT = self._calculateUiSize(50)
@@ -170,7 +189,7 @@ class UiScalingManager():
self.confirmation_modal.BUTTONS_IPADY = self._calculateUiSize(6)
# Dropdown Menu Window
self.config_window.MARGIN_WIDTH = self._calculateUiSize(16)
self.dropdown_menu_window.MARGIN_WIDTH = self._calculateUiSize(16)
# Config Window
self.config_window.DEFAULT_WIDTH = self._calculateUiSize(1080)
@@ -256,7 +275,6 @@ class UiScalingManager():
self.config_window.SB__OPTIONMENU_IMG_SIZE = (self._calculateUiSize(14), self._calculateUiSize(14))
self.config_window.SB__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS = self._calculateUiSize(4)
self.config_window.SB__DROPDOWN_MENU_WIDTH = self.config_window.SB__OPTIONMENU_MIN_WIDTH
self.config_window.SB__DROPDOWN_MENU_WINDOW_BORDER_WIDTH = self._calculateUiSize(1, is_allowed_odd=True)
self.config_window.SB__DROPDOWN_MENU_SCROLLBAR_IPADX = self.common.SCROLLBAR_IPADX
self.config_window.SB__DROPDOWN_MENU_SCROLLBAR_WIDTH = self.common.SCROLLBAR_WIDTH

View File

@@ -42,6 +42,17 @@ def getLongestText(text_list:list):
longest_text = text
return longest_text
def getLongestText_Dict(text_dict:dict):
max_length = 0
longest_text = ""
for key, text in text_dict.items():
if len(text) > max_length:
max_length = len(text)
longest_text = text
return longest_text
def calculateUiSize(default_size, scaling_float, is_allowed_odd:bool=False, is_zero_allowed:bool=False):
size = int(default_size * scaling_float)
size += 1 if not is_allowed_odd and size % 2 != 0 else 0
@@ -157,6 +168,60 @@ def createButtonWithImage(parent_widget, button_image_size, button_ipadxy, butto
return button_wrapper
def createLabelButton(parent_widget, label_button_bg_color, label_button_hovered_bg_color, label_button_clicked_bg_color, label_button_ipadx, label_button_ipady, variable, font_family, font_size, text_color, label_button_clicked_command, label_button_position=None, label_button_padx_between_img=0, label_button_min_height=None, label_button_min_width=None):
label_button_box = CTkFrame(parent_widget, corner_radius=6, fg_color=label_button_bg_color, cursor="hand2")
label_button_box.grid_rowconfigure(0, weight=1)
if label_button_min_height is not None:
label_button_box.grid_rowconfigure(0, minsize=label_button_min_height)
label_button_box.grid_columnconfigure(0, weight=1)
if label_button_min_width is not None:
label_button_box.grid_columnconfigure(0, minsize=label_button_min_width)
label_button_label_wrapper = CTkFrame(label_button_box, corner_radius=0, fg_color=label_button_bg_color)
label_button_label_wrapper.grid(row=0, column=0, padx=label_button_ipadx, pady=label_button_ipady, sticky="ew")
LABEL_COLUMN=0
if label_button_position == "center":
label_button_label_wrapper.grid_columnconfigure((0,2), weight=1)
LABEL_COLUMN=1
label_button_label_widget = CTkLabel(
label_button_label_wrapper,
textvariable=variable,
height=0,
font=CTkFont(family=font_family, size=font_size, weight="normal"),
text_color=text_color
)
label_button_label_widget.grid(row=0, column=LABEL_COLUMN, padx=(0, label_button_padx_between_img))
bindEnterAndLeaveColor([label_button_label_wrapper, label_button_box, label_button_label_widget], label_button_hovered_bg_color, label_button_bg_color)
bindButtonPressColor([label_button_label_wrapper, label_button_box, label_button_label_widget], label_button_clicked_bg_color, label_button_hovered_bg_color)
bindButtonReleaseFunction([label_button_label_wrapper, label_button_box, label_button_label_widget], label_button_clicked_command)
def bindEventFromWidgets():
bindButtonReleaseFunction([label_button_label_wrapper, label_button_box, label_button_label_widget], label_button_clicked_command)
bindEventFromWidgets()
def unbindEventFromWidgets():
unbindEnterLEaveButtonPressButtonReleaseFunction([label_button_label_wrapper, label_button_box, label_button_label_widget])
label_button_box.unbindFunction = unbindEventFromWidgets
label_button_box.bindFunction = bindEventFromWidgets
return (label_button_box, label_button_label_widget)
def createOptionMenuBox(parent_widget, optionmenu_bg_color, optionmenu_hovered_bg_color, optionmenu_clicked_bg_color, optionmenu_ipadx, optionmenu_ipady, variable, font_family, font_size, text_color, image_file, image_size, optionmenu_clicked_command, optionmenu_position=None, optionmenu_padx_between_img=0, optionmenu_min_height=None, optionmenu_min_width=None, setattr_widget=None, image_widget_attr_name=None):
option_menu_box = CTkFrame(parent_widget, corner_radius=6, fg_color=optionmenu_bg_color, cursor="hand2")
@@ -205,13 +270,15 @@ def createOptionMenuBox(parent_widget, optionmenu_bg_color, optionmenu_hovered_b
bindButtonPressColor([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_clicked_bg_color, optionmenu_hovered_bg_color)
bindButtonReleaseFunction([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_clicked_command)
def bindEventFromWidgets():
bindButtonReleaseFunction([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget], optionmenu_clicked_command)
bindEventFromWidgets()
def unbindEventFromWidgets():
unbindEnterLEaveButtonPressButtonReleaseFunction([optionmenu_label_wrapper, option_menu_box, optionmenu_label_widget, optionmenu_img_widget])
option_menu_box.unbindFunction = unbindEventFromWidgets
option_menu_box.bindFunction = bindEventFromWidgets
return (option_menu_box, optionmenu_label_widget, optionmenu_img_widget)

View File

@@ -71,14 +71,37 @@ class VRCT_GUI(CTk):
self.settings = settings
self._view_variable = view_variable
self.translation_engine_dropdown_menu_window = _CreateDropdownMenuWindow(
settings=settings.dropdown_menu_window,
view_variable=self._view_variable,
window_additional_y_pos=self.settings.main.uism.SLS__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS,
window_border_width=self.settings.main.uism.SLS__DROPDOWN_MENU_WINDOW_BORDER_WIDTH,
scrollbar_ipadx=self.settings.main.uism.SLS__DROPDOWN_MENU_SCROLLBAR_IPADX,
scrollbar_width=self.settings.main.uism.SLS__DROPDOWN_MENU_SCROLLBAR_WIDTH,
value_ipadx=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_IPADX,
value_ipady=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_IPADY,
value_pady=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_PADY,
value_font_size=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_FONT_SIZE,
dropdown_menu_default_min_width=self.settings.main.uism.SLS__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH,
window_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_WINDOW_BG_COLOR,
window_border_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_WINDOW_BORDER_COLOR,
values_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_BG_COLOR,
values_hovered_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_HOVERED_BG_COLOR,
values_clicked_bg_color=self.settings.main.ctm.SLS__DROPDOWN_MENU_CLICKED_BG_COLOR,
values_text_color=self.settings.main.ctm.BASIC_TEXT_COLOR,
)
createMainWindowWidgets(
vrct_gui=self,
settings=self.settings.main,
view_variable=self._view_variable
)
# For Config Window
self.dropdown_menu_window = _CreateDropdownMenuWindow(
settings=self.settings.config_window,
settings=self.settings.dropdown_menu_window,
view_variable=self._view_variable,
window_additional_y_pos=self.settings.config_window.uism.SB__DROPDOWN_MENU_WINDOW_ADDITIONAL_Y_POS,
@@ -227,14 +250,15 @@ class VRCT_GUI(CTk):
def _changeMainWindowWidgetsStatus(self, status, target_names, to_hold_state:bool=False):
def _changeMainWindowWidgetsStatus(self, status, target_names, to_lock_state:bool=False, release_locked_state:bool=False):
_changeMainWindowWidgetsStatus(
vrct_gui=self,
settings=self.settings.main,
view_variable=self._view_variable,
status=status,
target_names=target_names,
to_hold_state=to_hold_state,
to_lock_state=to_lock_state,
release_locked_state=release_locked_state,
)
def _changeConfigWindowWidgetsStatus(self, status, target_names):