added typeaheead and introspetion
This commit is contained in:
@@ -14,6 +14,30 @@ private struct DiagramPoint: Codable {
|
|||||||
var y: Double
|
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
|
@MainActor
|
||||||
struct DBSynSchemaDiagramView: View {
|
struct DBSynSchemaDiagramView: View {
|
||||||
@ObservedObject var model: DatabaseModel
|
@ObservedObject var model: DatabaseModel
|
||||||
@@ -219,9 +243,17 @@ struct DBSynSchemaDiagramView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ForEach(objects, id: \.self) { name in
|
ForEach(objects, id: \.self) { name in
|
||||||
diagramNode(name)
|
DiagramDraggableNode(zoom: zoom, onDrop: { translation in
|
||||||
.position(x: position(name).x + nodeWidth / 2,
|
let start = position(name)
|
||||||
y: position(name).y + height(name) / 2)
|
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)
|
.frame(width: canvasWidth, height: canvasHeight, alignment: .topLeading)
|
||||||
@@ -317,18 +349,7 @@ struct DBSynSchemaDiagramView: View {
|
|||||||
.shadow(color: .black.opacity(0.13), radius: 3, y: 2)
|
.shadow(color: .black.opacity(0.13), radius: 3, y: 2)
|
||||||
.opacity(related ? 1 : 0.4)
|
.opacity(related ? 1 : 0.4)
|
||||||
.onTapGesture { selectedObject = selectedObject == name ? nil : name }
|
.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
|
// Rebuild the visible canvas whenever the selected objects change. The
|
||||||
// previous implementation only saved the checkboxes, leaving the diagram
|
// previous implementation only saved the checkboxes, leaving the diagram
|
||||||
|
|||||||
Reference in New Issue
Block a user