bring inline with suggestions on pull request

This commit is contained in:
Qua-non 2012-03-20 00:39:11 +05:30
parent 23e8e4ab49
commit 5e7a864633
4 changed files with 68 additions and 45 deletions

View File

@ -26,12 +26,8 @@ Builder.load_string('''
on_release: root.show_tab()
<PanelTest>
size_hint: (None, None)
size: (350, 250)
pos_hint: {'center_x': .25, 'y': .55}
tab_pos: 'top_left'
tab_height: 20
tab_width: 70
size_hint: (.54, .45)
pos_hint: {'center_x': .5, 'y': .55}
default_tab_text: 'Settings'
default_content: cut
FloatLayout:
@ -84,15 +80,22 @@ class PanelTest(TabbedPanel):
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
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':
# restore text
tab._label.text = tab.text
# 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)
@ -105,6 +108,10 @@ class PanelTest(TabbedPanel):
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._label.text = ''
tab.bind(pos = partial(self.update_pos, sctr, tab))
@ -151,7 +158,7 @@ class PanelTest(TabbedPanel):
tab.background_normal = 'sequenced_images/data/images/info.png'
tab._label.text = ''
def on_default_tab(self, *l):
def on_Default_tab(self, *l):
self.change_tab_contents(self.default_content)
def change_tab_contents(self, *l):

View File

@ -25,7 +25,7 @@ Builder.load_string("""
BoxLayout:
id: set3_content
BubbleButton:
text: 'bubble button'
text: 'Bubble Button'
TabbedPanelHeader:
text: 'set2'
on_release: root.change_tab_contents(set2_content)
@ -40,7 +40,7 @@ class Test(TabbedPanel):
super(Test, self).__init__(**kwargs)
self.change_tab_contents(self.default_content)
def on_default_tab(self, *l):
def on_Default_tab(self, *l):
self.change_tab_contents(self.default_content)
def change_tab_contents(self, content, *l):

View File

@ -96,7 +96,7 @@
rgba: self.parent.background_color if self.parent else (1, 1, 1, 1)
BorderImage:
border: self.parent.border if self.parent else (16, 16, 16, 16)
texture: root.parent.background_texture if root.parent else None
texture: root.parent._bk_img.texture if root.parent else None
size: self.size
pos: self.pos
@ -107,14 +107,14 @@
rgba: self.tabbed_panel.background_color if self.tabbed_panel else (1, 1, 1, 1)
BorderImage:
border: (9, 9, 9, 9)
texture: self.tabbed_panel.background_texture if self.tabbed_panel else None
texture: self.tabbed_panel._bk_img.texture if self.tabbed_panel else None
size: self.size
pos: self.pos
<TabbedPanelHeader>:
group: '__tab__'
text_size: self.size
halign: 'center'
valign: 'middle'
background_normal: 'tools/theming/defaulttheme/tab_btn.png'
background_down: 'tools/theming/defaulttheme/tab_btn_pressed.png'
border: (0, 0, 0, 0)

View File

@ -59,10 +59,10 @@ Change panel contents depending on which tab is pressed::
tabbed_panel_instance.clear_widgets()
tabbed_panel_instance.add_widgets(...)...
Since the default tab exists by default, a `on_default_tab` event is provided.
Since the default tab exists by default, a `on_Default_tab` event is provided.
To facilitate changing panel contents on default tab selection::
tp.bind(on_default_tab = my_default_tab_callback)
tp.bind(on_Default_tab = my_default_tab_callback)
Remove Items::
@ -134,7 +134,7 @@ class TabbedPanelHeader(ToggleButton):
You can use this TabbedPanelHeader widget to add a new tab to TabbedPanel
'''
#only allow selecting the tab if not already selected
# only allow selecting the tab if not already selected
def on_touch_down(self, touch):
if self.state == 'down':
for child in self.children:
@ -199,7 +199,7 @@ class TabbedPanel(GridLayout):
default to 'bottom_mid'.
'''
tab_height = NumericProperty(20)
tab_height = NumericProperty(40)
'''Specifies the height of the Tab Heading
:data:`tab_height` is a :class:`~kivy.properties.NumericProperty`,
@ -232,13 +232,6 @@ class TabbedPanel(GridLayout):
read-only.
'''
background_texture = ObjectProperty(None)
'''Specifies the background texture of the Tabs contents and the Tab Heading
:data:`background_texture` is a :class:`~kivy.properties.ObjectProperty`,
default to 'None'.
'''
content = ObjectProperty(None)
'''This is the object where the main content of the current tab is held
@ -260,29 +253,27 @@ class TabbedPanel(GridLayout):
self._bk_img = Image(
source=self.background_image, allow_stretch = True,
keep_ratio = False, color = self.background_color)
self.background_texture = self._bk_img.texture
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.bind(on_release = self.on_default_tab)
_tabs.add_widget(Default_tab)
Default_tab.bind(on_release = self.on_Default_tab)
self.content = content = TabbedPanelContent()
super(TabbedPanel, self).__init__(**kwargs)
self.add_widget(content)
self._bk_img.bind(on_texture=self._on_texture)
self.on_tab_pos()
def on_default_tab(self, *l):
def on_Default_tab(self, *l):
'''This event is fired when the default tab is selected.
'''
def on_default_tab_text(self, *l):
self.default_tab.text = self.default_tab_text
self.Default_tab.text = self.default_tab_text
def add_widget(self, *l):
content = self.content
@ -292,6 +283,7 @@ class TabbedPanel(GridLayout):
super(TabbedPanel, self).add_widget(*l)
elif isinstance(l[0], TabbedPanelHeader):
self_tabs = self._tab_strip
l[0].group = '__tab%r__' %self_tabs.uid
self_tabs.add_widget(l[0])
self_tabs.width += l[0].width if not l[0].size_hint_x else\
self.tab_width
@ -306,16 +298,16 @@ 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:
Logger.info('TabbedPanel: default tab! can\'t be removed.\n' +
'change `default_tab` to a different tab to remove this.')
'change `Default_tab` to a different tab to remove this.')
else:
content.remove_widget(l[0])
@ -331,18 +323,15 @@ class TabbedPanel(GridLayout):
def clear_tabs(self, *l):
self_tabs = self._tab_strip
self_tabs.clear_widgets()
self_default_tab = self.default_tab
self_tabs.add_widget(self_default_tab)
self_tabs.width = self_default_tab.width
self_Default_tab = self.Default_tab
self_tabs.add_widget(self_Default_tab)
self_tabs.width = self_Default_tab.width
self.reposition_tabs()
def reposition_tabs(self, *l):
Clock.unschedule(self.on_tab_pos)
Clock.schedule_once(self.on_tab_pos)
def _on_texture(self, *l):
self.background_texture = self._bk_img.texture
def on_background_image(self, *l):
self._bk_img.source = self.background_image
@ -374,6 +363,7 @@ class TabbedPanel(GridLayout):
self_content = self.content
if not self_content:
return
# cache variables for faster access
self_tab_pos = self.tab_pos
self_tab_layout = self._tab_layout
self_tab_layout.clear_widgets()
@ -383,17 +373,24 @@ class TabbedPanel(GridLayout):
scrl_v.add_widget(self_tabs)
scrl_v.pos = (0, 0)
self_udpate_scrl_v_width = self._udpate_scrl_v_width
# update scrlv width when tab width changes depends on tab_pos
self_tabs.unbind(width = partial(self_udpate_scrl_v_width, scrl_v))
self_tabs.bind(width = partial(self_udpate_scrl_v_width, scrl_v))
# remove all widgets from the tab_strip
self.clear_widgets(do_super=True)
self_tab_height = self.tab_height
widget_list = []
tab_list = []
if self_tab_pos[0] == 'b' or self_tab_pos[0] == 't':
# bottom or top positions
# one col containing the tab_strip and the content
self.cols = 1
self.rows = 3
self.rows = 2
# tab_layout contains the scrollview containing tabs and two blank
# dummy widgets for spacing
self_tab_layout.rows = 1
self_tab_layout.cols = 3
self_tab_layout.size_hint = (1, None)
@ -401,6 +398,7 @@ class TabbedPanel(GridLayout):
self_udpate_scrl_v_width(scrl_v)
if self_tab_pos[0] == 'b':
# bottom
if self_tab_pos == 'bottom_mid':
tab_list = (Widget(), scrl_v, Widget())
widget_list = (self_content, self_tab_layout)
@ -412,8 +410,8 @@ class TabbedPanel(GridLayout):
tab_list = (Widget(), Widget(), scrl_v)
widget_list = (self_content, self_tab_layout)
else:
# top
if self_tab_pos == 'top_mid':
#add two dummy widgets
tab_list = (Widget(), scrl_v, Widget())
elif self_tab_pos == 'top_left':
tab_list = (scrl_v, Widget(), Widget())
@ -421,8 +419,12 @@ class TabbedPanel(GridLayout):
tab_list = (Widget(), Widget(), scrl_v)
widget_list = (self_tab_layout, self_content)
elif self_tab_pos[0] == 'l' or self_tab_pos[0] == 'r':
self.cols = 3
# left ot right positions
# one row containing the tab_strip and the content
self.cols = 2
self.rows = 1
# tab_layout contains two blank dummy widgets for spacing
#"vertically" and the scatter containing scrollview containing tabs
self_tab_layout.rows = 3
self_tab_layout.cols = 1
self_tab_layout.size_hint = (None, 1)
@ -430,6 +432,7 @@ class TabbedPanel(GridLayout):
scrl_v.height = self_tab_height
self_udpate_scrl_v_width(scrl_v)
# rotate the scatter for vertical positions
rotation = 90 if self_tab_pos[0] == 'l' else -90
sctr = Scatter(do_translation = False,
rotation = rotation,
@ -441,11 +444,22 @@ class TabbedPanel(GridLayout):
sctr.add_widget(scrl_v)
lentab_pos = len(self_tab_pos)
# Update scatter's top when it's pos changes.
# Needed for repositioning scatter to the correct place after its
# added to the parent. Use clock_schedule_once to ensure top is
# calculated after the parent's pos on canvas has been calculated.
# This is needed for when tab_pos changes to correctly position
# scatter. Without clock.schedule_once the positions would look
# fine but touch won't translate to the correct position
if self_tab_pos[lentab_pos-4:] == '_top':
#on positions 'left_top' and 'right_top'
sctr.bind(pos = Clock.schedule_once(
partial(self._update_top, sctr, 'top', None), -1))
tab_list = (sctr, )
elif self_tab_pos[lentab_pos-4:] == '_mid':
#calculate top of scatter
sctr.bind(pos = Clock.schedule_once(
partial(self._update_top, sctr, 'mid', scrl_v.width), -1))
tab_list = (Widget(), sctr, Widget())
@ -477,11 +491,13 @@ class TabbedPanel(GridLayout):
self_tab_pos = self.tab_pos
self_tabs = self._tab_strip
if self_tab_pos[0] == 'b' or self_tab_pos[0] == 't':
#bottom or top
scrl_v.width = min(self.width, self_tabs.width)
#required for situations when scrl_v's pos is calculated
#when it has no parent
scrl_v.top += 1
scrl_v.top -= 1
else:
# left or right
scrl_v.width = min(self.height, self_tabs.width)
self_tabs.pos = (0, 0)