diff --git a/controller.py b/controller.py index 686113bc..f9e9a5b3 100644 --- a/controller.py +++ b/controller.py @@ -876,9 +876,11 @@ def initSetConfigByExeArguments(): config.OSC_PORT = int(args.port) view.setGuiVariable_OscPort(config.OSC_PORT) -def createMainWindow(): +def createMainWindow(splash): + splash.toProgress(1) # create GUI view.createGUI() + splash.toProgress(2) # init config initSetConfigByExeArguments() @@ -908,6 +910,8 @@ def createMainWindow(): if config.ENABLE_LOGGER is True: model.startLogger() + splash.toProgress(3) # Last one. + # set UI and callback view.register( common_registers={ diff --git a/img/VRCT_starting_up.png b/img/VRCT_starting_up.png new file mode 100644 index 00000000..9feac583 Binary files /dev/null and b/img/VRCT_starting_up.png differ diff --git a/img/vrchat_chatbox_trasnlator_transcription.png b/img/vrchat_chatbox_trasnlator_transcription.png new file mode 100644 index 00000000..9f2e401e Binary files /dev/null and b/img/vrchat_chatbox_trasnlator_transcription.png differ diff --git a/img/vrct_logo_mark_white_square.png b/img/vrct_logo_mark_white_square.png new file mode 100644 index 00000000..bfb6f60d Binary files /dev/null and b/img/vrct_logo_mark_white_square.png differ diff --git a/main.py b/main.py index c160383d..4810cbe5 100644 --- a/main.py +++ b/main.py @@ -12,8 +12,9 @@ if __name__ == "__main__": if config.USE_TRANSLATION_FEATURE is True: downloadCTranslate2Weight(config.PATH_LOCAL, config.WEIGHT_TYPE, splash.updateDownloadProgress) + splash.toProgress(0) import controller - controller.createMainWindow() + controller.createMainWindow(splash) splash.destroySplash() controller.showMainWindow() diff --git a/vrct_gui/splash_window/SplashWindow.py b/vrct_gui/splash_window/SplashWindow.py index c7af9802..3a1084c0 100644 --- a/vrct_gui/splash_window/SplashWindow.py +++ b/vrct_gui/splash_window/SplashWindow.py @@ -1,4 +1,7 @@ -from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar +import math +import time + +from customtkinter import CTkImage, CTkLabel, CTkToplevel, CTkProgressBar, CTkFrame from ..ui_utils import openImageKeepAspectRatio, getImageFileFromUiUtils, setGeometryToCenterOfScreen, fadeInAnimation class SplashWindow(CTkToplevel): @@ -10,53 +13,228 @@ class SplashWindow(CTkToplevel): self.title("SplashWindow") self.wm_attributes("-toolwindow", True) - self.is_showed_progressbar = False + self.is_showed_weight_download_progressbar = False - sw=self.winfo_screenwidth() + BG_HEIGHT= 220 + BG_WIDTH= 450 + BG_HEX_COLOR = "#292a2d" - pw=int(sw/4) + self.grid_columnconfigure(0, weight=1) + self.grid_rowconfigure(0, weight=1) + self.splash_background = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=BG_WIDTH, height=BG_HEIGHT) + self.splash_background.grid() - self.grid_columnconfigure((0,2), weight=1) - self.grid_rowconfigure((0,2), weight=1) - (img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"), pw) - label = CTkLabel( + + self.progressbar_wrapper = CTkFrame(self, corner_radius=0, fg_color=BG_HEX_COLOR, width=0, height=0) + self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center") + self.progressbar_wrapper.rowconfigure(0, minsize=BG_HEIGHT) + + PROGRESSBAR_HEIGHT = 3 + PROGRESSBAR_WIDTH = 60 + PROGRESSBAR_RIGHT_PADX = 38 + ALL_PROGRESSBAR_WIDTH = (PROGRESSBAR_WIDTH + PROGRESSBAR_RIGHT_PADX)*3 + PROGRESSBAR_WIDTH + WHITE_HEX_COLOR = "#f2f2f2" + VRCT_HEX_COLOR = "#48a495" + column = 0 + + for i in range(3): + progressbar = CTkProgressBar( + self.progressbar_wrapper, + height=PROGRESSBAR_HEIGHT, + width=PROGRESSBAR_WIDTH, + corner_radius=0, + fg_color=BG_HEX_COLOR, + progress_color=WHITE_HEX_COLOR, + ) + progressbar.set(0) + progressbar.grid(row=0, column=column, padx=(0,PROGRESSBAR_RIGHT_PADX)) + + setattr(self, "progressbar_" + str(i), progressbar) + column+=1 + + + self.progressbar_3 = CTkProgressBar( + self.progressbar_wrapper, + height=PROGRESSBAR_HEIGHT, + width=PROGRESSBAR_WIDTH, + corner_radius=0, + fg_color=BG_HEX_COLOR, + progress_color=VRCT_HEX_COLOR, + ) + self.progressbar_3.set(0) + self.progressbar_3.grid(row=0, column=column, padx=0) + + + + self.chato_img_mask_frame = CTkFrame(self.progressbar_wrapper, corner_radius=0, fg_color=BG_HEX_COLOR, width=ALL_PROGRESSBAR_WIDTH, height=0) + self.chato_img_mask_frame.place(relx=1, rely=0.49, relheight=0.5, anchor="se") + + + CHATO_POSITION = int( (ALL_PROGRESSBAR_WIDTH-(PROGRESSBAR_WIDTH/2)) + 2) + (self.chato_img, self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_mark_white_square.png"), int(PROGRESSBAR_WIDTH - (PROGRESSBAR_WIDTH/5))) + + self.chato_img_label = CTkLabel( + self.chato_img_mask_frame, + text=None, + height=0, + fg_color=BG_HEX_COLOR, + image=CTkImage(self.chato_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT)) + ) + self.chato_img_label.place(x=CHATO_POSITION, rely=1, relwidth=1, anchor="n") + + + + (img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_starting_up.png"), 100) + self.starting_up_text_label = CTkLabel( self, text=None, height=0, - fg_color="#292a2d", + fg_color=BG_HEX_COLOR, image=CTkImage(img, size=(desired_width, height)) ) - label.grid(row=1, column=1, padx=int(desired_width/7), pady=int(height/3)) + self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center") - self.progressbar_widget = CTkProgressBar( + + (self.vrct_second_text_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrchat_chatbox_trasnlator_transcription.png"), 280) + self.vrct_second_text_img_label = CTkLabel( self, - height=10, + text=None, + height=0, + fg_color=BG_HEX_COLOR, + image=CTkImage(self.vrct_second_text_img, size=(desired_width, height)) + ) + self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se") + + + + + (self.vrct_logo_img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("vrct_logo_for_dark_mode.png"), 280) + self.vrct_logo_img_label = CTkLabel( + self, + text=None, + height=0, + fg_color=BG_HEX_COLOR, + image=CTkImage(self.vrct_logo_img, size=(desired_width, height)) + ) + + + + + self.weight_download_progressbar_widget = CTkProgressBar( + self, + height=8, corner_radius=0, fg_color="#4b4c4f", - progress_color="#48a495", + progress_color=VRCT_HEX_COLOR, ) - self.progressbar_widget.set(0) + self.weight_download_progressbar_widget.set(0) (img, desired_width, height) = openImageKeepAspectRatio(getImageFileFromUiUtils("VRCT_now_downloading.png"), 320) - self.text_label = CTkLabel( + self.weight_download_text_label = CTkLabel( self, text=None, height=0, - fg_color="#292a2d", + fg_color=BG_HEX_COLOR, image=CTkImage(img, size=(desired_width, height)) ) + def toProgress(self, num:int): + if self.is_showed_weight_download_progressbar is True: + self.vrct_logo_img_label.place_forget() + self.weight_download_progressbar_widget.place_forget() + self.weight_download_text_label.place_forget() + + self.progressbar_wrapper.place(relx=0.5, rely=0.5, anchor="center") + self.starting_up_text_label.place(relx=0.5, rely=0.7, anchor="center") + self.vrct_second_text_img_label.place(relx=0.98, rely=0.98, anchor="se") + self.update() + + target_progressbar_widget = getattr(self, "progressbar_" + str(num)) + + # This animation process' base code was made by ChatGPT. + start_time = time.time() + DURATION = 0.2 + while True: + elapsed_time = time.time() - start_time + progress = min(elapsed_time / DURATION, 1.0) + eased_progress = 1 - math.pow(1 - progress, 6) + + + target_progressbar_widget.set(eased_progress) + self.update_idletasks() + + if elapsed_time >= DURATION: + break + + time.sleep(0.01) + + DURATION = 0.2 + if num == 3: + start_time = time.time() + while True: + elapsed_time = time.time() - start_time + progress = min(elapsed_time / DURATION, 1.0) + eased_progress = 1 - math.pow(1 - progress, 6) + + # angleが45度未満の場合は0から45度に進むようにし、45度以上の場合は45度に固定 + angle = min(45, 45 * eased_progress) + angle = -angle + + rotated_img = self.rotateImage(self.chato_img, angle) + self.chato_img_label.configure(image=CTkImage(rotated_img, size=(self.CHATO_IMG_WIDTH, self.CHATO_IMG_HEIGHT))) + + rely = 1.0 - eased_progress * 0.6 + self.chato_img_label.place_configure(rely=rely) + self.update() + + if elapsed_time >= DURATION: + break + + time.sleep(0.01) + + def rotateImage(self, image, angle): + # 画像を回転させる + rotated_image = image.rotate(angle, expand=True) + return rotated_image + + # This making gradient color process was made by ChatGPT. + def generateGradientColor(self, value): + # 0の時の色と1の時の色を指定 + color_start = [242, 242, 242] # RGB values for #f2f2f2 + color_end = [72, 164, 149] # RGB values for #48a495 + + # 補完色を計算 + interpolated_color = [ + int(start + (end - start) * value) for start, end in zip(color_start, color_end) + ] + + # RGB値を0から255の範囲にクリップ + interpolated_color = [max(0, min(255, val)) for val in interpolated_color] + + # RGBを16進数に変換 + hex_color = "#{:02x}{:02x}{:02x}".format(*interpolated_color) + + return hex_color + def updateDownloadProgress(self, progress:float): - if self.is_showed_progressbar is False: - self.progressbar_widget.place(relwidth=0.9, relx=0.5, rely=0.9, anchor="s") - self.text_label.place(relx=0.98, rely=0.98, anchor="se") - self.is_showed_progressbar = True + if self.is_showed_weight_download_progressbar is False: + self.vrct_second_text_img_label.place_forget() + self.progressbar_wrapper.place_forget() + self.starting_up_text_label.place_forget() - self.progressbar_widget.set(progress) + self.vrct_logo_img_label.place(relx=0.5, rely=0.4, anchor="center") + self.weight_download_progressbar_widget.place(relwidth=0.9, relx=0.5, rely=0.84, anchor="s") + self.weight_download_text_label.place(relx=0.98, rely=0.96, anchor="se") + self.is_showed_weight_download_progressbar = True + self.update() + + progress_color = self.generateGradientColor(progress) + self.weight_download_progressbar_widget.configure(progress_color=progress_color) + self.weight_download_progressbar_widget.set(progress) self.update_idletasks()