Merge pull request #1326 from kivy/bubble_pos

Fixes for arrow_pos for Bubble when in left/right_mid positions and a new `show_arrow` proeprty
This commit is contained in:
Mathieu Virbel 2013-07-02 00:07:28 -07:00
commit 2b32643275
2 changed files with 44 additions and 25 deletions

View File

@ -14,10 +14,8 @@ from kivy.uix.bubble import Bubble
Builder.load_string('''
<cut_copy_paste>
size_hint: (None, None)
size: (150, 50)
size: (160, 120)
pos_hint: {'center_x': .5, 'y': .6}
arrow_pos: 'bottom_mid'
orientation: 'horizontal'
BubbleButton:
text: 'Cut'
BubbleButton:

View File

@ -61,9 +61,11 @@ from kivy.uix.image import Image
from kivy.uix.widget import Widget
from kivy.uix.scatter import Scatter
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.properties import ObjectProperty, StringProperty, OptionProperty, \
ListProperty
ListProperty, BooleanProperty
from kivy.clock import Clock
from kivy.base import EventLoop
@ -120,6 +122,15 @@ class Bubble(GridLayout):
default to 'atlas://data/images/defaulttheme/bubble_arrow'.
'''
show_arrow = BooleanProperty(True)
''' Indicates whether to show arrow.
.. versionadded:: 1.8.0
:data:`show_arrow` is a :class:`~kivy.properties.BooleanProperty`,
default to `True`.
'''
arrow_pos = OptionProperty('bottom_mid',
options=('left_top', 'left_mid', 'left_bottom', 'top_left',
'top_mid', 'top_right', 'right_top', 'right_mid',
@ -159,7 +170,7 @@ class Bubble(GridLayout):
def __init__(self, **kwargs):
self._prev_arrow_pos = None
self._arrow_layout = GridLayout(rows=1)
self._arrow_layout = BoxLayout()
self._bk_img = Image(
source=self.background_image, allow_stretch=True,
keep_ratio=False, color=self.background_color)
@ -170,7 +181,6 @@ class Bubble(GridLayout):
super(Bubble, self).__init__(**kwargs)
content.parent = None
self.add_widget(content)
self.arrow_pos = kwargs.get('arrow_pos', 'bottom_mid')
self.on_arrow_pos()
def add_widget(self, *l):
@ -202,6 +212,12 @@ class Bubble(GridLayout):
else:
content.clear_widgets()
def on_show_arrow(self, instance, value):
self._arrow_img.opacity = int(value)
def on_parent(self, instance, value):
Clock.schedule_once(self._update_arrow)
def on_pos(self, instance, pos):
lt = self.limit_to
if lt and lt is not object:
@ -240,9 +256,12 @@ class Bubble(GridLayout):
def on_arrow_pos(self, *l):
self_content = self.content
if not (self_content and self.canvas):
if not self_content:
Clock.schedule_once(self.on_arrow_pos)
return
if self_content not in self.children:
Clock.schedule_once(self.on_arrow_pos)
return
self_arrow_pos = self.arrow_pos
if self._prev_arrow_pos == self_arrow_pos:
return
@ -251,13 +270,13 @@ class Bubble(GridLayout):
self_arrow_layout = self._arrow_layout
self_arrow_layout.clear_widgets()
self_arrow_img = self._arrow_img
self_arrow_img.pos = (0, 0)
self._sctr = self._arrow_img
self.clear_widgets(do_super=True)
self_content.parent = None
self_arrow_img.size_hint = (1, None)
self_arrow_img.height = self_arrow_img.texture_size[1]
self_arrow_img.pos = 0, 0
widget_list = []
arrow_list = []
parent = self_arrow_img.parent
@ -266,9 +285,8 @@ class Bubble(GridLayout):
if self_arrow_pos[0] == 'b' or self_arrow_pos[0] == 't':
self.cols = 1
self.rows = 2
self_arrow_layout.rows = 1
self_arrow_layout.cols = 3
self.rows = 3
self_arrow_layout.orientation = 'horizontal'
self_arrow_img.width = self.width / 3
self_arrow_layout.size_hint = (1, None)
self_arrow_layout.height = self_arrow_img.height
@ -299,30 +317,30 @@ class Bubble(GridLayout):
arrow_list = (Widget(), Widget(), sctr)
widget_list = (self_arrow_layout, self_content)
elif self_arrow_pos[0] == 'l' or self_arrow_pos[0] == 'r':
self.cols = 2
self.cols = 3
self.rows = 1
self_arrow_img.width = self.height / 3
self_arrow_layout.rows = 3
self_arrow_layout.orientation = 'vertical'
self_arrow_layout.cols = 1
self_arrow_layout.size_hint = (None, 1)
self_arrow_layout.width = self_arrow_img.height
rotation = -90 if self_arrow_pos[0] == 'l' else 90
sctr = Scatter(do_translation=False,
rotation=rotation,
do_rotation=False,
do_scale=False,
size_hint=(None, None),
size=self_arrow_img.size)
self._sctr = sctr = Scatter(do_translation=False,
rotation=rotation,
do_rotation=False,
do_scale=False,
size_hint=(None, None),
size=(self_arrow_img.size))
sctr.add_widget(self_arrow_img)
lenarrow_pos = len(self_arrow_pos)
if self_arrow_pos[lenarrow_pos - 4:] == '_top':
if self_arrow_pos[-4:] == '_top':
arrow_list = (Widget(size_hint=(1, .07)),
sctr, Widget(size_hint=(1, .3)))
elif self_arrow_pos[lenarrow_pos - 4:] == '_mid':
elif self_arrow_pos[-4:] == '_mid':
arrow_list = (Widget(), sctr, Widget())
elif self_arrow_pos[lenarrow_pos - 7:] == '_bottom':
Clock.schedule_once(self._update_arrow)
elif self_arrow_pos[-7:] == '_bottom':
arrow_list = (Widget(), Widget(), sctr)
if self_arrow_pos[0] == 'l':
@ -340,3 +358,6 @@ class Bubble(GridLayout):
for widg in widget_list:
add(widg)
def _update_arrow(self, *dt):
if self.arrow_pos in ('left_mid', 'right_mid'):
self._sctr.center_y = self._arrow_layout.center_y