From d74a5e1ae45072296d29c4cd3eeeaa6268a4ac0e Mon Sep 17 00:00:00 2001 From: Looki2000 Date: Sat, 16 Mar 2024 21:57:13 +0100 Subject: [PATCH] added glyph text copy button, single button draw, configurable guide lines, initial dark theme --- .gitignore | 9 ++--- canvas.py | 56 ++++++++++++++++++------------- main.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 129 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index a087069..6052bb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ __pycache__/ -exports/* +.vscode/ + last_path_cache.txt -*.fontproj -test export/ -.vscode/ \ No newline at end of file +grid_values.txt + +*.fontproj \ No newline at end of file diff --git a/canvas.py b/canvas.py index 3ea2c70..4c46fb1 100644 --- a/canvas.py +++ b/canvas.py @@ -1,14 +1,15 @@ import base64 import tkinter +import clipboard GRID_COLOR = "#808080" -GRID_GUIDE_COLOR = (128, 128, 255) +GRID_GUIDE_COLOR = "#51bbfe" class EditorCanvas(tkinter.Canvas): def __init__(self,project,*args,**kwargs): super().__init__(*args,**kwargs) self.project=project - self.grid_size = 32 + self.grid_size = 64 self.current_char=33 self.current_char_pixels=[] self.current_char_modified=False @@ -18,24 +19,32 @@ class EditorCanvas(tkinter.Canvas): self.prev_mouse_y=0 self.view_x=0 self.view_y=0 + self.draw_color = 0 + self.guide_pos = () + + self.bind("",self.handle_draw_start) self.bind("",self.handle_draw) - self.bind("",self.handle_draw) + self.bind("",self.handle_move_start) self.bind("",self.handle_move) - self.bind("",self.handle_erase) - self.bind("",self.handle_erase) + def set_guide_pos(self, pos): + self.guide_pos = pos + self.draw() def draw(self): self.delete("all") # draw grid for x in range(self.project.char_res[0] + 1): - x = x * self.grid_size+self.view_x + x = x * self.grid_size + self.view_x self.create_line((x,self.view_y),(x,self.view_y+self.height),width=1,fill=GRID_COLOR) + for y in range(self.project.char_res[1] + 1): - y = y * self.grid_size+self.view_y - self.create_line((self.view_x,y),(self.view_x+self.width,y),width=1,fill=GRID_COLOR) + temp_color = GRID_GUIDE_COLOR if y in self.guide_pos else GRID_COLOR + + y = y * self.grid_size + self.view_y + self.create_line((self.view_x,y),(self.view_x+self.width,y),width=1,fill=temp_color) if self.project.does_char_exist(self.current_char) or self.current_char_modified: for i in range(len(self.current_char_pixels)): @@ -48,13 +57,22 @@ class EditorCanvas(tkinter.Canvas): self.create_line((self.view_x+self.width,self.view_y),(self.view_x,self.view_y+self.height),width=3,fill="red") - def handle_draw(self,event): - pixel_pos=self.cursor_pos_to_pixel((event.x,event.y)) + def handle_draw_start(self,event): + pixel_pos = self.cursor_pos_to_pixel((event.x,event.y)) if not pixel_pos: return - self.current_char_modified=True - self.project.modified=True - self.current_char_pixels[pixel_pos[0]*self.project.char_res[1]+pixel_pos[1]]=1 + self.draw_color = 1 - self.current_char_pixels[pixel_pos[0]*self.project.char_res[1]+pixel_pos[1]] + + self.handle_draw(event) + + + def handle_draw(self,event): + pixel_pos = self.cursor_pos_to_pixel((event.x,event.y)) + if not pixel_pos: + return + self.current_char_modified = True + self.project.modified = True + self.current_char_pixels[pixel_pos[0]*self.project.char_res[1]+pixel_pos[1]] = self.draw_color self.draw() @@ -71,16 +89,6 @@ class EditorCanvas(tkinter.Canvas): self.draw() - def handle_erase(self,event): - pixel_pos=self.cursor_pos_to_pixel((event.x,event.y)) - if not pixel_pos: - return - self.current_char_modified=True - self.project.modified=True - self.current_char_pixels[pixel_pos[0]*self.project.char_res[1]+pixel_pos[1]]=0 - self.draw() - - def zoom_by(self,amount): self.grid_size+=amount if self.grid_size<12: @@ -171,3 +179,5 @@ class EditorCanvas(tkinter.Canvas): self.current_char_pixels=[0 for _ in range(self.project.char_res[0]*self.project.char_res[1])] self.load_char() + def copy_char(self): + clipboard.copy(chr(self.current_char)) diff --git a/main.py b/main.py index 9238e88..c356cf8 100644 --- a/main.py +++ b/main.py @@ -16,6 +16,8 @@ WINDOW_SIZE = ( cross_color = (255, 60, 25) pixel_color = (255,) * 3 +bg_col = "#1e1e1e" + ################## project=Project() @@ -192,7 +194,7 @@ def button_glyph_search_click(): def number_only_validate(val): - return val.isdigit() + return val.isdigit() or val=="" def hex_only_validate(val): @@ -209,7 +211,7 @@ def update_glyph_preview(): canvas_preview.delete("all") canvas_preview.create_text((50,100),text=chr(canvas_editor.current_char),fill="white",font="tkDefaultFont 70") name=unicodedata.name(chr(canvas_editor.current_char),"unknown") - label_glyph_name.config(text=f"{name} U+{canvas_editor.current_char:04x}") + label_glyph_name.config(text=f"{canvas_editor.current_char}\n{name}\nU+{canvas_editor.current_char:04x}") def canvas_editor_handle_scroll(delta): @@ -228,6 +230,7 @@ window=tkinter.Tk() window.title("fonteditor") window.geometry(f"{WINDOW_SIZE[0]}x{WINDOW_SIZE[1]}") + menubar=tkinter.Menu(window) menu_file=tkinter.Menu(menubar,tearoff=False) menu_file.add_command(label="New project",command=menu_file_new_project_click) @@ -254,15 +257,95 @@ else: canvas_editor.bind("",lambda _: canvas_editor_handle_scroll(1)) canvas_editor.bind("",lambda _: canvas_editor_handle_scroll(-1)) -frame_controls=tkinter.Frame(window) + + +#### Guide pos #### + +frame_label_guide_pos = tkinter.Frame(window, bg=bg_col) +frame_label_guide_pos.pack(side="right") + +label_1 = tkinter.Label(frame_label_guide_pos, text="Guide 1 Y", bg=bg_col, fg="#ffffff").pack(side="top") +entry_1 = tkinter.Entry(frame_label_guide_pos, validate="all", validatecommand=((window.register(number_only_validate)),"%P")) +entry_1.pack(side="top", pady=2) + +label_2 = tkinter.Label(frame_label_guide_pos, text="Guide 2 Y", bg=bg_col, fg="#ffffff").pack(side="top") +entry_2 = tkinter.Entry(frame_label_guide_pos, validate="all", validatecommand=((window.register(number_only_validate)),"%P")) +entry_2.pack(side="top", pady=2) + +label_3 = tkinter.Label(frame_label_guide_pos, text="Guide 3 Y", bg=bg_col, fg="#ffffff").pack(side="top") +entry_3 = tkinter.Entry(frame_label_guide_pos, validate="all", validatecommand=((window.register(number_only_validate)),"%P")) +entry_3.pack(side="top", pady=2) + + +## load last values +cwd = os.path.dirname(os.path.realpath(__file__)) +grid_vals_path = os.path.join(cwd, "grid_values.txt") + + +def get_grid_entries(): + return ( + int(entry_1.get()), + int(entry_2.get()), + int(entry_3.get()) + ) + + +def update_guide_pos(pos, dont_save=False): + canvas_editor.set_guide_pos(pos) + + if dont_save: + return + + with open(grid_vals_path, "w") as f: + f.write(f"{entry_1.get()}\n{entry_2.get()}\n{entry_3.get()}") + + +if os.path.exists(grid_vals_path): + with open(grid_vals_path, "r") as f: + lines = f.readlines() + entry_1.insert(0, lines[0].strip()) + entry_2.insert(0, lines[1].strip()) + entry_3.insert(0, lines[2].strip()) + + update_guide_pos(get_grid_entries(), dont_save=True) + +else: + entry_1.insert(0, "2") + entry_2.insert(0, "4") + entry_3.insert(0, "10") + + update_guide_pos(get_grid_entries()) + + +set_button = tkinter.Button( + frame_label_guide_pos, + text="Set", + command=lambda: update_guide_pos(get_grid_entries()) +).pack(side="top", pady=[5, 30]) + + +#### Copy #### + +frame = tkinter.Frame(frame_label_guide_pos, bg=bg_col) +frame.pack(side="right") + +copy_button = tkinter.Button(frame, text="Copy", command=canvas_editor.copy_char) +copy_button.pack(side="top", pady=5) + + +#### Preview #### +frame_controls=tkinter.Frame(frame, bg=bg_col) frame_controls.pack(side="right") canvas_preview=tkinter.Canvas(frame_controls,width=100,height=200,bg="black") canvas_preview.pack(side="top") -label_glyph_name=tkinter.Label(frame_controls) +label_glyph_name=tkinter.Label(frame_controls, bg=bg_col, fg="#ffffff") label_glyph_name.pack(side="top") + +#### Navigation #### + frame_nav=tkinter.Frame(frame_controls) frame_nav.pack(side="top",pady=10) @@ -272,6 +355,9 @@ button_prev_glyph.pack(side="left") button_next_glyph=tkinter.Button(frame_nav,width=10,text="Next",command=button_next_glyph_click) button_next_glyph.pack(side="left") + +#### Glyph search #### + frame_glyph_id=tkinter.Frame(frame_controls) frame_glyph_id.pack(side="top",pady=10) @@ -281,5 +367,5 @@ entry_glyph_id.pack(side="left") button_glyph_search=tkinter.Button(frame_glyph_id,width=10,text="Search",command=button_glyph_search_click) button_glyph_search.pack(side="left") -window.config(menu=menubar) +window.config(menu=menubar, bg=bg_col) window.mainloop()