a
    V$c`$                    @   s  d dl mZmZmZmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZ d dlZd dlZd dlZd dlZd dlmZmZ dd Zi Zi Zdd ZdRd
dZdd Z dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&dd Z'dd Z(dd Z)d d! Z*d"d# Z+G d$d% d%ej,j-j.Z/G d&d' d'ej,j-j.Z0G d(d) d)ej,j-j.Z1G d*d+ d+ej,j-j.Z2G d,d- d-ej,j-j.Z3G d.d/ d/ej,j-j.Z4G d0d1 d1ej,j5j6Z7ej8ej9ej:ej;fZ<G d2d3 d3ej,j-j=Z>dSd6d7Z?G d8d9 d9e>Z@G d:d; d;eAZBdaCd	aDdaEg aFg aGd<d= ZHd>d? ZIG d@dA dAej,j5j6ZJG dBdC dCejKjKjLZMi ZNG dDdE dEejAjOZPG dFdG dGej,j5j6ZQG dHdI dIej,j-jRZSG dJdK dKejTjUZVG dLdM dMej,j-j.ZWG dNdO dOej,j5j6ZXG dPdQ dQej,j5j6ZYdS )T    )divisionabsolute_importwith_statementprint_functionunicode_literals)PY2
basestringbchrbordchropenpystrrangeroundstrtobytesunicodeN)renderRenderc                    s  t | ttfr6| sdS dd fdd| D  d S | tjjv rTttjj|   S | tjjv rrttjj|   S | du r~dS | 	d}|d	 d
kr rdt
jt|d f S dS |d	 dkr܈ rdt
jt|d f S dS h d}t }|d	 |v r
||d	 q|d	 dks&|d	 dkr*dS d|} d|v rDd nd|v rRd  rddt
j }n
dt
j }d|v r|d7 }n|d7 }| dvrd|v stjrd|v r|dt
j 7 }n|dt
j 7 }| dvr d|v r|dt
j 7 }n|dt
j 7 }| d vrDd!|v s&tjs6d|v r6|dt
j 7 }n|dt
j 7 }| d"vr~d#|v rf|dt
j 7 }d$|v r~|dt
j 7 }t|dkrt|d	 dkrtjjrtd%|  ndS |d&|d	  7 }n>|d	 d'krtjjrtd%|  ndS |d(tt
j|  7 }|S ))z
    Compiles a keymap entry into a python expression.

    keydown determines if we are dealing with keys going down (press),
    or keys going up (release).
    z(False)(z or c                    s   g | ]}t | qS  )compile_event.0ikeydownr   renpy/display\behavior.py
<listcomp>1       z!compile_event.<locals>.<listcomp>)N_r   	mousedownz#(ev.type == %d and ev.button == %d)   mouseup>	   repeataltnoshiftctrlosctrlshiftkeyupmetar   joypadr   Tr+   Fz(ev.type == %dr%   z and (ev.repeat)z and (not ev.repeat))K_LALTK_RALTr&   r)   z and (ev.mod & %d)z and not (ev.mod & %d))K_LGUIK_RGUIr,   )K_LCTRLK_RCTRLr(   )K_LSHIFTK_RSHIFTr*   r'   zInvalid key specifier %sz and ev.unicode == %r)Kz and ev.key == %d))
isinstancelisttuplejoinrenpyconfigkeymapr   default_keymapsplitpygameMOUSEBUTTONDOWNintMOUSEBUTTONUPsetaddpopKEYDOWNKEYUP	macintoshKMOD_ALT	KMOD_META	KMOD_CTRL
KMOD_SHIFTlen	developer	Exceptiongetattr	constants)keyr   part	MODIFIERS	modifiersrvr   r   r   r   $   s    	 















r   c                   C   s   t   t  dS )z
    :doc: other

    Clears the keymap cache. This allows changes to :var:`config.keymap` to
    take effect without restarting Ren'Py.
    N)event_cacheclearkeyup_cacher   r   r   r   clear_keymap_cache   s    r\   Fc                 K   sX   t jjsdS t| ttfs | g} | |d}|| tj	t jj
j|}tj| dS )aL  
    :doc: other

    Queues an event with the given name. `Name` should be one of the event
    names in :var:`config.keymap`, or a list of such names.

    `up`
        This should be false when the event begins (for example, when a keyboard
        button is pressed.) It should be true when the event ends (when the
        button is released.)

    The event is queued at the time this function is called. This function will
    not work to replace an event with another - doing so will change event order.
    (Use :var:`config.keymap` instead.)

    This method is threadsafe.
    N)
eventnamesup)r<   display	interfacer8   r9   r:   updaterA   eventEventcore	EVENTNAMEpost)namer^   kwargsdataevr   r   r   queue_event   s    

rk   c                 C   st   | j tjjjkr(|| jv r$| js$dS dS t|tr:t	|}t
|d}|du rltdt|d t }|t
|< || S )a#  
    :doc: udd_utility

    Returns true if the pygame event `ev` matches `keysym`

    `keysym`
        One of:

        * The name of a keybinding in :var:`config.keymap`.
        * A keysym, as documented in the :ref:`keymap` section.
        * A list containing one or more keysyms.
    TFNlambda ev : )typer<   r_   rd   re   r]   r^   r8   r9   r:   rY   getevalr   globalsrj   keysym
check_coder   r   r   	map_event   s    
rt   c                 C   sp   | j tjjjkr$|| jv r$| jr$dS t|tr6t	|}t
|d}|du rhtdt|d t }|t
|< || S )zCReturns true if the event matches the named keycode being released.TNrl   F)rm   r<   r_   rd   re   r]   r^   r8   r9   r:   r[   rn   ro   r   rp   rq   r   r   r   	map_keyup   s    
ru   c                 C   st   t jjsdS t jjsdS t| drJt jjjdu s8t jj	rJdt j_
t j  t| ds^t| drpdt j_
t j  dS )z
    This handles setting skipping in response to the press of one of the
    CONTROL keys. The library handles skipping in response to TAB.
    Nskipslowstop_skipping)r<   r=   allow_skippingstore	_skippingrt   gamer`   	text_rectskip_during_textskippingexportsrestart_interactionru   rj   r   r   r   r      s    


