244 lines
8.3 KiB
Python
244 lines
8.3 KiB
Python
|
'''
|
||
|
Showcase of Kivy Features
|
||
|
=========================
|
||
|
|
||
|
This showcases many features of Kivy. You should see a
|
||
|
menu bar across the top with a demonstration area below. The
|
||
|
first demonstration is the accordion layout. You can see, but not
|
||
|
edit, the kv language code for any screen by pressing the bug or
|
||
|
'show source' icon. Scroll through the demonstrations using the
|
||
|
left and right icons in the top right or selecting from the menu
|
||
|
bar.
|
||
|
|
||
|
The file showcase.kv describes the main container, while each demonstration
|
||
|
pane is described in a separate .kv file in the data/screens directory.
|
||
|
The image data/background.png provides the gradient background while the
|
||
|
icons in data/icon directory are used in the control bar. The file
|
||
|
data/faust_github.jpg is used in the Scatter pane. The icons are
|
||
|
from `http://www.gentleface.com/free_icon_set.html` and licensed as
|
||
|
Creative Commons - Attribution and Non-commercial Use Only; they
|
||
|
sell a commercial license.
|
||
|
|
||
|
The file android.txt is used to package the application for use with the
|
||
|
Kivy Launcher Android application. For Android devices, you can
|
||
|
copy/paste this directory into /sdcard/kivy/showcase on your Android device.
|
||
|
|
||
|
'''
|
||
|
|
||
|
from time import time
|
||
|
from kivy.app import App
|
||
|
from os.path import dirname, join
|
||
|
from kivy.lang import Builder
|
||
|
from kivy.properties import (
|
||
|
NumericProperty,
|
||
|
StringProperty,
|
||
|
BooleanProperty,
|
||
|
ListProperty,
|
||
|
)
|
||
|
from kivy.clock import Clock
|
||
|
from kivy.animation import Animation
|
||
|
from kivy.uix.screenmanager import Screen
|
||
|
|
||
|
|
||
|
class ShowcaseScreen(Screen):
|
||
|
fullscreen = BooleanProperty(False)
|
||
|
|
||
|
def add_widget(self, *args, **kwargs):
|
||
|
if 'content' in self.ids:
|
||
|
return self.ids.content.add_widget(*args, **kwargs)
|
||
|
return super(ShowcaseScreen, self).add_widget(*args, **kwargs)
|
||
|
|
||
|
|
||
|
class ShowcaseApp(App):
|
||
|
|
||
|
index = NumericProperty(-1)
|
||
|
current_title = StringProperty()
|
||
|
time = NumericProperty(0)
|
||
|
show_sourcecode = BooleanProperty(False)
|
||
|
sourcecode = StringProperty()
|
||
|
screen_names = ListProperty([])
|
||
|
hierarchy = ListProperty([])
|
||
|
|
||
|
def build(self):
|
||
|
self.title = 'hello world'
|
||
|
Clock.schedule_interval(self._update_clock, 1 / 60.)
|
||
|
self.screens = {}
|
||
|
self.available_screens = sorted([
|
||
|
'Buttons', 'ToggleButton', 'Sliders', 'ProgressBar', 'Switches',
|
||
|
'CheckBoxes', 'TextInputs', 'Accordions', 'FileChoosers',
|
||
|
'Carousel', 'Bubbles', 'CodeInput', 'DropDown', 'Spinner',
|
||
|
'Scatter', 'Splitter', 'TabbedPanel + Layouts', 'RstDocument',
|
||
|
'Popups', 'ScreenManager'])
|
||
|
self.screen_names = self.available_screens
|
||
|
curdir = dirname(__file__)
|
||
|
self.available_screens = [join(curdir, 'data', 'screens',
|
||
|
'{}.kv'.format(fn).lower()) for fn in self.available_screens]
|
||
|
self.go_next_screen()
|
||
|
|
||
|
def on_pause(self):
|
||
|
return True
|
||
|
|
||
|
def on_resume(self):
|
||
|
pass
|
||
|
|
||
|
def on_current_title(self, instance, value):
|
||
|
self.root.ids.spnr.text = value
|
||
|
|
||
|
def go_previous_screen(self):
|
||
|
self.index = (self.index - 1) % len(self.available_screens)
|
||
|
screen = self.load_screen(self.index)
|
||
|
sm = self.root.ids.sm
|
||
|
sm.switch_to(screen, direction='right')
|
||
|
self.current_title = screen.name
|
||
|
self.update_sourcecode()
|
||
|
|
||
|
def go_next_screen(self):
|
||
|
self.index = (self.index + 1) % len(self.available_screens)
|
||
|
screen = self.load_screen(self.index)
|
||
|
sm = self.root.ids.sm
|
||
|
sm.switch_to(screen, direction='left')
|
||
|
self.current_title = screen.name
|
||
|
self.update_sourcecode()
|
||
|
|
||
|
def go_screen(self, idx):
|
||
|
self.index = idx
|
||
|
self.root.ids.sm.switch_to(self.load_screen(idx), direction='left')
|
||
|
self.update_sourcecode()
|
||
|
|
||
|
def go_hierarchy_previous(self):
|
||
|
ahr = self.hierarchy
|
||
|
if len(ahr) == 1:
|
||
|
return
|
||
|
if ahr:
|
||
|
ahr.pop()
|
||
|
if ahr:
|
||
|
idx = ahr.pop()
|
||
|
self.go_screen(idx)
|
||
|
|
||
|
def load_screen(self, index):
|
||
|
if index in self.screens:
|
||
|
return self.screens[index]
|
||
|
screen = Builder.load_file(self.available_screens[index])
|
||
|
self.screens[index] = screen
|
||
|
return screen
|
||
|
|
||
|
def read_sourcecode(self):
|
||
|
fn = self.available_screens[self.index]
|
||
|
with open(fn) as fd:
|
||
|
return fd.read()
|
||
|
|
||
|
def toggle_source_code(self):
|
||
|
self.show_sourcecode = not self.show_sourcecode
|
||
|
if self.show_sourcecode:
|
||
|
height = self.root.height * .3
|
||
|
else:
|
||
|
height = 0
|
||
|
|
||
|
Animation(height=height, d=.3, t='out_quart').start(
|
||
|
self.root.ids.sv)
|
||
|
|
||
|
self.update_sourcecode()
|
||
|
|
||
|
def update_sourcecode(self):
|
||
|
if not self.show_sourcecode:
|
||
|
self.root.ids.sourcecode.focus = False
|
||
|
return
|
||
|
self.root.ids.sourcecode.text = self.read_sourcecode()
|
||
|
self.root.ids.sv.scroll_y = 1
|
||
|
|
||
|
def showcase_floatlayout(self, layout):
|
||
|
|
||
|
def add_button(*t):
|
||
|
if not layout.get_parent_window():
|
||
|
return
|
||
|
if len(layout.children) > 5:
|
||
|
layout.clear_widgets()
|
||
|
layout.add_widget(Builder.load_string('''
|
||
|
#:import random random.random
|
||
|
Button:
|
||
|
size_hint: random(), random()
|
||
|
pos_hint: {'x': random(), 'y': random()}
|
||
|
text:
|
||
|
'size_hint x: {} y: {}\\n pos_hint x: {} y: {}'.format(\
|
||
|
self.size_hint_x, self.size_hint_y, self.pos_hint['x'],\
|
||
|
self.pos_hint['y'])
|
||
|
'''))
|
||
|
Clock.schedule_once(add_button, 1)
|
||
|
Clock.schedule_once(add_button)
|
||
|
|
||
|
def showcase_boxlayout(self, layout):
|
||
|
|
||
|
def add_button(*t):
|
||
|
if not layout.get_parent_window():
|
||
|
return
|
||
|
if len(layout.children) > 5:
|
||
|
layout.orientation = 'vertical'\
|
||
|
if layout.orientation == 'horizontal' else 'horizontal'
|
||
|
layout.clear_widgets()
|
||
|
layout.add_widget(Builder.load_string('''
|
||
|
Button:
|
||
|
text: self.parent.orientation if self.parent else ''
|
||
|
'''))
|
||
|
Clock.schedule_once(add_button, 1)
|
||
|
Clock.schedule_once(add_button)
|
||
|
|
||
|
def showcase_gridlayout(self, layout):
|
||
|
|
||
|
def add_button(*t):
|
||
|
if not layout.get_parent_window():
|
||
|
return
|
||
|
if len(layout.children) > 15:
|
||
|
layout.rows = 3 if layout.rows is None else None
|
||
|
layout.cols = None if layout.rows == 3 else 3
|
||
|
layout.clear_widgets()
|
||
|
layout.add_widget(Builder.load_string('''
|
||
|
Button:
|
||
|
text:
|
||
|
'rows: {}\\ncols: {}'.format(self.parent.rows, self.parent.cols)\
|
||
|
if self.parent else ''
|
||
|
'''))
|
||
|
Clock.schedule_once(add_button, 1)
|
||
|
Clock.schedule_once(add_button)
|
||
|
|
||
|
def showcase_stacklayout(self, layout):
|
||
|
orientations = ('lr-tb', 'tb-lr',
|
||
|
'rl-tb', 'tb-rl',
|
||
|
'lr-bt', 'bt-lr',
|
||
|
'rl-bt', 'bt-rl')
|
||
|
|
||
|
def add_button(*t):
|
||
|
if not layout.get_parent_window():
|
||
|
return
|
||
|
if len(layout.children) > 11:
|
||
|
layout.clear_widgets()
|
||
|
cur_orientation = orientations.index(layout.orientation)
|
||
|
layout.orientation = orientations[cur_orientation - 1]
|
||
|
layout.add_widget(Builder.load_string('''
|
||
|
Button:
|
||
|
text: self.parent.orientation if self.parent else ''
|
||
|
size_hint: .2, .2
|
||
|
'''))
|
||
|
Clock.schedule_once(add_button, 1)
|
||
|
Clock.schedule_once(add_button)
|
||
|
|
||
|
def showcase_anchorlayout(self, layout):
|
||
|
|
||
|
def change_anchor(self, *l):
|
||
|
if not layout.get_parent_window():
|
||
|
return
|
||
|
anchor_x = ('left', 'center', 'right')
|
||
|
anchor_y = ('top', 'center', 'bottom')
|
||
|
if layout.anchor_x == 'left':
|
||
|
layout.anchor_y = anchor_y[anchor_y.index(layout.anchor_y) - 1]
|
||
|
layout.anchor_x = anchor_x[anchor_x.index(layout.anchor_x) - 1]
|
||
|
|
||
|
Clock.schedule_once(change_anchor, 1)
|
||
|
Clock.schedule_once(change_anchor, 1)
|
||
|
|
||
|
def _update_clock(self, dt):
|
||
|
self.time = time()
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
ShowcaseApp().run()
|