NotQuiteParadise2

Source code for nqp.ui_elements.generic.ui_input_box

from typing import TYPE_CHECKING

import pygame

from nqp.core.constants import FontType

if TYPE_CHECKING:
    from nqp.core.game import Game


# TODO - add numpad support
# TODO - add special character support, particularly - | .
# TODO - handle blank input fields


[docs]class UIInputBox:
[docs] def __init__( self, game, size: pygame.Vector2, pos: pygame.Vector2 = pygame.Vector2(0, 0), colour=(255, 255, 255), input_type="all", text="", font=None, ): self._game: Game = game self.size: pygame.Vector2 = size self.pos: pygame.Vector2 = pos self.colour = colour if input_type == "detect": if type(text) == int: input_type = "int" elif type(text) == float: input_type = "float" else: input_type = "lower" self.input_type = input_type self.previous_input_mode = None self.padding = 3 self.focused = False if not font: font = self._game.visual.create_font(FontType.DEFAULT, str(text)) self.font = font # assign font pos self.font.pos = pygame.Vector2( self.pos.x + self.padding, self.pos.y + (self.size.y - self.font.line_height) // 2 )
@property def value(self): if self.input_type == "int": return int(self.font.text) if self.input_type == "float": return float(self.font.text) else: return self.font.text @property def should_focus(self, offset=(0, 0)): if not self.focused: r = pygame.Rect(self.pos.x - offset[0], self.pos.y - offset[1], self.size.x, self.size.y) if r.collidepoint((self._game.input.mouse_pos.x, self._game.input.mouse_pos.y)): if self._game.input.mouse_state["left"]: return True return False else: r = pygame.Rect(self.pos.x - offset[0], self.pos.y - offset[1], self.size.x, self.size.y) if not r.collidepoint((self._game.input.mouse_pos.x, self._game.input.mouse_pos.y)): if self._game.input.mouse_state["left"]: return False return True
[docs] def focus(self): if not self.focused: self.previous_input_mode = self._game.input.mode self._game.input.mode = "typing" self.focused = True
[docs] def unfocus(self): if self.focused: self._game.input.mode = self.previous_input_mode self.focused = False
[docs] def update(self, delta_time: float): if self.focused: new_chars = self._game.input.unload_chars() for char in new_chars: if char == "backspace": self.font.text = self.font.text[:-1] elif self.input_type == "all": self.font.text += char if self.input_type in ["int", "float"]: if char in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]: self.font.text += char if self.input_type in ["float"]: if char in ["."]: if "." not in self.font.text: self.font.text += char if self.input_type in ["lower"]: if char in [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "_", ]: self.font.text += char
[docs] def draw(self, surf, offset: pygame.Vector2 = pygame.Vector2(0, 0)): base_pos = pygame.Vector2(self.pos.x - offset[0], self.pos.y - offset[1]) border_r = pygame.Rect(*base_pos, *self.size) pygame.draw.rect(surf, self.colour, border_r, width=1) self.font.draw(surf) text_width = self.font.width if self.focused and (self._game.master_clock % 1 > 0.2): pygame.draw.line( surf, self.colour, (base_pos.x + self.padding + text_width, base_pos.y + 2), (base_pos.x + self.padding + text_width, base_pos.y + self.size.y - 4), )