manuskript/manuskript/ui/views/storylineView.py
2016-02-27 21:48:38 +01:00

195 lines
6.1 KiB
Python

#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QBrush, QPen
from PyQt5.QtWidgets import QWidget, QGraphicsScene, QGraphicsSimpleTextItem, QMenu, QAction, QGraphicsRectItem, \
QGraphicsLineItem
from manuskript.functions import randomColor
from manuskript.ui.views.storylineView_ui import Ui_storylineView
class storylineView(QWidget, Ui_storylineView):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setupUi(self)
self._mdlPlots = None
self.btnRefresh.clicked.connect(self.refresh)
self.scene = QGraphicsScene()
self.view.setScene(self.scene)
self.reloadTimer = QTimer()
self.reloadTimer.timeout.connect(self.refresh)
self.reloadTimer.setSingleShot(True)
self.reloadTimer.setInterval(500)
self.generateMenu()
def generateMenu(self):
m = QMenu()
for i in [
self.tr("Show Plots"),
self.tr("Show Characters"),
self.tr("Show Objects"),
]:
a = QAction(i, m)
a.setCheckable(True)
a.setEnabled(False)
m.addAction(a)
self.btnSettings.setMenu(m)
def setModels(self, mdlOutline, mdlPersos, mdlPlots):
self._mdlPlots = mdlPlots
# self._mdlPlots.dataChanged.connect(self.refresh)
# self._mdlPlots.rowsInserted.connect(self.refresh)
self._mdlOutline = mdlOutline
self._mdlOutline.dataChanged.connect(self.reloadTimer.start)
self._mdlPersos = mdlPersos
self._mdlPersos.dataChanged.connect(self.reloadTimer.start)
def refresh(self):
if not self._mdlPlots or not self._mdlOutline or not self._mdlPersos:
pass
LINE_HEIGHT = 32
SPACING = 6
RECT_WIDTH = 200
TEXT_WIDTH = 25
LEVEL_HEIGHT = 12
s = self.scene
s.clear()
# Get Max Level
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 plots
plotsID = self._mdlPlots.getPlotsByImportance()
plots = []
for importance in plotsID:
for ID in importance:
name = self._mdlPlots.getPlotNameByID(ID)
plots.append((ID, name))
ROWS_HEIGHT = len(plots) * (LINE_HEIGHT + SPACING )
# Add Folders and Texts
outline = OutlineRect(0, 0, 0, ROWS_HEIGHT + SPACING + MAX_LEVEL * LEVEL_HEIGHT)
s.addItem(outline)
outline.setPos(RECT_WIDTH + SPACING, 0)
# A Function to add a rect with centered 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)
r.setPos(x, deltaH)
r.setToolTip(tooltip)
txt = QGraphicsSimpleTextItem(text, r)
f = txt.font()
f.setPointSize(8)
txt.setFont(f)
txt.setPos(r.boundingRect().center() - txt.boundingRect().center())
txt.setY(0)
return r
def itemWidth(item):
if item.isFolder():
r = 0
for c in item.children():
r += itemWidth(c)
return r
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())
listItems(child, parent, level + 1)
else:
addRectText(delta, TEXT_WIDTH, rect, "", level, tooltip=child.title())
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, name in plots:
color = randomColor()
# Rect
r = QGraphicsRectItem(0, 0, RECT_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(RECT_WIDTH,
r.mapToScene(r.rect().center()).y(),
OUTLINE_WIDTH + RECT_WIDTH + SPACING,
r.mapToScene(r.rect().center()).y())
s.addItem(line)
line.setPen(QPen(color, 5))
line.setToolTip(self.tr("Plot: ") + name)
# self.view.fitInView(0, 0, TOTAL_WIDTH, i * LINE_HEIGHT, Qt.KeepAspectRatioByExpanding) # KeepAspectRatio
self.view.setSceneRect(0, 0, 0, 0)
class OutlineRect(QGraphicsRectItem):
def __init__(self, x, y, w, h, parent=None):
QGraphicsRectItem.__init__(self, x, y, w, h, parent)
self.setBrush(Qt.white)
self.setAcceptHoverEvents(True)
def hoverEnterEvent(self, QGraphicsSceneHoverEvent):
self.setBrush(Qt.lightGray)
def hoverLeaveEvent(self, QGraphicsSceneHoverEvent):
self.setBrush(Qt.white)
class PlotLine(QGraphicsLineItem):
def __init__(self, x1, y1, x2, y2, parent=None):
QGraphicsLineItem.__init__(self, x1, y1, x2, y2, parent)
self.setAcceptHoverEvents(True)
def hoverEnterEvent(self, QGraphicsSceneHoverEvent):
p = self.pen()
p.setWidth(10)
self.setPen(p)
def hoverLeaveEvent(self, QGraphicsSceneHoverEvent):
p = self.pen()
p.setWidth(5)
self.setPen(p)