kivy/examples/widgets/tabbed_panel_advanced.py

233 lines
7.9 KiB
Python
Raw Normal View History

2012-01-24 11:07:31 +00:00
'''
2012-03-19 13:08:47 +00:00
TabbedPanel
============
2012-01-24 11:07:31 +00:00
Test of the widget TabbedPanel showing all capabilities.
2012-01-24 11:07:31 +00:00
'''
from kivy.app import App
from kivy.animation import Animation
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader
2012-02-25 20:54:59 +00:00
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.scatter import Scatter
from functools import partial
from kivy.lang import Builder
2012-02-25 20:54:59 +00:00
2012-01-24 11:07:31 +00:00
Builder.load_string('''
2012-01-30 10:12:02 +00:00
<TabShowcase>
but: _but
Button:
id: _but
2012-03-19 13:08:47 +00:00
text: 'Press to show Tabbed Panel'
2012-01-30 10:12:02 +00:00
on_release: root.show_tab()
<PanelTest>
size_hint: (.54, .45)
pos_hint: {'center_x': .5, 'y': .55}
2012-02-25 20:54:59 +00:00
default_tab_text: 'Settings'
2012-04-09 05:41:35 +00:00
default_tab_content: default_content
2012-01-27 13:48:09 +00:00
FloatLayout:
2012-01-28 14:52:44 +00:00
BoxLayout
2012-04-09 05:41:35 +00:00
id: default_content
2012-01-27 13:48:09 +00:00
pos:self.parent.pos
size: self.parent.size
2012-02-25 20:54:59 +00:00
Label:
2012-01-28 14:52:44 +00:00
text: 'everything is relative!'
2012-02-25 20:54:59 +00:00
BoxLayout:
orientation: 'vertical'
BubbleButton:
text:'press to add\\n a tab head'
on_release: root.add_heading()
ToggleButton:
group: 'tab_style'
2012-03-01 14:42:37 +00:00
text: ' Economic\\n Long Tabs'
2012-02-25 20:54:59 +00:00
on_state: root.economize_tabs(self)
ToggleButton:
group: 'tab_style'
2012-02-25 20:54:59 +00:00
text: 'Image tabs'
on_state: root.image_tabs(self)
ToggleButton:
group: 'tab_style'
2012-02-25 20:54:59 +00:00
text: 'Closable tabs'
on_state: root.closable_tabs(self)
2012-01-27 13:48:09 +00:00
Image:
2012-04-09 05:41:35 +00:00
id: tab_2_content
2012-01-27 13:48:09 +00:00
pos:self.parent.pos
size: self.parent.size
source: 'data/images/defaulttheme-0.png'
Image:
2012-04-09 05:41:35 +00:00
id: tab_3_content
2012-01-27 13:48:09 +00:00
pos:self.parent.pos
size: self.parent.size
source: 'data/images/image-loading.gif'
TabbedPanelHeader:
2012-01-24 11:07:31 +00:00
text: 'tab2'
2012-04-09 05:41:35 +00:00
content: tab_2_content
TabbedPanelHeader:
2012-01-24 11:07:31 +00:00
text: 'tab3'
2012-04-09 05:41:35 +00:00
content: tab_3_content
2012-01-24 11:07:31 +00:00
''')
2012-04-09 05:41:35 +00:00
class Tp(TabbedPanel):
#override tab switching method to animate on tab switch
def switch_to(self, header):
if header.content is None:
return
anim = Animation(color=(1, 1, 1, 0), d =.24, t = 'in_out_quad')
def start_anim(_anim, child, in_complete, *lt):
if hasattr(child, 'color'):
_anim.start(child)
elif not in_complete:
_on_complete()
def _on_complete(*lt):
self.clear_widgets()
if hasattr(header.content, 'color'):
header.content.color = (0, 0, 0, 0)
anim = Animation(color = (1, 1, 1, 1), d =.23, t = 'in_out_quad')
start_anim(anim, header.content, True)
self.add_widget(header.content)
anim.bind(on_complete = _on_complete)
if self.content != None:
start_anim(anim, self.content.children[0], False)
else:
_on_complete()
class PanelTest(Tp):
2012-02-25 20:54:59 +00:00
def update_pos(self, sctr, tab, *l):
sctr.pos = tab.pos
def update_sctr_rotation(self, sctr, *l):
sctr.rotation = 90 if self.tab_pos[0] != 'l' else -90
2012-02-25 20:54:59 +00:00
def economize_tabs(self, *l):
# switch width and height for long tabs
2012-02-25 20:54:59 +00:00
self.tab_width, self.tab_height = self.tab_height, self.tab_width
but_state = l[0].state
2012-02-25 20:54:59 +00:00
for tab in self.tab_list:
if but_state == 'normal':
2012-04-09 05:41:35 +00:00
try:
tab.color = tab.old_color
except AttributeError:
pass
# remove scatter and label
2012-02-28 10:46:34 +00:00
tab.clear_widgets()
2012-02-25 20:54:59 +00:00
else:
# add a scatter with a label rotated to display standing text
2012-02-25 20:54:59 +00:00
lbl = Label(text = tab.text,
2012-04-09 05:41:35 +00:00
size_hint=(None, None), size=tab.size)
2012-02-25 20:54:59 +00:00
sctr = Scatter(do_translation = False,
2012-02-28 10:46:34 +00:00
rotation = 90 if self.tab_pos[0] != 'l' else -90,
2012-02-25 20:54:59 +00:00
do_rotation = False,
do_scale = False,
size_hint = (None, None),
auto_bring_to_front = False,
size = lbl.size)
tab.add_widget(sctr)
sctr.add_widget(lbl)
# update scatter rotation on tab_pos required only if you need
# to dynamically change the tab_pos when in long tabs mode and
# going from 'bottom_right' to 'left_*' tab_pos
self.bind(tab_pos = partial(self.update_sctr_rotation, sctr))
2012-04-09 05:41:35 +00:00
tab.old_color = tab.color
tab.color = (0, 0, 0, 0)
2012-02-25 20:54:59 +00:00
tab.bind(pos = partial(self.update_pos, sctr, tab))
def position_close_btn(self, tab, btn, *l):
2012-03-20 10:59:15 +00:00
btn.pos = (tab.right - btn.width, tab.top - btn.height)
2012-02-25 20:54:59 +00:00
def close_tab(self, tab, *l):
self.remove_widget(tab)
def closable_tabs(self, *l):
but_state = l[0].state
for tab in self.tab_list:
if but_state == 'normal':
tab.clear_widgets()
else:
2012-02-28 10:46:34 +00:00
btn = Button(background_normal =
2012-03-20 10:59:15 +00:00
'tools/theming/defaulttheme/close.png',
2012-02-25 20:54:59 +00:00
size_hint = (None, None),
2012-03-20 10:59:15 +00:00
size = (15, 15),
border = (0, 0, 0, 0))
2012-02-25 20:54:59 +00:00
tab.add_widget(btn)
btn.bind(on_release = partial(self.close_tab, tab))
2012-03-20 10:59:15 +00:00
btn.pos = (tab.right - btn.width, tab.top - btn.height)
tab.bind(pos = partial(self.position_close_btn, tab, btn))
2012-02-25 20:54:59 +00:00
2012-04-09 05:41:35 +00:00
def image_tabs(self, but):
but_state = but.state
2012-02-25 20:54:59 +00:00
if but_state == 'normal':
self.tab_height = self.old_height
for tab in self.tab_list:
try:
2012-04-09 05:41:35 +00:00
tab.color = tab.old_color
2012-02-25 20:54:59 +00:00
tab.background_down = tab.old_img
2012-02-28 10:46:34 +00:00
tab.background_normal = tab.old_img_normal
2012-02-25 20:54:59 +00:00
except AttributeError:
pass
2012-04-09 05:41:35 +00:00
# all new tabs should also follow style
Builder.load_string(str('''
<TabbedPanelHeader>:
background_normal: '%s'
background_down: '%s'
color: (%x, %x, %x, %x)
font_size: 11''') %(tab.old_img_normal, tab.old_img,
tab.color[0], tab.color[1], tab.color[2], tab.color[3]))
2012-02-25 20:54:59 +00:00
else:
2012-02-28 10:46:34 +00:00
self.old_height = self.tab_height
self.tab_height = 50
for tab in self.tab_list:
2012-02-25 20:54:59 +00:00
tab.old_img = tab.background_down
tab.background_down = 'softboy.png'
2012-02-28 10:46:34 +00:00
tab.old_img_normal = tab.background_normal
tab.background_normal = 'sequenced_images/data/images/info.png'
2012-04-09 05:41:35 +00:00
tab.old_color = tab.color
tab.color = (0, 0, 0, 0)
# all new tabs should also follow style
Builder.load_string('''
<TabbedPanelHeader>:
background_normal: 'sequenced_images/data/images/info.png'
background_down: 'softboy.png'
color: 0,0,0,0
font_size: 11''')
def add_heading(self):
self.add_widget(TabbedPanelHeader(text = 'tabx'))
2012-01-24 11:07:31 +00:00
2012-01-30 10:12:02 +00:00
class TabShowcase(FloatLayout):
2012-01-24 11:07:31 +00:00
2012-04-09 05:41:35 +00:00
def show_tab(self):
2012-01-24 11:07:31 +00:00
if not hasattr(self, 'tab'):
self.tab = tab = PanelTest()
2012-01-24 11:07:31 +00:00
self.add_widget(tab)
else:
values = ('left_top', 'left_mid', 'left_bottom', 'top_left',
'top_mid', 'top_right', 'right_top', 'right_mid',
'right_bottom', 'bottom_left', 'bottom_mid', 'bottom_right')
index = values.index(self.tab.tab_pos)
self.tab.tab_pos = values[(index + 1) % len(values)]
2012-01-28 10:20:44 +00:00
self.but.text = 'Tabs in\'%s\' position,\n press to change to next pos'\
%self.tab.tab_pos
2012-01-24 11:07:31 +00:00
class TestTabApp(App):
def build(self):
return TabShowcase()
if __name__ in ('__main__', '__android__'):
2012-02-28 10:46:34 +00:00
TestTabApp().run()