implemented track_formatting interface

This commit is contained in:
Faraphel 2022-07-29 19:46:21 +02:00
parent 37bc9ade25
commit b3f85bbe43
2 changed files with 55 additions and 27 deletions

View file

@ -1,8 +1,8 @@
import tkinter
from tkinter import ttk
from source.translation import translate as _
from source.mkw.MKWColor import MKWColor
import re
from source.mkw.MKWColor import MKWColor
ModConfig: any
@ -17,9 +17,13 @@ class Window(tkinter.Toplevel):
self.entry_format_input.grid(row=1, column=1, sticky="NEWS")
self.entry_format_input.bind("<Return>", self.preview)
self.track_preview = tkinter.Text(self)
self.track_preview = tkinter.Text(self, background="black", foreground=MKWColor("off").color_code)
self.track_preview.grid(row=2, column=1, sticky="NEWS")
for color in MKWColor.get_all_colors():
self.track_preview.tag_configure(color.bmg, foreground=color.color_code)
self.track_preview.tag_configure("error", background="red", foreground="white")
def preview(self, event: tkinter.Event = None):
"""
Preview all the tracks name with the track format
@ -29,30 +33,40 @@ class Window(tkinter.Toplevel):
# insert all the tracks representation
for track in self.mod_config.get_tracks():
try: track_repr = track.repr_format(self.mod_config, self.entry_format_input.get())
except: track_repr = "< ERROR >"
try:
track_repr = track.repr_format(
self.mod_config, self.entry_format_input.get()
)
track_repr = track_repr.replace('\n', '\\n') + "\n"
self.track_preview.insert(tkinter.END, track_repr)
offset: int = 0 # the color tag is removed at every sub, so keep track of the offset
tags: list[tuple[int | None, str | None]] = [] # list of all the position of the tags, with the offset
# add the colors
for color in MKWColor.all_colors:
self.track_preview.tag_configure(color["bmg"], foreground=f"#{color['hex']:06X}")
text: str = self.track_preview.get(1.0, tkinter.END)
def tag_format(match: re.Match):
"""
Get the position of the tag and the corresponding color. Remove the tag from the string
"""
nonlocal offset, tags
tag_start: str = r"\c{" + color["bmg"] + "}"
tag_end: str = r"\c"
# add the position of the tag start
tags.append((match.span()[0] - offset, match.group("color_name")))
offset += len(match.group()) # add the tag len to the offset since it is removed
return "" # remove the tag
find_end = -len(tag_end)
# insert into the text the track_repr without the tags
self.track_preview.insert(
tkinter.END,
re.sub(r"\\c{(?P<color_name>.*?)}", tag_format, track_repr) + "\n"
)
while find_end < len(text):
if (find_start := text.find(tag_start, find_end + len(tag_end))) == -1: break
if (find_end := text.find(tag_end, find_start + len(tag_start))) == -1: find_end = len(text) - 1
# color every part of the track_repr with the position and color got in the re.sub
for (pos_start, tag_start), (pos_end, tag_end) in zip(tags, tags[1:] + [(None, None)]):
self.track_preview.tag_add(
tag_start,
f"end-1c-1l+{pos_start}c",
"end-1c" + (f"-1l+{pos_end}c" if pos_end is not None else "")
)
text_start = text[:find_start].split("\n")
text_start = f"{len(text_start)}.{len(text_start[-1])}"
text_end = text[:find_end].split("\n")
text_end = f"{len(text_end)}.{len(text_end[-1])}"
self.track_preview.tag_add(color["bmg"], text_start, text_end)
except Exception as exc:
formatted_exc = str(exc).replace('\n', ' ')
self.track_preview.insert(tkinter.END, f"< Error: {formatted_exc} >\n")
self.track_preview.tag_add("error", "end-1c-1l", "end-1c")

View file

@ -9,7 +9,7 @@ class MKWColor:
Represent a color that can be used inside MKW files
"""
all_colors: list[dict] = [
_all_colors: list[dict] = [
{"bmg": "yor7", "hex": 0xF5090B, "name": "apple red"},
{"bmg": "yor6", "hex": 0xE82C09, "name": "dark red"},
{"bmg": "yor5", "hex": 0xE65118, "name": "dark orange"}, # flame
@ -28,18 +28,32 @@ class MKWColor:
{"bmg": "red1", "hex": 0xE46C74, "name": "pink"},
{"bmg": "white", "hex": 0xFFFFFF, "name": "white"},
{"bmg": "clear", "hex": 0x000000, "name": "clear"},
{"bmg": "off", "hex": 0x998C86, "name": "off"},
{"bmg": "off", "hex": 0xDDDDDD, "name": "off"},
]
__slots__ = ("bmg", "hex", "name")
def __init__(self, color_data: any, color_key: str = "name"):
colors = list(filter(lambda color: color[color_key] == color_data, self.all_colors))
colors = list(filter(lambda color: color[color_key].upper() == color_data.upper(), self._all_colors))
if len(colors) == 0: raise ColorNotFound(color_data)
for key, value in colors[0].items():
setattr(self, key, value)
@classmethod
def get_all_colors(cls):
for color in cls._all_colors:
yield cls(color["name"])
@property
def color_code(self) -> str:
"""
Return the color code that can be used in tkinter
:return: the color code
"""
return f"#{self.hex:06X}"
def bmg_color_text(color_name: str, text: str) -> str:
"""