rapid expand

This commit is contained in:
Audrey 2022-11-21 07:07:00 -07:00
parent 98a3452a07
commit 839185d71d
1 changed files with 65 additions and 33 deletions

View File

@ -8,7 +8,7 @@ from threading import Lock
import logging
from PySide6.QtCore import QRectF, QPointF, QTimeLine, QEasingCurve, QMarginsF, QTimer, Qt, QEvent
from PySide6.QtGui import QColor, QFont, QBrush, QPainterPath, QPen, QAction, QShortcut
from PySide6.QtGui import QColor, QFont, QBrush, QPainterPath, QPen, QAction, QShortcut, QMouseEvent
from PySide6.QtWidgets import QGraphicsItem, QGraphicsRectItem, QGraphicsSimpleTextItem, QHBoxLayout, QGraphicsScene, \
QGraphicsEllipseItem, QGraphicsSceneMouseEvent, QMenu, QDialog, QVBoxLayout, QLineEdit, QInputDialog, QMessageBox, \
QGraphicsLineItem, QGraphicsTextItem
@ -106,6 +106,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self._layout_animation = QTimer()
self._layout_animation_controller = QTimer()
self._mouse_is_down = False
self._rapid_expand = False
self._selection_event_occurring = False
self._layout_event_occurring = False
self.faux_frontier = faux_frontier or set()
@ -213,15 +214,17 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
def begin_expand(self, model: RelativeAtomOrGroup):
self.expansion_models = [adj for adj in set(chain(self.ng.succ[model], self.ng.pred[model])) if adj in self.faux_frontier]
if not self.expansion_models:
l.error("How'd you do that")
return
for other_model in self.expansion_models:
self._do_expand(other_model)
self._layout(0)
qnode = self.qnodes[self.ug_reverse[model]]
self.scene().clearSelection()
qnode.setSelected(True)
for other_qnode in self.qnodes:
other_qnode.setAcceptHoverEvents(False)
other_qnode.setAcceptedMouseButtons(Qt.MouseButton.NoButton | Qt.MouseButton.NoButton)
other_qnode.setAcceptedMouseButtons(Qt.MouseButtons.NoButton)
if qnode is other_qnode:
other_qnode.setOpacity(0.8)
else:
@ -241,7 +244,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
qnode,
other_qnode,
other_model in self.ng.succ[model],
other_model in self.ng.pred[model]
other_model in self.ng.pred[model],
) for other_qnode, other_model in zip(self.expansion_qnodes, self.expansion_models)]
tmp_ag = pygraphviz.AGraph()
@ -259,7 +262,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self.scene().addItem(other_qnode)
other_qnode.center = parse_pos(tmp_ag.get_node(idx).attr['pos']) - origin + qnode.center
other_qnode.enter()
other_qnode.set_expandable(False)
other_qnode.set_expandable(self.can_expand(other_qnode.model))
for qedge in self.expansion_qedges:
self.scene().addItem(qedge)
@ -275,7 +278,7 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
def end_expand(self, accepted_qnode: Optional['PropChartHG']=None):
for qnode in self.qnodes:
qnode.setAcceptHoverEvents(True)
qnode.setAcceptedMouseButtons(Qt.MouseButton.AllButtons | Qt.MouseButton.AllButtons)
qnode.setAcceptedMouseButtons(Qt.MouseButtons.AllButtons)
qnode.setOpacity(1)
for edge in self.qedges:
edge.setOpacity(1)
@ -300,22 +303,8 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self.expansion_qnodes.clear()
self.expansion_models.clear()
if accepted_qnode:
if accepted_qnode is not None and accepted_qnode.model in self.faux_frontier:
self.faux_frontier.remove(accepted_qnode.model)
existing_groups = [(g, self.label(g)) for g in self.current_group.children if isinstance(g, RelativeAtomGroup)]
existing_groups = {
self.instance.kb.functions[lbl].addr: g
for (g, lbl) in existing_groups
if lbl in self.instance.kb.functions
}
newgroups = self.hg.expand_by_key(accepted_qnode.model, self.current_group.am_obj, self.hg.kp.atom_to_function, dict(existing_groups))
for k, g in newgroups.items():
if k in existing_groups:
continue
if k in self.hg.kp.kb.functions and self.hg.kp.kb.functions[k].alignment:
self.ignore.add(g)
else:
self.faux_frontier.add(g)
self._layout(0)
def set_drop_target(self, item: Optional['PropChartHG']):
@ -441,6 +430,22 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
# private interfaces
def _do_expand(self, model: RelativeAtomOrGroup):
existing_groups = [(g, self.label(g)) for g in self.current_group.children if isinstance(g, RelativeAtomGroup)]
existing_groups = {
self.instance.kb.functions[lbl].addr: g
for (g, lbl) in existing_groups
if lbl in self.instance.kb.functions
}
newgroups = self.hg.expand_by_key(model, self.current_group.am_obj, self.hg.kp.atom_to_function, dict(existing_groups))
for k, g in newgroups.items():
if k in existing_groups:
continue
if k in self.hg.kp.kb.functions and self.hg.kp.kb.functions[k].alignment:
self.ignore.add(g)
else:
self.faux_frontier.add(g)
def _rekey_externs(self, old_qnode: 'PropChartHG', new_qnode: 'PropChartHG'):
old_extern_model = ExternNode(old_qnode.model)
new_extern_model = ExternNode(new_qnode.model)
@ -648,12 +653,27 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
def viewportEvent(self, event):
if event.type() == QEvent.Type.ContextMenu:
return False
elif isinstance(event, QMouseEvent) and event.type() == QMouseEvent.Type.MouseButtonPress:
if event.button() == Qt.MouseButton.LeftButton:
self._mouse_is_down = True
if (event.modifiers() & Qt.ShiftModifier) == Qt.NoModifier:
self.setDragMode(QZoomableDraggableGraphicsView.ScrollHandDrag)
else:
self.setDragMode(QZoomableDraggableGraphicsView.RubberBandDrag)
self.viewport().setCursor(Qt.CursorShape.CrossCursor)
return super().viewportEvent(event)
def keyPressEvent(self, event):
if event.key() == Qt.Key_Z and not self.is_expanding:
self._layout_animation.start()
event.accept()
elif event.key() == Qt.Key_X:
if event.modifiers() & Qt.KeyboardModifier.ControlModifier:
self._rapid_expand ^= True
else:
self._rapid_expand = True
event.accept()
else:
super().keyPressEvent(event)
@ -661,6 +681,12 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
if event.key() == Qt.Key_Z:
self._layout_animation.stop()
event.accept()
elif event.key() == Qt.Key_X:
if event.modifiers() & Qt.KeyboardModifier.ControlModifier:
self._rapid_expand ^= True
else:
self._rapid_expand = False
event.accept()
super().keyReleaseEvent(event)
def mouseDoubleClickEvent(self, event):
@ -672,16 +698,12 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self.current_group.am_event()
def mousePressEvent(self, event):
self._mouse_is_down = True
if (event.modifiers() & Qt.ShiftModifier) == Qt.NoModifier:
self.setDragMode(QZoomableDraggableGraphicsView.ScrollHandDrag)
else:
self.setDragMode(QZoomableDraggableGraphicsView.RubberBandDrag)
self.viewport().setCursor(Qt.CursorShape.CrossCursor)
super(QZoomableDraggableGraphicsView, self).mousePressEvent(event) # lol. lmao even
def mouseReleaseEvent(self, event):
self._mouse_is_down = False
if event.button() == Qt.MouseButton.LeftButton:
self._mouse_is_down = False
if self.drop_target is not None:
self.confirm_drop()
super().mouseReleaseEvent(event)
@ -723,6 +745,10 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
self._selection_event_occurring = False
def _on_selection_changed_internal(self):
if not self.items():
# don't do anything if we are closing the pane (there will be a desync between items() and qnodes/qedges)
return
if self.is_expanding:
items = self.scene().selectedItems()
if not items:
@ -735,10 +761,8 @@ class HierarchicalGraphWidget(QZoomableDraggableGraphicsView):
else:
l.error("How'd you select more than one item during expansion")
elif not self._selection_event_occurring:
if self.items():
# don't do this if we are closing the pane (there will be a desync between items() and qnodes)
self.selected_nodes.am_obj = {model for model, qnode in zip(self.ug_lookup, self.qnodes) if qnode.isSelected()}
self.selected_nodes.am_event(src='qt')
self.selected_nodes.am_obj = {model for model, qnode in zip(self.ug_lookup, self.qnodes) if qnode.isSelected()}
self.selected_nodes.am_event(src='qt')
for qedge in self.qedges:
qedge.update()
@ -1013,6 +1037,9 @@ class PropChartHG(HGNode, PropChart):
self.object_btn: Optional[PlusButton] = None
super().__init__(parent, **kwargs)
self.setAcceptHoverEvents(True)
self.setAcceptedMouseButtons(Qt.MouseButtons.AllButtons)
@property
def label(self):
return self.hgw.label(self.model)
@ -1059,7 +1086,6 @@ class PropChartHG(HGNode, PropChart):
else:
obj.setY(obj.y() + lbl_height)
self.setTransformOriginPoint(self.center - self.pos())
def set_expandable(self, expandable: bool):
@ -1067,6 +1093,7 @@ class PropChartHG(HGNode, PropChart):
def begin_expand(self):
if self.timeline.state() == QTimeLine.NotRunning:
self.hgw.end_expand(self)
self.hgw.begin_expand(self.model)
return True
else:
@ -1120,8 +1147,13 @@ class PropChartHG(HGNode, PropChart):
break
else:
self.hgw.set_drop_target(None)
super().mouseMoveEvent(event)
def hoverEnterEvent(self, event):
if self.hgw._rapid_expand:
self.begin_expand()
def emphasize(self, duration=100):
self._start_animation(self._animate_emphasize, duration)