Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 971a572865 | |||
| bd7db53a9d | |||
| 6edf1a6188 | |||
| 81a7e375ff | |||
| b542929c04 | |||
| 613dcf3d7d |
294
main.py
294
main.py
@@ -1,8 +1,9 @@
|
|||||||
import tkinter as tk
|
import customtkinter as ctk
|
||||||
from tkinter import filedialog, messagebox, simpledialog, ttk
|
from tkinter import filedialog, messagebox, simpledialog, ttk
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
# Load translations from JSON file
|
# Load translations from JSON file
|
||||||
with open('translations.json', 'r', encoding='utf-8') as f:
|
with open('translations.json', 'r', encoding='utf-8') as f:
|
||||||
@@ -30,7 +31,7 @@ def open_file():
|
|||||||
global file_path, image, tk_image, zoom_level
|
global file_path, image, tk_image, zoom_level
|
||||||
file_path = filedialog.askopenfilename(title=translations["open_file"][language.get()], filetypes=[("All Files", "*.*")])
|
file_path = filedialog.askopenfilename(title=translations["open_file"][language.get()], filetypes=[("All Files", "*.*")])
|
||||||
if file_path:
|
if file_path:
|
||||||
file_label.config(text=f"{translations['selected_file'][language.get()]} {file_path.split('/')[-1]}")
|
file_label.configure(text=f"{translations['selected_file'][language.get()]} {file_path.split('/')[-1]}")
|
||||||
try:
|
try:
|
||||||
# Проверка расширения
|
# Проверка расширения
|
||||||
if not file_path.lower().endswith('.bin'):
|
if not file_path.lower().endswith('.bin'):
|
||||||
@@ -44,7 +45,7 @@ def open_file():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
messagebox.showerror(translations["error"][language.get()], f"{translations['file_processing_error'][language.get()]}: {e}")
|
messagebox.showerror(translations["error"][language.get()], f"{translations['file_processing_error'][language.get()]}: {e}")
|
||||||
else:
|
else:
|
||||||
file_label.config(text=translations["no_file_selected"][language.get()])
|
file_label.configure(text=translations["no_file_selected"][language.get()])
|
||||||
|
|
||||||
def reload_image():
|
def reload_image():
|
||||||
global image, tk_image
|
global image, tk_image
|
||||||
@@ -61,8 +62,8 @@ def display_image():
|
|||||||
if image:
|
if image:
|
||||||
zoomed_image = image.resize((int(image.width * zoom_level), int(image.height * zoom_level)), Image.NEAREST)
|
zoomed_image = image.resize((int(image.width * zoom_level), int(image.height * zoom_level)), Image.NEAREST)
|
||||||
tk_image = ImageTk.PhotoImage(zoomed_image)
|
tk_image = ImageTk.PhotoImage(zoomed_image)
|
||||||
canvas.config(scrollregion=(0, 0, zoomed_image.width, zoomed_image.height))
|
canvas.configure(scrollregion=(0, 0, zoomed_image.width, zoomed_image.height))
|
||||||
canvas.create_image(0, 0, anchor=tk.NW, image=tk_image)
|
canvas.create_image(0, 0, anchor=ctk.NW, image=tk_image)
|
||||||
|
|
||||||
# Clear existing grid lines
|
# Clear existing grid lines
|
||||||
canvas.delete("grid_line")
|
canvas.delete("grid_line")
|
||||||
@@ -133,11 +134,11 @@ def open_table_window():
|
|||||||
messagebox.showerror(translations["error"][language.get()], translations["open_image_first"][language.get()])
|
messagebox.showerror(translations["error"][language.get()], translations["open_image_first"][language.get()])
|
||||||
return
|
return
|
||||||
|
|
||||||
table_window = tk.Toplevel(root)
|
table_window = ctk.CTkToplevel(root)
|
||||||
table_window.title(translations["pixel_table"][language.get()])
|
table_window.title(translations["pixel_table"][language.get()])
|
||||||
|
|
||||||
table_frame = tk.Frame(table_window)
|
table_frame = ctk.CTkFrame(table_window)
|
||||||
table_frame.pack(fill=tk.BOTH, expand=True)
|
table_frame.pack(fill=ctk.BOTH, expand=True)
|
||||||
|
|
||||||
columns = simpledialog.askinteger(translations["table_settings"][language.get()], translations["enter_columns"][language.get()], initialvalue=16)
|
columns = simpledialog.askinteger(translations["table_settings"][language.get()], translations["enter_columns"][language.get()], initialvalue=16)
|
||||||
if not columns:
|
if not columns:
|
||||||
@@ -148,13 +149,13 @@ def open_table_window():
|
|||||||
tree.heading(f"col{i}", text=f"{translations['column'][language.get()]} {i+1}")
|
tree.heading(f"col{i}", text=f"{translations['column'][language.get()]} {i+1}")
|
||||||
tree.column(f"col{i}", width=50, anchor='center')
|
tree.column(f"col{i}", width=50, anchor='center')
|
||||||
|
|
||||||
scrollbar_y = ttk.Scrollbar(table_frame, orient=tk.VERTICAL, command=tree.yview)
|
scrollbar_y = ttk.Scrollbar(table_frame, orient=ctk.VERTICAL, command=tree.yview)
|
||||||
scrollbar_x = ttk.Scrollbar(table_frame, orient=tk.HORIZONTAL, command=tree.xview)
|
scrollbar_x = ttk.Scrollbar(table_frame, orient=ctk.HORIZONTAL, command=tree.xview)
|
||||||
tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
|
tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
|
||||||
|
|
||||||
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
|
scrollbar_y.pack(side=ctk.RIGHT, fill=ctk.Y)
|
||||||
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
|
scrollbar_x.pack(side=ctk.BOTTOM, fill=ctk.X)
|
||||||
tree.pack(fill=tk.BOTH, expand=True)
|
tree.pack(fill=ctk.BOTH, expand=True)
|
||||||
|
|
||||||
pixels = np.array(image.convert('L'))
|
pixels = np.array(image.convert('L'))
|
||||||
rows = pixels.shape[0]
|
rows = pixels.shape[0]
|
||||||
@@ -167,7 +168,7 @@ def open_table_window():
|
|||||||
values.append(pixels[row, col])
|
values.append(pixels[row, col])
|
||||||
else:
|
else:
|
||||||
values.append('')
|
values.append('')
|
||||||
tree.insert('', tk.END, values=values)
|
tree.insert('', ctk.END, values=values)
|
||||||
|
|
||||||
def export_image():
|
def export_image():
|
||||||
if not image:
|
if not image:
|
||||||
@@ -219,25 +220,198 @@ def update_zoom_level(value):
|
|||||||
def bind_hot_reload(event):
|
def bind_hot_reload(event):
|
||||||
reload_image()
|
reload_image()
|
||||||
|
|
||||||
|
def export_to_folder():
|
||||||
|
if not image:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], translations["open_image_first"][language.get()])
|
||||||
|
return
|
||||||
|
|
||||||
|
folder_path = filedialog.askdirectory(title=translations["select_folder"][language.get()])
|
||||||
|
if not folder_path:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
width = int(width_entry.get())
|
||||||
|
cell_size = width
|
||||||
|
img_width, img_height = image.size
|
||||||
|
|
||||||
|
# Create info file
|
||||||
|
with open(os.path.join(folder_path, 'info.txt'), 'w') as f:
|
||||||
|
f.write(str(width))
|
||||||
|
|
||||||
|
# Calculate grid dimensions
|
||||||
|
cols = img_width // cell_size
|
||||||
|
rows = img_height // cell_size
|
||||||
|
|
||||||
|
# Save each cell
|
||||||
|
for row in range(rows):
|
||||||
|
for col in range(cols):
|
||||||
|
left = col * cell_size
|
||||||
|
upper = row * cell_size
|
||||||
|
right = left + cell_size
|
||||||
|
lower = upper + cell_size
|
||||||
|
|
||||||
|
cell = image.crop((left, upper, right, lower))
|
||||||
|
cell.save(os.path.join(folder_path, f"{row}_{col}.tiff"))
|
||||||
|
|
||||||
|
messagebox.showinfo(translations["success"][language.get()], translations["image_exported"][language.get()])
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], f"Export error: {str(e)}")
|
||||||
|
|
||||||
|
def import_from_folder():
|
||||||
|
global image, zoom_level
|
||||||
|
folder_path = filedialog.askdirectory(title=translations["select_folder"][language.get()])
|
||||||
|
if not folder_path:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Read width info
|
||||||
|
with open(os.path.join(folder_path, 'info.txt'), 'r') as f:
|
||||||
|
saved_width = int(f.read().strip())
|
||||||
|
|
||||||
|
current_width = int(width_entry.get())
|
||||||
|
if saved_width != current_width:
|
||||||
|
messagebox.showerror(
|
||||||
|
translations["error"][language.get()],
|
||||||
|
translations["width_mismatch_error"][language.get()].format(
|
||||||
|
expected=current_width, actual=saved_width
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Collect and sort cell files
|
||||||
|
cell_files = []
|
||||||
|
for fname in os.listdir(folder_path):
|
||||||
|
if fname.endswith('.tiff'):
|
||||||
|
try:
|
||||||
|
parts = fname.split('_')
|
||||||
|
row = int(parts[0])
|
||||||
|
col = int(parts[1].split('.')[0])
|
||||||
|
cell_files.append((row, col, fname))
|
||||||
|
except:
|
||||||
|
messagebox.showerror(
|
||||||
|
translations["error"][language.get()],
|
||||||
|
translations["invalid_filename_error"][language.get()].format(filename=fname))
|
||||||
|
return
|
||||||
|
|
||||||
|
if not cell_files:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], translations["no_cell_files"][language.get()])
|
||||||
|
return
|
||||||
|
|
||||||
|
# Sort files by row and column
|
||||||
|
cell_files.sort()
|
||||||
|
max_row = max(r for r, c, _ in cell_files)
|
||||||
|
max_col = max(c for r, c, _ in cell_files)
|
||||||
|
|
||||||
|
# Create empty image
|
||||||
|
cell_size = current_width
|
||||||
|
full_width = (max_col + 1) * cell_size
|
||||||
|
full_height = (max_row + 1) * cell_size
|
||||||
|
new_image = Image.new('L', (full_width, full_height))
|
||||||
|
|
||||||
|
# Paste cells
|
||||||
|
for row, col, fname in cell_files:
|
||||||
|
cell_path = os.path.join(folder_path, fname)
|
||||||
|
cell = Image.open(cell_path).convert('L')
|
||||||
|
x = col * cell_size
|
||||||
|
y = row * cell_size
|
||||||
|
new_image.paste(cell, (x, y))
|
||||||
|
|
||||||
|
image = new_image
|
||||||
|
zoom_level = 1.0
|
||||||
|
display_image()
|
||||||
|
messagebox.showinfo(
|
||||||
|
translations["success"][language.get()],
|
||||||
|
translations["image_imported"][language.get()]
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], f"Import error: {str(e)}")
|
||||||
|
|
||||||
def update_language(*args):
|
def update_language(*args):
|
||||||
language_code = language.get()
|
language_code = language.get()
|
||||||
root.title(translations["title"][language_code])
|
root.title(translations["title"][language_code])
|
||||||
notebook.tab(editor_tab, text=translations["editor_tab"][language_code])
|
notebook.tab(editor_tab, text=translations["editor_tab"][language_code])
|
||||||
notebook.tab(settings_tab, text=translations["settings_tab"][language_code])
|
notebook.tab(settings_tab, text=translations["settings_tab"][language_code])
|
||||||
file_label.config(text=translations["no_file_selected"][language_code])
|
file_label.configure(text=translations["no_file_selected"][language_code])
|
||||||
open_button.config(text=translations["open_file_button"][language_code])
|
open_button.configure(text=translations["open_file_button"][language_code])
|
||||||
width_label.config(text=translations["width_label"][language_code])
|
width_label.configure(text=translations["width_label"][language_code])
|
||||||
table_button.config(text=translations["open_table_button"][language_code])
|
table_button.configure(text=translations["open_table_button"][language_code])
|
||||||
save_button.config(text=translations["save_image_button"][language_code])
|
save_button.configure(text=translations["save_image_button"][language_code])
|
||||||
save_bin_button.config(text=translations["save_bin_button"][language_code])
|
save_bin_button.configure(text=translations["save_bin_button"][language.get()])
|
||||||
reload_button.config(text=translations["reload_image_button"][language_code])
|
reload_button.configure(text=translations["reload_image_button"][language_code])
|
||||||
redraw_grid_button.config(text=translations["redraw_grid_button"][language_code])
|
redraw_grid_button.configure(text=translations["redraw_grid_button"][language_code])
|
||||||
export_button.config(text=translations["export_image_button"][language_code])
|
export_button.configure(text=translations["export_image_button"][language_code])
|
||||||
import_button.config(text=translations["import_image_button"][language_code])
|
import_button.configure(text=translations["import_image_button"][language.get()])
|
||||||
language_label.config(text=translations["language_label"][language_code])
|
language_label.configure(text=translations["language_label"][language_code])
|
||||||
grid_color_label.config(text=translations["grid_color_label"][language_code])
|
grid_color_label.configure(text=translations["grid_color_label"][language_code])
|
||||||
|
show_kanji_button.configure(text=translations["show_kanji_button"][language_code])
|
||||||
|
export_folder_button.configure(text=translations["export_folder_button"][language.get()])
|
||||||
|
import_folder_button.configure(text=translations["import_folder_button"][language.get()])
|
||||||
|
|
||||||
root = tk.Tk()
|
def fromhex(a):
|
||||||
|
hex_from_str = {'0':'0000', '1':'0001', '2':'0010', '3':'0011',
|
||||||
|
'4':'0100', '5':'0101', '6':'0110', '7':'0111', '8':'1000',
|
||||||
|
'9':'1001', 'A':'1010', 'B':'1011', 'C':'1100', 'D':'1101',
|
||||||
|
'E':'1110', 'F':'1111',}
|
||||||
|
b = ''
|
||||||
|
for char in a:
|
||||||
|
b += hex_from_str[char]
|
||||||
|
return int(b, 2)
|
||||||
|
|
||||||
|
def show(kanji, file_path):
|
||||||
|
RESIZE = 5
|
||||||
|
name = kanji
|
||||||
|
if kanji > 0x8000:
|
||||||
|
kanji -= 0x8000
|
||||||
|
else:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], translations["enter_hex_code"][language.get()])
|
||||||
|
return
|
||||||
|
with open(file_path, 'rb') as f:
|
||||||
|
f = f.read()
|
||||||
|
offset = kanji * 32
|
||||||
|
tile = f[offset:offset + 32]
|
||||||
|
picture = Image.new('1', (16, 16))
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
for i in range(0, 32, 2):
|
||||||
|
bitmap = int.from_bytes(tile[i:i + 2])
|
||||||
|
bitmap = bin(bitmap)[2:].zfill(16)
|
||||||
|
for number in bitmap:
|
||||||
|
if number == '1':
|
||||||
|
picture.putpixel((x, y), 1)
|
||||||
|
x += 1
|
||||||
|
else:
|
||||||
|
x += 1
|
||||||
|
y += 1
|
||||||
|
x = 0
|
||||||
|
picture = picture.resize((16 * RESIZE, 16 * RESIZE))
|
||||||
|
picture.show(title=name)
|
||||||
|
|
||||||
|
def open_kanji_window():
|
||||||
|
if not file_path:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], translations["open_file_first"][language.get()])
|
||||||
|
return
|
||||||
|
|
||||||
|
kanji_window = ctk.CTkToplevel(root)
|
||||||
|
kanji_window.title(translations["show_kanji_button"][language.get()])
|
||||||
|
|
||||||
|
kanji_label = ctk.CTkLabel(kanji_window, text=translations["enter_hex_code"][language.get()])
|
||||||
|
kanji_label.pack(pady=5)
|
||||||
|
|
||||||
|
kanji_entry = ctk.CTkEntry(kanji_window)
|
||||||
|
kanji_entry.pack(pady=5)
|
||||||
|
|
||||||
|
def show_kanji():
|
||||||
|
kanji_hex = kanji_entry.get()
|
||||||
|
try:
|
||||||
|
kanji = fromhex(kanji_hex)
|
||||||
|
show(kanji, file_path)
|
||||||
|
except Exception as e:
|
||||||
|
messagebox.showerror(translations["error"][language.get()], f"{translations['file_processing_error'][language.get()]}: {e}")
|
||||||
|
|
||||||
|
show_button = ctk.CTkButton(kanji_window, text=translations["show_kanji_button"][language.get()], command=show_kanji)
|
||||||
|
show_button.pack(pady=5)
|
||||||
|
|
||||||
|
root = ctk.CTk()
|
||||||
root.title(translations["title"]["en"])
|
root.title(translations["title"]["en"])
|
||||||
|
|
||||||
file_path = ""
|
file_path = ""
|
||||||
@@ -248,7 +422,7 @@ drawing = False
|
|||||||
new_color = None
|
new_color = None
|
||||||
|
|
||||||
# Language selection
|
# Language selection
|
||||||
language = tk.StringVar(value="en")
|
language = ctk.StringVar(value="en")
|
||||||
language_options = ["en", "ru", "eo", "ja", "uk"]
|
language_options = ["en", "ru", "eo", "ja", "uk"]
|
||||||
|
|
||||||
# Notebook for tabs
|
# Notebook for tabs
|
||||||
@@ -259,57 +433,64 @@ notebook.pack(expand=True, fill="both")
|
|||||||
editor_tab = ttk.Frame(notebook)
|
editor_tab = ttk.Frame(notebook)
|
||||||
notebook.add(editor_tab, text=translations["editor_tab"]["en"])
|
notebook.add(editor_tab, text=translations["editor_tab"]["en"])
|
||||||
|
|
||||||
file_label = tk.Label(editor_tab, text=translations["no_file_selected"]["en"])
|
file_label = ctk.CTkLabel(editor_tab, text=translations["no_file_selected"]["en"])
|
||||||
file_label.pack(pady=5)
|
file_label.pack(pady=5)
|
||||||
|
|
||||||
open_button = tk.Button(editor_tab, text=translations["open_file_button"]["en"], command=open_file)
|
open_button = ctk.CTkButton(editor_tab, text=translations["open_file_button"]["en"], command=open_file)
|
||||||
open_button.pack(pady=5)
|
open_button.pack(pady=5)
|
||||||
|
|
||||||
width_label = tk.Label(editor_tab, text=translations["width_label"]["en"])
|
width_label = ctk.CTkLabel(editor_tab, text=translations["width_label"]["en"])
|
||||||
width_label.pack(pady=5)
|
width_label.pack(pady=5)
|
||||||
|
|
||||||
width_entry = tk.Entry(editor_tab)
|
width_entry = ctk.CTkEntry(editor_tab)
|
||||||
width_entry.insert(0, "128")
|
width_entry.insert(0, "128")
|
||||||
width_entry.pack(pady=5)
|
width_entry.pack(pady=5)
|
||||||
|
|
||||||
table_button = tk.Button(editor_tab, text=translations["open_table_button"]["en"], command=open_table_window)
|
table_button = ctk.CTkButton(editor_tab, text=translations["open_table_button"]["en"], command=open_table_window)
|
||||||
table_button.pack(pady=5)
|
table_button.pack(pady=5)
|
||||||
|
|
||||||
save_button = tk.Button(editor_tab, text=translations["save_image_button"]["en"], command=save_image)
|
save_button = ctk.CTkButton(editor_tab, text=translations["save_image_button"]["en"], command=save_image)
|
||||||
save_button.pack(pady=5)
|
save_button.pack(pady=5)
|
||||||
|
|
||||||
save_bin_button = tk.Button(editor_tab, text=translations["save_bin_button"]["en"], command=save_to_bin)
|
save_bin_button = ctk.CTkButton(editor_tab, text=translations["save_bin_button"]["en"], command=save_to_bin)
|
||||||
save_bin_button.pack(pady=5)
|
save_bin_button.pack(pady=5)
|
||||||
|
|
||||||
reload_button = tk.Button(editor_tab, text=translations["reload_image_button"]["en"], command=reload_image)
|
reload_button = ctk.CTkButton(editor_tab, text=translations["reload_image_button"]["en"], command=reload_image)
|
||||||
reload_button.pack(pady=5)
|
reload_button.pack(pady=5)
|
||||||
|
|
||||||
redraw_grid_button = tk.Button(editor_tab, text=translations["redraw_grid_button"]["en"], command=redraw_grid)
|
redraw_grid_button = ctk.CTkButton(editor_tab, text=translations["redraw_grid_button"]["en"], command=redraw_grid)
|
||||||
redraw_grid_button.pack(pady=5)
|
redraw_grid_button.pack(pady=5)
|
||||||
|
|
||||||
export_button = tk.Button(editor_tab, text=translations["export_image_button"]["en"], command=export_image)
|
export_button = ctk.CTkButton(editor_tab, text=translations["export_image_button"]["en"], command=export_image)
|
||||||
export_button.pack(pady=5)
|
export_button.pack(pady=5)
|
||||||
|
|
||||||
import_button = tk.Button(editor_tab, text=translations["import_image_button"]["en"], command=import_image)
|
import_button = ctk.CTkButton(editor_tab, text=translations["import_image_button"]["en"], command=import_image)
|
||||||
import_button.pack(pady=5)
|
import_button.pack(pady=5)
|
||||||
|
|
||||||
canvas_frame = tk.Frame(editor_tab)
|
show_kanji_button = ctk.CTkButton(editor_tab, text=translations["show_kanji_button"]["en"], command=open_kanji_window)
|
||||||
canvas_frame.pack(fill=tk.BOTH, expand=True)
|
show_kanji_button.pack(pady=5)
|
||||||
|
export_folder_button = ctk.CTkButton(editor_tab, text=translations["export_folder_button"][language.get()], command=export_to_folder)
|
||||||
|
export_folder_button.pack(pady=5)
|
||||||
|
|
||||||
canvas = tk.Canvas(canvas_frame, bg="white")
|
import_folder_button = ctk.CTkButton(editor_tab, text=translations["import_folder_button"][language.get()], command=import_from_folder)
|
||||||
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
|
import_folder_button.pack(pady=5)
|
||||||
|
canvas_frame = ctk.CTkFrame(editor_tab)
|
||||||
|
canvas_frame.pack(fill=ctk.BOTH, expand=True)
|
||||||
|
|
||||||
scrollbar_y = tk.Scrollbar(canvas_frame, orient=tk.VERTICAL, command=canvas.yview)
|
canvas = ctk.CTkCanvas(canvas_frame, bg="white")
|
||||||
scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)
|
canvas.pack(side=ctk.LEFT, fill=ctk.BOTH, expand=True)
|
||||||
canvas.config(yscrollcommand=scrollbar_y.set)
|
|
||||||
|
|
||||||
scrollbar_x = tk.Scrollbar(editor_tab, orient=tk.HORIZONTAL, command=canvas.xview)
|
scrollbar_y = ctk.CTkScrollbar(canvas_frame, orientation="vertical", command=canvas.yview)
|
||||||
scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)
|
scrollbar_y.pack(side=ctk.RIGHT, fill=ctk.Y)
|
||||||
canvas.config(xscrollcommand=scrollbar_x.set)
|
canvas.configure(yscrollcommand=scrollbar_y.set)
|
||||||
|
|
||||||
zoom_scale = tk.Scale(editor_tab, from_=100, to=500, orient=tk.HORIZONTAL, label="Zoom Level (%)", command=update_zoom_level)
|
scrollbar_x = ctk.CTkScrollbar(editor_tab, orientation="horizontal", command=canvas.xview)
|
||||||
|
scrollbar_x.pack(side=ctk.BOTTOM, fill=ctk.X)
|
||||||
|
canvas.configure(xscrollcommand=scrollbar_x.set)
|
||||||
|
|
||||||
|
zoom_scale = ctk.CTkSlider(editor_tab, from_=100, to=500, orientation="horizontal", command=update_zoom_level)
|
||||||
zoom_scale.set(100)
|
zoom_scale.set(100)
|
||||||
zoom_scale.pack(side=tk.BOTTOM, fill=tk.X)
|
zoom_scale.pack(side=ctk.BOTTOM, fill=ctk.X)
|
||||||
|
|
||||||
canvas.bind("<Button-1>", start_drawing)
|
canvas.bind("<Button-1>", start_drawing)
|
||||||
canvas.bind("<B1-Motion>", draw)
|
canvas.bind("<B1-Motion>", draw)
|
||||||
@@ -323,16 +504,16 @@ root.bind('<Control-r>', bind_hot_reload)
|
|||||||
settings_tab = ttk.Frame(notebook)
|
settings_tab = ttk.Frame(notebook)
|
||||||
notebook.add(settings_tab, text=translations["settings_tab"]["en"])
|
notebook.add(settings_tab, text=translations["settings_tab"]["en"])
|
||||||
|
|
||||||
language_label = tk.Label(settings_tab, text=translations["language_label"]["en"])
|
language_label = ctk.CTkLabel(settings_tab, text=translations["language_label"]["en"])
|
||||||
language_label.pack(pady=5)
|
language_label.pack(pady=5)
|
||||||
|
|
||||||
language_menu = tk.OptionMenu(settings_tab, language, *language_options, command=update_language)
|
language_menu = ctk.CTkOptionMenu(settings_tab, variable=language, values=language_options, command=update_language)
|
||||||
language_menu.pack(pady=5)
|
language_menu.pack(pady=5)
|
||||||
|
|
||||||
grid_color_label = tk.Label(settings_tab, text=translations["grid_color_label"]["en"])
|
grid_color_label = ctk.CTkLabel(settings_tab, text=translations["grid_color_label"]["en"])
|
||||||
grid_color_label.pack(pady=5)
|
grid_color_label.pack(pady=5)
|
||||||
|
|
||||||
grid_color_entry = tk.Entry(settings_tab)
|
grid_color_entry = ctk.CTkEntry(settings_tab)
|
||||||
grid_color_entry.insert(0, "255,0,0")
|
grid_color_entry.insert(0, "255,0,0")
|
||||||
grid_color_entry.pack(pady=5)
|
grid_color_entry.pack(pady=5)
|
||||||
|
|
||||||
@@ -341,3 +522,6 @@ update_language()
|
|||||||
|
|
||||||
# Запуск основного цикла приложения
|
# Запуск основного цикла приложения
|
||||||
root.mainloop()
|
root.mainloop()
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: Пофиксить увеличение
|
||||||
|
|||||||
@@ -174,6 +174,13 @@
|
|||||||
"ja": "まず画像を開いてください",
|
"ja": "まず画像を開いてください",
|
||||||
"uk": "Спочатку відкрийте зображення"
|
"uk": "Спочатку відкрийте зображення"
|
||||||
},
|
},
|
||||||
|
"open_file_first": {
|
||||||
|
"en": "Open a file first",
|
||||||
|
"ru": "Сначала откройте файл",
|
||||||
|
"eo": "Unue malfermu dosieron",
|
||||||
|
"ja": "まずファイルを開いてください",
|
||||||
|
"uk": "Спочатку відкрийте файл"
|
||||||
|
},
|
||||||
"pixel_table": {
|
"pixel_table": {
|
||||||
"en": "Pixel Table",
|
"en": "Pixel Table",
|
||||||
"ru": "Таблица пикселей",
|
"ru": "Таблица пикселей",
|
||||||
@@ -229,5 +236,68 @@
|
|||||||
"eo": "Okazis eraro dum la importado de la bildo",
|
"eo": "Okazis eraro dum la importado de la bildo",
|
||||||
"ja": "画像のインポート中にエラーが発生しました",
|
"ja": "画像のインポート中にエラーが発生しました",
|
||||||
"uk": "Сталася помилка під час імпорту зображення"
|
"uk": "Сталася помилка під час імпорту зображення"
|
||||||
|
},
|
||||||
|
"show_kanji_button": {
|
||||||
|
"en": "Show Kanji",
|
||||||
|
"ru": "Показать кандзи",
|
||||||
|
"eo": "Montri Kandzi",
|
||||||
|
"ja": "漢字を表示",
|
||||||
|
"uk": "Показати кандзі"
|
||||||
|
},
|
||||||
|
"enter_hex_code": {
|
||||||
|
"en": "Enter the hex code of the character:",
|
||||||
|
"ru": "Введите hex-код символа:",
|
||||||
|
"eo": "Enigu la heksan kodon de la signo:",
|
||||||
|
"ja": "文字の16進コードを入力してください:",
|
||||||
|
"uk": "Введіть hex-код символу:"
|
||||||
|
},
|
||||||
|
"export_folder_button": {
|
||||||
|
"en": "Export as Folder",
|
||||||
|
"ru": "Экспортировать как папку",
|
||||||
|
"eo": "Eksporti kiel Dosierujo",
|
||||||
|
"ja": "フォルダとしてエクスポート",
|
||||||
|
"uk": "Експортувати як папку"
|
||||||
|
},
|
||||||
|
"import_folder_button": {
|
||||||
|
"en": "Import from Folder",
|
||||||
|
"ru": "Импортировать из папки",
|
||||||
|
"eo": "Importi el Dosierujo",
|
||||||
|
"ja": "フォルダからインポート",
|
||||||
|
"uk": "Імпортувати з папки"
|
||||||
|
},
|
||||||
|
"width_mismatch_error": {
|
||||||
|
"en": "Width mismatch! Expected: {expected}, Actual: {actual}",
|
||||||
|
"ru": "Несоответствие ширины! Ожидалось: {expected}, Фактическая: {actual}",
|
||||||
|
"eo": "Larĝo-neakordo! Atendita: {expected}, Reala: {actual}",
|
||||||
|
"ja": "幅が一致しません! 期待: {expected}, 実際: {actual}",
|
||||||
|
"uk": "Невідповідність ширини! Очікувано: {expected}, Фактична: {actual}"
|
||||||
|
},
|
||||||
|
"invalid_filename_error": {
|
||||||
|
"en": "Invalid filename format: {filename}",
|
||||||
|
"ru": "Недопустимый формат имени файла: {filename}",
|
||||||
|
"eo": "Nevalida dosiernoma formato: {filename}",
|
||||||
|
"ja": "無効なファイル名形式: {filename}",
|
||||||
|
"uk": "Невірний формат імені файлу: {filename}"
|
||||||
|
},
|
||||||
|
"select_folder": {
|
||||||
|
"en": "Select Folder",
|
||||||
|
"ru": "Выберите папку",
|
||||||
|
"eo": "Elektu Dosierujon",
|
||||||
|
"ja": "フォルダを選択",
|
||||||
|
"uk": "Виберіть папку"
|
||||||
|
},
|
||||||
|
"image_imported": {
|
||||||
|
"en": "Image imported successfully!",
|
||||||
|
"ru": "Изображение успешно импортировано!",
|
||||||
|
"eo": "Bildo importita sukcese!",
|
||||||
|
"ja": "画像のインポートが成功しました!",
|
||||||
|
"uk": "Зображення успішно імпортовано!"
|
||||||
|
},
|
||||||
|
"no_cell_files": {
|
||||||
|
"en": "No cell files found!",
|
||||||
|
"ru": "Файлы клеток не найдены!",
|
||||||
|
"eo": "Neniu ĉeldosieroj trovitaj!",
|
||||||
|
"ja": "セルファイルが見つかりません!",
|
||||||
|
"uk": "Файли клітинок не знайдено!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user