Merge branch 'view' into UI_2.0

This commit is contained in:
Sakamoto Shiina
2023-10-19 15:26:47 +09:00
10 changed files with 155 additions and 28 deletions

View File

@@ -66,6 +66,9 @@ config_window:
compact_mode: Compact Mode
version: version %{version}
restart_message: Apply changes with a restart.
common_error_message:
invalid_value: Invalid value.
side_menu_labels:
appearance: Appearance
# translation: Translation
@@ -75,16 +78,21 @@ config_window:
others: Others
advanced_settings: Advanced Settings
transparency:
label: Transparency
desc: Change the main window's transparency.
appearance_theme:
label: Theme [Under development]
desc: Change the color theme. Currently, only the Dark theme is supported. The Light theme is under development.
ui_size:
label: UI Size
font_family:
label: Font Family
ui_language:
label: UI Language
@@ -93,22 +101,32 @@ config_window:
mic_host:
label: Mic Host/Driver
mic_device:
label: Mic Device
mic_dynamic_energy_threshold:
label_for_automatic: "Mic Energy Threshold (Current Setting: Automatic)"
desc_for_automatic: "Automatically determine microphone input sensitivity."
label_for_manual: "Mic Energy Threshold (Current Setting: Manual)"
desc_for_manual: "Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume."
error_message: You can set it with a value between 0 to %{max}.
mic_record_timeout:
label: Mic Record Timeout
desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s))
error_message: It cannot be greater than '%{mic_phrase_timeout_label}' with a value of 0 or more.
mic_phrase_timeout:
label: Mic Phrase Timeout
desc: Transcription processing is performed at intervals of the specified number of seconds.
error_message: It cannot be set lower than '%{mic_record_timeout_label}' with a value of 0 or more.
mic_max_phrase:
label: Mic Max Phrases
desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat.
error_message: You can set a number equal to or greater than 0.
mic_word_filter:
label: Mic Word Filter
desc: "It will not send the sentence if the word(s) included in the set list of words.\nHow to set: e.g. AAA,BBB,CCC"
@@ -119,32 +137,46 @@ config_window:
desc_for_automatic: "Automatically determine speaker input sensitivity."
label_for_manual: "Speaker Energy Threshold (Current Setting: Manual)"
desc_for_manual: "Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume."
error_message: You can set it with a value between 0 to %{max}.
no_device_error_message: No speaker device detected.
speaker_record_timeout:
label: Speaker Record Timeout
desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))
error_message: It cannot be greater than '%{speaker_phrase_timeout_label}' with a value of 0 or more.
speaker_phrase_timeout:
label: Speaker Phrase Timeout
desc: Transcription processing is performed at intervals of the specified number of seconds.
error_message: It cannot be set lower than '%{speaker_record_timeout_label}' with a value of 0 or more.
speaker_max_phrase:
label: Speaker Max Phrases
desc: It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs.
error_message: You can set a number equal to or greater than 0.
auto_clear_the_message_box:
label: Auto Clear The Message Box
notice_xsoverlay:
label: Notification XSOverlay (VR Only)
desc: Notify received messages by using XSOverlay's notification feature.
auto_export_message_logs:
label: Auto Export Message Logs
desc: Automatically export the conversation messages as a text file.
message_format:
label: Message Format
desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\nIt will be used in Notification XSOverlay too."
send_message_to_vrc:
label: Send Message To VRChat
desc: There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat.
osc_ip_address:
label: OSC IP Address
osc_port:
label: OSC Port

View File

