@@ -176,7 +176,7 @@ public final class AppKitBackend: AppBackend {
176176 }
177177 }
178178
179- public func computeRootEnvironment( defaultEnvironment: Environment ) -> Environment {
179+ public func computeRootEnvironment( defaultEnvironment: EnvironmentValues ) -> EnvironmentValues {
180180 let isDark = UserDefaults . standard. string ( forKey: " AppleInterfaceStyle " ) == " Dark "
181181 let font = Font . system (
182182 size: Int ( NSFont . systemFont ( ofSize: 0.0 ) . pointSize. rounded ( . awayFromZero) )
@@ -358,7 +358,7 @@ public final class AppKitBackend: AppBackend {
358358 of text: String ,
359359 whenDisplayedIn textView: Widget ,
360360 proposedFrame: SIMD2 < Int > ? ,
361- environment: Environment
361+ environment: EnvironmentValues
362362 ) -> SIMD2 < Int > {
363363 if let proposedFrame, proposedFrame. x == 0 {
364364 // We want the text to have the same height as it would have if it were
@@ -400,7 +400,11 @@ public final class AppKitBackend: AppBackend {
400400 return field
401401 }
402402
403- public func updateTextView( _ textView: Widget , content: String , environment: Environment ) {
403+ public func updateTextView(
404+ _ textView: Widget ,
405+ content: String ,
406+ environment: EnvironmentValues
407+ ) {
404408 let field = textView as! NSTextField
405409 field. attributedStringValue = Self . attributedString ( for: content, in: environment)
406410 }
@@ -413,7 +417,7 @@ public final class AppKitBackend: AppBackend {
413417 _ button: Widget ,
414418 label: String ,
415419 action: @escaping ( ) -> Void ,
416- environment: Environment
420+ environment: EnvironmentValues
417421 ) {
418422 let button = button as! NSButton
419423 button. attributedTitle = Self . attributedString ( for: label, in: environment)
@@ -494,7 +498,7 @@ public final class AppKitBackend: AppBackend {
494498 public func updatePicker(
495499 _ picker: Widget ,
496500 options: [ String ] ,
497- environment: Environment ,
501+ environment: EnvironmentValues ,
498502 onChange: @escaping ( Int ? ) -> Void
499503 ) {
500504 let picker = picker as! NSPopUpButton
@@ -528,7 +532,7 @@ public final class AppKitBackend: AppBackend {
528532 public func updateTextField(
529533 _ textField: Widget ,
530534 placeholder: String ,
531- environment: Environment ,
535+ environment: EnvironmentValues ,
532536 onChange: @escaping ( String ) -> Void
533537 ) {
534538 let textField = textField as! NSObservableTextField
@@ -696,7 +700,7 @@ public final class AppKitBackend: AppBackend {
696700 public func setColumnLabels(
697701 ofTable table: Widget ,
698702 to labels: [ String ] ,
699- environment: Environment
703+ environment: EnvironmentValues
700704 ) {
701705 let table = ( table as! NSScrollView ) . documentView as! NSCustomTableView
702706 var columnIndices : [ ObjectIdentifier : Int ] = [ : ]
@@ -735,7 +739,7 @@ public final class AppKitBackend: AppBackend {
735739
736740 private static func attributedString(
737741 for text: String ,
738- in environment: Environment
742+ in environment: EnvironmentValues
739743 ) -> NSAttributedString {
740744 NSAttributedString (
741745 string: text,
@@ -744,7 +748,7 @@ public final class AppKitBackend: AppBackend {
744748 }
745749
746750 private static func attributes(
747- forTextIn environment: Environment
751+ forTextIn environment: EnvironmentValues
748752 ) -> [ NSAttributedString . Key : Any ] {
749753 let paragraphStyle = NSMutableParagraphStyle ( )
750754 paragraphStyle. alignment =
@@ -763,7 +767,7 @@ public final class AppKitBackend: AppBackend {
763767 ]
764768 }
765769
766- private static func font( for environment: Environment ) -> NSFont {
770+ private static func font( for environment: EnvironmentValues ) -> NSFont {
767771 switch environment. font {
768772 case . system( let size, let weight, let design) :
769773 switch design {
@@ -823,7 +827,7 @@ public final class AppKitBackend: AppBackend {
823827 public func updateProgressBar(
824828 _ widget: Widget ,
825829 progressFraction: Double ? ,
826- environment: Environment
830+ environment: EnvironmentValues
827831 ) {
828832 let progressBar = widget as! NSProgressIndicator
829833 progressBar. doubleValue = progressFraction ?? 0
@@ -847,7 +851,7 @@ public final class AppKitBackend: AppBackend {
847851 public func updatePopoverMenu(
848852 _ menu: Menu ,
849853 content: ResolvedMenu ,
850- environment: Environment
854+ environment: EnvironmentValues
851855 ) {
852856 menu. appearance = environment. colorScheme. nsAppearance
853857 menu. items = Self . renderMenuItems ( content. items)
@@ -876,7 +880,7 @@ public final class AppKitBackend: AppBackend {
876880 _ alert: Alert ,
877881 title: String ,
878882 actionLabels: [ String ] ,
879- environment: Environment
883+ environment: EnvironmentValues
880884 ) {
881885 alert. messageText = title
882886 for label in actionLabels {
@@ -908,6 +912,69 @@ public final class AppKitBackend: AppBackend {
908912 public func dismissAlert( _ alert: Alert , window: Window ) {
909913 window. endSheet ( alert. window)
910914 }
915+
916+ public func showOpenDialog(
917+ fileDialogOptions: FileDialogOptions ,
918+ openDialogOptions: OpenDialogOptions ,
919+ window: Window ,
920+ resultHandler handleResult: @escaping ( DialogResult < [ URL ] > ) -> Void
921+ ) {
922+ let panel = NSOpenPanel ( )
923+ panel. message = fileDialogOptions. title
924+ panel. prompt = fileDialogOptions. defaultButtonLabel
925+ panel. directoryURL = fileDialogOptions. initialDirectory
926+ panel. showsHiddenFiles = fileDialogOptions. showHiddenFiles
927+ panel. allowsOtherFileTypes = fileDialogOptions. allowOtherContentTypes
928+
929+ // TODO: allowedContentTypes
930+
931+ panel. allowsMultipleSelection = openDialogOptions. allowMultipleSelections
932+ panel. canChooseFiles = openDialogOptions. allowSelectingFiles
933+ panel. canChooseDirectories = openDialogOptions. allowSelectingDirectories
934+
935+ panel. beginSheetModal ( for: window) { response in
936+ guard response != . continue else {
937+ return
938+ }
939+
940+ if response == . OK {
941+ handleResult ( . success( panel. urls) )
942+ } else {
943+ handleResult ( . cancelled)
944+ }
945+ }
946+ }
947+
948+ public func showSaveDialog(
949+ fileDialogOptions: FileDialogOptions ,
950+ saveDialogOptions: SaveDialogOptions ,
951+ window: Window ,
952+ resultHandler handleResult: @escaping ( DialogResult < URL > ) -> Void
953+ ) {
954+ let panel = NSSavePanel ( )
955+ panel. message = fileDialogOptions. title
956+ panel. prompt = fileDialogOptions. defaultButtonLabel
957+ panel. directoryURL = fileDialogOptions. initialDirectory
958+ panel. showsHiddenFiles = fileDialogOptions. showHiddenFiles
959+ panel. allowsOtherFileTypes = fileDialogOptions. allowOtherContentTypes
960+
961+ // TODO: allowedContentTypes
962+
963+ panel. nameFieldLabel = saveDialogOptions. nameFieldLabel ?? panel. nameFieldLabel
964+ panel. nameFieldStringValue = saveDialogOptions. defaultFileName ?? " "
965+
966+ panel. beginSheetModal ( for: window) { response in
967+ guard response != . continue else {
968+ return
969+ }
970+
971+ if response == . OK {
972+ handleResult ( . success( panel. url!) )
973+ } else {
974+ handleResult ( . cancelled)
975+ }
976+ }
977+ }
911978}
912979
913980final class NSCustomMenuItem : NSMenuItem {
0 commit comments