From af125173c47f0dbfc6a64ea0cbfbfcf85126bd03 Mon Sep 17 00:00:00 2001 From: Joelnir Date: Thu, 18 Feb 2016 16:28:54 +0100 Subject: [PATCH] Settings Menu Finished the settings menu and systems for saving and loading settings from a config file. --- .gitignore | 4 +- __pycache__/config.cpython-35.pyc | Bin 1717 -> 2139 bytes __pycache__/ls_connection.cpython-35.pyc | Bin 2787 -> 2787 bytes __pycache__/note_reader.cpython-35.pyc | Bin 2445 -> 2445 bytes config.py | 131 +++++---- ls_connection.py | 32 ++- main_window.py | 331 ++++++++++++----------- note_reader.py | 45 +-- resources/config.cfg | 6 + resources/settings_icon.png | Bin 0 -> 3168 bytes setting_handler.py | 328 ++++++++++++++++------ 11 files changed, 528 insertions(+), 349 deletions(-) create mode 100644 resources/config.cfg create mode 100644 resources/settings_icon.png diff --git a/.gitignore b/.gitignore index 88b6a2a..e3cb549 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ *.pyc -TESTING.py \ No newline at end of file +TESTING.py +.idea +__pycache__ \ No newline at end of file diff --git a/__pycache__/config.cpython-35.pyc b/__pycache__/config.cpython-35.pyc index 693fc9bb0275190e0b892bb126dd8beb2cec7be2..f437d4070142da731ddd6bca1a26057137c360ee 100644 GIT binary patch delta 1207 zcmYjP&2rmR7(I$)#lNxZw24!oI0@5<+t4O0?LZ*|hA740IKgr=!=+$Ue{#@ZOBqS| zsW;&j80}cWu<8Tw2yFTYVpy^2lC9bBU6~L|qci6oo$v47`&;3U()mK6kp1<~-w%Gt z0)JuZ$us|mzu;R1AV4rG5DI7pVg{swG*AkpgJwZ#I4T5-8Bi9K1LZ*l&|IRkvk1Xv zj%9xdfFM|t##1bpepDN=mzL+;+X?=A&Q_4&?e{}=sp~7qXe=*&v3|`JNW>j4C+B}JDh5T z2Wf*oNha9_8K51|W6-B?QV`s51N2$a(C45gXcyE1?Iq3agT4T@lh%0#f>;231+!*H zKPdk!#c9*%bQ-P4=IBabhoR#h23@D;xzXv&=uMF}|I^}JYp-LNU1N8@^W|7KeBbkz zqa}6uP-J%YTAi-h5XQLNa8Im(L)9J64XdUzvX@29G};G7ySu;F?u@Tq7y{crvHj|i z=ZDJ{%`4}I_0 zrAdl7Hx=c4$2ZTZFhqv77M*Dyo{z3IofF$U8aO=aIzu~_mwQyYSm`^0&ko@$8f=mQ(W#U>t*SgXLynFE0Qls zxGv!}39mD-ZBg=#34cR!>xNwDqf~MxBTb&kDD(fx_$$)1D&Z|@%uEWcNueg;mW109 z))_`RkIVD;ccgNcp|%*!r5;A@)TweadYS597sdKPz0s_H+%&rK%9$_VKa%c8(R=!X zV~uGrV9*s^)ip*XuT@m$s;*R&i6T|0Cn*1D{6{Tos*=%k70ShX>CSWX#hagUOq~A$ D_?8(@ delta 788 zcmYjOOHUI~7(LT@^g#=y+EU*CdU7Tq>3L`RD7_w;1pX zXI7H=Jn#0l0uUe=6$k|sfrx-q2oI-!p4)yD6=p5)gC<})JxIPELEe77bA3Pd{V?c1X5zrbO9)sK7fZ)zIA^Je0 zpaSR`=oaV-Xe^9NgUS&7pxdBv&>hf3*qfs&pmj7khcoX%aO{214Cn!<2%1GxhscJL z5A$6X!fS9m&oc*_2eGmUhfO)q66hhw1TBL~pcT+6=n)(ZVgU3QcHv1ic&q#iK1N=R zc4D?!t*%-nTg2>!?>nt#yVGM;s-|5t%j?yr9o_Ui*9)f9p=k%-Kg@{e#-?R)MMtw1 z%BIlko>SjDmA~gS&G5I+clI0Y!B*p7&~x|et>8r68e3_(exqGX?7A(#)^-jX#mT$j zM{z-xC;Y~1zqaGF{XP(a;dUb*{In|D`wdYz8D9}P%s(YjUU4smnGxDr|48kW!j!)FjPa~tuZP| fEw3_{kCIWkn$+by%|ka;+mmm)$8hi@35t# diff --git a/__pycache__/ls_connection.cpython-35.pyc b/__pycache__/ls_connection.cpython-35.pyc index 953c75503ab70fb0ea4b7cfeed4017cc0becb2a6..ad423dc54c09537931af7cb4d07c9b97723c49f7 100644 GIT binary patch delta 85 zcmaDX`dE}xjF*>d!^Wdw4jVZ`m>9Vy$1zng3U0p16u`(RHd%|Mhf#I%c9t)UTASCf p>M=2zZNAN(z{u#k*oKplF?O;o*K~en9yT6U9)2L^;SuK%001EJ6yN{= delta 85 zcmaDX`dE}xjF*?|=j6j-t{XW+m>9Vx$1zng3T(c~6u`(RGFgkIhf!(rc9t)UYMa-v p>M=1IZNAN(z{u#i*oKplF> max_index: index = max_index - + runtime_info["active_split"] = index - + update_GUI(window, com_socket, text1, text2) - -def set_title_notes(window, index, split_name = False): + + +def set_title_notes(window, index, split_name=False): """ Set window title to fit with displayed notes. """ title = config.DEFAULT_WINDOW["TITLE"] - - disp_index = str(index + 1) #start at 1 + + disp_index = str(index + 1) # start at 1 title += " - " + disp_index - + if split_name: title += " - " + split_name - + if runtime_info["timer_running"]: title += " - " + config.RUNNING_ALERT - + update_title(title, window) - - -def menu_font_size(text_font, menu): + + +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"]) else: runtime_info["big_font"] = True menu.entryconfig(1, label=config.MENU_OPTIONS["SMALL"]) - + update_font_size(text_font) - + + def menu_open_settings(root_wnd, apply_method, text1, text2): - settings.edit_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 + # 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) + def init_UI(root): """Draws default UI and creates event bindings.""" - - #Create communication socket + + # Create communication socket com_socket = con.init_socket() - - #Graphical components + + # Graphical components root.geometry(str(config.DEFAULT_WINDOW["WIDTH"]) + "x" + str(config.DEFAULT_WINDOW["HEIGHT"])) - + box1 = tkinter.Frame(root) box2 = tkinter.Frame(root) @@ -377,80 +382,78 @@ def init_UI(root): scroll2 = tkinter.Scrollbar(box2) scroll2.pack(side=tkinter.RIGHT, fill=tkinter.Y) - text1 = tkinter.Text( - box1, - yscrollcommand=scroll1.set, - wrap=tkinter.WORD, - cursor="arrow" - ) + box1, + yscrollcommand=scroll1.set, + wrap=tkinter.WORD, + cursor="arrow" + ) text1.insert(tkinter.END, config.DEFAULT_MSG) text1.config(state=tkinter.DISABLED) text1.pack(fill=tkinter.BOTH, expand=True) text2 = tkinter.Text( - box2, - yscrollcommand=scroll2.set, - wrap=tkinter.WORD, - cursor="arrow" - ) + box2, + yscrollcommand=scroll2.set, + wrap=tkinter.WORD, + cursor="arrow" + ) text2.insert(tkinter.END, config.DEFAULT_MSG) text2.config(state=tkinter.DISABLED) text2.pack(fill=tkinter.BOTH, expand=True) scroll1.config(command=text1.yview) scroll2.config(command=text2.yview) - - #Set font and color for text + + # Set font and color for text text_font = font.Font( - family=config.FONT["NAME"], - size=config.FONT["SMALL"] - ) + family=config.FONT["NAME"], + size=config.FONT["SMALL"] + ) 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"]) - + set_single_layout(root, box1, box2) - - #create popup menu + + # 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 + 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 + 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)) - ) + 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)) - ) - - - #Set default window icon and title + label=config.MENU_OPTIONS["SETTINGS"], + command=(lambda: menu_open_settings(root, apply_settings, text1, text2)) + ) + + # Set default window icon and title root.tk.call('wm', 'iconphoto', root._w, red_icon) update_title(config.DEFAULT_WINDOW["TITLE"], root) - - #Event binds + + # Event binds root.bind("", (lambda e: adjust_content(root, box1, box2))) root.bind("", (lambda e: show_popup(e, popup))) root.bind("", (lambda e: right_arrow(root, com_socket, text1, text2))) root.bind("", (lambda e: left_arrow(root, com_socket, text1, text2))) - - #call update loop + + # call update loop update(root, com_socket, text1, text2) - + init_UI(root) -root.mainloop() \ No newline at end of file +root.mainloop() diff --git a/note_reader.py b/note_reader.py index 3db90a1..a0b431f 100644 --- a/note_reader.py +++ b/note_reader.py @@ -15,14 +15,15 @@ these can be used for titles. all other lines of text are added as notes """ + def get_note_lines(file_path): """ Reads file at given path and returns a list containing all rows of text in given file. Returns false if file can not be read. """ - - #check so file isn't too big + + # check so file isn't too big if path.getsize(file_path) > config.MAX_FILE_SIZE: return False @@ -30,37 +31,37 @@ def get_note_lines(file_path): notes_file = open(file_path, "r") except: return False - - #read file line per line + + # read file line per line f_lines = [] keep_reading = True while keep_reading: cur_line = notes_file.readline() - + if cur_line: f_lines.append(cur_line) else: keep_reading = False return f_lines - - + + def encode_notes(note_lines): """ Takes a list containing strings. Encodes given strings according to the note formatting. Returns the list containing the notes for every split. """ - + def is_title(line): if not line: return False - + return (line[0] == "[") and (line[-1] == "]") - + def is_newline(line): return (line == "\n") or (line == "\r") - + def remove_new_line(line): if (len(line) >= 1) and (is_newline(line[-1])): return line[:-1] @@ -69,9 +70,9 @@ def encode_notes(note_lines): note_list = [] cur_notes = "" - + for line in note_lines: - #remove whitespace at beginning and end + # remove whitespace at beginning and end line = line.strip(" ") if is_newline(line): @@ -81,11 +82,11 @@ def encode_notes(note_lines): else: line = remove_new_line(line) if not is_title(line): - cur_notes += line + "\n" #newline - + cur_notes += line + "\n" # newline + if cur_notes: note_list.append(cur_notes) - + return note_list @@ -97,12 +98,12 @@ def get_notes(file_path): Returns False if file is empty. """ note_lines = get_note_lines(file_path) - + if not note_lines: return False - + note_list = encode_notes(note_lines) - + return note_list @@ -112,10 +113,10 @@ def select_file(): Returns False upon no file selection. Otherwise returns absolute path to selected file. """ - + file = file_dia.askopenfilename(filetypes=config.TEXT_FILES) - + if file: return file else: - return False \ No newline at end of file + return False diff --git a/resources/config.cfg b/resources/config.cfg new file mode 100644 index 0000000..05e2cfa --- /dev/null +++ b/resources/config.cfg @@ -0,0 +1,6 @@ +notes= +font=times new roman +font_size=12 +server_port=34 +background_color=#4d73f4 +text_color=#ff8080 diff --git a/resources/settings_icon.png b/resources/settings_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..11374a692dd24607d0a72faa1e954e40f8a27fdc GIT binary patch literal 3168 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