<s> import pyglet <EOL> from pyglet_gui . mixins import FocusMixin <EOL> from pyglet_gui . override import InputLabel <EOL> from pyglet_gui . core import Viewer <EOL> class TextInput ( FocusMixin , Viewer ) : <EOL> def __init__ ( self , text = "<STR_LIT>" , length = <NUM_LIT:20> , max_length = None , padding = <NUM_LIT:0> , on_input = None ) : <EOL> Viewer . __init__ ( self ) <EOL> FocusMixin . __init__ ( self ) <EOL> self . _document = pyglet . text . document . UnformattedDocument ( text ) <EOL> self . _document_style_set = False <EOL> self . _length = length <EOL> self . _max_length = max_length <EOL> self . _on_input = on_input <EOL> self . _padding = <NUM_LIT:4> + padding <EOL> self . _field = None <EOL> self . _text_layout = None <EOL> self . _caret = None <EOL> self . _label = None <EOL> def get_path ( self ) : <EOL> return '<STR_LIT:input>' <EOL> def _load_label ( self , theme ) : <EOL> self . _label = InputLabel ( self . _document . text , <EOL> multiline = False , <EOL> width = self . width - self . _padding * <NUM_LIT:2> , <EOL> color = theme [ '<STR_LIT>' ] , <EOL> font_name = theme [ '<STR_LIT>' ] , <EOL> font_size = theme [ '<STR_LIT>' ] , <EOL> ** self . get_batch ( '<STR_LIT>' ) ) <EOL> def _load_writing ( self , theme ) : <EOL> needed_width , needed_height = self . _compute_needed_size ( ) <EOL> self . _text_layout = pyglet . text . layout . IncrementalTextLayout ( <EOL> self . _document , needed_width , needed_height , <EOL> multiline = False , ** self . get_batch ( '<STR_LIT>' ) ) <EOL> self . _caret = pyglet . text . caret . Caret ( self . _text_layout , color = theme [ '<STR_LIT>' ] [ <NUM_LIT:0> : <NUM_LIT:3> ] ) <EOL> self . _caret . visible = True <EOL> self . _caret . mark = <NUM_LIT:0> <EOL> self . _caret . position = len ( self . _document . text ) <EOL> def load_graphics ( self ) : <EOL> theme = self . theme [ self . get_path ( ) ] <EOL> if not self . _document_style_set : <EOL> self . _document . set_style ( <NUM_LIT:0> , <NUM_LIT:0> , <EOL> dict ( color = theme [ '<STR_LIT>' ] , <EOL> font_name = theme [ '<STR_LIT>' ] , <EOL> font_size = theme [ '<STR_LIT>' ] ) ) <EOL> self . _document_style_set = True <EOL> self . _field = theme [ '<STR_LIT:image>' ] . generate ( color = theme [ '<STR_LIT>' ] , ** self . get_batch ( '<STR_LIT>' ) ) <EOL> if self . is_focus ( ) : <EOL> self . _load_writing ( theme ) <EOL> else : <EOL> self . _load_label ( theme ) <EOL> def _unload_writing ( self ) : <EOL> self . _caret . delete ( ) <EOL> self . _document . remove_handlers ( self . _text_layout ) <EOL> self . _text_layout . delete ( ) <EOL> self . _caret = self . _text_layout = None <EOL> def _unload_label ( self ) : <EOL> self . _label . delete ( ) <EOL> self . _label = None <EOL> def unload_graphics ( self ) : <EOL> if self . is_focus ( ) : <EOL> self . _unload_writing ( ) <EOL> else : <EOL> self . _unload_label ( ) <EOL> self . _field . unload ( ) <EOL> def _compute_needed_size ( self ) : <EOL> font = self . _document . get_font ( <NUM_LIT:0> ) <EOL> height = font . ascent - font . descent <EOL> glyphs = font . get_glyphs ( '<STR_LIT>' ) <EOL> width = max ( [ x . width for x in glyphs ] ) <EOL> needed_width = self . _length * width - <NUM_LIT:2> * self . _padding <EOL> needed_height = height + <NUM_LIT:2> * self . _padding <EOL> return needed_width , needed_height <EOL> def get_text ( self ) : <EOL> return self . _document . text <EOL> def layout ( self ) : <EOL> Viewer . layout ( self ) <EOL> self . _field . update ( self . x , self . y , self . width , self . height ) <EOL> x , y , width , height = self . _field . get_content_region ( ) <EOL> if self . is_focus ( ) : <EOL> self . _text_layout . begin_update ( ) <EOL> self . _text_layout . x = self . x + self . _padding <EOL> self . _text_layout . y = self . y - self . _padding <EOL> self . _text_layout . end_update ( ) <EOL> else : <EOL> descent = self . _document . get_font ( ) . descent <EOL> self . _label . begin_update ( ) <EOL> self . _label . x = self . x + self . _padding <EOL> self . _label . y = self . y + self . _padding - descent <EOL> self . _label . width = width - self . _padding * <NUM_LIT:2> <EOL> self . _label . end_update ( ) <EOL> def on_gain_focus ( self ) : <EOL> self . unload ( ) <EOL> FocusMixin . on_gain_focus ( self ) <EOL> self . load ( ) <EOL> self . reset_size ( ) <EOL> self . layout ( ) <EOL> def on_lose_focus ( self ) : <EOL> if self . _on_input is not None : <EOL> self . _on_input ( self . get_text ( ) ) <EOL> self . unload ( ) <EOL> FocusMixin . on_lose_focus ( self ) <EOL> self . load ( ) <EOL> self . reset_size ( ) <EOL> self . layout ( ) <EOL> def hit_test ( self , x , y ) : <EOL> return self . is_inside ( x , y ) <EOL> def on_mouse_drag ( self , x , y , dx , dy , buttons , modifiers ) : <EOL> if self . is_focus ( ) : <EOL> return self . _caret . on_mouse_drag ( x , y , dx , dy , buttons , modifiers ) <EOL> def on_mouse_press ( self , x , y , button , modifiers ) : <EOL> if self . is_focus ( ) : <EOL> return self . _caret . on_mouse_press ( x , y , button , modifiers ) <EOL> def on_text ( self , text ) : <EOL> assert self . is_focus ( ) <EOL> self . _caret . on_text ( text ) <EOL> if self . _max_length and len ( self . _document . text ) > self . _max_length : <EOL> self . _document . text = self . _document . text [ : self . _max_length ] <EOL> self . _caret . mark = self . _caret . position = self . _max_length <EOL> return pyglet . event . EVENT_HANDLED <EOL> def on_text_motion ( self , motion ) : <EOL> assert self . is_focus ( ) <EOL> return self . _caret . on_text_motion ( motion ) <EOL> def on_text_motion_select ( self , motion ) : <EOL> assert self . is_focus ( ) <EOL> return self . _caret . on_text_motion_select ( motion ) <EOL> def set_text ( self , text ) : <EOL> self . _document . text = text <EOL> if self . is_focus ( ) : <EOL> self . _caret . mark = self . _caret . position = len ( self . _document . text ) <EOL> else : <EOL> self . _label . text = text <EOL> def compute_size ( self ) : <EOL> needed_width , needed_height = self . _compute_needed_size ( ) <EOL> return self . _field . get_needed_size ( needed_width , needed_height ) <EOL> def delete ( self ) : <EOL> FocusMixin . delete ( self ) <EOL> Viewer . delete ( self ) </s>
