2012-01-24 11:07:31 +00:00
|
|
|
'''
|
2012-03-19 13:08:47 +00:00
|
|
|
TabbedPanel
|
2012-01-31 12:21:26 +00:00
|
|
|
============
|
2012-01-24 11:07:31 +00:00
|
|
|
|
2012-03-19 14:51:29 +00:00
|
|
|
Test of the widget TabbedPanel showing all capabilities.
|
2012-01-24 11:07:31 +00:00
|
|
|
'''
|
|
|
|
|
|
|
|
from kivy.app import App
|
2012-01-24 22:42:31 +00:00
|
|
|
from kivy.animation import Animation
|
|
|
|
from kivy.uix.floatlayout import FloatLayout
|
2012-03-19 14:00:25 +00:00
|
|
|
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
|
|
|
|
|
2012-01-24 22:42:31 +00:00
|
|
|
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()
|
|
|
|
|
2012-03-19 14:00:25 +00:00
|
|
|
<PanelTest>
|
2012-03-19 19:09:11 +00:00
|
|
|
size_hint: (.54, .45)
|
|
|
|
pos_hint: {'center_x': .5, 'y': .55}
|
2012-02-25 20:54:59 +00:00
|
|
|
default_tab_text: 'Settings'
|
2012-01-24 11:07:31 +00:00
|
|
|
default_content: cut
|
2012-01-27 13:48:09 +00:00
|
|
|
FloatLayout:
|
2012-01-28 14:52:44 +00:00
|
|
|
BoxLayout
|
2012-01-27 13:48:09 +00:00
|
|
|
id: cut
|
|
|
|
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()
|
2012-03-19 13:33:38 +00:00
|
|
|
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)
|
2012-03-19 13:33:38 +00:00
|
|
|
ToggleButton:
|
2012-03-19 14:51:29 +00:00
|
|
|
group: 'tab_style'
|
2012-02-25 20:54:59 +00:00
|
|
|
text: 'Image tabs'
|
|
|
|
on_state: root.image_tabs(self)
|
2012-03-19 13:33:38 +00:00
|
|
|
ToggleButton:
|
2012-03-19 14:51:29 +00:00
|
|
|
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:
|
|
|
|
id: copy
|
|
|
|
color: 1, 1, 1, 0
|
|
|
|
pos:self.parent.pos
|
|
|
|
size: self.parent.size
|
|
|
|
source: 'data/images/defaulttheme-0.png'
|
|
|
|
Image:
|
|
|
|
id: paste
|
|
|
|
color: 1, 1, 1, 0
|
|
|
|
pos:self.parent.pos
|
|
|
|
size: self.parent.size
|
|
|
|
source: 'data/images/image-loading.gif'
|
2012-03-19 14:00:25 +00:00
|
|
|
TabbedPanelHeader:
|
2012-01-24 11:07:31 +00:00
|
|
|
text: 'tab2'
|
|
|
|
on_release: root.change_tab_contents(copy)
|
2012-03-19 14:00:25 +00:00
|
|
|
TabbedPanelHeader:
|
2012-01-24 11:07:31 +00:00
|
|
|
text: 'tab3'
|
|
|
|
on_release: root.change_tab_contents(paste)
|
|
|
|
''')
|
|
|
|
|
|
|
|
|
2012-03-19 14:00:25 +00:00
|
|
|
class PanelTest(TabbedPanel):
|
2012-02-25 20:54:59 +00:00
|
|
|
|
|
|
|
def update_pos(self, sctr, tab, *l):
|
|
|
|
sctr.pos = tab.pos
|
|
|
|
|
2012-03-19 19:09:11 +00:00
|
|
|
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):
|
2012-03-19 19:09:11 +00:00
|
|
|
# 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
|
|
|
|
|
2012-03-19 19:09:11 +00:00
|
|
|
but_state = l[0].state
|
2012-02-25 20:54:59 +00:00
|
|
|
for tab in self.tab_list:
|
|
|
|
if but_state == 'normal':
|
2012-03-19 19:09:11 +00:00
|
|
|
# restore text
|
2012-02-28 10:46:34 +00:00
|
|
|
tab._label.text = tab.text
|
2012-03-19 19:09:11 +00:00
|
|
|
# remove scatter and label
|
2012-02-28 10:46:34 +00:00
|
|
|
tab.clear_widgets()
|
2012-02-25 20:54:59 +00:00
|
|
|
else:
|
2012-03-19 19:09:11 +00:00
|
|
|
# add a scatter with a label rotated to display standing text
|
2012-02-25 20:54:59 +00:00
|
|
|
lbl = Label(text = tab.text,
|
|
|
|
size_hint = (None, None),
|
|
|
|
size = tab.size)
|
|
|
|
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)
|
2012-03-19 19:09:11 +00:00
|
|
|
# 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-02-25 20:54:59 +00:00
|
|
|
tab._label.text = ''
|
|
|
|
|
|
|
|
tab.bind(pos = partial(self.update_pos, sctr, tab))
|
|
|
|
|
2012-03-01 10:03:20 +00:00
|
|
|
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-03-01 10:03:20 +00:00
|
|
|
|
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)
|
2012-03-01 10:03:20 +00:00
|
|
|
tab.bind(pos = partial(self.position_close_btn, tab, btn))
|
2012-02-25 20:54:59 +00:00
|
|
|
|
|
|
|
def image_tabs(self, *l):
|
|
|
|
but_state = l[0].state
|
|
|
|
if but_state == 'normal':
|
|
|
|
self.tab_height = self.old_height
|
|
|
|
for tab in self.tab_list:
|
2012-02-28 10:46:34 +00:00
|
|
|
tab._label.text = tab.text
|
2012-02-25 20:54:59 +00:00
|
|
|
try:
|
|
|
|
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
|
|
|
|
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'
|
|
|
|
tab._label.text = ''
|
2012-01-24 11:07:31 +00:00
|
|
|
|
2012-03-19 19:09:11 +00:00
|
|
|
def on_Default_tab(self, *l):
|
2012-01-24 11:07:31 +00:00
|
|
|
self.change_tab_contents(self.default_content)
|
|
|
|
|
|
|
|
def change_tab_contents(self, *l):
|
2012-02-25 20:54:59 +00:00
|
|
|
anim = Animation(color=(1, 1, 1, 0), d =.24, t = 'in_out_quad')
|
2012-01-24 22:42:31 +00:00
|
|
|
|
2012-01-28 14:52:44 +00:00
|
|
|
def start_anim(_anim, child, in_complete, *lt):
|
|
|
|
if hasattr(child, 'color'):
|
|
|
|
_anim.start(child)
|
|
|
|
elif not in_complete:
|
|
|
|
_on_complete()
|
2012-01-27 13:48:09 +00:00
|
|
|
|
|
|
|
def _on_complete(*lt):
|
2012-01-28 10:20:44 +00:00
|
|
|
if l[0].parent:
|
|
|
|
l[0].parent.remove_widget(l[0])
|
2012-01-27 13:48:09 +00:00
|
|
|
self.clear_widgets()
|
|
|
|
self.add_widget(l[0])
|
2012-02-25 20:54:59 +00:00
|
|
|
anim = Animation(color = (1, 1, 1, 1), d =.23, t = 'in_out_quad')
|
2012-01-28 14:52:44 +00:00
|
|
|
start_anim(anim, l[0], True)
|
2012-01-27 13:48:09 +00:00
|
|
|
|
|
|
|
anim.bind(on_complete = _on_complete)
|
2012-01-28 14:52:44 +00:00
|
|
|
start_anim(anim, self.content.children[0], False)
|
2012-01-24 11:07:31 +00:00
|
|
|
|
2012-01-30 10:12:02 +00:00
|
|
|
def add_heading(self, *l):
|
2012-03-19 14:00:25 +00:00
|
|
|
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
|
|
|
|
|
|
|
def show_tab(self, *l):
|
|
|
|
if not hasattr(self, 'tab'):
|
2012-03-19 14:00:25 +00:00
|
|
|
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'\
|
2012-01-24 21:08:36 +00:00
|
|
|
%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()
|