From 5b38db9557ef31372eaebe392bff663759e08c66 Mon Sep 17 00:00:00 2001 From: Sakamoto Shiina <68018796+ShiinaSakamoto@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:31:43 +0900 Subject: [PATCH] [Update] Main Window, Quick Settings Window: add VR Settings and it'll open the settings window that is for Overlay settings. --- config.py | 56 +++++- controller.py | 49 ++++- locales/en.yml | 2 +- model.py | 5 + utils.py | 3 + view.py | 84 +++++++- .../setting_box_vr/createSettingBox_Vr.py | 17 +- .../main_window/createMainWindowWidgets.py | 54 ++++++ .../QuickSettingsWindow.py | 179 ++++++++++++++++++ .../_CreateQuickSettingBox.py | 143 ++++++++++++++ vrct_gui/quick_settings_window/__init__.py | 1 + vrct_gui/vrct_gui.py | 8 + 12 files changed, 569 insertions(+), 32 deletions(-) create mode 100644 vrct_gui/quick_settings_window/QuickSettingsWindow.py create mode 100644 vrct_gui/quick_settings_window/_CreateQuickSettingBox.py create mode 100644 vrct_gui/quick_settings_window/__init__.py diff --git a/config.py b/config.py index 5a0986d9..de2d5b6d 100644 --- a/config.py +++ b/config.py @@ -737,16 +737,47 @@ class Config: saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @property - @json_serializable('ENABLE_NOTICE_OVERLAY') - def ENABLE_NOTICE_OVERLAY(self): - return self._ENABLE_NOTICE_OVERLAY + @json_serializable('OVERLAY_SETTINGS') + def OVERLAY_SETTINGS(self): + return self._OVERLAY_SETTINGS - @ENABLE_NOTICE_OVERLAY.setter - def ENABLE_NOTICE_OVERLAY(self, value): + @OVERLAY_SETTINGS.setter + def OVERLAY_SETTINGS(self, value): + if isinstance(value, dict) and set(value.keys()) == set(self.OVERLAY_SETTINGS.keys()): + for key, value in value.items(): + if isinstance(value, float): + self._OVERLAY_SETTINGS[key] = value + saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.OVERLAY_SETTINGS) + + @property + @json_serializable('ENABLE_OVERLAY_SMALL_LOG') + def ENABLE_OVERLAY_SMALL_LOG(self): + return self._ENABLE_OVERLAY_SMALL_LOG + + @ENABLE_OVERLAY_SMALL_LOG.setter + def ENABLE_OVERLAY_SMALL_LOG(self, value): if isinstance(value, bool): - self._ENABLE_NOTICE_OVERLAY = value + self._ENABLE_OVERLAY_SMALL_LOG = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + @property + @json_serializable('OVERLAY_SMALL_LOG_SETTINGS') + def OVERLAY_SMALL_LOG_SETTINGS(self): + return self._OVERLAY_SMALL_LOG_SETTINGS + + @OVERLAY_SMALL_LOG_SETTINGS.setter + def OVERLAY_SMALL_LOG_SETTINGS(self, value): + if isinstance(value, dict) and set(value.keys()) == set(self.OVERLAY_SMALL_LOG_SETTINGS.keys()): + for key, value in value.items(): + match (key): + case "x_pos" | "y_pos" | "depth": + if isinstance(value, float): + self._OVERLAY_SMALL_LOG_SETTINGS[key] = value + case "display_duration" | "fadeout_duration": + if isinstance(value, int): + self._OVERLAY_SMALL_LOG_SETTINGS[key] = value + saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.OVERLAY_SMALL_LOG_SETTINGS) + @property @json_serializable('OVERLAY_UI_TYPE') def OVERLAY_UI_TYPE(self): @@ -1023,7 +1054,18 @@ class Config: self._ENABLE_SEND_ONLY_TRANSLATED_MESSAGES = False self._SEND_MESSAGE_BUTTON_TYPE = "show" self._ENABLE_NOTICE_XSOVERLAY = False - self._ENABLE_NOTICE_OVERLAY = False + self._OVERLAY_SETTINGS = { + "opacity": 1.0, + "ui_scaling": 1.0, + } + self._ENABLE_OVERLAY_SMALL_LOG = False + self._OVERLAY_SMALL_LOG_SETTINGS = { + "x_pos": 0.0, + "y_pos": -0.41, + "depth": 1.0, + "display_duration": 5, + "fadeout_duration": 2, + } self._OVERLAY_UI_TYPE = "default" self._ENABLE_SEND_MESSAGE_TO_VRC = True self._ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC = False # Speaker2Chatbox diff --git a/controller.py b/controller.py index ef3079e8..c549a795 100644 --- a/controller.py +++ b/controller.py @@ -101,7 +101,7 @@ def sendMicMessage(message): translation = f" ({translation})" model.logger.info(f"[SENT] {message}{translation}") - # if config.ENABLE_NOTICE_OVERLAY is True: + # if config.ENABLE_OVERLAY_SMALL_LOG is True: # overlay_image = model.createOverlayImageShort(message, translation) # model.setOverlayImage(overlay_image) # overlay_image = model.createOverlayImageLong("send", message, translation) @@ -164,7 +164,7 @@ def receiveSpeakerMessage(message): if model.th_overlay is None: model.startOverlay() - if config.ENABLE_NOTICE_OVERLAY is True: + if config.ENABLE_OVERLAY_SMALL_LOG is True: overlay_image = model.createOverlayImageShort(message, translation) model.setOverlayImage(overlay_image) # overlay_image = model.createOverlayImageLong("receive", message, translation) @@ -245,7 +245,7 @@ def sendChatMessage(message): osc_message = messageFormatter("SEND", translation, message) model.oscSendMessage(osc_message) - # if config.ENABLE_NOTICE_OVERLAY is True: + # if config.ENABLE_OVERLAY_SMALL_LOG is True: # overlay_image = model.createOverlayImageShort(message, translation) # model.setOverlayImage(overlay_image) # overlay_image = model.createOverlayImageLong("send", message, translation) @@ -859,9 +859,42 @@ def callbackSetWhisperWeightType(value): view.showRestartButtonIfRequired() # VR Tab -def callbackSetEnableOverlayUi(value): - print("callbackSetEnableOverlayUi", value) - config.ENABLE_NOTICE_OVERLAY = value +def callbackSetOverlaySettings(value, set_type:str): + print("callbackSetOverlaySettings", value, set_type) + pre_settings = config.OVERLAY_SETTINGS + pre_settings[set_type] = value + config.OVERLAY_SETTINGS = pre_settings + match (set_type): + case "opacity": + pass + # update? + case "ui_scaling": + pass + # update? + +def callbackSetEnableOverlaySmallLog(value): + print("callbackSetEnableOverlaySmallLog", value) + config.ENABLE_OVERLAY_SMALL_LOG = value + +def callbackSetOverlaySmallLogSettings(value, set_type:str): + print("callbackSetOverlaySmallLogSettings", value, set_type) + pre_settings = config.OVERLAY_SMALL_LOG_SETTINGS + pre_settings[set_type] = value + config.OVERLAY_SMALL_LOG_SETTINGS = pre_settings + match (set_type): + case "x_pos": + model.updateOverlayPosition() + case "y_pos": + model.updateOverlayPosition() + case "depth": + pass + # update? + case "display_duration": + pass + # update? + case "fadeout_duration": + pass + # update? # Others Tab def callbackSetEnableAutoClearMessageBox(value): @@ -1104,7 +1137,9 @@ def createMainWindow(splash): "callback_set_whisper_weight_type": callbackSetWhisperWeightType, # VR Tab - "callback_set_enable_overlay_ui": callbackSetEnableOverlayUi, + "callback_set_overlay_settings": callbackSetOverlaySettings, + "callback_set_enable_overlay_small_log": callbackSetEnableOverlaySmallLog, + "callback_set_overlay_small_log_settings": callbackSetOverlaySmallLogSettings, # Others Tab "callback_set_enable_auto_clear_chatbox": callbackSetEnableAutoClearMessageBox, diff --git a/locales/en.yml b/locales/en.yml index 670d488f..edc1606d 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -207,7 +207,7 @@ config_window: recommended_model_template: "%{model_name} model (%{capacity}) (Recommended)" - enable_overlay_ui: + enable_overlay_small_log: label: OpenVR # desc: diff --git a/model.py b/model.py index 8e8db087..1a4fc247 100644 --- a/model.py +++ b/model.py @@ -587,4 +587,9 @@ class Model: self.th_overlay.stop() self.th_overlay = None + def updateOverlayPosition(self): + pos = (config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"], config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]) + if self.overlay.initFlag is True: + self.overlay.uiManager.posUpdate(pos) + model = Model() \ No newline at end of file diff --git a/utils.py b/utils.py index c2af3568..55d3c479 100644 --- a/utils.py +++ b/utils.py @@ -34,6 +34,9 @@ def generatePercentageStringsList(start:int, end:int, step:int): def intToPctStr(value:int): return f"{value}%" +def floatToPctStr(value:float): + return f"{int(value*100)}%" + def strPctToInt(value:str): return int(value.replace("%", "")) diff --git a/view.py b/view.py index b8dc7080..dfa47767 100644 --- a/view.py +++ b/view.py @@ -5,10 +5,10 @@ from tkinter import font as tk_font import webbrowser import i18n -from customtkinter import StringVar, IntVar, BooleanVar, get_appearance_mode +from customtkinter import StringVar, IntVar, DoubleVar, BooleanVar, get_appearance_mode from vrct_gui.ui_managers import ColorThemeManager, UiScalingManager, AboutVrctManager from vrct_gui import vrct_gui -from utils import callFunctionIfCallable, intToPctStr +from utils import callFunctionIfCallable, intToPctStr, floatToPctStr from config import config @@ -138,6 +138,65 @@ class View(): + + # VR Settings + VAR_VR_SETTINGS=StringVar(value="VR Settings"), + CALLBACK_SET_CALLBACK_OPEN_VR_SETTINGS_WINDOW=self._openVrSettingsWindow, + + + VAR_LABEL_OVERLAY_OPACITY=StringVar(value="Opacity"), + SLIDER_RANGE_OVERLAY_OPACITY=(0.1, 1.0), + NUMBER_OF_STEPS_OVERLAY_OPACITY=18, + VAR_OVERLAY_OPACITY=DoubleVar(value=config.OVERLAY_SETTINGS["opacity"]), + VAR_CURRENT_VALUE_OVERLAY_OPACITY=StringVar(value=floatToPctStr(config.OVERLAY_SETTINGS["opacity"])), + + VAR_LABEL_OVERLAY_UI_SCALING=StringVar(value="Ui Scaling"), + SLIDER_RANGE_OVERLAY_UI_SCALING=(0.4, 2.0), + NUMBER_OF_STEPS_OVERLAY_UI_SCALING=16, + VAR_OVERLAY_UI_SCALING=DoubleVar(value=config.OVERLAY_SETTINGS["ui_scaling"]), + VAR_CURRENT_VALUE_OVERLAY_UI_SCALING=StringVar(value=floatToPctStr(config.OVERLAY_SETTINGS["ui_scaling"])), + + + + CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS=None, + + VAR_LABEL_OVERLAY_SMALL_LOG_X_POS=StringVar(value="X_position"), + SLIDER_RANGE_OVERLAY_SMALL_LOG_X_POS=(-0.5, 0.5), + NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_POS=100, + VAR_OVERLAY_SMALL_LOG_X_POS=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"]), + VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["x_pos"]), + + VAR_LABEL_OVERLAY_SMALL_LOG_Y_POS=StringVar(value="Y_position"), + SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_POS=(-0.5, 0.5), + NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_POS=100, + VAR_OVERLAY_SMALL_LOG_Y_POS=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]), + VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["y_pos"]), + + VAR_LABEL_OVERLAY_SMALL_LOG_DEPTH=StringVar(value="Depth"), + SLIDER_RANGE_OVERLAY_SMALL_LOG_DEPTH=(0.5, 1.5), + NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DEPTH=100, + VAR_OVERLAY_SMALL_LOG_DEPTH=DoubleVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["depth"]), + VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DEPTH=StringVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["depth"]), + + VAR_LABEL_OVERLAY_SMALL_LOG_DISPLAY_DURATION=StringVar(value="Display Duration"), + SLIDER_RANGE_OVERLAY_SMALL_LOG_DISPLAY_DURATION=(1, 60), + NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DISPLAY_DURATION=59, + VAR_OVERLAY_SMALL_LOG_DISPLAY_DURATION=IntVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["display_duration"]), + VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION=StringVar(value=f"{config.OVERLAY_SMALL_LOG_SETTINGS['display_duration']} second(s)"), + + VAR_LABEL_OVERLAY_SMALL_LOG_FADEOUT_DURATION=StringVar(value="Fadeout Duration"), + SLIDER_RANGE_OVERLAY_SMALL_LOG_FADEOUT_DURATION=(0, 5), + NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_FADEOUT_DURATION=5, + VAR_OVERLAY_SMALL_LOG_FADEOUT_DURATION=IntVar(value=config.OVERLAY_SMALL_LOG_SETTINGS["fadeout_duration"]), + VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION=StringVar(value=f"{config.OVERLAY_SMALL_LOG_SETTINGS['fadeout_duration']} second(s)"), + + + + + + + + # Main Window # Sidebar # Sidebar Compact Mode @@ -418,11 +477,11 @@ class View(): # VR Tab - VAR_LABEL_ENABLE_OVERLAY_UI=StringVar(value=i18n.t("config_window.enable_overlay_ui.label")), - VAR_DESC_ENABLE_OVERLAY_UI=None, - # VAR_DESC_ENABLE_OVERLAY_UI=StringVar(value=i18n.t("config_window.enable_overlay_ui.desc")), - CALLBACK_SET_ENABLE_OVERLAY_UI=None, - VAR_ENABLE_OVERLAY_UI=BooleanVar(value=config.ENABLE_NOTICE_OVERLAY), + VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG=StringVar(value=i18n.t("config_window.enable_overlay_small_log.label")), + VAR_DESC_ENABLE_OVERLAY_SMALL_LOG=None, + # VAR_DESC_ENABLE_OVERLAY_SMALL_LOG=StringVar(value=i18n.t("config_window.enable_overlay_small_log.desc")), + CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG=None, + VAR_ENABLE_OVERLAY_SMALL_LOG=BooleanVar(value=config.ENABLE_OVERLAY_SMALL_LOG), # Others Tab @@ -690,7 +749,13 @@ class View(): self.view_variable.CALLBACK_SET_WHISPER_WEIGHT_TYPE=config_window_registers.get("callback_set_whisper_weight_type", None) # VR Tab - self.view_variable.CALLBACK_SET_ENABLE_OVERLAY_UI=config_window_registers.get("callback_set_enable_overlay_ui", None) + # VR Tab (Quick Settings) + self.view_variable.CALLBACK_SET_OVERLAY_SETTINGS=config_window_registers.get("callback_set_overlay_settings", None) + + self.view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG=config_window_registers.get("callback_set_enable_overlay_small_log", None) + # VR Tab (Quick Settings) + self.view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS=config_window_registers.get("callback_set_overlay_small_log_settings", None) + # Others Tab self.view_variable.CALLBACK_SET_ENABLE_AUTO_CLEAR_MESSAGE_BOX=config_window_registers.get("callback_set_enable_auto_clear_chatbox", None) @@ -1613,6 +1678,9 @@ class View(): self._closeMicWordFilterList() vrct_gui._closeConfigWindow() + def _openVrSettingsWindow(self): + vrct_gui.quick_settings_window.show() + # Window Control (Main Window Cover) def _openTheCoverOfMainWindow(self): vrct_gui.main_window_cover.show() diff --git a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py index 97704529..9ecf6f93 100644 --- a/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py +++ b/vrct_gui/config_window/widgets/createSideMenuAndSettingsBoxContainers/setting_box_containers/setting_box_vr/createSettingBox_Vr.py @@ -7,16 +7,15 @@ def createSettingBox_Vr(setting_box_wrapper, config_window, settings, view_varia createSettingBoxSwitch = sbg.createSettingBoxSwitch def switchEnableOverlayUiCallback(switch_widget): - callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_OVERLAY_UI, switch_widget.get()) - + callFunctionIfCallable(view_variable.CALLBACK_SET_ENABLE_OVERLAY_SMALL_LOG, switch_widget.get()) row=0 - config_window.sb__enable_overlay_ui = createSettingBoxSwitch( - for_var_label_text=view_variable.VAR_LABEL_ENABLE_OVERLAY_UI, - for_var_desc_text=view_variable.VAR_DESC_ENABLE_OVERLAY_UI, - switch_attr_name="sb__switch_enable_overlay_ui", - command=lambda: switchEnableOverlayUiCallback(config_window.sb__switch_enable_overlay_ui), - variable=view_variable.VAR_ENABLE_OVERLAY_UI + config_window.sb__enable_overlay_small_log = createSettingBoxSwitch( + for_var_label_text=view_variable.VAR_LABEL_ENABLE_OVERLAY_SMALL_LOG, + for_var_desc_text=view_variable.VAR_DESC_ENABLE_OVERLAY_SMALL_LOG, + switch_attr_name="sb__switch_enable_overlay_small_log", + command=lambda: switchEnableOverlayUiCallback(config_window.sb__switch_enable_overlay_small_log), + variable=view_variable.VAR_ENABLE_OVERLAY_SMALL_LOG ) - config_window.sb__enable_overlay_ui.grid(row=row, pady=0) + config_window.sb__enable_overlay_small_log.grid(row=row) row+=1 \ No newline at end of file diff --git a/vrct_gui/main_window/createMainWindowWidgets.py b/vrct_gui/main_window/createMainWindowWidgets.py index c09f4bca..ff9f5ef3 100644 --- a/vrct_gui/main_window/createMainWindowWidgets.py +++ b/vrct_gui/main_window/createMainWindowWidgets.py @@ -47,6 +47,60 @@ def createMainWindowWidgets(vrct_gui, settings, view_variable): # Main Top Bar Container - Right Side # start from 3 main_topbar_column=3 + + # VR Settings Button + vrct_gui.vr_settings_container = CTkFrame( + vrct_gui.main_topbar_container, + corner_radius=settings.uism.UPDATE_AVAILABLE_BUTTON_CORNER_RADIUS, + fg_color=settings.ctm.MAIN_BG_COLOR, + cursor="hand2", + ) + vrct_gui.vr_settings_container.grid(row=0, column=main_topbar_column, padx=settings.uism.UPDATE_AVAILABLE_BUTTON_PADX, pady=settings.uism.TOP_BAR_BUTTON_PADY, sticky="nsw") + # vrct_gui.vr_settings_container.grid_remove() + + + vrct_gui.vr_settings_container.grid_rowconfigure((0,2), weight=1) + + vrct_gui.vr_settings_icon = CTkLabel( + vrct_gui.vr_settings_container, + text=None, + corner_radius=0, + height=0, + image=CTkImage(settings.image_file.CONFIGURATION_ICON, size=settings.uism.UPDATE_AVAILABLE_BUTTON_SIZE) + ) + vrct_gui.vr_settings_icon.grid(row=1, column=0, padx=(settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX, settings.uism.UPDATE_AVAILABLE_PADX_BETWEEN_LABEL_AND_ICON), pady=0) + + + vrct_gui.vr_settings_label = CTkLabel( + vrct_gui.vr_settings_container, + textvariable=view_variable.VAR_VR_SETTINGS, + height=0, + corner_radius=0, + font=CTkFont(family=settings.FONT_FAMILY, size=settings.uism.UPDATE_AVAILABLE_BUTTON_FONT_SIZE, weight="normal"), + anchor="e", + text_color="#fff", + # text_color=settings.ctm.UPDATE_AVAILABLE_BUTTON_TEXT_COLOR, + ) + # This "right padx +1" is for fixing a bug that sticks out from the frame. I don't know why that happens... + vrct_gui.vr_settings_label.grid(row=1, column=1, padx=(0,settings.uism.UPDATE_AVAILABLE_BUTTON_IPADX+1), pady=0) + + + bindButtonFunctionAndColor( + target_widgets=[ + vrct_gui.vr_settings_container, + vrct_gui.vr_settings_label, + vrct_gui.vr_settings_icon, + ], + enter_color=settings.ctm.TOP_BAR_BUTTON_HOVERED_BG_COLOR, + leave_color=settings.ctm.TOP_BAR_BUTTON_BG_COLOR, + clicked_color=settings.ctm.TOP_BAR_BUTTON_CLICKED_BG_COLOR, + buttonReleasedFunction=lambda e: callFunctionIfCallable(view_variable.CALLBACK_SET_CALLBACK_OPEN_VR_SETTINGS_WINDOW), + ) + + + + + main_topbar_column+=1 # Update Available Button vrct_gui.update_available_container = CTkFrame( vrct_gui.main_topbar_container, diff --git a/vrct_gui/quick_settings_window/QuickSettingsWindow.py b/vrct_gui/quick_settings_window/QuickSettingsWindow.py new file mode 100644 index 00000000..e4f95446 --- /dev/null +++ b/vrct_gui/quick_settings_window/QuickSettingsWindow.py @@ -0,0 +1,179 @@ +from utils import callFunctionIfCallable, floatToPctStr + +from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame, CTkSlider +from ..ui_utils import getImagePath, setGeometryToCenterOfScreen, fadeInAnimation + +from ._CreateQuickSettingBox import _CreateQuickSettingBox + +class QuickSettingsWindow(CTkToplevel): + def __init__(self, vrct_gui, settings, view_variable): + super().__init__() + self.withdraw() + # self.overrideredirect(True) + self.configure(fg_color="#292a2d") + self.title("Quick Settings") + # self.wm_attributes("-toolwindow", True) + self.protocol("WM_DELETE_WINDOW", self.withdraw) + self.after(200, lambda: self.iconbitmap(getImagePath("vrct_logo_mark_black.ico"))) + + + self.settings = settings + + BG_HEIGHT= 220 + BG_WIDTH= 450 + BG_HEX_COLOR = "#292a2d" + + self.grid_columnconfigure(0, weight=1, minsize=400) + self.grid_rowconfigure(0, weight=1) + self.qsw_background = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR) + self.qsw_background.grid(sticky="nsew") + self.qsw_background.grid_columnconfigure(0, weight=1) + + + cqsb = _CreateQuickSettingBox(self.qsw_background, vrct_gui, settings, view_variable) + createSettingBoxSlider = cqsb.createSettingBoxSlider + + + + + + # Overlay General Settings + row=0 + def sliderCallback(e): + value = round(e,2) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SETTINGS, value, "opacity") + view_variable.VAR_CURRENT_VALUE_OVERLAY_OPACITY.set(floatToPctStr(value)) + + self.qsb__overlay_opacity = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_OPACITY, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_OPACITY, + slider_attr_name="qsb__overlay_opacity_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_OPACITY, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_OPACITY, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_OPACITY, + ) + self.qsb__overlay_opacity.grid(row=row) + + + row+=1 + def sliderCallback(e): + value = round(e,2) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SETTINGS, value, "ui_scaling") + view_variable.VAR_CURRENT_VALUE_OVERLAY_UI_SCALING.set(floatToPctStr(value)) + + self.qsb__overlay_ui_scaling = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_UI_SCALING, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_UI_SCALING, + slider_attr_name="qsb__overlay_ui_scaling_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_UI_SCALING, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_UI_SCALING, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_UI_SCALING, + ) + self.qsb__overlay_ui_scaling.grid(row=row) + + + + + row+=1 + # Overlay Small Log Settings + def sliderCallback(e): + value = round(e,2) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "x_pos") + view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS.set(str(value)) + + self.qsb__overlay_small_log_settings_x_pos = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_X_POS, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_X_POS, + slider_attr_name="qsb__overlay_small_log_settings_x_pos_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_X_POS, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_X_POS, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_SMALL_LOG_X_POS, + ) + self.qsb__overlay_small_log_settings_x_pos.grid(row=row) + + + row+=1 + def sliderCallback(e): + value = round(e,2) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "y_pos") + view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS.set(str(value)) + + self.qsb__overlay_small_log_settings_y_pos = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_Y_POS, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_Y_POS, + slider_attr_name="qsb__overlay_small_log_settings_y_pos_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_Y_POS, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_Y_POS, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_SMALL_LOG_Y_POS, + ) + self.qsb__overlay_small_log_settings_y_pos.grid(row=row) + + + row+=1 + def sliderCallback(e): + value = round(e,2) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "depth") + view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DEPTH.set(str(value)) + + self.qsb__overlay_small_log_settings_depth = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_DEPTH, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DEPTH, + slider_attr_name="qsb__overlay_small_log_settings_depth_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_DEPTH, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DEPTH, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_SMALL_LOG_DEPTH, + ) + self.qsb__overlay_small_log_settings_depth.grid(row=row) + + + row+=1 + def sliderCallback(e): + value = int(e) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "display_duration") + view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION.set(f"{value} second(s)") + + self.qsb__overlay_small_log_settings_display_duration = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_DISPLAY_DURATION, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_DISPLAY_DURATION, + slider_attr_name="qsb__overlay_small_log_settings_display_duration_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_DISPLAY_DURATION, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_DISPLAY_DURATION, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_SMALL_LOG_DISPLAY_DURATION, + ) + self.qsb__overlay_small_log_settings_display_duration.grid(row=row) + + + + row+=1 + def sliderCallback(e): + value = int(e) + callFunctionIfCallable(view_variable.CALLBACK_SET_OVERLAY_SMALL_LOG_SETTINGS, value, "fadeout_duration") + view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION.set(f"{value} second(s)") + + self.qsb__overlay_small_log_settings_fadeout_duration = createSettingBoxSlider( + for_var_label_text=view_variable.VAR_LABEL_OVERLAY_SMALL_LOG_FADEOUT_DURATION, + for_var_current_value=view_variable.VAR_CURRENT_VALUE_OVERLAY_SMALL_LOG_FADEOUT_DURATION, + slider_attr_name="qsb__overlay_small_log_settings_fadeout_duration_slider", + slider_range=view_variable.SLIDER_RANGE_OVERLAY_SMALL_LOG_FADEOUT_DURATION, + slider_number_of_steps=view_variable.NUMBER_OF_STEPS_OVERLAY_SMALL_LOG_FADEOUT_DURATION, + command=sliderCallback, + variable=view_variable.VAR_OVERLAY_SMALL_LOG_FADEOUT_DURATION, + ) + self.qsb__overlay_small_log_settings_fadeout_duration.grid(row=row) + + + + + + + def show(self): + self.attributes("-alpha", 0) + self.deiconify() + setGeometryToCenterOfScreen(root_widget=self) + fadeInAnimation(self, steps=5, interval=0.02) \ No newline at end of file diff --git a/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py b/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py new file mode 100644 index 00000000..01bb931a --- /dev/null +++ b/vrct_gui/quick_settings_window/_CreateQuickSettingBox.py @@ -0,0 +1,143 @@ +from typing import Union + +from utils import callFunctionIfCallable + +from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame, CTkSlider, CTkFont +from ..ui_utils import openImageKeepAspectRatio, getImageFileFromUiUtils, setGeometryToCenterOfScreen, fadeInAnimation + +class _CreateQuickSettingBox(): + def __init__(self, parent_frame, vrct_gui, settings, view_variable): + self.view_variable = view_variable + self.vrct_gui = vrct_gui + self.settings = settings + self.parent_frame = parent_frame + + + + + + + + + + def _createSettingBoxFrame(self, for_var_label_text=None, for_var_current_value=None): + setting_box_frame = CTkFrame(self.parent_frame, corner_radius=0, fg_color=self.settings.ctm.SB__BG_COLOR, width=0, height=0) + + setting_box_frame.grid(row=0, column=0, sticky="ew") + setting_box_frame.grid_columnconfigure(0, weight=1) + + + 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="nsew") + setting_box_frame_wrapper.grid_columnconfigure(0, weight=1) + + + # Labels + 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") + + setting_box_labels_frame.grid_rowconfigure((0,2), weight=1) + setting_box_labels_frame.grid_columnconfigure(1, weight=1) + setting_box_label = CTkLabel( + setting_box_labels_frame, + textvariable=for_var_label_text, + anchor="w", + height=0, + font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__LABEL_FONT_SIZE, weight="normal"), + text_color=self.settings.ctm.LABELS_TEXT_COLOR + ) + setting_box_label.grid(row=1, column=0, padx=0, pady=0, sticky="nse") + + + + setting_box_label = CTkLabel( + setting_box_labels_frame, + textvariable=for_var_current_value, + anchor="w", + height=0, + font=CTkFont(family=self.settings.FONT_FAMILY, size=self.settings.uism.SB__LABEL_FONT_SIZE, weight="normal"), + text_color=self.settings.ctm.LABELS_TEXT_COLOR + ) + setting_box_label.grid(row=1, column=2, padx=0, pady=0, sticky="nsw") + + + + + + + + + # Items + setting_box_item_frame = CTkFrame(setting_box_frame_wrapper, corner_radius=0, width=0, height=0, fg_color=self.settings.ctm.SB__BG_COLOR) + setting_box_item_frame.grid(row=1, column=0, padx=0, sticky="nsew") + + setting_box_item_frame.grid_rowconfigure((0,2), weight=1) + setting_box_item_frame.grid_columnconfigure(1, weight=1) + + return (setting_box_frame, setting_box_item_frame) + + + + + + + + + + + + + + + + + def createSettingBoxSlider( + self, + for_var_label_text, + for_var_current_value, + slider_attr_name, + slider_range, + command, + variable, + slider_number_of_steps: Union[int, + None] = None, + slider_bind__ButtonPress=None, + slider_bind__ButtonRelease=None, + sliderTooltipFormatter=None, + ): + + (setting_box_frame, setting_box_item_frame) = self._createSettingBoxFrame(for_var_label_text, for_var_current_value) + + + + slider_widget = CTkSlider( + setting_box_item_frame, + width=self.settings.uism.SB__SLIDER_WIDTH, + height=self.settings.uism.SB__SLIDER_HEIGHT, + from_=slider_range[0], + to=slider_range[1], + number_of_steps=slider_number_of_steps, + fg_color=self.settings.ctm.SB__SLIDER_BG_COLOR, + progress_color=self.settings.ctm.SB__SLIDER_PROGRESS_BG_COLOR, + button_color=self.settings.ctm.SB__SLIDER_BUTTON_COLOR, + button_hover_color=self.settings.ctm.SB__SLIDER_BUTTON_HOVERED_COLOR, + command=command, + variable=variable, + ) + setattr(self.vrct_gui, slider_attr_name, slider_widget) + + + slider_widget.grid(row=1, column=1, sticky="ew") + + if slider_bind__ButtonPress is not None: + def adjusted_slider_bind__ButtonPress(e): + command(e) + slider_bind__ButtonPress() + slider_widget.configure(command=adjusted_slider_bind__ButtonPress) + + if slider_bind__ButtonRelease is not None: + def adjusted_slider_bind__ButtonRelease(_e): + slider_bind__ButtonRelease() + slider_widget.bind("", adjusted_slider_bind__ButtonRelease, "+") + + return setting_box_frame \ No newline at end of file diff --git a/vrct_gui/quick_settings_window/__init__.py b/vrct_gui/quick_settings_window/__init__.py new file mode 100644 index 00000000..4ee26014 --- /dev/null +++ b/vrct_gui/quick_settings_window/__init__.py @@ -0,0 +1 @@ +from .QuickSettingsWindow import * \ No newline at end of file diff --git a/vrct_gui/vrct_gui.py b/vrct_gui/vrct_gui.py index 0a795436..0d669c09 100644 --- a/vrct_gui/vrct_gui.py +++ b/vrct_gui/vrct_gui.py @@ -12,6 +12,7 @@ from ._PrintToTextbox import _PrintToTextbox from .main_window import createMainWindowWidgets from .config_window import ConfigWindow +from .quick_settings_window import QuickSettingsWindow from .ui_utils import setDefaultActiveTab, setGeometryToCenterOfScreen, fadeInAnimation from utils import callFunctionIfCallable @@ -128,6 +129,13 @@ class VRCT_GUI(CTk): view_variable=self._view_variable ) + self.quick_settings_window = QuickSettingsWindow( + vrct_gui=self, + settings=self.settings.config_window, + view_variable=self._view_variable + ) + # self.quick_settings_window.show() + self.selectable_languages_window = _CreateSelectableLanguagesWindow( vrct_gui=self, settings=self.settings.selectable_language_window,