WindowSDL: Add opacity feature (#8296)

* Update sdl2.pxi

Window.opacity feature

* Added opacity property to kivy.core.window.Window

Window.opacity feature

* Update window_sdl2.py

Window.opacity feature

* New feature: Window.opacity

Window.opacity feature

* Added Window.opacity example to kivy-examples

Window.opacity feature

* Create test for Window.opacity

* Fix opacity check 

Replace 'or' with 'and'

* Move tests to test_window_base.py

* Move tests to test_window_base.py

* Fix PEP8

* Fix PEP8 (first file)

* Fix PEP8 (second file)

* Move tests to WindowBaseTest class (#8296)

* Added error checking (#8296)

* Remove opacity range test (#8296)

* New Window.opacity test (#8296)

With @pythonic64 recommendations

* New error checking (kivy#8296)

* fix syntax (kivy#8296)

* Update __init__.py

* New Window.opacity test (kivy#8296)

* Add opacity value to log message (kivy#8296)

* Update __init__.py (#8296)

Add dispatching of opacity on the value change

* New example (#8296)

* Update __init__.py (kivy#8296)

* Update window_sdl2.py (kivy#8296)

* Update __init__.py (kivy#8296) 

I made a mistake, and now I've fixed it :)

* Update _window_sdl2.pyx (kivy#8296)

* Update window opacity tests (kivy#8296)

* Add more docs (kivy#8296)

* Fix docs 🫣 (kivy#8296)

* Update example (kivy#8296)

* Update example (kivy#8296)

* Fix typo (kivy#8296)

* Fix yet another typo (kivy#8296)
This commit is contained in:
Mak Sim 2023-10-16 22:03:31 +03:00 committed by GitHub
parent 23a844024c
commit f12d8e60bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 0 deletions

View File

@ -0,0 +1,28 @@
from kivy.app import App
from kivy.lang import Builder
kv = '''
#:import window kivy.core.window.Window
BoxLayout:
orientation: 'vertical'
Label:
text: f'Window opacity: {window.opacity}'
font_size: '25sp'
Slider:
size_hint_y: 4
min: 0.0
max: 1.0
value: window.opacity
on_value: window.opacity = args[1]
'''
class WindowOpacityApp(App):
def build(self):
return Builder.load_string(kv)
if __name__ == '__main__':
WindowOpacityApp().run()

View File

@ -933,6 +933,33 @@ class WindowBase(EventDispatcher):
the position set in :class:`~kivy.config.Config`.
'''
def _get_opacity(self):
return self._get_window_opacity()
def _set_opacity(self, opacity):
return self._set_window_opacity(opacity)
def _get_window_opacity(self):
Logger.warning('Window: Opacity is not implemented in the current '
'window provider')
def _set_window_opacity(self, opacity):
Logger.warning('Window: Opacity is not implemented in the current '
'window provider')
opacity = AliasProperty(_get_opacity, _set_opacity, cache=True)
'''Opacity of the window. Accepts a value between 0.0 (transparent) and
1.0 (opaque).
.. note::
This feature requires the SDL2 window provider.
.. versionadded:: 2.3.0
:attr:`opacity` is an :class:`~kivy.properties.AliasProperty` and defaults
to `1.0`.
'''
@property
def __self__(self):
return self

View File

@ -394,6 +394,23 @@ cdef class _WindowSDL2Storage:
def set_window_pos(self, x, y):
SDL_SetWindowPosition(self.win, x, y)
def set_window_opacity(self, opacity):
if SDL_SetWindowOpacity(self.win, opacity):
message = (<bytes>SDL_GetError()).decode('utf-8', 'replace')
Logger.error(f'WindowSDL: Setting opacity to {opacity} failed - '
f'{message}')
return False
return True
def get_window_opacity(self):
cdef float opacity
if SDL_GetWindowOpacity(self.win, &opacity):
message = (<bytes>SDL_GetError()).decode('utf-8', 'replace')
Logger.error(f'WindowSDL: Getting opacity failed - {message}')
return 1.0
else:
return opacity
def get_window_info(self):
cdef SDL_SysWMinfo wm_info
SDL_GetVersion(&wm_info.version)

View File

@ -482,6 +482,13 @@ class WindowSDL(WindowBase):
def _set_window_pos(self, x, y):
self._win.set_window_pos(x, y)
def _get_window_opacity(self):
return self._win.get_window_opacity()
def _set_window_opacity(self, opacity):
if self.opacity != opacity:
return self._win.set_window_opacity(opacity)
# Transparent Window background
def _is_shaped(self):
return self._win.is_window_shaped()

View File

@ -924,6 +924,10 @@ cdef extern from "SDL_audio.h":
)
cdef int SDL_ConvertAudio(SDL_AudioCVT *cvt)
cdef extern from "SDL_video.h":
cdef int SDL_SetWindowOpacity(SDL_Window *window, float opacity)
cdef int SDL_GetWindowOpacity(SDL_Window *window, float *opacity)
cdef extern from "SDL_mixer.h":
cdef struct Mix_Chunk:
int allocated

View File

@ -1,6 +1,7 @@
from itertools import product
from kivy.tests import GraphicUnitTest
from kivy.logger import LoggerHistory
class WindowBaseTest(GraphicUnitTest):
@ -18,3 +19,42 @@ class WindowBaseTest(GraphicUnitTest):
assert result_sy == expected_sy
finally:
win.system_size = old_system_size
class WindowOpacityTest(GraphicUnitTest):
def setUp(self):
super().setUp()
self._prev_window_opacity = self.Window.opacity
self._prev_history = LoggerHistory.history[:]
def tearDown(self):
self.Window.opacity = self._prev_window_opacity
LoggerHistory.history[:] = self._prev_history
super().tearDown()
def get_new_opacity_value(self):
opacity = self.Window.opacity
opacity = opacity - 0.1 if opacity >= 0.9 else opacity + 0.1
return round(opacity, 2)
def check_opacity_support(self):
LoggerHistory.clear_history()
self.Window.opacity = self.get_new_opacity_value()
return not LoggerHistory.history
def test_window_opacity_property(self):
if self.check_opacity_support():
opacity = self.get_new_opacity_value()
self.Window.opacity = opacity
self.assertEqual(self.Window.opacity, opacity)
def test_window_opacity_clamping_positive(self):
if self.check_opacity_support():
self.Window.opacity = 1.5
self.assertEqual(self.Window.opacity, 1.0)
def test_window_opacity_clamping_negative(self):
if self.check_opacity_support():
self.Window.opacity = -1.5
self.assertEqual(self.Window.opacity, 0.0)