Commits

Sven Hendriks committed 00db957

Lines can now be deleted.

Comments (0)

Files changed (7)

lyne/etc/__init__.py

Empty file added.

lyne/etc/codes.py

+# Define some constants.
+NODE_IS_SINGLETON = 0b001
+NODE_HAS_INPUTS   = 0b010
+NODE_HAS_OUTPUT   = 0b100
+

lyne/gui/diagramwidget.py

 
 import Tkinter
 
+from lyne.etc.codes import (
+    NODE_IS_SINGLETON,
+    NODE_HAS_INPUTS,
+    NODE_HAS_OUTPUT)
 
-# Define some constants.
-NODE_IS_SINGLETON = 0b001
-NODE_HAS_INPUTS   = 0b010
-NODE_HAS_OUTPUT   = 0b100
 
 # these are for internal use only.
 (_STATE_NO_ITEM_CLICKED,
         self._first_window_id_clicked = None
         self._widgets = {}
         self._lines = {}
+        self._line_ids = {}
 
         self._temp_new_line = None
         self._observers = []
                             self._handle_mouse_click)
         Tkinter.Widget.bind(self._canvas, '<Motion>', 
                             self._move_temp_new_line)
+        Tkinter.Widget.bind(self._canvas, '<Button-3>', 
+                            self._handle_right_click)
+
+    def _handle_right_click(self, event):
+        clicked_line_id = self._canvas.find_withtag(Tkinter.CURRENT)[0]
+        self._line_ids[clicked_line_id].delete()
 
     def attach_observer(self, observer):
         ''' Attach an observer.
 
         # tell the tree item widget what its canvas window id is
         widget.set_window_id(w_id)
-        widget.dgw = self
+        widget.dgw = self # XXX bah!
 
         # save a reference to the tree item widget just created
         # so we can later refer to it by a canvas window id
                     self._first_window_id_clicked]
                 second_widget = self._widgets[window_id]
 
-                # add line references to the tree item widgets
-                first_widget.attach_subwidget(second_widget)
+                ## add line references to the tree item widgets
+                ##first_widget.attach_subwidget(second_widget)
                 second_widget.attach_parentwidget(first_widget)
                 self._lines[(first_widget, second_widget)] = line
 
-                # update the underlying data model, i.e. attach the
-                # 2nd tree as subtree to the 1st tree
-                second_widget._tree.attach_subtree(
-                    first_widget._tree
-                )
+                # store references to the widgets in the line object,
+                # so when a line is deleted, we know which widgets to
+                # update
+                line.from_widget = first_widget
+                line.to_widget = second_widget
+
+                # store a reference to the line object based on the
+                # canvas line id
+                self._line_ids[line.id] = line
+
+                ## update the underlying data model, i.e. attach the
+                ## 2nd tree as subtree to the 1st tree
+                #second_widget._tree.attach_subtree(
+                #    first_widget._tree
+                #)
 
                 # reset main app's state
                 self._first_window_id_clicked = None
         self._canvas = canvas
         self._coords = (x0, y0, x1, y1)
 
+        # store, which two widgets this line connects
+        #
+        # (from) -----> (to)
+        #
+        self._from = None # the widget, this line is starting at
+        self._to   = None # the widget, this line is ending at
+
+        self._line = None # The canvas' line object
+
     def _update_line(self):
         raise NotImplementedError, 'You have to subclass from Line and ' \
             'implement this method.'
 
     def delete(self):
-        raise NotImplementedError, 'You have to subclass from Line and ' \
-            'implement this method.'
+        self._to.detach_parentwidget(self._from)
+        self._canvas.delete(self._line)
+
+    @property
+    def id(self):
+        if self._line:
+            return self._line
 
     def set_coords(self, (x0, y0, x1, y1)):
         self._coords = (x0, y0, x1, y1)
 
     coords = property(get_coords, set_coords)
 
+    def set_to(self, widget):
+        self._to = widget
+
+    def get_to(self):
+        return self._to
+
+    to_widget = property(get_to, set_to)
+
+    def set_from(self, widget):
+        self._from = widget
+
+    def get_from(self):
+        return self._from
+
+    from_widget = property(get_from, set_from)
+
+
 
 class LineWArrow(Line):
     ''' A straight line w/ an arrow at one end.
     def configure(self, *args, **kwargs):
         self._canvas.itemconfig(self._line, *args, **kwargs)
 
-    def delete(self):
-        self._canvas.delete(self._line)
 
     def _update_line(self):
         (x0, y0, x1, y1) = self.coords
             x1, y1
         )
 
-    def delete(self):
-        self._canvas.delete(self._line)
 
     def _update_line(self):
         self._coords_to_series()
                 x1, y1
             )
 
-    def delete(self):
-        self._canvas.delete(self._line)
 
     def _update_line(self):
         self._coords_to_series()
 from lyne.gui.treewidget import (
     TreeItemConstantWidget, TreeItemCounterWidget, 
     TreeItemOperatorWidget)
-from lyne.gui.diagramwidget import (
-    DiagramWidget, NODE_IS_SINGLETON,
-    NODE_HAS_INPUTS, NODE_HAS_OUTPUT)
+from lyne.gui.diagramwidget import DiagramWidget
+from lyne.etc.codes import (
+    NODE_IS_SINGLETON,
+    NODE_HAS_INPUTS,
+    NODE_HAS_OUTPUT)
+
 from lyne.lib.node import CountingNode, ConstantNode, OperatorNode
 from lyne.gui.line import LineWArrow
 

lyne/gui/treewidget.py

 
     def attach_parentwidget(self, widget):
         self._lines_in.append(widget)
+        widget._attach_subwidget(self)
+        self._tree.attach_subtree(widget._tree)
 
-    def attach_subwidget(self, widget):
+    def _attach_subwidget(self, widget):
         self._lines_out.append(widget)
 
+    def detach_parentwidget(self, widget):
+        self._lines_in.remove(widget)
+        widget._detach_subwidget(self)
+        self._tree.detach_subtree(widget._tree)
+
+    def _detach_subwidget(self, widget):
+        self._lines_out.remove(widget)
+
+
     def has_inputs(self):
         ''' Override this method if necessary.
         '''
     def _attach_parent(self, parent_tree):
         self.parents.append(parent_tree)
 
+    def detach_subtree(self, subtree):
+        if self.is_leaf:
+            raise ValueError, 'You cannot detach a subtree from a leaf node.'
+        if not isinstance(subtree, Tree):
+            raise ValueError, 'subtree must be a Tree object, not %r' % (subtree,)
+        self.subtrees.remove(subtree)
+        subtree._detach_parent(self)
+
+    def _detach_parent(self, parent_tree):
+        self.parents.remove(parent_tree)
+
     def delete(self):
         # delete node
         del self.node