Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
dae71e7
visible indicator for which column is active + new rect_abs function
rexendevar Jul 18, 2026
a0750fe
fixup! visible indicator for which column is active + new rect_abs fu…
rexendevar Jul 18, 2026
b216b5e
optimization
rexendevar Jul 18, 2026
3fc73f0
getting tired. starting 2 work on save box
rexendevar Jul 18, 2026
3b25c4a
exhausting myself
rexendevar Jul 18, 2026
b3109a7
part 1 of save box done. switching gears
rexendevar Jul 18, 2026
b71b00c
column labels basics
rexendevar Jul 18, 2026
fc4ba9f
minor optimization
rexendevar Jul 18, 2026
0f36ac3
starting to work on better text cursor behavior
rexendevar Jul 19, 2026
38d16cf
continued improvements
rexendevar Jul 19, 2026
f99ba32
new edit handling is complete i think
rexendevar Jul 19, 2026
bcac7ab
time button refinements
rexendevar Jul 19, 2026
59ff1c1
replace all humiliation
rexendevar Jul 19, 2026
03495fc
icon changes, hacky workaround for text display bug, text edit fix fo…
rexendevar Jul 19, 2026
a9e7b51
(mostly) fix time display desync bug
rexendevar Jul 19, 2026
c2329d2
beginnings of multiline text box
rexendevar Jul 19, 2026
9b7be71
major progress on multiline text box
rexendevar Jul 20, 2026
d6aef23
mlt
rexendevar Jul 20, 2026
039fec9
no idea what i'm doing
rexendevar Jul 20, 2026
7980d65
progress
rexendevar Jul 21, 2026
970a7f5
text highlighting basics
rexendevar Jul 21, 2026
9f593ce
multiline text box is alpha ready
rexendevar Jul 21, 2026
190fb24
starting to move back towards the editor
rexendevar Jul 21, 2026
8ec064d
major highlight progress
rexendevar Jul 21, 2026
5bb68ea
Merge branch 'master' into lyrics-editor-improvements
rexendevar Jul 21, 2026
b584fc4
yeah
rexendevar Jul 21, 2026
cf99307
Merge branch 'master' into lyrics-editor-improvements
rexendevar Jul 21, 2026
f4d9bc3
don't remenbver what i did employers don't read these please
rexendevar Jul 22, 2026
5df9df2
we are starting our final descent into pr airport
rexendevar Jul 23, 2026
bb146d5
further refinements
rexendevar Jul 23, 2026
9fac0a2
ctrl text editing with line breax
rexendevar Jul 23, 2026
3593441
abject misery back 2 drawing board. cool new ddt function
rexendevar Jul 24, 2026
d14326e
i think i've saved it i think all the text editing and highlighting i…
rexendevar Jul 24, 2026
f302d46
regular typing and deleting fixed. found bug where you can't edit the…
rexendevar Jul 24, 2026
1afbdc3
possibly actually fixed but i dont believe it
rexendevar Jul 25, 2026
0f03c8a
Sloptimization™
rexendevar Jul 25, 2026
00f6e79
my brain is leaking out my ears
rexendevar Jul 26, 2026
5fe4301
cleanup
rexendevar Jul 26, 2026
514f369
one final nut to crack before i'm done
rexendevar Jul 26, 2026
19642c2
slop appeasement
rexendevar Jul 27, 2026
61180be
fixed a severe and perplexing buggit add .git add .git add .! i think…
rexendevar Jul 27, 2026
cbb2058
final cleanup
rexendevar Jul 27, 2026
f420cdc
Merge branch 'master' into lyrics-editor-improvements
rexendevar Jul 28, 2026
e50d6a8
styles and types
rexendevar Jul 28, 2026
7363e5b
tiny spacing change
rexendevar Jul 30, 2026
94cec1e
chaunge logge
rexendevar Jul 30, 2026
1607aa4
final
rexendevar Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/tauon/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,3 +648,4 @@ def polyline(points: list[tuple[float, float]]) -> None:
open_crash_log(crash_log_path)
elif buttonid.value == BUTTON_ID_QUIT:
pass
sdl3.SDL_Quit() # i will forget to remove this but if i'm correct it will be a bugfix
95 changes: 95 additions & 0 deletions src/tauon/t_modules/t_draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def __init__(self, renderer: sdl3.LP_SDL_Renderer) -> None:

self.was_truncated = False

