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] =?UTF-8?q?[Update]=20=E4=BD=BF=E7=94=A8=E3=83=87=E3=82=A3?= =?UTF-8?q?=E3=82=B9=E3=83=97=E3=83=AC=E3=82=A4=E3=82=B5=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E3=81=AE=E5=A4=A7=E3=81=8D=E3=81=95(=E9=AB=98=E3=81=95)?= =?UTF-8?q?=E3=82=88=E3=82=8A=E3=80=81VRCT=E8=B5=B7=E5=8B=95=E6=99=82?= =?UTF-8?q?=E3=81=AE=E3=82=A6=E3=82=A3=E3=83=B3=E3=83=89=E3=82=A6=E3=81=AE?= =?UTF-8?q?=E6=96=B9=E3=81=8C=E5=A4=A7=E3=81=8D=E3=81=84=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AE=E5=AF=BE=E5=BF=9C=E3=80=82UI=20Scaling=E3=82=9220%?= =?UTF-8?q?=E4=B8=8B=E3=81=92=E3=81=A6=E5=86=8D=E8=B5=B7=E5=8B=95=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=81=8B=E3=81=A9=E3=81=86=E3=81=8B=E3=81=AE=E7=A2=BA?= =?UTF-8?q?=E8=AA=8D=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB=E3=82=92=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=80=82=20=E3=81=9D=E3=82=8C=E3=81=AB=E3=81=A8?= =?UTF-8?q?=E3=82=82=E3=81=AA=E3=81=84=E7=A2=BA=E8=AA=8D=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=80=E3=83=AB=E3=81=AE=E6=B1=8E=E7=94=A8=E5=8C=96=E3=80=82?= =?UTF-8?q?=20=E3=81=95=E3=82=89=E3=81=AB=E3=81=9D=E3=82=8C=E3=81=AB?= =?UTF-8?q?=E4=BC=B4=E3=81=84=E8=A8=88=E7=AE=97=E3=81=AE=E9=83=BD=E5=90=88?= =?UTF-8?q?=E4=B8=8AUI=20Scaling=E3=81=8C40%=E3=81=8B=E3=82=89200%?= =?UTF-8?q?=E3=81=A710%=E5=88=BB=E3=81=BF=E3=81=AB=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=EF=BC=88=E9=81=B8=E6=8A=9E=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=EF=BC=89=E3=81=97=E3=81=BE=E3=81=97=E3=81=9F?= =?UTF-8?q?=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