r   c                 C   s
   t | dS )N	inspector)rt   r   r   r   r   r     s    r   c                 C   sF   | du rdS t | tjjr"|   t | ttfrB| D ]}t| q4dS )zH
    Predicts some of the actions that may be caused by a variable.
    N)r8   r<   uiActionpredictr9   r:   predict_action)varr   r   r   r   r     s    r   c                 O   s\   | du rdS t | ttfrNd}| D ]&}t|g|R i |}|dur"|}q"|S | |i |S )a"  
    :doc: run
    :name: renpy.run
    :args: (action)

    Run an action or list of actions. A single action is called with no
    arguments, a list of actions is run in order using this function, and
    None is ignored.

    Returns the result of the last action to return a value.
    N)r8   r9   r:   run)actionargsrh   rX   r   new_rvr   r   r   r   .  s    r   c                 C   sN   | du rdS t | ttfr0| D ]}t| qdS t| dd}|durJ|  dS )zC
    Calls the unhovered method on the variable, if it exists.
    N	unhovered)r8   r9   r:   run_unhoveredrR   )r   r   fr   r   r   r   L  s    
r   c                 C   sb   t | ttfrFd }| D ]*}t||}|d ur|d u s<||k r|}q|S t | tjjr^| |S d S N)r8   r9   r:   run_periodicr<   r   r   periodic)r   strX   r   vr   r   r   r   _  s    
r   c                 C   sR   t | ttfr4| D ]}t|}|d ur|  S qd S t| dd }|d u rLd S | S )Nget_tooltip)r8   r9   r:   r   rR   )r   r   rX   funcr   r   r   r   p  s    
r   c                 C   sb   t | ttfrD| D ]}t |tjjr|   S qtdd | D S t | tjj	rZ|  S dS dS )z
    :name: renpy.is_selected
    :doc: run

    Returns a true value if the provided action or list of actions
    indicates it is selected, and false otherwise.
    c                 s   s   | ]}t |V  qd S r   )is_selectedr   r   r   r   	<genexpr>  r   zis_selected.<locals>.<genexpr>FN)
r8   r9   r:   r<   rz   
SelectedIfget_selectedanyr   r   r   r   r   r   r   r     s    	r   c                 C   sb   t | ttfrD| D ]}t |tjjr|   S qtdd | D S t | tjj	rZ|  S dS dS )z
    :name: renpy.is_sensitive
    :doc: run

    Returns a true value if the provided action or list of actions
    indicates it is sensitive, and false otherwise.
    c                 s   s   | ]}t |V  qd S r   )is_sensitiver   r   r   r   r     r   zis_sensitive.<locals>.<genexpr>TN)
r8   r9   r:   r<   rz   SensitiveIfget_sensitiveallr   r   r   r   r   r   r     s    	r   c                 C   sd   t | ttfrHg }| D ]}t|}|d ur|| q|rDd|S d S t | tjjr\| jS d S d S )N )	r8   r9   r:   r&   appendr;   r<   r   r   )clickedrX   r   tr   r   r   r&     s    
r&   c                       s:   e Zd ZdZdZdZd
 fdd	Zdd Zdd	 Z  Z	S )Keymapz
    This is a behavior that maps keys to actions that are called when
    the key is pressed. The keys are specified by giving the appropriate
    k_constant from pygame.constants, or the unicode for the key.
    TNc                    s@   |d urt t| jd|d nt t| jdd || _|| _d S )Ndefault)styleactivate_sound)r   )superr   __init__r>   capture)selfreplacesr   r   r>   	__class__r   r   r     s
    zKeymap.__init__c                 C   s\   | j  D ]L\}}t||r
tj| jj t|}|d urD|  S | j	r
tj
j q
d S r   )r>   itemsrt   r<   r   playr   r   r   r   r_   rd   IgnoreEvent)r   rj   xyr   rg   r   rX   r   r   r   rb     s    
zKeymap.eventc                 C   s   | j  D ]}t| q
d S r   )r>   valuesr   )r   r   r   r   r   predict_one_action  s    zKeymap.predict_one_action)NNT)
__name__
__module____qualname____doc__r   	_box_skipr   rb   r   __classcell__r   r   r   r   r     s   	r   c                       s(   e Zd ZdZ fddZdd Z  ZS )RollForwardz/
    This behavior implements rollforward.
    c                    s    t t| jf i | || _d S r   )r   r   r   value)r   r   
propertiesr   r   r   r     s    zRollForward.__init__c                 C   s   t |drtj| jS d S )Nrollforward)rt   r<   r   roll_forward_corer   r   rj   r   r   r   r   r   r   rb     s    
zRollForward.eventr   r   r   r   r   rb   r   r   r   r   r   r     s   r   c                       s2   e Zd ZdZdZdZd fdd	Zdd Z  ZS )	PauseBehaviorz
    This is a class implementing the Pause behavior, which is to
    return a value after a certain amount of time has elapsed.
    FNc                    sB   t t| jf i | || _|| _|| _|d u r8tjjn|| _	d S r   )
r   r   r   delayresultvoicer<   r=   modal_blocks_pausemodal)r   r   r   r   r   r   r   r   r   r     s
    zPauseBehavior.__init__c                 C   s   |j tjjjkr|jr:| jr:tjjt	| j
| d d S || j
kr| jrztjjrztj rhtjj rztjjd d S tjj|| j
 r| jS dtjj_tjjt	| j
| d d S )Nr   g?T)rm   r<   r_   rd   	TIMEEVENTr   r|   r`   timeoutmaxr   r   r=   nw_voiceafm_callbacktts	is_activedrawn_sincer   force_redrawr   r   r   r   rb   
  s    

zPauseBehavior.event)FFN)	r   r   r   r   r   r   r   rb   r   r   r   r   r   r     s
   r   c                       s(   e Zd ZdZ fddZdd Z  ZS )PredictPauseBehaviorz
    This behavior implements a pause that will last until Interface.force_prediction
    becomes False, meaning that everything that can be predicted has been predicted
    and loaded.
    c                    s   t t| jf i | d S r   )r   r   r   )r   r   r   r   r   r   +  s    zPredictPauseBehavior.__init__c                 C   s    t jjjsdS t jjd d S NFr   )r<   r_   r`   force_predictionr|   r   r   r   r   r   rb   .  s    
