def refresh(self): if not self._mdlPlots or not self._mdlOutline or not self._mdlCharacter: return if not self.isVisible(): return LINE_HEIGHT = 18 SPACING = 3 TEXT_WIDTH = self.sldTxtSize.value() CIRCLE_WIDTH = 10 LEVEL_HEIGHT = 12 s = self.scene s.clear() # Get Max Level (max depth) root = self._mdlOutline.rootItem def maxLevel(item, level=0, max=0): if level > max: max = level for c in item.children(): m = maxLevel(c, level + 1) if m > max: max = m return max MAX_LEVEL = maxLevel(root) # Get the list of tracked items (array of references) trackedItems = [] if self.actPlots.isChecked(): trackedItems += self.plotReferences() if self.actCharacters.isChecked(): trackedItems += self.charactersReferences() ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING) fm = QFontMetrics(s.font()) max_name = 0 for ref in trackedItems: name = references.title(ref) max_name = max(fm.width(name), max_name) TITLE_WIDTH = max_name + 2 * SPACING # Add Folders and Texts outline = OutlineRect(0, 0, 0, ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT) s.addItem(outline) outline.setPos(TITLE_WIDTH + SPACING, 0) refCircles = [ ] # a list of all references, to be added later on the lines # A Function to add a rect with centered elided text def addRectText(x, w, parent, text="", level=0, tooltip=""): deltaH = LEVEL_HEIGHT if level else 0 r = OutlineRect(0, 0, w, parent.rect().height() - deltaH, parent, title=text) r.setPos(x, deltaH) txt = QGraphicsSimpleTextItem(text, r) f = txt.font() f.setPointSize(8) fm = QFontMetricsF(f) elidedText = fm.elidedText(text, Qt.ElideMiddle, w) txt.setFont(f) txt.setText(elidedText) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) txt.setY(0) return r # A function to returns an item's width, by counting its children def itemWidth(item): if item.isFolder(): r = 0 for c in item.children(): r += itemWidth(c) return r or TEXT_WIDTH else: return TEXT_WIDTH def listItems(item, rect, level=0): delta = 0 for child in item.children(): w = itemWidth(child) if child.isFolder(): parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title()) parent.setToolTip( references.tooltip(references.textReference( child.ID()))) listItems(child, parent, level + 1) else: rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title()) rectChild.setToolTip( references.tooltip(references.textReference( child.ID()))) # Find tracked references in that scene (or parent folders) for ref in trackedItems: result = [] # Tests if POV scenePOV = False # Will hold true of character is POV of the current text, not containing folder if references.type(ref) == references.CharacterLetter: ID = references.ID(ref) c = child while c: if c.POV() == ID: result.append(c.ID()) if c == child: scenePOV = True c = c.parent() # Search in notes/references c = child while c: result += references.findReferencesTo( ref, c, recursive=False) c = c.parent() if result: ref2 = result[0] # Create a RefCircle with the reference c = RefCircle(TEXT_WIDTH / 2, -CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2, important=scenePOV) # Store it, with the position of that item, to display it on the line later on refCircles.append( (ref, c, rect.mapToItem(outline, rectChild.pos()))) delta += w listItems(root, outline) OUTLINE_WIDTH = itemWidth(root) # Add Tracked items i = 0 itemsRect = s.addRect(0, 0, 0, 0) itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING) # Set of colors for plots (as long as they don't have their own colors) colors = [ "#D97777", "#AE5F8C", "#D9A377", "#FFC2C2", "#FFDEC2", "#D2A0BC", "#7B0F0F", "#7B400F", "#620C3D", "#AA3939", "#AA6C39", "#882D61", "#4C0000", "#4C2200", "#3D0022", ] for ref in trackedItems: if references.type(ref) == references.CharacterLetter: color = self._mdlCharacter.getCharacterByID( references.ID(ref)).color() else: color = QColor(colors[i % len(colors)]) # Rect r = QGraphicsRectItem(0, 0, TITLE_WIDTH, LINE_HEIGHT, itemsRect) r.setPen(QPen(Qt.NoPen)) r.setBrush(QBrush(color)) r.setPos(0, i * LINE_HEIGHT + i * SPACING) r.setToolTip(references.tooltip(ref)) i += 1 # Text name = references.title(ref) txt = QGraphicsSimpleTextItem(name, r) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) # Line line = PlotLine(0, 0, OUTLINE_WIDTH + SPACING, 0) line.setPos(TITLE_WIDTH, r.mapToScene(r.rect().center()).y()) s.addItem(line) line.setPen(QPen(color, 5)) line.setToolTip(references.tooltip(ref)) # We add the circles / references to text, on the line for ref2, circle, pos in refCircles: if ref2 == ref: circle.setParentItem(line) circle.setPos(pos.x(), 0) # self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio self.view.setSceneRect(0, 0, 0, 0)
def refresh(self): if not self._mdlPlots or not self._mdlOutline or not self._mdlCharacter: return if not self.isVisible(): return LINE_HEIGHT = 18 SPACING = 3 TEXT_WIDTH = self.sldTxtSize.value() CIRCLE_WIDTH = 10 LEVEL_HEIGHT = 12 s = self.scene s.clear() # Get Max Level (max depth) root = self._mdlOutline.rootItem def maxLevel(item, level=0, max=0): if level > max: max = level for c in item.children(): m = maxLevel(c, level + 1) if m > max: max = m return max MAX_LEVEL = maxLevel(root) # Get the list of tracked items (array of references) trackedItems = [] if self.actPlots.isChecked(): trackedItems += self.plotReferences() if self.actCharacters.isChecked(): trackedItems += self.charactersReferences() ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING ) fm = QFontMetrics(s.font()) max_name = 0 for ref in trackedItems: name = references.title(ref) max_name = max(fm.width(name), max_name) TITLE_WIDTH = max_name + 2 * SPACING # Add Folders and Texts outline = OutlineRect(0, 0, 0, ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT) s.addItem(outline) outline.setPos(TITLE_WIDTH + SPACING, 0) refCircles = [] # a list of all references, to be added later on the lines # A Function to add a rect with centered elided text def addRectText(x, w, parent, text="", level=0, tooltip=""): deltaH = LEVEL_HEIGHT if level else 0 r = OutlineRect(0, 0, w, parent.rect().height()-deltaH, parent, title=text) r.setPos(x, deltaH) txt = QGraphicsSimpleTextItem(text, r) f = txt.font() f.setPointSize(8) fm = QFontMetricsF(f) elidedText = fm.elidedText(text, Qt.ElideMiddle, w) txt.setFont(f) txt.setText(elidedText) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) txt.setY(0) return r # A function to returns an item's width, by counting its children def itemWidth(item): if item.isFolder(): r = 0 for c in item.children(): r += itemWidth(c) return r or TEXT_WIDTH else: return TEXT_WIDTH def listItems(item, rect, level=0): delta = 0 for child in item.children(): w = itemWidth(child) if child.isFolder(): parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title()) parent.setToolTip(references.tooltip(references.textReference(child.ID()))) listItems(child, parent, level + 1) else: rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title()) rectChild.setToolTip(references.tooltip(references.textReference(child.ID()))) # Find tracked references in that scene (or parent folders) for ref in trackedItems: result = [] # Tests if POV scenePOV = False # Will hold true of character is POV of the current text, not containing folder if references.type(ref) == references.CharacterLetter: ID = references.ID(ref) c = child while c: if c.POV() == ID: result.append(c.ID()) if c == child: scenePOV = True c = c.parent() # Search in notes/references c = child while c: result += references.findReferencesTo(ref, c, recursive=False) c = c.parent() if result: ref2 = result[0] # Create a RefCircle with the reference c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2, important=scenePOV) # Store it, with the position of that item, to display it on the line later on refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos()))) delta += w listItems(root, outline) OUTLINE_WIDTH = itemWidth(root) # Add Tracked items i = 0 itemsRect = s.addRect(0, 0, 0, 0) itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING) # Set of colors for plots (as long as they don't have their own colors) colors = [ "#D97777", "#AE5F8C", "#D9A377", "#FFC2C2", "#FFDEC2", "#D2A0BC", "#7B0F0F", "#7B400F", "#620C3D", "#AA3939", "#AA6C39", "#882D61", "#4C0000", "#4C2200", "#3D0022", ] for ref in trackedItems: if references.type(ref) == references.CharacterLetter: color = self._mdlCharacter.getCharacterByID(references.ID(ref)).color() else: color = QColor(colors[i % len(colors)]) # Rect r = QGraphicsRectItem(0, 0, TITLE_WIDTH, LINE_HEIGHT, itemsRect) r.setPen(QPen(Qt.NoPen)) r.setBrush(QBrush(color)) r.setPos(0, i * LINE_HEIGHT + i * SPACING) r.setToolTip(references.tooltip(ref)) i += 1 # Text name = references.title(ref) txt = QGraphicsSimpleTextItem(name, r) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) # Line line = PlotLine(0, 0, OUTLINE_WIDTH + SPACING, 0) line.setPos(TITLE_WIDTH, r.mapToScene(r.rect().center()).y()) s.addItem(line) line.setPen(QPen(color, 5)) line.setToolTip(references.tooltip(ref)) # We add the circles / references to text, on the line for ref2, circle, pos in refCircles: if ref2 == ref: circle.setParentItem(line) circle.setPos(pos.x(), 0) # self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio self.view.setSceneRect(0, 0, 0, 0)
class BankNodeItem (NodeItem): maincolor = FlPalette.bank altcolor = FlPalette.bankvar label = "%s Bank" def __init__ (self, nodeobj, parent=None, view=None, state=1): super().__init__(nodeobj, parent, view, state) self.rect = QRectF() self.setZValue(-1) self.updatecomment() self.updatebanktype() self.updatebankmode() def nudgechildren(self): super().nudgechildren() for sub in self.sublist(): sub.setrank(self) def sublist (self): ID = self.nodeobj.ID itemtable = self.view.itemtable if self.state == 1 and ID in itemtable and not self.iscollapsed(): children = [] for child in self.nodeobj.subnodes: if child in itemtable[ID]: item = itemtable[ID][child] else: continue if item.state > -1: children.append(item) return children else: return [] def treeposition (self, ranks=None): self.updatelayout(external=True) return super().treeposition(ranks) def graphicsetup (self): super().graphicsetup() darkbrush = QBrush(FlPalette.bg) nopen = QPen(0) viewport = self.view.viewport() self.btypeicon = QGraphicsPixmapItemCond(self.icon, self, viewport) self.btypeicon.setPos(self.iconx-self.style.itemmargin-self.iwidth, self.style.itemmargin) self.iconx = self.btypeicon.x() self.fggroup.addToGroup(self.btypeicon) self.centerbox = QGraphicsRectItem(self) self.centerbox.setCacheMode(QGraphicsItem.DeviceCoordinateCache) self.centerbox.setRect(QRectF()) self.centerbox.setBrush(darkbrush) self.centerbox.setPen(nopen) self.centerbox.setPos(0, self.nodelabel.y()+self.nodelabel.boundingRect().height()+self.style.itemmargin*2) self.fggroup.addToGroup(self.centerbox) def updatebanktype (self): types = {"talk": "(T)", "response": "(R)", "": ""} self.nodelabel.setText("%s Bank %s" % (self.realid(), types[self.nodeobj.banktype])) def updatebankmode (self): icons = {"First": "bank-first", "All": "bank-all", "Append": "bank-append", "": "blank"} pixmap = self.pixmap("images/%s.png" % icons[self.nodeobj.bankmode]) self.btypeicon.setPixmap(pixmap) if self.nodeobj.bankmode: self.btypeicon.setToolTip("Bank mode: %s" % self.nodeobj.bankmode) else: self.btypeicon.setToolTip("") def updatecenterbox (self): verticalpos = self.centerbox.y() maxwidth = self.style.nodetextwidth subnodes = self.sublist() for subnode in subnodes: if subnode.nodeobj.typename == "bank": subnode.updatelayout(external=True) noderect = subnode.boundingRect() nodeheight = noderect.height() nodewidth = noderect.width() subnode.show() subnode.yoffset = self.mapToScene(0,verticalpos + nodeheight/2+self.style.activemargin).y()-self.y_bottom() verticalpos += nodeheight+self.style.activemargin*2 maxwidth = max(maxwidth, nodewidth) centerrect = self.centerbox.rect() centerrect.setWidth(maxwidth+self.style.selectmargin*2) centerrect.setHeight(verticalpos-self.centerbox.y()) self.centerbox.setRect(centerrect) centerrect = self.centerbox.mapRectToParent(centerrect) self.comment.setY(centerrect.bottom()+self.style.itemmargin) def updatelayout (self, external=False): subnodes = self.sublist() if self.iscollapsed(): rect = self.nodelabel.mapRectToParent(self.nodelabel.boundingRect()) else: self.updatecenterbox() rect = self.fggroup.childrenBoundingRect() mainrect = rect.marginsAdded(self.style.banknodemargins) self.mainbox.setRect(mainrect) self.shadowbox.setRect(mainrect) self.selectbox.setRect(mainrect.marginsAdded(self.style.selectmargins)) activerect = mainrect.marginsAdded(self.style.activemargins) self.activebox.setRect(activerect) oldypos = self.centerbox.mapToScene(self.centerbox.pos()).y() self.graphgroup.setPos(-activerect.width()//2-activerect.x(), -activerect.height()//2-activerect.y()) newypos = self.centerbox.mapToScene(self.centerbox.pos()).y() for subnode in subnodes: subnode.yoffset += newypos - oldypos subnode.setY(self.y()) self.prepareGeometryChange() self.rect = self.graphgroup.mapRectToParent(mainrect) if not external: self.view.updatelayout() def setY (self, y): super().setY(y) for subnode in self.sublist(): subnode.setY(y) def contextMenuEvent (self, event): menu = QMenu() if self.isselected(): window = FlGlob.mainwindow menu.addAction(window.actions["collapse"]) if self.isghost(): menu.addAction(window.actions["selectreal"]) menu.addAction(window.actions["copynode"]) menu.addMenu(window.subnodemenu) menu.addMenu(window.addmenu) menu.addAction(window.actions["moveup"]) menu.addAction(window.actions["movedown"]) menu.addAction(window.actions["parentswap"]) menu.addAction(window.actions["unlinknode"]) menu.addAction(window.actions["unlinkstree"]) menu.addAction(window.actions["settemplate"]) menu.addMenu(window.transformmenu) if not menu.isEmpty(): menu.exec_(event.screenPos())
texte.setDefaultTextColor(Qt.blue) scene.addItem(texte) d = 48. # diametre smiley ox = 4. # largeur oeil oy = 6. # hauteur oeil smiley = QGraphicsEllipseItem(-d / 2, -d / 2, d, d) smiley.setBrush(QBrush(Qt.yellow)) yeux = [QGraphicsEllipseItem(-ox/2.,-oy/2.,ox,oy,parent=smiley) \ for _ in range(2)] yeux[0].setPos(-d / 6, -d / 8) yeux[1].setPos(+d / 6, -d / 8) brush = QBrush(Qt.black) for oeil in yeux: oeil.setBrush(brush) smiley.setPos(rectGris.mapToScene(rectGris.rect().center())) scene.addItem(smiley) smiley.setRotation(20) smiley.setScale(1.5) smiley.setFlag(QGraphicsItem.ItemIsMovable) texte.setZValue(1) # vue principale vue = QGraphicsView(scene) vue.setRenderHints(QPainter.Antialiasing) vue.resize(800, 600) vue.centerOn(rectGris) vue.fitInView(rectGris, Qt.KeepAspectRatio) vue.show() # vues auxiliaires
def refresh(self): if not self._mdlPlots or not self._mdlOutline or not self._mdlPersos: pass LINE_HEIGHT = 18 SPACING = 3 TEXT_WIDTH = self.sldTxtSize.value() CIRCLE_WIDTH = 10 LEVEL_HEIGHT = 12 s = self.scene s.clear() # Get Max Level (max depth) root = self._mdlOutline.rootItem def maxLevel(item, level=0, max=0): if level > max: max = level for c in item.children(): m = maxLevel(c, level + 1) if m > max: max = m return max MAX_LEVEL = maxLevel(root) # Generate left entries # (As of now, plot only) plotsID = self._mdlPlots.getPlotsByImportance() trackedItems = [] fm = QFontMetrics(s.font()) max_name = 0 for importance in plotsID: for ID in importance: name = self._mdlPlots.getPlotNameByID(ID) ref = references.plotReference(ID, searchable=True) trackedItems.append((ID, ref, name)) max_name = max(fm.width(name), max_name) ROWS_HEIGHT = len(trackedItems) * (LINE_HEIGHT + SPACING ) TITLE_WIDTH = max_name + 2 * SPACING # Add Folders and Texts outline = OutlineRect(0, 0, 0, ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT) s.addItem(outline) outline.setPos(TITLE_WIDTH + SPACING, 0) refCircles = [] # a list of all references, to be added later on the lines # A Function to add a rect with centered elided text def addRectText(x, w, parent, text="", level=0, tooltip=""): deltaH = LEVEL_HEIGHT if level else 0 r = OutlineRect(0, 0, w, parent.rect().height()-deltaH, parent, title=text) r.setPos(x, deltaH) txt = QGraphicsSimpleTextItem(text, r) f = txt.font() f.setPointSize(8) fm = QFontMetricsF(f) elidedText = fm.elidedText(text, Qt.ElideMiddle, w) txt.setFont(f) txt.setText(elidedText) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) txt.setY(0) return r # A function to returns an item's width, by counting its children def itemWidth(item): if item.isFolder(): r = 0 for c in item.children(): r += itemWidth(c) return r or TEXT_WIDTH else: return TEXT_WIDTH def listItems(item, rect, level=0): delta = 0 for child in item.children(): w = itemWidth(child) if child.isFolder(): parent = addRectText(delta, w, rect, child.title(), level, tooltip=child.title()) parent.setToolTip(references.tooltip(references.textReference(child.ID()))) listItems(child, parent, level + 1) else: rectChild = addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title()) rectChild.setToolTip(references.tooltip(references.textReference(child.ID()))) # Find tracked references in that scene (or parent folders) for ID, ref, name in trackedItems: result = [] c = child while c: result += references.findReferencesTo(ref, c, recursive=False) c = c.parent() if result: ref2 = result[0] # Create a RefCircle with the reference c = RefCircle(TEXT_WIDTH / 2, - CIRCLE_WIDTH / 2, CIRCLE_WIDTH, ID=ref2) # Store it, with the position of that item, to display it on the line later on refCircles.append((ref, c, rect.mapToItem(outline, rectChild.pos()))) delta += w listItems(root, outline) OUTLINE_WIDTH = itemWidth(root) # Add Plots i = 0 itemsRect = s.addRect(0, 0, 0, 0) itemsRect.setPos(0, MAX_LEVEL * LEVEL_HEIGHT + SPACING) for ID, ref, name in trackedItems: color = randomColor() # Rect r = QGraphicsRectItem(0, 0, TITLE_WIDTH, LINE_HEIGHT, itemsRect) r.setPen(QPen(Qt.NoPen)) r.setBrush(QBrush(color)) r.setPos(0, i * LINE_HEIGHT + i * SPACING) i += 1 # Text txt = QGraphicsSimpleTextItem(name, r) txt.setPos(r.boundingRect().center() - txt.boundingRect().center()) # Line line = PlotLine(0, 0, OUTLINE_WIDTH + SPACING, 0) line.setPos(TITLE_WIDTH, r.mapToScene(r.rect().center()).y()) s.addItem(line) line.setPen(QPen(color, 5)) line.setToolTip(self.tr("Plot: ") + name) # We add the circles / references to text, on the line for ref2, circle, pos in refCircles: if ref2 == ref: circle.setParentItem(line) circle.setPos(pos.x(), 0) # self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio self.view.setSceneRect(0, 0, 0, 0)