Skip to content

Commit

Permalink
Add programmatic control over Player widget (#2994)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Dec 8, 2021
1 parent 2dba064 commit 646f4d2
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 13 deletions.
33 changes: 32 additions & 1 deletion examples/reference/widgets/DiscretePlayer.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"\n",
"##### Core\n",
"\n",
"* **``direction``** (int): Current play direction of the Player (-1: playing in reverse,\n",
"0: paused, 1: playing).\n",
"* **``options``** (list or dict): A list or dictionary of options to select from\n",
"* **``value``** (object): The current value; must be one of the option values\n",
"\n",
Expand All @@ -34,6 +36,7 @@
"* **``interval``** (int): Interval in milliseconds between updates\n",
"* **``name``** (str): The title of the widget\n",
"* **``loop_policy``** (str): Looping policy; must be one of 'once', 'loop', or 'reflect'\n",
"* **``show_loop_controls``** (boolean): Whether radio buttons allowing to switch between loop policies options are shown\n",
"\n",
"___"
]
Expand All @@ -51,7 +54,7 @@
"metadata": {},
"outputs": [],
"source": [
"discrete_player = pn.widgets.DiscretePlayer(name='Discrete Player', options=[2, 4, 8, 16, 32, 64, 128], value=32, loop_policy='loop')\n",
"discrete_player = pn.widgets.DiscretePlayer(name='Discrete Player', options=[2, 4, 8, 16, 32, 64, 128], value=8, loop_policy='loop')\n",
"\n",
"discrete_player"
]
Expand All @@ -72,6 +75,34 @@
"discrete_player.value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `DiscretePlayer` can be controlled programmatically using the `direction` parameter which has three possible states:\n",
" \n",
"- `-1`: playing in reverse\n",
"- `0`: paused\n",
"- `1`: playing\n",
"\n",
"Alternatively it can be controlled via the `.play`, `.pause` and `.reverse` methods:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"discrete_player.play()\n",
"time.sleep(2)\n",
"discrete_player.reverse()\n",
"time.sleep(2)\n",
"discrete_player.pause()"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
32 changes: 30 additions & 2 deletions examples/reference/widgets/Player.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
"\n",
"##### Core\n",
"\n",
"* **``direction``** (int): Current play direction of the Player (-1: playing in reverse,\n",
"0: paused, 1: playing).\n",
"* **``start``** (int): The range's lower bound\n",
"* **``end``** (int): The range's upper bound\n",
"* **``step``** (int): The interval between values\n",
Expand All @@ -37,8 +39,6 @@
"* **``name``** (str): The title of the widget\n",
"* **``loop_policy``** (str): Looping policy; must be one of 'once', 'loop', or 'reflect'\n",
"* **``show_loop_controls``** (boolean): Whether radio buttons allowing to switch between loop policies options are shown\n",
"* **``direction``** (int): Current play direction of the Player (-1: playing in reverse,\n",
"0: paused, 1: playing). Parameter is readonly.\n",
"\n",
"___"
]
Expand Down Expand Up @@ -77,6 +77,34 @@
"player.value"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `Player` can be controlled programmatically using the `direction` parameter which has three possible states:\n",
" \n",
"- `-1`: playing in reverse\n",
"- `0`: paused\n",
"- `1`: playing\n",
"\n",
"Alternatively it can be controlled via the `.play`, `.pause` and `.reverse` methods:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"\n",
"player.play()\n",
"time.sleep(2)\n",
"player.reverse()\n",
"time.sleep(2)\n",
"player.pause()"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
37 changes: 28 additions & 9 deletions panel/models/player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ export class PlayerView extends WidgetView {
protected _toggle_reverse: CallableFunction
protected _toogle_pause: CallableFunction
protected _toggle_play: CallableFunction
protected _changing: boolean = false

connect_signals(): void {
super.connect_signals()
this.connect(this.model.properties.direction.change, () => this.set_direction())
this.connect(this.model.properties.value.change, () => this.render())
this.connect(this.model.properties.loop_policy.change, () => this.set_loop_state(this.model.loop_policy))
this.connect(this.model.properties.disabled.change, () => this.toggle_disable())
Expand Down Expand Up @@ -301,29 +303,46 @@ export class PlayerView extends WidgetView {
}
}

set_direction(): void {
if (this._changing)
return
else if (this.model.direction === 0)
this.pause_animation()
else if(this.model.direction === 1)
this.play_animation()
else if(this.model.direction === -1)
this.reverse_animation()
}

pause_animation(): void {
this._toogle_pause()
this.model.direction = 0;
this._changing = true
this.model.direction = 0
this._changing = false
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
clearInterval(this.timer)
this.timer = null
}
}

play_animation(): void {
this.pause_animation();
this.pause_animation()
this._toggle_play()
this.model.direction = 1;
this._changing = true
this.model.direction = 1
this._changing = false
if (!this.timer)
this.timer = setInterval(() => this.anim_step_forward(), this.model.interval);
this.timer = setInterval(() => this.anim_step_forward(), this.model.interval)
}

reverse_animation(): void {
this.pause_animation();
this.pause_animation()
this._toggle_reverse()
this.model.direction = -1;
this._changing = true
this.model.direction = -1
this._changing = false
if (!this.timer)
this.timer = setInterval(() => this.anim_step_reverse(), this.model.interval);
this.timer = setInterval(() => this.anim_step_reverse(), this.model.interval)
}
}

Expand Down
12 changes: 11 additions & 1 deletion panel/widgets/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PlayerBase(Widget):
show_loop_controls = param.Boolean(default=True, doc="""
Whether the loop controls radio buttons are shown""")

direction = param.Integer(0, readonly=True, doc="""
direction = param.Integer(0, doc="""
Current play direction of the Player (-1: playing in reverse,
0: paused, 1: playing)""")

Expand All @@ -37,6 +37,16 @@ class PlayerBase(Widget):

__abstract = True

def play(self):
self.direction = 1

def pause(self):
self.direction = 0

def reverse(self):
self.direction = -1



class Player(PlayerBase):
"""
Expand Down

0 comments on commit 646f4d2

Please sign in to comment.