Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch Param pane widget type when bounds (un)defined #1953

Merged
merged 3 commits into from
Feb 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions panel/param.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,29 +427,31 @@ def action(change):

def link(change, watchers=[watcher]):
updates = {}
widget = self._widgets[p_name]
if change.what == 'constant':
updates['disabled'] = change.new
elif change.what == 'precedence':
if (change.new < self.display_threshold and
widget in self._widget_box.objects):
self._widget_box.pop(widget)
elif change.new >= self.display_threshold:
precedence = lambda k: self.object.param['name' if k == '_title' else k].precedence
params = self._ordered_params
if self.show_name:
params.insert(0, '_title')
widgets = []
for k in params:
if precedence(k) is None or precedence(k) >= self.display_threshold:
widgets.append(self._widgets[k])
self._widget_box.objects = widgets
self._rerender()
return
elif change.what == 'objects':
updates['options'] = p_obj.get_range()
elif change.what == 'bounds':
start, end = p_obj.get_soft_bounds()
updates['start'] = start
updates['end'] = end
supports_bounds = hasattr(widget, 'start')
if start is None or end is None:
rerender = supports_bounds
else:
rerender = not supports_bounds
if supports_bounds:
updates['start'] = start
updates['end'] = end
if rerender:
self._rerender_widget(p_name)
return
elif change.what == 'step':
updates['step'] = p_obj.step
elif change.what == 'label':
Expand Down Expand Up @@ -530,6 +532,27 @@ def _ordered_params(self):
# Model API
#----------------------------------------------------------------

def _rerender(self):
precedence = lambda k: self.object.param['name' if k == '_title' else k].precedence
params = self._ordered_params
if self.show_name:
params.insert(0, '_title')
widgets = []
for k in params:
if precedence(k) is None or precedence(k) >= self.display_threshold:
widgets.append(self._widgets[k])
self._widget_box.objects = widgets

def _rerender_widget(self, p_name):
watchers = []
for w in self._callbacks:
if w.inst is self._widgets[p_name]:
w.inst.param.unwatch(w)
else:
watchers.append(w)
self._widgets[p_name] = self.widget(p_name)
self._rerender()

def _get_widgets(self):
"""Return name,widget boxes for all parameters (i.e., a property sheet)"""
# Format name specially
Expand Down
38 changes: 30 additions & 8 deletions panel/tests/test_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import param

from bokeh.models import (
Div, Slider, Select, RangeSlider, MultiSelect, Row as BkRow,
CheckboxGroup, Toggle, Button, TextInput as BkTextInput,
Tabs as BkTabs, Column as BkColumn, TextInput)
Div, Slider, Select, RangeSlider as BkRangeSlider, MultiSelect,
Row as BkRow, CheckboxGroup, Toggle, Button, TextInput as
BkTextInput,Tabs as BkTabs, Column as BkColumn, TextInput)
from panel.pane import Pane, PaneBase, Matplotlib, Bokeh, HTML
from panel.layout import Tabs, Row
from panel.param import Param, ParamMethod, ParamFunction, JSONInit
from panel.widgets import LiteralInput
from panel.widgets import LiteralInput, RangeSlider
from panel.tests.util import mpl_available, mpl_figure


Expand Down Expand Up @@ -221,7 +221,7 @@ class Test(param.Parameterized):
model = test_pane.get_root(document, comm=comm)

widget = model.children[1]
assert isinstance(widget, RangeSlider)
assert isinstance(widget, BkRangeSlider)
assert widget.start == 0
assert widget.end == 1.1
assert widget.value == (0.1, 0.5)
Expand Down Expand Up @@ -660,9 +660,9 @@ class Test(param.Parameterized):
assert number.value != 3
assert test.a == 3

test.a = 4
assert number.value != 4
assert test.a == 4
pane._widgets['a']._process_events({'value': 4})
assert test.a == 3
assert number.value == 4


def test_set_show_name(document, comm):
Expand Down Expand Up @@ -1182,3 +1182,25 @@ def _update_text_pane(self, *_):
view.text = TextModel(text="New TextModel")
# Then
assert view.text_pane.parameters==["text"]


def test_rerender_bounded_widget_when_bounds_set_and_unset():
class Test(param.Parameterized):
num = param.Range()

test = Test()
p = Param(test)

assert isinstance(p._widgets['num'], LiteralInput)
assert p._widgets['num'] in p._widget_box

test.param.num.bounds = (0, 5)

assert isinstance(p._widgets['num'], RangeSlider)
assert p._widgets['num'] in p._widget_box

test.param.num.bounds = (None, 5)

assert isinstance(p._widgets['num'], LiteralInput)
assert p._widgets['num'] in p._widget_box