U
    Petb                     @   s  d Z ddlmZ ddlmZ 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 ddlmZ ddlmZ ddlmZ dd	lm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Z*G dd deZ+G dd de+Z,G dd de+Z-G dd de+Z.G d d! d!e+Z/G d"d# d#e+Z0G d$d% d%e+Z1G d&d' d'e+Z2G d(d) d)e+Z3G d*d+ d+e+Z4G d,d- d-eZ5G d.d/ d/eZ6d0S )1a  
EffectWidget
============

.. versionadded:: 1.9.0

The :class:`EffectWidget` is able to apply a variety of fancy
graphical effects to
its children. It works by rendering to a series of
:class:`~kivy.graphics.Fbo` instances with custom opengl fragment shaders.
As such, effects can freely do almost anything, from inverting the
colors of the widget, to anti-aliasing, to emulating the appearance of a
crt monitor!

.. warning::
    This code is still experimental, and its API is subject to change in a
    future version.

The basic usage is as follows::

    w = EffectWidget()
    w.add_widget(Button(text='Hello!')
    w.effects = [InvertEffect(), HorizontalBlurEffect(size=2.0)]

The equivalent in kv would be::

    #: import ew kivy.uix.effectwidget
    EffectWidget:
        effects: ew.InvertEffect(), ew.HorizontalBlurEffect(size=2.0)
        Button:
            text: 'Hello!'

The effects can be a list of effects of any length, and they will be
applied sequentially.

The module comes with a range of prebuilt effects, but the interface
is designed to make it easy to create your own. Instead of writing a
full glsl shader, you provide a single function that takes
some inputs based on the screen (current pixel color, current widget
texture etc.). See the sections below for more information.

Usage Guidelines
----------------

It is not efficient to resize an :class:`EffectWidget`, as
the :class:`~kivy.graphics.Fbo` is recreated on each resize event.
If you need to resize frequently, consider doing things a different
way.

Although some effects have adjustable parameters, it is
*not* efficient to animate these, as the entire
shader is reconstructed every time. You should use glsl
uniform variables instead. The :class:`AdvancedEffectBase`
may make this easier.

.. note:: The :class:`EffectWidget` *cannot* draw outside its own
          widget area (pos -> pos + size). Any child widgets
          overlapping the boundary will be cut off at this point.

Provided Effects
----------------

The module comes with several pre-written effects. Some have
adjustable properties (e.g. blur radius). Please see the individual
effect documentation for more details.

- :class:`MonochromeEffect` - makes the widget grayscale.
- :class:`InvertEffect` - inverts the widget colors.
- :class:`ChannelMixEffect` - swaps color channels.
- :class:`ScanlinesEffect` - displays flickering scanlines.
- :class:`PixelateEffect` - pixelates the image.
- :class:`HorizontalBlurEffect` - Gaussuan blurs horizontally.
- :class:`VerticalBlurEffect` - Gaussuan blurs vertically.
- :class:`FXAAEffect` - applies a very basic anti-aliasing.

Creating Effects
----------------

Effects are designed to make it easy to create and use your own
transformations. You do this by creating and using an instance of
:class:`EffectBase` with your own custom :attr:`EffectBase.glsl`
property.

The glsl property is a string representing part of a glsl fragment
shader. You can include as many functions as you like (the string
is simply spliced into the whole shader), but it
must implement a function :code:`effect` as below::

    vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
    {
        // ... your code here
        return something;  // must be a vec4 representing the new color
    }

The full shader will calculate the normal pixel color at each point,
then call your :code:`effect` function to transform it. The
parameters are:

- **color**: The normal color of the current pixel (i.e. texture
  sampled at tex_coords).
- **texture**: The texture containing the widget's normal background.
- **tex_coords**: The normal texture_coords used to access texture.
- **coords**: The pixel indices of the current pixel.

The shader code also has access to two useful uniform variables,
:code:`time` containing the time (in seconds) since the program start,
and :code:`resolution` containing the shape (x pixels, y pixels) of
the widget.

For instance, the following simple string (taken from the `InvertEffect`)
would invert the input color but set alpha to 1.0::

    vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
    {
        return vec4(1.0 - color.xyz, 1.0);
    }

You can also set the glsl by automatically loading the string from a
file, simply set the :attr:`EffectBase.source` property of an effect.

    )Clock)RelativeLayout)StringPropertyObjectPropertyListPropertyNumericPropertyDictProperty)	RenderContextFboColor	Rectangle	Translate
