1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2026-06-24 18:15:01 +00:00

17 Commits

Author SHA1 Message Date
RedDeadDepresso a925b0b768 Merge 64a2fed251 into 0d66a5c424 2023-12-26 00:54:52 +00:00
RedDeadDepresso 64a2fed251 refactor: MCE Manager
changed queue thread into daemon thread
2023-12-26 00:52:04 +00:00
RedDeadDepresso 26f7e491b3 fix: close random popup in main after login 2023-12-25 23:47:01 +00:00
RedDeadDepresso dd5e6d7803 feat: auto-generate MCE/config.json 2023-12-25 17:51:56 +00:00
RedDeadDepresso ea2b9d67cd revert changes in task 2023-12-25 16:30:27 +00:00
RedDeadDepresso cf9468e0c5 Update .gitignore 2023-12-25 14:15:50 +00:00
RedDeadDepresso 43074d386c fix: updated regex for mission 2023-12-25 14:07:20 +00:00
RedDeadDepresso 8186513bf1 fix: tasks 2023-12-25 11:48:00 +00:00
RedDeadDepresso 499651f51b feat: mission/commissions/event 2023-12-25 11:35:05 +00:00
YoursFunny 0d66a5c424 fix(tc): change refresh time 2023-12-25 13:56:42 +08:00
YoursFunny 37bbfba299 feat: add tasks assets for jp 2023-12-25 13:17:34 +08:00
YoursFunny 34c5323df3 fix(momotalk): correct sort switch 2023-12-23 17:23:40 +08:00
YoursFunny 30d63fa193 fix(momotalk): correct sidebar switch 2023-12-23 17:03:15 +08:00
YoursFunny be3fdb0988 fix(task): check all claimed 2023-12-23 16:21:46 +08:00
YoursFunny ba9472d0b1 lang: add zh for new settings 2023-12-23 16:09:06 +08:00
RedDeadDepresso 1791b4b05c Added Tasks, Shop, MomoTalk (#11)
* feat: tasks

Added module tasks for EN

* refactor: gui

added tree view Farm and Reward.

* feat: shop

* feat: momotalk

---------

Co-authored-by: YoursFunny <admin@yoursfunny.top>
2023-12-22 13:35:33 +08:00
YoursFunny f8d1ba3d4e perf: change tc priority 2023-12-21 17:56:06 +08:00
449 changed files with 642 additions and 5283 deletions
-102
View File
@@ -1,102 +0,0 @@
import customtkinter
import json
from MCE.custom_widgets.ctk_scrollable_dropdown import CTkScrollableDropdown
import os
from tkinter import END
class InputHelper(customtkinter.CTk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.create_tabview()
self.create_invite_student_widgets()
self.create_lessons_widgets()
def create_tabview(self):
self.tabview = customtkinter.CTkTabview(master=self)
self.tabview.grid(row=0, column=0)
self.cafe_tab = self.tabview.add("Cafe") # add tab at the end
self.lessons_tab = self.tabview.add("Lessons") # add tab at the end
self.tabview.set("Cafe") # set currently visible
def create_invite_student_widgets(self):
self.invitation_label = customtkinter.CTkLabel(master=self.cafe_tab, text="Copy and paste this in AAS Invitation Settings:")
self.invitation_label.grid(row=0, column=0, padx=60)
self.invitation_entry = customtkinter.CTkEntry(master=self.cafe_tab, width=500)
self.invitation_entry.grid(row=1, column=0)
self.invite_copy_button = customtkinter.CTkButton(master=self.cafe_tab, text="Copy", width=40, command=lambda : self.copy_entry(self.invitation_entry, self.invite_copy_button))
self.invite_copy_button.grid(row=1, column=3, padx=5)
self.invite_clear_button = customtkinter.CTkButton(master=self.cafe_tab, text="Clear", width=40, fg_color="crimson", command=lambda : self.invitation_entry.delete(0, END))
self.invite_clear_button.grid(row=1, column=4, padx=5)
self.invite_frame = customtkinter.CTkFrame(master=self.cafe_tab, fg_color="transparent")
self.invite_frame.grid(row=2, column=0, padx=20, pady=20)
self.server_dropdown = customtkinter.CTkOptionMenu(master=self.invite_frame, values=self.find_json_files("MCE/student_list"), command=self.switch_server, width=40)
self.server_dropdown.grid(row=0, column=0)
self.student_entry = customtkinter.CTkComboBox(master=self.invite_frame, width=300)
self.student_entry.grid(row=0, column=1, padx=(50,0))
self.student_dropdown = CTkScrollableDropdown(self.student_entry, width=300, height=550, autocomplete=True, command=lambda choice: self.insert(choice, self.invitation_entry), values=[""])
self.server_dropdown.set("EN")
self.switch_server("EN")
def create_lessons_widgets(self):
self.lessons_label = customtkinter.CTkLabel(master=self.lessons_tab, text="Copy and paste this in AAS Lessons Settings:")
self.lessons_label.grid(row=0, column=0, padx=60)
self.lessons_entry = customtkinter.CTkEntry(master=self.lessons_tab, width=500)
self.lessons_entry.grid(row=1, column=0)
self.lessons_copy_button = customtkinter.CTkButton(master=self.lessons_tab, text="Copy", width=40, command=lambda : self.copy_entry(self.lessons_entry, self.lessons_copy_button))
self.lessons_copy_button.grid(row=1, column=1, padx=5)
self.lessons_clear_button = customtkinter.CTkButton(master=self.lessons_tab, text="Clear", width=40, fg_color="crimson", command=lambda : self.lessons_entry.delete(0, END))
self.lessons_clear_button.grid(row=1, column=2, padx=5)
self.lessons_buttons_frame = customtkinter.CTkFrame(master=self.lessons_tab, fg_color="transparent")
self.lessons_buttons_frame.grid(row=2, column=0, padx=20, pady=20)
for i in range(9):
self.lesson_button = customtkinter.CTkButton(master=self.lessons_buttons_frame, text=str(i+1), command=lambda choice=str(i+1): self.insert(choice, self.lessons_entry), width=40)
self.lesson_button.grid(row=0, column=i, padx=5)
def find_json_files(self,folder_path):
json_files = []
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.endswith(".json"):
json_files.append(os.path.splitext(file)[0])
return json_files
def switch_server(self, server):
with open(f"MCE/student_list/{server}.json", "r") as f:
student_list = json.load(f)
self.student_dropdown.configure(values=student_list)
def insert(self, value, entry):
entry.insert(index=END, string=value + " > ")
def copy_entry(self, entry, button):
text_to_copy = entry.get()
# Check if there is text to copy
if text_to_copy:
# Clear the clipboard and set the new text
self.clipboard_clear()
self.clipboard_append(text_to_copy)
self.update() # This is necessary on some systems to update the clipboard
button_color = button.cget("fg_color")
button.configure(fg_color="green")
self.after(2000, lambda : button.configure(fg_color=['#3B8ED0', '#1F6AA5']))
if __name__ == "__main__":
app = InputHelper()
app.title("Input Helper")
app.mainloop()
+14 -19
View File
@@ -8,7 +8,6 @@ from MCE.custom_widgets.ctk_timeentry import CTkTimeEntry
from MCE.custom_widgets.ctk_integerspinbox import CTkIntegerSpinbox
from MCE.custom_widgets.ctk_templatedialog import CTkTemplateDialog
from MCE.custom_widgets.ctk_notification import CTkNotification
from MCE.custom_widgets.ctk_add_button import CTkAddButton
from MCE.utils import Linker, Config
from filelock import FileLock, Timeout
import threading
@@ -118,7 +117,7 @@ class MCE_Manager(customtkinter.CTk):
# Helper method to create Mission Tabview with Template and Queue Tabs
def create_mission_tabview(self):
self.mission_tabview = customtkinter.CTkTabview(self)
self.mission_tabview = customtkinter.CTkTabview(self, height=500)
self.mission_tabview.grid(row=17, column=0, columnspan=3, padx=20)
self.tab_template = self.mission_tabview.add('Template')
@@ -135,11 +134,11 @@ class MCE_Manager(customtkinter.CTk):
self.template_labels.grid(row=0, column=0, sticky="ew")
self.mode_label = customtkinter.CTkLabel(self.template_labels, text="Mode:", font=customtkinter.CTkFont(underline=True))
self.mode_tooltip = CTkToolTip(self.mode_label, message="N : Mission Normal\nH : Mission Hard\nE : Event Quest\nXP : Commissions EXP\nCR : Commissions Credits\n", justify=tk.LEFT)
self.mode_tooltip = CTkToolTip(self.mode_label, message="N:Mission Normal\nH:Mission Hard\nE:Event Quest\nBD:Commissions EXP\nIR:Commissions Credits\n")
self.mode_label.grid(row=1, column=0, padx=(130, 0), pady=5)
self.stage_label = customtkinter.CTkLabel(self.template_labels, text="Stage:", font=customtkinter.CTkFont(underline=True))
self.stage_tooltip = CTkToolTip(self.stage_label, message="Valid format\nMission: 1-1, 3-A\nCommissions & Event: 01", justify=tk.LEFT)
self.stage_tooltip = CTkToolTip(self.stage_label, message="Valid format for Mission: 1-1\nValid format for Commissions/Event: 01")
self.stage_label.grid(row=1, column=1, padx=(40, 20), pady=5)
self.run_times_label = customtkinter.CTkLabel(self.template_labels, text="Number of Sweeps:", font=customtkinter.CTkFont(underline=True))
@@ -152,8 +151,7 @@ class MCE_Manager(customtkinter.CTk):
self.highlight_label = customtkinter.CTkLabel(self.template_buttons_frame, text="*You can double click an entry and press up or down arrow to change its position", font=customtkinter.CTkFont(family="Inter", size=12))
self.highlight_label.grid(row=0, column=0, columnspan=3)
self.add_button = CTkAddButton(master=self.template_buttons_frame)
self.add_button.button.configure(command=lambda queue=queue, button=self.add_button.button: self.add_frame(queue=queue, button=button))
self.add_button = customtkinter.CTkButton(self.template_buttons_frame , text="Add", command=lambda queue=queue: self.add_frame(queue=queue))
self.add_button.grid(row=1, column=0, padx=5, pady=5)
# Clear button to clear all frames
@@ -168,10 +166,10 @@ class MCE_Manager(customtkinter.CTk):
# Helper method to create Template Frame and Queue Frame
def create_template_and_queue_frames(self):
self.template_frame = customtkinter.CTkScrollableFrame(self.tab_template, width=435, height=350)
self.template_frame = customtkinter.CTkScrollableFrame(self.tab_template, width=400, height=350)
self.template_frame.grid(row=1, column=0, sticky="nsew")
self.queue_frame = customtkinter.CTkScrollableFrame(self.tab_queue, width=435, height=350)
self.queue_frame = customtkinter.CTkScrollableFrame(self.tab_queue, width=400, height=350)
self.queue_frame.grid(row=1, column=0, sticky="nsew")
# Helper method to create Lists to Store Frame Widgets
@@ -213,7 +211,7 @@ class MCE_Manager(customtkinter.CTk):
self.template_optionmenu.set(self.previous_selected)
return
elif template_name in self.templates_list:
CTkMessagebox(title="Error", message="Name is invalid.", icon="MCE\icons\cancel.png")
CTkMessagebox(title="Error", message="Name is invalid.", icon="cancel")
self.template_optionmenu.set(self.previous_selected)
return
else:
@@ -234,7 +232,7 @@ class MCE_Manager(customtkinter.CTk):
def delete_template(self):
msg = CTkMessagebox(title="Template Deletetion", message=f"Are you sure you want to delete Template {self.previous_selected}?",
icon="MCE\icons\question.png", option_1="No", option_2="Yes")
icon="question", option_1="No", option_2="Yes")
response = msg.get()
if response=="Yes":
if len(self.templates) != 1:
@@ -252,19 +250,18 @@ class MCE_Manager(customtkinter.CTk):
self.template_optionmenu.configure(values=self.templates_list)
self.template_optionmenu.set(self.preferred_template)
else:
CTkMessagebox(title="Error", message="At least one template must exist!!!", icon="MCE\icons\cancel.png")
CTkMessagebox(title="Error", message="At least one template must exist!!!", icon="cancel")
return
# Function to add a frame with widgets
def add_frame(self, inner_list=None, queue=False, state="normal", button=None):
position = button.cget("text") if button else "Add Down"
def add_frame(self, inner_list=None, queue=False, state="normal"):
frames = self.queue_frames if queue else self.template_frames
parent_frame = self.queue_frame if queue else self.template_frame
row_index = len(frames) + 1 # Calculate the row for the new frame
# Create a frame
frame = tk.Frame(parent_frame, bg="gray17")
frame.grid(row=row_index, column=0, columnspan=4, padx=10, pady=10, sticky="w")
frames.append(frame) if position == "Add Down" else frames.insert(0, frame)
frames.append(frame)
# "Up" button to move the frame up
up_button = customtkinter.CTkButton(frame, text="Up", width=5, command=lambda f=frame, queue=queue: self.move_frame_up(f, queue), state=state)
up_button.grid(row=0, column=0, padx=5, pady=5, sticky="w")
@@ -272,7 +269,7 @@ class MCE_Manager(customtkinter.CTk):
down_button = customtkinter.CTkButton(frame, text="Down", width=5, command=lambda f=frame, queue=queue: self.move_frame_down(f, queue), state=state)
down_button.grid(row=0, column=1, padx=5, pady=5, sticky="w")
# Dropdown menu for mode
mode_optionmenu = customtkinter.CTkOptionMenu(frame, width=60, values=["N", "H", "E", "XP", "CR"], state=state)
mode_optionmenu = customtkinter.CTkOptionMenu(frame, width=60, values=["N", "H", "E", "BD", "IR"], state=state)
mode_optionmenu.set(inner_list[0] if inner_list else "N")
mode_optionmenu.grid(row=0, column=2, padx=5, pady=5, sticky="w")
# Entry widget for stage
@@ -291,9 +288,7 @@ class MCE_Manager(customtkinter.CTk):
delete_button = customtkinter.CTkButton(frame, text="Delete", width=5, command=lambda f=frame, queue=queue: self.delete_frame(f, queue), state=state)
delete_button.grid(row=0, column=5, padx=5, pady=5, sticky="w")
frame.bind("<Double-Button-1>", lambda event, f=frame: self.highlight_frame(f))
if position == "Add Up":
self.update_frame_positions(queue=queue)
frame.bind("<Double-Button-1>", lambda event, f=frame: self.highlight_frame(f))
# Function to clear all frames
def clear_frames(self, queue=False):
@@ -311,7 +306,7 @@ class MCE_Manager(customtkinter.CTk):
mode_optionmenu = frame.winfo_children()[2]
stage_entry = frame.winfo_children()[3]
if not self.check_entry(mode_optionmenu, stage_entry):
CTkMessagebox(title="Error", message="Configuration not saved. Some entries are incomplete or have incorect input.", icon="MCE\icons\cancel.png")
CTkMessagebox(title="Error", message="Configuration not saved. Some entries are incomplete or have incorect input.", icon="cancel")
return
mode = frame.winfo_children()[2].get()
stage = frame.winfo_children()[3].get().strip()
-19
View File
@@ -1,19 +0,0 @@
import customtkinter
class CTkAddButton(customtkinter.CTkFrame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.button = customtkinter.CTkButton(self, text="Add Down", corner_radius=0, width=120)
self.button.grid(row=0, column=0)
self.option_menu = customtkinter.CTkOptionMenu(
self, values= ["Add Up", "Add Down"], width=10, command=self.set_button, corner_radius=0
)
self.option_menu.set("")
self.option_menu.grid(row=0, column=1)
def set_button(self, value):
self.option_menu.set("")
self.button.configure(text=value)
def configure(self, *args, **kwargs):
self.button.configure(*args, **kwargs)
@@ -1,337 +0,0 @@
'''
Advanced Scrollable Dropdown class for customtkinter widgets
Author: Akash Bora
'''
import customtkinter
import sys
import time
import difflib
class CTkScrollableDropdown(customtkinter.CTkToplevel):
def __init__(self, attach, x=None, y=None, button_color=None, height: int = 200, width: int = None,
fg_color=None, button_height: int = 20, justify="center", scrollbar_button_color=None,
scrollbar=True, scrollbar_button_hover_color=None, frame_border_width=2, values=[],
command=None, image_values=[], alpha: float = 0.97, frame_corner_radius=20, double_click=False,
resize=True, frame_border_color=None, text_color=None, autocomplete=False, **button_kwargs):
super().__init__(takefocus=1)
self.focus()
self.lift()
self.alpha = alpha
self.attach = attach
self.corner = frame_corner_radius
self.padding = 0
self.focus_something = False
self.disable = True
self.update()
if sys.platform.startswith("win"):
self.after(100, lambda: self.overrideredirect(True))
self.transparent_color = self._apply_appearance_mode(self._fg_color)
self.attributes("-transparentcolor", self.transparent_color)
elif sys.platform.startswith("darwin"):
self.overrideredirect(True)
self.transparent_color = 'systemTransparent'
self.attributes("-transparent", True)
self.focus_something = True
else:
self.overrideredirect(True)
self.transparent_color = '#000001'
self.corner = 0
self.padding = 18
self.withdraw()
self.hide = True
self.attach.bind('<Configure>', lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind('<Configure>', lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind("<ButtonPress>", lambda e: self._withdraw() if not self.disable else None, add="+")
self.attributes('-alpha', 0)
self.disable = False
self.fg_color = customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] if fg_color is None else fg_color
self.scroll_button_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_color"] if scrollbar_button_color is None else scrollbar_button_color
self.scroll_hover_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_hover_color"] if scrollbar_button_hover_color is None else scrollbar_button_hover_color
self.frame_border_color = customtkinter.ThemeManager.theme["CTkFrame"]["border_color"] if frame_border_color is None else frame_border_color
self.button_color = customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"] if button_color is None else button_color
self.text_color = customtkinter.ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else text_color
if scrollbar is False:
self.scroll_button_color = self.fg_color
self.scroll_hover_color = self.fg_color
self.frame = customtkinter.CTkScrollableFrame(self, bg_color=self.transparent_color, fg_color=self.fg_color,
scrollbar_button_hover_color=self.scroll_hover_color,
corner_radius=self.corner, border_width=frame_border_width,
scrollbar_button_color=self.scroll_button_color,
border_color=self.frame_border_color)
self.frame._scrollbar.grid_configure(padx=3)
self.frame.pack(expand=True, fill="both")
self.dummy_entry = customtkinter.CTkEntry(self.frame, fg_color="transparent", border_width=0, height=1, width=1)
self.no_match = customtkinter.CTkLabel(self.frame, text="No Match")
self.height = height
self.height_new = height
self.width = width
self.command = command
self.fade = False
self.resize = resize
self.autocomplete = autocomplete
self.var_update = customtkinter.StringVar()
self.appear = False
if justify.lower()=="left":
self.justify = "w"
elif justify.lower()=="right":
self.justify = "e"
else:
self.justify = "c"
self.button_height = button_height
self.values = values
self.button_num = len(self.values)
self.image_values = None if len(image_values)!=len(self.values) else image_values
self.resizable(width=False, height=False)
self.transient(self.master)
self._init_buttons(**button_kwargs)
# Add binding for different ctk widgets
if double_click or self.attach.winfo_name().startswith("!ctkentry") or self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach.bind('<Double-Button-1>', lambda e: self._iconify(), add="+")
else:
self.attach.bind('<Button-1>', lambda e: self._iconify(), add="+")
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._canvas.tag_bind("right_parts", "<Button-1>", lambda e: self._iconify())
self.attach._canvas.tag_bind("dropdown_arrow", "<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
if self.attach.winfo_name().startswith("!ctkoptionmenu"):
self.attach._canvas.bind("<Button-1>", lambda e: self._iconify())
self.attach._text_label.bind("<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
self.attach.bind("<Destroy>", lambda _: self._destroy(), add="+")
self.update_idletasks()
self.x = x
self.y = y
if self.autocomplete:
self.bind_autocomplete()
self.deiconify()
self.withdraw()
self.attributes("-alpha", self.alpha)
def _destroy(self):
self.after(500, self.destroy_popup)
def _withdraw(self):
if self.winfo_viewable() and self.hide:
self.withdraw()
self.event_generate("<<Closed>>")
self.hide = True
def _update(self, a, b, c):
self.live_update(self.attach._entry.get())
def bind_autocomplete(self, ):
def appear(x):
self.appear = True
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._entry.configure(textvariable=self.var_update)
self.attach._entry.bind("<Key>", appear)
self.attach.set(self.values[0])
self.var_update.trace_add('write', self._update)
if self.attach.winfo_name().startswith("!ctkentry"):
self.attach.configure(textvariable=self.var_update)
self.attach.bind("<Key>", appear)
self.var_update.trace_add('write', self._update)
def fade_out(self):
for i in range(100,0,-10):
if not self.winfo_exists():
break
self.attributes("-alpha", i/100)
self.update()
time.sleep(1/100)
def fade_in(self):
for i in range(0,100,10):
if not self.winfo_exists():
break
self.attributes("-alpha", i/100)
self.update()
time.sleep(1/100)
def _init_buttons(self, **button_kwargs):
self.i = 0
self.widgets = {}
for row in self.values:
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=row,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
image=self.image_values[i] if self.image_values is not None else None,
anchor=self.justify,
command=lambda k=row: self._attach_key_press(k), **button_kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.hide = False
def destroy_popup(self):
self.destroy()
self.disable = True
def place_dropdown(self):
self.x_pos = self.attach.winfo_rootx() if self.x is None else self.x + self.attach.winfo_rootx()
self.y_pos = self.attach.winfo_rooty() + self.attach.winfo_reqheight() + 5 if self.y is None else self.y + self.attach.winfo_rooty()
self.width_new = self.attach.winfo_width() if self.width is None else self.width
if self.resize:
if self.button_num<=5:
self.height_new = self.button_height * self.button_num + 55
else:
self.height_new = self.button_height * self.button_num + 35
if self.height_new>self.height:
self.height_new = self.height
self.geometry('{}x{}+{}+{}'.format(self.width_new, self.height_new,
self.x_pos, self.y_pos))
self.fade_in()
self.attributes('-alpha', self.alpha)
self.attach.focus()
def _iconify(self):
if self.disable: return
if self.hide:
self.event_generate("<<Opened>>")
self._deiconify()
self.focus()
self.hide = False
self.place_dropdown()
if self.focus_something:
self.dummy_entry.pack()
self.dummy_entry.focus_set()
self.after(100, self.dummy_entry.pack_forget)
else:
self.withdraw()
self.hide = True
def _attach_key_press(self, k):
self.event_generate("<<Selected>>")
self.fade = True
if self.command:
self.command(k)
self.fade = False
self.fade_out()
self.withdraw()
self.hide = True
def live_update(self, string=None):
if not self.appear: return
if self.disable: return
if self.fade: return
if string:
string = string.lower()
self._deiconify()
i=1
for key in self.widgets.keys():
s = self.widgets[key].cget("text").lower()
text_similarity = difflib.SequenceMatcher(None, s[0:len(string)], string).ratio()
similar = s.startswith(string) or text_similarity > 0.75
if not similar:
self.widgets[key].pack_forget()
else:
self.widgets[key].pack(fill="x", pady=2, padx=(self.padding, 0))
i+=1
if i==1:
self.no_match.pack(fill="x", pady=2, padx=(self.padding, 0))
else:
self.no_match.pack_forget()
self.button_num = i
self.place_dropdown()
else:
self.no_match.pack_forget()
self.button_num = len(self.values)
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
self.place_dropdown()
self.frame._parent_canvas.yview_moveto(0.0)
self.appear = False
def insert(self, value, **kwargs):
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=value,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
anchor=self.justify,
command=lambda k=value: self._attach_key_press(k), **kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.values.append(value)
def _deiconify(self):
if len(self.values)>0:
self.deiconify()
def popup(self, x=None, y=None):
self.x = x
self.y = y
self.hide = True
self._iconify()
def configure(self, **kwargs):
if "height" in kwargs:
self.height = kwargs.pop("height")
self.height_new = self.height
if "alpha" in kwargs:
self.alpha = kwargs.pop("alpha")
if "width" in kwargs:
self.width = kwargs.pop("width")
if "fg_color" in kwargs:
self.frame.configure(fg_color=kwargs.pop("fg_color"))
if "values" in kwargs:
self.values = kwargs.pop("values")
self.image_values = None
self.button_num = len(self.values)
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
if "image_values" in kwargs:
self.image_values = kwargs.pop("image_values")
self.image_values = None if len(self.image_values)!=len(self.values) else self.image_values
if self.image_values is not None:
i=0
for key in self.widgets.keys():
self.widgets[key].configure(image=self.image_values[i])
i+=1
if "button_color" in kwargs:
for key in self.widgets.keys():
self.widgets[key].configure(fg_color=kwargs.pop("button_color"))
for key in self.widgets.keys():
self.widgets[key].configure(**kwargs)
@@ -1,291 +0,0 @@
'''
Advanced Scrollable Dropdown Frame class for customtkinter widgets
Author: Akash Bora
'''
import customtkinter
import sys
import difflib
class CTkScrollableDropdownFrame(customtkinter.CTkFrame):
def __init__(self, attach, x=None, y=None, button_color=None, height: int = 200, width: int = None,
fg_color=None, button_height: int = 20, justify="center", scrollbar_button_color=None,
scrollbar=True, scrollbar_button_hover_color=None, frame_border_width=2, values=[],
command=None, image_values=[], double_click=False, frame_corner_radius=True, resize=True, frame_border_color=None,
text_color=None, autocomplete=False, **button_kwargs):
super().__init__(master=attach.winfo_toplevel(), bg_color=attach.cget("bg_color"))
self.attach = attach
self.corner = 11 if frame_corner_radius else 0
self.padding = 0
self.disable = True
self.hide = True
self.attach.bind('<Configure>', lambda e: self._withdraw() if not self.disable else None, add="+")
self.attach.winfo_toplevel().bind("<ButtonPress>", lambda e: self._withdraw() if not self.disable else None, add="+")
self.disable = False
self.fg_color = customtkinter.ThemeManager.theme["CTkFrame"]["fg_color"] if fg_color is None else fg_color
self.scroll_button_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_color"] if scrollbar_button_color is None else scrollbar_button_color
self.scroll_hover_color = customtkinter.ThemeManager.theme["CTkScrollbar"]["button_hover_color"] if scrollbar_button_hover_color is None else scrollbar_button_hover_color
self.frame_border_color = customtkinter.ThemeManager.theme["CTkFrame"]["border_color"] if frame_border_color is None else frame_border_color
self.button_color = customtkinter.ThemeManager.theme["CTkFrame"]["top_fg_color"] if button_color is None else button_color
self.text_color = customtkinter.ThemeManager.theme["CTkLabel"]["text_color"] if text_color is None else text_color
if scrollbar is False:
self.scroll_button_color = self.fg_color
self.scroll_hover_color = self.fg_color
self.frame = customtkinter.CTkScrollableFrame(self, fg_color=self.fg_color, bg_color=attach.cget("bg_color"),
scrollbar_button_hover_color=self.scroll_hover_color,
corner_radius=self.corner, border_width=frame_border_width,
scrollbar_button_color=self.scroll_button_color,
border_color=self.frame_border_color)
self.frame._scrollbar.grid_configure(padx=3)
self.frame.pack(expand=True, fill="both")
if self.corner==0:
self.corner = 21
self.dummy_entry = customtkinter.CTkEntry(self.frame, fg_color="transparent", border_width=0, height=1, width=1)
self.no_match = customtkinter.CTkLabel(self.frame, text="No Match")
self.height = height
self.height_new = height
self.width = width
self.command = command
self.fade = False
self.resize = resize
self.autocomplete = autocomplete
self.var_update = customtkinter.StringVar()
self.appear = False
if justify.lower()=="left":
self.justify = "w"
elif justify.lower()=="right":
self.justify = "e"
else:
self.justify = "c"
self.button_height = button_height
self.values = values
self.button_num = len(self.values)
self.image_values = None if len(image_values)!=len(self.values) else image_values
self._init_buttons(**button_kwargs)
# Add binding for different ctk widgets
if double_click or self.attach.winfo_name().startswith("!ctkentry") or self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach.bind('<Double-Button-1>', lambda e: self._iconify(), add="+")
self.attach._entry.bind('<FocusOut>', lambda e: self._withdraw() if not self.disable else None, add="+")
else:
self.attach.bind('<Button-1>', lambda e: self._iconify(), add="+")
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._canvas.tag_bind("right_parts", "<Button-1>", lambda e: self._iconify())
self.attach._canvas.tag_bind("dropdown_arrow", "<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
if self.attach.winfo_name().startswith("!ctkoptionmenu"):
self.attach._canvas.bind("<Button-1>", lambda e: self._iconify())
self.attach._text_label.bind("<Button-1>", lambda e: self._iconify())
if self.command is None:
self.command = self.attach.set
self.x = x
self.y = y
self.attach.bind("<Destroy>", lambda _: self._destroy(), add="+")
if self.autocomplete:
self.bind_autocomplete()
def _destroy(self):
self.after(500, self.destroy_popup)
def _withdraw(self):
if self.winfo_viewable() and self.hide:
self.place_forget()
self.event_generate("<<Closed>>")
self.hide = True
def _update(self, a, b, c):
self.live_update(self.attach._entry.get())
def bind_autocomplete(self, ):
def appear(x):
self.appear = True
if self.attach.winfo_name().startswith("!ctkcombobox"):
self.attach._entry.configure(textvariable=self.var_update)
self.attach.set(self.values[0])
self.attach._entry.bind("<Key>", appear)
self.var_update.trace_add('write', self._update)
if self.attach.winfo_name().startswith("!ctkentry"):
self.attach.configure(textvariable=self.var_update)
self.attach.bind("<Key>", appear)
self.var_update.trace_add('write', self._update)
def _init_buttons(self, **button_kwargs):
self.i = 0
self.widgets = {}
for row in self.values:
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=row,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
image=self.image_values[i] if self.image_values is not None else None,
anchor=self.justify,
command=lambda k=row: self._attach_key_press(k), **button_kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.hide = False
def destroy_popup(self):
self.destroy()
self.disable = True
def place_dropdown(self):
self.x_pos = self.attach.winfo_x() if self.x is None else self.x + self.attach.winfo_rootx()
self.y_pos = self.attach.winfo_y() + self.attach.winfo_reqheight() + 5 if self.y is None else self.y + self.attach.winfo_rooty()
self.width_new = self.attach.winfo_width()-45+self.corner if self.width is None else self.width
if self.resize:
if self.button_num<=5:
self.height_new = self.button_height * self.button_num + 55
else:
self.height_new = self.button_height * self.button_num + 35
if self.height_new>self.height:
self.height_new = self.height
self.frame.configure(width=self.width_new, height=self.height_new)
self.place(x=self.x_pos, y=self.y_pos)
if sys.platform.startswith("darwin"):
self.dummy_entry.pack()
self.after(100, self.dummy_entry.pack_forget())
self.lift()
self.attach.focus()
def _iconify(self):
if self.disable: return
if self.hide:
self.event_generate("<<Opened>>")
self.hide = False
self.place_dropdown()
else:
self.place_forget()
self.hide = True
def _attach_key_press(self, k):
self.event_generate("<<Selected>>")
self.fade = True
if self.command:
self.command(k)
self.fade = False
self.place_forget()
self.hide = True
def live_update(self, string=None):
if not self.appear: return
if self.disable: return
if self.fade: return
if string:
string = string.lower()
self._deiconify()
i=1
for key in self.widgets.keys():
s = self.widgets[key].cget("text").lower()
text_similarity = difflib.SequenceMatcher(None, s[0:len(string)], string).ratio()
similar = s.startswith(string) or text_similarity > 0.75
if not similar:
self.widgets[key].pack_forget()
else:
self.widgets[key].pack(fill="x", pady=2, padx=(self.padding, 0))
i+=1
if i==1:
self.no_match.pack(fill="x", pady=2, padx=(self.padding, 0))
else:
self.no_match.pack_forget()
self.button_num = i
self.place_dropdown()
else:
self.no_match.pack_forget()
self.button_num = len(self.values)
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
self.place_dropdown()
self.frame._parent_canvas.yview_moveto(0.0)
self.appear = False
def insert(self, value, **kwargs):
self.widgets[self.i] = customtkinter.CTkButton(self.frame,
text=value,
height=self.button_height,
fg_color=self.button_color,
text_color=self.text_color,
anchor=self.justify,
command=lambda k=value: self._attach_key_press(k), **kwargs)
self.widgets[self.i].pack(fill="x", pady=2, padx=(self.padding, 0))
self.i+=1
self.values.append(value)
def _deiconify(self):
if len(self.values)>0:
self.pack_forget()
def popup(self, x=None, y=None):
self.x = x
self.y = y
self.hide = True
self._iconify()
def configure(self, **kwargs):
if "height" in kwargs:
self.height = kwargs.pop("height")
self.height_new = self.height
if "alpha" in kwargs:
self.alpha = kwargs.pop("alpha")
if "width" in kwargs:
self.width = kwargs.pop("width")
if "fg_color" in kwargs:
self.frame.configure(fg_color=kwargs.pop("fg_color"))
if "values" in kwargs:
self.values = kwargs.pop("values")
self.image_values = None
self.button_num = len(self.values)
for key in self.widgets.keys():
self.widgets[key].destroy()
self._init_buttons()
if "image_values" in kwargs:
self.image_values = kwargs.pop("image_values")
self.image_values = None if len(self.image_values)!=len(self.values) else self.image_values
if self.image_values is not None:
i=0
for key in self.widgets.keys():
self.widgets[key].configure(image=self.image_values[i])
i+=1
if "button_color" in kwargs:
for key in self.widgets.keys():
self.widgets[key].configure(fg_color=kwargs.pop("button_color"))
for key in self.widgets.keys():
self.widgets[key].configure(**kwargs)

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

-158
View File
@@ -1,158 +0,0 @@
[
"Airi",
"Akane",
"Akane (Bunny Girl)",
"Akari",
"Ako",
"Arisu",
"Arisu (Maid)",
"Aru",
"Aru (New Year)",
"Asuna",
"Asuna (Bunny Girl)",
"Atsuko",
"Ayane",
"Ayane (Swimsuit)",
"Azusa",
"Azusa (Swimsuit)",
"Cherino",
"Cherino (Hot Spring)",
"Chihiro",
"Chinatsu",
"Chinatsu (Hot Spring)",
"Chise",
"Chise (Swimsuit)",
"Eimi",
"Fubuki",
"Fuuka",
"Fuuka (New Year)",
"Hanae",
"Hanae (Christmas)",
"Hanako",
"Hanako (Swimsuit)",
"Hare",
"Haruka",
"Haruka (New Year)",
"Haruna",
"Haruna (New Year)",
"Haruna (Sportswear)",
"Hasumi",
"Hasumi (Sportswear)",
"Hatsune Miku",
"Hibiki",
"Hibiki (Cheerleader)",
"Hifumi",
"Hifumi (Swimsuit)",
"Himari",
"Hina",
"Hina (Swimsuit)",
"Hinata",
"Hinata (Swimsuit)",
"Hiyori",
"Hoshino",
"Hoshino (Swimsuit)",
"Iori",
"Iori (Swimsuit)",
"Iroha",
"Izumi",
"Izumi (Swimsuit)",
"Izuna",
"Izuna (Swimsuit)",
"Junko",
"Junko (New Year)",
"Juri",
"Kaede",
"Kaho",
"Kanna",
"Karin",
"Karin (Bunny Girl)",
"Kayoko",
"Kayoko (New Year)",
"Kazusa",
"Kirino",
"Koharu",
"Koharu (Swimsuit)",
"Kokona",
"Kotama",
"Kotori",
"Kotori (Cheerleader)",
"Koyuki",
"Maki",
"Mari",
"Mari (Sportswear)",
"Marina",
"Mashiro",
"Mashiro (Swimsuit)",
"Megu",
"Meru",
"Michiru",
"Midori",
"Mika",
"Mimori",
"Mimori (Swimsuit)",
"Mina",
"Mine",
"Minori",
"Misaki",
"Miyako",
"Miyako (Swimsuit)",
"Miyu",
"Miyu (Swimsuit)",
"Moe",
"Momiji",
"Momoi",
"Mutsuki",
"Mutsuki (New Year)",
"Nagisa",
"Natsu",
"Neru",
"Neru (Bunny Girl)",
"Noa",
"Nodoka",
"Nodoka (Hot Spring)",
"Nonomi",
"Nonomi (Swimsuit)",
"Pina",
"Reisa",
"Rumi",
"Saki",
"Saki (Swimsuit)",
"Sakurako",
"Saori",
"Saya",
"Saya (Casual)",
"Sena",
"Serika",
"Serika (New Year)",
"Serina",
"Serina (Christmas)",
"Shigure",
"Shimiko",
"Shiroko",
"Shiroko (Riding)",
"Shiroko (Swimsuit)",
"Shizuko",
"Shizuko (Swimsuit)",
"Shun",
"Shun (Kid)",
"Sumire",
"Suzumi",
"Toki",
"Toki (Bunny Girl)",
"Tomoe",
"Tsubaki",
"Tsukuyo",
"Tsurugi",
"Tsurugi (Swimsuit)",
"Ui",
"Ui (Swimsuit)",
"Utaha",
"Utaha (Cheerleader)",
"Wakamo",
"Wakamo (Swimsuit)",
"Yoshimi",
"Yuuka",
"Yuuka (Sportswear)",
"Yuzu",
"Yuzu (Maid)"
]
-168
View File
@@ -1,168 +0,0 @@
[
"\u30a2\u30a4\u30ea",
"\u30a2\u30ab\u30cd",
"\u30a2\u30ab\u30cd\n\uff08\u30d0\u30cb\u30fc\u30ac\u30fc\u30eb\uff09",
"\u30a2\u30ab\u30ea",
"\u30a2\u30b3",
"\u30a2\u30b9\u30ca",
"\u30a2\u30b9\u30ca\n\uff08\u30d0\u30cb\u30fc\u30ac\u30fc\u30eb\uff09",
"\u30a2\u30ba\u30b5",
"\u30a2\u30ba\u30b5\uff08\u6c34\u7740\uff09",
"\u30a2\u30c4\u30b3",
"\u30a2\u30e4\u30cd",
"\u30a2\u30e4\u30cd\uff08\u6c34\u7740\uff09",
"\u30a2\u30ea\u30b9",
"\u30a2\u30ea\u30b9\uff08\u30e1\u30a4\u30c9\uff09",
"\u30a2\u30eb",
"\u30a2\u30eb\uff08\u6b63\u6708\uff09",
"\u30a4\u30aa\u30ea",
"\u30a4\u30aa\u30ea\uff08\u6c34\u7740\uff09",
"\u30a4\u30ba\u30ca",
"\u30a4\u30ba\u30ca\uff08\u6c34\u7740\uff09",
"\u30a4\u30ba\u30df",
"\u30a4\u30ba\u30df\uff08\u6c34\u7740\uff09",
"\u30a4\u30c1\u30ab",
"\u30a4\u30ed\u30cf",
"\u30a6\u30a4",
"\u30a6\u30a4\uff08\u6c34\u7740\uff09",
"\u30a6\u30bf\u30cf",
"\u30a6\u30bf\u30cf\uff08\u5fdc\u63f4\u56e3\uff09",
"\u30a8\u30a4\u30df",
"\u30a8\u30a4\u30df\uff08\u6c34\u7740\uff09",
"\u30ab\u30a8\u30c7",
"\u30ab\u30b9\u30df",
"\u30ab\u30ba\u30b5",
"\u30ab\u30db",
"\u30ab\u30e8\u30b3",
"\u30ab\u30e8\u30b3\uff08\u6b63\u6708\uff09",
"\u30ab\u30ea\u30f3",
"\u30ab\u30ea\u30f3\n\uff08\u30d0\u30cb\u30fc\u30ac\u30fc\u30eb\uff09",
"\u30ab\u30f3\u30ca",
"\u30ad\u30ad\u30e7\u30a6",
"\u30ad\u30ea\u30ce",
"\u30b3\u30b3\u30ca",
"\u30b3\u30bf\u30de",
"\u30b3\u30c8\u30ea",
"\u30b3\u30c8\u30ea\uff08\u5fdc\u63f4\u56e3\uff09",
"\u30b3\u30cf\u30eb",
"\u30b3\u30cf\u30eb\uff08\u6c34\u7740\uff09",
"\u30b3\u30e6\u30ad",
"\u30b5\u30aa\u30ea",
"\u30b5\u30ad",
"\u30b5\u30ad\uff08\u6c34\u7740\uff09",
"\u30b5\u30af\u30e9\u30b3",
"\u30b5\u30e4",
"\u30b5\u30e4\uff08\u79c1\u670d\uff09",
"\u30b7\u30b0\u30ec",
"\u30b7\u30b0\u30ec\uff08\u6e29\u6cc9\uff09",
"\u30b7\u30ba\u30b3",
"\u30b7\u30ba\u30b3\uff08\u6c34\u7740\uff09",
"\u30b7\u30df\u30b3",
"\u30b7\u30e5\u30f3",
"\u30b7\u30e5\u30f3\uff08\u5e7c\u5973\uff09",
"\u30b7\u30ed\u30b3",
"\u30b7\u30ed\u30b3\n\uff08\u30e9\u30a4\u30c7\u30a3\u30f3\u30b0\uff09",
"\u30b7\u30ed\u30b3\uff08\u6c34\u7740\uff09",
"\u30b8\u30e5\u30ea",
"\u30b8\u30e5\u30f3\u30b3",
"\u30b8\u30e5\u30f3\u30b3\uff08\u6b63\u6708\uff09",
"\u30b9\u30ba\u30df",
"\u30b9\u30df\u30ec",
"\u30bb\u30ca",
"\u30bb\u30ea\u30ab",
"\u30bb\u30ea\u30ab\uff08\u6b63\u6708\uff09",
"\u30bb\u30ea\u30ca",
"\u30bb\u30ea\u30ca\n\uff08\u30af\u30ea\u30b9\u30de\u30b9\uff09",
"\u30c1\u30a7\u30ea\u30ce",
"\u30c1\u30a7\u30ea\u30ce\uff08\u6e29\u6cc9\uff09",
"\u30c1\u30bb",
"\u30c1\u30bb\uff08\u6c34\u7740\uff09",
"\u30c1\u30ca\u30c4",
"\u30c1\u30ca\u30c4\uff08\u6e29\u6cc9\uff09",
"\u30c1\u30d2\u30ed",
"\u30c4\u30af\u30e8",
"\u30c4\u30d0\u30ad",
"\u30c4\u30eb\u30ae",
"\u30c4\u30eb\u30ae\uff08\u6c34\u7740\uff09",
"\u30c8\u30ad",
"\u30c8\u30ad\n\uff08\u30d0\u30cb\u30fc\u30ac\u30fc\u30eb\uff09",
"\u30c8\u30e2\u30a8",
"\u30ca\u30ae\u30b5",
"\u30ca\u30c4",
"\u30cd\u30eb",
"\u30cd\u30eb\n\uff08\u30d0\u30cb\u30fc\u30ac\u30fc\u30eb\uff09",
"\u30ce\u30a2",
"\u30ce\u30c9\u30ab",
"\u30ce\u30c9\u30ab\uff08\u6e29\u6cc9\uff09",
"\u30ce\u30ce\u30df",
"\u30ce\u30ce\u30df\uff08\u6c34\u7740\uff09",
"\u30cf\u30b9\u30df",
"\u30cf\u30b9\u30df\uff08\u4f53\u64cd\u670d\uff09",
"\u30cf\u30ca\u30a8",
"\u30cf\u30ca\u30a8\n\uff08\u30af\u30ea\u30b9\u30de\u30b9\uff09",
"\u30cf\u30ca\u30b3",
"\u30cf\u30ca\u30b3\uff08\u6c34\u7740\uff09",
"\u30cf\u30eb\u30ab",
"\u30cf\u30eb\u30ab\uff08\u6b63\u6708\uff09",
"\u30cf\u30eb\u30ca",
"\u30cf\u30eb\u30ca\uff08\u4f53\u64cd\u670d\uff09",
"\u30cf\u30eb\u30ca\uff08\u6b63\u6708\uff09",
"\u30cf\u30ec",
"\u30d2\u30ca",
"\u30d2\u30ca\u30bf",
"\u30d2\u30ca\u30bf\uff08\u6c34\u7740\uff09",
"\u30d2\u30ca\uff08\u6c34\u7740\uff09",
"\u30d2\u30d3\u30ad",
"\u30d2\u30d3\u30ad\uff08\u5fdc\u63f4\u56e3\uff09",
"\u30d2\u30d5\u30df",
"\u30d2\u30d5\u30df\uff08\u6c34\u7740\uff09",
"\u30d2\u30de\u30ea",
"\u30d2\u30e8\u30ea",
"\u30d5\u30a3\u30fc\u30ca",
"\u30d5\u30a6\u30ab",
"\u30d5\u30a6\u30ab\uff08\u6b63\u6708\uff09",
"\u30d5\u30d6\u30ad",
"\u30db\u30b7\u30ce",
"\u30db\u30b7\u30ce\uff08\u6c34\u7740\uff09",
"\u30de\u30ad",
"\u30de\u30b7\u30ed",
"\u30de\u30b7\u30ed\uff08\u6c34\u7740\uff09",
"\u30de\u30ea\u30ca",
"\u30de\u30ea\u30fc",
"\u30de\u30ea\u30fc\uff08\u4f53\u64cd\u670d\uff09",
"\u30df\u30ab",
"\u30df\u30b5\u30ad",
"\u30df\u30c1\u30eb",
"\u30df\u30c9\u30ea",
"\u30df\u30ca",
"\u30df\u30cd",
"\u30df\u30ce\u30ea",
"\u30df\u30e2\u30ea",
"\u30df\u30e2\u30ea\uff08\u6c34\u7740\uff09",
"\u30df\u30e4\u30b3",
"\u30df\u30e4\u30b3\uff08\u6c34\u7740\uff09",
"\u30df\u30e6",
"\u30df\u30e6\uff08\u6c34\u7740\uff09",
"\u30e0\u30c4\u30ad",
"\u30e0\u30c4\u30ad\uff08\u6b63\u6708\uff09",
"\u30e1\u30b0",
"\u30e1\u30eb",
"\u30e2\u30a8",
"\u30e2\u30df\u30b8",
"\u30e2\u30e2\u30a4",
"\u30e6\u30a6\u30ab",
"\u30e6\u30a6\u30ab\uff08\u4f53\u64cd\u670d\uff09",
"\u30e6\u30ab\u30ea",
"\u30e6\u30ba",
"\u30e6\u30ba\uff08\u30e1\u30a4\u30c9\uff09",
"\u30e8\u30b7\u30df",
"\u30eb\u30df",
"\u30ec\u30a4\u30b5",
"\u30ec\u30f3\u30b2",
"\u30ef\u30ab\u30e2",
"\u30ef\u30ab\u30e2\uff08\u6c34\u7740\uff09",
"\u4f50\u5929\u6d99\u5b50",
"\u521d\u97f3\u30df\u30af",
"\u5fa1\u5742\u7f8e\u7434",
"\u98df\u8702\u64cd\u7948"
]
-4
View File
@@ -62,10 +62,6 @@ class ArisuAutoSweeper(AzurLaneAutoScript):
from tasks.mission.mission import Mission
Mission(config=self.config, device=self.device).run()
def schedule(self):
from tasks.schedule.schedule import Schedule
Schedule(config=self.config, device=self.device).run()
def data_update(self):
from tasks.item.data_update import DataUpdate
DataUpdate(config=self.config, device=self.device).run()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

-1
View File
@@ -377,7 +377,6 @@ pre.rich-traceback-code {
#pywebio-scope-scheduler-bar,
#pywebio-scope-log-bar,
#pywebio-scope-log,
#pywebio-scope-daemon-log-bar,
#pywebio-scope-daemon-overview #pywebio-scope-groups {
font-weight: 500;
margin: 0.3125rem;
+3 -4
View File
@@ -133,13 +133,12 @@ pre.rich-traceback-code {
color: #c9d1d9;
}
#pywebio-scope-running,
#pywebio-scope-pending,
#pywebio-scope-waiting,
#pywebio-scope-scheduler-bar,
#pywebio-scope-log-bar,
#pywebio-scope-log,
#pywebio-scope-daemon-log-bar,
#pywebio-scope-running,
#pywebio-scope-pending,
#pywebio-scope-waiting,
#pywebio-scope-daemon-overview #pywebio-scope-groups {
background-color: #2f3136;
border: 1px solid #21262d;
+3 -4
View File
@@ -133,13 +133,12 @@ pre.rich-traceback-code {
border: 1px solid lightgrey;
}
#pywebio-scope-running,
#pywebio-scope-pending,
#pywebio-scope-waiting,
#pywebio-scope-scheduler-bar,
#pywebio-scope-log-bar,
#pywebio-scope-log,
#pywebio-scope-daemon-log-bar,
#pywebio-scope-running,
#pywebio-scope-pending,
#pywebio-scope-waiting,
#pywebio-scope-daemon-overview #pywebio-scope-groups {
background-color: white;
border: 1px solid lightgrey;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Some files were not shown because too many files have changed in this diff Show More