From 239b0acce39f7cdf0fb0989b289a8032d28809a8 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Tue, 17 Oct 2023 15:03:17 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[Update]=20Config=20Window:=20message=20for?= =?UTF-8?q?mat's=20description.=20add=20sentence=20for=20mentioning=20that?= =?UTF-8?q?=20will=20be=20used=20Notification=20XSOverlay=20too.=20[Update?= =?UTF-8?q?]=20Config=20Window:=20Notification=20XSOverlay's=20label.=20?= =?UTF-8?q?=E6=97=A5=E6=9C=AC=E8=AA=9E=E7=89=88=E3=81=A7=E3=81=AE=E6=96=87?= =?UTF-8?q?=E8=A8=80=E5=A4=89=E6=9B=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.yml | 2 +- locales/ja.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index 1b182fec..b18fbd5d 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -130,7 +130,7 @@ config_window: 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." + 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. diff --git a/locales/ja.yml b/locales/ja.yml index 251edf09..7733ddc0 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -123,14 +123,14 @@ config_window: auto_clear_the_message_box: label: 送信後はチャットボックスを空にする notice_xsoverlay: - label: XSOverlayの通知機能を有効 (VR限定) + label: XSOverlayでの通知受け取り機能を有効 (VR限定) desc: 文字起こし(受信)されたメッセージをXSOverlayの機能を使って通知として受け取れます。 auto_export_message_logs: label: 会話ログを自動的に保存する desc: テキストファイルとしてログがlogsフォルダ内に保存されます。 message_format: label: 送信するメッセージのフォーマット - desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、\n[translation]が翻訳されたメッセージに置換されます。" + desc: "VRChatで相手に実際に見えるフォーマットを変更できます。\n[message]がメッセージに置換され、\n[translation]が翻訳されたメッセージに置換されます。\n※XSOverlayでの通知受け取り機能でも使われます。" send_message_to_vrc: label: VRChatにメッセージを送信する desc: "サポート対象外ですが、VRChatにメッセージを送信せずに使う方法があります。送信したい場合、この機能を有効にする事を忘れないでください。" From 7430bd25f80c11c88f90d84cc3e9368221e06b6e Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Tue, 17 Oct 2023 17:31:45 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[Update]=20Config=20Window:=20Mic/Speaker?= =?UTF-8?q?=20Record=20Timeout=E3=81=AA=E3=81=A9=E3=81=AE=E8=AA=AC?= =?UTF-8?q?=E6=98=8E=E6=96=87=E8=BF=BD=E5=8A=A0=E3=81=A8=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.yml | 13 ++++++------- locales/ja.yml | 13 ++++++------- view.py | 4 ++-- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index b18fbd5d..e8c33dab 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -92,15 +92,13 @@ config_window: 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." mic_record_timeout: label: Mic Record Timeout - desc: (Second(s)) - # desc: Duration in seconds for detecting silence and determining the end of audio input. + desc: Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s)) mic_phrase_timeout: label: Mic Phrase Timeout - desc: (Second(s)) - # desc: Duration in seconds for determining the end of audio input and transcribing it in one go. + desc: Transcription processing is performed at intervals of the specified number of seconds. mic_max_phrase: label: Mic Max Phrases - # desc: Once the minimum word count for transcription is reached, it will be send. + 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. 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" @@ -113,12 +111,13 @@ config_window: 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." speaker_record_timeout: label: Speaker Record Timeout - desc: (Second(s)) + desc: Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s)) speaker_phrase_timeout: label: Speaker Phrase Timeout - desc: (Second(s)) + desc: Transcription processing is performed at intervals of the specified number of seconds. 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. auto_clear_the_message_box: label: Auto Clear The Message Box diff --git a/locales/ja.yml b/locales/ja.yml index 7733ddc0..b638374e 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -92,15 +92,13 @@ config_window: desc_for_manual: スライダーを調整して入力感度を手動で決められます。マイクのアイコンを押すと、実際に声を入力し、音量を確認しながら調節できます。 mic_record_timeout: label: 入力が終了したとみなす無音時間 - desc: 単位は秒です。 - # desc: 無音を検出し、音声入力が終了したとみなす時間の長さです。(秒) + desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 mic_phrase_timeout: label: 一度に文字起こしする時間の長さ - desc: 単位は秒です。 - # desc: 一度に文字起こし処理をする音声時間の長さです。(秒) + desc: 設定された秒数ごとに文字起こし処理が行われます。 mic_max_phrase: label: 送信するまでに保持する単語数 - # desc: 文字起こしされた単語数を保持する最大値で、その数を超えると送信します。 + desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をVRChatへ送信し、ログに表示します。 mic_word_filter: label: ワードフィルター desc: "設定された単語を検出すると、その文章は送信されません。\n設定の例: AAA,BBB,CCC" @@ -113,12 +111,13 @@ config_window: desc_for_manual: スライダーを調整して入力感度を手動で決められます。ヘッドフォンのアイコンを押すと、実際に音声を聞き取り、音量を確認しながら調節できます。 speaker_record_timeout: label: 入力が終了したとみなす無音時間 - desc: 単位は秒です。 + desc: 無音を検出し、設定された秒数経過すると、音声入力が終了したとみなします。 speaker_phrase_timeout: label: 一度に文字起こしする時間の長さ - desc: 単位は秒です。 + desc: 設定された秒数ごとに文字起こし処理が行われます。 speaker_max_phrase: label: ログとして表示するまでに保持する単語数 + desc: 文字起こしされた単語数の下限値で、この数値を超えた場合のみ結果をログに表示します。 auto_clear_the_message_box: label: 送信後はチャットボックスを空にする diff --git a/view.py b/view.py index a9100c77..2a890af7 100644 --- a/view.py +++ b/view.py @@ -249,7 +249,7 @@ class View(): CALLBACK_FOCUS_OUT_MIC_PHRASE_TIMEOUT=self.setLatestConfigVariable_MicPhraseTimeout, VAR_LABEL_MIC_MAX_PHRASES=StringVar(value=i18n.t("config_window.mic_max_phrase.label")), - VAR_DESC_MIC_MAX_PHRASES=None, + VAR_DESC_MIC_MAX_PHRASES=StringVar(value=i18n.t("config_window.mic_max_phrase.desc")), CALLBACK_SET_MIC_MAX_PHRASES=None, VAR_MIC_MAX_PHRASES=StringVar(value=config.INPUT_MIC_MAX_PHRASES), CALLBACK_FOCUS_OUT_MIC_MAX_PHRASES=self.setLatestConfigVariable_MicMaxPhrases, @@ -286,7 +286,7 @@ class View(): CALLBACK_FOCUS_OUT_SPEAKER_PHRASE_TIMEOUT=self.setLatestConfigVariable_SpeakerPhraseTimeout, VAR_LABEL_SPEAKER_MAX_PHRASES=StringVar(value=i18n.t("config_window.speaker_max_phrase.label")), - VAR_DESC_SPEAKER_MAX_PHRASES=None, + VAR_DESC_SPEAKER_MAX_PHRASES=StringVar(value=i18n.t("config_window.speaker_max_phrase.desc")), CALLBACK_SET_SPEAKER_MAX_PHRASES=None, VAR_SPEAKER_MAX_PHRASES=StringVar(value=config.INPUT_SPEAKER_MAX_PHRASES), CALLBACK_FOCUS_OUT_SPEAKER_MAX_PHRASES=self.setLatestConfigVariable_SpeakerMaxPhrases, From 98ac2232a3aa7c88fa9a67206a54b6d07e5b85a9 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Tue, 17 Oct 2023 23:24:41 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[Refactor]=20Main=20Window:=20=E3=83=A1?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E7=94=BB=E9=9D=A2=E3=82=AB=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=81=AEgeometry=E8=A8=88=E7=AE=97=E3=82=92show=E6=99=82?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vrct_gui/_CreateWindowCover.py | 16 ++++++---------- vrct_gui/vrct_gui.py | 1 - 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/vrct_gui/_CreateWindowCover.py b/vrct_gui/_CreateWindowCover.py index f86929c1..d2fc22ce 100644 --- a/vrct_gui/_CreateWindowCover.py +++ b/vrct_gui/_CreateWindowCover.py @@ -22,16 +22,6 @@ class _CreateWindowCover(CTkToplevel): self.settings = settings self._view_variable = view_variable - - self.attach_window.update_idletasks() - self.x_pos = self.attach_window.winfo_rootx() - self.y_pos = self.attach_window.winfo_rooty() - self.width_new = self.attach_window.winfo_width() - self.height_new = self.attach_window.winfo_height() - - - self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos)) - self.grid_rowconfigure(0,weight=1) self.grid_columnconfigure(0,weight=1) self.cover_container = CTkFrame(self, corner_radius=0, fg_color="black", width=0, height=0) @@ -53,4 +43,10 @@ class _CreateWindowCover(CTkToplevel): def show(self): self.attributes("-alpha", 0) self.deiconify() + self.attach_window.update_idletasks() + self.x_pos = self.attach_window.winfo_rootx() + self.y_pos = self.attach_window.winfo_rooty() + self.width_new = self.attach_window.winfo_width() + self.height_new = self.attach_window.winfo_height() + self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos)) fadeInAnimation(self, steps=5, interval=0.005, max_alpha=0.5) diff --git a/vrct_gui/vrct_gui.py b/vrct_gui/vrct_gui.py index ae3b8fcb..0c3446d6 100644 --- a/vrct_gui/vrct_gui.py +++ b/vrct_gui/vrct_gui.py @@ -132,7 +132,6 @@ class VRCT_GUI(CTk): def _openConfigWindow(self, _e): callFunctionIfCallable(self._view_variable.CALLBACK_OPEN_CONFIG_WINDOW) - self._adjustToMainWindowGeometry() self.main_window_cover.show() self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID = self.bind("", self._adjustToMainWindowGeometry, "+") From 5abfe3c20bb59b318b29c20a77f336df6bf3bb52 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Wed, 18 Oct 2023 14:54:18 +0900 Subject: [PATCH 4/5] [Update] add Update Software Confirmation Modal Window. --- locales/en.yml | 7 + locales/ja.yml | 7 + view.py | 70 ++++++- vrct_gui/_CreateConfirmationModal.py | 173 ++++++++++++++++++ vrct_gui/_CreateWindowCover.py | 4 + vrct_gui/config_window/ConfigWindow.py | 8 +- .../main_window/widgets/create_sidebar.py | 3 +- vrct_gui/ui_managers/ColorThemeManager.py | 17 +- vrct_gui/ui_managers/UiScalingManager.py | 13 ++ vrct_gui/ui_utils/ui_utils.py | 16 ++ vrct_gui/vrct_gui.py | 17 +- 11 files changed, 316 insertions(+), 19 deletions(-) create mode 100644 vrct_gui/_CreateConfirmationModal.py diff --git a/locales/en.yml b/locales/en.yml index e8c33dab..457ea069 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -44,6 +44,13 @@ main_window: cover_message: The functionality is temporarily disabled until the settings window is closed. + confirmation_message: + update_software: "Download new version and restart automatically.\nIt'll take a while. Do it now?" + deny_update_software: Do it later + accept_update_software: Update and Restart + updating: Now updating... + + selectable_language_window: title_your_language: Select Your Language diff --git a/locales/ja.yml b/locales/ja.yml index b638374e..529e893c 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -44,6 +44,13 @@ main_window: cover_message: 設定画面が閉じられるまで、一時的に機能を停止しています。 + confirmation_message: + update_software: "新しいバージョンをダウンロードして再起動します。\n少し時間がかかるかもしれません。今すぐ行いますか?" + deny_update_software: 後でする + accept_update_software: アップデートして再起動 + updating: アップデート中... + + selectable_language_window: title_your_language: あなたの言語 diff --git a/view.py b/view.py index 2a890af7..ff57f89f 100644 --- a/view.py +++ b/view.py @@ -10,6 +10,7 @@ from languages import selectable_languages from customtkinter import StringVar, IntVar, BooleanVar, END as CTK_END, get_appearance_mode from vrct_gui.ui_managers import ColorThemeManager, ImageFileManager, UiScalingManager from vrct_gui import vrct_gui +from utils import callFunctionIfCallable from config import config @@ -73,20 +74,37 @@ class View(): **common_args ) + self.settings.update_confirmation_modal = SimpleNamespace( + ctm=all_ctm.update_confirmation_modal, + uism=all_uism.update_confirmation_modal, + **common_args + ) + self.view_variable = SimpleNamespace( # Common CALLBACK_RESTART_SOFTWARE=None, # Open Config Window + CALLBACK_CLICKED_OPEN_CONFIG_WINDOW_BUTTON=self._openConfigWindow, + CALLBACK_CLICKED_CLOSE_CONFIG_WINDOW_BUTTON=self._closeConfigWindow, CALLBACK_OPEN_CONFIG_WINDOW=None, CALLBACK_CLOSE_CONFIG_WINDOW=None, # Open Help and Information Page CALLBACK_CLICKED_HELP_AND_INFO=self.openWebPage_VrctDocuments, - # Open Update Page - CALLBACK_CLICKED_UPDATE_AVAILABLE=None, + # For Update Software + # Open Update Confirmation Modal + CALLBACK_CLICKED_UPDATE_AVAILABLE=self._showUpdateSoftwareConfirmationModal, + + CALLBACK_UPDATE_SOFTWARE=None, + CALLBACK_ACCEPT_UPDATE=self._startUpdateSoftware, + CALLBACK_DENY_UPDATE=self._deniedUpdateSoftware, + CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL=self._hideUpdateSoftwareConfirmationModal, + VAR_MESSAGE_CONFIRMATION_MODAL=StringVar(value=""), + VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON=StringVar(value=""), + VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON=StringVar(value=""), # Main Window @@ -137,7 +155,7 @@ class View(): # Main Window Cover - VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE=StringVar(value=i18n.t("main_window.cover_message")), + VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE=StringVar(value=""), # Selectable Language Window VAR_TITLE_LABEL_SELECTABLE_LANGUAGE=StringVar(value=""), @@ -353,7 +371,7 @@ class View(): if common_registers is not None: - self.view_variable.CALLBACK_CLICKED_UPDATE_AVAILABLE=common_registers.get("callback_update_software", None) + self.view_variable.CALLBACK_UPDATE_SOFTWARE=common_registers.get("callback_update_software", None) self.view_variable.CALLBACK_RESTART_SOFTWARE=common_registers.get("callback_restart_software", None) @@ -548,9 +566,49 @@ class View(): def foregroundOff(): vrct_gui.attributes("-topmost", False) + def _showUpdateSoftwareConfirmationModal(self): - @staticmethod - def _openTheCoverOfMainWindow(): + self.foregroundOffIfForegroundEnabled() + + + self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set("") + vrct_gui.main_window_cover.show() + + self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.update_software")) + self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON.set(i18n.t("main_window.confirmation_message.deny_update_software")) + self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_update_software")) + vrct_gui.update_confirmation_modal.show() + vrct_gui.update_confirmation_modal.focus_set() + + def _hideUpdateSoftwareConfirmationModal(self): + self._deniedUpdateSoftware() + self.foregroundOnIfForegroundEnabled() + + + def _startUpdateSoftware(self): + self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.updating")) + vrct_gui.update_confirmation_modal.hide_buttons() + vrct_gui.update() + vrct_gui.update_confirmation_modal.update() + callFunctionIfCallable(self.view_variable.CALLBACK_UPDATE_SOFTWARE) + + def _deniedUpdateSoftware(self): + vrct_gui.update_confirmation_modal.hide() + vrct_gui.main_window_cover.hide() + + + def _openConfigWindow(self): + self.view_variable.VAR_LABEL_MAIN_WINDOW_COVER_MESSAGE.set(i18n.t("main_window.cover_message")) + callFunctionIfCallable(self.view_variable.CALLBACK_OPEN_CONFIG_WINDOW) + vrct_gui._openConfigWindow() + + def _closeConfigWindow(self): + callFunctionIfCallable(self.view_variable.CALLBACK_CLOSE_CONFIG_WINDOW) + vrct_gui._closeConfigWindow() + + + + def _openTheCoverOfMainWindow(self): vrct_gui.main_window_cover.show() vrct_gui.config_window.lift() diff --git a/vrct_gui/_CreateConfirmationModal.py b/vrct_gui/_CreateConfirmationModal.py new file mode 100644 index 00000000..bc6fbd3c --- /dev/null +++ b/vrct_gui/_CreateConfirmationModal.py @@ -0,0 +1,173 @@ +from customtkinter import CTkToplevel, CTkFrame, CTkLabel, CTkFont + +from .ui_utils import fadeInAnimation, setGeometryToCenterOfTheWidget, bindButtonFunctionAndColor + +from utils import callFunctionIfCallable + +class _CreateConfirmationModal(CTkToplevel): + def __init__(self, attach_window, settings, view_variable): + super().__init__() + self.withdraw() + + + self.title("") + self.overrideredirect(True) + + self.wm_attributes("-toolwindow", True) + + self.attach_window = attach_window + self.settings = settings + self._view_variable = view_variable + + + # self.configure(fg_color="#ff7f50") + self.configure(fg_color=self.settings.ctm.FAKE_BORDER_COLOR) + self.protocol("WM_DELETE_WINDOW", lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL)) + + def fucusOutFunction(e): + if str(e.widget) != ".!_createconfirmationmodal": return + callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL) + + self.bind("", fucusOutFunction, "+") + + + self.grid_rowconfigure(0,weight=1) + self.grid_columnconfigure(0,weight=1) + self.modal_container = CTkFrame(self, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR) + self.modal_container.grid(row=0, column=0, padx=self.settings.uism.FAKE_BORDER_SIZE, pady=self.settings.uism.FAKE_BORDER_SIZE) + + + self.modal_contents_wrapper = CTkFrame(self.modal_container, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR) + self.modal_contents_wrapper.grid(row=0, column=0, padx=self.settings.uism.CONTENTS_WRAPPER, pady=self.settings.uism.CONTENTS_WRAPPER) + + + + self.modal_contents_wrapper.grid_rowconfigure(1, minsize=self.settings.uism.MARGIN_BETWEEN_MESSAGE_AND_BUTTONS) + + self.modal_message_label_wrapper = CTkFrame(self.modal_contents_wrapper, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR) + self.modal_message_label_wrapper.grid(row=0, column=0) + + self.modal_message_label_wrapper.grid_rowconfigure((0,2),weight=1) + self.modal_message_label_wrapper.grid_columnconfigure((0,2),weight=1) + + self.modal_message_label = CTkLabel( + self.modal_message_label_wrapper, + textvariable=self._view_variable.VAR_MESSAGE_CONFIRMATION_MODAL, + height=0, + corner_radius=0, + font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.MESSAGE_FONT_SIZE, weight="normal"), + anchor="w", + text_color=self.settings.ctm.MESSAGE_TEXT_COLOR, + ) + self.modal_message_label.grid(row=1, column=1) + + + + self.modal_buttons_container = CTkFrame(self.modal_contents_wrapper, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR) + self.modal_buttons_container.grid(row=2, column=0, sticky="nsew") + + self.modal_buttons_container.grid_rowconfigure((0,2),weight=1) + self.modal_buttons_container.grid_columnconfigure(0,weight=1) + + self.modal_buttons_wrapper = CTkFrame(self.modal_buttons_container, corner_radius=0, fg_color=self.settings.ctm.BG_COLOR) + self.modal_buttons_wrapper.grid(row=1, column=0, sticky="ew") + + + self.modal_buttons_wrapper.grid_columnconfigure(1, weight=1, minsize=self.settings.uism.BUTTONS_BETWEEN_PADDING) + self.modal_buttons_wrapper.grid_columnconfigure((0,2), weight=0, uniform="button_wrapper") + + + + + + self.deny_button = CTkFrame(self.modal_buttons_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.DENY_BUTTON_BG_COLOR, cursor="hand2") + self.deny_button.grid(row=0, column=0, sticky="ew") + + + self.deny_button.grid_columnconfigure(0, weight=1) + self.deny_button_label_wrapper = CTkFrame(self.deny_button, corner_radius=0, fg_color=self.settings.ctm.DENY_BUTTON_BG_COLOR) + self.deny_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.BUTTONS_IPADX, pady=self.settings.uism.BUTTONS_IPADY, sticky="ew") + + self.deny_button_label_wrapper.grid_columnconfigure((0,2), weight=1) + + + self.deny_button_label_wrapper.grid_columnconfigure(0, weight=1) + self.deny_button_label = CTkLabel( + self.deny_button_label_wrapper, + textvariable=self._view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON, + height=0, + corner_radius=0, + font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE, weight="normal"), + anchor="w", + text_color=self.settings.ctm.CONFIRMATION_BUTTONS_TEXT_COLOR, + ) + self.deny_button_label.grid(row=0, column=1) + + + + bindButtonFunctionAndColor( + target_widgets=[ + self.deny_button, + self.deny_button_label_wrapper, + self.deny_button_label, + ], + enter_color=settings.ctm.DENY_BUTTON_HOVERED_BG_COLOR, + leave_color=settings.ctm.DENY_BUTTON_BG_COLOR, + clicked_color=settings.ctm.DENY_BUTTON_CLICKED_BG_COLOR, + buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_DENY_UPDATE), + ) + + + + self.accept_button = CTkFrame(self.modal_buttons_wrapper, corner_radius=self.settings.uism.BUTTONS_CORNER_RADIUS, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR, cursor="hand2") + self.accept_button.grid(row=0, column=2, sticky="ew") + + + self.accept_button.grid_columnconfigure(0, weight=1) + self.accept_button_label_wrapper = CTkFrame(self.accept_button, corner_radius=0, fg_color=self.settings.ctm.ACCEPT_BUTTON_BG_COLOR) + self.accept_button_label_wrapper.grid(row=0, column=0, padx=self.settings.uism.BUTTONS_IPADX, pady=self.settings.uism.BUTTONS_IPADY, sticky="ew") + + self.accept_button_label_wrapper.grid_columnconfigure((0,2), weight=1) + self.accept_button_label = CTkLabel( + self.accept_button_label_wrapper, + textvariable=self._view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON, + height=0, + corner_radius=0, + font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE, weight="normal"), + anchor="w", + text_color=self.settings.ctm.CONFIRMATION_BUTTONS_TEXT_COLOR, + ) + self.accept_button_label.grid(row=0, column=1) + + + + bindButtonFunctionAndColor( + target_widgets=[ + self.accept_button, + self.accept_button_label_wrapper, + self.accept_button_label, + ], + enter_color=settings.ctm.ACCEPT_BUTTON_HOVERED_BG_COLOR, + leave_color=settings.ctm.ACCEPT_BUTTON_BG_COLOR, + clicked_color=settings.ctm.ACCEPT_BUTTON_CLICKED_BG_COLOR, + buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ACCEPT_UPDATE), + ) + + + def hide_buttons(self): + self.modal_buttons_wrapper.grid_remove() + + + def show(self): + self.attributes("-alpha", 0) + self.deiconify() + self.focus_set() + setGeometryToCenterOfTheWidget( + attach_widget=self.attach_window, + target_widget=self + ) + fadeInAnimation(self, steps=5, interval=0.005, max_alpha=1) + + + def hide(self): + self.withdraw() diff --git a/vrct_gui/_CreateWindowCover.py b/vrct_gui/_CreateWindowCover.py index d2fc22ce..caae57bd 100644 --- a/vrct_gui/_CreateWindowCover.py +++ b/vrct_gui/_CreateWindowCover.py @@ -50,3 +50,7 @@ class _CreateWindowCover(CTkToplevel): self.height_new = self.attach_window.winfo_height() self.geometry("{}x{}+{}+{}".format(self.width_new, self.height_new, self.x_pos, self.y_pos)) fadeInAnimation(self, steps=5, interval=0.005, max_alpha=0.5) + + + def hide(self): + self.withdraw() diff --git a/vrct_gui/config_window/ConfigWindow.py b/vrct_gui/config_window/ConfigWindow.py index 9e57aa3c..1e9d776d 100644 --- a/vrct_gui/config_window/ConfigWindow.py +++ b/vrct_gui/config_window/ConfigWindow.py @@ -11,17 +11,17 @@ class ConfigWindow(CTkToplevel): super().__init__() self.withdraw() + self.settings = settings + self._view_variable = view_variable # configure window self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico"))) - self.geometry(f"{settings.uism.DEFAULT_WIDTH}x{settings.uism.DEFAULT_HEIGHT}") + self.geometry(f"{self.settings.uism.DEFAULT_WIDTH}x{self.settings.uism.DEFAULT_HEIGHT}") self.configure(fg_color="#ff7f50") - self.protocol("WM_DELETE_WINDOW", vrct_gui._closeConfigWindow) + self.protocol("WM_DELETE_WINDOW", self._view_variable.CALLBACK_CLICKED_CLOSE_CONFIG_WINDOW_BUTTON) - self.settings = settings - self._view_variable = view_variable self.title(self._view_variable.VAR_CONFIG_WINDOW_TITLE.get()) # When the configuration window's compact mode is turned on, it will call `grid_remove()` on each widget appended to this array. In the opposite case, `grid()` will be called. diff --git a/vrct_gui/main_window/widgets/create_sidebar.py b/vrct_gui/main_window/widgets/create_sidebar.py index ac6efe14..9f30d269 100644 --- a/vrct_gui/main_window/widgets/create_sidebar.py +++ b/vrct_gui/main_window/widgets/create_sidebar.py @@ -1,6 +1,7 @@ from customtkinter import CTkFrame, CTkLabel, CTkImage from ...ui_utils import bindButtonFunctionAndColor +from utils import callFunctionIfCallable from ._create_sidebar import createSidebarFeatures, createSidebarLanguagesSettings @@ -59,5 +60,5 @@ def createSidebar(settings, main_window, view_variable): enter_color=settings.ctm.CONFIG_BUTTON_HOVERED_BG_COLOR, leave_color=settings.ctm.CONFIG_BUTTON_BG_COLOR, clicked_color=settings.ctm.CONFIG_BUTTON_CLICKED_BG_COLOR, - buttonReleasedFunction=main_window._openConfigWindow, + buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_CLICKED_OPEN_CONFIG_WINDOW_BUTTON), ) \ No newline at end of file diff --git a/vrct_gui/ui_managers/ColorThemeManager.py b/vrct_gui/ui_managers/ColorThemeManager.py index bdded267..6c3ffdb9 100644 --- a/vrct_gui/ui_managers/ColorThemeManager.py +++ b/vrct_gui/ui_managers/ColorThemeManager.py @@ -7,6 +7,7 @@ class ColorThemeManager(): self.selectable_language_window = SimpleNamespace() self.main_window_cover = SimpleNamespace() self.error_message_window = SimpleNamespace() + self.update_confirmation_modal = SimpleNamespace() # old one. But leave it here for now. # self.PRIMARY_100_COLOR = "#c4eac1" @@ -26,6 +27,7 @@ class ColorThemeManager(): self.PRIMARY_200_COLOR = "#8acac0" self.PRIMARY_300_COLOR = "#61b4a7" self.PRIMARY_400_COLOR = "#48a495" + self.PRIMARY_450_COLOR = "#429c8c" self.PRIMARY_500_COLOR = "#3b9483" self.PRIMARY_600_COLOR = "#368777" self.PRIMARY_650_COLOR = "#347f6f" @@ -42,7 +44,7 @@ class ColorThemeManager(): self.DARK_450_COLOR = "#b8b9bd" self.DARK_500_COLOR = "#a9aaae" self.DARK_600_COLOR = "#7f8084" - # self.DARK_650_COLOR = "#75767a" + self.DARK_650_COLOR = "#75767a" self.DARK_700_COLOR = "#6a6c6f" self.DARK_725_COLOR = "#636467" self.DARK_750_COLOR = "#5b5c5f" @@ -216,6 +218,19 @@ class ColorThemeManager(): self.main_window_cover.TEXT_COLOR = self.LIGHT_100_COLOR + self.update_confirmation_modal.MESSAGE_TEXT_COLOR = self.LIGHT_100_COLOR + self.update_confirmation_modal.FAKE_BORDER_COLOR = self.DARK_600_COLOR + self.update_confirmation_modal.BG_COLOR = self.DARK_800_COLOR + self.update_confirmation_modal.CONFIRMATION_BUTTONS_TEXT_COLOR = self.LIGHT_100_COLOR + + self.update_confirmation_modal.ACCEPT_BUTTON_BG_COLOR = self.PRIMARY_600_COLOR + self.update_confirmation_modal.ACCEPT_BUTTON_HOVERED_BG_COLOR = self.PRIMARY_450_COLOR + self.update_confirmation_modal.ACCEPT_BUTTON_CLICKED_BG_COLOR = self.PRIMARY_750_COLOR + self.update_confirmation_modal.DENY_BUTTON_BG_COLOR = self.DARK_750_COLOR + self.update_confirmation_modal.DENY_BUTTON_HOVERED_BG_COLOR = self.DARK_700_COLOR + self.update_confirmation_modal.DENY_BUTTON_CLICKED_BG_COLOR = self.DARK_825_COLOR + + # Common self.config_window.BASIC_TEXT_COLOR = self.main.BASIC_TEXT_COLOR self.config_window.LABELS_TEXT_COLOR = self.config_window.BASIC_TEXT_COLOR diff --git a/vrct_gui/ui_managers/UiScalingManager.py b/vrct_gui/ui_managers/UiScalingManager.py index 56d5cafd..488b91ed 100644 --- a/vrct_gui/ui_managers/UiScalingManager.py +++ b/vrct_gui/ui_managers/UiScalingManager.py @@ -10,6 +10,7 @@ class UiScalingManager(): self.selectable_language_window = SimpleNamespace() self.main_window_cover = SimpleNamespace() self.error_message_window = SimpleNamespace() + self.update_confirmation_modal = SimpleNamespace() self._calculatedUiSizes() @@ -142,6 +143,18 @@ class UiScalingManager(): self.main_window_cover.TEXT_FONT_SIZE = self._calculateUiSize(20) + + self.update_confirmation_modal.FAKE_BORDER_SIZE = self._calculateUiSize(1, is_allowed_odd=True) + self.update_confirmation_modal.CONTENTS_WRAPPER = self._calculateUiSize(20) + self.update_confirmation_modal.MARGIN_BETWEEN_MESSAGE_AND_BUTTONS = self._calculateUiSize(40) + self.update_confirmation_modal.MESSAGE_FONT_SIZE = self._calculateUiSize(20) + self.update_confirmation_modal.CONFIRMATION_BUTTONS_TEXT_FONT_SIZE = self._calculateUiSize(18) + self.update_confirmation_modal.BUTTONS_BETWEEN_PADDING = self._calculateUiSize(100) + self.update_confirmation_modal.BUTTONS_CORNER_RADIUS = self._calculateUiSize(6) + self.update_confirmation_modal.BUTTONS_IPADX = self._calculateUiSize(10) + self.update_confirmation_modal.BUTTONS_IPADY = self._calculateUiSize(6) + + # Config Window self.config_window.DEFAULT_WIDTH = self._calculateUiSize(1080) self.config_window.DEFAULT_HEIGHT = self._calculateUiSize(680) diff --git a/vrct_gui/ui_utils/ui_utils.py b/vrct_gui/ui_utils/ui_utils.py index e1d4886a..5bdcaebe 100644 --- a/vrct_gui/ui_utils/ui_utils.py +++ b/vrct_gui/ui_utils/ui_utils.py @@ -225,6 +225,22 @@ def setGeometryToCenterOfScreen(root_widget): root_widget.geometry(str(geometry_width)+"x"+str(geometry_height)+"+"+str((sw-geometry_width)//2)+"+"+str((sh-geometry_height)//2)) +def setGeometryToCenterOfTheWidget(attach_widget, target_widget): + target_widget.update() + target_widget.update() + current_window_x = attach_widget.winfo_rootx() + current_window_y = attach_widget.winfo_rooty() + current_window_width = attach_widget.winfo_width() + current_window_height = attach_widget.winfo_height() + desired_window_width = target_widget.winfo_width() + desired_window_height = target_widget.winfo_height() + + desired_window_x = int((current_window_x + current_window_width / 2) - (desired_window_width / 2)) + desired_window_y = int((current_window_y + current_window_height / 2) - (desired_window_height / 2)) + + target_widget.geometry(str(desired_window_width) + "x" + str(desired_window_height) + "+" + str(desired_window_x) + "+" + str(desired_window_y)) + + def fadeInAnimation(root_widget, steps:int=10, interval:float=0.1, max_alpha:float=1): alpha_steps = 100 alpha_steps*=max_alpha diff --git a/vrct_gui/vrct_gui.py b/vrct_gui/vrct_gui.py index 0c3446d6..fbcb9043 100644 --- a/vrct_gui/vrct_gui.py +++ b/vrct_gui/vrct_gui.py @@ -7,6 +7,7 @@ from ._CreateErrorWindow import _CreateErrorWindow from ._CreateDropdownMenuWindow import _CreateDropdownMenuWindow from ._changeMainWindowWidgetsStatus import _changeMainWindowWidgetsStatus from ._changeConfigWindowWidgetsStatus import _changeConfigWindowWidgetsStatus +from ._CreateConfirmationModal import _CreateConfirmationModal from ._printToTextbox import _printToTextbox from .main_window import createMainWindowWidgets @@ -113,9 +114,15 @@ class VRCT_GUI(CTk): message_bg_color=self.settings.config_window.ctm.SB__ERROR_MESSAGE_BG_COLOR, message_text_color=self.settings.config_window.ctm.SB__ERROR_MESSAGE_TEXT_COLOR, - ) + self.update_confirmation_modal = _CreateConfirmationModal( + attach_window=self.toplevel_wrapper, + settings=self.settings.update_confirmation_modal, + view_variable=self._view_variable + ) + + # self.update() # self.geometry("{}x{}".format(self.winfo_width(), self.winfo_height())) @@ -129,9 +136,7 @@ class VRCT_GUI(CTk): self.destroy() - def _openConfigWindow(self, _e): - callFunctionIfCallable(self._view_variable.CALLBACK_OPEN_CONFIG_WINDOW) - + def _openConfigWindow(self): self.main_window_cover.show() self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID = self.bind("", self._adjustToMainWindowGeometry, "+") @@ -151,11 +156,9 @@ class VRCT_GUI(CTk): self.config_window.focus_set() def _closeConfigWindow(self): - callFunctionIfCallable(self._view_variable.CALLBACK_CLOSE_CONFIG_WINDOW) - self.config_window.withdraw() - self.main_window_cover.withdraw() + self.main_window_cover.hide() self.unbind("", self.BIND_CONFIGURE_ADJUSTED_GEOMETRY_FUNC_ID) self.unbind("", self.BIND_UNMAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID) self.unbind("", self.BIND_MAP_DETECT_MAIN_WINDOW_STATE_FUNC_ID) From 7cc7b5a7c38c96d9f83574d00a583e59b8278aa7 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Wed, 18 Oct 2023 18:46:10 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[Update]=20=E4=BD=BF=E7=94=A8=E3=83=87?= =?UTF-8?q?=E3=82=A3=E3=82=B9=E3=83=97=E3=83=AC=E3=82=A4=E3=82=B5=E3=82=A4?= =?UTF-8?q?=E3=82=BA=E3=81=AE=E5=A4=A7=E3=81=8D=E3=81=95(=E9=AB=98?= =?UTF-8?q?=E3=81=95)=E3=82=88=E3=82=8A=E3=80=81VRCT=E8=B5=B7=E5=8B=95?= =?UTF-8?q?=E6=99=82=E3=81=AE=E3=82=A6=E3=82=A3=E3=83=B3=E3=83=89=E3=82=A6?= =?UTF-8?q?=E3=81=AE=E6=96=B9=E3=81=8C=E5=A4=A7=E3=81=8D=E3=81=84=E5=A0=B4?= =?UTF-8?q?=E5=90=88=E3=81=AE=E5=AF=BE=E5=BF=9C=E3=80=82UI=20Scaling?= =?UTF-8?q?=E3=82=9220%=E4=B8=8B=E3=81=92=E3=81=A6=E5=86=8D=E8=B5=B7?= =?UTF-8?q?=E5=8B=95=E3=81=99=E3=82=8B=E3=81=8B=E3=81=A9=E3=81=86=E3=81=8B?= =?UTF-8?q?=E3=81=AE=E7=A2=BA=E8=AA=8D=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB?= =?UTF-8?q?=E3=82=92=E8=A1=A8=E7=A4=BA=E3=80=82=20=E3=81=9D=E3=82=8C?= =?UTF-8?q?=E3=81=AB=E3=81=A8=E3=82=82=E3=81=AA=E3=81=84=E7=A2=BA=E8=AA=8D?= =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB=E3=81=AE=E6=B1=8E=E7=94=A8?= =?UTF-8?q?=E5=8C=96=E3=80=82=20=E3=81=95=E3=82=89=E3=81=AB=E3=81=9D?= =?UTF-8?q?=E3=82=8C=E3=81=AB=E4=BC=B4=E3=81=84=E8=A8=88=E7=AE=97=E3=81=AE?= =?UTF-8?q?=E9=83=BD=E5=90=88=E4=B8=8AUI=20Scaling=E3=81=8C40%=E3=81=8B?= =?UTF-8?q?=E3=82=89200%=E3=81=A710%=E5=88=BB=E3=81=BF=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C=EF=BC=88=E9=81=B8=E6=8A=9E=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=EF=BC=89=E3=81=97=E3=81=BE=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.py | 3 +- locales/en.yml | 3 ++ locales/ja.yml | 4 ++ utils.py | 8 ++- view.py | 75 +++++++++++++++++++++------- vrct_gui/_CreateConfirmationModal.py | 42 ++++++++++++---- vrct_gui/_CreateWindowCover.py | 2 +- vrct_gui/ui_utils/ui_utils.py | 2 +- vrct_gui/vrct_gui.py | 15 ++++++ 9 files changed, 121 insertions(+), 33 deletions(-) diff --git a/config.py b/config.py index d7e6db4c..f8953bd3 100644 --- a/config.py +++ b/config.py @@ -8,6 +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 json_serializable_vars = {} def json_serializable(var_name): @@ -220,7 +221,7 @@ class Config: @UI_SCALING.setter def UI_SCALING(self, value): - if value in ["40%", "60%", "80%", "90%", "100%", "110%", "120%", "150%", "200%"]: + if value in generatePercentageStringsList(start=40,end=200, step=10): self._UI_SCALING = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) diff --git a/locales/en.yml b/locales/en.yml index 457ea069..e1616fd8 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -50,6 +50,9 @@ main_window: accept_update_software: Update and Restart updating: Now updating... + detected_over_ui_size: "Current UI Size: %{current_ui_size}\nVRCT's window size may be larger than your display size.\n* Depending on your display size, you may need to adjust it multiple times." + deny_adjust_ui_size: "Keep it at this size" + accept_adjust_ui_size: "Set it smaller and restart" selectable_language_window: diff --git a/locales/ja.yml b/locales/ja.yml index 529e893c..6f807f52 100644 --- a/locales/ja.yml +++ b/locales/ja.yml @@ -50,6 +50,10 @@ main_window: accept_update_software: アップデートして再起動 updating: アップデート中... + detected_over_ui_size: "現在のUI サイズ: %{current_ui_size}\nVRCTのウィンドウサイズが、お使いのディスプレイサイズより大きい可能性があります。\n※ディスプレイサイズによっては、何度か再設定が必要な場合があります。" + deny_adjust_ui_size: このサイズのままで良い + accept_adjust_ui_size: 小さく設定して再起動 + selectable_language_window: diff --git a/utils.py b/utils.py index 5ed7bcd2..6efe6d0a 100644 --- a/utils.py +++ b/utils.py @@ -20,4 +20,10 @@ def isEven(number): def makeEven(number, minus:bool=False): if minus is True: return number if isEven(number) else number - 1 - return number if isEven(number) else number + 1 \ No newline at end of file + return number if isEven(number) else number + 1 + +def generatePercentageStringsList(start=40, end=200, step=10): + strings = [] + for percent in range(start, end + 1, step): + strings.append(f"{percent}%") + return strings \ No newline at end of file diff --git a/view.py b/view.py index ff57f89f..e6c0ed51 100644 --- a/view.py +++ b/view.py @@ -10,7 +10,7 @@ from languages import selectable_languages from customtkinter import StringVar, IntVar, BooleanVar, END as CTK_END, get_appearance_mode from vrct_gui.ui_managers import ColorThemeManager, ImageFileManager, UiScalingManager from vrct_gui import vrct_gui -from utils import callFunctionIfCallable +from utils import callFunctionIfCallable, generatePercentageStringsList from config import config @@ -83,7 +83,17 @@ class View(): self.view_variable = SimpleNamespace( # Common CALLBACK_RESTART_SOFTWARE=None, + CALLBACK_UPDATE_SOFTWARE=None, + CALLBACK_WHEN_DETECT_WINDOW_OVERED_SIZE=self._showDisplayOverUiSizeConfirmationModal, + + # Confirmation Modal + CALLBACK_HIDE_CONFIRMATION_MODAL=None, + CALLBACK_ACCEPTED_CONFIRMATION_MODAL=None, + CALLBACK_DENIED_CONFIRMATION_MODAL=None, + VAR_MESSAGE_CONFIRMATION_MODAL=StringVar(value=""), + VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON=StringVar(value=""), + VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON=StringVar(value=""), # Open Config Window CALLBACK_CLICKED_OPEN_CONFIG_WINDOW_BUTTON=self._openConfigWindow, @@ -94,17 +104,9 @@ class View(): # Open Help and Information Page CALLBACK_CLICKED_HELP_AND_INFO=self.openWebPage_VrctDocuments, - # For Update Software # Open Update Confirmation Modal CALLBACK_CLICKED_UPDATE_AVAILABLE=self._showUpdateSoftwareConfirmationModal, - CALLBACK_UPDATE_SOFTWARE=None, - CALLBACK_ACCEPT_UPDATE=self._startUpdateSoftware, - CALLBACK_DENY_UPDATE=self._deniedUpdateSoftware, - CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL=self._hideUpdateSoftwareConfirmationModal, - VAR_MESSAGE_CONFIRMATION_MODAL=StringVar(value=""), - VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON=StringVar(value=""), - VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON=StringVar(value=""), # Main Window @@ -203,7 +205,7 @@ class View(): VAR_LABEL_UI_SCALING=StringVar(value=i18n.t("config_window.ui_size.label")), VAR_DESC_UI_SCALING=None, - LIST_UI_SCALING=["40%", "60%", "80%", "90%", "100%", "110%", "120%", "150%", "200%"], + LIST_UI_SCALING=generatePercentageStringsList(start=40,end=200, step=10), CALLBACK_SET_UI_SCALING=None, VAR_UI_SCALING=StringVar(value=config.UI_SCALING), @@ -566,24 +568,64 @@ class View(): def foregroundOff(): vrct_gui.attributes("-topmost", False) - def _showUpdateSoftwareConfirmationModal(self): + def _showDisplayOverUiSizeConfirmationModal(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._hideConfirmationModal + self.view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL=self._adjustUiSizeAndRestart + self.view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL=self._hideConfirmationModal + + self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.detected_over_ui_size", current_ui_size=config.UI_SCALING)) + self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON.set(i18n.t("main_window.confirmation_message.deny_adjust_ui_size")) + self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_adjust_ui_size")) + + vrct_gui.update_confirmation_modal.show(hide_title_bar=False, close_when_focusout=False) + + + def _adjustUiSizeAndRestart(self): + current_percentage = int(config.UI_SCALING.replace("%","")) + target_percentage = current_percentage - 20 + if target_percentage >= 40 and str(target_percentage) + "%" in self.view_variable.LIST_UI_SCALING: + 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) + + # ※Below 40% of the UI size is not supported, and we cannot handle it at this time. + + + + + + + + + + def _showUpdateSoftwareConfirmationModal(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._hideConfirmationModal + self.view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL=self._startUpdateSoftware + self.view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL=self._hideConfirmationModal + self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.update_software")) self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_DENY_BUTTON.set(i18n.t("main_window.confirmation_message.deny_update_software")) self.view_variable.VAR_LABEL_CONFIRMATION_MODAL_ACCEPT_BUTTON.set(i18n.t("main_window.confirmation_message.accept_update_software")) vrct_gui.update_confirmation_modal.show() - vrct_gui.update_confirmation_modal.focus_set() - def _hideUpdateSoftwareConfirmationModal(self): - self._deniedUpdateSoftware() + def _hideConfirmationModal(self): + vrct_gui.update_confirmation_modal.hide() + vrct_gui.main_window_cover.hide() self.foregroundOnIfForegroundEnabled() + # def _deniedUpdateSoftware(self): + # self._hideConfirmationModal() def _startUpdateSoftware(self): self.view_variable.VAR_MESSAGE_CONFIRMATION_MODAL.set(i18n.t("main_window.confirmation_message.updating")) @@ -592,9 +634,6 @@ class View(): vrct_gui.update_confirmation_modal.update() callFunctionIfCallable(self.view_variable.CALLBACK_UPDATE_SOFTWARE) - def _deniedUpdateSoftware(self): - vrct_gui.update_confirmation_modal.hide() - vrct_gui.main_window_cover.hide() def _openConfigWindow(self): diff --git a/vrct_gui/_CreateConfirmationModal.py b/vrct_gui/_CreateConfirmationModal.py index bc6fbd3c..ece22e2a 100644 --- a/vrct_gui/_CreateConfirmationModal.py +++ b/vrct_gui/_CreateConfirmationModal.py @@ -12,9 +12,11 @@ class _CreateConfirmationModal(CTkToplevel): self.title("") self.overrideredirect(True) - self.wm_attributes("-toolwindow", True) + self.BIND_FOCUS_OUT_FUNC_ID=None + + self.attach_window = attach_window self.settings = settings self._view_variable = view_variable @@ -22,13 +24,8 @@ class _CreateConfirmationModal(CTkToplevel): # self.configure(fg_color="#ff7f50") self.configure(fg_color=self.settings.ctm.FAKE_BORDER_COLOR) - self.protocol("WM_DELETE_WINDOW", lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL)) + self.protocol("WM_DELETE_WINDOW", lambda: callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL)) - def fucusOutFunction(e): - if str(e.widget) != ".!_createconfirmationmodal": return - callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_UPDATE_CONFIRMATION_MODAL) - - self.bind("", fucusOutFunction, "+") self.grid_rowconfigure(0,weight=1) @@ -114,7 +111,7 @@ class _CreateConfirmationModal(CTkToplevel): enter_color=settings.ctm.DENY_BUTTON_HOVERED_BG_COLOR, leave_color=settings.ctm.DENY_BUTTON_BG_COLOR, clicked_color=settings.ctm.DENY_BUTTON_CLICKED_BG_COLOR, - buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_DENY_UPDATE), + buttonReleasedFunction=lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_DENIED_CONFIRMATION_MODAL), ) @@ -150,7 +147,7 @@ class _CreateConfirmationModal(CTkToplevel): enter_color=settings.ctm.ACCEPT_BUTTON_HOVERED_BG_COLOR, leave_color=settings.ctm.ACCEPT_BUTTON_BG_COLOR, clicked_color=settings.ctm.ACCEPT_BUTTON_CLICKED_BG_COLOR, - buttonReleasedFunction=lambda _e: callFunctionIfCallable(view_variable.CALLBACK_ACCEPT_UPDATE), + buttonReleasedFunction=lambda _e: callFunctionIfCallable(self._view_variable.CALLBACK_ACCEPTED_CONFIRMATION_MODAL), ) @@ -158,16 +155,39 @@ class _CreateConfirmationModal(CTkToplevel): self.modal_buttons_wrapper.grid_remove() - def show(self): + def show(self, hide_title_bar:bool=True, close_when_focusout:bool=True): + if hide_title_bar is False: + self.overrideredirect(False) + else: + self.overrideredirect(True) + + self.close_when_focusout = close_when_focusout + if self.close_when_focusout is True: + self.BIND_FOCUS_OUT_FUNC_ID = self.bind("", self.focusOutFunction, "+") + else: + self._grab_set() + + self.attributes("-alpha", 0) self.deiconify() - self.focus_set() setGeometryToCenterOfTheWidget( attach_widget=self.attach_window, target_widget=self ) fadeInAnimation(self, steps=5, interval=0.005, max_alpha=1) + self.focus_set() def hide(self): + if self.BIND_FOCUS_OUT_FUNC_ID is not None: + self.unbind("", self.BIND_FOCUS_OUT_FUNC_ID) + self.withdraw() + self.grab_release() + + def focusOutFunction(self, e): + if str(e.widget) != ".!_createconfirmationmodal": return + callFunctionIfCallable(self._view_variable.CALLBACK_HIDE_CONFIRMATION_MODAL) + + def _grab_set(self): + self.grab_set() diff --git a/vrct_gui/_CreateWindowCover.py b/vrct_gui/_CreateWindowCover.py index caae57bd..9ab8c4ee 100644 --- a/vrct_gui/_CreateWindowCover.py +++ b/vrct_gui/_CreateWindowCover.py @@ -17,7 +17,7 @@ class _CreateWindowCover(CTkToplevel): self.configure(fg_color="#ff7f50") - self.protocol("WM_DELETE_WINDOW", lambda e: self.withdraw()) + self.protocol("WM_DELETE_WINDOW", lambda: self.withdraw()) self.settings = settings self._view_variable = view_variable diff --git a/vrct_gui/ui_utils/ui_utils.py b/vrct_gui/ui_utils/ui_utils.py index 5bdcaebe..bf64a985 100644 --- a/vrct_gui/ui_utils/ui_utils.py +++ b/vrct_gui/ui_utils/ui_utils.py @@ -226,7 +226,7 @@ def setGeometryToCenterOfScreen(root_widget): def setGeometryToCenterOfTheWidget(attach_widget, target_widget): - target_widget.update() + attach_widget.update() target_widget.update() current_window_x = attach_widget.winfo_rootx() current_window_y = attach_widget.winfo_rooty() diff --git a/vrct_gui/vrct_gui.py b/vrct_gui/vrct_gui.py index fbcb9043..2337e23c 100644 --- a/vrct_gui/vrct_gui.py +++ b/vrct_gui/vrct_gui.py @@ -54,6 +54,11 @@ class VRCT_GUI(CTk): self._enableMainWindowSidebarCompactMode() fadeInAnimation(self, steps=5, interval=0.008) + + if self._isOverWindowSizeCheck() is True: + callFunctionIfCallable(self._view_variable.CALLBACK_WHEN_DETECT_WINDOW_OVERED_SIZE) + + def _createGUI(self, settings, view_variable): self.settings = settings self._view_variable = view_variable @@ -282,4 +287,14 @@ class VRCT_GUI(CTk): pass + def _isOverWindowSizeCheck(self): + 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: + return False + vrct_gui = VRCT_GUI() \ No newline at end of file