PushMatrix	PopMatrix
ClearColorClearBuffers)EventDispatcher)	EventLoop)resource_find)Logger)EffectWidget
EffectBaseAdvancedEffectBaseMonochromeEffectInvertEffectChannelMixEffectScanlinesEffectPixelateEffectHorizontalBlurEffectVerticalBlurEffect
FXAAEffectz
#ifdef GL_ES
precision highp float;
#endif

/* Outputs from the vertex shader */
varying vec4 frag_color;
varying vec2 tex_coord0;

/* uniform texture samplers */
uniform sampler2D texture0;
z.
uniform vec2 resolution;
uniform float time;
zW
void main (void){
     gl_FragColor = frag_color * texture2D(texture0, tex_coord0);
}
z
void main (void){
    vec4 normal_color = frag_color * texture2D(texture0, tex_coord0);
    vec4 effect_color = effect(normal_color, texture0, tex_coord0,
                               gl_FragCoord.xy);
    gl_FragColor = effect_color;
}
z`
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    return color;
}
z
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    float mag = 1.0/3.0 * (color.x + color.y + color.z);
    return vec4(mag, mag, mag, color.w);
}
zy
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    return vec4(1.0 - color.xyz, color.w);
}
z
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{{
    return vec4(color.{}, color.{}, color.{}, color.w);
}}
aB  
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{{
    float dt = ({} / 4.0) * 1.0 / resolution.x;
    vec4 sum = vec4(0.0);
    sum += texture2D(texture, vec2(tex_coords.x - 4.0*dt, tex_coords.y))
                     * 0.05;
    sum += texture2D(texture, vec2(tex_coords.x - 3.0*dt, tex_coords.y))
                     * 0.09;
    sum += texture2D(texture, vec2(tex_coords.x - 2.0*dt, tex_coords.y))
                     * 0.12;
    sum += texture2D(texture, vec2(tex_coords.x - dt, tex_coords.y))
                     * 0.15;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y))
                     * 0.16;
    sum += texture2D(texture, vec2(tex_coords.x + dt, tex_coords.y))
                     * 0.15;
    sum += texture2D(texture, vec2(tex_coords.x + 2.0*dt, tex_coords.y))
                     * 0.12;
    sum += texture2D(texture, vec2(tex_coords.x + 3.0*dt, tex_coords.y))
                     * 0.09;
    sum += texture2D(texture, vec2(tex_coords.x + 4.0*dt, tex_coords.y))
                     * 0.05;
    return vec4(sum.xyz, color.w);
}}
aW  
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{{
    float dt = ({} / 4.0)
                     * 1.0 / resolution.x;
    vec4 sum = vec4(0.0);
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y - 4.0*dt))
                     * 0.05;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y - 3.0*dt))
                     * 0.09;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y - 2.0*dt))
                     * 0.12;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y - dt))
                     * 0.15;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y))
                     * 0.16;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y + dt))
                     * 0.15;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y + 2.0*dt))
                     * 0.12;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y + 3.0*dt))
                     * 0.09;
    sum += texture2D(texture, vec2(tex_coords.x, tex_coords.y + 4.0*dt))
                     * 0.05;
    return vec4(sum.xyz, color.w);
}}
a,  
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
    vec2 q = tex_coords * vec2(1, -1);
    vec2 uv = 0.5 + (q-0.5);//*(0.9);// + 0.1*sin(0.2*time));

    vec3 oricol = texture2D(texture,vec2(q.x,1.0-q.y)).xyz;
    vec3 col;

    col.r = texture2D(texture,vec2(uv.x+0.003,-uv.y)).x;
    col.g = texture2D(texture,vec2(uv.x+0.000,-uv.y)).y;
    col.b = texture2D(texture,vec2(uv.x-0.003,-uv.y)).z;

    col = clamp(col*0.5+0.5*col*col*1.2,0.0,1.0);

    //col *= 0.5 + 0.5*16.0*uv.x*uv.y*(1.0-uv.x)*(1.0-uv.y);

    col *= vec3(0.8,1.0,0.7);

    col *= 0.9+0.1*sin(10.0*time+uv.y*1000.0);

    col *= 0.97+0.03*sin(110.0*time);

    float comp = smoothstep( 0.2, 0.7, sin(time) );
    //col = mix( col, oricol, clamp(-2.0+2.0*q.x+3.0*comp,0.0,1.0) );

    return vec4(col, color.w);
}
z
vec4 effect(vec4 vcolor, sampler2D texture, vec2 texcoord, vec2 pixel_coords)
{{
    vec2 pixelSize = {} / resolution;

    vec2 xy = floor(texcoord/pixelSize)*pixelSize + pixelSize/2.0;

    return texture2D(texture, xy);
}}
a  
vec4 effect( vec4 color, sampler2D buf0, vec2 texCoords, vec2 coords)
{

    vec2 frameBufSize = resolution;

    float FXAA_SPAN_MAX = 8.0;
    float FXAA_REDUCE_MUL = 1.0/8.0;
    float FXAA_REDUCE_MIN = 1.0/128.0;

    vec3 rgbNW=texture2D(buf0,texCoords+(vec2(-1.0,-1.0)/frameBufSize)).xyz;
    vec3 rgbNE=texture2D(buf0,texCoords+(vec2(1.0,-1.0)/frameBufSize)).xyz;
    vec3 rgbSW=texture2D(buf0,texCoords+(vec2(-1.0,1.0)/frameBufSize)).xyz;
    vec3 rgbSE=texture2D(buf0,texCoords+(vec2(1.0,1.0)/frameBufSize)).xyz;
    vec3 rgbM=texture2D(buf0,texCoords).xyz;

    vec3 luma=vec3(0.299, 0.587, 0.114);
    float lumaNW = dot(rgbNW, luma);
    float lumaNE = dot(rgbNE, luma);
    float lumaSW = dot(rgbSW, luma);
    float lumaSE = dot(rgbSE, luma);
    float lumaM  = dot(rgbM, luma);

    float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
    float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));

    vec2 dir;
    dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
    dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));

    float dirReduce = max(
        (lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL),
        FXAA_REDUCE_MIN);

    float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce);

    dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
          max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
          dir * rcpDirMin)) / frameBufSize;

    vec3 rgbA = (1.0/2.0) * (
        texture2D(buf0, texCoords.xy + dir * (1.0/3.0 - 0.5)).xyz +
        texture2D(buf0, texCoords.xy + dir * (2.0/3.0 - 0.5)).xyz);
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
        texture2D(buf0, texCoords.xy + dir * (0.0/3.0 - 0.5)).xyz +
        texture2D(buf0, texCoords.xy + dir * (3.0/3.0 - 0.5)).xyz);
    float lumaB = dot(rgbB, luma);

    vec4 return_color;
    if((lumaB < lumaMin) || (lumaB > lumaMax)){
        return_color = vec4(rgbA, color.w);
    }else{
        return_color = vec4(rgbB, color.w);
    }

    return return_color;
}
c                       sL   e Zd ZdZeeZedZedddZ	 fddZ
dd	 Zd
d Z  ZS )r   zwThe base class for GLSL effects. It simply returns its input.

    See the module documentation for more details.

     NT)Z	allownonec                    sB   t t| j|| | j}| j}|d| |d| |d| j d S )Nfboglslsource)superr   __init__fbindset_fbo_shader_load_from_source)selfargskwargsr'   Z
fbo_shader	__class__ 9/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/effectwidget.pyr&     s    

zEffectBase.__init__c                 G   s,   | j dkrdS | j tt | j t  dS )zSets the :class:`~kivy.graphics.Fbo`'s shader by splicing
        the :attr:`glsl` string into a full fragment shader.

        The full shader is made up of :code:`shader_header +
        shader_uniforms + self.glsl + shader_footer_effect`.
        N)r"   set_fsshader_headershader_uniformsr#   shader_footer_effectr*   r+   r/   r/   r0   r(     s
    
zEffectBase.set_fbo_shaderc              	   G   sR   | j }|sdS t|}|dkr0tdj|dS t|}| | _W 5 Q R X dS )z4(internal) Loads the glsl string from a source file.NzError reading file {filename})filename)r$   r   r   errorformatopenreadr#   )r*   r+   r$   r6   Zfilehr/   r/   r0   r)     s    
zEffectBase._load_from_source)__name__
__module____qualname____doc__r   effect_trivialr#   r$   r   r"   r&   r(   r)   __classcell__r/   r/   r-   r0   r   h  s   	r   c                       s<   e Zd ZdZei Z fddZdd Z fddZ  Z	S )r   a~  An :class:`EffectBase` with additional behavior to easily
    set and update uniform variables in your shader.

    This class is provided for convenience when implementing your own
    effects: it is not used by any of those provided with Kivy.

    In addition to your base glsl string that must be provided as
    normal, the :class:`AdvancedEffectBase` has an extra property
    :attr:`uniforms`, a dictionary of name-value pairs. Whenever
    a value is changed, the new value for the uniform variable is
    uploaded to the shader.

    You must still manually declare your uniform variables at the top
    of your glsl string.
    c                    s$   t t| j|| | d| j d S )Nuniforms)r%   r   r&   r'   _update_uniformsr*   r+   r,   r-   r/   r0   r&     s    zAdvancedEffectBase.__init__c                 G   s0   | j d krd S | j D ]\}}|| j |< qd S N)r"   rA   items)r*   r+   keyvaluer/   r/   r0   rB     s    
z#AdvancedEffectBase._update_uniformsc                    s   t t| j|  |   d S rD   )r%   r   r(   rB   r5   r-   r/   r0   r(     s    z!AdvancedEffectBase.set_fbo_shader)
r;   r<   r=   r>   r   rA   r&   rB   r(   r@   r/   r/   r-   r0   r     s
   r   c                       s    e Zd ZdZ fddZ  ZS )r   z'Returns its input colors in monochrome.c                    s   t t| j|| t| _d S rD   )r%   r   r&   effect_monochromer#   rC   r-   r/   r0   r&     s    zMonochromeEffect.__init__r;   r<   r=   r>   r&   r@   r/   r/   r-   r0   r     s   r   c                       s    e Zd ZdZ fddZ  ZS )r   z Inverts the colors in the input.c                    s   t t| j|| t| _d S rD   )r%   r   r&   effect_invertr#   rC   r-   r/   r0   r&     s    zInvertEffect.__init__rI   r/   r/   r-   r0   r     s   r   c                       s    e Zd ZdZ fddZ  ZS )r   zAdds scanlines to the input.c                    s   t t| j|| t| _d S rD   )r%   r   r&   effect_postprocessingr#   rC   r-   r/   r0   r&     s    zScanlinesEffect.__init__rI   r/   r/   r-   r0   r     s   r   c                       s>   e Zd ZdZedddgZ fddZdd Zd	d
 Z  Z	S )r   z~Mixes the color channels of the input according to the order
    property. Channels may be arbitrarily rearranged or repeated.      r   c                    s   t t| j|| |   d S rD   )r%   r   r&   do_glslrC   r-   r/   r0   r&     s    zChannelMixEffect.__init__c                 G   s   |    d S rD   rN   r5   r/   r/   r0   on_order  s    zChannelMixEffect.on_orderc                 C   s    dd | j D }tj| | _d S )Nc                 S   s   g | ]}d ddd| qS )xyz)r   rL   rM   r/   ).0ir/   r/   r0   
<listcomp>  s     z,ChannelMixEffect.do_glsl.<locals>.<listcomp>)order
effect_mixr8   r#   )r*   lettersr/   r/   r0   rN     s    zChannelMixEffect.do_glsl)
r;   r<   r=   r>   r   rW   r&   rP   rN   r@   r/   r/   r-   r0   r     s
   r   c                       s8   e Zd ZdZedZ fddZdd Zdd Z  Z	S )	r   zKPixelates the input according to its
    :attr:`~PixelateEffect.pixel_size`
   c                    s   t t| j|| |   d S rD   )r%   r   r&   rN   rC   r-   r/   r0   r&   
  s    zPixelateEffect.__init__c                 G   s   |    d S rD   rO   r5   r/   r/   r0   on_pixel_size  s    zPixelateEffect.on_pixel_sizec                 C   s   t t| j| _d S rD   )effect_pixelater8   float
pixel_sizer#   r*   r/   r/   r0   rN     s    zPixelateEffect.do_glsl)
r;   r<   r=   r>   r   r^   r&   r[   rN   r@   r/   r/   r-   r0   r     s
   	r   c                       s8   e Zd ZdZedZ fddZdd Zdd Z  Z	S )	r   z]Blurs the input horizontally, with the width given by
    :attr:`~HorizontalBlurEffect.size`.      @c                    s   t t| j|| |   d S rD   )r%   r   r&   rN   rC   r-   r/   r0   r&      s    zHorizontalBlurEffect.__init__c                 G   s   |    d S rD   rO   r5   r/   r/   r0   on_size$  s    zHorizontalBlurEffect.on_sizec                 C   s   t t| j| _d S rD   )effect_blur_hr8   r]   sizer#   r_   r/   r/   r0   rN   '  s    zHorizontalBlurEffect.do_glsl
r;   r<   r=   r>   r   rc   r&   ra   rN   r@   r/   r/   r-   r0   r     s
   r   c                       s8   e Zd ZdZedZ fddZdd Zdd Z  Z	S )	r   zYBlurs the input vertically, with the width given by
    :attr:`~VerticalBlurEffect.size`.r`   c                    s   t t| j|| |   d S rD   )r%   r   r&   rN   rC   r-   r/   r0   r&   6  s    zVerticalBlurEffect.__init__c                 G   s   |    d S rD   rO   r5   r/   r/   r0   ra   :  s    zVerticalBlurEffect.on_sizec                 C   s   t t| j| _d S rD   )effect_blur_vr8   r]   rc   r#   r_   r/   r/   r0   rN   =  s    zVerticalBlurEffect.do_glslrd   r/   r/   r-   r0   r   +  s
   r   c                       s    e Zd ZdZ fddZ  ZS )r    z+Applies very simple anti-aliasing via fxaa.c                    s   t t| j|| t| _d S rD   )r%   r    r&   effect_fxaar#   rC   r-   r/   r0   r&   C  s    zFXAAEffect.__init__rI   r/   r/   r-   r0   r    A  s   r    c                       s(   e Zd ZdZ fddZdd Z  ZS )	EffectFboz~An :class:`~kivy.graphics.Fbo` with extra functionality that allows
    attempts to set a new shader. See :meth:`set_fs`.
    c                    s(   | dd tt| j|| d | _d S )NZwith_stencilbufferT)
