2
$\begingroup$

I've created a colored bar using the gpu module (see picture). Here is the code. Now I would like to add some text as displayed in the image with the labels 5 Kg and 100 kg. Any suggestion?

import bpy
import gpu
from gpu_extras.batch import batch_for_shader

vertices = (
(50, 50), (300, 50),
(50, 70), (300, 70))

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')
batch = batch_for_shader(shader, 'TRIS', {"pos": vertices, "color": colors}, 
indices=indices)


def draw():
  batch.draw(shader)

# Add the draw handler
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

enter image description here

$\endgroup$

1 Answer 1

2
$\begingroup$

Calculate text width and height using blf.dimensions

scale = 1.0

scale = 1.0

scale = 1.3

scale = 1.3

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')
$\endgroup$
1
  • $\begingroup$ Great, thanks a lot! $\endgroup$
    – Alex Mekx
    Commented Jul 6 at 10:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .