Quellcode für miniworlds.actors.widgets.input

import logging
from typing import Union

import miniworlds.actors.shapes.shapes as shapes
import miniworlds.actors.widgets.button as widget
from miniworlds.base.exceptions import NoValidWorldPositionError


logger = logging.getLogger(__name__)


[Doku] class Input(widget.Button): def __init__(self, position): super().__init__("") self.background_color = (255, 255, 255, 0) try: self.position = position except NoValidWorldPositionError: raise NoValidWorldPositionError(position) self._max_chars = 10 self.fixed_width = 20 # (self._max_chars * self.text.font_size) / 2 self.current_input = "" self._cursor_position = 0 self.cursor_x = self.x self.cursor = shapes.Line((0, 0), (100, 100)) # set in update_cursor self.cursor.border_color = (255, 255, 255, 255) self.fixed_width = True self.is_focusable = True cursor = self.cursor # for decorator @cursor.register def act(self): if self._parent.has_focus: if self.world.frame % 20 == 0 and not self.world.frame % 40 == 0: self.hide() if self.world.frame % 40 == 0: self.show() else: self.hide() self.update_cursor() self.add_child(self.cursor)
[Doku] def has_focus(self): if self.world.event_manager.focus_actor == self: return True else: return False
@property def max_chars(self): return self._max_chars @max_chars.setter def max_chars(self, value): self._max_chars = value self.resize()
[Doku] def resize(self): if not self._resize: return """resizes widget based on text_width and height""" super().resize() # sets fixed width if self._img: self._img.height = self.row_height - self.padding_top - self.padding_bottom self._img.width = self._img_width self._img.position = ( self.position[0] + self.padding_left, self.position[1] + self.padding_top, ) if not self.fixed_width: # no image: Set width/height by text and img width if self._text_align == "left" and not self._img: self.width = self.text.width elif ( self._text_align == "left" and self._img or self._text_align == "image" ): self.width = ( self.text.width + self._padding_left + self._padding_right + self._img_width + self.img_padding_right ) self.height = self.text.height + self._padding_top + self._padding_bottom self.update_positions() self.cut_text()
[Doku] def update_cursor(self): font_size = self.text.font_size if self.cursor_position == 0: self.cursor_x = self.x else: self.cursor_x = self.x + self.text.costume.font_manager.get_text_width( self.current_input[0 : self.cursor_position] ) self.cursor.start_position = (self.cursor_x + font_size / 2, self.y) self.cursor.end_position = (self.cursor_x + font_size / 2, self.y + self.height)
@property def cursor_position(self): return self._cursor_position @cursor_position.setter def cursor_position(self, value): self._cursor_position = value self.update_cursor()
[Doku] def set_text(self, text: Union[str, int, float]): self.current_input = text super().set_text(text)
[Doku] def on_key_down(self, keys): if self.has_focus: if "SHIFT_L" in keys: pass elif "LEFT" in keys and self.cursor_position > 0: self.cursor_position -= 1 elif "RIGHT" in keys and self.cursor_position < len(self.current_input): self.cursor_position += 1 elif "BACKSPACE" in keys: if 0 < self.cursor_position <= len(self.current_input): self.cursor_position -= 1 self.set_text( self.current_input[0 : self.cursor_position] + self.current_input[self.cursor_position + 1 :] ) else: text = keys[-1] if text != "": self.set_text( self.current_input[0 : self.cursor_position] + text + self.current_input[self.cursor_position :] ) self.cursor_position += 1 self.update_cursor() logger.debug( "Updated input cursor to x=%s y=%s width=%s height=%s", self.cursor.x, self.cursor.y, self.cursor.width, self.cursor.height, )
[Doku] def on_focus(self): logger.debug("Input widget gained focus")
[Doku] def on_focus_lost(self): logger.debug("Input widget lost focus")