zPredictPauseBehavior.eventr   r   r   r   r   r   $  s   r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )SoundStopBehaviorz
    This is a class implementing the sound stop behavior,
    which is to return False when a sound is no longer playing
    on the named channel.
    Fc                    s&   t t| jf i | || _|| _d S r   )r   r   r   channelr   )r   r   r   r   r   r   r   r   <  s    zSoundStopBehavior.__init__c                 C   s(   t jj| js| jS t jjd d S )Ng?)	r<   audiomusicget_playingr   r   r|   r`   r   r   r   r   r   rb   B  s    zSoundStopBehavior.event)Fr   r   r   r   r   r   5  s   r   c                       sV   e Zd ZdZdZdZdgZdddgddgf fdd	Zdd	 Zd
d Z	dd Z
  ZS )SayBehaviorz
    This is a class that implements the say behavior,
    which is to return True (ending the interaction) if
    the user presses space or enter, or clicks the left
    mouse button.
    TNdismiss_unfocuseddismissc                    sr   t t| jf d|i| t|ttfs.|g}t|ttfsB|g}|d urVt|| _nd | _|| _|| _	|| _
d S )Nr   )r   r   r   r8   r9   r:   rO   
afm_lengthr   r   allow_dismiss)r   r   afmr   r   r   r   r   r   r   r   W  s    zSayBehavior.__init__c                 C   s   t jj d S r   )r<   r_   r   TTSRootr   r   r   r   _tts_allk  s    zSayBehavior._tts_allc              	   G   s   || _ d| _d| _|D ]x}zD|jd |j|j }tjjj|g d}|  jt	t
|d7  _W q ty   |  jt	|j|j d7  _Y q0 qd S )Nr#   r   )allow)
text_tupler   	text_timetextstartendr<   extrasfilter_text_tagsr   rO   rQ   )r   r   r   afm_textr   r   r   set_textn  s    zSayBehavior.set_textc                 C   s"  | j rtjjjrtjjjrdtjj| j   tjj tjjj }| j	d urnd}| j	D ]}t
|| }qR||7 }|jtjjjkr|jrd S ||krtjjrtj rtjj sdS tjjd qdS ntjj||  dd | jD dd | jD  }|D ]l\}	}
t||	 r|
r(|  s( qtjjrPd tj_tj  tjj tjjs^d}tjd	rxtjjj }n
tjjj!}|jt"j#krd| tjj$ }|d
kr|tjj%k rtj&  tjj n2|dkrd| tjj%k rtj&  tjj tjjj'rFtjjjrFtjjj(sFdtjj_tj  tjj | j)rd| ) sdtjj  dS  qtjj*d }tjjrtjj+rtj,j-r|jtjjjkr||kr|jrd S tjjj.rdS tjjdkrdS tj/ 0drdS d tj_tj  ntjj||  d S )Ng      ?r   Tg?c                 S   s   g | ]}|d fqS )Tr   r   r   r   r   r     r   z%SayBehavior.event.<locals>.<listcomp>c                 S   s   g | ]}|d fqS )Fr   r   r   r   r   r     r   disablemobileleftrightFg     @@fast)1r   r<   r|   preferencesafm_time
afm_enabler=   	afm_bonusafm_charactersr   r   get_timerm   r_   rd   r   r   r   r   r   r`   r   r   r   rt   
is_focusedr   r   r   r   enable_rollback_sidevariantmobile_rollback_sidedesktop_rollback_siderA   rD   screen_widthrollback_side_sizerollbackusing_afm_enableafm_after_clickr   
skip_delayry   rz   r{   skip_unseencontextseen_current)r   rj   r   r   r   	afm_delaymax_timer   r   dismiss_eventcheck_focusrollback_sidepercentr  r   r   r   rb   }  s    $

 











zSayBehavior.event)r   r   r   r   	focusabler   r   r   r   r   rb   r   r   r   r   r   r   J  s   r   c                       sR   e Zd ZdZdZd fdd	Zdd Zdd	 Z fd
dZdd Z	dd Z
  ZS )DismissBehaviorzJ
    This is used to implement the dismiss screen language statement.
    TNc                    s6   t t| jf i | |d u r&td|| _|| _d S )NzDismiss requires an action.)r   r  r   rQ   r   r   )r   r   r   r   r   r   r   r     s
    zDismissBehavior.__init__c                 C   s   dS N r   r   r   r   r   _tts  s    zDismissBehavior._ttsc                 C   s   |  t| j}|S r   )_tts_commonr&   r   r   rX   r   r   r   r     s    zDismissBehavior._tts_allc                    s2   | j rt| j stjj  tt| || d S r   )	r   callabler<   r_   focus
mark_modalr   r  find_focusable)r   callback
focus_namer   r   r   r    s    zDismissBehavior.find_focusablec                 C   s>   t jjdd}|| d d d d d  | jr:t| js:d|_|S )Nr   r   )r<   r_   r   r   	add_focusr   r  r   widthheightr   atrX   r   r   r   r     s
    zDismissBehavior.renderc                 C   sn   |   rDt|drDtj| jj t| j}|d ur8|S tj	j
 tj	j| j|||d d rjtj	j d S )Nr   )r   rt   r<   r   r   r   r   r   r   r_   rd   r   layoutcheck_modalr   IgnoreLayers)r   rj   r   r   r   rX   r   r   r   rb     s    
zDismissBehavior.event)NT)r   r   r   r   r  r   r  r   r  r   rb   r   r   r   r   r   r    s   

