Calculate text width and height using blf.dimensions
scale = 1.0
![scale = 1.0](https://cdn.statically.io/img/i.sstatic.net/nuiEkbtP.png)
scale = 1.3
![scale = 1.3](https://cdn.statically.io/img/i.sstatic.net/MBSN6Akp.png)
import bpy, blf
import gpu
from gpu_extras.batch import batch_for_shader
colors = (
(0, 1, 0, 1), (1, 0, 0, 1), # Green to Red (bottom vertices)
(0, 1, 0, 1), (1, 0, 0, 1)) # Green to Red (top vertices)
indices = ((0, 1, 2), (2, 1, 3))
shader = gpu.shader.from_builtin('SMOOTH_COLOR')
shader_box = gpu.shader.from_builtin('UNIFORM_COLOR')
class BlfText:
__slots__ = 'color', 'x', 'y', 'text', 'size', 'font_id'
# x : Left
# y : Bottom
def __init__(self, color, x=0, y=0, text="", size=12, font_id=0):
self.color = color
self.x = x
self.y = y
self.text = text
self.size = size
self.font_id = font_id
def calc_center_pos_x(self):
blf.size(self.font_id, self.size)
return round(self.x + blf.dimensions(self.font_id, self.text)[0] / 2)
def calc_center_pos_y(self):
blf.size(self.font_id, self.size)
return round(self.y + blf.dimensions(self.font_id, self.text)[1] / 2)
def draw(self):
font_id = self.font_id
blf.color(font_id, *self.color)
blf.size(font_id, self.size)
blf.position(font_id, self.x, self.y, 0)
blf.draw(font_id, self.text)
def draw_element(pos_left=0, pos_bottom=0, scale=1.0, bar_size_x=250, bar_size_y=20):
border = round(10 * scale)
inner = round(8 * scale)
font_size = round(14 * scale)
font_id = 0
font_color = (0.7, 0.7, 0.7, 1.0)
blf.size(font_id, font_size)
bar_B = pos_bottom + border
bar_T = round(bar_B + bar_size_y * scale)
text_y = bar_T + inner
text_x = pos_left + border
background_T = text_y + round(blf.dimensions(font_id, "X")[1]) + border
text_5kg = BlfText(font_color, text_x, text_y, "5 kg", font_size, font_id)
bar_L = text_5kg.calc_center_pos_x()
bar_R = round(bar_L + bar_size_x * scale)
text_100kg = BlfText(font_color, 0, text_y, "100 kg", font_size, font_id)
dimen_half = text_100kg.calc_center_pos_x()
text_100kg.x = bar_R - dimen_half
background_R = round(text_100kg.x + blf.dimensions(font_id, text_100kg.text)[0] + border)
batch_background = batch_for_shader(shader_box, 'TRIS', {"pos": (
(pos_left, pos_bottom), (background_R, pos_bottom),
(pos_left, background_T), (background_R, background_T),
)}, indices=indices)
batch_bar = batch_for_shader(shader, 'TRIS', {"pos": (
(bar_L, bar_B), (bar_R, bar_B),
(bar_L, bar_T), (bar_R, bar_T),
), "color": colors}, indices=indices)
shader_box.uniform_float("color", (0.2, 0.2, 0.2, 1.0))
batch_background.draw(shader_box)
batch_bar.draw(shader)
text_5kg.draw()
text_100kg.draw()
def draw():
draw_element(
pos_left = 50,
pos_bottom = 50,
scale = 1.0 # or use blender UI scale
)
# Add the draw handler
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')