Merge branch 'ui_update_message_format' into develop

This commit is contained in:
Sakamoto Shiina
2023-11-05 11:38:37 +09:00
15 changed files with 438 additions and 20 deletions

View File

@@ -8,7 +8,7 @@ from tkinter import font
from languages import selectable_languages
from models.translation.translation_languages import translatorEngine
from models.transcription.transcription_utils import getInputDevices, getDefaultInputDevice
from utils import generatePercentageStringsList
from utils import generatePercentageStringsList, isUniqueStrings
json_serializable_vars = {}
def json_serializable(var_name):
@@ -447,6 +447,8 @@ class Config:
@MESSAGE_FORMAT.setter
def MESSAGE_FORMAT(self, value):
if type(value) is str:
if isUniqueStrings(["[message]", "[translation]"], value) is False:
value = "[message]([translation])"
self._MESSAGE_FORMAT = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)

View File

@@ -3,7 +3,7 @@ from threading import Thread
from config import config
from model import model
from view import view
from utils import get_key_by_value
from utils import get_key_by_value, isUniqueStrings
from languages import selectable_languages
# Common
@@ -627,7 +627,14 @@ def callbackSetEnableAutoExportMessageLogs(value):
def callbackSetMessageFormat(value):
print("callbackSetMessageFormat", value)
if len(value) > 0:
config.MESSAGE_FORMAT = value
if isUniqueStrings(["[message]", "[translation]"], value) is True:
config.MESSAGE_FORMAT = value
view.clearErrorMessage()
view.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
else:
view.showErrorMessage_MessageFormat()
view.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
def callbackSetEnableSendMessageToVrc(value):
print("callbackSetEnableSendMessageToVrc", value)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
img/refresh_update_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
img/swap_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -181,6 +181,8 @@ config_window:
message_format:
label: Message Format
desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\nIt will be used in Notification XSOverlay too."
example_text: This is an example sentence. Fonts, line breaks, etc. may differ from the actual display.
error_message: "The characters '[message]' and '[translation]' cannot be used."
send_message_to_vrc:
label: Send Message To VRChat

View File

