simplify tabbed_pannel_advanced example

This commit is contained in:
Qua-non 2012-04-09 15:54:24 +05:30
parent 33576a90f2
commit 289113a843
2 changed files with 195 additions and 147 deletions

View File

@ -9,11 +9,20 @@ from kivy.app import App
from kivy.animation import Animation
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader
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.factory import Factory
class StandingHeader(TabbedPanelHeader):
pass
class ClosableHeader(TabbedPanelHeader):
pass
class ImageHeader(TabbedPanelHeader):
pass
Factory.register('StandingHeader', cls = StandingHeader)
Factory.register('ClosableHeader', cls = ClosableHeader)
Factory.register('ImageHeader', cls = ImageHeader)
from kivy.lang import Builder
@ -25,35 +34,121 @@ Builder.load_string('''
text: 'Press to show Tabbed Panel'
on_release: root.show_tab()
<PanelTest>
size_hint: (.54, .45)
pos_hint: {'center_x': .5, 'y': .55}
<StandingHeader>
color: 0,0,0,0
Scatter:
do_translation: False
do_scale: False
do_rotation: False
auto_bring_to_front: False
rotation: 70
size_hint: None, None
size: lbl.size
center: root.center
#pos: root.x - root.width/2, root.y
Label:
id: lbl
text: root.text
size: root.size
pos: 0,0
<PanelLeft>
size_hint: (.45, .45)
pos_hint: {'center_x': .25, 'y': .55}
#replace the default tab with our custom tab
default_tab: def_tab
tab_width: 40
tab_height: 70
FloatLayout:
RstDocument:
id: default_content
text: 'Standing tabs\\n-------------\\n'
Image:
id: tab_2_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/defaulttheme-0.png'
Image:
id: tab_3_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/image-loading.gif'
StandingHeader:
id: def_tab
content: default_content
text: 'Default tab'
StandingHeader:
content: tab_2_content
text: 'tab 2'
StandingHeader:
content: tab_3_content
text: 'tab 3'
<ClosableHeader>
color: 0,0,0,0
BoxLayout:
pos: root.pos
size_hint: None, None
size: root.size
Label:
id: lbl
text: root.text
BoxLayout:
size_hint: None, 1
width: 18
orientation: 'vertical'
Widget:
Button:
border: 0,0,0,0
background_normal: 'tools/theming/defaulttheme/close.png'
on_release: root.panel.remove_widget(root)
Widget:
<PanelRight>
tab_pos: 'top_right'
size_hint: (.45, .45)
pos_hint: {'center_x': .75, 'y': .55}
default_tab: def_tab
FloatLayout:
RstDocument:
id: default_content
text: 'Closable tabs\\n-------------\\n'
Image:
id: tab_2_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/defaulttheme-0.png'
Image:
id: tab_3_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/image-loading.gif'
ClosableHeader:
id: def_tab
text: 'default\\ntab'
content:default_content
panel: root
ClosableHeader:
text: 'tab2'
content: tab_2_content
panel: root
ClosableHeader:
text: 'tab3'
content: tab_3_content
panel: root
<PanelbLeft>
tab_pos: 'bottom_left'
size_hint: (.45, .45)
pos_hint: {'center_x': .25, 'y': .02}
default_tab_text: 'Settings'
default_tab_content: default_content
FloatLayout:
BoxLayout
RstDocument:
id: default_content
pos:self.parent.pos
size: self.parent.size
Label:
text: 'everything is relative!'
BoxLayout:
orientation: 'vertical'
BubbleButton:
text:'press to add\\n a tab head'
on_release: root.add_heading()
ToggleButton:
group: 'tab_style'
text: ' Economic\\n Long Tabs'
on_state: root.economize_tabs(self)
ToggleButton:
group: 'tab_style'
text: 'Image tabs'
on_state: root.image_tabs(self)
ToggleButton:
group: 'tab_style'
text: 'Closable tabs'
on_state: root.closable_tabs(self)
text: 'Normal tabs\\n-------------\\n press ' +\
'background button to change tab_pos'
Image:
id: tab_2_content
pos:self.parent.pos
@ -70,6 +165,38 @@ Builder.load_string('''
TabbedPanelHeader:
text: 'tab3'
content: tab_3_content
<ImageHeader>
border: 0, 0, 0, 0
background_down: 'softboy.png'
background_normal:'sequenced_images/data/images/info.png'
<PanelbRight>
tab_pos: 'right_top'
size_hint: (.45, .45)
pos_hint: {'center_x': .75, 'y': .02}
default_tab: def_tab
FloatLayout:
RstDocument:
id: default_content
text: 'Image tabs\\n-------------\\n'
Image:
id: tab_2_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/defaulttheme-0.png'
Image:
id: tab_3_content
pos:self.parent.pos
size: self.parent.size
source: 'data/images/image-loading.gif'
ImageHeader:
id: def_tab
content:default_content
ImageHeader:
content: tab_2_content
ImageHeader:
content: tab_3_content
''')
@ -100,118 +227,29 @@ class Tp(TabbedPanel):
else:
_on_complete()
class PanelLeft(Tp):
pass
class PanelTest(Tp):
class PanelRight(Tp):
pass
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
def economize_tabs(self, *l):
# switch width and height for long tabs
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':
try:
tab.color = tab.old_color
except AttributeError:
pass
# remove scatter and label
tab.clear_widgets()
else:
# add a scatter with a label rotated to display standing text
lbl = Label(text = tab.text,
size_hint=(None, None), size=tab.size)
sctr = Scatter(do_translation = False,
rotation = 90 if self.tab_pos[0] != 'l' else -90,
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))
tab.old_color = tab.color
tab.color = (0, 0, 0, 0)
tab.bind(pos = partial(self.update_pos, sctr, tab))
def position_close_btn(self, tab, btn, *l):
btn.pos = (tab.right - btn.width, tab.top - btn.height)
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:
btn = Button(background_normal =
'tools/theming/defaulttheme/close.png',
size_hint = (None, None),
size = (15, 15),
border = (0, 0, 0, 0))
tab.add_widget(btn)
btn.bind(on_release = partial(self.close_tab, tab))
btn.pos = (tab.right - btn.width, tab.top - btn.height)
tab.bind(pos = partial(self.position_close_btn, tab, btn))
def image_tabs(self, but):
but_state = but.state
if but_state == 'normal':
self.tab_height = self.old_height
for tab in self.tab_list:
try:
tab.color = tab.old_color
tab.background_down = tab.old_img
tab.background_normal = tab.old_img_normal
except AttributeError:
pass
# 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]))
else:
self.old_height = self.tab_height
self.tab_height = 50
for tab in self.tab_list:
tab.old_img = tab.background_down
tab.background_down = 'softboy.png'
tab.old_img_normal = tab.background_normal
tab.background_normal = 'sequenced_images/data/images/info.png'
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'))
class PanelbLeft(Tp):
pass
class PanelbRight(Tp):
pass
class TabShowcase(FloatLayout):
def show_tab(self):
if not hasattr(self, 'tab'):
self.tab = tab = PanelTest()
self.tab = tab = PanelLeft()
self.add_widget(tab)
self.tab = tab = PanelRight()
self.add_widget(tab)
self.tab = tab = PanelbRight()
self.add_widget(tab)
self.tab = tab = PanelbLeft()
self.add_widget(tab)
else:
values = ('left_top', 'left_mid', 'left_bottom', 'top_left',

View File

@ -14,8 +14,7 @@ TabbedPanel
The `TabbedPanel` widget is exactly what it sounds like, a Tabbed Panel.
The :class:`TabbedPanel` contains one tabbed panel by default pointing towards
the direction you choose.
The :class:`TabbedPanel` contains one tab by default.
Simple example
--------------
@ -249,6 +248,22 @@ class TabbedPanel(GridLayout):
default to 'None'.
'''
def get_def_tab(self):
return self._default_tab
def set_def_tab(self, *l):
old_tab = self._default_tab
self._default_tab = l[0]
self.remove_widget(old_tab)
self.switch_to(l[0])
l[0].state = 'down'
default_tab = AliasProperty(get_def_tab, set_def_tab)
'''Holds the default_tab
:data:`default_tab` is a :class:`~kivy.properties.AliasProperty`
'''
def get_def_tab_content(self):
return self.default_tab.content
@ -279,13 +294,12 @@ class TabbedPanel(GridLayout):
self._tab_strip = _tabs = TabbedPanelStrip(tabbed_panel = self,
rows = 1, cols = 99, size_hint = (None, None),\
height = self.tab_height, width = self.tab_width)
self.default_tab = default_tab = \
self._default_tab = default_tab = \
TabbedPanelHeader(text = self.default_tab_text,
height = self.tab_height, state = 'down',
width = self.tab_width)
_tabs.add_widget(default_tab)
default_tab.group = '__tab%r__' %_tabs.uid
default_tab.bind(on_release=self.on_default_tab)
self._partial_update_scrollview = None
self.content = content = TabbedPanelContent()
@ -293,14 +307,10 @@ class TabbedPanel(GridLayout):
self.add_widget(content)
self.on_tab_pos()
#make default tab the active tab
self.switch_to(self.default_tab)
def on_default_tab(self, *l):
'''This event is fired when the default tab is selected.
'''
self.switch_to(self._default_tab)
def on_default_tab_text(self, *l):
self.default_tab.text = self.default_tab_text
self._default_tab.text = self.default_tab_text
def switch_to(self, header):
'''Switch to a specific panel header
@ -333,11 +343,11 @@ class TabbedPanel(GridLayout):
if l[0] == content or l[0] == self._tab_layout:
super(TabbedPanel, self).remove_widget(*l)
elif isinstance(l[0], TabbedPanelHeader):
if l[0]!= self.default_tab:
if l[0]!= self._default_tab:
self_tabs = self._tab_strip
self_tabs.remove_widget(l[0])
if l[0].state == 'down':
self.default_tab.on_release()
self._default_tab.on_release()
self_tabs.width -= l[0].width
self.reposition_tabs()
else:
@ -358,7 +368,7 @@ class TabbedPanel(GridLayout):
def clear_tabs(self, *l):
self_tabs = self._tab_strip
self_tabs.clear_widgets()
self_default_tab = self.default_tab
self_default_tab = self._default_tab
self_tabs.add_widget(self_default_tab)
self_tabs.width = self_default_tab.width
self.reposition_tabs()