r  c                       s   e Zd Zi ZdZdZdZdZdZdZ	dZ
dZdZddddddddi dddddf fdd	Zdd Zdd	 Zd
d Z fddZd  fdd	Zd! fdd	Zdd Zdd Z fddZ fddZ fddZdd Zdd Z  ZS )"ButtonNFbuttonc                    s   t |tjjr|}tt| j|fd|i| || _|| _|| _	|| _
|| _|| _|
| _d| _|| _|	| _|| _|| _d | _d| _d S )Nr   TF)r8   r<   r   r   r   r"  r   r   selected	sensitiver   hoveredr   	alternater  role_parameterr>   rr   alternate_keysymtime_policy_data_duplicatable)r   childr   r   r&  r   r   roletime_policyr>   r'  r$  r%  rr   r)  r   r   r   r   r   9  s"    zButton.__init__c                 C   s   | j d ur| j S t| jS r   )_tooltipr   r   r   r   r   r   _get_tooltipX  s    
zButton._get_tooltipc                 C   s4   |   }| j |_|| jjd d|_d|_|S NTF)_copyr   copyset_style_prefixprefixr  lockedr  r   r   r   _in_current_store^  s    zButton._in_current_storec                 C   sJ   t | j t | j t | j t | j | jrF| j D ]}t | q8d S r   )r   r   r&  r   r'  r>   r   r   r   r   r   r   r   f  s    



zButton.predict_one_actionc                    s*  | j jr"| j || j| j \}| _tt| ||||}| jr&| j j}|d ur^|\}}}	}
n,| j j}| j j	}|j
| j j }	|j| j j }
| j j}|du r|}nP|d urztjj||j
|j||}W n( ty   t|r|}ntdY n0 |d urd}d}nd }d }|| d |||	|
|||	 |S )NTz<Focus_mask must be None, True, a displayable, or a callable.r   )r   r.  r*  r   r"  r   r   
focus_rectleft_margin
top_marginr  right_marginr  bottom_margin
focus_maskr<   r_   rQ   r  r  )r   r  r  r   r  rX   rectfxfyfwfhmaskfmxfmyr   r   r   r   p  s>    
zButton.renderc                    sR   t t| | d }|s"t| j}| | jd  | jd urN| j| jd  |S Nhover)r   r"  r  r   r&  set_transform_eventr-  r,  )r   r   rX   r   r   r   r    s    

zButton.focusc                    s^   t t| | d | _|s.t| j t| j | | j	d  | j
d urZ| j
| j	d  d S Nidle)r   r"  unfocuslongpress_startr   r&  r   r   rI  r-  r,  r   r   r   r   r   rL    s    


zButton.unfocusc                 C   s   | j d ur| j S t| jS r   )r$  r   r   r   r   r   r   r     s    
zButton.is_selectedc                 C   s   | j d ur| j S t| jS r   )r%  r   r   r   r   r   r   r     s    
zButton.is_sensitivec                    s   | j s| jd ur<|  rd}nd}|  r2| j}qFd }d}n
d}| j}| jd urV| j}|| jksj|| jurtjj	
|  || _|| _| jd ur| | jd d d| _n| | jd d d| _tt|   d S )N	selected_r  idle_Tinsensitive_F)r6  r   r   r   r   r(  r-  r<   r_   r   
invalidater4  r  r   r"  per_interact)r   r-  r   r   r   r   rS    s.    


zButton.per_interactc           
         sJ   j r
d S  fdd}t j|}|d ur8tjj| |jtvsJ j	j
rltt ||||}|d url|S  jd ur jd urt| jr| jS  jd ur jd urt| jr| jS   sd S  j D ]\}}	t||rt|	  S qֈ jd urtjjr|jtjkrJ|jdkrJ| _| _| _tjjtjj   jd urt!"| j | j tjj#krd  _n:| jtjj  krtj$%tjj& tjj'  | jS  jd urt|drtjj()  jd urt|drtjj()  jd ur$t|dr$| jS  jd urFt|drF| jS d S )Nc                    s4   t j jj t| }|d ur$|S t jj d S r   )	r<   r   r   r   r   r   r_   rd   r   )r   rX   r   r   r   handle_click  s
    z"Button.event.<locals>.handle_clickr#   button_ignorebutton_alternate_ignorebutton_selectbutton_alternate)*r6  r   r   r<   r|   r`   r   rm   
KEY_EVENTSr   
key_eventsr   r"  rb   rr   r   rt   r)  r'  r   r>   r   r   r_   touchrA   rB   r#  rM  longpress_xlongpress_yr=   longpress_durationmathhypotlongpress_radiusr   vibratelongpress_vibrateafter_longpressrd   r   )
r   rj   r   r   r   rT  r   rX   rg   r   r   r   r   rb     sV    


"


zButton.eventc                    s   |rt t| || d S r   )r   r"  r4  r   r5  rootr   r   r   r4  8  s    zButton.set_style_prefixc                 C   s   dS r  r   r   r   r   r   r  <  s    zButton._ttsc                 C   s0   |  t| j}|  r,|dtjd 7 }|S )Nr   r$  )r  r&   r   r   r<   minstore__r  r   r   r   r   ?  s    zButton._tts_all)F)F)r   r   r   r>   r   r'  rM  r\  r]  r(  rr   r)  r6  r   r0  r7  r   r   r  rL  r   r   rS  rb   r4  r  r   r   r   r   r   r   r"  '  s8   
,%Pr"  r#  button_textc                 K   sD   t j|dd\}}t jjj| fd|i|} t| f||d|S )Ntext_r  r   )r   r   )r<   easysplit_propertiesr   Textr"  )r   r   
text_styler   r   text_propertiesbutton_propertiesr   r   r   
TextButtonK  s    rq  c                
       s:   e Zd ZdZdZdZd
 fdd	Zdd Zdd	 Z  Z	S )ImageButtonz8
    Used to implement the guts of an image button.
    Nimage_buttonc                    s   |p|}|p|}|p|}|p|}|p&|}|p.|}|p6|}t tj|tj|tj|tj|tj|tj|tj|tj|d| _tt| jd|	|
|d| d S )N)rP  hover_rQ  	activate_selected_idle_selected_hover_selected_insensitive_selected_activate_)r   r   r&  )N)dictr<   rk  displayablestate_childrenr   rr  r   )r   
idle_imagehover_imageinsensitive_imageactivate_imageselected_idle_imageselected_hover_imageselected_insensitive_imageselected_activate_imager   r   r&  r   r   r   r   r   \  s0    







zImageButton.__init__c                 C   s2   | j d u rt| j S t| j | j g S d S r   )imagebutton_childr9   r|  r   r   r   r   r   visit  s    
zImageButton.visitc                 C   sZ   | j jp| j| j j }|| jurT|| _|jrD|d | _| j  n|| _| j	  | jS r   )
r   r,  r|  r5  imagebutton_raw_childr+  
_duplicater  _uniquerS  )r   	raw_childr   r   r   	get_child  s    

zImageButton.get_child)
NNNNNNNrs  NN)
r   r   r   r   r  r  r   r  r  r   r   r   r   r   rr  T  s              )rr  c                   @   s   e Zd Zdd Zdd ZdS )HoveredProxyc                 C   s   || _ || _d S r   ab)r   r  r  r   r   r   r     s    zHoveredProxy.__init__c                 C   s   |    | jr|  S d S r   r  r   r   r   r   __call__  s    zHoveredProxy.__call__N)r   r   r   r   r  r   r   r   r   r    s   r  c                   C   s   g a g ad ad S r   )input_valuesinputsdefault_input_valuer   r   r   r   input_pre_per_interact  s    r  c                  C   sv   t D ]} | tu r qqtadatD ]N} | jtu o:to:| jj}| j }| j|ksZ|| jkr"| 	|| t
|| _q"d S NT)r  current_input_valuer  input_value_activer  r   editableget_textcontentupdate_textrO   	caret_pos)r   r  r  r   r   r   input_post_per_interact  s    
r  c                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )

CaretBlinkz/
    A displayable that renders the caret.
    c                    s\   | dd tt| jf i | tj|}|jrF|d }|	  || _
|| _d| _d S )Nyaligng        r   )
setdefaultr   r  r   r<   rk  r{  r+  r  r  caretcaret_blinkst_base)r   r  r  r   r   r   r   r     s    
zCaretBlink.__init__c                 C   s
   | j  S r   )r  get_placementr   r   r   r   r    s    zCaretBlink.get_placementc                 C   s   | j gS r   )r  r   r   r   r   r    s    zCaretBlink.visitc                 C   sz   || j 8 }tjj| j||||}tjjd|}| j|| j  }|| jd kr\||d tjj| || jd   |S )Nr#   g       @r   r   )	r  r<   r_   r   r  r   r  blitredraw)r   r  r  r   r  crrX   ttlr   r   r   r     s    
zCaretBlink.render)	r   r   r   r   r   r  r  r   r   r   r   r   r   r    s
   r  c                       s   e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZd fdd		Zdd
dZ fddZdd Zdd Zdd Zdd Z fddZ  ZS )Inputz9
    This is a Displayable that takes text as input.
    Nr  r   FinputTc                    sn  t t| jd||
dd| |d u r.tjj}|rF|| _|j}| }t	|| _
| j
| _|| _|| _|| _|| _|| _|| _|| _|| _|| _dd i}|D ]}|dr|| ||< qtjjjf dtjjjf|d|}|rt||}|| _t| j| _| j| _ |	r.d| _t!| j"|	j#|	_#t!| j$|	j%|	_%t&|
trZ|
j| _|
j| _|
j| _|
j'| _'| (| j| j d S )Nr  F)r   r   
substitutecolorr#   )xysizer   )r  ))r   r  r   r<   r=   input_caret_blinkr   r   r  r   r   r  lengthr   excluder5  suffix	copypastechangedr  pixel_widthendswithr_   imageSolidrz   r   	font_sizer  r  rO   r  old_caret_posr  enabler&  r   r   r8   shownr  )r   r   r  r   r   r  r5  r  r  r#  r   r  r  r   r  r  r   
caretpropsr   r  r   r   r   r     sL    

$
zInput.__init__c                    s|  t jjj}j}|jks(jks(|r8t jjd _jj	  d u rTj	 |r|j
_|j
d |j }|j
|j|j|j  }|j
|j|j d  }d|rd|dd d 7 |rڈd|dd d 7 |rd|dd d 7 n
d_d fdd	}	|	| |rVjrV \}
}|
jkrVj_|	| d S ||krx|_jrx| d S )
Nr   r  z{u=1}{{{z{/u}z{u=2}c              
      s   | dkrd} rXt | }j| dj dd | j| ddjg nj| ddjg tjtrj	j_
tjjjd d S )Nr  r   r   r  r  )rO   r   r5  r  replacer  r8   r  r  r   r  r<   r_   r   r  )r  lr  	edit_textr  r   r   r   set_content  s     
z&Input.update_text.<locals>.set_content)r<   r_   r`   text_editingr  r  r   r  r   r  r   r  r   r  r  r  sizer  r  r  )r   new_contentr  
check_sizeeditold_contentedit_text_0edit_text_1edit_text_2r  w_hr   r  r   r  d  sD    

zInput.update_textc                    s2   || j jkr| | j| j tt| || d S r   )r   r5  r  r  r  r   r  r4  re  r   r   r   r4    s    zInput.set_style_prefixc                 C   s   |  | jd d S r  r  r  r   r   r   r   r    s    zInput.enablec                 C   s   |  | jd d S )NFr  r   r   r   r   r     s    zInput.disablec                 C   s   | j d ur6t|  t| j  | j jr6td u r6| j a| js| j d urZ| j  }t|| _| j| _	t
| j	| _| | j	| j d| _d S r  )r   r  r   r  r   r  r  r  r   r  rO   r  r  r  rN  r   r   r   rS    s    




zInput.per_interactc                 C   s  || _ | j| _| jsd S tt|dt|dt|dt|dg}|jtjkrjtj	
 tj@ rj|jsj|sjd S t| j}d }t|dr| jr| jdkr| jd| jd  | j| j|  }|  jd8  _| || j tjj| d tjj nt|drR| j}| jr0|d| j | j | j| jd   }| jrB| j S | js|S n:t|d	r| jdkr|  jd8  _| | j| j tjj| d tjj nt|dr6| jdkrd}	td
| jd | j D ]"}
|
 \}}|| jkr|}	q|	| _| | j| j tjj| d tjj nVt|dr| j|k rl|  jd7  _| | j| j tjj| d tjj n t|dr(| j|k r|}	td
| j| jd d  D ]}
|
 \}}|}	 qqt|	| j d || _| | j| j tjj| d tjj ndt|dr| j|k rr| jd| j | j| jd |  }| || j tjj| d tjj nt|dr<| j|krd}	td
| jd | j D ]"}
|
 \}}|| jkr|}	q| jd|	 | j| j|  }|	| _| || j tjj| d tjj nPt|dr| j|krx| j| j| }d| _| || j tjj| d tjj nt|drd| _| | j| j tjj| d tjj nt|dr|| _| | j| j tjj| d tjj np| jr^t|dr^| jd}tj !tj j"| tjj n.| jrt|drtj #tj j"}|$d}d}|D ]}t%|dkr||7 }qn|jtj&kr| j| j| jdd tjj n|jtj'kr d| _|j(}n|jtjkr|jr2t%|jd dkr2|j}nZtjj)* rNtjj n>d|j	  krhdk rn n |j+tj,tj-B @ stjj |d urd}|D ]}| j.rt/| j.tj0r| j.1|d u rqn|| j.vrq| j2r"t/| j2tj0r| j21|d ur"qn|| j2v r"q||7 }q| j3rR| j3t| j }|d | }|r| jd| j | | j| j|  }|  jt|7  _| j|| jdd tjj d S )Ninput_jump_word_leftinput_jump_word_rightinput_delete_wordinput_delete_fullinput_backspacer   r#   input_enter
input_leftz\s+input_rightinput_delete
input_home	input_end
input_copyzutf-8input_paster      T)r     )4r   r  r  r  r   rt   rm   rA   rH   rT   get_mods	KMOD_LALTr   rO   r  r  r<   r_   r   r  rd   r   r  r   enterr  refinditerspanminr  encodescrapput
SCRAP_TEXTrn   decodeordTEXTEDITING	TEXTINPUTr   r`   text_event_in_queuemodrK   rL   r   r8   Patternsearchr  r  )r   rj   r   r   r   edit_controlsr  raw_textr  	space_positemr   r   r   c	remainingr   r   r   rb     s$   &

