def test_split_single(canvas, line): # Start with 2 handles & 1 port, after split: expect 3 handles & 2 ports assert len(line.handles()) == 2 assert len(line.ports()) == 1 old_port = line.ports()[0] h1, h2 = line.handles() assert h1.pos == old_port.start assert h2.pos == old_port.end segment = Segment(line, canvas) handles, ports = segment.split_segment(0) handle = handles[0] assert 1 == len(handles) assert (50, 50) == handle.pos.pos assert 3 == len(line.handles()) assert 2 == len(line.ports()) # New handle is between old handles assert handle == line.handles()[1] # The old port is deleted assert old_port not in line.ports() # check ports order p1, p2 = line.ports() h1, h2, h3 = line.handles() assert h1.pos == p1.start assert h2.pos == p1.end assert h2.pos == p2.start assert h3.pos == p2.end
def create_canvas(canvas, title): # Setup drawing window window = Gtk.Window() window.set_title(title) window.set_default_size(400, 400) view = GtkView() #Gtk widget view.painter = DefaultPainter() view.canvas = canvas win_box = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL) #added Gtk box to Gtk window window.add(win_box) win_box.pack_start(view, True, True, 0) #added "view" widget to the box # Draw gaphas box b2 = Box(60, 60) b2.min_width = 40 b2.min_height = 50 b2.matrix.translate(170, 170) canvas.add(b2) # Draw gaphas line line = Line() line.matrix.translate(100, 60) canvas.add(line) line.handles()[1].pos = (30, 30) segment = Segment(line, canvas) segment.split_segment(0) window.show_all() window.connect("destroy", Gtk.main_quit)
def test_orthogonal_horizontal_undo(revert_undo, undo_fixture): """Test orthogonal line constraints bug (#107). """ canvas = Canvas() line = Line() canvas.add(line) assert not line.horizontal assert len(canvas.solver._constraints) == 0 segment = Segment(line, None) segment.split_segment(0) line.orthogonal = True assert 2 == len(canvas.solver._constraints) del undo_fixture[2][:] # Clear undo_list line.horizontal = True assert 2 == len(canvas.solver._constraints) undo_fixture[0]() # Call undo assert not line.horizontal assert 2 == len(canvas.solver._constraints) line.horizontal = True assert line.horizontal assert 2 == len(canvas.solver._constraints)
def get_handle_at_point(self, pos, split=True): view = self.view connection_v = view.hovered_item handle = None end_handles = connection_v.end_handles(include_waypoints=True) if len(end_handles) == 4: from_handle, from_handle_waypoint, to_handle_waypoint, to_handle = end_handles cur_pos = self.view.get_matrix_v2i(connection_v).transform_point( *pos) max_distance = connection_v.line_width / 2. distance_from_segment, _ = distance_line_point( from_handle.pos, from_handle_waypoint.pos, cur_pos) if distance_from_segment < max_distance: return connection_v, from_handle distance_to_segment, _ = distance_line_point( to_handle.pos, to_handle_waypoint.pos, cur_pos) if distance_to_segment < max_distance: return connection_v, to_handle if split: try: segment = Segment(self.item, self.view) except TypeError: pass else: handle = segment.split(pos) if not handle: connection_v, handle = super(SegmentHandleFinder, self).get_handle_at_point(pos) return connection_v, handle
def test_orthogonal_horizontal_undo(self): """Test orthogonal line constraints bug (#107) """ canvas = Canvas() line = Line() canvas.add(line) assert not line.horizontal assert len(canvas.solver._constraints) == 0 segment = Segment(line, None) segment.split_segment(0) line.orthogonal = True self.assertEqual(2, len(canvas.solver._constraints)) after_ortho = set(canvas.solver._constraints) del undo_list[:] line.horizontal = True self.assertEqual(2, len(canvas.solver._constraints)) undo() self.assertFalse(line.horizontal) self.assertEqual(2, len(canvas.solver._constraints)) line.horizontal = True self.assertTrue(line.horizontal) self.assertEqual(2, len(canvas.solver._constraints))
def test_orthogonal_horizontal_undo(self): """Test orthogonal line constraints bug (#107) """ canvas = Canvas() line = Line() canvas.add(line) assert not line.horizontal assert len(canvas.solver._constraints) == 0 segment = Segment(line, None) segment.split_segment(0) line.orthogonal = True self.assertEquals(2, len(canvas.solver._constraints)) after_ortho = set(canvas.solver._constraints) del undo_list[:] line.horizontal = True self.assertEquals(2, len(canvas.solver._constraints)) undo() self.assertFalse(line.horizontal) self.assertEquals(2, len(canvas.solver._constraints)) line.horizontal = True self.assertTrue(line.horizontal) self.assertEquals(2, len(canvas.solver._constraints))
def test_orthogonal_line_undo(revert_undo, undo_fixture): """Test orthogonal line undo. """ canvas = Canvas() line = Line() canvas.add(line) segment = Segment(line, None) segment.split_segment(0) # Start with no orthogonal constraints assert len(canvas.solver._constraints) == 0 line.orthogonal = True # Check orthogonal constraints assert 2 == len(canvas.solver._constraints) assert 3 == len(line.handles()) undo_fixture[0]() # Call undo assert not line.orthogonal assert 0 == len(canvas.solver._constraints) assert 2 == len(line.handles())
def __init__(self, canvas): Gtk.Window.__init__(self, title="Hello World") #connect the button widget #connect to its clicked signal #add is as child to the top-level window #self.button = Gtk.Button(label="Click Here") #self.button.connect("clicked", self.on_button_clicked) self.label = Gtk.Label() self.view = GtkView() #Gtk widget self.view.painter = DefaultPainter() self.view.canvas = canvas self.win_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) self.add(self.win_box) self.win_box.pack_start(self.label, True, True, 0) self.win_box.pack_start(self.view, True, True, 0) self.b2 = Box(60, 60) self.b2.min_width = 40 self.b2.min_height = 50 self.b2.matrix.translate(170, 170) canvas.add(self.b2) # Draw gaphas line self.line = Line() self.line.matrix.translate(100, 60) canvas.add(self.line) self.line.handles()[1].pos = (30, 30) self.segment = Segment(self.line, canvas) self.segment.split_segment(0)
def test_add_segment_to_line(canvas, connections): line = Line(connections) canvas.add(line) segment = Segment(line, canvas) assert 2 == len(line.handles()) segment.split((5, 5)) assert 3 == len(line.handles())
def _on_orthogonal_change(self, button): if len(self.item.handles()) < 3: line_segment = Segment(self.item, None) line_segment.split_segment(0) active = button.get_active() self.item.orthogonal = active self.item.canvas.update_now() self.horizontal_button.set_sensitive(active)
def test_merge_orthogonal_line(canvas, connections): line = Line(connections) canvas.add(line) Segment(line, canvas).split_segment(0) line.orthogonal = True line.handles()[2].pos = (100, 0) line.handles()[1].pos = (100, 0) with pytest.raises(ValueError): Segment(line, canvas).merge_segment(1)
def test_line_merge_segment(diagram, undo_manager, event_manager): with Transaction(event_manager): line = diagram.create(LinePresentation) segment = Segment(line, diagram) segment.split((5, 5)) head_handle = line.head tail_handle = line.tail with Transaction(event_manager): segment = Segment(line, diagram) segment.merge_segment(0) assert len(line.handles()) == 2 assert line.head is head_handle assert line.tail is tail_handle undo_manager.undo_transaction() assert len(line.handles()) == 3 assert line.head is head_handle assert line.tail is tail_handle undo_manager.redo_transaction() assert len(line.handles()) == 2
def unselect(self): self.view.canvas.solver.solve() item = self.item handle = self.handle handles = item.handles() # don't merge using first or last handle if handles[0] is handle or handles[-1] is handle: return True handle_index = handles.index(handle) segment = handle_index - 1 # cannot merge starting from last segment if segment == len(item.ports()) - 1: segment = -1 assert 0 <= segment < len(item.ports()) - 1 before = handles[handle_index - 1] after = handles[handle_index + 1] d, p = distance_line_point(before.pos, after.pos, handle.pos) # Checks how far the waypoint is from an imaginary line connecting the previous and next way/end point # If it is close, the two segments are merged to one merge_distance = item.line_width * 4 if d < merge_distance: assert len(self.view.canvas.solver._marked_cons) == 0 Segment(item, self.view).merge_segment(segment) if handle: item.request_update()
def create_canvas(c=None): if not c: c = Canvas() b = MyBox(c.connections) b.min_width = 20 b.min_height = 30 b.matrix.translate(20, 20) b.width = b.height = 40 c.add(b) bb = Box(c.connections) bb.matrix.translate(10, 10) c.add(bb, parent=b) bb = Box(c.connections) bb.matrix.rotate(math.pi / 1.567) c.add(bb, parent=b) circle = Circle() h1, h2 = circle.handles() circle.radius = 20 circle.matrix.translate(50, 160) c.add(circle) pb = Box(c.connections, 60, 60) pb.min_width = 40 pb.min_height = 50 pb.matrix.translate(100, 20) c.add(pb) ut = UnderlineText() ut.matrix.translate(100, 130) c.add(ut) t = MyText("Single line") t.matrix.translate(100, 170) c.add(t) line = MyLine(c.connections) c.add(line) line.handles()[1].pos = (30, 30) segment = Segment(line, c) segment.split_segment(0, 3) line.matrix.translate(30, 80) line.orthogonal = True return c
def test_merge_first_single(line, canvas, view): """Test single line merging starting from 1st segment.""" line.handles()[1].pos = (20, 0) segment = Segment(line, canvas) segment.split_segment(0) # We start with 3 handles and 2 ports, after merging 2 handles and 1 port # are expected assert len(line.handles()) == 3 assert len(line.ports()) == 2 old_ports = line.ports()[:] segment = Segment(line, canvas) handles, ports = segment.merge_segment(0) # Deleted handles and ports assert 1 == len(handles) assert 2 == len(ports) # Handles and ports left after segment merging assert 2 == len(line.handles()) assert 1 == len(line.ports()) assert handles[0] not in line.handles() assert ports[0] not in line.ports() assert ports[1] not in line.ports() # Old ports are completely removed as they are replaced by new one port assert old_ports == ports # Finally, created port shall span between first and last handle port = line.ports()[0] assert (0, 0) == port.start.pos assert (20, 0) == port.end.pos
def test_split_multiple(canvas, line): """Test multiple line splitting.""" line.handles()[1].pos = (20, 16) handles = line.handles() old_ports = line.ports()[:] # Start with two handles, split into 4 segments: expect 3 new handles assert len(handles) == 2 assert len(old_ports) == 1 segment = Segment(line, canvas) handles, ports = segment.split_segment(0, count=4) assert 3 == len(handles) h1, h2, h3 = handles assert (5, 4) == h1.pos.pos assert (10, 8) == h2.pos.pos assert (15, 12) == h3.pos.pos # New handles between old handles assert 5 == len(line.handles()) assert h1 == line.handles()[1] assert h2 == line.handles()[2] assert h3 == line.handles()[3] assert 4 == len(line.ports()) # The old port is deleted assert old_ports[0] not in line.ports() # Check ports order p1, p2, p3, p4 = line.ports() h1, h2, h3, h4, h5 = line.handles() assert h1.pos == p1.start assert h2.pos == p1.end assert h2.pos == p2.start assert h3.pos == p2.end assert h3.pos == p3.start assert h4.pos == p3.end assert h4.pos == p4.start assert h5.pos == p4.end
def test_orthogonal_line_split(canvas, line): """Test orthogonal line splitting.""" # Start with no orthogonal constraints assert len(line._orthogonal_constraints) == 0 segment = Segment(line, canvas) segment.split_segment(0) line.orthogonal = True # Check orthogonal constraints assert 2 == len(line._orthogonal_constraints) assert 3 == len(line.handles()) Segment(line, canvas).split_segment(0) # 3 handles and 2 ports are expected # 2 constraints keep the self.line orthogonal assert 3 == len(line._orthogonal_constraints) assert 4 == len(line.handles()) assert 3 == len(line.ports())
def test_constraints_after_merge(canvas, connections, line, view): """Test if constraints are recreated after line merge.""" line2 = Line(connections) canvas.add(line2) head = line2.handles()[0] canvas.request_update(line) canvas.request_update(line2) view.update() HandleMove(line2, head, view).connect((25, 25)) cinfo = connections.get_connection(head) assert line == cinfo.connected segment = Segment(line, canvas) segment.split_segment(0) assert len(line.handles()) == 3 orig_constraint = cinfo.constraint segment.merge_segment(0) assert len(line.handles()) == 2 h1, h2 = line.handles() # Connection shall be reconstrained between 1st and 2nd handle cinfo = canvas.connections.get_connection(head) assert orig_constraint != cinfo.constraint
def test_merge_multiple(canvas, line): """Test multiple line merge.""" line.handles()[1].pos = (20, 16) segment = Segment(line, canvas) segment.split_segment(0, count=3) # Start with 4 handles and 3 ports, merge 3 segments assert len(line.handles()) == 4 assert len(line.ports()) == 3 handles, ports = segment.merge_segment(0, count=3) assert 2 == len(handles) assert 3 == len(ports) assert 2 == len(line.handles()) assert 1 == len(line.ports()) assert not set(handles).intersection(set(line.handles())) assert not set(ports).intersection(set(line.ports())) # Finally, the created port shall span between first and last handle port = line.ports()[0] assert (0, 0) == port.start.pos assert (20, 16) == port.end.pos
def test_orthogonal_line_undo(self): """Test orthogonal line undo """ canvas = Canvas() line = Line() canvas.add(line) segment = Segment(line, None) segment.split_segment(0) # start with no orthogonal constraints assert len(canvas.solver._constraints) == 0 line.orthogonal = True # check orthogonal constraints self.assertEqual(2, len(canvas.solver._constraints)) self.assertEqual(3, len(line.handles())) undo() self.assertFalse(line.orthogonal) self.assertEqual(0, len(canvas.solver._constraints)) self.assertEqual(2, len(line.handles()))
def test_orthogonal_line_undo(self): """Test orthogonal line undo """ canvas = Canvas() line = Line() canvas.add(line) segment = Segment(line, None) segment.split_segment(0) # start with no orthogonal constraints assert len(canvas.solver._constraints) == 0 line.orthogonal = True # check orthogonal constraints self.assertEquals(2, len(canvas.solver._constraints)) self.assertEquals(3, len(line.handles())) undo() self.assertFalse(line.orthogonal) self.assertEquals(0, len(canvas.solver._constraints)) self.assertEquals(2, len(line.handles()))
def test_constraints_after_split(canvas, connections, line, view): """Test if constraints are recreated after line split.""" # Connect line2 to self.line line2 = Line(connections) canvas.add(line2) head = line2.handles()[0] HandleMove(line2, head, view).connect((25, 25)) cinfo = canvas.connections.get_connection(head) assert line == cinfo.connected orig_constraint = cinfo.constraint Segment(line, canvas).split_segment(0) assert len(line.handles()) == 3 h1, h2, h3 = line.handles() cinfo = canvas.connections.get_connection(head) assert cinfo.constraint != orig_constraint
class ConnectorTool(BlockConnectTool): """ This is a port-connecting handle tool that additionally initiates the creation of connector lines when the user is withing gluing distance of an as-yet-unconnected Port. """ def __init__(self): self._handle_index_glued = 0 self._handle_index_dragged = 1 self.grabbed_handle = None self.grabbed_item = None self._new_item = None self.motion_handle = None def on_button_press(self, event): glueitem, glueport, gluepos = self.view.get_port_at_point( (event.x, event.y), distance=10, exclude=[]) line, handle = self.view.get_handle_at_point((event.x, event.y)) try: if glueport and hasattr(glueport, "point"): self.toggle_highlight_ports(glueport.portinstance) self.line = self._create_line((event.x, event.y)) self._new_item = self.line h_glue = self.line.handles()[self._handle_index_glued] conn = Connector(self.line, h_glue) sink = ConnectionSink(glueitem, glueport) conn.connect_port(sink) h_drag = self.line.handles()[self._handle_index_dragged] self.grab_handle(self.line, h_drag) return True except Exception as e: print 'Connection Failed, Disconnect/Connect the last Connection again: /n', e def _create_line(self, (x, y)): canvas = self.view.canvas line = BlockLine() segment = Segment(line, view=self.view) canvas.add(line) x, y = self.view.get_matrix_v2i(line).transform_point(x, y) line.matrix.translate(x, y) line.fuzziness = 1.0 return line
def test_ports_after_split(canvas, line): """Test ports removal after split.""" line.handles()[1].pos = (20, 16) segment = Segment(line, canvas) segment.split_segment(0) handles = line.handles() old_ports = line.ports()[:] # Start with 3 handles and 2 ports assert len(handles) == 3 assert len(old_ports) == 2 # Split 1st segment again: 1st port should be deleted, but 2nd one should # remain untouched segment.split_segment(0) assert old_ports[0] not in line.ports() assert old_ports[1] == line.ports()[2]
def test_orthogonal_line_merge(canvas, connections, line): """Test orthogonal line merging.""" assert 0 == len(connections.solver._constraints) line.handles()[-1].pos = 100, 100 segment = Segment(line, canvas) # Prepare the self.line for merging segment.split_segment(0) segment.split_segment(0) line.orthogonal = True assert 3 == len(connections.solver._constraints) assert 4 == len(line.handles()) assert 3 == len(line.ports()) # Test the merging segment.merge_segment(0) assert 2 == len(connections.solver._constraints) assert 3 == len(line.handles()) assert 2 == len(line.ports())
def on_split_line_clicked(button): selection = view.selection if isinstance(selection.focused_item, Line): segment = Segment(selection.focused_item, canvas) segment.split_segment(0)
def create_canvas(c=None): if not c: c = Canvas() b = MyBox() b.min_width = 20 b.min_height = 30 b.matrix = (1.0, 0.0, 0.0, 1, 20, 20) b.width = b.height = 40 c.add(b) bb = Box() bb.matrix = (1.0, 0.0, 0.0, 1, 10, 10) c.add(bb, parent=b) fl = FatLine() fl.height = 50 fl.matrix.translate(100, 100) c.add(fl) circle = Circle() h1, h2 = circle.handles() circle.radius = 20 circle.matrix.translate(50, 100) c.add(circle) # AJM: extra boxes: bb = Box() bb.matrix.rotate(math.pi / 1.567) c.add(bb, parent=b) # for i in xrange(10): # bb = Box() # print('box', bb) # bb.matrix.rotate(math.pi/4.0 * i / 10.0) # c.add(bb, parent=b) b = PortoBox(60, 60) b.min_width = 40 b.min_height = 50 b.matrix.translate(55, 55) c.add(b) t = UnderlineText() t.matrix.translate(70, 30) c.add(t) t = MyText("Single line") t.matrix.translate(70, 70) c.add(t) l = MyLine() c.add(l) l.handles()[1].pos = (30, 30) segment = Segment(l, view=None) segment.split_segment(0, 3) l.matrix.translate(30, 60) l.orthogonal = True off_y = 0 for align_x in (-1, 0, 1): for align_y in (-1, 0, 1): t = MyText( f"Aligned text {align_x:d}/{align_y:d}", align_x=align_x, align_y=align_y, ) t.matrix.translate(120, 200 + off_y) off_y += 30 c.add(t) t = MyText("Multiple\nlines", multiline=True) t.matrix.translate(70, 100) c.add(t) return c
def on_clicked(button): if isinstance(view.focused_item, Line): segment = Segment(view.focused_item, view) segment.split_segment(0) view.queue_draw_item(view.focused_item)
def create_canvas(c=None): if not c: c = Canvas() b=MyBox() b.min_width = 20 b.min_height = 30 print 'box', b b.matrix=(1.0, 0.0, 0.0, 1, 20,20) b.width = b.height = 40 c.add(b) bb=Box() print 'box', bb bb.matrix=(1.0, 0.0, 0.0, 1, 10,10) c.add(bb, parent=b) fl = FatLine() fl.height = 50 fl.matrix.translate(100, 100) c.add(fl) circle = Circle() h1, h2 = circle.handles() circle.radius = 20 circle.matrix.translate(50, 100) c.add(circle) # AJM: extra boxes: bb = Box() print 'box', bb bb.matrix.rotate(math.pi/4.) c.add(bb, parent=b) # for i in xrange(10): # bb=Box() # print 'box', bb # bb.matrix.rotate(math.pi/4.0 * i / 10.0) # c.add(bb, parent=b) b = PortoBox(60, 60) b.min_width = 40 b.min_height = 50 b.matrix.translate(55, 55) c.add(b) t = UnderlineText() t.matrix.translate(70,30) c.add(t) t = MyText('Single line') t.matrix.translate(70,70) c.add(t) l = MyLine() c.add(l) l.handles()[1].pos = (30, 30) segment = Segment(l, view=None) segment.split_segment(0, 3) l.matrix.translate(30, 60) l.orthogonal = True off_y = 0 for align_x in (-1, 0, 1): for align_y in (-1, 0, 1): t=MyText('Aligned text %d/%d' % (align_x, align_y), align_x=align_x, align_y=align_y) t.matrix.translate(120, 200 + off_y) off_y += 30 c.add(t) t=MyText('Multiple\nlines', multiline = True) t.matrix.translate(70,100) c.add(t) return c
def revert(self, target): segment = Segment(target, target.diagram) segment.split_segment(self.segment, self.count)
def test_params_error_exc(canvas, connections): """Test parameter error exceptions.""" line = Line(connections) segment = Segment(line, canvas) # There is only 1 segment with pytest.raises(ValueError): segment.split_segment(-1) line = Line(connections) segment = Segment(line, canvas) with pytest.raises(ValueError): segment.split_segment(1) line = Line(connections) # Can't split into one or less segment :) segment = Segment(line, canvas) with pytest.raises(ValueError): segment.split_segment(0, 1)
def test_segment_fails_for_element(canvas, connections): item = Element(connections) with pytest.raises(TypeError): Segment(canvas, item)
def test_params_errors(canvas, connections, num_segments): """Test parameter error exceptions.""" line = Line(connections) canvas.add(line) segment = Segment(line, canvas) with pytest.raises(ValueError): if isinstance(num_segments, tuple): segment.split_segment(0) segment.merge_segment(num_segments[0], num_segments[1]) elif num_segments == 0: assert 2 == len(line.handles()) segment.merge_segment(0) else: segment.split_segment(0) segment.merge_segment(num_segments)