Skip to content

Commit 56cff85

Browse files
committed
doc: added functional example to behaviors/compoundselection.py
1 parent 5ee1115 commit 56cff85

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

kivy/uix/behaviors/compoundselection.py

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@
88
derived widget. For example, it can be combined with a
99
:class:`~kivy.uix.gridlayout.GridLayout` to add selection to the layout.
1010
11+
Compound selection concepts
12+
---------------------------
13+
1114
At its core, it keeps a dynamic list of widgets that can be selected.
1215
Then, as the touches and keyboard input are passed in, it selects one or
1316
more of the widgets based on these inputs. For example, it uses the mouse
1417
scroll and keyboard up/down buttons to scroll through the list of widgets.
1518
Multiselection can also be achieved using the keyboard shift and ctrl keys.
16-
Finally, in addition to the up/down type keyboard inputs, it can also
17-
accepts letters from the keyboard to be used to select nodes with
19+
20+
Finally, in addition to the up/down type keyboard inputs, compound selection
21+
can also accept letters from the keyboard to be used to select nodes with
1822
associated strings that start with those letters, similar to how files
1923
are selected by a file browser.
2024
25+
Selection mechanics
26+
-------------------
27+
2128
When the controller needs to select a node, it calls :meth:`select_node` and
2229
:meth:`deselect_node`. Therefore, they must be overwritten in order alter
2330
node selection. By default, the class doesn't listen for keyboard or
@@ -30,27 +37,69 @@
3037
-------
3138
3239
To add selection to a grid layout which will contain
33-
:class:`~kivy.uix.Button` widgets::
40+
:class:`~kivy.uix.Button` widgets. For each button added to the layout, you
41+
need to bind the :attr:`~kivy.uix.widget.Widget.on_touch_down` of the button
42+
to :meth:`select_with_touch` to pass on the touch events::
43+
44+
from kivy.uix.behaviors.compoundselection import CompoundSelectionBehavior
45+
from kivy.uix.button import Button
46+
from kivy.uix.gridlayout import GridLayout
47+
from kivy.core.window import Window
48+
from kivy.app import App
3449
35-
class SelectableGrid(CompoundSelectionBehavior, GridLayout):
3650
51+
class SelectableGrid(CompoundSelectionBehavior, GridLayout):
3752
def __init__(self, **kwargs):
53+
""" Use the initialize method to bind to the keyboard to enable
54+
keyboard interaction e.g. using shift and control for multi-select.
55+
"""
3856
super(CompoundSelectionBehavior, self).__init__(**kwargs)
3957
keyboard = Window.request_keyboard(None, self)
4058
keyboard.bind(on_key_down=self.select_with_key_down,
41-
on_key_up=self.select_with_key_up)
59+
on_key_up=self.select_with_key_up)
60+
61+
def add_widget(self, widget):
62+
""" Override the adding of widgets so we can bind and catch their
63+
*on_touch_down* events. """
64+
widget.bind(on_touch_down=self.button_touch_down,
65+
on_touch_up=self.button_touch_up)
66+
return super(SelectableGrid, self).add_widget(widget)
67+
68+
def button_touch_down(self, button, touch):
69+
""" Use collision detection to select buttons when the touch occurs
70+
within their area. """
71+
if button.collide_point(*touch.pos):
72+
self.select_with_touch(button, touch)
73+
74+
def button_touch_up(self, button, touch):
75+
""" Use collision detection to de-select buttons when the touch
76+
occurs outside their area and *touch_multiselect* is not True. """
77+
if not (button.collide_point(*touch.pos) or self.touch_multiselect):
78+
self.deselect_node(button)
4279
4380
def select_node(self, node):
4481
node.background_color = (1, 0, 0, 1)
45-
return super(CompoundSelectionBehavior, self).select_node(node)
82+
return super(SelectableGrid, self).select_node(node)
4683
4784
def deselect_node(self, node):
4885
node.background_color = (1, 1, 1, 1)
49-
super(CompoundSelectionBehavior, self).deselect_node(node)
86+
super(SelectableGrid, self).deselect_node(node)
87+
88+
def on_selected_nodes(self, gird, nodes):
89+
print("Selected nodes = {0}".format(nodes))
90+
91+
92+
class TestApp(App):
93+
def build(self):
94+
grid = SelectableGrid(cols=3, rows=2, touch_multiselect=True,
95+
multiselect=True)
96+
for i in range(0, 6):
97+
grid.add_widget(Button(text="Button {0}".format(i)))
98+
return grid
99+
100+
101+
TestApp().run()
50102
51-
Then, for each button added to the layout, bind the
52-
:attr:`~kivy.uix.widget.Widget.on_touch_down` of the button
53-
to :meth:`select_with_touch` to pass on the touch events.
54103
55104
.. warning::
56105
@@ -92,7 +141,7 @@ class CompoundSelectionBehavior(object):
92141

93142
touch_multiselect = BooleanProperty(False)
94143
'''A special touch mode which determines whether touch events, as
95-
processed with :meth:`select_with_touch`, will add the currently touched
144+
processed by :meth:`select_with_touch`, will add the currently touched
96145
node to the selection, or if it will clear the selection before adding the
97146
node. This allows the selection of multiple nodes by simply touching them.
98147

0 commit comments

Comments
 (0)