rapid expand
This commit is contained in:
parent
98a3452a07
commit
839185d71d
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue