You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.4 KiB
93 lines
2.4 KiB
''' |
|
ComboBox |
|
======= |
|
|
|
Based on Spinner |
|
''' |
|
|
|
__all__ = ('ComboBox', 'ComboBoxOption') |
|
|
|
from kivy.properties import ListProperty, ObjectProperty, BooleanProperty |
|
from kivy.uix.button import Button |
|
from kivy.uix.dropdown import DropDown |
|
from kivy.lang import Builder |
|
|
|
|
|
Builder.load_string(''' |
|
<ComboBoxOption>: |
|
size_hint_y: None |
|
height: 44 |
|
|
|
<ComboBox>: |
|
background_normal: 'atlas://data/images/defaulttheme/spinner' |
|
background_down: 'atlas://data/images/defaulttheme/spinner_pressed' |
|
on_key: |
|
if self.items: x, y = zip(*self.items); self.text = y[x.index(args[1])] |
|
''') |
|
|
|
|
|
class ComboBoxOption(Button): |
|
pass |
|
|
|
|
|
class ComboBox(Button): |
|
items = ListProperty() |
|
key = ObjectProperty() |
|
|
|
option_cls = ObjectProperty(ComboBoxOption) |
|
|
|
dropdown_cls = ObjectProperty(DropDown) |
|
|
|
is_open = BooleanProperty(False) |
|
|
|
def __init__(self, **kwargs): |
|
self._dropdown = None |
|
super(ComboBox, self).__init__(**kwargs) |
|
self.items_dict = dict(self.items) |
|
self.bind( |
|
on_release=self._toggle_dropdown, |
|
dropdown_cls=self._build_dropdown, |
|
option_cls=self._build_dropdown, |
|
items=self._update_dropdown, |
|
key=self._update_text) |
|
self._build_dropdown() |
|
self._update_text() |
|
|
|
def _update_text(self, *largs): |
|
try: |
|
self.text = self.items_dict[self.key] |
|
except KeyError: |
|
pass |
|
|
|
def _build_dropdown(self, *largs): |
|
if self._dropdown: |
|
self._dropdown.unbind(on_select=self._on_dropdown_select) |
|
self._dropdown.dismiss() |
|
self._dropdown = None |
|
self._dropdown = self.dropdown_cls() |
|
self._dropdown.bind(on_select=self._on_dropdown_select) |
|
self._update_dropdown() |
|
|
|
def _update_dropdown(self, *largs): |
|
dp = self._dropdown |
|
cls = self.option_cls |
|
dp.clear_widgets() |
|
for key, value in self.items: |
|
item = cls(text=value) |
|
# extra attribute |
|
item.key = key |
|
item.bind(on_release=lambda option: dp.select(option.key)) |
|
dp.add_widget(item) |
|
|
|
def _toggle_dropdown(self, *largs): |
|
self.is_open = not self.is_open |
|
|
|
def _on_dropdown_select(self, instance, data, *largs): |
|
self.key = data |
|
self.is_open = False |
|
|
|
def on_is_open(self, instance, value): |
|
if value: |
|
self._dropdown.open(self) |
|
else: |
|
self._dropdown.dismiss()
|
|
|