merge modal location
This commit is contained in:
@@ -25,6 +25,7 @@ struct OverlayModal {
|
||||
let content: AnyView
|
||||
let buttons: [ModalButton]
|
||||
let anchor: CGRect?
|
||||
let inPane: Bool
|
||||
let canSubmit: @MainActor () -> Bool
|
||||
let done: (String) -> Void
|
||||
}
|
||||
@@ -49,7 +50,7 @@ final class Overlays {
|
||||
var leftTab = LeftTab.lead
|
||||
var leadFocus = 0
|
||||
@ObservationIgnored var pickerFrame: CGRect = .zero
|
||||
@ObservationIgnored var mergeFrame: CGRect?
|
||||
var paneFrame: CGRect = .zero
|
||||
@ObservationIgnored private var monitor: Any?
|
||||
|
||||
var isOpen: Bool {
|
||||
@@ -64,10 +65,10 @@ final class Overlays {
|
||||
alerts.append(OverlayAlert(content: AnyView(content)))
|
||||
}
|
||||
|
||||
func showModal(_ content: some View, _ buttons: [ModalButton], anchor: CGRect? = nil, canSubmit: @escaping @MainActor () -> Bool = { true }) async -> String {
|
||||
func showModal(_ content: some View, _ buttons: [ModalButton], anchor: CGRect? = nil, inPane: Bool = false, canSubmit: @escaping @MainActor () -> Bool = { true }) async -> String {
|
||||
modal?.done("cancel")
|
||||
return await withCheckedContinuation { cont in
|
||||
modal = OverlayModal(content: AnyView(content), buttons: buttons, anchor: anchor, canSubmit: canSubmit) { value in
|
||||
modal = OverlayModal(content: AnyView(content), buttons: buttons, anchor: anchor, inPane: inPane, canSubmit: canSubmit) { value in
|
||||
cont.resume(returning: value)
|
||||
}
|
||||
}
|
||||
@@ -248,7 +249,7 @@ struct OverlayHost: View {
|
||||
.onTapGesture {
|
||||
overlays.answerModal("cancel")
|
||||
}
|
||||
ModalPlacement(modal: m) { value in
|
||||
ModalPlacement(modal: m, pane: overlays.paneFrame) { value in
|
||||
overlays.answerModal(value)
|
||||
}
|
||||
}
|
||||
@@ -316,8 +317,25 @@ private struct AnchoredBox: Layout {
|
||||
}
|
||||
}
|
||||
|
||||
private struct PaneCenteredBox: Layout {
|
||||
let pane: CGRect
|
||||
|
||||
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
||||
proposal.replacingUnspecifiedDimensions()
|
||||
}
|
||||
|
||||
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
||||
let width = min(520, pane.width - 48)
|
||||
let size = subviews[0].sizeThatFits(ProposedViewSize(width: width, height: nil))
|
||||
let x = pane.midX - size.width / 2
|
||||
let y = min(max(overlayMargin, pane.midY - size.height / 2), bounds.height - overlayMargin - size.height)
|
||||
subviews[0].place(at: CGPoint(x: bounds.minX + x, y: bounds.minY + y), proposal: ProposedViewSize(width: width, height: size.height))
|
||||
}
|
||||
}
|
||||
|
||||
private struct ModalPlacement: View {
|
||||
let modal: OverlayModal
|
||||
let pane: CGRect
|
||||
let answer: (String) -> Void
|
||||
|
||||
var body: some View {
|
||||
@@ -327,6 +345,10 @@ private struct ModalPlacement: View {
|
||||
AnchoredBox(anchor: anchor) {
|
||||
box
|
||||
}
|
||||
} else if modal.inPane {
|
||||
PaneCenteredBox(pane: pane) {
|
||||
box
|
||||
}
|
||||
} else {
|
||||
box
|
||||
.padding(24)
|
||||
|
||||
Reference in New Issue
Block a user