graphics/widget: introduce opacity attribute on the canvas and widget.

You can use the opacity attribute to control the opacity of the widget
and its children. The attribute is cumulative, and multiplied to the
current context color. By default, the opacity is 1.0, and doesn't act
at all.
This commit is contained in:
Mathieu Virbel 2012-09-19 01:06:08 +02:00
parent 97e4555ff0
commit 522c520fe2
5 changed files with 52 additions and 2 deletions

View File

@ -1,6 +1,6 @@
$HEADER$
void main (void) {
frag_color = color;
frag_color = color * vec4(1.0, 1.0, 1.0, opacity);
tex_coord0 = vTexCoords0;
gl_Position = projection_mat * modelview_mat * vec4(vPosition.xy, 0.0, 1.0);
}

View File

@ -14,3 +14,4 @@ attribute vec2 vTexCoords0;
uniform mat4 modelview_mat;
uniform mat4 projection_mat;
uniform vec4 color;
uniform float opacity;

View File

@ -82,6 +82,7 @@ cdef class CanvasBase(InstructionGroup):
cdef class Canvas(CanvasBase):
cdef object __weakref__
cdef float _opacity
cdef CanvasBase _before
cdef CanvasBase _after
cdef void reload(self)
@ -89,6 +90,7 @@ cdef class Canvas(CanvasBase):
cpdef add(self, Instruction c)
cpdef remove(self, Instruction c)
cpdef draw(self)
cdef void apply(self)
cdef class RenderContext(Canvas):

View File

@ -499,6 +499,7 @@ cdef class Canvas(CanvasBase):
def __init__(self, **kwargs):
get_context().register_canvas(self)
CanvasBase.__init__(self, **kwargs)
self._opacity = kwargs.get('opacity', 1.0)
self._before = None
self._after = None
@ -530,6 +531,19 @@ cdef class Canvas(CanvasBase):
'''
self.apply()
cdef void apply(self):
cdef float opacity = self._opacity
cdef float rc_opacity
cdef RenderContext rc
if opacity != 1.0:
rc = getActiveContext()
rc_opacity = rc['opacity']
rc.push_state('opacity')
rc['opacity'] = rc_opacity * opacity
InstructionGroup.apply(self)
if opacity != 1.0:
rc.pop_state('opacity')
cpdef add(self, Instruction c):
# the after group must remain the last one.
if self._after is None:
@ -569,6 +583,15 @@ cdef class Canvas(CanvasBase):
self._after = c
return self._after
property opacity:
'''Property for getting the opacity value
'''
def __get__(self):
return self._opacity
def __set__(self, value):
self._opacity = value
self.flag_update()
# Active Canvas and getActiveCanvas function is used
# by instructions, so they know which canvas to add
# tehmselves to
@ -629,8 +652,8 @@ cdef class RenderContext(Canvas):
self.default_texture = tex
self.state_stacks = {
'opacity': [1.0],
'texture0' : [0],
'linewidth': [1.0],
'color' : [[1.0,1.0,1.0,1.0]],
'projection_mat': [Matrix()],
'modelview_mat' : [Matrix()],

View File

@ -532,6 +532,30 @@ class Widget(EventDispatcher):
dict.
'''
opacity = NumericProperty(1.0)
'''Opacity of the widget and all the children.
.. versionadded:: 1.4.1
The opacity attribute control the opacity of the widget and the children.
Take care, it's a cumulative attribute: the value is multiplied to the
current global opacity, and the result is applied to the current context
color.
For example: if your parent have an opacity of 0.5, and one children have an
opacity of 0.2, the real opacity of the children will be 0.5 * 0.2 = 0.1.
Then, the opacity is applied on the shader as::
frag_color = color * vec4(1.0, 1.0, 1.0, opacity);
:data:`opacity` is a :class:`~kivy.properties.NumericProperty`, default to
1.0.
'''
def on_opacity(self, instance, value):
self.canvas.opacity = value
canvas = None
'''Canvas of the widget.