diff --git a/SketchWidget.py b/SketchWidget.py index c719dde..b6ac4cf 100644 --- a/SketchWidget.py +++ b/SketchWidget.py @@ -16,8 +16,8 @@ class SketchWidget: self.view_width = 4.0 self.size = (1, 1) self.panning = False - self.drawingLine = None - self.drawingCircle = None + self.drawingShape = None + self.drawingConstraints = [] self.mode = '' # Configuration parameters @@ -116,15 +116,10 @@ class SketchWidget: self.drawShapes() self.drawConstraints() - if self.drawingLine is not None: - self.drawLine(self.drawingLine) - if self.drawingLine.getPt(0)[0] == self.drawingLine.getPt(1)[0]: - self.drawVertical(Vertical(self.drawingLine, 0, - self.drawingLine, 1)) - elif self.drawingLine.getPt(0)[1] == self.drawingLine.getPt(1)[1]: - self.drawHorizontal( - Horizontal(self.drawingLine, 0, - self.drawingLine, 1)) + if self.drawingShape is not None: + self.drawShape(self.drawingShape) + for c in self.drawingConstraints: + self.drawConstraint(c) if gldrawable.is_double_buffered(): gldrawable.swap_buffers() @@ -248,23 +243,9 @@ class SketchWidget: self.view_center[1] - this_pt[1] + start_pt[1]) self.panning_start = (event.x, self.size[1] - event.y) self.queue_redraw() - elif self.drawingLine is not None: - this_pt = self.screenPtToPt((event.x, self.size[1] - event.y)) - start = self.drawingLine.getPt(0) - angle = math.atan2(this_pt[1] - start[1], this_pt[0] - start[0]) - angle *= 180.0 / math.pi - def within(a, b, d): return abs(a - b) < d - def snaps_to(q): return within(angle, q, self.snap_angle) - if ((snaps_to(-180) or snaps_to(180) or snaps_to(0)) - and within(start[1], this_pt[1], - self.screenDistToDist(self.snap_dist))): - this_pt = (this_pt[0], start[1]) - elif ((snaps_to(-90) or snaps_to(90)) - and within(start[0], this_pt[0], - self.screenDistToDist(self.snap_dist))): - this_pt = (start[0], this_pt[1]) - self.drawingLine.setPt(1, this_pt) - self.queue_redraw() + elif self.drawingShape is not None: + if self.mode == 'line': + self.do_line_motion(event.x, event.y) def scroll_event(self, widget, event, data = None): if event.direction == gtk.gdk.SCROLL_UP: @@ -291,19 +272,25 @@ class SketchWidget: def drawShapes(self): for shape in self.sketch: - if isinstance(shape, Line): - self.drawLine(shape) - elif isinstance(shape, Circle): - self.drawCircle(shape) + self.drawShape(shape) + + def drawShape(self, shape): + if isinstance(shape, Line): + self.drawLine(shape) + elif isinstance(shape, Circle): + self.drawCircle(shape) def drawConstraints(self): for c in self.sketch.constraints: - if isinstance(c, Connect): - self.drawConnect(c) - elif isinstance(c, Horizontal): - self.drawHorizontal(c) - elif isinstance(c, Vertical): - self.drawVertical(c) + self.drawConstraint(c) + + def drawConstraint(self, c): + if isinstance(c, Connect): + self.drawConnect(c) + elif isinstance(c, Horizontal): + self.drawHorizontal(c) + elif isinstance(c, Vertical): + self.drawVertical(c) def drawConnect(self, con): glColor(*self.constraint_color) @@ -356,43 +343,64 @@ class SketchWidget: def set_mode(self, mode): if mode != self.mode: if self.mode == 'line': - self.drawingLine = None + self.drawingShape = None self.queue_redraw() elif self.mode == 'circle': - self.drawingCircle = None + self.drawingShape = None self.queue_redraw() self.mode = mode def do_line_left_click(self, x, y): start = self.screenPtToPt((x, self.size[1] - y)) - if self.drawingLine is not None: - self.sketch.shapes.append(self.drawingLine) - if self.drawingLine.getPt(0)[0] == self.drawingLine.getPt(1)[0]: - self.sketch.constraints.append( - Vertical(self.drawingLine, 0, - self.drawingLine, 1)) - elif (self.drawingLine.getPt(0)[1] - == self.drawingLine.getPt(1)[1]): - self.sketch.constraints.append( - Horizontal(self.drawingLine, 0, - self.drawingLine, 1)) - start = self.drawingLine.getPt(1) - self.drawingLine = Line(start[0], start[1], start[0], start[1]) + if self.drawingShape is not None: + self.sketch.shapes.append(self.drawingShape) + for c in self.drawingConstraints: + self.sketch.constraints.append(c) + self.drawingConstraints = [] + start = self.drawingShape.getPt(1) + self.drawingShape = Line(start[0], start[1], start[0], start[1]) self.queue_redraw() def do_line_right_click(self, x, y): - if self.drawingLine is not None: + if self.drawingShape is not None: # cancel line currently being drawn - self.drawingLine = None + self.drawingShape = None self.queue_redraw() + def do_line_motion(self, x, y): + this_pt = self.screenPtToPt((x, self.size[1] - y)) + start = self.drawingShape.getPt(0) + angle = math.atan2(this_pt[1] - start[1], this_pt[0] - start[0]) + angle *= 180.0 / math.pi + def within(a, b, d): return abs(a - b) < d + def snaps_to(q): return within(angle, q, self.snap_angle) + snap_dist = self.screenDistToDist(self.snap_dist) + if ((snaps_to(-180) or snaps_to(180) or snaps_to(0)) + and within(start[1], this_pt[1], snap_dist)): + this_pt = (this_pt[0], start[1]) + if not (len(self.drawingConstraints) > 0 + and isinstance(self.drawingConstraints[0], Horizontal)): + c = Horizontal(self.drawingShape, 0, self.drawingShape, 1) + self.drawingConstraints = [c] + elif ((snaps_to(-90) or snaps_to(90)) + and within(start[0], this_pt[0], snap_dist)): + this_pt = (start[0], this_pt[1]) + if not (len(self.drawingConstraints) > 0 + and isinstance(self.drawingConstraints[0], Vertical)): + c = Vertical(self.drawingShape, 0, self.drawingShape, 1) + self.drawingConstraints = [c] + else: + self.drawingConstraints = [] + self.drawingShape.setPt(1, this_pt) + self.queue_redraw() + def do_circle_left_click(self, x, y): pt = self.screenPtToPt((x, self.size[1] - y)) - if self.drawingCircle is None: - self.drawingCircle = Circle(pt[0], pt[1], 0) + if self.drawingShape is None: + self.drawingShape = Circle(pt[0], pt[1], 0) def do_circle_right_click(self, x, y): - if self.drawingCircle is not None: + if self.drawingShape is not None: # cancel circle currently being drawn - self.drawingCircle = None + self.drawingShape = None self.queue_redraw()