Skip to content

Commit

Permalink
Minify Player/DiscretePlayer with scale_buttons/visible_buttons/visib…
Browse files Browse the repository at this point in the history
…le_loop_options (#7065)

* scale player button

* add support for visible loop options and buttons

* add and fix test

* add docs

* pre-commit

* tweak ts

* add ui test

* Apply suggestions from code review

Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>

* fix merge

---------

Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
  • Loading branch information
ahuang11 and philippjfr authored Aug 14, 2024
1 parent a3959ec commit 0b76e99
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 135 deletions.
20 changes: 20 additions & 0 deletions examples/reference/widgets/DiscretePlayer.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@
"\n",
"* **``disabled``** (boolean): Whether the widget is editable\n",
"* **``name``** (str): The title of the widget\n",
"* **``scale_buttons``** (float): The scaling factor to resize the buttons\n",
"* **``show_loop_controls``** (boolean): Whether radio buttons allowing to switch between loop policies options are shown\n",
"* **``show_value``** (boolean): Whether to display the value of the player\n",
"* **``value_align``** (str): Where to display the value; must be one of 'start', 'center', 'end'\n",
"* **``visible_buttons``** (list[str]): The buttons to display on the player ('slower', 'first', 'previous', 'reverse', 'pause', 'play', 'next', 'last', 'faster')\n",
"* **``visible_loop_options``** (list[str]): The loop options to display on the player. ('once', 'loop', 'reflect')\n",
"\n",
"___"
]
Expand Down Expand Up @@ -107,6 +110,23 @@
"discrete_player.pause()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `DiscretePlayer` can be slimmed down by setting `scale_buttons`, `show_loop_controls`, `visible_buttons`, and/or `visible_loop_options`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"discrete_player = pn.widgets.DiscretePlayer(name='Player', visible_buttons=[\"play\", \"pause\"], scale_buttons=0.9, show_loop_controls=False, width=150)\n",
"discrete_player"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
20 changes: 20 additions & 0 deletions examples/reference/widgets/Player.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@
"\n",
"* **``disabled``** (boolean): Whether the widget is editable\n",
"* **``name``** (str): The title of the widget\n",
"* **``scale_buttons``** (float): The scaling factor to resize the buttons\n",
"* **``show_loop_controls``** (boolean): Whether radio buttons allowing to switch between loop policies options are shown\n",
"* **``show_value``** (boolean): Whether to display the value of the player\n",
"* **``value_align``** (str): Where to display the value; must be one of 'start', 'center', 'end'\n",
"* **``visible_buttons``** (list[str]): The buttons to display on the player ('slower', 'first', 'previous', 'reverse', 'pause', 'play', 'next', 'last', 'faster')\n",
"* **``visible_loop_options``** (list[str]): The loop options to display on the player. ('once', 'loop', 'reflect')\n",
"\n",
"___"
]
Expand Down Expand Up @@ -109,6 +112,23 @@
"player.pause()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `Player` can be slimmed down by setting `scale_buttons`, `show_loop_controls`, `visible_buttons`, and/or `visible_loop_options`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"player = pn.widgets.Player(name='Player', visible_buttons=[\"play\", \"pause\"], scale_buttons=0.9, show_loop_controls=False, width=150)\n",
"player"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
288 changes: 154 additions & 134 deletions panel/models/player.ts

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions panel/models/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ class Player(Widget):

height = Override(default=250)

scale_buttons = Float(1, help="Percentage to scale the size of the buttons by")

visible_buttons = List(String, default=[
'slower', 'first', 'previous', 'reverse', 'pause', 'play', 'next', 'last', 'faster'
], help="The buttons to display on the player.")

visible_loop_options = List(String, default=[
'once', 'loop', 'reflect'
], help="The loop options to display on the player.")

class DiscretePlayer(Player):

Expand Down
42 changes: 42 additions & 0 deletions panel/tests/ui/widgets/test_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,45 @@ def test_name_and_show_value(page):

name = page.locator('.pn-player-title:has-text("test")')
expect(name).to_have_count(1)
def test_player_visible_buttons(page):
player = Player(visible_buttons=["play", "pause"])
serve_component(page, player)

assert page.is_visible(".play")
assert page.is_visible(".pause")
assert not page.is_visible(".reverse")
assert not page.is_visible(".first")
assert not page.is_visible(".previous")
assert not page.is_visible(".next")
assert not page.is_visible(".last")
assert not page.is_visible(".slower")
assert not page.is_visible(".faster")

player.visible_buttons = ["first"]
expect(page.locator(".first")).to_be_visible()
assert not page.is_visible(".play")
assert not page.is_visible(".pause")


def test_player_visible_loop_options(page):
player = Player(visible_loop_options=["loop", "once"])
serve_component(page, player)

assert page.is_visible(".loop")
assert page.is_visible(".once")
assert not page.is_visible(".reflect")

player.visible_loop_options = ["reflect"]
expect(page.locator(".reflect")).to_be_visible()
assert not page.is_visible(".loop")
assert not page.is_visible(".once")


def test_player_scale_buttons(page):
player = Player(scale_buttons=2)
serve_component(page, player)

expect(page.locator(".play")).to_have_attribute(
"style",
"text-align: center; flex-grow: 2; margin: 2px; transform: scale(2); max-width: 50px;",
)
12 changes: 12 additions & 0 deletions panel/tests/widgets/test_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,15 @@ def test_discrete_player(document, comm):

discrete_player.value = 100
assert widget.value == 3


def test_player_loop_policy_not_in_loop_options(document, comm):
player = DiscretePlayer(name='Player', loop_policy='once', visible_loop_options=['loop', 'reflect'])
assert player.loop_policy == 'loop'
assert player.visible_loop_options == ['loop', 'reflect']


def test_player_loop_policy_with_no_loop_options(document, comm):
player = DiscretePlayer(name='Player', loop_policy='loop', visible_loop_options=[])
assert player.loop_policy == 'loop'
assert player.visible_loop_options == []
16 changes: 15 additions & 1 deletion panel/widgets/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,18 @@ class PlayerBase(Widget):
Width of this component. If sizing_mode is set to stretch
or scale mode this will merely be used as a suggestion.""")

_rename: ClassVar[Mapping[str, str | None]] = {'name': 'title'}
scale_buttons = param.Number(default=1, doc="""
The scaling factor to resize the buttons.""")

visible_buttons = param.List(default=[
'slower', 'first', 'previous', 'reverse', 'pause', 'play', 'next', 'last', 'faster'
], doc="""The buttons to display on the player.""")

visible_loop_options = param.List(default=[
'once', 'loop', 'reflect'
], doc="The loop options to display on the player.")

_rename: ClassVar[Mapping[str, str | None]] = {'name': "title"}

_widget_type: ClassVar[type[Model]] = _BkPlayer

Expand All @@ -67,6 +78,9 @@ class PlayerBase(Widget):
__abstract = True

def __init__(self, **params):
if loop_options := params.get("visible_loop_options", []):
if params.get("loop_policy", "once") not in loop_options:
params["loop_policy"] = loop_options[0]
if 'value' in params and 'value_throttled' in self.param:
params['value_throttled'] = params['value']
super().__init__(**params)
Expand Down

0 comments on commit 0b76e99

Please sign in to comment.