YYY
YYY

Reputation: 103

Pygame - Unable to put an entire text in different lines

I have an input box in which text is put to be rendered. However, if the text exceeds a certain length, I want it to be displayed in different lines.

I had some code that looks like this:

 def scale_box(self, screen, text):
        max_length = 10
        nb_lines = int(len(text) / max_length)
        index = 0
        self.box.y -= nb_lines * self.coords[3]
        self.box.h *= nb_lines
        y = self.box.y
        for i in range(0, nb_lines + 1):
            line = text[index: index + max_length]
            index += max_length
            Line = self.box_font.render(line, True, self.font_color)
            screen.blit(Line, (self.box.x + 10, y))
            y += self.coords[3]

So, the size (dimensions) of the input box is updated depending on the length of the text. This method is called when a certain event occurs.

And somewhere in the "main" code

    screen.blit(self.text_box, (self.box.x + 10, self.box.y + 10))

For example, if the text = 'Something written here...'. I want to get something like this:

Something 
written he
re...

But I get only the last line:

re...

Upvotes: 1

Views: 66

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

The calculation of the number of lines is wrong. The number of lines is the integral part of the division len(text) // max_length + 1, except there the text has a length with is exactly a multiple of the number of lines. This means +1 has to be done if the remainder len(text) % max_length is greater 0:

nb_lines = len(text) // max_length + (1 if len(text) % max_length > 0 else 0)

Split the text and render it to a list of surfaces:

lines = []
for i in range(nb_lines):
    linetext = text[i*max_length : (i+1)*max_length]
    lines.append( self.box_font.render(linetext, True, self.font_color) )

Calculate the width and the height of the text block, shift and update athe text box:

width = max([l.get_width() for l in lines])
height = sum([l.get_height() for l in lines])
y = self.box.y - nb_lines * self.coords[3]

self.box = pygame.Rect(self.box.x, y, width, height)

Finally blit the text to the screen, line by line:

y = self.box.y
for l in lines:
    screen.blit(l, (self.box.x + 10, y))  
    y += l.get_height() 

The full function may look like this:

def scale_box(self, screen, text):

    max_length = 10
    nb_lines = len(text) // max_length + (1 if len(text) % max_length > 0 else 0)
    lines = []
    for i in range(nb_lines):
        linetext = text[i*max_length : (i+1)*max_length]
        lines.append( self.box_font.render(linetext, True, self.font_color) )

    width = max([l.get_width() for l in lines])
    height = sum([l.get_height() for l in lines])
    y = self.box.y - nb_lines * self.coords[3]
    self.box = pygame.Rect(self.box.x, y, width, height)

    y = self.box.y
    for l in lines:
        screen.blit(l, (self.box.x + 10, y))  
        y += l.get_height() 

Upvotes: 1

Related Questions