Add text into a colored input text box pygame

Viewed 261

I want to create a colored input text box in which the user can type some text.

Here is the code I am trying with:

import pygame


class InputBox:
    def __init__(self, x, y, w, h, color_active, color_inactive, font, text=''):
        self.rect = pygame.Rect(x, y, w, h)
        self.inner_rect = pygame.Rect(x+2, y+2, w-4, h-4)
        self.color_active = color_active
        self.color_inactive = color_inactive
        self.color = self.color_inactive
        self.text = text
        self.font = font
        self.txt_surface = font.render(text, True, self.color)
        self.active = False

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            # If the user clicked on the input_box rect.
            if self.rect.collidepoint(event.pos):
                # Toggle the active variable.
                self.active = not self.active
            else:
                self.active = False
            # Change the current color of the input box.
            self.color = self.color_active if self.active else self.color_inactive
        if event.type == pygame.KEYDOWN:
            if self.active:
                if event.key == pygame.K_RETURN:
                    print(self.text)
                    self.text = ''
                elif event.key == pygame.K_BACKSPACE:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode
                # Re-render the text.
                self.txt_surface = font.render(self.text, True, self.color)

    def update(self):
        # Resize the box if the text is too long.
        width = max(200, self.txt_surface.get_width()+10)
        self.rect.w = width

    def draw(self, screen):
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))
        # Blit the rect.
        pygame.draw.rect(screen, self.color, self.rect, 2)
        pygame.draw.rect(screen, (255, 255, 255), self.inner_rect)


if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    color_inactive = pygame.Color('lightskyblue3')
    color_active = pygame.Color('dodgerblue2')
    font = pygame.font.Font(None, 32)
    input_box1 = InputBox(100, 100, 140, 32, color_active, color_inactive, font)
    input_box2 = InputBox(100, 300, 140, 32, color_active, color_inactive, font)
    input_boxes = [input_box1, input_box2]
    done = False
    
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            for box in input_boxes:
                box.handle_event(event)
        for box in input_boxes:
            box.update()

        screen.fill((30, 30, 30))
        for box in input_boxes:
            box.draw(screen)

        pygame.display.flip()

The result I am getting is that the text is behind the input text box background (check the screenshot)

enter image description here

I want the text to be in the foreground.
I tried to change the place of screen.fill((30, 30, 30)) in the beginning and end of the loop, but it didn't work.
Does anyone know how to solve this problem?
Thanks in advance.

1 Answers

The result I am getting is that the text is behind the input

So, you have to draw the background before the text:

class InputBox:
    # [...]

    def draw(self, screen):
        # Draw the background of the text box 
        pygame.draw.rect(screen, (255, 255, 255), self.inner_rect)
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))
        # Blit the rect.
        pygame.draw.rect(screen, self.color, self.rect, 2)

Related