Save layouts

This commit is contained in:
Audrey 2022-11-16 14:16:38 -07:00
parent 8e23aae786
commit 46baaeeabb
1 changed files with 40 additions and 27 deletions

View File

@ -78,6 +78,8 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self.current_group: Union[ObjectContainer, RelativeAtomGroup] = ObjectContainer(hg.root_group if current_group is None else current_group)
self.selected_nodes: Union[ObjectContainer, Set[RelativeAtomOrGroupOrExtern]] = ObjectContainer(set())
self.instance = instance
self._old_group: RelativeAtomGroup = self.current_group.am_obj
self._layouts: Dict[RelativeAtomGroup, Dict[RelativeAtomOrGroupOrExtern, QPointF]] = defaultdict(dict)
self.qnodes: List[HGNode] = []
self.qedges: List[HGArrow] = []
@ -208,7 +210,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
qedge.layout()
qedge.enter()
self._update_scene_rect()
self._update_scene_rect(False)
@property
def is_expanding(self):
@ -397,25 +399,20 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
if ibr.isEmpty():
ibr = QRectF(0, -1000, 1000, 1000)
for i, node in enumerate(self.ug_lookup):
if isinstance(node, ExternNode):
qnode = old_nodes.pop(node, None)
if qnode is None:
qnode = old_nodes.pop(node, None)
if qnode is None:
if isinstance(node, ExternNode):
qnode = HGExtern(None, model=node, hgw=self)
entering.add(qnode)
qnode.center = rand_point(ibr, i)
self.qnodes.append(qnode)
else:
qnode = old_nodes.pop(node, None)
if qnode is None:
else:
qnode = PropChartHG(
None,
byte_height=byte_height,
model=node,
hgw=self,
)
entering.add(qnode)
qnode.center = rand_point(ibr, i)
self.qnodes.append(qnode)
entering.add(qnode)
qnode.center = self._layouts[self.current_group.am_obj].get(node, rand_point(ibr, i))
self.qnodes.append(qnode)
for model, qnode in zip(self.ug_lookup, self.qnodes):
qnode.set_expandable(self.can_expand(model))
@ -459,9 +456,9 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
qnode.enter()
self.ag = networkx.drawing.nx_agraph.to_agraph(self.ug)
self._iterate_layout(maxiter)
self._iterate_layout(maxiter, pin_known=True)
def _iterate_layout(self, maxiter=1):
def _iterate_layout(self, maxiter=1, pin_known=False):
if not maxiter:
return
if self._layout_lock.acquire(blocking=False):
@ -472,7 +469,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
qnode = self.qnodes[idx]
qnode.set_agraph_node_properties(node)
node.attr['pos'] = render_pos(qnode.center)
node.attr['pin'] = str(qnode.pinned).lower()
node.attr['pin'] = str(qnode.pinned or (pin_known and qnode.model in self._layouts[self.current_group.am_obj])).lower()
for edge in self.ag.edges_iter():
edge.attr['len'] = self.layout_social_distancing
self.ag.graph_attr['overlap'] = self.layout_overlap
@ -493,27 +490,39 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
for edge in self.qedges:
edge.layout()
self._update_scene_rect()
self._update_scene_rect(False)
finally:
self._layout_event_occurring = False
self._layout_lock.release()
else:
l.warning("Layout lock conflict. Is the application lagging?")
def _update_scene_rect(self):
def _update_scene_rect(self, scene_change):
rect = None
for item in self.items():
if isinstance(item, AnimatableItem) and item.exiting:
continue
br = item.boundingRect()
br.translate(item.x(), item.y())
rect = rect.united(br) if rect is not None else br
if rect is None:
rect = self.mapToScene(self.viewport().rect()).boundingRect()
if not scene_change:
if rect is None:
rect = self.mapToScene(self.viewport().rect()).boundingRect()
else:
rect = rect.marginsAdded(QMarginsF(SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN))
rect = rect.united(self.mapToScene(self.viewport().rect()).boundingRect())
center = self.mapToScene(self.viewport().rect().center())
self.setSceneRect(rect)
self.centerOn(center)
else:
rect = rect.marginsAdded(QMarginsF(SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN))
rect = rect.united(self.mapToScene(self.viewport().rect()).boundingRect())
center = self.mapToScene(self.viewport().rect().center())
self.setSceneRect(rect)
self.centerOn(center)
if rect is None:
rect = QRectF()
else:
rect = rect.marginsAdded(QMarginsF(SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN, SCENE_MARGIN))
self.setSceneRect(rect)
self.resetTransform()
self.centerOn(self.sceneRect().center())
# qt overrides
@ -550,9 +559,10 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
# objectcontainer event handlers
def _on_change_group(self, **kwargs):
self._layouts[self._old_group] = {qnode.model: qnode.center for qnode in self.qnodes}
self._old_group = self.current_group.am_obj
self._layout(600)
self.resetTransform()
self.centerOn(self.sceneRect().center())
self._update_scene_rect(True)
def _on_selection_changed(self, src=None, **kwargs):
if src == 'qt':
@ -586,6 +596,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
class AnimatableItem(QGraphicsItem):
def __init__(self, *args, **kwargs):
self.timeline: Optional[QTimeLine] = None
self.exiting = False
super().__init__(*args, **kwargs)
def _start_animation(self, animation, duration, finished=None, ease=QEasingCurve.Linear):
@ -614,6 +625,7 @@ class HGNode(AnimatableItem):
# public interfaces
def exit(self, duration=250):
self.exiting = True
for edge in self.edges.values():
edge.orient(self, away=True)
edge.exit(duration)
@ -967,6 +979,7 @@ class HGArrow(AnimatableItem):
self.percentage = value
def exit(self, duration=250):
self.exiting = True
self._start_animation(self._animate_exit, duration, self._finish_exit)
def _animate_exit(self, value):