2026-02-16

This commit is contained in:
2026-03-17 15:25:32 -06:00
parent d5dd373de0
commit 60100fbab2
560 changed files with 33397 additions and 20776 deletions
@@ -1,5 +1,10 @@
import blf
import bpy
import gpu
from typing import Tuple, Union
from gpu_extras.batch import batch_for_shader
from .bl_ui_widget import BL_UI_Widget
@@ -17,6 +22,9 @@ class BL_UI_Label(BL_UI_Widget):
self.multiline = False
self.row_height = 20
self.padding: Union[Tuple[float, float], float] = 0
self.background = False
@property
def text_color(self):
return self._text_color
@@ -61,6 +69,30 @@ class BL_UI_Label(BL_UI_Widget):
blf.size(font_id, self._text_size, 72)
else:
blf.size(font_id, self._text_size)
lines = self._text.split("\n") if self.multiline else [self._text]
if not lines:
return
default_line_height = self.row_height if self.multiline else self._text_size
line_metrics = []
max_line_width = 0.0
total_height = 0.0
for line in lines:
width, height = blf.dimensions(font_id, line)
if height == 0:
height = default_line_height
line_height = (
self.row_height if self.multiline else max(height, self._text_size)
)
if line_height == 0:
line_height = default_line_height
line_metrics.append((line, width, line_height))
max_line_width = max(max_line_width, width)
total_height += line_height
if not line_metrics:
return
textpos_y = area_height - self.y_screen - self.height
@@ -76,16 +108,55 @@ class BL_UI_Label(BL_UI_Widget):
if self._valign == "CENTER":
y -= height // 2
# bottom could be here but there's no reason for it
first_line_height = line_metrics[0][2]
if self.background and (max_line_width > 0 or total_height > 0):
pad_x, pad_y = self._padding_tuple()
text_top = y + first_line_height
text_bottom = text_top - total_height
left = x - pad_x
right = x + max_line_width + pad_x
top = text_top + pad_y
bottom = text_bottom - pad_y
self._draw_background_rect(left, right, bottom, top)
current_y = y
if not self.multiline:
blf.position(font_id, x, y, 0)
blf.position(font_id, x, current_y, 0)
blf.color(font_id, r, g, b, a)
blf.draw(font_id, self._text)
else:
lines = self._text.split("\n")
for line in lines:
blf.position(font_id, x, y, 0)
for line, _, line_height in line_metrics:
blf.position(font_id, x, current_y, 0)
blf.color(font_id, r, g, b, a)
blf.draw(font_id, line)
y -= self.row_height
current_y -= line_height
def _padding_tuple(self) -> Tuple[float, float]:
pad = self.padding
if isinstance(pad, (list, tuple)):
if len(pad) == 0:
return (0.0, 0.0)
if len(pad) == 1:
value = float(pad[0])
return (value, value)
return (float(pad[0]), float(pad[1]))
value = float(pad)
return (value, value)
def _draw_background_rect(self, left, right, bottom, top):
vertices = (
(left, top),
(left, bottom),
(right, bottom),
(right, top),
)
indices = ((0, 1, 2), (0, 2, 3))
gpu.state.blend_set("ALPHA")
self.shader.bind()
self.shader.uniform_float("color", self._bg_color)
batch = batch_for_shader(
self.shader, "TRIS", {"pos": vertices}, indices=indices
)
batch.draw(self.shader)