setdefaultr%   rg   r&   texture_rectanglerC   r-   r/   r0   r&   L  s    zEffectFbo.__init__c                 C   s*   | j }|j}||_|js&||_tddS )zAttempt to set the fragment shader to the given value.
        If setting the shader fails, the existing one is preserved and an
        exception is raised.
        zSetting new shader failed.N)shaderfssuccess	Exception)r*   rG   rj   	old_valuer/   r/   r0   r1   Q  s    zEffectFbo.set_fs)r;   r<   r=   r>   r&   r1   r@   r/   r/   r-   r0   rg   H  s   rg   c                       s   e Zd ZdZedZedZeg Zeg Z	eg Z
 fddZdd Zdd	 Zd
d Z fddZ fddZ fddZ  ZS )r   z
    Widget with the ability to apply a series of graphical effects to
    its children. See the module documentation for more information on
    setting effects and creating your own.
    )r   r   r   r   Nc              	      s
  t   tddd| _| j t| jd| _W 5 Q R X | jj t  W 5 Q R X | j4 t	dddd t
  t| j | _t| jd| _W 5 Q R X | jj t  W 5 Q R X tt| jf | t| jd | j}| j}|d| |d| |d| j |   |   d S )NT)Zuse_parent_projectionZuse_parent_modelviewrc   r   rc   effectsbackground_color)r   Zensure_windowr	   canvasr
   rc   r"   beforer   r   r   r   rq   _background_colorr   fbo_rectangleafterr   r%   r   r&   r   Zschedule_interval_update_glslr'   refresh_fbo_setup_refresh_background_color)r*   r,   r'   Z	fbo_setupr-   r/   r0   r&     s0    



zEffectWidget.__init__c                 G   s   | j | j_d S rD   )rq   rt   Zrgbar5   r/   r/   r0   ry     s    z&EffectWidget._refresh_background_colorc                 G   sL   t  }dd | jD }|| jd< || jd< | jD ]}||d< ||d< q2dS )z[(internal) Passes new time and resolution uniform
        variables to the shader.
        c                 S   s   g | ]}t |qS r/   )r]   )rT   rc   r/   r/   r0   rV     s     z-EffectWidget._update_glsl.<locals>.<listcomp>time
resolutionN)r   Zget_boottimerc   rr   fbo_list)r*   largsrz   r{   r"   r/   r/   r0   rw     s    


zEffectWidget._update_glslc              	   G   s  t | jt | jk r| j t| jd}W 5 Q R X |@ tdddd t  tdddd t	| jd|_
| j|j
_W 5 Q R X | j| q t | jt | jkr| j }| j| q| jD ]}|| jkrd|_q| j| _| j| j_| j| j_tt | jD ]"}| j| j| _| j| j| j
_qt | jdkr>| jj| _dS tdt | jD ]$}| j| }| j|d  j|j
_qNt| j| jD ]\}}||_q| jj| jd j
_| jd j| _| jD ]}|  q| j  dS )z(internal) Creates and assigns one :class:`~kivy.graphics.Fbo`
        per effect, and makes sure all sizes etc. are correct and
        consistent.
        ro   r   rL   N)lenr|   rp   rr   rg   rc   r   r   r   r   ri   appendpopremove_bound_effectsr"   ru   rangetexturezipZdraw)r*   r+   Znew_fboZold_fboZeffectrU   r"   r/   r/   r0   rx     sF    








zEffectWidget.refresh_fbo_setupc                    s*   | j }| j| _ tt| j|| || _ d S rD   )rr   r"   r%   r   
add_widgetr*   r+   r,   cr-   r/   r0   r     s    zEffectWidget.add_widgetc                    s*   | j }| j| _ tt| j|| || _ d S rD   )rr   r"   r%   r   remove_widgetr   r-   r/   r0   r     s    zEffectWidget.remove_widgetc                    s*   | j }| j| _ tt| j|| || _ d S rD   )rr   r"   r%   r   clear_widgetsr   r-   r/   r0   r     s    zEffectWidget.clear_widgets)r;   r<   r=   r>   r   rq   r   r   rp   r|   r   r&   ry   rw   rx   r   r   r   r@   r/   r/   r-   r0   r   ^  s   !6r   N)7r>   Z
kivy.clockr   Zkivy.uix.relativelayoutr   Zkivy.propertiesr   r   r   r   r   Zkivy.graphicsr	   r
   r   r   r   r   r   r   r   Z
kivy.eventr   Z	kivy.baser   Zkivy.resourcesr   Zkivy.loggerr   __all__r2   r3   Zshader_footer_trivialr4   r?   rH   rJ   rX   rb   re   rK   r\   rf   r   r   r   r   r   r   r   r   r   r    rg   r   r/   r/   r/   r0   <module>   sD   z,
<A(