a
    V$cO
                    @   s6  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mZmZ dd Zdd ZG d	d
 d
ejjjZG dd dejjjZdd Z e Z!G dd deZ"G dd deZ#G dd de$Z%dd Z&dd Z'G dd deZ(dd Z)G dd dej*j+Z,e- Z.G dd  d eZ/d!d" Z0G d#d$ d$ejjjZ1i Z2d%d& Z3dCd'd(Z4dDd)d*Z5d+d, Z6d-d. Z7G d/d0 d0eZ8d1d2 Z9e9Z:G d3d4 d4eZ;G d5d6 d6ejjjZ<G d7d8 d8eZ=G d9d: d:eZ>G d;d< d<eZ?e?Z@G d=d> d>eZAG d?d@ d@eZBG dAdB dBeZCdS )E    )divisionabsolute_importwith_statementprint_functionunicode_literals)PY2
basestringbchrbordchropenpystrrangeroundstrtobytesunicodeN)renderRenderc                 C   s   t | tu r| | S | S dS )zj
    If num is a float, multiplies it by base and returns that. Otherwise,
    returns num unchanged.
    N)typefloat)numbase r   renpy/display\layout.pyscale"   s    r   c                 C   s   | j }| j}t|tu rF| j}t|tu r>|r>tjjr>|| }|| }t|tu r| j}t|tu rx|rxtjjrx|| }|| }||fS )z
    Get the xyminimum and yminimum values as actual pixels, taking into account
    that width and height might have been adjusted by x/ymaximum already.
    )	xminimumyminimumr   r   xmaximumrenpyconfigadjust_minimumsymaximum)stylewidthheightr   r   r   r"   r   r   r   
xyminimums.   s    r&   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )Nullar  
    :doc: disp_imagelike
    :name: Null

    A displayable that creates an empty box on the screen. The size
    of the box is controlled by `width` and `height`. This can be used
    when a displayable requires a child, but no child is suitable, or
    as a spacer inside a box.

    ::

        image logo spaced = HBox("logo.png", Null(width=100), "logo.png")

    r   c                    s&   t t| jf i | || _|| _d S N)superr'   __init__r$   r%   )selfr$   r%   
properties	__class__r   r   r*   Z   s    zNull.__init__c                 C   s2   t jj| j| j}| jr.|| d d d d d  |S r(   )r   displayr   r   r$   r%   	focusable	add_focus)r+   r$   r%   statrvr   r   r   r   _   s    zNull.render)r   r   __name__
__module____qualname____doc__r*   r   __classcell__r   r   r-   r   r'   J   s   r'   c                       s   e Zd ZdZeZ fddZdd Z f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dd Z  ZS ) 	Containera  
    This is the base class for containers that can have one or more
    children.

    @ivar children: A list giving the children that have been added to
    this container, in the order that they were added in.

    @ivar child: The last child added to this container. This is also
    used to access the sole child in containers that can only hold
    one child.

    @ivar offsets: A list giving offsets for each of our children.
    It's expected that render will set this up each time it is called.

    @ivar sizes: A list giving sizes for each of our children. It's
    also expected that render will set this each time it is called.

    c                    sH   |   | _d | _|   | _|D ]}| | qtt| jf i | d S r(   )
_list_typechildrenchildoffsetsaddr)   r;   r*   )r+   argsr,   ir-   r   r   r*      s    

zContainer.__init__c                 C   s    | j D ]}||r dS qdS NTF)r=   _handles_event)r+   eventrB   r   r   r   rD      s    

zContainer._handles_eventc                    s.   t t| || | jD ]}||d qd S NF)r)   r;   set_style_prefixr=   )r+   prefixrootrB   r-   r   r   rG      s    
zContainer.set_style_prefixc                    sp    r j r   | js| S |  } fdd| jD |_|jrN|jd |_d|_|jD ]}|jrZd|_qZ|S )Nc                    s   g | ]}|  qS r   )
_duplicate.0rB   rA   r   r   
<listcomp>       z(Container._duplicate.<locals>.<listcomp>FT)rA   
extraneous_duplicatable_copyr=   r>   )r+   rA   r4   rB   r   rM   r   rJ      s    


zContainer._duplicatec                 C   s   | j D ]}|  qd| _d S rF   )r=   _uniquerR   )r+   rB   r   r   r   rT      s    

zContainer._uniquec                 C   s^   g }d}| j D ]"}| }|||uO }|| q|s:| S |  }||_ |j rZ|j d |_|S )NFrP   )r=   _in_current_storeappendrS   r>   )r+   r=   changedoldnewr4   r   r   r   rU      s    
zContainer._in_current_storec                 C   s8   t j|}| j| || _|  | _|jr4d| _dS )z1
        Adds a child to this container.
        TN)	r   easydisplayabler=   rV   r>   r<   r?   rR   )r+   dr>   r   r   r   r@      s    
zContainer.addc                 C   s.   d | _ |  | _|  | _tjj| d d S Nr   )r>   r<   r=   r?   r   r/   r   redrawr+   r   r   r   _clear   s    

zContainer._clearc                 C   sX   t | jD ]\}}||u r
 q$q
dS | j| |  | _| jrN| jd | _nd| _dS )zt
        Removes the first instance of child from this container. May
        not work with all containers.
        NrP   )	enumerater=   popr<   r?   r>   )r+   r\   rB   cr   r   r   remove   s    
zContainer.removec                 C   s   t jj|  dS )zw
        This should be called if a child is added to this
        displayable outside of the render function.
        N)r   r/   r   
invalidater_   r   r   r   update   s    zContainer.updatec           	   	   C   sT   t ||}|  | _| jD ]4}t|||||}||dd|||}| j| q|S r]   )r   r<   r?   r=   r   placerV   )	r+   r$   r%   r2   r3   r4   rc   croffsetr   r   r   r      s    


zContainer.renderc                 C   sz   | j }| j}t|t|kr d S tt|d ddD ]@}|| }|| \}	}
||||	 ||
 |}|d ur4|  S q4d S )N   rP   )r=   r?   lenr   rE   )r+   evxyr2   r=   r?   rB   r\   xoyor4   r   r   r   rE     s    
zContainer.eventc                 C   s
   t | jS r(   )listr=   r_   r   r   r   visit  s    zContainer.visitc                 C   s   t j|  | S r(   )r   uicontext_enterr_   r   r   r   	__enter__#  s    zContainer.__enter__c                 C   s   t j|  dS rF   )r   rs   context_exit)r+   exc_typeexc_valexc_tbr   r   r   __exit__(  s    zContainer.__exit__)r6   r7   r8   r9   rq   r<   r*   rD   rG   rJ   rT   rU   r@   r`   rd   rf   r   rE   rr   ru   rz   r:   r   r   r-   r   r;   h   s"   r;   c           
   
   O   s   | dd | \}}tf ||||d|}t|d dkrDtdt|ddd |ddd D ](\}}|\}}	|t||d|	dd	 qb|S )
a  
    :name: Composite
    :doc: disp_imagelike

    This creates a new displayable of `size`, by compositing other
    displayables. `size` is a (width, height) tuple.

    The remaining positional arguments are used to place images inside
    the Composite. The remaining positional arguments should come
    in groups of two, with the first member of each group an (x, y)
    tuple, and the second member of a group is a displayable that
    is composited at that position.

    Displayables are composited from back to front.

    ::

       image eileen composite = Composite(
           (300, 600),
           (0, 0), "body.png",
           (0, 0), "clothes.png",
           (50, 50), "expression.png")
    r#   image_placement)r   r"   r   r      r   z2LiveComposite requires an odd number of arguments.Nrj   )xposxanchoryposyanchor)
setdefaultFixedrk   	Exceptionzipr@   Position)
sizerA   r,   r$   r%   r4   poswidgetr}   r   r   r   r   	Composite.  s    &r   c                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )
r   a  
    :undocumented:

    Controls the placement of a displayable on the screen, using
    supplied position properties. This is the non-curried form of
    Position, which should be used when the user has directly created
    the displayable that will be shown on the screen.
    r{   c                    s(   t t| jf d|i| | | dS )z
        @param child: The child that is being laid out.

        @param style: The base style of this position.

        @param properties: Position properties that control where the
        child of this widget is placed.
        r#   N)r)   r   r*   r@   r+   r>   r#   r,   r-   r   r   r*   d  s    
zPosition.__init__c                 C   s>   t | j||||}dg| _tjj |j|j}||d |S Nr   r   )	r   r>   r?   r   r/   r   r$   r%   blit)r+   r$   r%   r2   r3   surfr4   r   r   r   r   q  s
    zPosition.renderc           	      C   s   | j  \}}}}}}}|d u r$d}|d u r0d}| jj}|d urD|}| jj}|d urX|}| jj}|d url|}| jj}|d ur|}| jj}|d ur||7 }| jj}|d ur||7 }| jj	}|s|d ur|}|||||||fS r]   )
r>   get_placementr#   r}   r   r~   r   xoffsetyoffsetsubpixel)	r+   r}   r   r~   r   r   r   r   vr   r   r   r   |  s6    zPosition.get_placement)r{   r6   r7   r8   r9   r*   r   r   r:   r   r   r-   r   r   Z  s   	r   c                       sF   e Zd ZdZdZd fdd	Zdd Z fd	d
Z fddZ  Z	S )Gridz
    A grid is a widget that evenly allocates space to its children.
    The child widgets should not be greedy, but should instead be
    widgets that only use part of the space available to them.
    NFgridc                    sZ   |dur| d| tt| jf d|i| t|}t|}|| _|| _|| _|| _dS )a;  
        @param cols: The number of columns in this widget.

        @params rows: The number of rows in this widget.

        @params transpose: True if the grid should be transposed.

        @params allow_underfull: Controls if grid may be underfull.
        If None - uses config.allow_underfull_grids.
        Nspacingr#   )	r   r)   r   r*   intcolsrows	transposeallow_underfull)r+   r   r   paddingr   r#   r   r,   r-   r   r   r*     s    zGrid.__init__c              
      s  | j j}| j j}|d u r | j j}|d u r0| j j}t| j j|}t| j j|}t| j j|}	t| j j|}
| j	}| j
}| jrg }t|D ]*}t|D ]}|| j|||    qqn| j}||| j jr||d |  | | | | j jr||d |  |	 |
 |  fdd|D }dd |D }d}d}|D ]\}}t||}t||}q>| j jrl}| j jrz}|| ||d   | | }|| ||d   |	 |
 }tjj||}g }td|D ]v}td|D ]d}||||   }||||   }|||  | }|||  |	 }|||||||}|| qސq| jrg | _t|D ].}t|D ]}| j||| |   qjq^n|| _|S )Nrj   c                    s   g | ]}t | qS r   )r   rK   r3   	renheightrenwidthr2   r   r   rN     rO   zGrid.render.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )get_sizerK   r   r   r   rN     rO   r   )r#   xspacingyspacingr   r   left_marginright_margin
top_marginbottom_marginr   r   r   r   rV   r=   xfillyfillmaxr   r/   r   r   rg   r?   )r+   r$   r%   r2   r3   r   r   r   r   r   r   r   r   r=   rn   rm   renderssizescwidthcheightwhr4   r?   r>   r   r}   r   ri   r   r   r   r     sl    



"zGrid.renderc                    s2   t t| | t| j| j| j kr.tdd S )NzGrid overfull.)r)   r   r@   rk   r=   r   r   r   r+   r\   r-   r   r   r@     s    zGrid.addc                    sz   t t|   | j| j t| j }|dkrv| j}|d u rBtj	j
}tj	jsNd}|s\tdnt|D ]}| t  qdd S )Nr   TzGrid not completely full.)r)   r   per_interactr   r   rk   r=   r   r   r    allow_underfull_grids	developerr   r   r@   r'   )r+   deltar   _r-   r   r   r   $  s    
zGrid.per_interact)NFr   N)
r6   r7   r8   r9   r   r*   r   r@   r   r:   r   r   r-   r   r     s       Sr   c                   @   s   e Zd ZdZdS )IgnoreLayersz
    Raise this to have the event ignored by layers, but reach the
    underlay. This can also be used to stop processing focuses.
    N)r6   r7   r8   r9   r   r   r   r   r   7  s   r   c                 C   sD   |d u rdS d|  kr |k r@n nd|  kr8|k r@n ndS dS )NTr   Fr   )rl   rm   rn   r   r   r   r   r   default_modal_function@  s
    0r   c                 C   sp   | sdS |dur*|j tjjjkr*|jr*dS t| s6t} | |||||rl|durh|j tjjjkrhd|_dS dS dS )zB
    This evaluates the modal property of frames and screens.
    FNT)r   r   r/   core	TIMEEVENTmodalcallabler   )r   rl   rm   rn   r   r   r   r   r   check_modalJ  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 fdd	Z fddZ fd	d
Zdd Z fddZd fdd	Zdd Zdd Zdd Zdd Zdd Z  ZS )MultiBoxNTFdefaultc                    s\   |d ur||d< t t| jf d|i| | jj| _|| _g | _g | _d | _	d | _
d | _d S )Nr   r#   )r)   r   r*   r#   clipping	_clippingdefault_layoutstart_times
anim_timeslayers
raw_layers
scene_list)r+   r   layoutr#   r,   r-   r   r   r*   o  s    
zMultiBox.__init__c                    s0   t t|   g | _g | _d | _d | _d | _d S r(   )r)   r   r`   r   r   r   r   r   r_   r-   r   r   r`     s    zMultiBox._clearc           
         s  | j d ur| jd u r| S g }d}| jD ]4}| }|j }||jurP||_d}|| q&|sd| S t| jd}| j |_ || n| j	r4t| jd}i |_	i |_
d}tjj	D ]v}| j
| }| }	|	|j
|< |	|urd}tj jj||	|j|jd}	|	|j	|< n
| j	| }	|	|j	|< ||	 q|sB| S ntt|  S | jrVt| j|_| jrjt| j|_| jr~t| j|_|S )NFT)r   )layer_at_listcamera_list)
layer_namer   copyr[   rU   rV   r   r   append_scene_listr   r   r   r    gamecontextscene_liststransform_layer_layer_at_list_camera_listr@   r)   r?   rq   r   r   )
r+   r   rW   old_slenew_sler\   r4   layerold_dnew_dr-   r   r   rU     sV    









zMultiBox._in_current_storec                 C   sT   t | turt | jS | jj}|d u r,| j}|dkr8dS |dkrDdS |dkrPdS dS )Nfixedr   
horizontalHBoxverticalVBoxr   )r   r   r6   r#   
box_layoutr   )r+   r   r   r   r   
_classname  s    
zMultiBox._classnamec                    s8   t | tu r*|  }tt|  d|S tt|  S )Nr   )r   r   r   r)   __repr__replace)r+   	classnamer-   r   r   r     s    zMultiBox.__repr__c                    s,   t t| | | j| | j| dS )aq  
        Adds a displayable to this box.

        `start_time`
            The wall time when this displayable was first shown. Can also
            be None to set start_time when this box is rendered or True to
            pass st from this box. (The last is used by the MoveTransition.)

        `anim_time`
            Same thing, in the animation timebase.
        N)r)   r   r@   r   rV   r   )r+   r   
start_time	anim_timer-   r   r   r@     s    zMultiBox.addc                 C   s>   |D ]}|  |j|j|j q| jd u r.g | _| j| d S r(   )r@   r[   	show_timeanimation_timer   extend)r+   lsler   r   r   r     s
    
zMultiBox.append_scene_listc                 C   s   t jjj}|d u rd S g }g }| jD ](}|d u r6|}n|du rBd}|| q$| jD ](}|d u rf|}n|du rrd}|| qT|| _|| _d| _d S rC   )r   r   	interfaceinteract_timer   rV   r   first)r+   itnew_start_timesnew_anim_timesrB   r   r   r   update_times  s(    


zMultiBox.update_timesc           6   	      s  | j s| jd urd}nd}| jj}|d ur:t|t||}| jj}|d urZt|t||}| jrl|rl|   | jj	}|d u r| j
}dd  |rtjjj fdd| jD }	 fdd| jD }
n gt| j }	gt| j }
g }|dkr"d }| jjr"tt| jt|	t|
}nt| j|	|
}tjjj||| j d	}| jj}| jj}| jj}|d
krrd}d}n,|dkrd}d}n|rd}d}nd}d}g }|D ]\}}}t|||||}| }|| |r|d  }|_d }|r|d  }|_d }|r(| |dd|||}|| n
|d q|rd}t||D ]0\}}t|d |d  |}|d u rJ q|qJ||_|tj!j"krt#d$||rd}t||D ]0\}}t|d |d  |}|d u r qq||_|tj!j"krt#d$|| jjr|%  || _&|S | jj'}| jj(}|d u r@|}|g|gt| jd   }| jj)}| jj*} | jj+}!| jj,}"| jj}#| jj}$ddt-| j}%| jj.r|%%  |%  g ddd}d}fdd}&d}'d}(|dkr$|"r|}n|$}dg })|}*|!r|}+n|#}+t|%||	|
D ]\},}-}}|,j/rLtj!j0rLd}-|rX|}.n|*}.t|,|.||( ||}| \}/}0|r|*|/ |- dk r|)r|&|)|+|' d\|(|  7 }(d}'d|}*g })|)|,|'|(|f t|0|'|/|- 7 }'|*|/|- 8 }*q*|&|)|s|+|' ndd\nB|dkrZ|!r:|}n|#}dg })|}1|"rV|}2n|$}2t|%||	|
D ]\},}-}}|,j/rtj!j0rd}-|r|}3n|1}3t|,||' |3||}| \}/}0|r|1|0 |- dk r|&|)d|2|( \|'|  7 }'d}(d|}1g })|)|,|'|(|f t|/|(|0|- 7 }(|1|0|- 8 }1qh|&|)d|sN|2|( nd\nt#d| |!svt|#}|"st|$}tjj||}| jj.| jjA r%  D ]D\}}'}(}4}5}t||4}4t||5}5| ||'|(|4|5|}|| q| jjr|%  || _&|S )NTFc                 S   s$   | d u rdS | du r|S ||  S d S )Nr   Tr   )t
frame_timetimebaser   r   r   adjust>  s
    zMultiBox.render.<locals>.adjustc                    s   g | ]} |qS r   r   )rL   start)r   r   r2   r   r   rN   J  rO   z#MultiBox.render.<locals>.<listcomp>c                    s   g | ]} |qS r   r   )rL   anim)r   r3   r   r   r   rN   K  rO   r   )r   r$   r%   r   rj   r   z"Fixed fit width ({}) is too large.z#Fixed fit height ({}) is too large.c              	      s  t d|}t d|}tjjr0tdd | D }nt| }|dkrR|| }|| }nd}d}}}d}| D ]\}	}
}}| \}}t |}t  |}|	jrtjjs|
|| 7 }
||| 7 }||7 }||7 }|d7 }|	|
||||f t ||
| }t ||| }qj||fS )z
            Lays out a single line.

            `line` a list of (child, x, y, surf) tuples.
            `xfill` the amount of space to add in the x direction.
            `yfill` the amount of space to add in the y direction.
            r   c                 S   s   g | ]}|d  j s|qS )r   )	_box_skiprK   r   r   r   rN     rO   z8MultiBox.render.<locals>.layout_line.<locals>.<listcomp>rj   )r   r   r    box_skiprk   r   r   rV   )liner   r   
line_count	xperchild	yperchildmaxxoutmaxyoutrB   r>   rm   rn   r   swsh)line_height
line_widthmaxxmaxy
placementsr   r   layout_line  s6    	




z$MultiBox.render.<locals>.layout_liner   r   zUnknown box layout: %r)1r   r   r#   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rk   r=   order_reverser   reversedr/   r   r   xfityfit	fit_firstr   rV   r$   r%   rg   r    max_fit_sizer   formatreverser?   r   first_spacingbox_wrapbox_wrap_spacingr   r   rq   box_reverser   r   )6r+   r$   r%   r2   r3   adjust_timesminxminyr   cstscatsr?   r4   iteratorr	  r
  r  first_fit_widthfirst_fit_heightr   r>   cstcatr   r   ri   osr   r  spacingsr  r  r   r   r   r   r=   r  rm   rn   r   remwidthtarget_widthr\   r   rwr   r   	remheighttarget_heightrhr   r   r   )	r   r3   r   r  r  r  r  r  r2   r   r   &  sj   
	













4

"

 




zMultiBox.renderc                 C   s   | j r| js| jd ur|   tt| j| j| j}| j	j
sD|  z^|D ]T\}\}}}	|	d u rf|}
ntjjj|	 }
|||| || |
}|d urJ|  W S qJW n< ty   | jr|jtjjjkrtjj  Y d S  Y n0 d S r(   )r   r   r   r   rq   r   r=   r?   r   r#   r  r  r   r   r   
event_timerE   r   r   r/   r   r   post_time_event)r+   rl   rm   rn   r2   children_offsetsrB   ro   rp   r   r  r4   r   r   r   rE     s*    zMultiBox.eventc                 C   s(   | j s| jr| jtjjdS |  S d S )N)r  )r   r   _tts_commonr   r    tts_front_to_backr_   r   r   r   _tts  s    zMultiBox._tts)NNr   )NN)r6   r7   r8   r   r   r  r   r   r   r   r   r*   r`   rU   r   r   r@   r   r   r   rE   r+  r:   r   r   r-   r   r   b  s*   	C
  ^%r   c                  K   s   t f ddi| S )Nr   r   )r   )r,   r   r   r   r     s    r   c                       s$   e Zd Z fddZdd Z  ZS )	SizeGroupc                    s$   t t|   g | _d | _d| _d S rF   )r)   r,  r*   members_widthcomputing_widthr_   r-   r   r   r*     s    zSizeGroup.__init__c                 C   sb   | j d ur| j S | jrdS d| _d}| jD ]&}tjj|||||}t|j|}q*|| _ d| _|S )Nr   TF)	r.  r/  r-  r   r/   r   render_for_sizer   r$   )r+   r$   r%   r2   r3   maxwidthrB   rendr   r   r   r$     s    

zSizeGroup.width)r6   r7   r8   r*   r$   r:   r   r   r-   r   r,    s   r,  c                       sV   e Zd ZdZdZdZd fdd	Zdd Zd	d
 Zdd Z	dd Z
 fddZ  ZS )Windowz
    A window that has padding and margins, and can place a background
    behind its child. `child` is the child added to this
    displayable. All other properties are as for the :ref:`Window`
    screen language statement.
    r   Nwindowc                    s0   t t| jf d|i| |d ur,| | d S Nr#   )r)   r3  r*   r@   r   r-   r   r   r*     s    zWindow.__init__c                 C   s   g }| j |j || j S r(   )r#   _visit_windowrV   r=   )r+   r4   r   r   r   rr     s    zWindow.visitc                 C   s   | j jp| jS r(   )r#   r>   r_   r   r   r   	get_child  s    zWindow.get_childc                 C   s>   | j j}|r:t|d }|d u r.t  }t|< |j|  d S r(   )r#   
size_groupsize_groupsgetr,  r-  rV   )r+   r8  groupr   r   r   r     s    zWindow.per_interactc           "   	   C   sF  | j }t|||\}}| j j}| j j}	t|tu r6|}t|	tu rF|}	| j j}
|
rt|
tv rtt|t|
 	||||}t||}t||}t
|j|}t
|j|}t
|j|}t
|j|}t
|j|}t
|j|}t
|j|}t
|j|}|| }|| }|| }|| }|  }|| jur| jd ur| j}|}t|tjjjspt|tjjjsp||krp| }| }t|tjjjrt|tjjjr|| || || _t||| | || | ||}| \}}|jst|| | |}|j st|| | |}tj!j"r@|d ur,t#||}|	d ur@t#||	}tjj$||}| j j%|_%|j%rtt&|j%std|_%|j'r|| }|| }t|j'||||} |j'j(|||||| dd |(||| || || | || | |}!|j)r(|| }|| }t|j)||||} |j)j(|||||| dd | j*r8|!g| _+||f| _,|S )Nr4  Fmain)-r#   r&   r   r"   r   r   r8  r9  r   r$   r   r   left_paddingr   right_paddingr   top_paddingr   bottom_paddingr7  current_child
isinstancer   r/   	transform	Transform_target
take_statetake_execution_stater   r   r   r   r    enforce_window_max_sizeminr   r   r   
backgroundrg   
foregroundr>   r?   window_size)"r+   r$   r%   r2   r3   r#   r   r   r   r"   r8  r   r>  r   r?  r   r@  r   rA  cxmargincymargin	cxpadding	cypaddingr>   
old_target
new_targetr   r   r   r4   bwbhbackr?   r   r   r   r     s    

$
$











	
zWindow.renderc                    sb   t t| ||||}|d ur"|S | j\}}|jtjtjtjfv r^t	| j
j|||||r^t d S r(   )r)   r3  rE   rM  r   pygameMOUSEBUTTONDOWNMOUSEBUTTONUPMOUSEMOTIONr   r#   r   r   )r+   rl   rm   rn   r2   r4   r   r   r-   r   r   rE   u  s    
zWindow.event)Nr4  )r6   r7   r8   r9   rM  rB  r*   rr   r7  r   r   rE   r:   r   r   r-   r   r3    s   
r3  c                 C   s   t j|}|d fS r(   )r   pythonpy_eval)r2   r3   exprr>   r   r   r   dynamic_displayable_compat  s    r^  c                       s~   e Zd ZdZdgZdZdZdZdZdd Z	 f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  ZS )DynamicDisplayablea  
    :doc: disp_dynamic

    A displayable that can change its child based on a Python
    function, over the course of an interaction. It does not
    take any properties, as its layout is controlled by the
    properties of the child displayable it returns.

    `function`
        A function that is called with the arguments:

        * The amount of time the displayable has been shown for.
        * The amount of time any displayable with the same tag has been shown for.
        * Any positional or keyword arguments supplied to DynamicDisplayable.

        and should return a (d, redraw) tuple, where:

        * `d` is a displayable to show.
        * `redraw` is the maximum amount of time to wait before calling the
          function again, or None to not require the function be called again
          before the start of the next interaction.

        `function` is called at the start of every interaction.

    As a special case, `function` may also be a python string that evaluates
    to a displayable. In that case, function is run once per interaction.

    ::

        # Shows a countdown from 5 to 0, updating it every tenth of
        # a second until the time expires.
        init python:

            def show_countdown(st, at):
                if st > 5.0:
                    return Text("0.0"), None
                else:
                    d = Text("{:.1f}".format(5.0 - st))
                    return d, 0.1

        image countdown = DynamicDisplayable(show_countdown)
    r>   TNr   c                 C   s   d | _ d | _d S r(   )r>   	raw_childr_   r   r   r   after_setstate  s    z!DynamicDisplayable.after_setstatec                    sP   t t|   d | _t|tr,|f}i }t}|dd | _|| _	|| _
|| _d S )N_predict_function)r)   r_  r*   r>   rC  r   r^  rb   predict_functionfunctionrA   kwargs)r+   rd  rA   re  r-   r   r   r*     s    
zDynamicDisplayable.__init__c                 C   s   |  |}d |_d |_|S r(   )rS   r>   r`  )r+   rA   r4   r   r   r   rJ     s    
zDynamicDisplayable._duplicatec                 C   s&   |  | j| j | jr| jgS g S d S r(   )rf   last_stlast_atr>   r_   r   r   r   rr     s    zDynamicDisplayable.visitc                 C   s   || _ || _| j||g| jR i | j\}}|| jkr|| _tj|}|j	rf|
| j}|  n|}t| jtjjjrt|tjjjr|| j || j |dd  || _|d urtjj| | d S )Nc                 S   s   |   S r(   )r   )rc   r   r   r   <lambda>  rO   z+DynamicDisplayable.update.<locals>.<lambda>)rf  rg  rd  rA   re  r`  r   rZ   r[   rR   rJ   _argsrT   rC  r>   r/   rD  rE  rG  rH  	visit_allr   r^   )r+   r2   r3   r`  r^   r>   r   r   r   rf     s"    "

"zDynamicDisplayable.updatec                 C   s   t jj| d d S r]   )r   r/   r   r^   r_   r   r   r   r     s    zDynamicDisplayable.per_interactc                 C   sH   |  || tjj| j||||}tjj|j|j}||d |S r   )	rf   r   r/   r   r>   r   r$   r%   r   )r+   r   r   r2   r3   rh   r4   r   r   r   r     s
    zDynamicDisplayable.renderc                 C   s   zt| j r| j | ji | j}n"| jddg| jR i | j\}}t|trd|D ]}tjj	| qNntjj	| W n t
y   Y n0 d S r]   )rc  rA   re  rd  rC  rq   r   r/   predictr[   r   )r+   r>   r   rB   r   r   r   predict_one  s    "
zDynamicDisplayable.predict_onec                 C   s   | j s| dd | j  S r]   )r>   rf   r   r_   r   r   r   r     s    z DynamicDisplayable.get_placementc                 C   s   | j r| j ||||S d S r(   )r>   rE   r+   rl   rm   rn   r2   r   r   r   rE     s    zDynamicDisplayable.event)r6   r7   r8   r9   nosaverR   r`  rf  rg  ra  r*   rJ   rr   rf   r   r   rl  r   rE   r:   r   r   r-   r   r_    s    +r_  c                 C   sp   | D ]T\}}|d u r|  S |t v r.t | }ntj|d}|t |< tj|r|  S qtjjrjtdt S )Nevalz&Switch could not choose a displayable.)	
cond_cacher   r[  
py_compilepy_eval_bytecoder    r   r   r'   )switchcondr\   coder   r   r   condition_switch_pick'  s    

rv  c                 C   s   t |d fS r(   )rv  )r2   r3   rs  predict_allr   r   r   condition_switch_show;  s    rx  c                 C   s>   |d u rt jj}t jjs&|r4t jjjr4dd | D S t| gS )Nc                 S   s   g | ]\}}|qS r   r   )rL   _condr\   r   r   r   rN   E  rO   z,condition_switch_predict.<locals>.<listcomp>)	r   r    conditionswitch_predict_allr   lintr/   rk  
predictingrv  )rs  rw  r   r   r   condition_switch_predict?  s
    r}  c                  O   s   | dd}|dd g }t| d dkr4tdt| ddd | ddd D ]@\}}|tvrxtj|d	}|t|< tj	
|}|||f qRtt||td
}t|fi |S )a  
    :name: ConditionSwitch
    :doc: disp_dynamic
    :args: (*args, predict_all=None, **properties)

    This is a displayable that changes what it is showing based on
    Python conditions. The positional arguments should be given in
    groups of two, where each group consists of:

    * A string containing a Python condition.
    * A displayable to use if the condition is true.

    The first true condition has its displayable shown, at least
    one condition should always be true.

    The conditions uses here should not have externally-visible side-effects.

    `predict_all`
        If True, all of the possible displayables will be predicted when
        the displayable is shown. If False, only the current condition is
        predicted. If None, :var:`config.conditionswitch_predict_all` is
        used.

    ::

        image jill = ConditionSwitch(
            "jill_beers > 4", "jill_drunk.png",
            "True", "jill_sober.png")
    rw  Nr#   r   r|   r   z1ConditionSwitch takes an even number of argumentsrj   ro  )rb  )rb   r   rk   r   r   rp  r   r[  rq  rZ   r[   rV   r_  rx  r}  r   )rA   re  rw  rs  rt  r\   ru  r4   r   r   r   ConditionSwitchJ  s"    &r~  c                  O   s   | dd}t| d dkr$tdg }t| ddd | ddd D ]L\}}|durzt|tslt| }d||f }nd}|| || qFt|i |S )	a  
    :doc: disp_dynamic
    :args: (*args, predict_all=None, **properties)

    This is a displayable that changes what it is showing based on the
    images are showing on the screen. The positional argument should
    be given in groups of two, where each group consists of:

    * A string giving an image name, or None to indicate the default.
    * A displayable to use if the condition is true.

    A default image should be specified.

    `predict_all`
        If True, all of the possible displayables will be predicted when
        the displayable is shown. If False, only the current condition is
        predicted. If None, :var:`config.conditionswitch_predict_all` is
        used.

    One use of ShowingSwitch is to have images change depending on
    the current emotion of a character. For example::

        image emotion_indicator = ShowingSwitch(
           "eileen concerned", "emotion_indicator concerned",
           "eileen vhappy", "emotion_indicator vhappy",
           None, "emotion_indicator happy")

    r   masterr|   r   z:ShowingSwitch takes an even number of positional argumentsNrj   zrenpy.showing(%r, layer=%r))	rb   rk   r   r   rC  tuplesplitrV   r~  )rA   re  r   condargsnamer\   rt  r   r   r   ShowingSwitch  s    &

r  c                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	IgnoresEventsc                    s$   t t| jf i | | | d S r(   )r)   r  r*   r@   )r+   r>   r,   r-   r   r   r*     s    zIgnoresEvents.__init__c           	      C   sH   t jj| j||||}| \}}t jj||}|j|ddd |S )Nr   Ffocus)r   r/   r   r>   r   r   r   	r+   r   r   r2   r3   rh   cwchr4   r   r   r   r     s
    zIgnoresEvents.renderc                 C   s
   | j  S r(   r>   r   r_   r   r   r   r     s    zIgnoresEvents.get_placementc                 C   s   d S r(   r   rm  r   r   r   rE     s    zIgnoresEvents.event)r6   r7   r8   r*   r   r   rE   r:   r   r   r-   r   r    s   r  c                 K   s   t jjj|fd| i|S )z
    :doc: disp_imagelike
    :name: Crop

    This creates a displayable by cropping `child` to `rect`, where
    `rect` is an (x, y, width, height) tuple. ::

        image eileen cropped = Crop((0, 0, 300, 300), "eileen happy")
    crop)r   r/   motionrE  )rectr>   r,   r   r   r   Crop  s    r  c                       sZ   e Zd Zeg dZdd Zd fdd	Z fddZ fd	d
Zdd Z	dd Z
  ZS )Side)	tlr   trrbrbblr   rc   c                 C   s
   d| _ d S rF   sizedr_   r   r   r   ra    s    zSide.after_setstatesidec                    s   t t| jf d|i| t|tr,| }t }|D ]<}|tjvrRtd|f ||v rhtd|f |	| q6t
|| _d| _d S )Nr#   z(Side used with impossible position '%s'.z'Side used with duplicate position '%s'.F)r)   r  r*   rC  r   r  setpossible_positionsr   r@   r  	positionsr  )r+   r  r#   r,   seenrB   r-   r   r   r*     s    


zSide.__init__c                    s0   t | jt | jkrtdtt| | d S )Nz'Side has been given too many arguments.)rk   r=   r  r   r)   r  r@   r   r-   r   r   r@     s    zSide.addc                    s   t t|   d| _d S rF   )r)   r  r`   r  r_   r-   r   r   r`     s    zSide._clearc                 C   s
   d| _ d S rF   r  r_   r   r   r   r     s    zSide.per_interactc           #         s  t jjr$tjtjkr$tdi i ttjjD ]\}\}}||< ||< q>|}|}	j	sd_	j
jfdd}
|
ddd|\_}|
dd	d
|\_}|
ddd|\_}|
ddd
|\_}d}d}d}d}d}d} fdd}|d||dd\}}|d||||\}}|d||||\}}|d||||\}}|d	||||\}}|d||||\}}|d||||\}}|d||||\}}|d
||||\}}|_|_|_|_|_|_n$j}j}j}j}j}j}|}|	}dgtj _j}j}j}j}j
jr>|}j
jrL|}t||| | | | }t||| | | | }t jj|| | | | || | | |  fdd}d}|| }|| | | }d}|| }|| | | }d||||fd||||fd	||||fd||||fd||||fd||||fd||||fd
||||fd||||fg	}t jjrfdd}|j|d |D ] \}}} }!}"|||| |!|" qS )Nz(A side has the wrong number of children.Tc                    s0   |  v s| v s| v r$| fS d|fS d S r]   r   )ar  rc   axis)pos_dr   r   r   spacer  s    zSide.render.<locals>.spacerr  r   r  r  r  r  r   r  r   c                    sB   | vr||fS t jj|  || }t||jt||jfS r(   )r   r/   r   r0  r   r$   r%   )r   r$   r%   owidthoheightr2  )r3   r  r2   r   r   sizeit0  s    zSide.render.<locals>.sizeitrc   r   c                    sN   | vrd S |  }|  }t ||| }|  |||||j|< d S r(   )r   rg   r?   )r   rm   rn   r   r   r\   rB   r2  )r3   r  pos_ir4   r+   r2   r   r   rg   j  s    zSide.render.<locals>.placec                    s,   | \}}}}}| vr t jS j|S r(   )rk   r  index)elemr   rm   rn   r   r   )r  r+   r   r   sort  s    
zSide.render.<locals>.sort)key)r   r    r   rk   r  r=   r   ra   r   r  r#   r   
left_spaceright_space	top_spacebottom_spacer   r   topbottomleftrightr?   r   r   rJ  r/   r   r   keep_side_render_orderr  )#r+   r$   r%   r2   r3   rB   r   r\   	old_width
old_heightr  r  r  r  r  r   r   r  leftsrightstopsbottomsrg   col1col2col3row1row2row3place_orderr  rm   rn   r   r   r   )r3   r  r  r4   r+   r   r2   r   r     s    




zSide.render)r  )r6   r7   r8   r  r  ra  r*   r@   r`   r   r   r:   r   r   r-   r   r    s   r  c                       s.   e Zd Zd	 fdd	Zdd Zdd Z  ZS )
AlphaNFc	           
         sL   t t| jf i |	 || _|| _|| _tj|| _	|| _
|| _|| _d S r(   )r)   r  r*   r   endtimer   rZ   r[   r>   repeatanim_timebase	time_warp)
r+   r   r  r  r>   r  bouncer  r  r,   r-   r   r   r*     s    zAlpha.__init__c                 C   s   | j gS r(   )r>   r_   r   r   r   rr     s    zAlpha.visitc                 C   s  | j r|}n|}| jr(t|| j d}nd}tjjr:d}n8| jrZ|d }tjj	| d n|dkrrtjj	| d | j
r| 
|}| j|| j| j   }tjj| j||||}| \}	}
tjj|	|
}||d ||_|d |d| |dd |S )N      ?r   r   zrenpy.alphau_renpy_alphau_renpy_over)r  r  rJ  r   r   less_updatesr  r/   r   r^   r  r   r  r>   r   r   r   alpha
add_shaderadd_uniform)r+   r%   r$   r2   r3   r   doner  r2  r   r   r4   r   r   r   r     s2    

zAlpha.render)NFFFN)r6   r7   r8   r*   rr   r   r:   r   r   r-   r   r    s
     r  c                       s<   e Zd Z fddZdd Zdd Zdd Zd	d
 Z  ZS )AdjustTimesc                    s0   t t| jf i | || _|| _| | d S r(   )r)   r  r*   r   r   r@   )r+   r>   r   r   r,   r-   r   r   r*     s    zAdjustTimes.__init__c                 C   s   t jjj}| jd u r"|d ur"|| _| jd ur>t jjj| j }nd}| jd u rZ|d urZ|| _| jd urvt jjj| j }nd}||fS r]   )r   r   r   r   r   r   r   )r+   r   r2   r3   r   r   r   adjusted_times  s    


zAdjustTimes.adjusted_timesc           	      C   sX   |   \}}tjj| j||||}| \}}tjj||}||d dg| _|S r   )	r  r   r/   r   r>   r   r   r   r?   r  r   r   r   r     s    zAdjustTimes.renderc                 C   s"   |   \}}t| |||| d S r(   )r  r;   rE   )r+   rl   rm   rn   r2   r   r   r   r   rE     s    zAdjustTimes.eventc                 C   s
   | j  S r(   r  r_   r   r   r   r     s    zAdjustTimes.get_placement)	r6   r7   r8   r*   r  r   rE   r   r:   r   r   r-   r   r    s
   r  c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )
MatchTimesa  
    A displayable that changes the `target` so that the times given to
    this target match the times this displayable was rendered at.

    `target`
        This must be an AdjustTimes displayable, that's a child of this
        MatchTimes displayable.
    c                    s*   t t| jf i | || _| | d S r(   )r)   r  r*   targetr@   )r+   r>   r  r,   r-   r   r   r*     s    zMatchTimes.__init__c           	      C   sp   t jjj| | j_t jjj| | j_t jj| j	||||}|
 \}}t jj||}||d dg| _|S r   )r   r   r   r   r  r   r   r/   r   r>   r   r   r   r?   r  r   r   r   r     s    zMatchTimes.renderc                 C   s
   | j  S r(   r  r_   r   r   r   r   *  s    zMatchTimes.get_placementr   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 )Tilez
    :doc: disp_imagelike
    :name: Tile

    Tiles `child` until it fills the area allocated to this displayable.

    ::

        image bg tile = Tile("bg.png")

    tilec                    s(   t t| jf d|i| | | d S r5  )r)   LiveTiler*   r@   r   r-   r   r   r*   ;  s    zTile.__init__c                 C   s   t jj| j||||}| \}}t jj||}t|}t|}t|}t|}td||D ]n}	td||D ]\}
t|||
 }t|||	 }||k s||k r|	dd||f}n|}|j
||
|	fdd qpq`|S )Nr   Fr  )r   r/   r   r>   r   r   r   r   rJ  
subsurfacer   )r+   r$   r%   r2   r3   rh   r  r  r4   rn   rm   ccwcchccrr   r   r   r   @  s     zTile.render)r  r5   r   r   r-   r   r  .  s   r  c                       s6   e Zd ZdZdZd	 fdd	Zdd Zdd Z  ZS )
Flattena?  
    :doc: disp_imagelike

    This flattens `child`, which may be made up of multiple textures, into
    a single texture.

    Certain operations, like the alpha transform property, apply to every
    texture making up a displayable, which can yield incorrect results
    when the textures overlap on screen. Flatten creates a single texture
    from multiple textures, which can prevent this problem.

    Flatten is a relatively expensive operation, and so should only be used
    when absolutely required.

    `drawable_resolution`
        Defaults to true, which is usually the right choice, but may cause
        the resulting texture, when scaled, to have different artifacts than
        the textures that make it up. Setting this to False will change the
        artifacts, which may be more pleasing in some cases.
    Tc                    s*   t t| jf i | | | || _d S r(   )r)   r  r*   r@   drawable_resolution)r+   r>   r  r,   r-   r   r   r*   v  s    
zFlatten.__init__c           	      C   s   t jj| j||||}| \}}t jj||}||d t jjj|_d|_	|
d |d| jjd u rvt jjn| jj |d| j dg| _|S )Nr   Tzrenpy.texturemipmapr  )r   r/   r   r>   r   r   r   FLATTEN	operationmeshr  add_propertyr#   r  r    mipmap_dissolvesr  r?   )	r+   r$   r%   r2   r3   rh   r  r  r4   r   r   r   r   }  s    
$zFlatten.renderc                 C   s
   | j  S r(   r  r_   r   r   r   r     s    zFlatten.get_placement)T)	r6   r7   r8   r9   r  r*   r   r   r:   r   r   r-   r   r  ^  s
   r  c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )	AlphaMaskaa  
    :doc: disp_imagelike

    This displayable takes its colors from `child`, and its alpha channel
    from the multiplication of the alpha channels of `child` and `mask`.
    The result is a displayable that has the same colors as `child`, is
    transparent where either `child` or `mask` is transparent, and is
    opaque where `child` and `mask` are both opaque.

    The `child` and `mask` parameters may be arbitrary displayables. The
    size of the AlphaMask is the size of `child`.

    Note that this takes different arguments from :func:`im.AlphaMask`,
    which uses the mask's red channel.
    c                    sD   t t| jf i | tj|| _| | j | | d | _d S r(   )	r)   r  r*   r   rZ   r[   maskr@   null)r+   r>   r  r,   r-   r   r   r*     s
    
zAlphaMask.__init__c                 C   s   | j | jgS r(   )r  r>   r_   r   r   r   rr     s    zAlphaMask.visitc                 C   s   t jj| j||||}| \}}t jj||}|j| jdd | jd u rVt	 | _t jj| j||||}	t jj||}
t jjj
|
_d|
_d|
_d|
_d|
_|
d |
dd |
d	d
 |
d| jjd u rt jjn| jj |
|d |
j|	dddd |
|d ddg| _|
S )NFr<  Tg      ?   zrenpy.imagedissolveu_renpy_dissolve_offsetr   u_renpy_dissolve_multiplierr  r  r   )r  r=  )r   r/   r   r>   r   r   rg   r  r  r   IMAGEDISSOLVEr  operation_alphaoperation_completeoperation_parameterr  r  r  r  r#   r  r    r  r   r?   )r+   r$   r%   r2   r3   rh   r   r   mrnrr4   r   r   r   r     s,    

$
zAlphaMask.render)r6   r7   r8   r9   r*   rr   r   r:   r   r   r-   r   r    s   r  c                       sF   e Zd ZdZd fdd	Zdd Zdd	 Z fd
dZdd Z  Z	S )NearRectz
    This lays a child above or below a supplied rectangle.

    `rect`
        The rectangle to place the child near.

    `prefer_top`
        If true, the child is placed above the rectangle, if there is
        room.
    NFc                    s   t t| jf i | |d ur,tjj|}|d u rD|d u rDtd|| _|| _	|| _
|d urh|j| _nd | _|d ur| | d S )Nz7A NearRect requires either a focus or a rect parameter.)r)   r  r*   r   r/   r  get_focus_rectr   parent_rect
focus_rect
prefer_tophide_parent_rectr@   )r+   r>   r  r  r  replacesr,   r-   r   r   r*     s    
zNearRect.__init__c                 C   s   | j d u rd S tjj| j }|d ur>| jd u r>| jd n&|d u rd| jd urd| jd | j| _| j|kr|| _tjj	
| d d S )Nshowhider   )r  r   r/   r  r  r  r>   set_transform_eventr  r   r^   )r+   r  r   r   r   r     s    

zNearRect.per_interactc                 C   s  t jj||}| jp| j}|d u r0dg| _|S |\}}}	}
|}t||| |
 }t jj| j||||}|	 \}}t
| jt jjjr| jjrd | _nd | _| jp| j}|d u rdg| _|S | j \}}}}}}}|d u rd}|d u rd}|d u rd}|d u rd}| jr$||k r$|| }n$||| |
 kr@||
 }n|| }t
|tr\||	 }t
|trp|| }|| | }|| |kr|| }|dk rd}||7 }||7 }||||f ||fg| _|S )Nr   r   )r   r/   r   r   r  r  r?   r   r>   r   rC  r  rE  hide_responser   r  r   r   )r+   r$   r%   r2   r3   r4   r  pxpypwphavail_wavail_hrh   r  r  r}   _yposr~   _yanchorr   r   	_subpixellayout_ylayout_xr   r   r   r   	  s\    



zNearRect.renderc                    s(   | j d ur tt| ||||S d S d S r(   )r  r)   r  rE   rm  r-   r   r   rE   U	  s    
zNearRect.eventc                 C   s   | j d ur|  S dS d S )N )r  r)  r_   r   r   r   r+  [	  s    
zNearRect._tts)NNNFN)
r6   r7   r8   r9   r*   r   r   rE   r+  r:   r   r   r-   r   r    s   Or  )N)N)D
__future__r   r   r   r   r   renpy.compatr   r   r	   r
   r   r   r   r   r   r   r   r   pygame_sdl2rW  r   renpy.display.renderr   r   r   r&   r/   r   Displayabler'   r;   r   LiveCompositer   r   r   r   r   r   r   r   objectObjectr,  dictr9  r3  r^  r_  rp  rv  rx  r}  r~  r  r  r  LiveCropr  r  r  r  r  r  r  r  r  r   r   r   r   <module>   sb   8 G)J 	
    P 0 

83 C85#-5?