Add on_key_press
This commit is contained in:
parent
14783b2193
commit
2ca5c7b9c8
3 changed files with 73 additions and 10 deletions
16
README.rst
16
README.rst
|
|
@ -85,16 +85,14 @@ Advanced Usage
|
||||||
# Option access, in general these require the core to reinitialize
|
# Option access, in general these require the core to reinitialize
|
||||||
player['vo'] = 'opengl'
|
player['vo'] = 'opengl'
|
||||||
|
|
||||||
def my_q_binding(state, key):
|
@player.on_key_press('q')
|
||||||
if state[0] == 'd':
|
def my_q_binding():
|
||||||
print('THERE IS NO ESCAPE')
|
print('THERE IS NO ESCAPE')
|
||||||
player.register_key_binding('q', my_q_binding)
|
|
||||||
|
|
||||||
def my_s_binding(state, key):
|
@player.on_key_press('s')
|
||||||
if state[0] == 'd':
|
def my_s_binding():
|
||||||
pillow_img = player.screenshot_raw()
|
pillow_img = player.screenshot_raw()
|
||||||
pillow_img.save('screenshot.png')
|
pillow_img.save('screenshot.png')
|
||||||
player.register_key_binding('s', my_s_binding)
|
|
||||||
|
|
||||||
player.play('https://youtu.be/DLzxrzFCyOs')
|
player.play('https://youtu.be/DLzxrzFCyOs')
|
||||||
player.wait_for_playback()
|
player.wait_for_playback()
|
||||||
|
|
|
||||||
35
mpv-test.py
35
mpv-test.py
|
|
@ -316,6 +316,41 @@ class KeyBindingTest(MpvTestCase):
|
||||||
self.assertNotIn(b('b'), self.m._key_binding_handlers)
|
self.assertNotIn(b('b'), self.m._key_binding_handlers)
|
||||||
self.assertIn(b('c'), self.m._key_binding_handlers)
|
self.assertIn(b('c'), self.m._key_binding_handlers)
|
||||||
|
|
||||||
|
def test_register_simple_decorator_fun_chaining(self):
|
||||||
|
b = mpv.MPV._binding_name
|
||||||
|
|
||||||
|
handler1, handler2 = mock.Mock(), mock.Mock()
|
||||||
|
|
||||||
|
@self.m.on_key_press('a')
|
||||||
|
@self.m.on_key_press('b')
|
||||||
|
def reg_test_fun(*args, **kwargs):
|
||||||
|
handler1(*args, **kwargs)
|
||||||
|
|
||||||
|
@self.m.on_key_press('c')
|
||||||
|
def reg_test_fun_2_stay_intact(*args, **kwargs):
|
||||||
|
handler2(*args, **kwargs)
|
||||||
|
|
||||||
|
self.assertEqual(reg_test_fun.mpv_key_bindings, ['b', 'a'])
|
||||||
|
self.assertIn(b('a'), self.m._key_binding_handlers)
|
||||||
|
self.assertIn(b('b'), self.m._key_binding_handlers)
|
||||||
|
self.assertIn(b('c'), self.m._key_binding_handlers)
|
||||||
|
|
||||||
|
self.m._key_binding_handlers[b('a')]('p-', 'q')
|
||||||
|
handler1.assert_has_calls([ mock.call() ])
|
||||||
|
handler2.assert_has_calls([])
|
||||||
|
handler1.reset_mock()
|
||||||
|
self.m._key_binding_handlers[b('b')]('p-', 'q')
|
||||||
|
handler1.assert_has_calls([ mock.call() ])
|
||||||
|
handler2.assert_has_calls([])
|
||||||
|
self.m._key_binding_handlers[b('c')]('p-', 'q')
|
||||||
|
handler1.assert_has_calls([])
|
||||||
|
handler2.assert_has_calls([ mock.call() ])
|
||||||
|
|
||||||
|
reg_test_fun.unregister_mpv_key_bindings()
|
||||||
|
self.assertNotIn(b('a'), self.m._key_binding_handlers)
|
||||||
|
self.assertNotIn(b('b'), self.m._key_binding_handlers)
|
||||||
|
self.assertIn(b('c'), self.m._key_binding_handlers)
|
||||||
|
|
||||||
class TestLifecycle(unittest.TestCase):
|
class TestLifecycle(unittest.TestCase):
|
||||||
def test_create_destroy(self):
|
def test_create_destroy(self):
|
||||||
thread_names = lambda: [ t.name for t in threading.enumerate() ]
|
thread_names = lambda: [ t.name for t in threading.enumerate() ]
|
||||||
|
|
|
||||||
32
mpv.py
32
mpv.py
|
|
@ -915,8 +915,38 @@ class MPV(object):
|
||||||
def _binding_name(callback_or_cmd):
|
def _binding_name(callback_or_cmd):
|
||||||
return 'py_kb_{:016x}'.format(hash(callback_or_cmd)&0xffffffffffffffff)
|
return 'py_kb_{:016x}'.format(hash(callback_or_cmd)&0xffffffffffffffff)
|
||||||
|
|
||||||
|
def on_key_press(self, keydef, mode='force'):
|
||||||
|
""" Function decorator to register a simplified key binding. The callback is called whenever the key
|
||||||
|
given is *pressed*.
|
||||||
|
|
||||||
|
To unregister the callback function, you can call its ```unregister_mpv_key_bindings``` attribute:
|
||||||
|
|
||||||
|
```
|
||||||
|
player = mpv.MPV()
|
||||||
|
@player.on_key_press('Q')
|
||||||
|
def binding():
|
||||||
|
print('blep')
|
||||||
|
|
||||||
|
binding.unregister_mpv_key_bindings()
|
||||||
|
```
|
||||||
|
|
||||||
|
WARNING: For a single keydef only a single callback/command can be registered at the same time. If you register
|
||||||
|
a binding multiple times older bindings will be overwritten and there is a possibility of references leaking. So
|
||||||
|
don't do that.
|
||||||
|
|
||||||
|
The BIG FAT WARNING regarding untrusted keydefs from the key_binding method applies here as well. """
|
||||||
|
|
||||||
|
def register(fun):
|
||||||
|
@self.key_binding(keydef, mode)
|
||||||
|
@wraps(fun)
|
||||||
|
def wrapper(state='p-', name=None):
|
||||||
|
if state[0] in ('d', 'p'):
|
||||||
|
fun()
|
||||||
|
return wrapper
|
||||||
|
return register
|
||||||
|
|
||||||
def key_binding(self, keydef, mode='force'):
|
def key_binding(self, keydef, mode='force'):
|
||||||
""" Function decorator to register a key binding.
|
""" Function decorator to register a low-level key binding.
|
||||||
|
|
||||||
The callback function signature is ```fun(key_state, key_name)``` where ```key_state``` is either ```'U'``` for
|
The callback function signature is ```fun(key_state, key_name)``` where ```key_state``` is either ```'U'``` for
|
||||||
"key up" or ```'D'``` for "key down".
|
"key up" or ```'D'``` for "key down".
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue