2012-01-24 11:07:31 +00:00
|
|
|
'''
|
|
|
|
TabbedPannel
|
2012-01-31 12:21:26 +00:00
|
|
|
============
|
2012-01-24 11:07:31 +00:00
|
|
|
|
|
|
|
Test of the widget TabbedPannel.
|
|
|
|
'''
|
|
|
|
|
|
|
|
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-01-30 10:12:02 +00:00
|
|
|
from kivy.uix.tabbedpannel import TabbedPannel, Tab_Heading
|
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
|
|
|
|
|
|
|
|
|
|
|
|
class CheckButton(ToggleButton):
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
from kivy.factory import Factory
|
|
|
|
Factory.register('CheckButton', cls = CheckButton)
|
2012-01-24 11:07:31 +00:00
|
|
|
|
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-02-25 20:54:59 +00:00
|
|
|
<CheckButton>
|
|
|
|
background_down: 'atlas://data/images/defaulttheme/bubble_btn_pressed'
|
|
|
|
background_normal: 'atlas://data/images/defaulttheme/bubble_btn'
|
|
|
|
group: 'tab_style'
|
|
|
|
Image:
|
|
|
|
source: 'tools/theming/defaulttheme/textinput_active.png'\
|
|
|
|
if self.parent.state == 'normal' else\
|
|
|
|
'tools/theming/defaulttheme/check_mark.png'
|
|
|
|
size: (20, 20)
|
|
|
|
y: self.parent.y + (self.parent.height/2) - (self.height/2)
|
|
|
|
x: self.parent.x #+ (self.width/2)
|
|
|
|
|
2012-01-30 10:12:02 +00:00
|
|
|
<TabShowcase>
|
|
|
|
but: _but
|
|
|
|
Button:
|
|
|
|
id: _but
|
|
|
|
text: 'Press to show Tabbed Pannel'
|
|
|
|
on_release: root.show_tab()
|
|
|
|
|
2012-02-25 20:54:59 +00:00
|
|
|
<Panel_Test>
|
2012-01-24 11:07:31 +00:00
|
|
|
size_hint: (None, None)
|
|
|
|
size: (350, 250)
|
|
|
|
pos_hint: {'center_x': .25, 'y': .55}
|
2012-01-24 21:08:36 +00:00
|
|
|
tab_pos: 'top_left'
|
2012-01-24 13:40:03 +00:00
|
|
|
tab_height: 20
|
2012-01-24 20:27:07 +00:00
|
|
|
tab_width: 70
|
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()
|
|
|
|
CheckButton:
|
|
|
|
text: ' Economize Space\\n Long Tabs'
|
|
|
|
on_state: root.economize_tabs(self)
|
|
|
|
CheckButton:
|
|
|
|
text: 'Image tabs'
|
|
|
|
on_state: root.image_tabs(self)
|
|
|
|
CheckButton:
|
|
|
|
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-01-24 11:07:31 +00:00
|
|
|
Tab_Heading:
|
|
|
|
text: 'tab2'
|
|
|
|
on_release: root.change_tab_contents(copy)
|
|
|
|
Tab_Heading:
|
|
|
|
text: 'tab3'
|
|
|
|
on_release: root.change_tab_contents(paste)
|
|
|
|
''')
|
|
|
|
|
|
|
|
|
2012-02-25 20:54:59 +00:00
|
|
|
class Panel_Test(TabbedPannel):
|
|
|
|
|
|
|
|
def update_pos(self, sctr, tab, *l):
|
|
|
|
sctr.pos = tab.pos
|
|
|
|
|
|
|
|
def economize_tabs(self, *l):
|
|
|
|
self.tab_width, self.tab_height = self.tab_height, self.tab_width
|
|
|
|
but_state = l[0].state
|
|
|
|
|
|
|
|
for tab in self.tab_list:
|
|
|
|
if but_state == 'normal':
|
2012-02-28 10:46:34 +00:00
|
|
|
tab._label.text = tab.text
|
|
|
|
tab.clear_widgets()
|
2012-02-25 20:54:59 +00:00
|
|
|
else:
|
|
|
|
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)
|
|
|
|
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):
|
|
|
|
btn.pos = (tab.x + tab.width - btn.width, tab.y + 0)
|
|
|
|
|
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 =
|
|
|
|
'atlas://data/images/defaulttheme/image-missing',
|
2012-02-25 20:54:59 +00:00
|
|
|
size_hint = (None, None),
|
|
|
|
size = (20, 20))
|
|
|
|
tab.add_widget(btn)
|
|
|
|
btn.bind(on_release = partial(self.close_tab, tab))
|
2012-03-01 10:03:20 +00:00
|
|
|
btn.pos = (tab.x + tab.width - btn.width, tab.y + 0)
|
|
|
|
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
|
|
|
|
|
|
|
def on_default_tab(self, *l):
|
|
|
|
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):
|
|
|
|
self.add_widget(Tab_Heading(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-02-25 20:54:59 +00:00
|
|
|
self.tab = tab = Panel_Test()
|
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()
|