Skip to content

Commit

Permalink
Add native file dialogs (#6)
Browse files Browse the repository at this point in the history
* Add SwiftNFD package

* Add dialogs

* Fix foundation import in package

* Fix submodule compile failure

* Update SwiftNFD
  • Loading branch information
ctreffs authored Nov 6, 2021
1 parent 3312756 commit 220f07d
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
9 changes: 9 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
"version": "0.11.0"
}
},
{
"package": "SwiftNFD",
"repositoryURL": "https://github.com/ctreffs/SwiftNFD.git",
"state": {
"branch": null,
"revision": "6c9e4666649f70920775e25d187d5a2c05df5fd2",
"version": "1.0.2"
}
},
{
"package": "SDL2",
"repositoryURL": "https://github.com/ctreffs/SwiftSDL2.git",
Expand Down
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ let package = Package(
.firebladeTime,
.vulkan,
.sdl2,
.nfd,
],
targets: [
.target(
Expand All @@ -120,6 +121,7 @@ let package = Package(
.firebladeTime,
.sdl2,
.vulkan,
.nfd,
],
swiftSettings: swiftSettings
),
Expand All @@ -142,13 +144,15 @@ extension Package.Dependency {
static let firebladeTime = Package.Dependency.package(name: "FirebladeTime", url: "https://github.com/fireblade-engine/time.git", from: "0.2.0")
static let sdl2 = Package.Dependency.package(name: "SDL2", url: "https://github.com/ctreffs/SwiftSDL2.git", from: "1.3.1")
static let vulkan = Package.Dependency.package(name: "Vulkan", url: "https://github.com/ctreffs/SwiftVulkan", from: "0.1.2")
static let nfd = Package.Dependency.package(name: "SwiftNFD", url: "https://github.com/ctreffs/SwiftNFD.git", from: "1.0.2")
}

extension Target.Dependency {
static let firebladeTime = byName(name: "FirebladeTime")
static let firebladeMath = product(name: "FirebladeMath", package: "FirebladeMath")
static let sdl2 = product(name: "SDL2", package: "SDL2")
static let vulkan = product(name: "Vulkan", package: "Vulkan")
static let nfd = product(name: "NFD", package: "SwiftNFD")
}

extension Env {
Expand Down
61 changes: 61 additions & 0 deletions Sources/FirebladePAL/Window.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// Licensed under MIT License. See LICENSE file for details.

import FirebladeMath
@_implementationOnly import NFD

#if FRB_PLATFORM_SDL
public typealias Window = SDLWindow
Expand Down Expand Up @@ -48,6 +49,66 @@ public protocol WindowBase: AnyObject {
func centerOnScreen()
}

// MARK: - Dialogs

public extension WindowBase {
/// Single file open dialog
/// - Parameters:
/// - startPath: The current directory shown in the dialog.
/// - fileExtensions: An array of filename extensions or UTIs that represent the allowed file types for the dialog.
/// - Returns: Selected file path or `nil` if user canceled.
static func openDialog(at startPath: String? = nil, filterFor fileExtensions: [String]? = nil) throws -> String? {
switch NFD.OpenDialog(filter: fileExtensions, defaultPath: startPath) {
case let .success(path):
return path
case let .failure(error):
throw error
}
}

/// Multiple file open dialog
/// - Parameters:
/// - startPath: The current directory shown in the dialog.
/// - fileExtensions: An array of filename extensions or UTIs that represent the allowed file types for the dialog.
/// - Returns: Array of selected file paths or `nil` if user canceled.
static func openDialogMultiple(at startPath: String? = nil, filterFor fileExtensions: [String]? = nil) throws -> [String]? {
switch NFD.OpenDialogMultiple(filter: fileExtensions, defaultPath: startPath) {
case let .success(path):
return path
case let .failure(error):
throw error
}
}

/// Save dialog
/// - Parameters:
/// - startPath: The current directory shown in the dialog.
/// - fileExtensions: An array of filename extensions or UTIs that represent the allowed file types for the dialog.
/// - Returns: Selected file path or `nil` if user canceled.
static func saveDialog(at startPath: String? = nil, filterFor fileExtensions: [String]? = nil) throws -> String? {
switch NFD.SaveDialog(filter: fileExtensions, defaultPath: startPath) {
case let .success(path):
return path
case let .failure(error):
throw error
}
}

/// Select folder dialog
/// - Parameter startPath: The current directory shown in the dialog.
/// - Returns: Selected folder path or `nil` if user canceled.
static func pickFolder(at startPath: String? = nil) throws -> String? {
switch NFD.PickFolder(defaultPath: startPath) {
case let .success(path):
return path
case let .failure(error):
throw error
}
}
}

// MARK: - Window properties

public struct WindowProperties {
public var title: String
public var frame: Rect<Int>
Expand Down

0 comments on commit 220f07d

Please sign in to comment.