Advertisement
FoxboyPrower

KivyChildSizeHelp4

Aug 3rd, 2019
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.37 KB | None | 0 0
  1. from kivy.app import App
  2. from kivy.lang import Builder
  3. from kivy.uix.widget import Widget
  4. from kivy.uix.label import Label
  5. from kivy.clock import Clock
  6. from kivy.uix.boxlayout import BoxLayout
  7. from kivy.uix.gridlayout import GridLayout
  8. from kivy.properties import StringProperty
  9. from kivy.uix.textinput import TextInput
  10. from kivy.properties import BooleanProperty, ObjectProperty
  11. from lib.modules.adaptive_grid_layout import Adaptive_GridLayout
  12. #This now has StretchingLabel, which will change size to match it's dynamically changing contents
  13. #ResizingFrame is derived from the new class Adaptive_GridLayout.
  14. #So this adaptive layout itself is dynamically adding StretchingLabel
  15. Builder.load_string('''
  16. <StretchingLabel>:
  17.    padding: 10, 5
  18.    size_hint_y: None
  19.    text_size: self.width, None
  20.    height: self.texture_size[1]
  21.    group: 'test'
  22.    canvas.before:
  23.        Color:
  24.            rgba: .7, .7, .7, 1
  25.        Rectangle:
  26.            pos: self.pos
  27.            size: self.size
  28. <Resizing_GridLayout>:
  29.    cols: 1
  30.    row_force_default: True
  31. <ResizingRow_GridLayout>:
  32.    cols: 1
  33.    height: sum([c.height for c in self.children])
  34.  
  35. <ContainerBox>:
  36.    orientation: 'horizontal'
  37.  
  38.    Resizing_GridLayout:
  39.        ResizingFrame:
  40.            id: Row1
  41.            cols: 1
  42.            grow_rows: True
  43.        Adaptive_GridLayout:
  44.            id: Row2
  45.            cols: 1
  46.            grow_rows: True
  47.            Label:
  48.                height: 30
  49.                text: 'Label One'
  50.                canvas.before:
  51.                    Color:
  52.                        rgba: .4, .4, .4, 1
  53.                    Rectangle:
  54.                        pos: self.pos
  55.                        size: self.size
  56.            TextInput:
  57.                height: 30
  58.                multiline: False
  59.                write_tab: False
  60.                hint_text: 'Insert one liner'
  61.  
  62.        Adaptive_GridLayout:
  63.            id: Row3
  64.            cols: 1
  65.            grow_rows: True
  66.            Label:
  67.                height: 45
  68.                text: 'Label two'
  69.            Button:
  70.                text: 'Button One'
  71.                height: 60
  72.            GridLayout:
  73.                rows: 1
  74.                height: 25
  75.                Button:
  76.                    text: 'Button Two'
  77.                Button:
  78.                    text: 'Button three'
  79. ''')
  80.  
  81. class StretchingLabel(Label):
  82.     edit = BooleanProperty(False)
  83.     textinput = ObjectProperty(None, allownone=True)
  84.  
  85.     def on_touch_down(self, touch):
  86.         if self.collide_point(*touch.pos) and touch.is_double_tap and not self.edit:
  87.             self.edit = True
  88.         return super(StretchingLabel, self).on_touch_down(touch)
  89.  
  90.     def on_edit(self, instance, value):
  91.         if not value:
  92.             if self.textinput:
  93.                 self.remove_widget(self.textinput)
  94.             return
  95.         self.textinput = t = TextInput(
  96.             text=self.text, size_hint=(None, None),
  97.             font_size=self.font_size, font_name=self.font_name,
  98.             pos=self.pos, size=self.size, multiline=False)
  99.         self.bind(pos=t.setter('pos'), size=t.setter('size'))
  100.         self.add_widget(self.textinput)
  101.         t.bind(on_text_validate=self.on_text_validate, focus=self.on_text_focus)
  102.  
  103.     def on_text_validate(self, instance):
  104.         self.text = instance.text
  105.         self.edit = False
  106.         print(self, type(self))
  107.         print(self.parent, type(self.parent))
  108.         #Note: This is the child widget calling the layout's function that should adjust its height
  109.         self.parent.trigger_refresh_y_dimension()
  110.  
  111.     def on_text_focus(self, instance, focus):
  112.         if focus is False:
  113.             self.text = instance.text
  114.             self.edit = False
  115.  
  116. class Resizing_GridLayout(GridLayout):
  117.     def __init__(self, **kwargs):
  118.         super(Resizing_GridLayout, self).__init__(**kwargs)
  119.         Clock.schedule_once(lambda dt: self.calc_height(), timeout=0.1)
  120.  
  121.     def calc_height(self):
  122.         foo = [self.rows_minimum.update({i: x.height}) for i, x in enumerate(reversed(list(self.children)))]
  123.  
  124. class ResizingRow_GridLayout(GridLayout):
  125.     def __init__(self, **kwargs):
  126.         super(ResizingRow_GridLayout, self).__init__(**kwargs)
  127.  
  128. class ResizingFrame(Adaptive_GridLayout):
  129.     c_value = StringProperty('SomeThing goes here')
  130.  
  131.     def __init__(self, **kwargs):
  132.         super(ResizingFrame, self).__init__(**kwargs)
  133.         Clock.schedule_once(lambda dt: self.makeLabel(), timeout=0.1)
  134.  
  135.     def makeLabel(self):
  136.         c_label = StretchingLabel()
  137.         self.bind(pos=c_label.setter('pos'), width=c_label.setter('width'), c_value=c_label.setter('text'))
  138.         self.add_widget(c_label)
  139.         # this forces a property event so the label's text will be changed
  140.         Clock.schedule_once(lambda dt: self.property('c_value').dispatch(self), 0.5)
  141.         # this forces a property event so the label's pos will be changed
  142.         Clock.schedule_once(lambda dt: self.chg_text(c_label), 1)
  143.  
  144.     def chg_text(self, p_widget):
  145.         # this forces a property event so the label's text will be changed
  146.         self.property('c_value').dispatch(self)
  147.         #Note: This just seems to push the label down from the top of the screen without changing the layout's height
  148.         self.trigger_refresh_y_dimension()
  149.         #the same behaviour can be seen if you double click the stretching label and enter a change
  150.  
  151. class ContainerBox(BoxLayout):
  152.     def __init__(self, **kwargs):
  153.         super(ContainerBox, self).__init__(**kwargs)
  154.  
  155. class Nested2App(App):
  156.     def build(self):
  157.         return ContainerBox()
  158.  
  159.     def on_stop(self):
  160.         print()
  161.         print("Nested2App.on_start: starting")
  162.         f_Resizing_Grid = self.root.children[0]
  163.         f_ResizingFrame = self.root.children[0].children[2]
  164.         f_FreshLabel = f_ResizingFrame.children[0]
  165.         print("\tf_Resizing_Grid size: \t", f_Resizing_Grid.size, "\t\theight:", f_Resizing_Grid.size[1])
  166.         print("\tf_Resizing_Grid pos : \t\t", f_Resizing_Grid.pos)
  167.         print("\tf_ResizingFrame size: \t\t", f_ResizingFrame.size, "\t\theight:", f_ResizingFrame.size[1])
  168.         print("\tf_ResizingFrame pos : \t\t\t", f_ResizingFrame.pos)
  169.         print("\tf_FreshLabel size: \t\t", f_FreshLabel.size, "\t\theight:", f_FreshLabel.size[1])
  170.         print("\tf_FreshLabel pos : \t\t\t", f_FreshLabel.pos)
  171.  
  172.  
  173. if __name__ == '__main__':
  174.     Nested2App().run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement