<s> '''<STR_LIT>''' <EOL> __all__ = ( '<STR_LIT>' , ) <EOL> from kivy . properties import OptionProperty , ObjectProperty , BooleanProperty , AliasProperty <EOL> from kivy . config import Config <EOL> from kivy . base import EventLoop <EOL> _is_desktop = False <EOL> _keyboard_mode = '<STR_LIT>' <EOL> if Config : <EOL> _is_desktop = Config . getboolean ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> _keyboard_mode = Config . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> class FocusBehavior ( object ) : <EOL> '''<STR_LIT>''' <EOL> _requested_keyboard = False <EOL> _keyboard = ObjectProperty ( None , allownone = True ) <EOL> _keyboards = { } <EOL> ignored_touch = [ ] <EOL> '''<STR_LIT>''' <EOL> def _set_keyboard ( self , value ) : <EOL> focus = self . focus <EOL> keyboard = self . _keyboard <EOL> keyboards = FocusBehavior . _keyboards <EOL> if keyboard : <EOL> self . focus = False <EOL> if self . _keyboard : <EOL> del keyboards [ keyboard ] <EOL> if value and not value in keyboards : <EOL> keyboards [ value ] = None <EOL> self . _keyboard = value <EOL> self . focus = focus <EOL> def _get_keyboard ( self ) : <EOL> return self . _keyboard <EOL> keyboard = AliasProperty ( _get_keyboard , _set_keyboard , <EOL> bind = ( '<STR_LIT>' , ) ) <EOL> '''<STR_LIT>''' <EOL> is_focusable = BooleanProperty ( _is_desktop ) <EOL> '''<STR_LIT>''' <EOL> focus = BooleanProperty ( False ) <EOL> '''<STR_LIT>''' <EOL> focused = focus <EOL> '''<STR_LIT>''' <EOL> def _set_on_focus_next ( self , instance , value ) : <EOL> '''<STR_LIT>''' <EOL> next = self . _old_focus_next <EOL> if next is value : <EOL> return <EOL> if isinstance ( next , FocusBehavior ) : <EOL> next . focus_previous = None <EOL> self . _old_focus_next = value <EOL> if value is None or value is StopIteration : <EOL> return <EOL> if not isinstance ( value , FocusBehavior ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> value . focus_previous = self <EOL> focus_next = ObjectProperty ( None , allownone = True ) <EOL> '''<STR_LIT>''' <EOL> def _set_on_focus_previous ( self , instance , value ) : <EOL> prev = self . _old_focus_previous <EOL> if prev is value : <EOL> return <EOL> if isinstance ( prev , FocusBehavior ) : <EOL> prev . focus_next = None <EOL> self . _old_focus_previous = value <EOL> if value is None or value is StopIteration : <EOL> return <EOL> if not isinstance ( value , FocusBehavior ) : <EOL> raise ValueError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> value . focus_next = self <EOL> focus_previous = ObjectProperty ( None , allownone = True ) <EOL> '''<STR_LIT>''' <EOL> keyboard_mode = OptionProperty ( '<STR_LIT>' , options = ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> '''<STR_LIT>''' <EOL> input_type = OptionProperty ( '<STR_LIT:text>' , options = ( '<STR_LIT:text>' , '<STR_LIT>' , '<STR_LIT:url>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT:address>' ) ) <EOL> '''<STR_LIT>''' <EOL> unfocus_on_touch = BooleanProperty ( _keyboard_mode not in <EOL> ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , ** kwargs ) : <EOL> self . _old_focus_next = None <EOL> self . _old_focus_previous = None <EOL> super ( FocusBehavior , self ) . __init__ ( ** kwargs ) <EOL> self . _keyboard_mode = _keyboard_mode <EOL> fbind = self . fbind <EOL> fbind ( '<STR_LIT>' , self . _on_focus ) <EOL> fbind ( '<STR_LIT>' , self . _on_focusable ) <EOL> fbind ( '<STR_LIT>' , self . _on_focusable ) <EOL> fbind ( '<STR_LIT>' , self . _set_on_focus_next ) <EOL> fbind ( '<STR_LIT>' , self . _set_on_focus_previous ) <EOL> def _on_focusable ( self , instance , value ) : <EOL> if self . disabled or not self . is_focusable : <EOL> self . focus = False <EOL> def _on_focus ( self , instance , value , * largs ) : <EOL> if self . is_focusable and self . keyboard_mode == '<STR_LIT>' : <EOL> if value : <EOL> self . _bind_keyboard ( ) <EOL> else : <EOL> self . _unbind_keyboard ( ) <EOL> def _ensure_keyboard ( self ) : <EOL> if self . _keyboard is None : <EOL> self . _requested_keyboard = True <EOL> keyboard = self . _keyboard = EventLoop . window . request_keyboard ( <EOL> self . _keyboard_released , self , input_type = self . input_type ) <EOL> keyboards = FocusBehavior . _keyboards <EOL> if keyboard not in keyboards : <EOL> keyboards [ keyboard ] = None <EOL> def _bind_keyboard ( self ) : <EOL> self . _ensure_keyboard ( ) <EOL> keyboard = self . _keyboard <EOL> if not keyboard or self . disabled or not self . is_focusable : <EOL> self . focus = False <EOL> return <EOL> keyboards = FocusBehavior . _keyboards <EOL> old_focus = keyboards [ keyboard ] <EOL> if old_focus : <EOL> old_focus . focus = False <EOL> keyboards [ keyboard ] = self <EOL> keyboard . bind ( on_key_down = self . keyboard_on_key_down , <EOL> on_key_up = self . keyboard_on_key_up , <EOL> on_textinput = self . keyboard_on_textinput ) <EOL> def _unbind_keyboard ( self ) : <EOL> keyboard = self . _keyboard <EOL> if keyboard : <EOL> keyboard . unbind ( on_key_down = self . keyboard_on_key_down , <EOL> on_key_up = self . keyboard_on_key_up , <EOL> on_textinput = self . keyboard_on_textinput ) <EOL> if self . _requested_keyboard : <EOL> keyboard . release ( ) <EOL> self . _keyboard = None <EOL> self . _requested_keyboard = False <EOL> del FocusBehavior . _keyboards [ keyboard ] <EOL> else : <EOL> FocusBehavior . _keyboards [ keyboard ] = None <EOL> def keyboard_on_textinput ( self , window , text ) : <EOL> pass <EOL> def _keyboard_released ( self ) : <EOL> self . focus = False <EOL> def on_touch_down ( self , touch ) : <EOL> if not self . collide_point ( * touch . pos ) : <EOL> return <EOL> if ( not self . disabled and self . is_focusable and <EOL> ( '<STR_LIT>' not in touch . profile or <EOL> not touch . button . startswith ( '<STR_LIT>' ) ) ) : <EOL> self . focus = True <EOL> FocusBehavior . ignored_touch . append ( touch ) <EOL> return super ( FocusBehavior , self ) . on_touch_down ( touch ) <EOL> @ staticmethod <EOL> def _handle_post_on_touch_up ( touch ) : <EOL> '''<STR_LIT>''' <EOL> touches = FocusBehavior . ignored_touch <EOL> if touch in touches : <EOL> touches . remove ( touch ) <EOL> return <EOL> if '<STR_LIT>' in touch . profile and touch . button in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> return <EOL> for focusable in list ( FocusBehavior . _keyboards . values ( ) ) : <EOL> if focusable is None or not focusable . unfocus_on_touch : <EOL> continue <EOL> focusable . focus = False <EOL> def _get_focus_next ( self , focus_dir ) : <EOL> current = self <EOL> walk_tree = '<STR_LIT>' if focus_dir is '<STR_LIT>' else '<STR_LIT>' <EOL> while <NUM_LIT:1> : <EOL> while getattr ( current , focus_dir ) is not None : <EOL> current = getattr ( current , focus_dir ) <EOL> if current is self or current is StopIteration : <EOL> return None <EOL> if current . is_focusable and not current . disabled : <EOL> return current <EOL> itr = getattr ( current , walk_tree ) ( loopback = True ) <EOL> if focus_dir is '<STR_LIT>' : <EOL> next ( itr ) <EOL> for current in itr : <EOL> if isinstance ( current , FocusBehavior ) : <EOL> break <EOL> if isinstance ( current , FocusBehavior ) : <EOL> if current is self : <EOL> return None <EOL> if current . is_focusable and not current . disabled : <EOL> return current <EOL> else : <EOL> return None <EOL> def keyboard_on_key_down ( self , window , keycode , text , modifiers ) : <EOL> '''<STR_LIT>''' <EOL> if keycode [ <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> if [ '<STR_LIT>' ] == modifiers : <EOL> next = self . _get_focus_next ( '<STR_LIT>' ) <EOL> else : <EOL> next = self . _get_focus_next ( '<STR_LIT>' ) <EOL> if next : <EOL> self . focus = False <EOL> next . focus = True <EOL> return True <EOL> return False <EOL> def keyboard_on_key_up ( self , window , keycode ) : <EOL> '''<STR_LIT>''' <EOL> if keycode [ <NUM_LIT:1> ] == '<STR_LIT>' : <EOL> self . focus = False <EOL> return True <EOL> return False <EOL> def show_keyboard ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . keyboard_mode == '<STR_LIT>' : <EOL> self . _bind_keyboard ( ) <EOL> def hide_keyboard ( self ) : <EOL> '''<STR_LIT>''' <EOL> if self . keyboard_mode == '<STR_LIT>' : <EOL> self . _unbind_keyboard ( ) </s>
