def drawToolButtonMenuIndicator(self, option, painter, widget=None): arrow_rect = self.proxy().subControlRect(QStyle.CC_ToolButton, option, QStyle.SC_ToolButtonMenu, widget) text_color = option.palette.color(QPalette.WindowText if option.state & QStyle.State_AutoRaise else QPalette.ButtonText) button_color = option.palette.color(QPalette.Button) background_color = self.background_color(button_color, 0.5) painter.save() # draw separating vertical line if option.state & (QStyle.State_On|QStyle.State_Sunken): top_offset, bottom_offset = 4, 3 else: top_offset, bottom_offset = 2, 2 if option.direction == Qt.LeftToRight: separator_line = QLineF(arrow_rect.x()-3, arrow_rect.top()+top_offset, arrow_rect.x()-3, arrow_rect.bottom()-bottom_offset) else: separator_line = QLineF(arrow_rect.right()+3, arrow_rect.top()+top_offset, arrow_rect.right()+3, arrow_rect.bottom()-bottom_offset) light_gradient = QLinearGradient(separator_line.p1(), separator_line.p2()) light_gradient.setColorAt(0.0, ColorScheme.shade(self.background_top_color(button_color), ColorScheme.LightShade, 0.0)) light_gradient.setColorAt(1.0, ColorScheme.shade(self.background_bottom_color(button_color), ColorScheme.MidlightShade, 0.5)) separator_color = ColorScheme.shade(self.background_bottom_color(button_color), ColorScheme.MidShade, 0.0) painter.setRenderHint(QPainter.Antialiasing, False) painter.setPen(QPen(light_gradient, 1)) painter.drawLine(separator_line.translated(-1, 0)) painter.drawLine(separator_line.translated(+1, 0)) painter.setPen(QPen(separator_color, 1)) painter.drawLine(separator_line) # draw arrow arrow = QPolygonF([QPointF(-3, -1.5), QPointF(0.5, 2.5), QPointF(4, -1.5)]) if option.direction == Qt.LeftToRight: arrow.translate(-2, 1) else: arrow.translate(+2, 1) pen_thickness = 1.6 painter.setRenderHint(QPainter.Antialiasing, True) painter.translate(arrow_rect.center()) painter.translate(0, +1) painter.setPen(QPen(self.calc_light_color(background_color), pen_thickness, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawPolyline(arrow) painter.translate(0, -1) painter.setPen(QPen(self.deco_color(background_color, text_color), pen_thickness, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawPolyline(arrow) painter.restore()
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 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)