$$
 
$
2
$zInput.eventc                    s,   || _ tt| ||||}| jr(d|_|S r  )r   r   r  r   r  
text_inputr  r   r   r   r     s
    zInput.render)r  Nr  NNr  r  NNNTNNFN)F)r   r   r   r   r  r5  r  r  r  r  r   r  r   r  r   r   r  r4  r  r   rS  rb   r   r   r   r   r   r   r  
  sH                  H
J Tr  c                       s   e Zd ZdZdZd  fdd	Zdd	 Zd
d Zdd Ze	eeZ
dd Zdd Ze	eeZdd Zdd Ze	eeZdd Zdd Ze	eeZdd Zdd Zdd Z  ZS )!
Adjustmenta  
    :doc: ui
    :name: ui.adjustment class

    Adjustment objects represent a value that can be adjusted by a bar
    or viewport. They contain information about the value, the range
    of the value, and how to adjust the value in small steps and large
    pages.


    Fr#   r   Nc	           	         sZ   t t|   |du r|rd}|| _t||| _|| _|| _|| _|| _	|| _
|| _dS )af  
        The following parameters correspond to fields or properties on
        the adjustment object:

        `range`
            The range of the adjustment, a number.

        `value`
            The value of the adjustment, a number.

        `step`
            The step size of the adjustment, a number. If None, then
            defaults to 1/10th of a page, if set. Otherwise, defaults
            to the 1/20th of the range.

            This is used when scrolling a viewport with the mouse wheel.

        `page`
            The page size of the adjustment. If None, this is set
            automatically by a viewport. If never set, defaults to 1/10th
            of the range.

            It's can be used when clicking on a scrollbar.

        The following parameters control the behavior of the adjustment.

        `adjustable`
            If True, this adjustment can be changed by a bar. If False,
            it can't.

            It defaults to being adjustable if a `changed` function
            is given or if the adjustment is associated with a viewport,
            and not adjustable otherwise.

        `changed`
            This function is called with the new value when the value of
            the adjustment changes.

        `ranged`
            This function is called with the adjustment object when
            the range of the adjustment is set by a viewport.

            This function may be called multiple times, as part of the layout
            process.

        `force_step`
            If True and this adjustment changes by dragging associated
            viewport or a bar, value will be changed only if the drag
            reached next step.
            If "release" and this adjustment changes by dragging associated
            viewport or a bar, after the release, value will be
            rounded to the nearest step.
            If False, this adjustment will changes by dragging, ignoring
            the step value.

        .. method:: change(value)

            Changes the value of the adjustment to `value`, updating
            any bars and viewports that use the adjustment.
         NT)r   r  r   _rangerm   _value_page_stepr  
adjustableranged
force_step)	r   r   r   steppager  r  r   r  r   r   r   r     s    >zAdjustment.__init__c                 C   sh   |dkrt | jdS || jkr&| jS | jdu r4|S |sF| jdkrF|S t | j| jtt|| j  S )Nr   Frelease)rm   r  r  r  r  r   float)r   r   r  r   r   r   round_value  s    

zAdjustment.round_valuec                 C   s0   | j dkrt| j dS | j | jkr*| jS | j S Nr   )r  rm   r  r   r   r   r   	get_value#  s
    
zAdjustment.get_valuec                 C   s
   || _ d S r   )r  r8  r   r   r   	set_value+  s    zAdjustment.set_valuec                 C   s   | j S r   )r  r   r   r   r   	get_range0  s    zAdjustment.get_rangec                 C   s   || _ | jr| |  d S r   )r  r   r8  r   r   r   	set_range3  s    zAdjustment.set_rangec                 C   s   | j d ur| j S | jd S )N
   )r  r  r   r   r   r   get_page:  s    
zAdjustment.get_pagec                 C   s
   || _ d S r   )r  r8  r   r   r   set_page@  s    zAdjustment.set_pagec                 C   sL   | j d ur| j S | jd ur.| jdkr.| jd S t| jtrD| jd S dS d S )Nr   r  r#   )r  r  r  r8   r  r  r   r   r   r   get_stepE  s    


zAdjustment.get_stepc                 C   s
   || _ d S r   )r  r8  r   r   r   set_stepQ  s    zAdjustment.set_stepc                 C   s   t | g | d S r   )adj_registeredr  r   r   dr   r   r   registerW  s    zAdjustment.registerc                 C   sb   |dk rd}|| j kr| j }|| jkr^|| _t| g D ]}tjj|d q8| jr^| |S d S r  )	r  r  r  r  r<   r_   r   r  r  )r   r   r  r   r   r   changeZ  s    


zAdjustment.changec                 C   s$   t | g D ]}tjj| qdS )zk
        Updates things that depend on this adjustment without firing the
        changed handler.
        N)r  r  r<   r_   r   rR  r  r   r   r   ra   j  s    zAdjustment.update)r#   r   NNNNNF)r   r   r   r   r  r   r  r  r	  propertyr   r
  r  r   r  r  r  r  r  r  r  r  ra   r   r   r   r   r   r    s&   M



r  c                       s   e Zd ZdZdZdd Zd fdd	Zd	d
 Zdd Zdd Z	d fdd	Z
d fdd	Zdd Z fddZdd Zdd Z  ZS )Barzf
    Implements a bar that can display an integer value, and respond
    to clicks on that value.
       c                 C   sH   |dk r6t | j| j| jd| _| j|  | `| `| `|dk rDd | _d S )Nr#   )r  r  )r  r   r   r  
adjustmentr  r   versionr   r   r   after_upgrade|  s    zBar.after_upgradeNFc                    s6  d | _ |d u r~t|tjjrlt|tr2||j  || _ | }tjj	
d | }|d ur~|d| nt|||||d}|
d u r| j d ur|r| j  d }
q| j  d }
n|rd}
nd}
|d ur||d< |d ur||d< tt| jf d	|
i| || _d
| _d| _d| _d| _d| _|| _|| _|| _d S )Nr   tooltip)r  r  r  r#   vbarbarxmaximumymaximumr   TF)r   r8   r<   r   BarValuer  r   get_adjustmentr|   r`   r   r   r  r  	get_styler   r   r  r  	thumb_dimr  r  hiddenr&  r   released)r   r   r   r  r  r  r  r  r  r  r   verticalr   r&  r   r'  r   r  r   r   r   r     sD    

zBar.__init__c                 C   sN   | j d ur4| j  }|j | j kr.tjj|  || _| jj| _| j	|  d S r   )
r   r#  r<   r_   r   rR  r  r  r  r  )r   r  r   r   r   rS    s    


zBar.per_interactc                 C   s   g }| j |j |S r   )r   
_visit_barr   r  r   r   r   r    s    z	Bar.visitc                 C   sr  | j d ur.| j |}|d ur.tjj| | tjj| j||\}}|d urXt	||}|d urjt	||}|| _
|| _| jj}| jj }	| jj}
|dkr| jjdkrd| _tjj||S | jjdkr| dd d| _| jj| jjA r||	 }	| jj}|r|}n|}| jj}| jj}|| | }|r:||
 ||
  }n|}t| jj}|rt| jj||||}t| jj||||}|j}n.t| jj||||}t| jj||||}|j
}||d 8 }|| _||8 }|r||	 | }n|}t|}|| }||7 }||7 }tjj||}|r6| jjrt| jj||||}t| jj||||}| |d|| f |j |ddd	 |j |d|| fdd	 | |d|| f nt| jj||||}t| jj||||}| |d|| f |j |!dd||fddd	 |j |!d|| ||fd|| fdd	 | |d|| f n| jjrt| jj||||}t| jj||||}| ||| df |j |ddd	 |j ||| dfdd	 | ||| df nt| jj||||}t| jj||||}| ||| df |j |!dd||fddd	 |j |!|| d||f|| dfdd	 | ||| df | j"rn|#| d dd|| |S )
Nr   hideTinsensitiverQ  Fr  r  )main)$r   r   r<   r_   r   r  r  
xyminimumsr   r   r  r  r  r   r  unscrollabler&  r   r4  
bar_invertbar_verticalfore_gutter
aft_gutterabsthumb_offsetthumbthumb_shadowr%  rC   bar_resizingfore_baraft_barr  
subsurfacer  r  )r   r  r  r   r  r  xminimumyminimumr   r   r  r0  	dimensionr1  r2  activer%  r4  r5  r6  	fore_sizeaft_sizerX   foresurfaftsurfr   r   r   r     s    



*
*z
Bar.renderc                    s,   t t| | | d |s(t| j d S rG  )r   r  r  rI  r   r&  rN  r   r   r   r  ]  s    
z	Bar.focusc                    s4   t t|   | d |s0t| j t| j d S rJ  )r   r  rL  rI  r   r&  r   r   rN  r   r   r   rL  d  s
    

zBar.unfocusc                 C   sH  | j s
d S |  sd S | jr d S | jj}| jj}|}| jj}| jj|A }	|	rT|| }t	j
j | u }
d}d}|
st|drt	j
jt	jd t	j
j|  | dd d}d}
d}t	j| jj |
rJ|rd}d}nd}d	}t||rt	j
jt	jd
 || jj8 }d}t||rFt	j
jt	jd || jj7 }d}|jtjtjtjfv r|r| jj}| jj}| j| | | j  }|r|| | j d  | | }nd}nJ| jj}| jj}| j!| | | j  }|r|| | j d  | | }nd}d}t"|t#rt#|}|dk r.t	j
jd d}||krJt	j
jd |}|	rX|| }|
r|st|drt	j
jt	jd | dd t	j
jd  | jj$|dd}||kr| j%|}|d ur|S t&| j'}|d ur|S t	j
j() ||kr,| jj$|dd}| j%|}|d ur,|S |r@t	j
j() nd S d S )NFbar_activateactivaterw  Tbar_downbar_up	bar_rightbar_leftdecreaseincreaser  r   r  bar_deactivate
deactivatert  )r  )*r  r   r&  r  r   r   r   r0  r/  r<   r_   r  get_grabrt   r   speakrg  rh  set_grabr4  r   r   r   r  rm   rA   MOUSEMOTIONrD   rB   r1  r2  r  r%  r  r8   rC   r  r  r   r'  rd   r   )r   rj   r   r   r   r   	old_valuer   r(  invertgrabbedjust_grabbedignore_eventrJ  rI  tgutterbgutterzone_heightlgutterrgutter
zone_widthrX   r   r   r   rb   l  s    







z	Bar.eventc                    s   |rt t| || d S r   )r   r  r4  re  r   r   r   r4    s    zBar.set_style_prefixc                 C   s   dS r  r   r   r   r   r   r    s    zBar._ttsc                 C   s.   | j d ur| j j}nd}| |tjd S )Nr  r  )r   r&   r  r<   rg  rh  )r   r&   r   r   r   r     s    

zBar._tts_all)NNNNNNNNNNFNNNN)F)F)r   r   r   r   __version__r  r   rS  r  r   r  rL  rb   r4  r  r   r   r   r   r   r   r  t  s8                  G}wr  c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )Conditionalz
    This class renders its child if and only if the condition is
    true. Otherwise, it renders nothing. (Well, a Null).

    Warning: the condition MUST NOT update the game state in any
    way, as that would break rollback.
    c                    sB   t t| j|i | || _tjj | _t	| jt
tj| _d S r   )r   r]  r   	conditionr<   r_   r  Nullnullro   varsrz   state)r   r^  r   r   r   r   r   r     s    zConditional.__init__c                 C   s.   | j rt| j||||S t| j||||S d S r   )rb  r   r,  r`  r   r  r  r   r  r   r   r   r   	  s    zConditional.renderc                 C   sL   t | jttj}|| jkr,tjj| d || _|rH| j	
||||S d S r  )ro   r^  ra  r<   rz   rb  r_   r   r  r,  rb   r   rj   r   r   r   rb  r   r   r   rb   	  s    
zConditional.event)r   r   r   r   r   r   rb   r   r   r   r   r   r]    s   r]  c                   @   s   e Zd ZdZdZdZdS )
TimerStatezJ
    Stores the state of the timer, which may need to be rolled back.
    FN)r   r   r   r   started
next_eventr   r   r   r   re  	  s   re  c                       sV   e Zd ZdZdZdZdZdd Zdddi ddf fdd		Z fd
dZ	dd Z
  ZS )Timerr#   FTc                 C   s(   |dk r$t  | _| j| j_| j| j_d S )Nr#   )re  rb  rf  rg  r  r   r   r   r  )	  s    
zTimer.after_upgradeNr   c           	         s   t t| jf i | |dkr&td|| _|| _d | _|| _|| _|| _	d| _
|d u r`tjjn|| _t|trz|j| _nt | _d S )Nr   zA timer's delay must be > 0.F)r   rh  r   rQ   r   r%   rg  functionr   rh   rf  r<   r=   modal_blocks_timerr   r8   rb  re  )	r   r   r   r%   r   rh   r   r   r   r   r   r   r   /	  s    

zTimer.__init__c                    sB   | j js,d| j _|| j | j _tjj| tt	| 
||||S r  )rb  rf  r   rg  r<   r|   r`   r   r   rh  r   rc  r   r   r   r   N	  s
    zTimer.renderc                 C   s   |j tjjjkr | jr |jr d S | j}|js>d|_|| j |_	|j	d u rLd S ||j	k rntj
j|j	|  d S | js|d |_	n8|j	| j |_	|j	|k r|| j |_	tj
j|j	|  t| jg| jR i | jS r  )rm   r<   r_   rd   r   r   rb  rf  r   rg  r|   r`   r   r%   r   ri  r   rh   rd  r   r   r   rb   W	  s$    


zTimer.event)r   r   r   r\  rf  r   r   r  r   r   rb   r   r   r   r   r   rh  !	  s   	rh  c                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )
	MouseArear   Nc                    sJ   t t| jf i | || _|| _d| _t|tr:|j| _d| _d| _d S r   )	r   rk  r   r&  r   
is_hoveredr8   r  r  )r   r&  r   r   r   r   r   r   r   z	  s    
zMouseArea.__init__c                 C   s    || _ || _|| | _t||S r   )r  r  at_st_offsetr   rc  r   r   r   r   	  s    
zMouseArea.renderc                 C   s   t jj rd S t jjjdkr$d}n|jt jjjkr@|jr@d}n|| j	j
d ur~t jj| j	j
| j| j|| j| }|||}n>d|  kr| jk rn n d|  kr| jk rn nd}nd}|r| jsd| _t| jS |s| jrd| _t| j t| j d S )NkeyboardFr   T)r<   r_   r  rM  pending_focus_typerm   rd   r   r   r   r>  r   r  r  rm  is_pixel_opaquerl  r   r&  r   r   )r   rj   r   r   r   rl  crendr   r   r   rb   	  s&    $4



zMouseArea.event)NNN)r   r   r   rm  r   r   rb   r   r   r   r   r   rk  u	  s   rk  c                       sD   e Zd ZdZg f fdd	Zdd Zdd Zdd	 Zd
d Z  Z	S )OnEventz
    This is a displayable that runs an action in response to a transform
    event. It's used to implement the screen language on statement.
    c                    s   t t|   || _|| _dS )z
        `event`
            A string giving the event name.

        `action`
            An action or list of actions that are run when the event occurs.
        N)r   rr  r   
event_namer   )r   rb   r   r   r   r   r   	  s    	zOnEvent.__init__c                 C   s$   t | jtr| j|kS || jv S d S r   )r8   rs  r   r   rb   r   r   r   is_event	  s    
zOnEvent.is_eventc                 C   s   |  |rdS dS d S r1  )ru  rt  r   r   r   _handles_event	  s    
zOnEvent._handles_eventc                 C   s   |  |rt| j d S r   )ru  r   r   rt  r   r   r   rI  	  s    
zOnEvent.set_transform_eventc                 C   s   t jjddS r  )r<   r_   r   r   rc  r   r   r   r   	  s    zOnEvent.render)
r   r   r   r   r   ru  rv  rI  r   r   r   r   r   r   rr  	  s   rr  )F)r#  ri  N)Z
__future__r   r   r   r   r   renpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   r_  r  pygame_sdl2rA   r<   renpy.display.renderr   r   r   rY   r[   r\   rk   rt   ru   r   r   r   r   r   r   r   r   r   r&   r_   r  r_  r   r   r   r   r   r   rd   Displayabler  rH   rI   r  r  rY  Windowr"  rq  rr  objectr  r  r  r  r  r  r  r  r  r   rm  r  r  Objectr  r  	Containerr]  pythonAlwaysRollbackre  rh  rk  rr  r   r   r   r   <module>   s   8x
!(+ <  &  
	J
+   + =   $	T>