mirror of
https://github.com/ApfelTeeSaft/SplitNotes.git
synced 2026-08-26 19:33:39 +00:00
Finished settings menu and automatic note loads
Implemented the settings menu to the main window so the settings are applied. Moved the double layout option to the settings instead of the right click menu. Also implemented a system to automatically load the notes that were active when SplitNotes was closed last time.
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
||||
*.pyc
|
||||
TESTING.py
|
||||
.idea
|
||||
__pycache__
|
||||
__pycache__
|
||||
resources/config.cfg
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -64,7 +64,7 @@ TEXT_FILES = [
|
||||
]
|
||||
|
||||
# Default content of config.cfg file
|
||||
DEFAULT_CONFIG = "notes=\nfont_size=12\nfont=arial\ntext_color=#FFFFFF\nbackground_color=#000000\nserver_port=16834"
|
||||
DEFAULT_CONFIG = "notes=\nfont_size=12\nfont=arial\ntext_color=#000000\nbackground_color=#FFFFFF\ndouble_layout=False\nserver_port=16834"
|
||||
|
||||
# Required settings
|
||||
REQUIRED_SETTINGS = ("notes",
|
||||
@@ -72,13 +72,14 @@ REQUIRED_SETTINGS = ("notes",
|
||||
"font_size",
|
||||
"text_color",
|
||||
"background_color",
|
||||
"server_port"
|
||||
"server_port",
|
||||
"double_layout"
|
||||
)
|
||||
|
||||
# Settings window options
|
||||
SETTINGS_WINDOW = {"TITLE": "Settings",
|
||||
"WIDTH": 360,
|
||||
"HEIGHT": 280,
|
||||
"HEIGHT": 330,
|
||||
"CANCEL": "Cancel",
|
||||
"SAVE": "Save"}
|
||||
|
||||
@@ -88,12 +89,12 @@ SETTINGS_OPTIONS = {"FONT": "Font",
|
||||
"TEXT_COLOR": "Text Color",
|
||||
"BG_COLOR": "Background Color",
|
||||
"SERVER_PORT": "LiveSplit Server port",
|
||||
"DEFAULT_SERVER_PORT": "(Default is 16834)"}
|
||||
"DEFAULT_SERVER_PORT": "(Default is 16834)",
|
||||
"DOUBLE_LAYOUT": "Use double layout"}
|
||||
|
||||
# Fonts that can be selected
|
||||
AVAILABLE_FONTS = ("arial",
|
||||
"courier new",
|
||||
"comic sans",
|
||||
"fixedsys",
|
||||
"ms sans serif",
|
||||
"ms serif",
|
||||
|
||||
+4
-4
@@ -8,9 +8,9 @@ import config
|
||||
import select # used for checking if socket has data pending
|
||||
|
||||
|
||||
def ls_connect(ls_socket, call_func, window):
|
||||
def ls_connect(ls_socket, call_func, window, server_port):
|
||||
"""Connects given socket to the livesplit server."""
|
||||
con_thread = Thread(target=try_connection, args=(ls_socket, call_func, window))
|
||||
con_thread = Thread(target=try_connection, args=(ls_socket, call_func, window, server_port))
|
||||
con_thread.start()
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ def init_socket():
|
||||
return socket.socket()
|
||||
|
||||
|
||||
def try_connection(ls_socket, call_func, window):
|
||||
def try_connection(ls_socket, call_func, window, server_port):
|
||||
"""
|
||||
Tries to connect given socket to ls.
|
||||
If connection is successful given "call_func"
|
||||
@@ -27,7 +27,7 @@ def try_connection(ls_socket, call_func, window):
|
||||
(made to be ran in a separate thread)
|
||||
"""
|
||||
try:
|
||||
ls_socket.connect((config.HOST, config.PORT))
|
||||
ls_socket.connect((config.HOST, server_port))
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
+73
-72
@@ -9,16 +9,15 @@ import sys
|
||||
import config
|
||||
import ls_connection as con
|
||||
import note_reader as noter
|
||||
import setting_handler as settings
|
||||
import setting_handler
|
||||
|
||||
runtime_info = {
|
||||
"ls_connected": False,
|
||||
"timer_running": False,
|
||||
"icon_active": False,
|
||||
"active_split": -1,
|
||||
"notes": [],
|
||||
"double_layout": False,
|
||||
"big_font": False
|
||||
"server_port": 0,
|
||||
"force_reset": False
|
||||
}
|
||||
|
||||
root = tkinter.Tk()
|
||||
@@ -41,9 +40,14 @@ def update(window, com_socket, text1, text2):
|
||||
"""
|
||||
Function to loop along tkinter mainloop.
|
||||
"""
|
||||
if not runtime_info["ls_connected"]:
|
||||
if runtime_info["force_reset"]:
|
||||
#boolean flag to force a connection reset
|
||||
com_socket = reset_connection(com_socket, window, text1, text2)
|
||||
runtime_info["force_reset"] = False
|
||||
|
||||
elif not runtime_info["ls_connected"]:
|
||||
# try connecting to ls
|
||||
con.ls_connect(com_socket, server_found, window)
|
||||
con.ls_connect(com_socket, server_found, window, runtime_info["server_port"])
|
||||
else:
|
||||
# is_connected
|
||||
if runtime_info["notes"]:
|
||||
@@ -105,7 +109,7 @@ def update_GUI(window, com_socket, text1, text2):
|
||||
|
||||
if runtime_info["notes"]:
|
||||
set_title_notes(window, index, split_name)
|
||||
update_notes(window, text1, text2, index)
|
||||
update_notes(text1, text2, index)
|
||||
else:
|
||||
update_title(config.DEFAULT_WINDOW["TITLE"], window)
|
||||
|
||||
@@ -139,6 +143,7 @@ def reset_connection(com_socket, window, text1, text2):
|
||||
|
||||
# Close old and return a fresh socket
|
||||
con.close_socket(com_socket)
|
||||
|
||||
return con.init_socket()
|
||||
|
||||
|
||||
@@ -153,12 +158,10 @@ def server_found(window):
|
||||
|
||||
def update_icon(active, window):
|
||||
"""Updates icon of window depending on "active" variable"""
|
||||
if active and not runtime_info["icon_active"]:
|
||||
if active:
|
||||
window.tk.call('wm', 'iconphoto', window._w, green_icon)
|
||||
runtime_info["icon_active"] = True
|
||||
elif runtime_info["icon_active"]:
|
||||
else:
|
||||
window.tk.call('wm', 'iconphoto', window._w, red_icon)
|
||||
runtime_info["icon_active"] = False
|
||||
|
||||
|
||||
def update_title(name, window):
|
||||
@@ -205,16 +208,6 @@ def show_popup(event, menu):
|
||||
menu.post(event.x_root, event.y_root)
|
||||
|
||||
|
||||
def menu_change_layout(window, box1, box2, popup):
|
||||
"""Menu option for changing layout selected."""
|
||||
if runtime_info["double_layout"]:
|
||||
set_single_layout(window, box1, box2)
|
||||
popup.entryconfig(0, label=config.MENU_OPTIONS["DOUBLE"])
|
||||
else:
|
||||
set_double_layout(window, box1, box2)
|
||||
popup.entryconfig(0, label=config.MENU_OPTIONS["SINGLE"])
|
||||
|
||||
|
||||
def menu_load_notes(window, text1, text2, com_socket):
|
||||
"""Menu selected load notes option."""
|
||||
load_notes(window, text1, text2, com_socket)
|
||||
@@ -232,6 +225,11 @@ def load_notes(window, text1, text2, com_socket):
|
||||
# Notes loaded correctly
|
||||
runtime_info["notes"] = notes
|
||||
|
||||
# Save notes to settings
|
||||
settings = setting_handler.load_settings()
|
||||
settings["notes"] = file
|
||||
setting_handler.save_settings(settings)
|
||||
|
||||
split_c = len(notes)
|
||||
show_info(("Notes Loaded",
|
||||
("Loaded notes with " + str(split_c) + " splits.")))
|
||||
@@ -244,10 +242,9 @@ def load_notes(window, text1, text2, com_socket):
|
||||
else:
|
||||
show_info(config.ERRORS["NOTES_EMPTY"], True)
|
||||
|
||||
|
||||
def show_info(info, warning=False):
|
||||
"""
|
||||
Displays an infor popup window.
|
||||
Displays an info popup window.
|
||||
if warning is True window has a warning triangle.
|
||||
"""
|
||||
if warning:
|
||||
@@ -256,7 +253,7 @@ def show_info(info, warning=False):
|
||||
messagebox.showinfo(info[0], info[1])
|
||||
|
||||
|
||||
def update_notes(window, text1, text2, index):
|
||||
def update_notes(text1, text2, index):
|
||||
"""
|
||||
Displays notes with the given index in given text widgets.
|
||||
If index is lower than 0, displays notes for index 0.
|
||||
@@ -279,7 +276,7 @@ def update_notes(window, text1, text2, index):
|
||||
if index <= max_index:
|
||||
text1.insert(tkinter.END, runtime_info["notes"][index])
|
||||
|
||||
# cand disply notes for index+1
|
||||
# cant disply notes for index+1
|
||||
if index < max_index:
|
||||
text2.insert(tkinter.END, runtime_info["notes"][index + 1])
|
||||
|
||||
@@ -298,7 +295,10 @@ def left_arrow(window, com_socket, text1, text2):
|
||||
|
||||
|
||||
def change_preview(window, com_socket, text1, text2, move):
|
||||
"""move is either 1 for next or -1 for previous."""
|
||||
"""
|
||||
Chnges notes that are currently displayed.
|
||||
Move is either 1 for next or -1 for previous.
|
||||
"""
|
||||
if runtime_info["notes"] and (not runtime_info["timer_running"]):
|
||||
max_index = (len(runtime_info["notes"]) - 1)
|
||||
index = runtime_info["active_split"]
|
||||
@@ -334,34 +334,31 @@ def set_title_notes(window, index, split_name=False):
|
||||
update_title(title, window)
|
||||
|
||||
|
||||
def menu_font_size(text_font, menu):
|
||||
if runtime_info["big_font"]:
|
||||
runtime_info["big_font"] = False
|
||||
menu.entryconfig(1, label=config.MENU_OPTIONS["BIG"])
|
||||
def menu_open_settings(root_wnd, box1, box2, text1, text2):
|
||||
setting_handler.edit_settings(root_wnd,
|
||||
(lambda settings: apply_settings(settings,
|
||||
root_wnd,
|
||||
box1,box2,
|
||||
text1, text2)))
|
||||
|
||||
|
||||
def apply_settings(settings, window, box1, box2, text1, text2):
|
||||
#Server port change
|
||||
if not (runtime_info["server_port"] == int(settings["server_port"])):
|
||||
runtime_info["server_port"] = int(settings["server_port"])
|
||||
runtime_info["force_reset"] = True
|
||||
|
||||
text_font = (settings["font"], int(settings["font_size"]))
|
||||
|
||||
if setting_handler.decode_boolean_setting(settings["double_layout"]):
|
||||
set_double_layout(window, box1, box2)
|
||||
else:
|
||||
runtime_info["big_font"] = True
|
||||
menu.entryconfig(1, label=config.MENU_OPTIONS["SMALL"])
|
||||
set_single_layout(window, box1, box2)
|
||||
|
||||
update_font_size(text_font)
|
||||
|
||||
|
||||
def menu_open_settings(root_wnd, apply_method, text1, text2):
|
||||
settings.edit_settings(root_wnd, (lambda settings: apply_settings(settings, text1, text2)))
|
||||
|
||||
|
||||
def apply_settings(config, text1, text2):
|
||||
# TODO apply all settings to the root window
|
||||
print("Applying settings")
|
||||
print(config)
|
||||
|
||||
|
||||
def update_font_size(text_font):
|
||||
if runtime_info["big_font"]:
|
||||
font_size = config.FONT["BIG"]
|
||||
else:
|
||||
font_size = config.FONT["SMALL"]
|
||||
|
||||
text_font.config(size=font_size)
|
||||
text1.config(font=text_font)
|
||||
text2.config(font=text_font)
|
||||
text1.config(fg=settings["text_color"], bg=settings["background_color"])
|
||||
text2.config(fg=settings["text_color"], bg=settings["background_color"])
|
||||
|
||||
|
||||
def init_UI(root):
|
||||
@@ -370,6 +367,10 @@ def init_UI(root):
|
||||
# Create communication socket
|
||||
com_socket = con.init_socket()
|
||||
|
||||
# Load Settings
|
||||
settings = setting_handler.load_settings()
|
||||
runtime_info["server_port"] = int(settings["server_port"])
|
||||
|
||||
# Graphical components
|
||||
root.geometry(str(config.DEFAULT_WINDOW["WIDTH"]) + "x" + str(config.DEFAULT_WINDOW["HEIGHT"]))
|
||||
|
||||
@@ -392,6 +393,7 @@ def init_UI(root):
|
||||
text1.config(state=tkinter.DISABLED)
|
||||
text1.pack(fill=tkinter.BOTH, expand=True)
|
||||
|
||||
|
||||
text2 = tkinter.Text(
|
||||
box2,
|
||||
yscrollcommand=scroll2.set,
|
||||
@@ -406,44 +408,43 @@ def init_UI(root):
|
||||
scroll2.config(command=text2.yview)
|
||||
|
||||
# Set font and color for text
|
||||
text_font = font.Font(
|
||||
family=config.FONT["NAME"],
|
||||
size=config.FONT["SMALL"]
|
||||
)
|
||||
text_font = (settings["font"], int(settings["font_size"]))
|
||||
|
||||
text1.config(font=text_font)
|
||||
text2.config(font=text_font)
|
||||
text1.config(fg=config.COLOR["TEXT"], bg=config.COLOR["TEXT_BG"])
|
||||
text2.config(fg=config.COLOR["TEXT"], bg=config.COLOR["TEXT_BG"])
|
||||
text1.config(fg=settings["text_color"], bg=settings["background_color"])
|
||||
text2.config(fg=settings["text_color"], bg=settings["background_color"])
|
||||
|
||||
set_single_layout(root, box1, box2)
|
||||
if setting_handler.decode_boolean_setting(settings["double_layout"]):
|
||||
set_double_layout(root, box1, box2)
|
||||
else:
|
||||
set_single_layout(root, box1, box2)
|
||||
|
||||
# create popup menu
|
||||
popup = tkinter.Menu(root, tearoff=0)
|
||||
popup.add_command(
|
||||
label=config.MENU_OPTIONS["DOUBLE"],
|
||||
command=(
|
||||
lambda: menu_change_layout(root, box1, box2, popup)
|
||||
)
|
||||
) # Needs to be at index 0
|
||||
popup.add_command(
|
||||
label=config.MENU_OPTIONS["BIG"],
|
||||
command=(
|
||||
lambda: menu_font_size(text_font, popup)
|
||||
)
|
||||
) # Needs to be at index 1
|
||||
popup.add_command(
|
||||
label=config.MENU_OPTIONS["LOAD"],
|
||||
command=(lambda: menu_load_notes(root, text1, text2, com_socket))
|
||||
)
|
||||
popup.add_command(
|
||||
label=config.MENU_OPTIONS["SETTINGS"],
|
||||
command=(lambda: menu_open_settings(root, apply_settings, text1, text2))
|
||||
command=(lambda: menu_open_settings(root, box1, box2, text1, text2))
|
||||
)
|
||||
|
||||
# Set default window icon and title
|
||||
root.tk.call('wm', 'iconphoto', root._w, red_icon)
|
||||
update_title(config.DEFAULT_WINDOW["TITLE"], root)
|
||||
|
||||
# Check if notes can be loaded from settings
|
||||
settings = setting_handler.load_settings()
|
||||
|
||||
if settings["notes"] and noter.file_exists(settings["notes"]):
|
||||
notes = noter.get_notes(settings["notes"])
|
||||
|
||||
if notes:
|
||||
runtime_info["notes"] = notes
|
||||
update_GUI(root, com_socket, text1, text2)
|
||||
|
||||
# Event binds
|
||||
root.bind("<Configure>", (lambda e: adjust_content(root, box1, box2)))
|
||||
root.bind("<Button-3>", (lambda e: show_popup(e, popup)))
|
||||
|
||||
@@ -120,3 +120,7 @@ def select_file():
|
||||
return file
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def file_exists(file):
|
||||
return path.isfile(file)
|
||||
@@ -1,6 +1,7 @@
|
||||
notes=
|
||||
font=times new roman
|
||||
font_size=12
|
||||
server_port=34
|
||||
background_color=#4d73f4
|
||||
text_color=#ff8080
|
||||
notes=C:/Users/Joel/Documents/EA Games/Mirror's Edge/TdGame/Config/TdEngine.ini
|
||||
server_port=16834
|
||||
text_color=#000000
|
||||
double_layout=True
|
||||
font_size=11
|
||||
font=ms sans serif
|
||||
background_color=#ffffff
|
||||
|
||||
+39
-9
@@ -18,6 +18,7 @@ settings_icon_path = os.path.join(
|
||||
config.ICONS["SETTINGS"]
|
||||
)
|
||||
|
||||
|
||||
def load_settings():
|
||||
"""
|
||||
Tries to load settings from file.
|
||||
@@ -65,10 +66,11 @@ def format_settings(file_rows):
|
||||
|
||||
for row in file_rows:
|
||||
row = row.strip("\n")
|
||||
parts = row.split("=")
|
||||
parts = row.split("=", 1)
|
||||
|
||||
if len(parts) == SETTING_PART_LENGTH:
|
||||
settings[parts[0]] = parts[1]
|
||||
# Strip to remove whitespace at end and beginning
|
||||
settings[parts[0].strip()] = parts[1].strip()
|
||||
|
||||
return settings
|
||||
|
||||
@@ -115,6 +117,10 @@ def validate_settings(settings):
|
||||
if not (settings["font"] in config.AVAILABLE_FONTS):
|
||||
return False
|
||||
|
||||
if not ((settings["double_layout"] == "True") or
|
||||
(settings["double_layout"] == "False")):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
@@ -156,6 +162,9 @@ def edit_settings(root_wnd, apply_method):
|
||||
bg_color_label = tkinter.Label(settings_wnd,
|
||||
text=config.SETTINGS_OPTIONS["BG_COLOR"],
|
||||
font=config.GUI_FONT)
|
||||
layout_label = tkinter.Label(settings_wnd,
|
||||
text=config.SETTINGS_OPTIONS["DOUBLE_LAYOUT"],
|
||||
font=config.GUI_FONT)
|
||||
port_label = tkinter.Label(settings_wnd,
|
||||
text=config.SETTINGS_OPTIONS["SERVER_PORT"],
|
||||
font=config.GUI_FONT)
|
||||
@@ -163,6 +172,7 @@ def edit_settings(root_wnd, apply_method):
|
||||
text=config.SETTINGS_OPTIONS["DEFAULT_SERVER_PORT"],
|
||||
font=config.GUI_FONT)
|
||||
|
||||
|
||||
# Font Selection
|
||||
selected_font = tkinter.StringVar(settings_wnd)
|
||||
selected_font.set(settings["font"])
|
||||
@@ -211,7 +221,6 @@ def edit_settings(root_wnd, apply_method):
|
||||
def bg_color_selection():
|
||||
choosen_color = colorchooser.askcolor()
|
||||
if choosen_color[1]:
|
||||
print(choosen_color)
|
||||
settings["background_color"] = choosen_color[1]
|
||||
bg_color.configure(background=settings["background_color"])
|
||||
|
||||
@@ -223,6 +232,13 @@ def edit_settings(root_wnd, apply_method):
|
||||
port_entry = tkinter.Entry(settings_wnd, width=6, font=config.GUI_FONT)
|
||||
port_entry.insert(0, settings["server_port"])
|
||||
|
||||
# Double Layout Selection
|
||||
double_layout = tkinter.BooleanVar()
|
||||
double_layout_btn = tkinter.Checkbutton(settings_wnd, variable=double_layout)
|
||||
|
||||
if decode_boolean_setting(settings["double_layout"]):
|
||||
double_layout_btn.select()
|
||||
|
||||
# Save and cancel buttons
|
||||
def control_and_save():
|
||||
errors_found = False
|
||||
@@ -232,6 +248,8 @@ def edit_settings(root_wnd, apply_method):
|
||||
chosen_font_size = font_size_entry.get()
|
||||
chosen_port = port_entry.get()
|
||||
|
||||
settings["double_layout"] = encode_boolean_setting(double_layout.get())
|
||||
|
||||
if not validate_font_size(chosen_font_size):
|
||||
msgbox.showerror(config.ERRORS["FONT_SIZE"][0], config.ERRORS["FONT_SIZE"][1])
|
||||
errors_found = True
|
||||
@@ -265,17 +283,19 @@ def edit_settings(root_wnd, apply_method):
|
||||
font_size_label.place(x=15, y=55)
|
||||
text_color_label.place(x=15, y=95)
|
||||
bg_color_label.place(x=15, y=135)
|
||||
port_label.place(x=15, y=175)
|
||||
default_port_label.place(x=15, y=200)
|
||||
layout_label.place(x=15, y=175)
|
||||
port_label.place(x=15, y=215)
|
||||
default_port_label.place(x=15, y=240)
|
||||
|
||||
font_dropdown.place(x=178, y=15)
|
||||
font_size_entry.place(x=180, y=55)
|
||||
text_color.place(x=180, y=95)
|
||||
bg_color.place(x=180, y=135)
|
||||
port_entry.place(x=180, y=175)
|
||||
double_layout_btn.place(x=180, y=175)
|
||||
port_entry.place(x=180, y=215)
|
||||
|
||||
save_btn.place(x=110, y=230)
|
||||
cancel_btn.place(x=190, y=230)
|
||||
save_btn.place(x=110, y=280)
|
||||
cancel_btn.place(x=190, y=280)
|
||||
|
||||
|
||||
def validate_color(color):
|
||||
@@ -314,4 +334,14 @@ def save_settings(settings):
|
||||
for key in settings.keys():
|
||||
file_content += key + "=" + settings[key] + "\n"
|
||||
|
||||
set_settings_file_content(file_content)
|
||||
set_settings_file_content(file_content)
|
||||
|
||||
|
||||
def decode_boolean_setting(setting):
|
||||
return setting == "True"
|
||||
|
||||
def encode_boolean_setting(value):
|
||||
if value:
|
||||
return "True"
|
||||
else:
|
||||
return "False"
|
||||
|
||||
Reference in New Issue
Block a user