added typeaheead and introspetion

This commit is contained in:
Mark Gregory
2026-10-19 09:38:08 +01:00
parent 66e1845fc6
commit f63d40ff48
+35 -14
View File
@@ -14,6 +14,30 @@ private struct DiagramPoint: Codable {
var y: Double
}
// Keep the drag translation local to the node. Updating the entire diagram's
// positions dictionary on every mouse event caused layout churn and jerky drags.
private struct DiagramDraggableNode<Content: View>: View {
let zoom: CGFloat
let onDrop: (CGSize) -> Void
@ViewBuilder let content: () -> Content
@GestureState private var translation: CGSize = .zero
var body: some View {
content()
.offset(x: translation.width / max(zoom, 0.1),
y: translation.height / max(zoom, 0.1))
.highPriorityGesture(
DragGesture(minimumDistance: 3, coordinateSpace: .global)
.updating($translation) { value, state, _ in
state = value.translation
}
.onEnded { value in
onDrop(value.translation)
}
)
}
}
@MainActor
struct DBSynSchemaDiagramView: View {
@ObservedObject var model: DatabaseModel
@@ -219,9 +243,17 @@ struct DBSynSchemaDiagramView: View {
}
}
ForEach(objects, id: \.self) { name in
diagramNode(name)
.position(x: position(name).x + nodeWidth / 2,
y: position(name).y + height(name) / 2)
DiagramDraggableNode(zoom: zoom, onDrop: { translation in
let start = position(name)
positions[name] = CGPoint(
x: max(10, start.x + translation.width / max(zoom, 0.1)),
y: max(10, start.y + translation.height / max(zoom, 0.1)))
savePositions()
}) {
diagramNode(name)
}
.position(x: position(name).x + nodeWidth / 2,
y: position(name).y + height(name) / 2)
}
}
.frame(width: canvasWidth, height: canvasHeight, alignment: .topLeading)
@@ -317,18 +349,7 @@ struct DBSynSchemaDiagramView: View {
.shadow(color: .black.opacity(0.13), radius: 3, y: 2)
.opacity(related ? 1 : 0.4)
.onTapGesture { selectedObject = selectedObject == name ? nil : name }
.gesture(DragGesture(minimumDistance: 4)
.onChanged { value in
let current = position(name)
// DragGesture.translation is relative to the gesture start.
if dragOrigins[name] == nil { dragOrigins[name] = current }
let start = dragOrigins[name] ?? current
positions[name] = CGPoint(x: max(10, start.x + value.translation.width / zoom),
y: max(10, start.y + value.translation.height / zoom))
}
.onEnded { _ in dragOrigins.removeValue(forKey: name); savePositions() })
}
@State private var dragOrigins: [String: CGPoint] = [:]
// Rebuild the visible canvas whenever the selected objects change. The
// previous implementation only saved the checkboxes, leaving the diagram