title: Kivy: Adding a toolbar to my app
body: <p>I'm trying to implement a simple toolbar. Right now I am stuck on the basics.</p>
  
  <p><strong>My current goal:</strong></p>
  
  <p>A toolbar which sits on the side of the app, and allows the user to add widgets to the main gui.</p>
  
  <p><strong>My current progress:</strong></p>
  
  <p>A white rectangle that sits in the correct location. Buttons which add the correct widgets. I need to position the buttons correctly.</p>
  
  <p>It looks like ideally I'd like to use some kind of layout (Box?). However I can't work out how to embed this just on the rectangle.</p>
  
  <p>I also don't know why what I've done so far doesn't work.</p>
  
  <p><strong>Current Code:</strong></p>
  
  <p>I'll attach a working piece of code, where the buttons aren't positioned correctly. I will happily provide minimal code if this is more helpful (just ask :) ).</p>
  
  <p><em>Python code:</em></p>
  
  <pre><code>from kivy.app import App
  from kivy.uix.widget import Widget
  from kivy.uix.button import Button
  from kivy.uix.boxlayout import BoxLayout
  from kivy.properties import Property, NumericProperty, ReferenceListProperty,\
      ObjectProperty
  from kivy.graphics import Color, Ellipse, Line
  from kivy.clock import Clock
  import math
  
  class GraphToolBar(Widget):
  
      def add_buttons(self, game):
          createNodeButton = Button(text = 'CreateNode', pos = (self.x,game.height))
          createEdgeButton = Button(text = 'CreateEdge', pos = (self.x,0.8*game.height))
  
          self.add_widget(createNodeButton)
          self.add_widget(createEdgeButton)
  
          def createNode(instance):
              newNode = GraphNode()
              game.add_widget(newNode)
              print "Node Created"
  
          def createEdge(instance):
              newEdge = GraphEdge()
              game.add_widget(newEdge)
              print "Edge Created"
  
          createNodeButton.bind(on_press=createNode)
          createEdgeButton.bind(on_press=createEdge)
      pass
  
  
  
  class GraphInterface(Widget): 
      node = ObjectProperty(None)
      toolbar = ObjectProperty(None)
  
      def update(self, dt):
          for widget in self.children:
              if isinstance(widget, GraphEdge) and widget.collide_widget(self):
                  widget.check_connection()
  
      def construct_toolbar(self):
          self.toolbar.add_buttons(self)
  
  class GraphNode(Widget):
      r = NumericProperty(1.0)
  
      def __init__(self, **kwargs):
          self.size= [50,50]
          self.pos = [175,125]
          self.r = 1.0
          super(GraphNode, self).__init__(**kwargs)
  
      def on_touch_down(self, touch):
          if self.collide_point(*touch.pos):
              if touch.grab_current == None:
                  self.r = 0.6
                  touch.grab(self)             
                  return True                
          return super(GraphNode, self).on_touch_down(touch)
  
      def on_touch_move(self, touch):
          if touch.grab_current is self:
              self.pos=[touch.x-25,touch.y-25]
          for widget in self.parent.children:
              if isinstance(widget, GraphEdge) and widget.collide_widget(self):
                  widget.snap_to_node(self)
  
  
      def on_touch_up(self, touch):
          if touch.grab_current is self:
              touch.ungrab(self)
              self.r = 1.0
              # and finish up here
  
      pass
  
  class GraphEdge(Widget):
      r = NumericProperty(1.0)
      connected_point_0 = Property(False)
      connected_point_1 = Property(False)
      connected_node_0 = Widget()
      connected_node_1 = Widget()
  
      def __init__(self, **kwargs):
          super(GraphEdge, self).__init__(**kwargs)
          with self.canvas:
              Color(self.r, 1, 1, 1)
              self.line = Line(points=[100, 200, 200, 200], width = 2.0, close = True)
              self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
  
  
      def snap_to_node(self, node):
          if self.collide_widget(node):
              distance_from_0 = [math.sqrt(((self.line.points[0]-node.center[0])**2 + (self.line.points[1]-node.center[1])**2))]*2
              distance_from_1 = [math.sqrt(((self.line.points[2]-node.center[0])**2 + (self.line.points[3]-node.center[1])**2))]*2
  
              if distance_from_0 &lt; distance_from_1:
                  if (self.connected_point_0 is False):
                      print "collision"                
                      if node is not self.connected_node_1:
                          self.connected_point_0 = True
                          self.connected_node_0 = node
                          self.line.points = node.center + self.line.points[2:]
                          self.size = [math.sqrt(((self.line.points[0]-self.line.points[2])**2 + (self.line.points[1]-self.line.points[3])**2))]*2
                          self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
                  return True
  
              elif distance_from_1 &lt; distance_from_0:
                  if (self.connected_point_1 is False):
                      print "collision"
                      if node is not self.connected_node_0:
                          self.connected_point_1 = True
                          self.connected_node_1 = node
                          self.line.points =  self.line.points[:-2] + node.center
                          self.size = [math.sqrt(((self.line.points[0]-self.line.points[2])**2 + (self.line.points[1]-self.line.points[3])**2))]*2
                          self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
                      return True
          pass
  
      def check_connection(self):
          if self.connected_point_0:
              self.line.points = self.connected_node_0.center + self.line.points[2:] 
              self.size = [math.sqrt(((self.line.points[0]-self.line.points[2])**2 + (self.line.points[1]-self.line.points[3])**2))]*2
              self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
              self.r = self.connected_node_1.r
  
          if self.connected_point_1:
              self.line.points = self.line.points[:2] + self.connected_node_1.center
              self.size = [math.sqrt(((self.line.points[0]-self.line.points[2])**2 + (self.line.points[1]-self.line.points[3])**2))]*2
              self.center = ((self.line.points[0]+self.line.points[2])/2,(self.line.points[1]+self.line.points[3])/2)
              self.r = self.connected_node_1.r
  
  class GraphApp(App):
  
      def build(self):
          game = GraphInterface()
  
          game.construct_toolbar()
  
          Clock.schedule_interval(game.update, 1.0/20.0)  
          return game
  
  if __name__ == '__main__':
  
      GraphApp().run()
  </code></pre>
  
  <p><em>.kv file:</em></p>
  
  <pre><code>#:kivy 1.0.9
  
  &lt;GraphInterface&gt;:
      node: graph_node
      toolbar: graph_toolbar
  
      GraphNode:
          id: graph_node
          center: self.parent.center  
  
      GraphToolBar:
          id: graph_toolbar
          size: root.width * 2/10, root.height
          x: root.width * 8/10
          y: 0
  
  &lt;GraphToolBar&gt;:
      size: 10,100
  
      canvas:
          Color:
              rgba: (1,1,1,1)
          Rectangle:
              size: self.size
              pos: self.pos
  
  &lt;GraphNode&gt;:
      size: 50, 50
      canvas:
          Color:
              rgba: (root.r,1,1,1)
          Ellipse:
              pos: self.pos
              size: self.size
  
  
  &lt;GraphEdge&gt;:
      size: self.size
      center: self.center
      canvas:
          Color:
              rgba: (root.r,1,1,1)
          Line:
              width: 2.0
              close: True
  </code></pre>
  
  <p>Thanks for your patience!</p>