/
player.py
121 lines (87 loc) · 3.65 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
Defines Player widgets which offer media-player like controls.
"""
import param
from ..models.widgets import Player as _BkPlayer
from ..util import isIn, indexOf
from .base import Widget
from .select import SelectBase
class PlayerBase(Widget):
interval = param.Integer(default=500, doc="Interval between updates")
loop_policy = param.ObjectSelector(default='once',
objects=['once', 'loop', 'reflect'], doc="""
Policy used when player hits last frame""")
step = param.Integer(default=1, doc="""
Number of frames to step forward and back by on each event.""")
show_loop_controls = param.Boolean(default=True, doc="""
Whether the loop controls radio buttons are shown""")
direction = param.Integer(0, doc="""
Current play direction of the Player (-1: playing in reverse,
0: paused, 1: playing)""")
height = param.Integer(default=80)
width = param.Integer(default=510)
_widget_type = _BkPlayer
_rename = {'name': None}
__abstract = True
def play(self):
self.direction = 1
def pause(self):
self.direction = 0
def reverse(self):
self.direction = -1
class Player(PlayerBase):
"""
The Player provides controls to play and skip through a number of
frames defined by explicit start and end values. The speed at
which the widget plays is defined by the interval, but it is also
possible to skip frames using the step parameter.
"""
start = param.Integer(default=0, doc="Lower bound on the slider value")
end = param.Integer(default=10, doc="Upper bound on the slider value")
value = param.Integer(default=0, doc="Current player value")
_supports_embed = True
def __init__(self, **params):
if 'length' in params:
if 'start' in params or 'end' in params:
raise ValueError('Supply either length or start and end to Player not both')
params['start'] = 0
params['end'] = params.pop('length')-1
elif params.get('start', 0) > 0 and not 'value' in params:
params['value'] = params['start']
super().__init__(**params)
def _get_embed_state(self, root, values=None, max_opts=3):
if values is None:
values = list(range(self.start, self.end, self.step))
return (self, self._models[root.ref['id']][0], values,
lambda x: x.value, 'value', 'cb_obj.value')
class DiscretePlayer(PlayerBase, SelectBase):
"""
The DiscretePlayer provides controls to iterate through a list of
discrete options. The speed at which the widget plays is defined
by the interval, but it is also possible to skip items using the
step parameter.
"""
interval = param.Integer(default=500, doc="Interval between updates")
value = param.Parameter()
_rename = {'name': None, 'options': None}
_source_transforms = {'value': None}
def _process_param_change(self, msg):
values = self.values
if 'options' in msg:
msg['start'] = 0
msg['end'] = len(values) - 1
if values and not isIn(self.value, values):
self.value = values[0]
if 'value' in msg:
value = msg['value']
if isIn(value, values):
msg['value'] = indexOf(value, values)
elif values:
self.value = values[0]
return super()._process_param_change(msg)
def _process_property_change(self, msg):
if 'value' in msg:
value = msg.pop('value')
if value < len(self.options):
msg['value'] = self.values[value]
return msg