@@ -67,6 +67,9 @@ config_window:
compact_mode: コンパクトモード
version: バージョン %{version}
restart_message: 再起動して変更を適用する。
common_error_message:
invalid_value: 無効な値です。
side_menu_labels:
appearance: デザイン
# translation: 翻訳
@@ -76,16 +79,21 @@ config_window:
others: その他
advanced_settings: 高度な設定
transparency:
label: 透明度
desc: メイン画面の透明度を変更できます。
appearance_theme:
label: 外観テーマ [開発中]
desc: カラーテーマを変更できます。現在はDarkテーマのみ対応。Lightテーマは制作中です。
ui_size:
label: UIサイズ
font_family:
label: 使用フォント
ui_language:
label: UIの言語 / UI Language
@@ -94,22 +102,32 @@ config_window:
mic_host:
label: マイク(ホスト/ドライバー)
mic_device:
label: マイク (デバイス)
mic_dynamic_energy_threshold:
label_for_automatic: "マイク入力感度の調整 (現在の設定: 自動)"
desc_for_automatic: マイクの入力感度を自動的に調節する。
label_for_manual: "マイク入力感度の調整 (現在の設定: 手動)"
desc_for_manual: スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。
error_message: 0 から %{max} までの数値で設定できます。
mic_record_timeout:
label: 入力が終了したとみなす無音時間
desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。
error_message: 0 以上で 「%{mic_phrase_timeout_label}」より大きくすることはできません。
mic_phrase_timeout:
label: 一度に文字起こしする時間の長さ
desc: 設定された秒数ごとに文字起こし処理が行われます。
error_message: 0 以上で 「%{mic_record_timeout_label}」より小さくすることはできません。
mic_max_phrase:
label: 送信するまでに保持する単語数
desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。
error_message: 0以上の数値を設定できます。
mic_word_filter:
label: ワードフィルター
desc: "設定された単語を検出すると、その文章は送信されません。\n設定の例: AAA,BBB,CCC"
@@ -120,32 +138,45 @@ config_window:
desc_for_automatic: スピーカーの入力感度を自動的に調節する。
label_for_manual: "スピーカー入力感度の調整 (現在の設定: 手動)"
desc_for_manual: スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。
error_message: 0 から %{max} までの数値で設定できます。
no_device_error_message: スピーカーデバイスが検出されませんでした。
speaker_record_timeout:
label: 入力が終了したとみなす無音時間
desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。
error_message: 0 以上で 「%{speaker_phrase_timeout_label}」より大きくすることはできません。
speaker_phrase_timeout:
label: 一度に文字起こしする時間の長さ
desc: 設定された秒数ごとに文字起こし処理が行われます。
error_message: 0 以上で 「%{speaker_record_timeout_label}」より小さくすることはできません。
speaker_max_phrase:
label: ログとして表示するまでに保持する単語数
desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。
error_message: 0以上の数値を設定できます。
auto_clear_the_message_box:
label: 送信後はチャットボックスを空にする
notice_xsoverlay:
label: XSOverlayでの通知受け取り機能を有効 (VR限定)
desc: 文字起こし受信されたメッセージをXSOverlayの機能を使って通知として受け取れます。
auto_export_message_logs:
label: 会話ログを自動的に保存する
desc: テキストファイルとしてログがlogsフォルダ内に保存されます。
message_format:
label: 送信するメッセージのフォーマット
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、\n[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能でも使われます。"
send_message_to_vrc:
label: VRChatにメッセージを送信する
desc: "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。"
osc_ip_address:
label: OSC IP Address
osc_port:
label: OSC Port

72
view.py
View File

@@ -593,7 +593,8 @@ class View():
index = self.view_variable.LIST_UI_SCALING.index(str(target_percentage) + "%")
callFunctionIfCallable(self.view_variable.CALLBACK_SET_UI_SCALING, self.view_variable.LIST_UI_SCALING[index])
callFunctionIfCallable(self.view_variable.CALLBACK_RESTART_SOFTWARE)
else:
self._hideConfirmationModal()
# ※Below 40% of the UI size is not supported, and we cannot handle it at this time.
@@ -1040,38 +1041,89 @@ class View():
def showErrorMessage_MicEnergyThreshold(self):
self._showErrorMessage(vrct_gui.config_window.sb__progressbar_x_slider__entry_mic_energy_threshold, "Mic Energy Threshold Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__progressbar_x_slider__entry_mic_energy_threshold,
self._makeInvalidValueErrorMessage(i18n.t("config_window.mic_dynamic_energy_threshold.error_message", max=config.MAX_MIC_ENERGY_THRESHOLD))
)
def showErrorMessage_MicRecordTimeout(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_mic_record_timeout, "Mic Record Timeout Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_mic_record_timeout,
self._makeInvalidValueErrorMessage(
i18n.t(
"config_window.mic_record_timeout.error_message",
mic_phrase_timeout_label=i18n.t("config_window.mic_phrase_timeout.label")
)
)
)
def showErrorMessage_MicPhraseTimeout(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_mic_phrase_timeout, "Mic Phrase Timeout Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_mic_phrase_timeout,
self._makeInvalidValueErrorMessage(
i18n.t(
"config_window.mic_phrase_timeout.error_message",
mic_record_timeout_label=i18n.t("config_window.mic_record_timeout.label")
)
)
)
def showErrorMessage_MicMaxPhrases(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_mic_max_phrases, "Mic Max Phrases Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_mic_max_phrases,
self._makeInvalidValueErrorMessage(i18n.t("config_window.mic_max_phrase.error_message"))
)
def showErrorMessage_SpeakerEnergyThreshold(self):
self._showErrorMessage(vrct_gui.config_window.sb__progressbar_x_slider__entry_speaker_energy_threshold, "Speaker Energy Threshold Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__progressbar_x_slider__entry_speaker_energy_threshold,
self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_dynamic_energy_threshold.error_message", max=config.MAX_SPEAKER_ENERGY_THRESHOLD))
)
def showErrorMessage_SpeakerRecordTimeout(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_speaker_record_timeout, "Speaker Record Timeout Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_speaker_record_timeout,
self._makeInvalidValueErrorMessage(
i18n.t(
"config_window.speaker_record_timeout.error_message",
speaker_phrase_timeout_label=i18n.t("config_window.speaker_phrase_timeout.label")
)
)
)
def showErrorMessage_SpeakerPhraseTimeout(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_speaker_phrase_timeout, "Speaker Phrase Timeout Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_speaker_phrase_timeout,
self._makeInvalidValueErrorMessage(
i18n.t(
"config_window.speaker_phrase_timeout.error_message",
speaker_record_timeout_label=i18n.t("config_window.speaker_record_timeout.label")
)
)
)
def showErrorMessage_SpeakerMaxPhrases(self):
self._showErrorMessage(vrct_gui.config_window.sb__entry_speaker_max_phrases, "Speaker Max Phrases Error Message")
self._showErrorMessage(
vrct_gui.config_window.sb__entry_speaker_max_phrases,
self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_max_phrase.error_message"))
)
def showErrorMessage_CheckSpeakerThreshold_NoDevice(self):
self._showErrorMessage(vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold, "No speaker device detected")
self._showErrorMessage(
vrct_gui.config_window.sb__progressbar_x_slider__active_button_speaker_energy_threshold,
self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_dynamic_energy_threshold.no_device_error_message"))
)
def _showErrorMessage(self, target_widget, message):
self.view_variable.VAR_ERROR_MESSAGE.set(message)
vrct_gui._showErrorMessage(target_widget=target_widget)
@staticmethod
def _makeInvalidValueErrorMessage(error_message):
return i18n.t("config_window.common_error_message.invalid_value") + "\n" + error_message
def clearErrorMessage(self):
vrct_gui._clearErrorMessage()

View File

@@ -3,7 +3,7 @@ from types import SimpleNamespace
from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont, CTkScrollableFrame
from time import sleep
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar
from .ui_utils import bindButtonReleaseFunction, bindEnterAndLeaveColor, bindButtonPressColor, getLatestHeight, applyUiScalingAndFixTheBugScrollBar, getLatestWidth, getLongestText
from functools import partial
from utils import isEven, makeEven
@@ -22,6 +22,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
value_ipady,
value_pady,
value_font_size,
dropdown_menu_default_min_width,
window_bg_color,
window_border_color,
@@ -53,6 +54,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
self.value_ipady=value_ipady
self.value_pady=value_pady
self.value_font_size=value_font_size
self.dropdown_menu_default_min_width=dropdown_menu_default_min_width
self.window_bg_color=window_bg_color
self.window_border_color=window_border_color
@@ -97,19 +99,19 @@ class _CreateDropdownMenuWindow(CTkToplevel):
wrapper_widget=self.dropdown_menu_widgets[dropdown_menu_widget_id].wrapper_widget,
attach_widget=self.dropdown_menu_widgets[dropdown_menu_widget_id].attach_widget,
dropdown_menu_width=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.dropdown_menu_width,
dropdown_menu_min_width=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.dropdown_menu_min_width,
dropdown_menu_height=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.dropdown_menu_height,
max_display_length=self.dropdown_menu_widgets[dropdown_menu_widget_id].dropdown_menu_settings.max_display_length,
)
def createDropdownMenuBox(self, dropdown_menu_widget_id, dropdown_menu_values, command, wrapper_widget, attach_widget, dropdown_menu_width=None, dropdown_menu_height=None, max_display_length=None):
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):
self.attach_widget = attach_widget
self.wrapper_widget = wrapper_widget
self.update()
self.new_width = dropdown_menu_width if dropdown_menu_width is not None else self.attach_widget.winfo_width()
self.new_width = dropdown_menu_min_width if dropdown_menu_min_width is not None else self.dropdown_menu_default_min_width
self.new_height = dropdown_menu_height if dropdown_menu_height is not None else self.init_height
self.max_display_length = max_display_length if max_display_length is not None else self.init_max_display_length
@@ -151,7 +153,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
wrapper_widget=wrapper_widget,
attach_widget=attach_widget,
dropdown_menu_settings=SimpleNamespace(
dropdown_menu_width=dropdown_menu_width,
dropdown_menu_min_width=dropdown_menu_min_width,
dropdown_menu_height=dropdown_menu_height,
max_display_length=max_display_length,
),
@@ -166,6 +168,7 @@ class _CreateDropdownMenuWindow(CTkToplevel):
def _createDropdownMenuValues(self, dropdown_menu_widget_id, dropdown_menu_values, command):
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)
@@ -177,10 +180,10 @@ class _CreateDropdownMenuWindow(CTkToplevel):
__dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
__dropdown_menu_value_wrapper.grid_columnconfigure(0, weight=1)
# __dropdown_menu_value_wrapper.grid_columnconfigure(0, weight=1)
__label_widget = CTkLabel(
__dropdown_menu_value_wrapper,
text="Aa",
text=longest_text,
height=0,
corner_radius=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.value_font_size, weight="normal"),
@@ -190,7 +193,13 @@ class _CreateDropdownMenuWindow(CTkToplevel):
# setattr(self, f"l", __label_widget)
__label_widget.grid(row=1, column=0, padx=self.value_ipadx, pady=self.value_ipady, sticky="w")
label_height = getLatestHeight(__dropdown_menu_value_wrapper)
label_width = getLatestWidth(__label_widget)
label_width += self.scroll_frame_container._scrollbar.winfo_width() + (self.window_border_width*2) + (self.scrollbar_ipadx[0] + self.scrollbar_ipadx[1])
if label_width > self.new_width:
additional_width = int(label_width - self.new_width)
self.new_width += additional_width
# for fixing 1px bug
if isEven(label_height) is False:
@@ -223,7 +232,6 @@ class _CreateDropdownMenuWindow(CTkToplevel):
dropdown_menu_value_wrapper.grid_rowconfigure((0,2), weight=1)
dropdown_menu_value_wrapper.grid_columnconfigure(0, weight=1)
label_widget = CTkLabel(
dropdown_menu_value_wrapper,
text=dropdown_menu_value,

View File

@@ -11,7 +11,6 @@ class _CreateSelectableLanguagesWindow(CTkToplevel):
self.withdraw()
# configure window
self.title("_CreateSelectableLanguagesWindow")
self.overrideredirect(True)
@@ -24,7 +23,8 @@ class _CreateSelectableLanguagesWindow(CTkToplevel):
self.settings = settings
self._view_variable = view_variable
self.bind("<FocusOut>", lambda e: vrct_gui._closeSelectableLanguagesWindow())
self.bind("<FocusOut>", self.focusOutFunction)
@@ -179,4 +179,9 @@ class _CreateSelectableLanguagesWindow(CTkToplevel):
row+=1
self.is_created = True
self.is_created = True
def focusOutFunction(self, e):
if str(e.widget) != ".!_createselectablelanguageswindow": return
self.vrct_gui._closeSelectableLanguagesWindow()

View File

@@ -96,7 +96,7 @@ class _SettingBoxGenerator():
for_var_label_text, for_var_desc_text,
optionmenu_attr_name,
command,
dropdown_menu_width=None,
dropdown_menu_min_width=None,
dropdown_menu_values=None,
variable=None,
):
@@ -144,7 +144,7 @@ class _SettingBoxGenerator():
command=adjustedCommand,
wrapper_widget=self.config_window.main_bg_container,
attach_widget=option_menu_widget,
dropdown_menu_width=dropdown_menu_width,
dropdown_menu_min_width=dropdown_menu_min_width,
)
return setting_box_frame

