2014-02-22 20:55:13 +00:00
|
|
|
from kivy.app import App
|
|
|
|
from kivy.uix.gridlayout import GridLayout
|
|
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
|
|
from kivy.uix.button import Button
|
|
|
|
from kivy.uix.behaviors import FocusBehavior
|
|
|
|
|
|
|
|
|
|
|
|
class FocusButton(FocusBehavior, Button):
|
|
|
|
'''A button, which when focused, turns red and sets the keyboard
|
|
|
|
input to the text of the button.
|
|
|
|
'''
|
|
|
|
|
|
|
|
def on_focused(self, instance, value, *largs):
|
|
|
|
self.background_color = [1, 0, 0, 1] if value else [1, 1, 1, 1]
|
|
|
|
|
|
|
|
def keyboard_on_key_down(self, window, keycode, text, modifiers):
|
|
|
|
'''We call super before doing anything else to enable tab cycling
|
|
|
|
by FocusBehavior. If we wanted to use tab for ourselves, we could just
|
|
|
|
not call it, or call it if we didn't need tab.
|
|
|
|
'''
|
|
|
|
if super(FocusButton, self).keyboard_on_key_down(window, keycode,
|
|
|
|
text, modifiers):
|
|
|
|
return True
|
|
|
|
self.text = keycode[1]
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
class FocusApp(App):
|
|
|
|
|
|
|
|
def build(self):
|
|
|
|
root = BoxLayout()
|
|
|
|
self.grid1 = grid1 = GridLayout(cols=4)
|
|
|
|
self.grid2 = grid2 = GridLayout(cols=4)
|
2014-02-23 23:22:51 +00:00
|
|
|
root.add_widget(FocusButton(text='Left', size_hint_x=0.4))
|
2014-02-22 20:55:13 +00:00
|
|
|
root.add_widget(grid1)
|
|
|
|
root.add_widget(grid2)
|
2014-02-23 23:22:51 +00:00
|
|
|
root.add_widget(FocusButton(text='Right', size_hint_x=0.4))
|
2014-02-22 20:55:13 +00:00
|
|
|
|
|
|
|
for i in range(40):
|
|
|
|
grid1.add_widget(FocusButton(text='l' + str(i)))
|
|
|
|
for i in range(40):
|
|
|
|
grid2.add_widget(FocusButton(text='r' + str(i)))
|
|
|
|
|
|
|
|
# make elements 29, 9 un-focusable. The widgets are displayed in
|
|
|
|
# reverse order, so 9 = 39 - 10
|
2014-02-23 23:22:51 +00:00
|
|
|
grid2.children[30].text = grid1.children[14].text =\
|
|
|
|
grid2.children[10].text = grid1.children[34].text = 'Skip me'
|
2014-02-22 20:55:13 +00:00
|
|
|
grid2.children[10].is_focusable = False
|
|
|
|
grid2.children[30].is_focusable = False
|
|
|
|
# similarly, make 39 - 14 = 25, and 5 un-focusable
|
|
|
|
grid1.children[14].is_focusable = False
|
|
|
|
grid1.children[34].is_focusable = False
|
2014-02-23 23:22:51 +00:00
|
|
|
# don't move focus passed this element
|
|
|
|
grid2.children[35].focus_next = FocusBehavior.EndIteration
|
|
|
|
grid2.children[35].text = 'Stop forward'
|
2014-02-22 20:55:13 +00:00
|
|
|
|
|
|
|
# exchange the links between the sides so that it'll skip to the other
|
|
|
|
# side in the middle. Remember that children are displayed reversed
|
|
|
|
# in layouts.
|
|
|
|
grid1.children[10].link_focus(next=grid2.children[9])
|
|
|
|
grid2.children[10].link_focus(next=grid1.children[9])
|
|
|
|
return root
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
FocusApp().run()
|