84 lines
3.0 KiB
Python
84 lines
3.0 KiB
Python
from kivy.uix.gridlayout import GridLayout
|
|
from kivy.uix.button import Button
|
|
from kivy.uix.behaviors import CompoundSelectionBehavior
|
|
from kivy.uix.behaviors import FocusBehavior
|
|
from kivy.app import runTouchApp
|
|
|
|
|
|
class SelectableGrid(FocusBehavior, CompoundSelectionBehavior, GridLayout):
|
|
|
|
def __init__(self, **kwargs):
|
|
super(SelectableGrid, self).__init__(**kwargs)
|
|
|
|
def print_selection(*l):
|
|
print('selected: ', [x.text for x in self.selected_nodes])
|
|
self.bind(selected_nodes=print_selection)
|
|
|
|
def keyboard_on_key_down(self, window, keycode, text, modifiers):
|
|
if super(SelectableGrid, self).keyboard_on_key_down(
|
|
window, keycode, text, modifiers):
|
|
return True
|
|
if self.select_with_key_down(window, keycode, text, modifiers):
|
|
return True
|
|
return False
|
|
|
|
def keyboard_on_key_up(self, window, keycode):
|
|
if super(SelectableGrid, self).keyboard_on_key_up(window, keycode):
|
|
return True
|
|
if self.select_with_key_up(window, keycode):
|
|
return True
|
|
return False
|
|
|
|
def goto_node(self, key, last_node, last_node_idx):
|
|
''' This function is used to go to the node by typing the number
|
|
of the text of the button.
|
|
'''
|
|
node, idx = super(SelectableGrid, self).goto_node(key, last_node,
|
|
last_node_idx)
|
|
if node != last_node:
|
|
return node, idx
|
|
|
|
items = list(enumerate(self.get_selectable_nodes()))
|
|
'''If self.nodes_order_reversed (the default due to using
|
|
self.children which is reversed), the index is counted from the
|
|
starts of the selectable nodes, like normal but the nodes are traversed
|
|
in the reverse order.
|
|
'''
|
|
# start searching after the last selected node
|
|
if not self.nodes_order_reversed:
|
|
items = items[last_node_idx + 1:] + items[:last_node_idx + 1]
|
|
else:
|
|
items = items[:last_node_idx][::-1] + items[last_node_idx:][::-1]
|
|
|
|
for i, child in items:
|
|
if child.text.startswith(key):
|
|
return child, i
|
|
return node, idx
|
|
|
|
def select_node(self, node):
|
|
node.background_color = (1, 0, 0, 1)
|
|
return super(SelectableGrid, self).select_node(node)
|
|
|
|
def deselect_node(self, node):
|
|
node.background_color = (1, 1, 1, 1)
|
|
super(SelectableGrid, self).deselect_node(node)
|
|
|
|
def do_touch(self, instance, touch):
|
|
if ('button' in touch.profile and touch.button in
|
|
('scrollup', 'scrolldown', 'scrollleft', 'scrollright')) or\
|
|
instance.collide_point(*touch.pos):
|
|
self.select_with_touch(instance, touch)
|
|
else:
|
|
return False
|
|
return True
|
|
|
|
|
|
root = SelectableGrid(cols=5, up_count=5, multiselect=True, scroll_count=1)
|
|
for i in range(40):
|
|
c = Button(text=str(i))
|
|
c.bind(on_touch_down=root.do_touch)
|
|
root.add_widget(c)
|
|
|
|
|
|
runTouchApp(root)
|