Skip to content

Commit

Permalink
Fixed CompositeWidget sizing
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Jan 20, 2020
1 parent a0c21d3 commit 630161b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 49 deletions.
2 changes: 2 additions & 0 deletions panel/viewable.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ class Layoutable(param.Parameterized):
def __init__(self, **params):
if (params.get('width', None) is not None and
params.get('height', None) is not None and
params.get('width_policy') is None and
params.get('height_policy') is None and
'sizing_mode' not in params):
params['sizing_mode'] = 'fixed'
elif not self.param.sizing_mode.constant and not self.param.sizing_mode.readonly:
Expand Down
10 changes: 9 additions & 1 deletion panel/widgets/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,14 @@ class CompositeWidget(Widget):
def __init__(self, **params):
super(CompositeWidget, self).__init__(**params)
layout = {p: getattr(self, p) for p in Layoutable.param
if p != 'name' and getattr(self, p) is not None}
if getattr(self, p) is not None}
self._composite = self._composite_type(**layout)
self._models = self._composite._models
self.param.watch(self._update_layout_params, list(Layoutable.param))

def _update_layout_params(self, *events):
for event in events:
setattr(self._composite, event.name, event.new)

def select(self, selector=None):
"""
Expand Down Expand Up @@ -169,3 +174,6 @@ def _get_model(self, doc, root=None, parent=None, comm=None):

def __contains__(self, object):
return object in self._composite.objects

def _synced_params(self):
return []
26 changes: 15 additions & 11 deletions panel/widgets/file_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ class FileSelector(CompositeWidget):
directory = param.String(default=os.getcwd(), doc="""
The directory to explore.""")

height = param.Integer(default=300, doc="""
The number of options shown at once (note this is the
only way to control the height of this widget)""")

file_pattern = param.String(default='*', doc="""
A glob-like pattern to filter the files.""")

Expand All @@ -78,27 +82,27 @@ def __init__(self, directory=None, **params):
from ..pane import Markdown
if directory is not None:
params['directory'] = os.path.abspath(os.path.expanduser(directory))
if params.get('width') and params.get('height') and 'sizing_mode' not in params:
params['sizing_mode'] = None
super(FileSelector, self).__init__(**params)

# Set up layout
layout = {p: getattr(self, p) for p in Layoutable.param
if p not in ('name', 'height') and getattr(self, p) is not None}
sel_layout = dict(layout)
if self.height:
sel_layout['height'] = self.height-100
if p not in ('name', 'height', 'margin') and getattr(self, p) is not None}
sel_layout = dict(layout, sizing_mode='stretch_both', margin=0)
self._selector = CrossSelector(filter_fn=lambda p, f: fnmatch(f, p), **sel_layout)
self._go = Button(name='⬇', disabled=True, width=25, margin=(5, 25, 0, 0))
self._directory = TextInput(value=self.directory, width_policy='max')
self._back = Button(name='◀', width=25, margin=(5, 10), disabled=True)
self._back = Button(name='◀', width=25, margin=(5, 10, 0, 0), disabled=True)
self._forward = Button(name='▶', width=25, margin=(5, 10), disabled=True)
self._up = Button(name='⬆', width=25, margin=(5, 10), disabled=True)
self._directory = TextInput(value=self.directory, margin=(5, 10), width_policy='max')
self._go = Button(name='⬇', disabled=True, width=25, margin=(5, 15, 0, 0))
self._nav_bar = Row(
self._back, self._forward, self._up, self._directory, self._go,
margin=(0, 10), width_policy='max'
**dict(layout, width=None, margin=0, width_policy='max')
)
self._composite[:] = [self._nav_bar, Divider(margin=(0, 20)), self._selector]
self._selector._selected.insert(0, Markdown('### Selected files', margin=(-10, 10)))
self._selector._unselected.insert(0, Markdown('### File Browser', margin=(-10, 10)))
self._composite[:] = [self._nav_bar, Divider(margin=0), self._selector]
self._selector._selected.insert(0, Markdown('### Selected files', margin=(-10, 0)))
self._selector._unselected.insert(0, Markdown('### File Browser', margin=(-10, 0)))

# Set up state
self._stack = []
Expand Down
53 changes: 16 additions & 37 deletions panel/widgets/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,10 @@ def __init__(self, *args, **kwargs):
selected = [labels[indexOf(v, values)] for v in kwargs.get('value', [])
if isIn(v, values)]
unselected = [k for k in labels if k not in selected]
layout = dict(sizing_mode=self.sizing_mode, width_policy=self.width_policy,
height_policy=self.height_policy, background=self.background)
width = int((self.width-50)/2)
layout = dict(sizing_mode='stretch_both', background=self.background, margin=0)
self._lists = {
False: MultiSelect(options=unselected, size=self.size,
height=self.height-50, width=width, **layout),
True: MultiSelect(options=selected, size=self.size,
height=self.height-50, width=width, **layout)
False: MultiSelect(options=unselected, size=self.size, **layout),
True: MultiSelect(options=selected, size=self.size, **layout)
}
self._lists[False].param.watch(self._update_selection, 'value')
self._lists[True].param.watch(self._update_selection, 'value')
Expand All @@ -382,49 +378,32 @@ def __init__(self, *args, **kwargs):

# Define search
self._search = {
False: TextInput(placeholder='Filter available options', width=width, **layout),
True: TextInput(placeholder='Filter selected options', width=width, **layout)
False: TextInput(placeholder='Filter available options',
margin=(0, 0, 10, 0), width_policy='max'),
True: TextInput(placeholder='Filter selected options',
margin=(0, 0, 10, 0), width_policy='max')
}
self._search[False].param.watch(self._filter_options, 'value')
self._search[True].param.watch(self._filter_options, 'value')

self._placeholder = TextAreaInput(
placeholder=("To select an item highlight it on the left "
"and use the arrow button to move it to the right."),
disabled=True, height=self.height-50, width=width, **layout
disabled=True, **layout
)
right = self._lists[True] if self.value else self._placeholder

# Define Layout
self._unselected = Column(self._search[False], self._lists[False], **layout)
self._selected = Column(self._search[True], right, **layout)
buttons = Column(self._buttons[True], self._buttons[False])
buttons = Column(self._buttons[True], self._buttons[False], margin=(0, 5))

self._composite[:] = [
self._unselected, Column(VSpacer(), buttons, VSpacer()), self._selected
]

self._selected = {False: [], True: []}
self._selections = {False: [], True: []}
self._query = {False: '', True: ''}
self.param.watch(self._update_layout_params, list(Layoutable.param))

def _update_layout_params(self, *events):
for event in events:
if event.name in ['css_classes']:
setattr(self._composite, event.name, event.new)
elif event.name in ['sizing_mode', 'width_policy', 'height_policy',
'background', 'margin']:
setattr(self._composite, event.name, event.new)
setattr(self._lists[True], event.name, event.new)
setattr(self._lists[False], event.name, event.new)
elif event.name == 'height':
setattr(self._lists[True], event.name, event.new-50)
setattr(self._lists[False], event.name, event.new-50)
elif event.name == 'width':
width = int((event.new-50)/2)
setattr(self._lists[True], event.name, width)
setattr(self._lists[False], event.name, width)


@param.depends('size', watch=True)
def _update_size(self):
Expand Down Expand Up @@ -453,8 +432,8 @@ def _update_options(self):
Updates the options of each of the sublists after the options
for the whole widget are updated.
"""
self._selected[False] = []
self._selected[True] = []
self._selections[False] = []
self._selections[True] = []
self._update_value()

def _apply_filters(self):
Expand Down Expand Up @@ -493,7 +472,7 @@ def _update_selection(self, event):
Updates the current selection in each list.
"""
selected = event.obj is self._lists[True]
self._selected[selected] = [v for v in event.new if v != '']
self._selections[selected] = [v for v in event.new if v != '']

def _apply_selection(self, event):
"""
Expand All @@ -502,7 +481,7 @@ def _apply_selection(self, event):
"""
selected = event.obj is self._buttons[True]

new = OrderedDict([(k, self._items[k]) for k in self._selected[not selected]])
new = OrderedDict([(k, self._items[k]) for k in self._selections[not selected]])
old = self._lists[selected].options
other = self._lists[not selected].options

Expand All @@ -511,9 +490,9 @@ def _apply_selection(self, event):
self._lists[selected].options = merged if merged else {}
self._lists[not selected].options = leftovers if leftovers else {}
if len(self._lists[True].options):
self._selected[1] = self._lists[True]
self._selected[-1] = self._lists[True]
else:
self._selected[1] = self._placeholder
self._selected[-1] = self._placeholder
self.value = [self._items[o] for o in self._lists[True].options if o != '']
self._apply_filters()

Expand Down

0 comments on commit 630161b

Please sign in to comment.