-
-
Notifications
You must be signed in to change notification settings - Fork 58
Sheet Modifier #219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Sheet Modifier #219
Changes from all commits
d13cfaa
19d772d
daca3e4
d6a63f2
79837ed
b1e436b
3108f77
7df381c
8669cb6
ed300d2
a76ca7c
941131e
9d6542e
602ab54
af6da88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ public final class AppKitBackend: AppBackend { | |
public typealias Menu = NSMenu | ||
public typealias Alert = NSAlert | ||
public typealias Path = NSBezierPath | ||
public typealias Sheet = NSCustomSheet | ||
|
||
public let defaultTableRowContentHeight = 20 | ||
public let defaultTableCellVerticalPadding = 4 | ||
|
@@ -1685,6 +1686,113 @@ public final class AppKitBackend: AppBackend { | |
let request = URLRequest(url: url) | ||
webView.load(request) | ||
} | ||
|
||
public func createSheet() -> NSCustomSheet { | ||
// Initialize with a default contentRect, similar to window creation (lines 58-68) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refer to method name instead of lines (lines may change) |
||
let sheet = NSCustomSheet( | ||
contentRect: NSRect( | ||
x: 0, | ||
y: 0, | ||
width: 400, // Default width | ||
height: 300 // Default height | ||
), | ||
styleMask: [.titled, .closable], | ||
backing: .buffered, | ||
defer: true | ||
) | ||
return sheet | ||
} | ||
|
||
public func updateSheet( | ||
_ sheet: NSCustomSheet, content: NSView, onDismiss: @escaping () -> Void | ||
) { | ||
let contentSize = naturalSize(of: content) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Content size should be passed in from SwiftCrossUI because even if this works for AppKitBackend, not all backends will be able to infer the sizing that SwiftCrossUI has assigned to their sheet content. This may resolve the Gtk issues you were facing. |
||
|
||
let width = max(contentSize.x, 10) | ||
let height = max(contentSize.y, 10) | ||
sheet.setContentSize(NSSize(width: width, height: height)) | ||
|
||
sheet.contentView = content | ||
sheet.onDismiss = onDismiss | ||
} | ||
|
||
public func showSheet(_ sheet: NSCustomSheet, window: NSCustomWindow?) { | ||
guard let window else { | ||
print("warning: Cannot show sheet without a parent window") | ||
return | ||
} | ||
// critical sheets stack | ||
// beginSheet only shows a nested | ||
// sheet after its parent gets dismissed | ||
Comment on lines
+1724
to
+1726
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
window.beginCriticalSheet(sheet) | ||
} | ||
|
||
public func dismissSheet(_ sheet: NSCustomSheet, window: NSCustomWindow?) { | ||
if let window { | ||
window.endSheet(sheet) | ||
} else { | ||
NSApplication.shared.stopModal() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this necessary if showSheet never shows sheets without parent windows? |
||
} | ||
} | ||
|
||
public func setPresentationBackground(of sheet: NSCustomSheet, to color: Color) { | ||
let backgroundView = NSView() | ||
backgroundView.wantsLayer = true | ||
backgroundView.layer?.backgroundColor = color.nsColor.cgColor | ||
|
||
Comment on lines
+1739
to
+1742
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it work to set the |
||
if let existingContentView = sheet.contentView { | ||
let container = NSView() | ||
container.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
container.addSubview(backgroundView) | ||
backgroundView.translatesAutoresizingMaskIntoConstraints = false | ||
backgroundView.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = | ||
true | ||
backgroundView.topAnchor.constraint(equalTo: container.topAnchor).isActive = true | ||
backgroundView.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = | ||
true | ||
backgroundView.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true | ||
|
||
container.addSubview(existingContentView) | ||
existingContentView.translatesAutoresizingMaskIntoConstraints = false | ||
existingContentView.leadingAnchor.constraint(equalTo: container.leadingAnchor) | ||
.isActive = true | ||
existingContentView.topAnchor.constraint(equalTo: container.topAnchor).isActive = true | ||
existingContentView.trailingAnchor.constraint(equalTo: container.trailingAnchor) | ||
.isActive = true | ||
existingContentView.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = | ||
true | ||
|
||
sheet.contentView = container | ||
} | ||
} | ||
|
||
public func setInteractiveDismissDisabled(for sheet: NSCustomSheet, to disabled: Bool) { | ||
sheet.interactiveDismissDisabled = disabled | ||
} | ||
} | ||
|
||
public final class NSCustomSheet: NSCustomWindow, NSWindowDelegate, SheetImplementation { | ||
public var sheetSize: SIMD2<Int> { | ||
guard let size = self.contentView?.frame.size else { | ||
return SIMD2(x: 0, y: 0) | ||
} | ||
return SIMD2(x: Int(size.width), y: Int(size.height)) | ||
} | ||
public var onDismiss: (() -> Void)? | ||
|
||
public var interactiveDismissDisabled: Bool = false | ||
|
||
public func dismiss() { | ||
onDismiss?() | ||
self.contentViewController?.dismiss(self) | ||
} | ||
|
||
@objc override public func cancelOperation(_ sender: Any?) { | ||
if !interactiveDismissDisabled { | ||
dismiss() | ||
} | ||
} | ||
} | ||
|
||
final class NSCustomTapGestureTarget: NSView { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.