self._locate_cache: dict = {}

def load_image(self, g: BytesIO) -> sdl3.LP_SDL_Surface:
size = g.getbuffer().nbytes
pointer = ctypes.c_void_p(ctypes.addressof(ctypes.c_char.from_buffer(g.getbuffer())))
Expand Down Expand Up @@ -259,6 +261,24 @@ def rect(self, rectangle: tuple[int, int, int, int], colour: ColourRGBA) -> None
# else:
# sdl3.SDL_RenderDrawRect(self.renderer, self.sdlrect)

def rect_abs(self, rectangle: tuple[int, int, int, int], colour: ColourRGBA) -> None:
'''x1, y1, x2, y2'''
sdl3.SDL_SetRenderDrawColor(self.renderer, colour.r, colour.g, colour.b, colour.a)

x1 = min(rectangle[0], rectangle[2])
y1 = min(rectangle[1], rectangle[3])
x2 = max(rectangle[0], rectangle[2])
y2 = max(rectangle[1], rectangle[3])
self.sdlrect.x = float(x1)
self.sdlrect.y = float(y1)
self.sdlrect.w = float(x2-x1)
self.sdlrect.h = float(y2-y1)

# if fill:
sdl3.SDL_RenderFillRect(self.renderer, self.sdlrect)
# else:
# sdl3.SDL_RenderDrawRect(self.renderer, self.sdlrect)

def bordered_rect(
self, rectangle: tuple[int, int, int, int], fill_colour: ColourRGBA, outer_colour: ColourRGBA, border_size: int
) -> None:
Expand Down Expand Up @@ -759,3 +779,78 @@ def text(
)

return self.__draw_text_cairo(location, text, colour, font, max_w, bg, align, real_bg=real_bg, key=key)

def get_wrapped_lines(self, text: str, font: int, max_x: int) -> list[str]:
# this function is 95% Genuine Slop™
# imagines a beautiful world where the input text is wrapped and returns the separated lines as they would appear
if not text:
return []

if font not in self.f_dict:
logging.info(f"Font not loaded: {font!s}")
return [text]

max_x += 12
max_x = round(max_x)

layout = self.layout
layout.set_auto_dir(False)
layout.set_font_description(self._font_description(font))
layout.set_wrap(Pango.WrapMode.WORD_CHAR)
layout.set_ellipsize(Pango.EllipsizeMode.NONE)
layout.set_width(max_x * 1000)
layout.set_height(-1)

all_lines: list[str] = []

# Split on real newlines ourselves so Pango only ever wraps a single
# paragraph at a time — that way every line it returns is a soft wrap,
# and every boundary between paragraphs is unambiguously a real \n.
for paragraph in text.split("\n"):
if paragraph == "":
all_lines.append("\n")
continue

try:
layout.set_text(paragraph, -1)
except Exception:
logging.exception(f"Text error on text: {paragraph}")
paragraph = paragraph.encode("utf-8", "replace").decode("utf-8")
layout.set_text(paragraph, -1)

encoded = paragraph.encode("utf-8")
for i, line in enumerate(layout.get_lines_readonly()):
start = line.start_index
end = start + line.length
if i == 0 and all_lines:
all_lines.append('\n' + encoded[start:end].decode("utf-8"))
else:
all_lines.append(encoded[start:end].decode("utf-8"))

return all_lines

def measure_and_locate(self, text: str, font: int, x_pixels: float, y_pixels: float = 0) -> tuple[float, int, bool]:
# this function is 100% Genuine Slop™
# provides a faster way of setting your cursor position based on mouse position
key = (text, font)
layout = self._locate_cache.get(key)
if layout is None:
layout = PangoCairo.create_layout(self.context)
layout.set_font_description(self._font_description(font))
layout.set_width(-1)
layout.set_text(text, -1)
self._locate_cache[key] = layout
# simple bound so this doesn't grow forever
if len(self._locate_cache) > 64:
self._locate_cache.pop(next(iter(self._locate_cache)))

full_w_pango, _ = layout.get_size()
full_w_px = full_w_pango / Pango.SCALE

inside, index, trailing = layout.xy_to_index(
round(x_pixels * Pango.SCALE),
round(y_pixels * Pango.SCALE),
)
char_index = len(text.encode("utf-8")[:index].decode("utf-8"))

return full_w_px, char_index, bool(trailing)
Loading
Loading