@@ -179,7 +179,9 @@ config_window:
message_format:
label: 送信するメッセージのフォーマット
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、\n[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能でも使われます。"
desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能でも使われます。"
example_text: これは例文です。フォントや改行箇所など、実際の表示とは異なる場合があります。
error_message: "[message]と[translation]という文字は使えません。"
send_message_to_vrc:
label: VRChatにメッセージを送信する

View File

@@ -175,6 +175,7 @@ config_window:
message_format:
label: 전송 형식
# desc: "You can change the decoration of the message you want to send.\n[message] will be replaced with the message, and [translation] will be replaced with the translated message.\nIt will be used in Notification XSOverlay too."
example_text: 예문입니다. 글꼴, 줄 바꿈 등이 실제 표시와 다를 수 있습니다.
# send_message_to_vrc:
# label: Send Message To VRChat

View File

@@ -1,3 +1,4 @@
from typing import Union
from os import path as os_path
from PIL.Image import open as Image_open
@@ -29,4 +30,19 @@ def generatePercentageStringsList(start=40, end=200, step=10):
return strings
def intToPercentageStringsFormatter(value:int):
return f"{value}%"
return f"{value}%"
def isUniqueStrings(unique_strings:Union[str, list], input_string:str, require=False):
import re
if isinstance(unique_strings, str):
unique_strings = [unique_strings]
patterns = [re.escape(s) for s in unique_strings]
counts = [len(re.findall(pattern, input_string)) for pattern in patterns]
if require is True:
# If require is True, unique_strings must appear once
return all(count == 1 for count in counts) and counts.count(1) == 2
else:
# If require is False, check if unique strings are used exactly once
return all(count == 1 for count in counts)

121
view.py
View File

@@ -347,7 +347,15 @@ class View():
VAR_LABEL_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.message_format.label")),
VAR_DESC_MESSAGE_FORMAT=StringVar(value=i18n.t("config_window.message_format.desc")),
CALLBACK_SET_MESSAGE_FORMAT=None,
CALLBACK_SWAP_MESSAGE_FORMAT_REQUIRED_TEXT=self._swapMessageFormatRequiredText,
VAR_MESSAGE_FORMAT=StringVar(value=config.MESSAGE_FORMAT),
VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_0_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_1_MESSAGE_FORMAT=StringVar(value=""),
VAR_ENTRY_2_MESSAGE_FORMAT=StringVar(value=""),
VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT=StringVar(value="[message]"),
VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT=StringVar(value="[translation]"),
CALLBACK_FOCUS_OUT_MESSAGE_FORMAT=self.callbackBindFocusOut_MessageFormat,
VAR_LABEL_ENABLE_SEND_MESSAGE_TO_VRC=StringVar(value=i18n.t("config_window.send_message_to_vrc.label")),
@@ -531,10 +539,56 @@ class View():
self.openSpeakerEnergyThresholdWidget()
self.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
# Insert sample conversation for testing.
# self._insertSampleConversationToTextbox()
def setMessageFormatEntryWidgets(self, message_format:str):
result = self.extractMessageFormat(message_format)
if result.is_message_first is True:
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set("[message]")
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set("[translation]")
else:
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set("[translation]")
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set("[message]")
self.view_variable.VAR_ENTRY_0_MESSAGE_FORMAT.set(result.before)
self.view_variable.VAR_ENTRY_1_MESSAGE_FORMAT.set(result.between)
self.view_variable.VAR_ENTRY_2_MESSAGE_FORMAT.set(result.after)
self.updateMessageFormat_ExampleTextWidget()
def _swapMessageFormatRequiredText(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.get()
self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.set(text_1)
self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.set(text_0)
self.updateMessageFormat_ExampleTextWidget()
new_message_format = self.getLatestMessageFormatFromWidget()
callFunctionIfCallable(self.view_variable.CALLBACK_SET_MESSAGE_FORMAT, new_message_format)
def getLatestMessageFormatFromWidget(self):
text_0 = self.view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT.get()
text_1 = self.view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT.get()
entry_0 = self.view_variable.VAR_ENTRY_0_MESSAGE_FORMAT.get()
entry_1 = self.view_variable.VAR_ENTRY_1_MESSAGE_FORMAT.get()
entry_2 = self.view_variable.VAR_ENTRY_2_MESSAGE_FORMAT.get()
return entry_0+text_0+entry_1+text_1+entry_2
def updateMessageFormat_ExampleTextWidget(self):
message = i18n.t("config_window.message_format.example_text", locale=config.UI_LANGUAGE)
translation_locale = "ja" if config.UI_LANGUAGE == "en" else "en"
translation = i18n.t("config_window.message_format.example_text", locale=translation_locale)
example_message = config.MESSAGE_FORMAT.replace("[message]", message)
example_message = example_message.replace("[translation]", translation)
self.view_variable.VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT.set(example_message)
# GUI process
def createGUI(self):
@@ -1068,6 +1122,9 @@ class View():
case "SpeakerMaxPhrases":
self.setGuiVariable_SpeakerMaxPhrases(config.INPUT_SPEAKER_MAX_PHRASES)
case "MessageFormat":
self.setMessageFormatEntryWidgets(config.MESSAGE_FORMAT)
case _:
raise ValueError(f"No matching case for target_name: {target_name}")
@@ -1217,7 +1274,9 @@ class View():
self.clearErrorMessage()
def callbackBindFocusOut_MessageFormat(self, _e=None):
self.setLatestConfigVariable("MessageFormat")
self.clearErrorMessage()
@@ -1299,6 +1358,13 @@ class View():
self._makeInvalidValueErrorMessage(i18n.t("config_window.speaker_dynamic_energy_threshold.no_device_error_message"))
)
def showErrorMessage_MessageFormat(self):
self._showErrorMessage(
vrct_gui.config_window.sb__entry_message_format_2,
self._makeInvalidValueErrorMessage(i18n.t("config_window.message_format.error_message"))
)
@staticmethod
def _makeInvalidValueErrorMessage(error_message):
return i18n.t("config_window.common_error_message.invalid_value") + "\n" + error_message
@@ -1308,6 +1374,59 @@ class View():
vrct_gui._showErrorMessage(target_widget=target_widget)
@staticmethod
def extractMessageFormat(text):
import re
message_index = text.find("[message]")
translation_index = text.find("[translation]")
result_data = SimpleNamespace(
is_message_first = True,
before = "",
between = "",
after = "",
)
if message_index < translation_index:
text_before_message = text[:message_index]
result_data.before = text_before_message
match = re.search(r"\[message\](.*?)\[translation\]", text)
if match:
extracted_text = match.group(1)
result_data.between = extracted_text
else:
raise ValueError("Invalid Message Format")
text_after_translation = text[translation_index + len("[translation]"):]
result_data.after = text_after_translation
elif translation_index < message_index:
result_data.is_message_first = False
text_before_translation = text[:translation_index]
result_data.before = text_before_translation
match = re.search(r"\[translation\](.*?)\[message\]", text)
if match:
extracted_text = match.group(1)
result_data.between = extracted_text
else:
raise ValueError("Invalid Message Format")
text_after_message = text[message_index + len("[message]"):]
result_data.after = text_after_message
else:
raise ValueError("Invalid Message Format")
return result_data

View File

@@ -2,7 +2,7 @@ from functools import partial
from types import SimpleNamespace
from typing import Union
from customtkinter import CTkOptionMenu, CTkFont, CTkFrame, CTkLabel, CTkRadioButton, CTkEntry, CTkSlider, CTkSwitch, CTkCheckBox, CTkProgressBar
from customtkinter import CTkOptionMenu, CTkFont, CTkFrame, CTkLabel, CTkRadioButton, CTkEntry, CTkSlider, CTkSwitch, CTkCheckBox, CTkProgressBar, CTkImage
from CTkToolTip import *
from vrct_gui.ui_utils import createButtonWithImage, getLatestWidth, createOptionMenuBox, getLatestHeight, bindButtonFunctionAndColor
@@ -22,7 +22,7 @@ class _SettingBoxGenerator():
self.dropdown_menu_window = vrct_gui.vrct_gui.dropdown_menu_window
def _createSettingBoxFrame(self, sb__attr_name, for_var_label_text=None, for_var_desc_text=None):
def _createSettingBoxFrame(self, sb__attr_name, for_var_label_text=None, for_var_desc_text=None, expand_label_frame:bool=False):
self.config_window.sb__widgets[sb__attr_name] = SimpleNamespace()
setting_box_frame = CTkFrame(self.parent_widget, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
@@ -34,8 +34,7 @@ class _SettingBoxGenerator():
setting_box_frame_wrapper = CTkFrame(setting_box_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
setting_box_frame_wrapper.grid(row=0, column=0, padx=self.settings.uism.SB__IPADX, pady=self.settings.uism.SB__IPADY, sticky="ew")
setting_box_frame_wrapper.grid_columnconfigure(0, weight=0, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
setting_box_frame_wrapper.grid_columnconfigure(2, weight=1, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
setting_box_frame_wrapper_fix_border = CTkFrame(setting_box_frame, corner_radius=0, width=0, height=0)
setting_box_frame_wrapper_fix_border.grid(row=1, column=0, sticky="ew")
@@ -43,10 +42,22 @@ class _SettingBoxGenerator():
setting_box_frame_wrapper_fix_border2 = CTkFrame(setting_box_frame, corner_radius=0, width=0, height=0)
setting_box_frame_wrapper_fix_border2.grid(row=0, column=1, sticky="ns")
if for_var_label_text is not None:
self._setSettingBoxLabels(sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text)
# setting_box_item_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, width=0, height=0, fg_color="red")
if for_var_label_text is not None:
self._setSettingBoxLabels(sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text, expand_label_frame)
if expand_label_frame is True:
setting_box_frame_wrapper.grid_columnconfigure(0, weight=1, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH))
setting_box_frame_wrapper.grid(columnspan=3)
return setting_box_frame
setting_box_frame_wrapper.grid_columnconfigure(0, weight=0, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
setting_box_frame_wrapper.grid_columnconfigure(2, weight=1, minsize=int(self.settings.uism.MAIN_AREA_MIN_WIDTH / 2))
setting_box_item_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, width=0, height=0, fg_color=self.settings.ctm.SB__BG_COLOR)
if for_var_label_text is not None:
setting_box_item_frame.grid(row=0, column=2, padx=0, sticky="nsew")
@@ -57,7 +68,7 @@ class _SettingBoxGenerator():
return (setting_box_frame, setting_box_item_frame)
def _setSettingBoxLabels(self, sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text=None):
def _setSettingBoxLabels(self, sb__attr_name, setting_box_frame_wrapper, for_var_label_text, for_var_desc_text=None, expand_label_frame:bool=False):
setting_box_labels_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
setting_box_labels_frame.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
@@ -86,6 +97,9 @@ class _SettingBoxGenerator():
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__DESC_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.LABELS_DESC_TEXT_COLOR
)
if expand_label_frame is True:
setting_box_desc.configure(wraplength=self.settings.uism.MAIN_AREA_MIN_WIDTH)
setting_box_desc.grid(row=2, column=0, padx=0, pady=(self.settings.uism.SB__DESC_TOP_PADY,0), sticky="ew")
self.config_window.additional_widgets.append(setting_box_desc)
self.config_window.sb__widgets[sb__attr_name].desc_widget=setting_box_desc
@@ -93,6 +107,16 @@ class _SettingBoxGenerator():
self.config_window.sb__widgets[sb__attr_name].desc_widget=None
def createSettingBox_Labels(
self,
for_var_label_text, for_var_desc_text,
labels_attr_name,
):
setting_box_frame= self._createSettingBoxFrame(labels_attr_name, for_var_label_text, for_var_desc_text, expand_label_frame=True)
return setting_box_frame
def createSettingBoxDropdownMenu(
@@ -452,6 +476,210 @@ class _SettingBoxGenerator():
return setting_box_frame
def createSettingBoxMessageFormatEntries(self,
base_entry_attr_name,
entry_textvariable_0,
entry_textvariable_1,
entry_textvariable_2,
textvariable_0,
textvariable_1,
entry_bind__Any_KeyRelease,
entry_bind__FocusOut=None,
):
(setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(base_entry_attr_name)
all_wrapper = CTkFrame(setting_box_item_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
all_wrapper.grid(row=1, column=0, sticky="ew")
all_wrapper.grid_columnconfigure(0, weight=1)
example_box_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
example_box_wrapper.grid(row=0, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
entries_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
entries_wrapper.grid(row=1, column=0, pady=self.settings.uism.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY, sticky="ew")
swap_button_wrapper = CTkFrame(all_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
swap_button_wrapper.grid(row=2, column=0, sticky="e")
example_box_wrapper.grid_columnconfigure((0,2), weight=1)
example_frame_widget = CTkFrame(example_box_wrapper, corner_radius=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR, width=0, height=0)
example_frame_widget.grid(row=0, column=1)
example_frame_widget.grid_rowconfigure((0,2), weight=1)
example_frame_widget.grid_columnconfigure((0,2), weight=1)
example_label_widget = CTkLabel(
example_frame_widget,
textvariable=self.view_variable.VAR_LABEL_EXAMPLE_TEXT_MESSAGE_FORMAT,
anchor="center",
justify="center",
wraplength=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH,
height=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.LABELS_TEXT_COLOR,
)
example_label_widget.grid(row=1, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, pady=self.settings.uism.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY, sticky="ew")
self.config_window.additional_widgets.append(example_box_wrapper)
entry_textvariables = [entry_textvariable_0, entry_textvariable_1, entry_textvariable_2]
for i in range(3):
entry_widget = CTkEntry(
entries_wrapper,
text_color=self.settings.ctm.SB__ENTRY_TEXT_COLOR,
fg_color=self.settings.ctm.SB__ENTRY_BG_COLOR,
border_color=self.settings.ctm.SB__ENTRY_BORDER_COLOR,
height=self.settings.uism.SB__MESSAGE_FORMAT__ENTRY_HEIGHT,
textvariable=entry_textvariables[i],
justify="center",
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__ENTRY_FONT_SIZE, weight="normal"),
)
setattr(self.config_window, base_entry_attr_name + "_" + str(i), entry_widget)
if entry_bind__FocusOut is not None:
entry_widget.bind("<FocusOut>", entry_bind__FocusOut, "+")
label_frame_widget_0 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
label_frame_widget_0.grid_rowconfigure((0,2), weight=1)
label_frame_widget_0.grid_columnconfigure(0, weight=1)
label_widget_0 = CTkLabel(
label_frame_widget_0,
textvariable=textvariable_0,
anchor="center",
height=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.LABELS_TEXT_COLOR
)
label_widget_0.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
label_frame_widget_1 = CTkFrame(entries_wrapper, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0)
label_frame_widget_1.grid_rowconfigure((0,2), weight=1)
label_frame_widget_1.grid_columnconfigure(0, weight=1)
label_widget_1 = CTkLabel(
label_frame_widget_1,
textvariable=textvariable_1,
anchor="center",
height=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE, weight="normal"),
text_color=self.settings.ctm.LABELS_TEXT_COLOR
)
label_widget_1.grid(row=1, column=0, padx=0, pady=0, sticky="ew")
entries_wrapper.grid_columnconfigure((0,2,4), weight=1)
entries_wrapper.grid_columnconfigure((1,3), weight=0, uniform="message_format_fixed_labels")
entry_widget_0 = getattr(self.config_window, base_entry_attr_name+"_0")
entry_widget_1 = getattr(self.config_window, base_entry_attr_name+"_1")
entry_widget_2 = getattr(self.config_window, base_entry_attr_name+"_2")
entry_widget_0.grid(row=0, column=0, sticky="ew")
entry_widget_1.grid(row=0, column=2, sticky="ew")
entry_widget_2.grid(row=0, column=4, sticky="ew")
label_frame_widget_0.grid(row=0, column=1, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
label_frame_widget_1.grid(row=0, column=3, padx=self.settings.uism.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX, sticky="ew")
def adjusted_command__for_entry_bind__Any_KeyRelease(_e):
message_format = entry_widget_0.get() + textvariable_0.get() + entry_widget_1.get() + textvariable_1.get() + entry_widget_2.get()
entry_bind__Any_KeyRelease(message_format)
entry_widget_0.bind("<Any-KeyRelease>", adjusted_command__for_entry_bind__Any_KeyRelease)
entry_widget_1.bind("<Any-KeyRelease>", adjusted_command__for_entry_bind__Any_KeyRelease)
entry_widget_2.bind("<Any-KeyRelease>", adjusted_command__for_entry_bind__Any_KeyRelease)
swap_button = CTkFrame(swap_button_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR, cursor="hand2")
swap_button.grid(row=0, column=2, sticky="ew")
swap_button.grid_columnconfigure(0, weight=1)
swap_button_label_wrapper = CTkFrame(swap_button, corner_radius=0, fg_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR)
swap_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADX, pady=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADY, sticky="ew")
swap_button_label_wrapper.grid_columnconfigure((0,4), weight=1)
swap_button_label_wrapper.grid_rowconfigure((0,2), weight=1)
swap_button_label_0 = CTkLabel(
swap_button_label_wrapper,
textvariable=textvariable_0,
height=0,
corner_radius=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE, weight="normal"),
anchor="w",
text_color=self.settings.ctm.LABELS_TEXT_COLOR,
)
swap_button_label_0.grid(row=1, column=1)
swap_button_both_direction_arrow_img = CTkLabel(
swap_button_label_wrapper,
text=None,
height=0,
corner_radius=0,
image=CTkImage((self.settings.image_file.SWAP_ICON), size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_ARROWS_IMG_SIZE),
anchor="w",
text_color=self.settings.ctm.LABELS_TEXT_COLOR,
)
swap_button_both_direction_arrow_img.grid(row=1, column=2, padx=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_TEXT_PADX)
swap_button_label_1 = CTkLabel(
swap_button_label_wrapper,
textvariable=textvariable_1,
height=0,
corner_radius=0,
font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE, weight="normal"),
anchor="w",
text_color=self.settings.ctm.LABELS_TEXT_COLOR,
)
swap_button_label_1.grid(row=1, column=3)
def adjustedCommand():
callFunctionIfCallable(self.view_variable.CALLBACK_SWAP_MESSAGE_FORMAT_REQUIRED_TEXT)
bindButtonFunctionAndColor(
target_widgets=[
swap_button,
swap_button_label_wrapper,
swap_button_label_0,
swap_button_both_direction_arrow_img,
swap_button_label_1,
],
enter_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR,
leave_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR,
clicked_color=self.settings.ctm.SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR,
buttonReleasedFunction=lambda _e: adjustedCommand(),
)
return setting_box_frame
def createSettingBoxArrowSwitch(
self,
for_var_label_text, for_var_desc_text,

View File

@@ -5,7 +5,8 @@ from .._SettingBoxGenerator import _SettingBoxGenerator
def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_variable):
sbg = _SettingBoxGenerator(setting_box_wrapper, config_window, settings, view_variable)
createSettingBoxCheckbox = sbg.createSettingBoxCheckbox
createSettingBoxEntry = sbg.createSettingBoxEntry
createSettingBox_Labels = sbg.createSettingBox_Labels
createSettingBoxMessageFormatEntries = sbg.createSettingBoxMessageFormatEntries
# 元 checkbox_auto_clear_chatbox_callback
@@ -63,13 +64,25 @@ def createSettingBox_Others(setting_box_wrapper, config_window, settings, view_v
row+=1
config_window.sb__message_format = createSettingBoxEntry(
config_window.sb__message_format_labels = createSettingBox_Labels(
for_var_label_text=view_variable.VAR_LABEL_MESSAGE_FORMAT,
for_var_desc_text=view_variable.VAR_DESC_MESSAGE_FORMAT,
entry_attr_name="sb__entry_message_format",
entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_250,
labels_attr_name="sb__labels_message_format",
)
config_window.sb__message_format_labels.grid(row=row, pady=0)
row+=1
config_window.sb__message_format = createSettingBoxMessageFormatEntries(
base_entry_attr_name="sb__entry_message_format",
# entry_width=settings.uism.RESPONSIVE_UI_SIZE_INT_150,
entry_textvariable_0=view_variable.VAR_ENTRY_0_MESSAGE_FORMAT,
entry_textvariable_1=view_variable.VAR_ENTRY_1_MESSAGE_FORMAT,
entry_textvariable_2=view_variable.VAR_ENTRY_2_MESSAGE_FORMAT,
textvariable_0=view_variable.VAR_TEXT_REQUIRED_0_MESSAGE_FORMAT,
textvariable_1=view_variable.VAR_TEXT_REQUIRED_1_MESSAGE_FORMAT,
entry_bind__Any_KeyRelease=lambda value: entry_message_format_callback(value),
entry_textvariable=view_variable.VAR_MESSAGE_FORMAT,
# entry_textvariable=view_variable.VAR_MESSAGE_FORMAT,
entry_bind__FocusOut=view_variable.CALLBACK_FOCUS_OUT_MESSAGE_FORMAT,
)
config_window.sb__message_format.grid(row=row)
row+=1

View File

@@ -68,7 +68,7 @@ def createMainWindowWidgets(vrct_gui, settings, view_variable):
text=None,
corner_radius=0,
height=0,
image=CTkImage(settings.image_file.REFRESH_ICON.rotate(25), size=settings.uism.UPDATE_AVAILABLE_BUTTON_SIZE)
image=CTkImage(settings.image_file.REFRESH_UPDATE_ICON.rotate(25), size=settings.uism.UPDATE_AVAILABLE_BUTTON_SIZE)
)
vrct_gui.update_available_icon.grid(row=1, column=0, padx=(settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX, settings.uism.UPDATE_AVAILABLE_PADX_BETWEEN_LABEL_AND_ICON), pady=0)

View File

@@ -246,6 +246,13 @@ def _darkTheme(base_color):
SB__ADD_AND_DELETE_ABLE_LIST__VALUES_DELETED_BUTTON_CLICKED_BG_COLOR = base_color.DARK_900_COLOR,
SB__MESSAGE_FORMAT__EXAMPLE_BG_COLOR = "#3a4554", # from VRChat' chat display color
SB__MESSAGE_FORMAT__SWAP_BUTTON_COLOR = base_color.DARK_875_COLOR,
SB__MESSAGE_FORMAT__SWAP_BUTTON_HOVERED_COLOR = base_color.DARK_800_COLOR,
SB__MESSAGE_FORMAT__SWAP_BUTTON_CLICKED_COLOR = base_color.DARK_888_COLOR,
# Side menu
SIDE_MENU_BG_COLOR = base_color.DARK_950_COLOR,
@@ -289,11 +296,13 @@ def _darkTheme(base_color):
ARROW_LEFT = getImageFileFromUiUtils("arrow_left_white.png"),
ARROW_LEFT_DISABLED = getImageFileFromUiUtils("arrow_left_disabled.png"),
REFRESH_UPDATE_ICON = getImageFileFromUiUtils("refresh_update_icon.png"),
REFRESH_ICON = getImageFileFromUiUtils("refresh_icon.png"),
HELP_ICON = getImageFileFromUiUtils("help_icon_white.png"),
CANCEL_ICON = getImageFileFromUiUtils("cancel_icon.png"),
REDO_ICON = getImageFileFromUiUtils("redo_white.png"),
SWAP_ICON = getImageFileFromUiUtils("swap_icon.png"),
),
)

View File

@@ -302,6 +302,25 @@ class UiScalingManager():
self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_LEFT_PADX = (self._calculateUiSize(20), 0)
self.config_window.ADD_AND_DELETE_ABLE_LIST__ADD_BUTTON_FONT_SIZE = self._calculateUiSize(14)
self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_CORNER_RADIUS = self._calculateUiSize(16)
self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_IPADXY = self._calculateUiSize(10)
self.config_window.SB__MESSAGE_FORMAT__EXAMPLE_WRAP_LENGTH = self._calculateUiSize(300)
self.config_window.SB__MESSAGE_FORMAT__ENTRY_HEIGHT = self.config_window.SB__ENTRY_HEIGHT
self.config_window.SB__MESSAGE_FORMAT__REQUIRED_TEXT_PADX = self._calculateUiSize(10)
self.config_window.SB__MESSAGE_FORMAT__REQUIRED_TEXT_FONT_SIZE = self._calculateUiSize(16)
self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_ARROWS_IMG_SIZE = self.dupTuple(self._calculateUiSize(20))
self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADX = self._calculateUiSize(16)
self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_IPADY = self._calculateUiSize(6)
self.config_window.SB__MESSAGE_FORMAT__SWAP_BUTTON_FONT_SIZE = self._calculateUiSize(14)
self.config_window.SB__MESSAGE_FORMAT__SWAP_TEXT_PADX = self._calculateUiSize(10)
self.config_window.SB__MESSAGE_FORMAT__ENTRIES_BOTTOM_PADY = (0, self._calculateUiSize(14))
def _calculateUiSize(self, default_size, is_allowed_odd:bool=False, is_zero_allowed:bool=False):
size = calculateUiSize(default_size, self.SCALING_FLOAT, is_allowed_odd, is_zero_allowed)
return size