View File

@@ -70,7 +70,6 @@ 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,
dropdown_menu_width=settings.uism.RESPONSIVE_UI_SIZE_INT_300,
command=lambda value: optionmenu_font_family_callback(value),
variable=view_variable.VAR_FONT_FAMILY,
)

View File

@@ -58,7 +58,6 @@ 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,
dropdown_menu_width=settings.uism.RESPONSIVE_UI_SIZE_INT_500,
command=lambda value: optionmenu_input_mic_device_callback(value),
variable=view_variable.VAR_MIC_DEVICE,
)

View File

@@ -217,7 +217,7 @@ class UiScalingManager():
self.config_window.SB__ERROR_MESSAGE_IPADX = (self._calculateUiSize(10), self._calculateUiSize(10))
self.config_window.SB__ERROR_MESSAGE_IPADY = (self._calculateUiSize(6), self._calculateUiSize(6))
self.config_window.SB__ERROR_MESSAGE_FONT_SIZE = self._calculateUiSize(12)
self.config_window.SB__ERROR_MESSAGE_FONT_SIZE = self._calculateUiSize(14)
self.config_window.SB__SELECTOR_FONT_SIZE = self._calculateUiSize(14)
@@ -243,6 +243,7 @@ class UiScalingManager():
self.config_window.SB__DROPDOWN_MENU_VALUE_IPADY = (self._calculateUiSize(6), self._calculateUiSize(6))
self.config_window.SB__DROPDOWN_MENU_VALUE_PADY = (0, self._calculateUiSize(1, is_allowed_odd=True))
self.config_window.SB__DROPDOWN_MENU_VALUE_FONT_SIZE = self._calculateUiSize(14)
self.config_window.SB__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH = self._calculateUiSize(200)
self.config_window.SB__SWITCH_WIDTH = self._calculateUiSize(50)

View File

@@ -81,6 +81,7 @@ class VRCT_GUI(CTk):
value_ipady=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_IPADY,
value_pady=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_PADY,
value_font_size=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_FONT_SIZE,
dropdown_menu_default_min_width=self.settings.config_window.uism.SB__DROPDOWN_MENU_VALUE_DEFAULT_MIN_WIDTH,
window_bg_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_WINDOW_BG_COLOR,
window_border_color=self.settings.config_window.ctm.SB__DROPDOWN_MENU_WINDOW_BORDER_COLOR,
@@ -291,7 +292,6 @@ class VRCT_GUI(CTk):
self.update()
screen_height = self.winfo_screenheight()
window_height = self.winfo_height()
print(screen_height, window_height)
if screen_height < window_height:
return True
else: