def button_at(self, mouse_pos): white_button = QPainterPath() white_button.addEllipse( QPointF(self.contentsRect().width() - 50, self.contentsRect().height() - 50), 35, 35) if white_button.contains(mouse_pos): return True, "W" black_button = QPainterPath() black_button.addEllipse(QPointF(self.contentsRect().width() - 50, 50), 35, 35) if black_button.contains(mouse_pos): return True, "B" return False, ""
def _write(self, shapes, svg_file, width, height, stroke_colour = None, stroke_width = None, background_colour = None): svg_file.write('<?xml version="1.0" standalone="no"?>\n' '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n' ' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n') svg_file.write('<svg width="%.6fcm" height="%.6fcm" ' % (width, height)) svg_file.write('viewBox="%.6f %.6f %.6f %.6f" ' 'xmlns="http://www.w3.org/2000/svg" ' 'version="1.1">\n' % (0.0, 0.0, width, height)) if stroke_width is None: stroke_width = "0.1%" if background_colour is not None: svg_file.write('<polygon fill="%s" ' % background_colour) svg_file.write('points="%.6f,%.6f %.6f,%.6f %.6f,%.6f %.6f,%.6f" />\n' % ( 0.0, 0.0, width, 0.0, width, height, 0.0, height)) path = QPainterPath() shapes.reverse() new_shapes = {} for points, polygon in shapes: rgb = self.parts.colours.get(polygon.colour, "#ffffff") new_points = [] for x, y in points: new_points.append(QPointF(x + width/2.0, height/2.0 - y)) new_polygon = QPolygonF(new_points) new_path = QPainterPath() new_path.addPolygon(new_polygon) if path.contains(new_path): continue inter = path.intersected(new_path) remaining = new_path.subtracted(inter) # Combine the new path with the accumulated path and simplify # the result. path = path.united(new_path) path = path.simplified() piece_dict = new_shapes.setdefault(polygon.piece, {}) colour_path = piece_dict.get(polygon.colour, QPainterPath()) piece_dict[polygon.colour] = colour_path.united(remaining) for piece, piece_dict in new_shapes.items(): svg_file.write('<g>\n') for colour, colour_path in piece_dict.items(): if colour_path.isEmpty(): continue rgb = self.parts.colours.get(colour, "#ffffff") shape = '<path style="fill:%s; opacity:%f" d="' % ( rgb, self._opacity_from_colour(colour)) i = 0 in_path = False while i < colour_path.elementCount(): p = colour_path.elementAt(i) if p.type == QPainterPath.MoveToElement: if in_path: shape += 'Z ' shape += 'M %.6f %.6f ' % (p.x, p.y) in_path = True elif p.type == QPainterPath.LineToElement: shape += 'L %.6f %.6f ' % (p.x, p.y) i += 1 if in_path: shape += 'Z' shape += '" />\n' svg_file.write(shape) svg_file.write('</g>\n') svg_file.write("</svg>\n") svg_file.close()
class CellItem(QGraphicsItem): """ Class representing a cell on the screen. :IVariables: cell_id : int Identifier of the cell hover : bool True if the cell is being hovered over hover_contour : bool True if the contour of the cell is being hovered over hover_side : int|None Number of the side being hovered over sides : list of `QPainterPath` shape of each side polygon_id : list of int list of point ids for the polygon walls : `TimedWallShapes` Ref to the structure defining the shape of the walls at the current time points : dict of int * QPointF Ref to the structure holding the position of all the points at the current time current : bool True if the cell is the currently selected one drag_line : bool True if one of the side is being dragged p1 : int Start of a division line p2 : int End of a division line """ def __init__(self, scale, glob_scale, cell_id, polygon, points, walls, parent=None): QGraphicsItem.__init__(self, parent) self.cell_id = cell_id self.setZValue(2.5) self.setAcceptsHoverEvents(True) self.setSelectable(False) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.hover = False self.hover_contour = False self.hover_side = None self.scale = scale self.glob_scale = glob_scale self.setToolTip(unicode(cell_id)) self.polygon_id = polygon self.walls = walls self.sides = [] self.points = points self.current = False self.drag_line = False self.dragging_line = False self.editable = False self.p1 = None self.p2 = None self.setGeometry() def __del__(self): cleanQObject(self) def setCurrent(self, value=True): """ Set this cell as the current one (i.e. on top and different color) """ if value: self.setZValue(2.8) else: self.setZValue(2.5) self.current = value self.update() def setDivisionLine(self, p1, p2): """ Set the line from p1 to p2 to be a division line (i.e. different representation) """ self.p1 = p1 self.p2 = p2 self.setGeometry() def setGeometry(self): """ Read the parameters that define the geometry of the point """ params = parameters.instance self.setEditable(params.is_cell_editable) points = self.points polygon_id = self.polygon_id polygon = [ points[pt].pos() if pt in points else None for pt in polygon_id ] non_none_cnt = len([p for p in polygon if p is not None]) if non_none_cnt == 0: self.rect = QRectF() self.bounding_rect = QRectF() self.setVisible(False) return self.setVisible(True) # First, check if this is a "simple" cell walls = self.walls real_polygon = [pid for pid in polygon_id if pid in points] #sides = [ walls[real_polygon[i], real_polygon[(i+1)%len(real_polygon)]] for i in range(len(real_polygon)) ] sides = [None] * len(polygon) self.sides = sides real_scale_x = self.scale[0] / self.glob_scale real_scale_y = self.scale[1] / self.glob_scale for i in range(len(polygon)): if polygon[i] is not None: # Find the next j = (i + 1) % len(polygon) while polygon[j] is None: j = (j + 1) % len(polygon) w = [ QPointF(p.x() * real_scale_x, p.y() * real_scale_y) for p in walls[polygon_id[i], polygon_id[j]] ] sides[i] = [polygon[i]] + w + [polygon[j]] prev = real_polygon[-1] polygon_shape = [] for i in range(len(polygon)): if polygon[i]: polygon_shape.append(polygon[i]) polygon_shape.extend(sides[i]) # Now add the dummy points .. starts at the first non-None point if non_none_cnt > 2: start = None for i in range(len(polygon)): if polygon[i] is not None: start = i break prev = start cur = start + 1 if start + 1 < len(polygon) else 0 log_debug("Polygon before: [%s]" % ",".join("(%f,%f)" % (p.x(), p.y()) if p is not None else "None" for p in polygon)) while cur != start: if polygon[cur] is None: cnt = 1 next = cur + 1 if cur + 1 < len(polygon) else 0 while True: if polygon[next] is None: cnt += 1 else: break next += 1 if next == len(polygon): next = 0 #print "%d points missing" % cnt # First, find total length of wall length = 0.0 side = sides[prev] for i in range(len(side) - 1): length += dist(side[i], side[i + 1]) diff = length / (cnt + 1) # Distance between two points i = cur p = side[0] for j in range(cnt): l = 0.0 found = False for k in range(len(side) - 1): dl = dist(side[k], side[k + 1]) l += dl if l > diff * ( 1 + 1e-5 ): # Account for accumulation of small errors c = (i + j) % len(polygon) delta = diff - l + dl p = side[k] + (side[k + 1] - side[k]) * delta / dl s1 = side[:k + 1] + [p] s2 = [p] + side[k + 1:] sides[c - 1] = s1 sides[c] = s2 side = s2 polygon[c] = p found = True break assert found, "Could not find point in polygon for position %d" % ( j + i, ) #p = p + diff #c = (i+j)%len(polygon) #polygon[c] = QPointF(p) cur = next else: prev = cur cur += 1 if cur >= len(polygon): cur = 0 assert None not in polygon, "Error, some dummy points were not added" else: polygon = [p for p in polygon if p is not None] center = sum(polygon, QPointF(0, 0)) / float(len(polygon)) self.center = center if len(polygon) > 2: polygon = QPolygonF(polygon + [polygon[0]]) polygon.translate(-center) polygon_shape = QPolygonF(polygon_shape + [polygon_shape[0]]) self.polygon_shape = polygon_shape polygon_shape.translate(-center) # Translate the sides too sides = [[p - center for p in s] for s in sides] self.sides = sides assert len(sides) == len(polygon) - 1 elif len(polygon) == 2: polygon = QLineF(polygon[0], polygon[1]) polygon.translate(-center) else: polygon = None self.polygon = polygon self.setPos(center) params = parameters.instance self.prepareGeometryChange() size = params.cell_size scale = self.scale height = size * cos(pi / 6) * scale[1] width = size * scale[0] pos_x = size * cos(pi / 3) * scale[0] self.sel_rect = QRectF(-width, -height, 2 * width, 2 * height) if isinstance(polygon, QPolygonF): self.rect = self.polygon_shape.boundingRect() | self.sel_rect elif isinstance(polygon, QLineF): self.rect = QRectF(polygon.p1(), polygon.p2()).normalized() | self.sel_rect else: self.rect = self.sel_rect self.bounding_rect = QRectF(self.rect) if self.p1 in points and self.p2 in points: self.division_line = QLineF(points[self.p1].pos() - center, points[self.p2].pos() - center) else: self.division_line = None self.hexagon = QPolygonF([ QPointF(-width, 0), QPointF(-pos_x, height), QPointF(pos_x, height), QPointF(width, 0), QPointF(pos_x, -height), QPointF(-pos_x, -height) ]) self.hexagon_path = QPainterPath() self.hexagon_path.addPolygon(self.hexagon) s1 = QPainterPath() if isinstance(self.polygon, QPolygonF): s1.addPolygon(polygon_shape) elif isinstance(self.polygon, QLineF): s1.moveTo(self.polygon.p1()) s1.lineTo(self.polygon.p2()) stroke = QPainterPathStroker() sel_thick = 3 * params.cell_thickness if sel_thick == 0: sel_thick = 3 stroke.setWidth(sel_thick) self.stroke = stroke.createStroke(s1) def changePoints(self, polygon): self.polygon_id = polygon self.setGeometry() def paint(self, painter, option, widget): params = parameters.instance pen = QPen(QColor(Qt.black)) scale = self.scale ms = min(scale) pen.setWidth(params.cell_thickness) sel_thick = 2 * params.cell_thickness if sel_thick == 0: sel_thick = 2 * ms col = None if self.current: col = QColor(params.selected_cell_color) elif self.hover: col = QColor(params.cell_hover_color) else: col = QColor(params.cell_color) painter.setBrush(col) if self.hover_contour: pen1 = QPen(QColor(Qt.white)) pen1.setWidth(sel_thick) painter.setPen(pen1) else: painter.setPen(pen) if isinstance(self.polygon, QPolygonF): painter.drawPolygon(self.polygon_shape) elif isinstance(self.polygon, QLineF): painter.drawLine(self.polygon) pen.setWidth(0) painter.setPen(pen) painter.drawPolygon(self.hexagon) if self.hover_side is not None: pen = QPen(QColor(Qt.red)) pen.setWidth(sel_thick) side = self.sides[self.hover_side] painter.setPen(pen) pp = QPainterPath() pp.moveTo(side[0]) for p in side[1:]: pp.lineTo(p) painter.drawPath(pp) elif self.division_line is not None: pen = QPen(params.division_wall_color) pen.setWidth(sel_thick) painter.setPen(pen) painter.drawLine(self.division_line) elif self.dragging_line: pen = QPen(QColor(Qt.red)) pen.setWidth(sel_thick) painter.setPen(pen) polygon = self.polygon dg = self.drag_side p1 = polygon[dg] p2 = polygon[dg + 1] painter.drawLine(p1, self.moving_point) painter.drawLine(self.moving_point, p2) def setEditable(self, value): self.editable = value def boundingRect(self): return self.bounding_rect def shape(self): """ Returns the shape used for selection """ s = QPainterPath() s.addPath(self.hexagon_path) if self.editable: s.addPath(self.stroke) return s def setSelectable(self, value=True): self.setFlag(QGraphicsItem.ItemIsSelectable, value) self.setFlag(QGraphicsItem.ItemIsMovable, True) def findClosestSide(self, pos): """ Find the side of the polygon closest to pos """ polygon = self.polygon min_dist = inf min_side = None if isinstance(polygon, QLineF): min_side = 0 min_dist = 0 else: #pos = pos + self.center sides = self.sides assert len(sides) == len(polygon) - 1 for i in range(len(polygon) - 1): side = sides[i] d = distToPolyLine(pos, side) if d < min_dist: min_dist = d min_side = i #print "Closest side found = %d, with distance = %f"%(min_side, min_dist) return min_side, min_dist def findHover(self, pos): """ Find which side is being hovered over """ if self.editable: if self.drag_line: self.hover = False self.hover_side = None self.hover_contour = False elif self.hexagon_path.contains(pos): self.hover = True self.hover_side = None self.hover_contour = False else: params = parameters.instance sel_thick = 3 * params.cell_thickness if sel_thick == 0: sel_thick = 3 self.hover_contour = True self.hover = False polygon = self.polygon if isinstance(polygon, QPolygonF): min_side, min_dist = self.findClosestSide(pos) #print "Closest side = %d"%min_side if min_dist < sel_thick and min_side is not None: self.hover_side = min_side else: self.hover_side = None self.hover_contour = False self.hover = True else: self.hover = True self.hover_side = None self.hover_contour = False def hoverEnterEvent(self, event): self.findHover(event.pos()) self.update() def hoverMoveEvent(self, event): self.findHover(event.pos()) self.update() def hoverLeaveEvent(self, event): self.hover = False self.hover_contour = False self.hover_side = None self.update() def mousePressEvent(self, event): if self.hover_side is not None: moving_point = QPointF(event.pos()) self.drag_side = self.hover_side #self.polygon.insert(self.hover_side+1, moving_point) #self.sides[self.hover_side] = [self.polygon[self.hover_side], self.polygon[self.hover_side+1]] #self.sides.insert(self.hover_side+1, [self.polygon[self.hover_side+1], self.polygon[self.hover_side+2]]) self.moving_point = moving_point self.start_drag = event.screenPos() self.hover_contour = False self.hover_side = None self.drag_line = True self.dragging_line = False self.update() event.accept() else: event.ignore() QGraphicsItem.mousePressEvent(self, event) def mouseMoveEvent(self, event): if not self.dragging_line and self.drag_line and ( self.start_drag - event.screenPos()).manhattanLength() > 5: self.dragging_line = True if self.dragging_line: params = parameters.instance ms = min(self.scale) sel_thick = 2 * params.cell_thickness if sel_thick == 0: sel_thick = 2 * ms self.prepareGeometryChange() mp = self.moving_point mp.setX(event.pos().x()) mp.setY(event.pos().y()) self.bounding_rect = self.rect | QRectF( mp.x() - sel_thick, mp.y() - sel_thick, 2 * sel_thick, 2 * sel_thick) self.update() def mouseReleaseEvent(self, event): if self.dragging_line: log_debug("Adding point to cell") self.setGeometry() drag_side = (self.drag_side + 1) % (len(self.polygon) - 1) self.scene().addPointToCell(self.cell_id, drag_side, self.mapToScene(event.pos())) else: event.ignore() QGraphicsItem.mouseReleaseEvent(self, event) self.drag_line = False self.dragging_line = False
class CellItem(QGraphicsItem): """ Class representing a cell on the screen. :IVariables: cell_id : int Identifier of the cell hover : bool True if the cell is being hovered over hover_contour : bool True if the contour of the cell is being hovered over hover_side : int|None Number of the side being hovered over sides : list of `QPainterPath` shape of each side polygon_id : list of int list of point ids for the polygon walls : `TimedWallShapes` Ref to the structure defining the shape of the walls at the current time points : dict of int * QPointF Ref to the structure holding the position of all the points at the current time current : bool True if the cell is the currently selected one drag_line : bool True if one of the side is being dragged p1 : int Start of a division line p2 : int End of a division line """ def __init__(self, scale, glob_scale, cell_id, polygon, points, walls, parent=None): QGraphicsItem.__init__(self, parent) self.cell_id = cell_id self.setZValue(2.5) self.setAcceptsHoverEvents(True) self.setSelectable(False) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.hover = False self.hover_contour = False self.hover_side = None self.scale = scale self.glob_scale = glob_scale self.setToolTip(unicode(cell_id)) self.polygon_id = polygon self.walls = walls self.sides = [] self.points = points self.current = False self.drag_line = False self.dragging_line = False self.editable = False self.p1 = None self.p2 = None self.setGeometry() def __del__(self): cleanQObject(self) def setCurrent(self, value=True): """ Set this cell as the current one (i.e. on top and different color) """ if value: self.setZValue(2.8) else: self.setZValue(2.5) self.current = value self.update() def setDivisionLine(self, p1, p2): """ Set the line from p1 to p2 to be a division line (i.e. different representation) """ self.p1 = p1 self.p2 = p2 self.setGeometry() def setGeometry(self): """ Read the parameters that define the geometry of the point """ params = parameters.instance self.setEditable(params.is_cell_editable) points = self.points polygon_id = self.polygon_id polygon = [points[pt].pos() if pt in points else None for pt in polygon_id] non_none_cnt = len([p for p in polygon if p is not None]) if non_none_cnt == 0: self.rect = QRectF() self.bounding_rect = QRectF() self.setVisible(False) return self.setVisible(True) # First, check if this is a "simple" cell walls = self.walls real_polygon = [pid for pid in polygon_id if pid in points] #sides = [ walls[real_polygon[i], real_polygon[(i+1)%len(real_polygon)]] for i in range(len(real_polygon)) ] sides = [None] * len(polygon) self.sides = sides real_scale_x = self.scale[0]/self.glob_scale real_scale_y = self.scale[1]/self.glob_scale for i in range(len(polygon)): if polygon[i] is not None: # Find the next j = (i+1) % len(polygon) while polygon[j] is None: j = (j+1) % len(polygon) w = [QPointF(p.x()*real_scale_x, p.y()*real_scale_y) for p in walls[polygon_id[i], polygon_id[j]]] sides[i] = [polygon[i]] + w + [polygon[j]] prev = real_polygon[-1] polygon_shape = [] for i in range(len(polygon)): if polygon[i]: polygon_shape.append(polygon[i]) polygon_shape.extend(sides[i]) # Now add the dummy points .. starts at the first non-None point if non_none_cnt > 2: start = None for i in range(len(polygon)): if polygon[i] is not None: start = i break prev = start cur = start+1 if start+1 < len(polygon) else 0 log_debug("Polygon before: [%s]" % ",".join("(%f,%f)" % (p.x(), p.y()) if p is not None else "None" for p in polygon)) while cur != start: if polygon[cur] is None: cnt = 1 next = cur+1 if cur+1 < len(polygon) else 0 while True: if polygon[next] is None: cnt += 1 else: break next += 1 if next == len(polygon): next = 0 #print "%d points missing" % cnt # First, find total length of wall length = 0.0 side = sides[prev] for i in range(len(side)-1): length += dist(side[i], side[i+1]) diff = length/(cnt+1) # Distance between two points i = cur p = side[0] for j in range(cnt): l = 0.0 found = False for k in range(len(side)-1): dl = dist(side[k], side[k+1]) l += dl if l > diff*(1+1e-5): # Account for accumulation of small errors c = (i + j) % len(polygon) delta = diff-l+dl p = side[k] + (side[k+1]-side[k])*delta/dl s1 = side[:k+1] + [p] s2 = [p] + side[k+1:] sides[c-1] = s1 sides[c] = s2 side = s2 polygon[c] = p found = True break assert found, "Could not find point in polygon for position %d" % (j+i,) #p = p + diff #c = (i+j)%len(polygon) #polygon[c] = QPointF(p) cur = next else: prev = cur cur += 1 if cur >= len(polygon): cur = 0 assert None not in polygon, "Error, some dummy points were not added" else: polygon = [p for p in polygon if p is not None] center = sum(polygon, QPointF(0, 0)) / float(len(polygon)) self.center = center if len(polygon) > 2: polygon = QPolygonF(polygon+[polygon[0]]) polygon.translate(-center) polygon_shape = QPolygonF(polygon_shape + [polygon_shape[0]]) self.polygon_shape = polygon_shape polygon_shape.translate(-center) # Translate the sides too sides = [[p-center for p in s] for s in sides] self.sides = sides assert len(sides) == len(polygon)-1 elif len(polygon) == 2: polygon = QLineF(polygon[0], polygon[1]) polygon.translate(-center) else: polygon = None self.polygon = polygon self.setPos(center) params = parameters.instance self.prepareGeometryChange() size = params.cell_size scale = self.scale height = size*cos(pi/6)*scale[1] width = size*scale[0] pos_x = size*cos(pi/3)*scale[0] self.sel_rect = QRectF(-width, -height, 2*width, 2*height) if isinstance(polygon, QPolygonF): self.rect = self.polygon_shape.boundingRect() | self.sel_rect elif isinstance(polygon, QLineF): self.rect = QRectF(polygon.p1(), polygon.p2()).normalized() | self.sel_rect else: self.rect = self.sel_rect self.bounding_rect = QRectF(self.rect) if self.p1 in points and self.p2 in points: self.division_line = QLineF(points[self.p1].pos()-center, points[self.p2].pos()-center) else: self.division_line = None self.hexagon = QPolygonF([QPointF(-width, 0), QPointF(-pos_x, height), QPointF(pos_x, height), QPointF(width, 0), QPointF(pos_x, -height), QPointF(-pos_x, -height)]) self.hexagon_path = QPainterPath() self.hexagon_path.addPolygon(self.hexagon) s1 = QPainterPath() if isinstance(self.polygon, QPolygonF): s1.addPolygon(polygon_shape) elif isinstance(self.polygon, QLineF): s1.moveTo(self.polygon.p1()) s1.lineTo(self.polygon.p2()) stroke = QPainterPathStroker() sel_thick = 3*params.cell_thickness if sel_thick == 0: sel_thick = 3 stroke.setWidth(sel_thick) self.stroke = stroke.createStroke(s1) def changePoints(self, polygon): self.polygon_id = polygon self.setGeometry() def paint(self, painter, option, widget): params = parameters.instance pen = QPen(QColor(Qt.black)) scale = self.scale ms = min(scale) pen.setWidth(params.cell_thickness) sel_thick = 2*params.cell_thickness if sel_thick == 0: sel_thick = 2*ms col = None if self.current: col = QColor(params.selected_cell_color) elif self.hover: col = QColor(params.cell_hover_color) else: col = QColor(params.cell_color) painter.setBrush(col) if self.hover_contour: pen1 = QPen(QColor(Qt.white)) pen1.setWidth(sel_thick) painter.setPen(pen1) else: painter.setPen(pen) if isinstance(self.polygon, QPolygonF): painter.drawPolygon(self.polygon_shape) elif isinstance(self.polygon, QLineF): painter.drawLine(self.polygon) pen.setWidth(0) painter.setPen(pen) painter.drawPolygon(self.hexagon) if self.hover_side is not None: pen = QPen(QColor(Qt.red)) pen.setWidth(sel_thick) side = self.sides[self.hover_side] painter.setPen(pen) pp = QPainterPath() pp.moveTo(side[0]) for p in side[1:]: pp.lineTo(p) painter.drawPath(pp) elif self.division_line is not None: pen = QPen(params.division_wall_color) pen.setWidth(sel_thick) painter.setPen(pen) painter.drawLine(self.division_line) elif self.dragging_line: pen = QPen(QColor(Qt.red)) pen.setWidth(sel_thick) painter.setPen(pen) polygon = self.polygon dg = self.drag_side p1 = polygon[dg] p2 = polygon[dg+1] painter.drawLine(p1, self.moving_point) painter.drawLine(self.moving_point, p2) def setEditable(self, value): self.editable = value def boundingRect(self): return self.bounding_rect def shape(self): """ Returns the shape used for selection """ s = QPainterPath() s.addPath(self.hexagon_path) if self.editable: s.addPath(self.stroke) return s def setSelectable(self, value=True): self.setFlag(QGraphicsItem.ItemIsSelectable, value) self.setFlag(QGraphicsItem.ItemIsMovable, True) def findClosestSide(self, pos): """ Find the side of the polygon closest to pos """ polygon = self.polygon min_dist = inf min_side = None if isinstance(polygon, QLineF): min_side = 0 min_dist = 0 else: #pos = pos + self.center sides = self.sides assert len(sides) == len(polygon)-1 for i in range(len(polygon)-1): side = sides[i] d = distToPolyLine(pos, side) if d < min_dist: min_dist = d min_side = i #print "Closest side found = %d, with distance = %f"%(min_side, min_dist) return min_side, min_dist def findHover(self, pos): """ Find which side is being hovered over """ if self.editable: if self.drag_line: self.hover = False self.hover_side = None self.hover_contour = False elif self.hexagon_path.contains(pos): self.hover = True self.hover_side = None self.hover_contour = False else: params = parameters.instance sel_thick = 3*params.cell_thickness if sel_thick == 0: sel_thick = 3 self.hover_contour = True self.hover = False polygon = self.polygon if isinstance(polygon, QPolygonF): min_side, min_dist = self.findClosestSide(pos) #print "Closest side = %d"%min_side if min_dist < sel_thick and min_side is not None: self.hover_side = min_side else: self.hover_side = None self.hover_contour = False self.hover = True else: self.hover = True self.hover_side = None self.hover_contour = False def hoverEnterEvent(self, event): self.findHover(event.pos()) self.update() def hoverMoveEvent(self, event): self.findHover(event.pos()) self.update() def hoverLeaveEvent(self, event): self.hover = False self.hover_contour = False self.hover_side = None self.update() def mousePressEvent(self, event): if self.hover_side is not None: moving_point = QPointF(event.pos()) self.drag_side = self.hover_side #self.polygon.insert(self.hover_side+1, moving_point) #self.sides[self.hover_side] = [self.polygon[self.hover_side], self.polygon[self.hover_side+1]] #self.sides.insert(self.hover_side+1, [self.polygon[self.hover_side+1], self.polygon[self.hover_side+2]]) self.moving_point = moving_point self.start_drag = event.screenPos() self.hover_contour = False self.hover_side = None self.drag_line = True self.dragging_line = False self.update() event.accept() else: event.ignore() QGraphicsItem.mousePressEvent(self, event) def mouseMoveEvent(self, event): if not self.dragging_line and self.drag_line and (self.start_drag - event.screenPos()).manhattanLength() > 5: self.dragging_line = True if self.dragging_line: params = parameters.instance ms = min(self.scale) sel_thick = 2*params.cell_thickness if sel_thick == 0: sel_thick = 2*ms self.prepareGeometryChange() mp = self.moving_point mp.setX(event.pos().x()) mp.setY(event.pos().y()) self.bounding_rect = self.rect | QRectF(mp.x()-sel_thick, mp.y()-sel_thick, 2*sel_thick, 2*sel_thick) self.update() def mouseReleaseEvent(self, event): if self.dragging_line: log_debug("Adding point to cell") self.setGeometry() drag_side = (self.drag_side+1) % (len(self.polygon)-1) self.scene().addPointToCell(self.cell_id, drag_side, self.mapToScene(event.pos())) else: event.ignore() QGraphicsItem.mouseReleaseEvent(self, event) self.drag_line = False self.dragging_line = False