点击选中故事线特性开发完成
This commit is contained in:
parent
30574c9e1f
commit
74d7f05dca
|
@ -7,6 +7,8 @@
|
||||||
<list default="true" id="f609c0f2-cd0d-4eea-87f1-8caf02d3f04f" name="Changes" comment="">
|
<list default="true" id="f609c0f2-cd0d-4eea-87f1-8caf02d3f04f" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/frame/ContentView.py" beforeDir="false" afterPath="$PROJECT_DIR$/frame/ContentView.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/frame/ContentView.py" beforeDir="false" afterPath="$PROJECT_DIR$/frame/ContentView.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/graph/DataType.py" beforeDir="false" afterPath="$PROJECT_DIR$/graph/DataType.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGLayout.py" beforeDir="false" afterPath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGLayout.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGPresent.py" beforeDir="false" afterPath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGPresent.py" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGPresent.py" beforeDir="false" afterPath="$PROJECT_DIR$/graph/directed_acyclic_graph/DAGPresent.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
@ -190,7 +192,7 @@
|
||||||
<component name="SharedIndexes">
|
<component name="SharedIndexes">
|
||||||
<attachedChunks>
|
<attachedChunks>
|
||||||
<set>
|
<set>
|
||||||
<option value="bundled-python-sdk-50da183f06c8-d3b881c8e49f-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-233.13135.95" />
|
<option value="bundled-python-sdk-5b207ade9991-746f403e7f0c-com.jetbrains.pycharm.community.sharedIndexes.bundled-PC-241.17890.14" />
|
||||||
</set>
|
</set>
|
||||||
</attachedChunks>
|
</attachedChunks>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import sys
|
import sys
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
|
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QMainWindow
|
||||||
|
from PyQt5.QtWidgets import QMenu,QAction
|
||||||
|
from PyQt5.QtCore import QPoint
|
||||||
|
|
||||||
from graph.DataType import Arrow, Point
|
from graph.DataType import Arrow, Point
|
||||||
from graph.directed_acyclic_graph.DAGPresent import DAGActiveView, Direction
|
from graph.directed_acyclic_graph.DAGPresent import DAGActiveView, Direction
|
||||||
|
@ -10,21 +12,24 @@ from parse.ast_load import global_ast_path
|
||||||
|
|
||||||
|
|
||||||
class FragmentPoint(Point):
|
class FragmentPoint(Point):
|
||||||
def __init__(self, name: str, start_mark: bool):
|
def __init__(self, name: str):
|
||||||
Point.__init__(self, name, start_mark)
|
Point.__init__(self, name)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ContentWindow(QWidget):
|
class ContentWindow(QMainWindow):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
QWidget.__init__(self, parent)
|
QMainWindow.__init__(self, parent)
|
||||||
layout = QVBoxLayout(self)
|
self.fragment_view = DAGActiveView(self)
|
||||||
self.fragment_view = DAGActiveView(Direction.RankLR, self)
|
self.setCentralWidget(self.fragment_view)
|
||||||
layout.addWidget(self.fragment_view)
|
self.fragment_view.nodes_clicked.connect(self.print_node_list)
|
||||||
|
self.present_graph: Dict[str, StoryMap] = None
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def present_stories_graph(self, graph: Dict[str, StoryMap]) -> None:
|
def present_stories_graph(self, graph: Dict[str, StoryMap]) -> None:
|
||||||
|
self.present_graph = graph
|
||||||
|
|
||||||
arrows: List[Arrow] = []
|
arrows: List[Arrow] = []
|
||||||
for story_name in graph:
|
for story_name in graph:
|
||||||
fragments = graph[story_name].slice_list
|
fragments = graph[story_name].slice_list
|
||||||
|
@ -42,8 +47,8 @@ class ContentWindow(QWidget):
|
||||||
end_node_label = f"{end_frag.story_refer}&{end_frag.fragm_refer}"
|
end_node_label = f"{end_frag.story_refer}&{end_frag.fragm_refer}"
|
||||||
|
|
||||||
arrows.append(Arrow(
|
arrows.append(Arrow(
|
||||||
FragmentPoint(start_node_label, fragi == 1),
|
FragmentPoint(start_node_label),
|
||||||
FragmentPoint(end_node_label, False))
|
FragmentPoint(end_node_label))
|
||||||
)
|
)
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
@ -51,6 +56,60 @@ class ContentWindow(QWidget):
|
||||||
self.fragment_view.update_with_edges(arrows)
|
self.fragment_view.update_with_edges(arrows)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def print_node_list(self, xpos, ypos, list):
|
||||||
|
if len(list) == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(list) > 1:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
node_x = list[0]
|
||||||
|
if node_x[0].startswith("node"):
|
||||||
|
node_sections = [s for s in node_x[1].split("&") if s != ""]
|
||||||
|
if len(node_sections) == 1:
|
||||||
|
story = self.present_graph[node_sections[0]]
|
||||||
|
node_names = [node_sections[0]]
|
||||||
|
for slice in story.slice_list[1:]:
|
||||||
|
if slice.is_define_node[0]:
|
||||||
|
node_names.append(f"{slice.parent_story}&{slice.is_define_node[1]}")
|
||||||
|
else:
|
||||||
|
node_names.append(f"{slice.story_refer}&{slice.fragm_refer}")
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
self.fragment_view.highlight_graph_link(node_names)
|
||||||
|
pass
|
||||||
|
elif len(node_sections) > 1:
|
||||||
|
story_node = self.present_graph[node_sections[0]]
|
||||||
|
fragm_node = story_node.get_fragment_defined(node_sections[1])
|
||||||
|
|
||||||
|
story_list = [node_sections[0]]
|
||||||
|
for vsname in fragm_node.refers_slice:
|
||||||
|
if vsname not in story_list:
|
||||||
|
story_list.append(vsname)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
if len(story_list) == 1:
|
||||||
|
self.print_node_list(xpos, ypos, [("node", story_list[0])])
|
||||||
|
elif len(story_list) > 1:
|
||||||
|
menu = QMenu()
|
||||||
|
for story in story_list:
|
||||||
|
def trigger(story_name:str):
|
||||||
|
return lambda : self.print_node_list(xpos, ypos, [("node", story_name)])
|
||||||
|
|
||||||
|
menu.addAction(f"story/{story}", trigger(story))
|
||||||
|
pass
|
||||||
|
|
||||||
|
menu.exec(self.fragment_view.mapToGlobal(QPoint(xpos, ypos)))
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print(story_list)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
@ -60,4 +119,6 @@ if __name__ == "__main__":
|
||||||
tool = XAST_ParseTool(global_ast_path)
|
tool = XAST_ParseTool(global_ast_path)
|
||||||
view.present_stories_graph(tool.get_story_graph())
|
view.present_stories_graph(tool.get_story_graph())
|
||||||
|
|
||||||
|
# view.fragment_view.highlight_graph_link(["血脉的源头", "血脉的源头&待续"])
|
||||||
|
|
||||||
app.exec()
|
app.exec()
|
|
@ -12,16 +12,15 @@ class Pos:
|
||||||
|
|
||||||
|
|
||||||
class Point:
|
class Point:
|
||||||
def __init__(self, name:str, start_mark: bool):
|
def __init__(self, name:str):
|
||||||
self.point_name = name
|
self.point_name = name
|
||||||
self.is_start = start_mark
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self.point_name
|
return self.point_name
|
||||||
|
|
||||||
def make_copy(self) -> 'Point':
|
def make_copy(self) -> 'Point':
|
||||||
return Point(self.point_name, self.is_start)
|
return Point(self.point_name)
|
||||||
|
|
||||||
|
|
||||||
class Line:
|
class Line:
|
||||||
|
|
Binary file not shown.
|
@ -36,11 +36,12 @@ class DAGLayerHelper:
|
||||||
|
|
||||||
|
|
||||||
class DAGOrderHelper:
|
class DAGOrderHelper:
|
||||||
def __init__(self, level:int = 0, relate:DAGLayerHelper|None = None, bind: DAGLayerHelper|None = None):
|
def __init__(self, relate:DAGLayerHelper|None, towards:DAGLayerHelper | None, bind:DAGLayerHelper|None):
|
||||||
self.layer_bind = bind
|
self.layer_bind = bind
|
||||||
self.relate_bind = relate
|
self.relate_bind = relate
|
||||||
|
self.towards_to = towards
|
||||||
|
|
||||||
self.layer_number = level
|
self.layer_number = 0
|
||||||
self.sort_number:float = 0
|
self.sort_number:float = 0
|
||||||
self.__prev_layer_nodes: List['DAGOrderHelper'] = []
|
self.__prev_layer_nodes: List['DAGOrderHelper'] = []
|
||||||
|
|
||||||
|
@ -161,14 +162,15 @@ class DAGGraph:
|
||||||
|
|
||||||
def __node_layering(self, inst: DAGLayerHelper, layer_current: int = 0) -> int:
|
def __node_layering(self, inst: DAGLayerHelper, layer_current: int = 0) -> int:
|
||||||
"""
|
"""
|
||||||
节点分层处理,返回路径最大长度
|
节点分层处理,返回本次执行路径最大长度
|
||||||
:param inst: 当前节点
|
:param inst: 当前节点
|
||||||
:param layer_current: 节点等级
|
:param layer_current: 节点等级
|
||||||
:return: 最长路径长度
|
:return: 最长路径长度
|
||||||
"""
|
"""
|
||||||
inst.layer_v = max(inst.layer_v, layer_current)
|
max_remains = layer_current
|
||||||
|
if layer_current == 0 or inst.layer_v < layer_current:
|
||||||
|
inst.layer_v = layer_current
|
||||||
|
|
||||||
max_remains = inst.layer_v
|
|
||||||
values = inst.next_nodes()
|
values = inst.next_nodes()
|
||||||
for fork in values:
|
for fork in values:
|
||||||
max_remains = max(self.__node_layering(fork, inst.layer_v + 1), max_remains)
|
max_remains = max(self.__node_layering(fork, inst.layer_v + 1), max_remains)
|
||||||
|
@ -181,7 +183,7 @@ class DAGGraph:
|
||||||
|
|
||||||
# 注册所有数据图实节点
|
# 注册所有数据图实节点
|
||||||
for node in self.graph_inst.values():
|
for node in self.graph_inst.values():
|
||||||
nodes_temp[node.bind_point().point_name] = DAGOrderHelper(bind=node, relate=node)
|
nodes_temp[node.bind_point().point_name] = DAGOrderHelper(bind=node, relate=None, towards=None)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
temp_array: List[DAGOrderHelper] = []
|
temp_array: List[DAGOrderHelper] = []
|
||||||
|
@ -192,7 +194,8 @@ class DAGGraph:
|
||||||
for next in node.next_nodes():
|
for next in node.next_nodes():
|
||||||
node_links = [nodes_temp[node.bind_point().point_name]]
|
node_links = [nodes_temp[node.bind_point().point_name]]
|
||||||
for layer_index in range(node.layer_v + 1, next.layer_v):
|
for layer_index in range(node.layer_v + 1, next.layer_v):
|
||||||
node_links.append(DAGOrderHelper(layer_index, relate=node))
|
node_links.append(DAGOrderHelper(relate=node, towards=next, bind=None))
|
||||||
|
node_links[-1].layer_number = layer_index
|
||||||
pass
|
pass
|
||||||
|
|
||||||
node_links.append(nodes_temp[next.bind_point().point_name])
|
node_links.append(nodes_temp[next.bind_point().point_name])
|
||||||
|
|
|
@ -2,14 +2,32 @@ from graph.directed_acyclic_graph.DAGLayout import DAGGraph, DAGOrderHelper
|
||||||
from graph.DataType import Arrow, Point
|
from graph.DataType import Arrow, Point
|
||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
from PyQt5.QtWidgets import QWidget, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem
|
from PyQt5.QtWidgets import QWidget, QApplication, QGraphicsView, QGraphicsScene, QGraphicsItem
|
||||||
from PyQt5.QtCore import QRectF, Qt, QPointF
|
from PyQt5.QtCore import QRectF, Qt, QPointF, pyqtSignal
|
||||||
from PyQt5.QtGui import QFont, QBrush, QPen, QPainter, QPainterPath
|
from PyQt5.QtGui import QFont, QBrush, QPen, QPainter, QPainterPath, QMouseEvent
|
||||||
import sys
|
import sys
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class GraphNodeType(Enum):
|
||||||
|
ActivePresentNode = 0,
|
||||||
|
PenetrateNode = 1,
|
||||||
|
TransitionCurve = 2,
|
||||||
|
|
||||||
|
|
||||||
class GraphNode:
|
class GraphNode:
|
||||||
|
@abstractmethod
|
||||||
|
def node_type(self) -> GraphNodeType:
|
||||||
|
raise NotImplementedError("node_type")
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def highlight(self, flag: bool):
|
||||||
|
raise NotImplementedError("highlight")
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def is_highlighted(self) -> bool:
|
||||||
|
raise NotImplementedError("is_highlighted")
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def boundingRect(self) -> QRectF:
|
def boundingRect(self) -> QRectF:
|
||||||
raise NotImplementedError("boundingRect")
|
raise NotImplementedError("boundingRect")
|
||||||
|
@ -35,12 +53,23 @@ class ActivePresentNode(QGraphicsItem, GraphNode):
|
||||||
def __init__(self, name: str, type: StoryNodeType, font: QFont, parent):
|
def __init__(self, name: str, type: StoryNodeType, font: QFont, parent):
|
||||||
QGraphicsItem.__init__(self, parent)
|
QGraphicsItem.__init__(self, parent)
|
||||||
|
|
||||||
|
self.__highlight_mark = False
|
||||||
self.node_type_within_story = type
|
self.node_type_within_story = type
|
||||||
self.fragment_name = name
|
self.fragment_name = name
|
||||||
self.font_bind = font
|
self.font_bind = font
|
||||||
self.data_bind: object = None
|
self.data_bind: object = None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def node_type(self) -> GraphNodeType:
|
||||||
|
return GraphNodeType.ActivePresentNode
|
||||||
|
|
||||||
|
def highlight(self, flag: bool):
|
||||||
|
self.__highlight_mark = flag
|
||||||
|
pass
|
||||||
|
|
||||||
|
def is_highlighted(self) -> bool:
|
||||||
|
return self.__highlight_mark
|
||||||
|
|
||||||
def boundingRect(self) -> QRectF:
|
def boundingRect(self) -> QRectF:
|
||||||
size = self.font_bind.pixelSize()
|
size = self.font_bind.pixelSize()
|
||||||
if self.node_type_within_story == StoryNodeType.FragmentNode:
|
if self.node_type_within_story == StoryNodeType.FragmentNode:
|
||||||
|
@ -53,10 +82,16 @@ class ActivePresentNode(QGraphicsItem, GraphNode):
|
||||||
text_rect = QRectF(outline.x() + 5, outline.y() + 5, outline.width() - 10, outline.height() - 10)
|
text_rect = QRectF(outline.x() + 5, outline.y() + 5, outline.width() - 10, outline.height() - 10)
|
||||||
|
|
||||||
painter.save()
|
painter.save()
|
||||||
|
|
||||||
if self.node_type_within_story == StoryNodeType.FragmentNode:
|
if self.node_type_within_story == StoryNodeType.FragmentNode:
|
||||||
painter.fillRect(outline, QBrush(Qt.gray))
|
painter.fillRect(outline, Qt.gray)
|
||||||
else:
|
else:
|
||||||
painter.fillRect(outline, Qt.green)
|
painter.fillRect(outline, Qt.green)
|
||||||
|
pass
|
||||||
|
|
||||||
|
if self.__highlight_mark:
|
||||||
|
painter.setPen(Qt.red)
|
||||||
|
|
||||||
painter.drawRect(outline)
|
painter.drawRect(outline)
|
||||||
painter.setFont(self.font_bind)
|
painter.setFont(self.font_bind)
|
||||||
painter.drawText(text_rect, self.fragment_name)
|
painter.drawText(text_rect, self.fragment_name)
|
||||||
|
@ -83,9 +118,20 @@ class PenetrateNode(QGraphicsItem, GraphNode):
|
||||||
def __init__(self, width: float, parent):
|
def __init__(self, width: float, parent):
|
||||||
QGraphicsItem.__init__(self, parent)
|
QGraphicsItem.__init__(self, parent)
|
||||||
self.width_store = width
|
self.width_store = width
|
||||||
|
self.__highlight_mark = False
|
||||||
self.data_bind: object = None
|
self.data_bind: object = None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def node_type(self) -> GraphNodeType:
|
||||||
|
return GraphNodeType.PenetrateNode
|
||||||
|
|
||||||
|
def highlight(self, flag: bool):
|
||||||
|
self.__highlight_mark = flag
|
||||||
|
pass
|
||||||
|
|
||||||
|
def is_highlighted(self) -> bool:
|
||||||
|
return self.__highlight_mark
|
||||||
|
|
||||||
def resize_width(self, width: float):
|
def resize_width(self, width: float):
|
||||||
self.width_store = width
|
self.width_store = width
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -98,7 +144,13 @@ class PenetrateNode(QGraphicsItem, GraphNode):
|
||||||
outline = self.boundingRect()
|
outline = self.boundingRect()
|
||||||
|
|
||||||
painter.save()
|
painter.save()
|
||||||
|
|
||||||
|
if self.__highlight_mark:
|
||||||
|
painter.fillRect(QRectF(0, 2, outline.width(), 4), Qt.red)
|
||||||
|
else:
|
||||||
painter.fillRect(QRectF(0, 2, outline.width(), 4), Qt.black)
|
painter.fillRect(QRectF(0, 2, outline.width(), 4), Qt.black)
|
||||||
|
pass
|
||||||
|
|
||||||
painter.restore()
|
painter.restore()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -111,9 +163,10 @@ class PenetrateNode(QGraphicsItem, GraphNode):
|
||||||
return self.data_bind
|
return self.data_bind
|
||||||
|
|
||||||
|
|
||||||
class TransitionCurve(QGraphicsItem):
|
class TransitionCurve(QGraphicsItem, GraphNode):
|
||||||
def __init__(self, start: GraphNode, end: GraphNode, prev_layrer_width:float, parent):
|
def __init__(self, start: GraphNode, end: GraphNode, prev_layrer_width:float, parent):
|
||||||
QGraphicsItem.__init__(self, parent)
|
QGraphicsItem.__init__(self, parent)
|
||||||
|
self.__highlight_mark = False
|
||||||
self.start_node = start
|
self.start_node = start
|
||||||
self.end_node = end
|
self.end_node = end
|
||||||
self.prev_layer_w = prev_layrer_width
|
self.prev_layer_w = prev_layrer_width
|
||||||
|
@ -121,6 +174,16 @@ class TransitionCurve(QGraphicsItem):
|
||||||
self.data_bind: object = None
|
self.data_bind: object = None
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def node_type(self) -> GraphNodeType:
|
||||||
|
return GraphNodeType.TransitionCurve
|
||||||
|
|
||||||
|
def highlight(self, flag: bool):
|
||||||
|
self.__highlight_mark = flag
|
||||||
|
pass
|
||||||
|
|
||||||
|
def is_highlighted(self) -> bool:
|
||||||
|
return self.__highlight_mark
|
||||||
|
|
||||||
def layout_refresh(self):
|
def layout_refresh(self):
|
||||||
orect = self.start_node.boundingRect()
|
orect = self.start_node.boundingRect()
|
||||||
erect = self.end_node.boundingRect()
|
erect = self.end_node.boundingRect()
|
||||||
|
@ -160,6 +223,10 @@ class TransitionCurve(QGraphicsItem):
|
||||||
control_pos1 = end_pos - QPointF((outline.width() - line_span)/3, 0)
|
control_pos1 = end_pos - QPointF((outline.width() - line_span)/3, 0)
|
||||||
|
|
||||||
npen = QPen(Qt.black)
|
npen = QPen(Qt.black)
|
||||||
|
if self.__highlight_mark:
|
||||||
|
npen = QPen(Qt.red)
|
||||||
|
pass
|
||||||
|
|
||||||
npen.setWidthF(4)
|
npen.setWidthF(4)
|
||||||
painter.setPen(npen)
|
painter.setPen(npen)
|
||||||
|
|
||||||
|
@ -188,21 +255,24 @@ class Direction(Enum):
|
||||||
|
|
||||||
|
|
||||||
class DAGActiveView(QGraphicsView):
|
class DAGActiveView(QGraphicsView):
|
||||||
def __init__(self, orie: Direction, parent):
|
nodes_clicked = pyqtSignal(int,int,list)
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
QGraphicsView.__init__(self, parent)
|
QGraphicsView.__init__(self, parent)
|
||||||
self.setViewportUpdateMode(QGraphicsView.ViewportUpdateMode.FullViewportUpdate)
|
self.setViewportUpdateMode(QGraphicsView.ViewportUpdateMode.FullViewportUpdate)
|
||||||
|
|
||||||
self.layer_span = 200
|
|
||||||
self.node_span = 20
|
|
||||||
|
|
||||||
self.orientation = orie
|
|
||||||
self.scene_bind = QGraphicsScene(self)
|
|
||||||
self.setScene(self.scene_bind)
|
|
||||||
|
|
||||||
font = QFont()
|
font = QFont()
|
||||||
font.setPixelSize(20)
|
font.setPixelSize(20)
|
||||||
self.setFont(font)
|
self.setFont(font)
|
||||||
|
|
||||||
|
self.layer_span = 200
|
||||||
|
self.node_span = 20
|
||||||
|
|
||||||
|
self.scene_bind = QGraphicsScene(self)
|
||||||
|
self.setScene(self.scene_bind)
|
||||||
|
|
||||||
|
self.__highlight_nodelist: List[GraphNode] = []
|
||||||
|
self.__total_graph_nodes: Dict[str, GraphNode] = {}
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def update_with_edges(self, arrows: List[Arrow]) -> None:
|
def update_with_edges(self, arrows: List[Arrow]) -> None:
|
||||||
|
@ -229,18 +299,30 @@ class DAGActiveView(QGraphicsView):
|
||||||
ypos_acc += curr_gnode.boundingRect().height()
|
ypos_acc += curr_gnode.boundingRect().height()
|
||||||
current_graphics_nodes.append(curr_gnode)
|
current_graphics_nodes.append(curr_gnode)
|
||||||
self.scene_bind.addItem(curr_gnode)
|
self.scene_bind.addItem(curr_gnode)
|
||||||
|
|
||||||
|
fragm_start = node.relate_bind.bind_point().point_name
|
||||||
|
fragm_end = node.towards_to.bind_node.point_name
|
||||||
|
node_key = (f"plac${fragm_start}::{fragm_end}-{node.layer_number}")
|
||||||
|
curr_gnode.node_key_bind = "plac", fragm_start, fragm_end, node.layer_number
|
||||||
|
self.__total_graph_nodes[node_key] = curr_gnode
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
if node.layer_bind.bind_point().is_start:
|
node_type_vx = StoryNodeType.FragmentNode
|
||||||
curr_gnode = ActivePresentNode(node.layer_bind.bind_point().point_name, StoryNodeType.StoryStartNode,
|
if node.layer_bind.input_count == 0:
|
||||||
self.font(), None)
|
node_type_vx = StoryNodeType.StoryStartNode
|
||||||
else:
|
|
||||||
curr_gnode = ActivePresentNode(node.layer_bind.bind_point().point_name, StoryNodeType.FragmentNode,
|
curr_gnode = ActivePresentNode(node.layer_bind.bind_point().point_name,
|
||||||
self.font(), None)
|
node_type_vx, self.font(), None)
|
||||||
|
|
||||||
curr_gnode.attach_data(node)
|
curr_gnode.attach_data(node)
|
||||||
curr_gnode.setPos(previous_node_end, ypos_acc)
|
curr_gnode.setPos(previous_node_end, ypos_acc)
|
||||||
ypos_acc += curr_gnode.boundingRect().height()
|
ypos_acc += curr_gnode.boundingRect().height()
|
||||||
current_graphics_nodes.append(curr_gnode)
|
current_graphics_nodes.append(curr_gnode)
|
||||||
self.scene_bind.addItem(curr_gnode)
|
self.scene_bind.addItem(curr_gnode)
|
||||||
|
|
||||||
|
node_key = f"node@{node.layer_bind.bind_point().point_name}"
|
||||||
|
curr_gnode.node_key_bind = "node", node.layer_bind.bind_point().point_name
|
||||||
|
self.__total_graph_nodes[node_key] = curr_gnode
|
||||||
pass
|
pass
|
||||||
|
|
||||||
ypos_acc += self.node_span
|
ypos_acc += self.node_span
|
||||||
|
@ -271,6 +353,24 @@ class DAGActiveView(QGraphicsView):
|
||||||
line_cmbn = TransitionCurve(prev_gnode, curr_gnode, prev_layer_width,None)
|
line_cmbn = TransitionCurve(prev_gnode, curr_gnode, prev_layer_width,None)
|
||||||
self.scene_bind.addItem(line_cmbn)
|
self.scene_bind.addItem(line_cmbn)
|
||||||
line_cmbn.layout_refresh()
|
line_cmbn.layout_refresh()
|
||||||
|
|
||||||
|
relate_node_name = ""
|
||||||
|
if prev_gnode.node_type() == GraphNodeType.ActivePresentNode:
|
||||||
|
relate_node_name = prev_gnode.get_data().layer_bind.bind_point().point_name
|
||||||
|
elif prev_gnode.node_type() == GraphNodeType.PenetrateNode:
|
||||||
|
relate_node_name = prev_gnode.get_data().relate_bind.bind_point().point_name
|
||||||
|
|
||||||
|
towards_node_name = ""
|
||||||
|
if curr_gnode.node_type() == GraphNodeType.ActivePresentNode:
|
||||||
|
towards_node_name = sort_helper.layer_bind.bind_point().point_name
|
||||||
|
elif curr_gnode.node_type() == GraphNodeType.PenetrateNode:
|
||||||
|
towards_node_name = sort_helper.towards_to.bind_point().point_name
|
||||||
|
|
||||||
|
fragm_start = relate_node_name
|
||||||
|
fragm_end = towards_node_name
|
||||||
|
node_key = f"curv&{relate_node_name}::{towards_node_name}-{sort_helper.layer_number}"
|
||||||
|
line_cmbn.node_key_bind = "curv", fragm_start, fragm_end, sort_helper.layer_number
|
||||||
|
self.__total_graph_nodes[node_key] = line_cmbn
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
@ -281,10 +381,62 @@ class DAGActiveView(QGraphicsView):
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def highlight_graph_link(self, highlight_path: List[str]):
|
||||||
|
for n in self.__highlight_nodelist:
|
||||||
|
n.highlight(False)
|
||||||
|
pass
|
||||||
|
self.__highlight_nodelist.clear()
|
||||||
|
|
||||||
|
start_node = self.__total_graph_nodes[f"node@{highlight_path[0]}"]
|
||||||
|
start_node.highlight(True)
|
||||||
|
self.__highlight_nodelist.append(start_node)
|
||||||
|
|
||||||
|
for idx in range(1, len(highlight_path)):
|
||||||
|
start_name = highlight_path[idx-1]
|
||||||
|
end_name = highlight_path[idx]
|
||||||
|
|
||||||
|
end_node = self.__total_graph_nodes[f"node@{end_name}"]
|
||||||
|
end_node.highlight(True)
|
||||||
|
self.__highlight_nodelist.append(end_node)
|
||||||
|
|
||||||
|
plac_key = f"plac${start_name}::{end_name}"
|
||||||
|
curv_key = f"curv&{start_name}::{end_name}"
|
||||||
|
for key in self.__total_graph_nodes:
|
||||||
|
if key.startswith(plac_key):
|
||||||
|
placex = self.__total_graph_nodes[key]
|
||||||
|
placex.highlight(True)
|
||||||
|
self.__highlight_nodelist.append(placex)
|
||||||
|
pass
|
||||||
|
if key.startswith(curv_key):
|
||||||
|
curvx = self.__total_graph_nodes[key]
|
||||||
|
curvx.highlight(True)
|
||||||
|
self.__highlight_nodelist.append(curvx)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.scene_bind.update()
|
||||||
|
self.update()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def mousePressEvent(self, event: QMouseEvent):
|
||||||
|
QGraphicsView.mousePressEvent(self, event)
|
||||||
|
|
||||||
|
gitems = self.items(event.pos())
|
||||||
|
noderef_names = []
|
||||||
|
for gnode in gitems:
|
||||||
|
if gnode.node_key_bind[0].startswith("node"):
|
||||||
|
noderef_names.append(gnode.node_key_bind)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.nodes_clicked.emit(event.pos().x(), event.pos().y(), noderef_names[0:1])
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
view = DAGActiveView(Direction.RankLR, None)
|
view = DAGActiveView(None)
|
||||||
view.show()
|
view.show()
|
||||||
|
|
||||||
arrows = [
|
arrows = [
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue