text: # coding=utf-8
  
  from kivy.lang import Builder
  from kivy.properties import StringProperty, BooleanProperty, ObjectProperty, \
      NumericProperty, ListProperty, OptionProperty
  from kivy.uix.behaviors import ButtonBehavior
  from kivy.uix.boxlayout import BoxLayout
  from kivy.uix.floatlayout import FloatLayout
  from kivymd.ripplebehavior import RectangularRippleBehavior
  from kivymd.theming import ThemableBehavior
  
  Builder.load_string("""
  <SmartTile>
      _img_widget: img
      _img_overlay: img_overlay
      _box_overlay: box
  
      AsyncImage:
          id: img
          allow_stretch: root.allow_stretch
          anim_delay: root.anim_delay
          anim_loop: root.anim_loop
          color: root.img_color
          keep_ratio: root.keep_ratio
          mipmap: root.mipmap
          source: root.source
          size_hint_y: 1 if root.overlap else None
          x: root.x
          y: root.y if root.overlap or root.box_position == 'header' else box.top
  
      BoxLayout:
          id: img_overlay
          size_hint: img.size_hint
          size: img.size
          pos: img.pos
  
      BoxLayout:
          canvas:
              Color:
                  rgba: root.box_color
              Rectangle:
                  pos: self.pos
                  size: self.size
          id: box
          size_hint_y: None
          height: dp(68) if root.lines == 2 else dp(48)
          x: root.x
          y: root.y if root.box_position == 'footer' else root.y + root.height - self.height
  
  <SmartTileWithLabel>
      _img_widget: img
      _img_overlay: img_overlay
      _box_overlay: box
      _box_label: boxlabel
  
      AsyncImage:
          id: img
          allow_stretch: root.allow_stretch
          anim_delay: root.anim_delay
          anim_loop: root.anim_loop
          color: root.img_color
          keep_ratio: root.keep_ratio
          mipmap: root.mipmap
          source: root.source
          size_hint_y: 1 if root.overlap else None
          x: root.x
          y: root.y if root.overlap or root.box_position == 'header' else box.top
  
      BoxLayout:
          id: img_overlay
          size_hint: img.size_hint
          size: img.size
          pos: img.pos
  
      BoxLayout:
          canvas:
              Color:
                  rgba: root.box_color
              Rectangle:
                  pos: self.pos
                  size: self.size
          id: box
          size_hint_y: None
          height: dp(68) if root.lines == 2 else dp(48)
          x: root.x
          y: root.y if root.box_position == 'footer' else root.y + root.height - self.height
          MDLabel:
              id: boxlabel
              font_style: root.font_style
              #halign: "center"
              text: root.text
              color: root.tile_text_color
  """)
  
  
  class Tile(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior,
             BoxLayout):
      """A simple tile. It does nothing special, just inherits the right behaviors
      to work as a building block.
      """
      pass
  
  
  class SmartTile(ThemableBehavior, RectangularRippleBehavior, ButtonBehavior,
                  FloatLayout):
      """A tile for more complex needs.
  
      Includes an image, a container to place overlays and a box that can act
      as a header or a footer, as described in the Material Design specs.
      """
  
      box_color = ListProperty([0, 0, 0, 0.5])
      """Sets the color and opacity for the information box."""
  
      box_position = OptionProperty('footer', options=['footer', 'header'])
      """Determines wether the information box acts as a header or footer to the
      image.
      """
  
      lines = OptionProperty(1, options=[1, 2])
      """Number of lines in the header/footer.
  
      As per Material Design specs, only 1 and 2 are valid values.
      """
  
      overlap = BooleanProperty(True)
      """Determines if the header/footer overlaps on top of the image or not"""
  
      # Img properties
      allow_stretch = BooleanProperty(True)
      anim_delay = NumericProperty(0.25)
      anim_loop = NumericProperty(0)
      img_color = ListProperty([1, 1, 1, 1])
      keep_ratio = BooleanProperty(False)
      mipmap = BooleanProperty(False)
      source = StringProperty()
  
      _img_widget = ObjectProperty()
      _img_overlay = ObjectProperty()
      _box_overlay = ObjectProperty()
      _box_label = ObjectProperty()
  
      def reload(self):
          self._img_widget.reload()
  
      def add_widget(self, widget, index=0):
          if issubclass(widget.__class__, IOverlay):
              self._img_overlay.add_widget(widget, index)
          elif issubclass(widget.__class__, IBoxOverlay):
              self._box_overlay.add_widget(widget, index)
          else:
              super(SmartTile, self).add_widget(widget, index)
  
  
  class SmartTileWithLabel(SmartTile):
      _box_label = ObjectProperty()
  
      # MDLabel properties
      font_style = StringProperty("Caption")
      theme_text_color = StringProperty("Custom")
      tile_text_color = ListProperty([1, 1, 1, 1])
      text = StringProperty("")
      """Determines the text for the box footer/header"""
  
  
  class IBoxOverlay():
      """An interface to specify widgets that belong to to the image overlay
      in the :class:`SmartTile` widget when added as a child.
      """
  
      pass
  
  
  class IOverlay():
      """An interface to specify widgets that belong to to the image overlay
      in the :class:`SmartTile` widget when added as a child.
      """
  
      pass
  