v0.2.8
This commit is contained in:
parent
8eb8690493
commit
f62ad9aae9
11
CTkToolTip/__init__.py
Normal file
11
CTkToolTip/__init__.py
Normal file
@ -0,0 +1,11 @@
|
||||
"""
|
||||
CustomTkinter ToolTip
|
||||
Author: Akash Bora
|
||||
This is a tooltip/pop-up widget made with customtkinter.
|
||||
Homepage: https://github.com/Akascape/CTkToolTip
|
||||
"""
|
||||
|
||||
__version__ = '0.8'
|
||||
|
||||
from .ctk_tooltip import CTkToolTip
|
||||
|
BIN
CTkToolTip/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
CTkToolTip/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
CTkToolTip/__pycache__/ctk_tooltip.cpython-311.pyc
Normal file
BIN
CTkToolTip/__pycache__/ctk_tooltip.cpython-311.pyc
Normal file
Binary file not shown.
227
CTkToolTip/ctk_tooltip.py
Normal file
227
CTkToolTip/ctk_tooltip.py
Normal file
@ -0,0 +1,227 @@
|
||||
"""
|
||||
CTkToolTip Widget
|
||||
version: 0.8
|
||||
"""
|
||||
|
||||
import time
|
||||
import sys
|
||||
import customtkinter
|
||||
import threading
|
||||
from tkinter import Toplevel, Frame
|
||||
|
||||
class CTkToolTip(Toplevel):
|
||||
"""
|
||||
Creates a ToolTip (pop-up) widget for customtkinter.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
widget: any = None,
|
||||
message: str = None,
|
||||
delay: float = 0.2,
|
||||
follow: bool = True,
|
||||
x_offset: int = +20,
|
||||
y_offset: int = +10,
|
||||
bg_color: str = None,
|
||||
corner_radius: int = 10,
|
||||
border_width: int = 0,
|
||||
border_color: str = None,
|
||||
alpha: float = 0.95,
|
||||
padding: tuple = (10, 2),
|
||||
is_noti: bool = False,
|
||||
noti_event: any = None,
|
||||
noti_dur: float = 3.0,
|
||||
**message_kwargs):
|
||||
|
||||
super().__init__()
|
||||
|
||||
self.widget = widget
|
||||
|
||||
if not is_noti:
|
||||
self.withdraw()
|
||||
|
||||
# Disable ToolTip's title bar
|
||||
self.overrideredirect(True)
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
self.transparent_color = self.widget._apply_appearance_mode(
|
||||
customtkinter.ThemeManager.theme["CTkToplevel"]["fg_color"])
|
||||
self.attributes("-transparentcolor", self.transparent_color)
|
||||
self.transient()
|
||||
elif sys.platform.startswith("darwin"):
|
||||
self.transparent_color = 'systemTransparent'
|
||||
self.attributes("-transparent", True)
|
||||
self.transient(self.master)
|
||||
else:
|
||||
self.transparent_color = '#000001'
|
||||
corner_radius = 0
|
||||
self.transient()
|
||||
|
||||
self.resizable(width=True, height=True)
|
||||
|
||||
# Make the background transparent
|
||||
self.config(background=self.transparent_color)
|
||||
|
||||
# StringVar instance for msg string
|
||||
self.messageVar = customtkinter.StringVar()
|
||||
self.message = message
|
||||
self.messageVar.set(self.message)
|
||||
|
||||
self.noti_dur = noti_dur
|
||||
self.is_noti = is_noti
|
||||
self.delay = delay
|
||||
self.follow = follow
|
||||
self.x_offset = x_offset
|
||||
self.y_offset = y_offset
|
||||
self.corner_radius = corner_radius
|
||||
self.alpha = alpha
|
||||
self.border_width = border_width
|
||||
self.padding = padding
|
||||
self.bg_color = customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] if bg_color is None else bg_color
|
||||
self.border_color = border_color
|
||||
self.disable = False
|
||||
|
||||
# visibility status of the ToolTip inside|outside|visible
|
||||
self.status = "outside"
|
||||
self.last_moved = 0
|
||||
self.attributes('-alpha', self.alpha)
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
if self.widget._apply_appearance_mode(self.bg_color) == self.transparent_color:
|
||||
self.transparent_color = "#000001"
|
||||
self.config(background=self.transparent_color)
|
||||
self.attributes("-transparentcolor", self.transparent_color)
|
||||
|
||||
# Add the message widget inside the tooltip
|
||||
self.transparent_frame = Frame(self, bg=self.transparent_color)
|
||||
self.transparent_frame.pack(padx=0, pady=0, fill="both", expand=True)
|
||||
|
||||
self.frame = customtkinter.CTkFrame(self.transparent_frame, bg_color=self.transparent_color,
|
||||
corner_radius=self.corner_radius,
|
||||
border_width=self.border_width, fg_color=self.bg_color,
|
||||
border_color=self.border_color)
|
||||
self.frame.pack(padx=0, pady=0, fill="both", expand=True)
|
||||
|
||||
self.message_label = customtkinter.CTkLabel(self.frame, textvariable=self.messageVar, **message_kwargs)
|
||||
self.message_label.pack(fill="both", padx=self.padding[0] + self.border_width,
|
||||
pady=self.padding[1] + self.border_width, expand=True)
|
||||
|
||||
if self.widget.winfo_name() != "tk":
|
||||
if self.frame.cget("fg_color") == self.widget.cget("bg_color"):
|
||||
if not bg_color:
|
||||
self._top_fg_color = self.frame._apply_appearance_mode(
|
||||
customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"])
|
||||
if self._top_fg_color != self.transparent_color:
|
||||
self.frame.configure(fg_color=self._top_fg_color)
|
||||
|
||||
# Add bindings to the widget without overriding the existing ones
|
||||
if self.is_noti:
|
||||
if noti_event:
|
||||
self.on_enter(noti_event)
|
||||
else:
|
||||
self.widget.bind("<Button-1>", self.on_enter, add="+")
|
||||
else:
|
||||
self.widget.bind("<Enter>", self.on_enter, add="+")
|
||||
self.widget.bind("<Leave>", self.on_leave, add="+")
|
||||
self.widget.bind("<Motion>", self.on_enter, add="+")
|
||||
self.widget.bind("<B1-Motion>", self.on_enter, add="+")
|
||||
self.widget.bind("<Destroy>", lambda _: self.hide(), add="+")
|
||||
|
||||
def show(self) -> None:
|
||||
"""
|
||||
Enable the widget.
|
||||
"""
|
||||
self.disable = False
|
||||
|
||||
def on_enter(self, event) -> None:
|
||||
"""
|
||||
Processes motion within the widget including entering and moving.
|
||||
"""
|
||||
|
||||
if self.disable:
|
||||
return
|
||||
self.last_moved = time.time()
|
||||
|
||||
# Set the status as inside for the very first time
|
||||
if self.status == "outside":
|
||||
self.status = "inside"
|
||||
|
||||
# If the follow flag is not set, motion within the widget will make the ToolTip dissapear
|
||||
if not self.follow:
|
||||
self.status = "inside"
|
||||
self.withdraw()
|
||||
|
||||
# Calculate available space on the right side of the widget relative to the screen
|
||||
root_width = self.winfo_screenwidth()
|
||||
widget_x = event.x_root
|
||||
space_on_right = root_width - widget_x
|
||||
|
||||
# Calculate the width of the tooltip's text based on the length of the message string
|
||||
text_width = self.message_label.winfo_reqwidth()
|
||||
|
||||
# Calculate the offset based on available space and text width to avoid going off-screen on the right side
|
||||
offset_x = self.x_offset
|
||||
if space_on_right < text_width + 20: # Adjust the threshold as needed
|
||||
offset_x = -text_width - 20 # Negative offset when space is limited on the right side
|
||||
|
||||
# Offsets the ToolTip using the coordinates od an event as an origin
|
||||
self.geometry(f"+{event.x_root + offset_x}+{event.y_root + self.y_offset}")
|
||||
|
||||
# Time is in integer: milliseconds
|
||||
self.after(int(self.delay * 1000), self._show)
|
||||
|
||||
if self.is_noti:
|
||||
threading.Timer(self.noti_dur, self.destroy).start()
|
||||
|
||||
def on_leave(self, event=None) -> None:
|
||||
"""
|
||||
Hides the ToolTip temporarily.
|
||||
"""
|
||||
|
||||
if self.disable: return
|
||||
self.status = "outside"
|
||||
self.withdraw()
|
||||
|
||||
def _show(self) -> None:
|
||||
"""
|
||||
Displays the ToolTip.
|
||||
"""
|
||||
|
||||
if not self.widget.winfo_exists():
|
||||
self.hide()
|
||||
self.destroy()
|
||||
|
||||
if self.status == "inside" and time.time() - self.last_moved >= self.delay:
|
||||
self.status = "visible"
|
||||
self.deiconify()
|
||||
|
||||
def hide(self) -> None:
|
||||
"""
|
||||
Disable the widget from appearing.
|
||||
"""
|
||||
if not self.winfo_exists():
|
||||
return
|
||||
self.withdraw()
|
||||
self.disable = True
|
||||
|
||||
def is_disabled(self) -> None:
|
||||
"""
|
||||
Return the window state
|
||||
"""
|
||||
return self.disable
|
||||
|
||||
def get(self) -> None:
|
||||
"""
|
||||
Returns the text on the tooltip.
|
||||
"""
|
||||
return self.messageVar.get()
|
||||
|
||||
def configure(self, message: str = None, delay: float = None, bg_color: str = None, **kwargs):
|
||||
"""
|
||||
Set new message or configure the label parameters.
|
||||
"""
|
||||
if delay: self.delay = delay
|
||||
if bg_color: self.frame.configure(fg_color=bg_color)
|
||||
|
||||
self.messageVar.set(message)
|
||||
self.message_label.configure(**kwargs)
|
101
boiiiwd.py
101
boiiiwd.py
@ -549,9 +549,10 @@ class LibraryTab(ctk.CTkScrollableFrame):
|
||||
except:
|
||||
pass
|
||||
|
||||
def open_folder_location(self,folder, event=None):
|
||||
def open_folder_location(self, folder, event=None):
|
||||
if os.path.exists(folder):
|
||||
os.startfile(folder)
|
||||
show_noti(self, "Opening folder", event, 1.0)
|
||||
|
||||
def filter_items(self, event):
|
||||
filter_text = self.filter_entry.get().lower()
|
||||
@ -1218,7 +1219,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.queuetextarea = ctk.CTkTextbox(master=self.qeueuframe, font=("", 15))
|
||||
self.queuetextarea.grid(row=1, column=0, columnspan=4, padx=(20, 20), pady=(0, 20), sticky="nwse")
|
||||
|
||||
self.status_text = ctk.CTkLabel(self.qeueuframe, text="Status: Not Downloading")
|
||||
self.status_text = ctk.CTkLabel(self.qeueuframe, text="Status: Standby!")
|
||||
self.status_text.grid(row=3, column=0, padx=(20, 20), pady=(0, 20), sticky="ws")
|
||||
|
||||
self.skip_boutton = ctk.CTkButton(master=self.qeueuframe, text="Skip", command=self.skip_current_queue_item, width=10, height=10, fg_color="#585858")
|
||||
@ -1246,14 +1247,14 @@ class BOIIIWD(ctk.CTk):
|
||||
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
|
||||
self.txt_label = ctk.CTkLabel(self.sidebar_frame, text="- Sidebar -", font=(font, 17))
|
||||
self.txt_label.grid(row=1, column=0, padx=20, pady=(20, 10))
|
||||
self.sidebar_main = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_main.grid(row=2, column=0, padx=20, pady=10)
|
||||
self.sidebar_queue = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_queue.grid(row=3, column=0, padx=20, pady=10)
|
||||
self.sidebar_library = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_library.grid(row=4, column=0, padx=20, pady=10, sticky="n")
|
||||
self.sidebar_settings = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_settings.grid(row=5, column=0, padx=20, pady=10, sticky="n")
|
||||
self.sidebar_main = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_main.grid(row=2, column=0, padx=10, pady=(20, 6))
|
||||
self.sidebar_queue = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_queue.grid(row=3, column=0, padx=10, pady=6)
|
||||
self.sidebar_library = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_library.grid(row=4, column=0, padx=10, pady=6, sticky="n")
|
||||
self.sidebar_settings = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_settings.grid(row=5, column=0, padx=10, pady=6, sticky="n")
|
||||
|
||||
# create optionsframe
|
||||
self.optionsframe = ctk.CTkFrame(self)
|
||||
@ -1276,12 +1277,10 @@ class BOIIIWD(ctk.CTk):
|
||||
# self.spacer = ctk.CTkLabel(master=self.slider_progressbar_frame, text="")
|
||||
# self.spacer.grid(row=0, column=0, columnspan=1)
|
||||
|
||||
self.label_speed = ctk.CTkLabel(master=self.slider_progressbar_frame, text="Network Speed: 0 KB/s")
|
||||
self.label_speed = ctk.CTkLabel(master=self.slider_progressbar_frame, text="Awaiting Download!")
|
||||
self.label_speed.grid(row=1, column=0, padx=20, pady=(0, 10), sticky="w")
|
||||
|
||||
self.elapsed_time = ctk.CTkLabel(master=self.slider_progressbar_frame, text="")
|
||||
self.elapsed_time.grid(row=1, column=1, padx=20, pady=(0, 10), sticky="nsew", columnspan=1)
|
||||
|
||||
self.elapsed_time = ctk.CTkLabel(master=self.slider_progressbar_frame, text="", anchor="center")
|
||||
self.elapsed_time.grid(row=1, column=1, padx=20, pady=(0, 10), sticky="nsew") # Use "nsew" to center label
|
||||
self.label_file_size = ctk.CTkLabel(master=self.slider_progressbar_frame, text="File size: 0KB")
|
||||
self.label_file_size.grid(row=1, column=2, padx=(0, 20), pady=(0, 10), sticky="e")
|
||||
|
||||
@ -1915,7 +1914,7 @@ class BOIIIWD(ctk.CTk):
|
||||
def skip_current_queue_item(self):
|
||||
if self.button_download._state == "normal":
|
||||
self.skip_boutton.grid_remove()
|
||||
self.after(1, self.status_text.configure(text=f"Status: Not Downloading"))
|
||||
self.after(1, self.status_text.configure(text=f"Status: Standby!"))
|
||||
return
|
||||
self.settings_tab.stopped = True
|
||||
self.item_skipped = True
|
||||
@ -1958,7 +1957,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.settings_tab.stopped = True
|
||||
self.queue_stop_button = True
|
||||
show_message("Error", f"Couldn't remove {map_folder}, please do so manually\n{e}", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if self.settings_tab.continuous:
|
||||
@ -2074,6 +2073,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.is_downloading = False
|
||||
self.fail_threshold = 0
|
||||
if not self.is_pressed:
|
||||
self.after(1, self.label_speed.configure(text=f"Loading..."))
|
||||
self.is_pressed = True
|
||||
self.library_tab.load_items(self.edit_destination_folder.get())
|
||||
if self.queue_enabled:
|
||||
@ -2112,19 +2112,19 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not items:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
destination_folder = self.edit_destination_folder.get().strip()
|
||||
|
||||
if not destination_folder or not os.path.exists(destination_folder):
|
||||
show_message("Error", "Please select a valid destination folder => in the main tab!.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not steamcmd_path or not os.path.exists(steamcmd_path):
|
||||
show_message("Error", "Please enter a valid SteamCMD path => in the main tab!.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
self.total_queue_size = 0
|
||||
@ -2139,15 +2139,15 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
if not valid_id(workshop_id):
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
@ -2156,7 +2156,7 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if file_size is None:
|
||||
show_message("Error", "Failed to retrieve file size.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||
@ -2170,7 +2170,7 @@ class BOIIIWD(ctk.CTk):
|
||||
items.remove(item)
|
||||
show_message("Heads up!, map/s skipped => skip is on in settings", f"These item IDs may already be installed and are skipped:\n{item_ids}", icon="info")
|
||||
if not any(isinstance(item, int) for item in items):
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
else:
|
||||
show_message("Heads up! map/s not skipped => skip is off in settings", f"These item IDs may already be installed:\n{item_ids}", icon="info")
|
||||
@ -2182,7 +2182,7 @@ class BOIIIWD(ctk.CTk):
|
||||
current_number = index + 1
|
||||
total_items = len(items)
|
||||
if self.queue_stop_button:
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
break
|
||||
item.strip()
|
||||
self.settings_tab.stopped = False
|
||||
@ -2193,11 +2193,11 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
file_size = ws_file_size
|
||||
@ -2341,7 +2341,6 @@ class BOIIIWD(ctk.CTk):
|
||||
update_ui_thread.start()
|
||||
update_ui_thread.join()
|
||||
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.progress_bar.set(0.0)
|
||||
|
||||
@ -2350,6 +2349,7 @@ class BOIIIWD(ctk.CTk):
|
||||
json_file_path = os.path.join(map_folder, "workshop.json")
|
||||
|
||||
if os.path.exists(json_file_path):
|
||||
self.label_speed.configure(text="Installing...")
|
||||
mod_type = extract_json_data(json_file_path, "Type")
|
||||
folder_name = extract_json_data(json_file_path, "FolderName")
|
||||
|
||||
@ -2377,6 +2377,12 @@ class BOIIIWD(ctk.CTk):
|
||||
if index == len(items) - 1:
|
||||
self.after(1, self.status_text.configure(text=f"Status: Done! => Please press stop only if you see no popup window (rare bug)"))
|
||||
self.show_complete_message(message=f"All files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)")
|
||||
self.label_speed.configure(text="Awaiting Download!")
|
||||
elif os.path.exists(json_file_path) and not self.settings_tab.stopped:
|
||||
show_message("Error", "Failed to find workshop.json, please try again.", icon="cancel")
|
||||
if index == len(items) - 1:
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
self.button_download.configure(state="disabled")
|
||||
self.button_stop.configure(state="normal")
|
||||
@ -2392,15 +2398,14 @@ class BOIIIWD(ctk.CTk):
|
||||
self.skip_boutton.grid_remove()
|
||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||
self.settings_tab.stopped = True
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
finally:
|
||||
self.settings_tab.steam_fail_counter = 0
|
||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
self.is_pressed = False
|
||||
|
||||
|
||||
def download_thread(self):
|
||||
try:
|
||||
self.settings_tab.stopped = False
|
||||
@ -2424,12 +2429,12 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not destination_folder or not os.path.exists(destination_folder):
|
||||
show_message("Error", "Please select a valid destination folder.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not steamcmd_path or not os.path.exists(steamcmd_path):
|
||||
show_message("Error", "Please enter a valid SteamCMD path.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not workshop_id.isdigit():
|
||||
@ -2438,11 +2443,11 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
@ -2450,18 +2455,18 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not valid_id(workshop_id):
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if file_size is None:
|
||||
show_message("Error", "Failed to retrieve file size.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||
if self.settings_tab.skip_already_installed:
|
||||
show_message("Heads up!, map skipped => Skip is on in settings", f"This item may already be installed, Stopping: {workshop_id}", icon="info")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
show_message("Heads up! map not skipped => Skip is off in settings", f"This item may already be installed: {workshop_id}", icon="info")
|
||||
|
||||
@ -2578,8 +2583,6 @@ class BOIIIWD(ctk.CTk):
|
||||
update_ui_thread.join()
|
||||
|
||||
self.settings_tab.stopped = True
|
||||
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.progress_bar.set(0.0)
|
||||
|
||||
@ -2588,6 +2591,7 @@ class BOIIIWD(ctk.CTk):
|
||||
json_file_path = os.path.join(map_folder, "workshop.json")
|
||||
|
||||
if os.path.exists(json_file_path):
|
||||
self.label_speed.configure(text="Installing...")
|
||||
mod_type = extract_json_data(json_file_path, "Type")
|
||||
folder_name = extract_json_data(json_file_path, "FolderName")
|
||||
|
||||
@ -2599,7 +2603,7 @@ class BOIIIWD(ctk.CTk):
|
||||
folder_name_path = os.path.join(usermaps_folder, folder_name, "zone")
|
||||
else:
|
||||
show_message("Error", "Invalid workshop type in workshop.json, are you sure this is a map or a mod?.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
os.makedirs(folder_name_path, exist_ok=True)
|
||||
@ -2616,16 +2620,21 @@ class BOIIIWD(ctk.CTk):
|
||||
self.show_complete_message(message=f"{mod_type.capitalize()} files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)")
|
||||
self.button_download.configure(state="normal")
|
||||
self.button_stop.configure(state="disabled")
|
||||
elif os.path.exists(json_file_path) and not self.settings_tab.stopped:
|
||||
show_message("Error", "Failed to find workshop.json, please try again.", icon="cancel")
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
update_wait_thread = threading.Thread(target=wait_for_threads)
|
||||
update_wait_thread.start()
|
||||
|
||||
self.button_download.configure(state="disabled")
|
||||
self.button_stop.configure(state="normal")
|
||||
steamcmd_thread.join()
|
||||
update_wait_thread.join()
|
||||
|
||||
finally:
|
||||
self.settings_tab.steam_fail_counter = 0
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
self.is_pressed = False
|
||||
|
||||
def copy_with_progress(self, src, dst):
|
||||
@ -2668,11 +2677,11 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
self.button_download.configure(state="normal")
|
||||
self.button_stop.configure(state="disabled")
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.elapsed_time.configure(text=f"")
|
||||
self.progress_bar.set(0.0)
|
||||
self.after(50, self.status_text.configure(text=f"Status: Not Downloading"))
|
||||
self.after(50, self.status_text.configure(text=f"Status: Standby!"))
|
||||
self.after(1, self.label_speed.configure(text=f"Awaiting Download!"))
|
||||
self.skip_boutton.grid_remove()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -70,9 +70,10 @@ class LibraryTab(ctk.CTkScrollableFrame):
|
||||
except:
|
||||
pass
|
||||
|
||||
def open_folder_location(self,folder, event=None):
|
||||
def open_folder_location(self, folder, event=None):
|
||||
if os.path.exists(folder):
|
||||
os.startfile(folder)
|
||||
show_noti(self, "Opening folder", event, 1.0)
|
||||
|
||||
def filter_items(self, event):
|
||||
filter_text = self.filter_entry.get().lower()
|
||||
|
@ -89,7 +89,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.queuetextarea = ctk.CTkTextbox(master=self.qeueuframe, font=("", 15))
|
||||
self.queuetextarea.grid(row=1, column=0, columnspan=4, padx=(20, 20), pady=(0, 20), sticky="nwse")
|
||||
|
||||
self.status_text = ctk.CTkLabel(self.qeueuframe, text="Status: Not Downloading")
|
||||
self.status_text = ctk.CTkLabel(self.qeueuframe, text="Status: Standby!")
|
||||
self.status_text.grid(row=3, column=0, padx=(20, 20), pady=(0, 20), sticky="ws")
|
||||
|
||||
self.skip_boutton = ctk.CTkButton(master=self.qeueuframe, text="Skip", command=self.skip_current_queue_item, width=10, height=10, fg_color="#585858")
|
||||
@ -117,14 +117,14 @@ class BOIIIWD(ctk.CTk):
|
||||
self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
|
||||
self.txt_label = ctk.CTkLabel(self.sidebar_frame, text="- Sidebar -", font=(font, 17))
|
||||
self.txt_label.grid(row=1, column=0, padx=20, pady=(20, 10))
|
||||
self.sidebar_main = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_main.grid(row=2, column=0, padx=20, pady=10)
|
||||
self.sidebar_queue = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_queue.grid(row=3, column=0, padx=20, pady=10)
|
||||
self.sidebar_library = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_library.grid(row=4, column=0, padx=20, pady=10, sticky="n")
|
||||
self.sidebar_settings = ctk.CTkButton(self.sidebar_frame)
|
||||
self.sidebar_settings.grid(row=5, column=0, padx=20, pady=10, sticky="n")
|
||||
self.sidebar_main = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_main.grid(row=2, column=0, padx=10, pady=(20, 6))
|
||||
self.sidebar_queue = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_queue.grid(row=3, column=0, padx=10, pady=6)
|
||||
self.sidebar_library = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_library.grid(row=4, column=0, padx=10, pady=6, sticky="n")
|
||||
self.sidebar_settings = ctk.CTkButton(self.sidebar_frame, height=28)
|
||||
self.sidebar_settings.grid(row=5, column=0, padx=10, pady=6, sticky="n")
|
||||
|
||||
# create optionsframe
|
||||
self.optionsframe = ctk.CTkFrame(self)
|
||||
@ -147,12 +147,10 @@ class BOIIIWD(ctk.CTk):
|
||||
# self.spacer = ctk.CTkLabel(master=self.slider_progressbar_frame, text="")
|
||||
# self.spacer.grid(row=0, column=0, columnspan=1)
|
||||
|
||||
self.label_speed = ctk.CTkLabel(master=self.slider_progressbar_frame, text="Network Speed: 0 KB/s")
|
||||
self.label_speed = ctk.CTkLabel(master=self.slider_progressbar_frame, text="Awaiting Download!")
|
||||
self.label_speed.grid(row=1, column=0, padx=20, pady=(0, 10), sticky="w")
|
||||
|
||||
self.elapsed_time = ctk.CTkLabel(master=self.slider_progressbar_frame, text="")
|
||||
self.elapsed_time.grid(row=1, column=1, padx=20, pady=(0, 10), sticky="nsew", columnspan=1)
|
||||
|
||||
self.elapsed_time = ctk.CTkLabel(master=self.slider_progressbar_frame, text="", anchor="center")
|
||||
self.elapsed_time.grid(row=1, column=1, padx=20, pady=(0, 10), sticky="nsew") # Use "nsew" to center label
|
||||
self.label_file_size = ctk.CTkLabel(master=self.slider_progressbar_frame, text="File size: 0KB")
|
||||
self.label_file_size.grid(row=1, column=2, padx=(0, 20), pady=(0, 10), sticky="e")
|
||||
|
||||
@ -786,7 +784,7 @@ class BOIIIWD(ctk.CTk):
|
||||
def skip_current_queue_item(self):
|
||||
if self.button_download._state == "normal":
|
||||
self.skip_boutton.grid_remove()
|
||||
self.after(1, self.status_text.configure(text=f"Status: Not Downloading"))
|
||||
self.after(1, self.status_text.configure(text=f"Status: Standby!"))
|
||||
return
|
||||
self.settings_tab.stopped = True
|
||||
self.item_skipped = True
|
||||
@ -829,7 +827,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.settings_tab.stopped = True
|
||||
self.queue_stop_button = True
|
||||
show_message("Error", f"Couldn't remove {map_folder}, please do so manually\n{e}", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if self.settings_tab.continuous:
|
||||
@ -945,6 +943,7 @@ class BOIIIWD(ctk.CTk):
|
||||
self.is_downloading = False
|
||||
self.fail_threshold = 0
|
||||
if not self.is_pressed:
|
||||
self.after(1, self.label_speed.configure(text=f"Loading..."))
|
||||
self.is_pressed = True
|
||||
self.library_tab.load_items(self.edit_destination_folder.get())
|
||||
if self.queue_enabled:
|
||||
@ -983,19 +982,19 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not items:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
destination_folder = self.edit_destination_folder.get().strip()
|
||||
|
||||
if not destination_folder or not os.path.exists(destination_folder):
|
||||
show_message("Error", "Please select a valid destination folder => in the main tab!.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not steamcmd_path or not os.path.exists(steamcmd_path):
|
||||
show_message("Error", "Please enter a valid SteamCMD path => in the main tab!.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
self.total_queue_size = 0
|
||||
@ -1010,15 +1009,15 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
if not valid_id(workshop_id):
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
@ -1027,7 +1026,7 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if file_size is None:
|
||||
show_message("Error", "Failed to retrieve file size.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||
@ -1041,7 +1040,7 @@ class BOIIIWD(ctk.CTk):
|
||||
items.remove(item)
|
||||
show_message("Heads up!, map/s skipped => skip is on in settings", f"These item IDs may already be installed and are skipped:\n{item_ids}", icon="info")
|
||||
if not any(isinstance(item, int) for item in items):
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
else:
|
||||
show_message("Heads up! map/s not skipped => skip is off in settings", f"These item IDs may already be installed:\n{item_ids}", icon="info")
|
||||
@ -1053,7 +1052,7 @@ class BOIIIWD(ctk.CTk):
|
||||
current_number = index + 1
|
||||
total_items = len(items)
|
||||
if self.queue_stop_button:
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
break
|
||||
item.strip()
|
||||
self.settings_tab.stopped = False
|
||||
@ -1064,11 +1063,11 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter valid Workshop IDs/Links.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
file_size = ws_file_size
|
||||
@ -1211,8 +1210,6 @@ class BOIIIWD(ctk.CTk):
|
||||
update_ui_thread.daemon = True
|
||||
update_ui_thread.start()
|
||||
update_ui_thread.join()
|
||||
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.progress_bar.set(0.0)
|
||||
|
||||
@ -1221,6 +1218,7 @@ class BOIIIWD(ctk.CTk):
|
||||
json_file_path = os.path.join(map_folder, "workshop.json")
|
||||
|
||||
if os.path.exists(json_file_path):
|
||||
self.label_speed.configure(text="Installing...")
|
||||
mod_type = extract_json_data(json_file_path, "Type")
|
||||
folder_name = extract_json_data(json_file_path, "FolderName")
|
||||
|
||||
@ -1248,6 +1246,12 @@ class BOIIIWD(ctk.CTk):
|
||||
if index == len(items) - 1:
|
||||
self.after(1, self.status_text.configure(text=f"Status: Done! => Please press stop only if you see no popup window (rare bug)"))
|
||||
self.show_complete_message(message=f"All files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)")
|
||||
self.label_speed.configure(text="Awaiting Download!")
|
||||
elif os.path.exists(json_file_path) and not self.settings_tab.stopped:
|
||||
show_message("Error", "Failed to find workshop.json, please try again.", icon="cancel")
|
||||
if index == len(items) - 1:
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
self.button_download.configure(state="disabled")
|
||||
self.button_stop.configure(state="normal")
|
||||
@ -1263,15 +1267,14 @@ class BOIIIWD(ctk.CTk):
|
||||
self.skip_boutton.grid_remove()
|
||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||
self.settings_tab.stopped = True
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
finally:
|
||||
self.settings_tab.steam_fail_counter = 0
|
||||
self.after(1, self.label_file_size.configure(text=f"File size: 0KB"))
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
self.is_pressed = False
|
||||
|
||||
|
||||
def download_thread(self):
|
||||
try:
|
||||
self.settings_tab.stopped = False
|
||||
@ -1295,12 +1298,12 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not destination_folder or not os.path.exists(destination_folder):
|
||||
show_message("Error", "Please select a valid destination folder.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not steamcmd_path or not os.path.exists(steamcmd_path):
|
||||
show_message("Error", "Please enter a valid SteamCMD path.")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if not workshop_id.isdigit():
|
||||
@ -1309,11 +1312,11 @@ class BOIIIWD(ctk.CTk):
|
||||
workshop_id = extract_workshop_id(workshop_id).strip()
|
||||
else:
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
except:
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
ws_file_size = get_workshop_file_size(workshop_id)
|
||||
@ -1321,18 +1324,18 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
if not valid_id(workshop_id):
|
||||
show_message("Warning", "Please enter a valid Workshop ID/Link.", icon="warning")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if file_size is None:
|
||||
show_message("Error", "Failed to retrieve file size.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
if any(workshop_id in item for item in self.library_tab.added_items):
|
||||
if self.settings_tab.skip_already_installed:
|
||||
show_message("Heads up!, map skipped => Skip is on in settings", f"This item may already be installed, Stopping: {workshop_id}", icon="info")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
show_message("Heads up! map not skipped => Skip is off in settings", f"This item may already be installed: {workshop_id}", icon="info")
|
||||
|
||||
@ -1449,8 +1452,6 @@ class BOIIIWD(ctk.CTk):
|
||||
update_ui_thread.join()
|
||||
|
||||
self.settings_tab.stopped = True
|
||||
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.progress_bar.set(0.0)
|
||||
|
||||
@ -1459,6 +1460,7 @@ class BOIIIWD(ctk.CTk):
|
||||
json_file_path = os.path.join(map_folder, "workshop.json")
|
||||
|
||||
if os.path.exists(json_file_path):
|
||||
self.label_speed.configure(text="Installing...")
|
||||
mod_type = extract_json_data(json_file_path, "Type")
|
||||
folder_name = extract_json_data(json_file_path, "FolderName")
|
||||
|
||||
@ -1470,7 +1472,7 @@ class BOIIIWD(ctk.CTk):
|
||||
folder_name_path = os.path.join(usermaps_folder, folder_name, "zone")
|
||||
else:
|
||||
show_message("Error", "Invalid workshop type in workshop.json, are you sure this is a map or a mod?.", icon="cancel")
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
os.makedirs(folder_name_path, exist_ok=True)
|
||||
@ -1487,16 +1489,21 @@ class BOIIIWD(ctk.CTk):
|
||||
self.show_complete_message(message=f"{mod_type.capitalize()} files were downloaded\nYou can run the game now!\nPS: You have to restart the game \n(pressing launch will launch/restarts)")
|
||||
self.button_download.configure(state="normal")
|
||||
self.button_stop.configure(state="disabled")
|
||||
elif os.path.exists(json_file_path) and not self.settings_tab.stopped:
|
||||
show_message("Error", "Failed to find workshop.json, please try again.", icon="cancel")
|
||||
self.stop_download()
|
||||
return
|
||||
|
||||
update_wait_thread = threading.Thread(target=wait_for_threads)
|
||||
update_wait_thread.start()
|
||||
|
||||
self.button_download.configure(state="disabled")
|
||||
self.button_stop.configure(state="normal")
|
||||
steamcmd_thread.join()
|
||||
update_wait_thread.join()
|
||||
|
||||
finally:
|
||||
self.settings_tab.steam_fail_counter = 0
|
||||
self.stop_download
|
||||
self.stop_download()
|
||||
self.is_pressed = False
|
||||
|
||||
def copy_with_progress(self, src, dst):
|
||||
@ -1539,9 +1546,9 @@ class BOIIIWD(ctk.CTk):
|
||||
|
||||
self.button_download.configure(state="normal")
|
||||
self.button_stop.configure(state="disabled")
|
||||
self.label_speed.configure(text="Network Speed: 0 KB/s")
|
||||
self.progress_text.configure(text="0%")
|
||||
self.elapsed_time.configure(text=f"")
|
||||
self.progress_bar.set(0.0)
|
||||
self.after(50, self.status_text.configure(text=f"Status: Not Downloading"))
|
||||
self.after(50, self.status_text.configure(text=f"Status: Standby!"))
|
||||
self.after(1, self.label_speed.configure(text=f"Awaiting Download!"))
|
||||
self.skip_boutton.grid_remove()
|
||||
|
BIN
dist/BOIIIWD.exe
vendored
BIN
dist/BOIIIWD.exe
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user