Add support for folder importers
This commit is contained in:
parent
037a697c74
commit
c8ce2cc2fe
@ -133,7 +133,6 @@ extension AnyView {
|
|||||||
/// - open: The signal to open the dialog.
|
/// - open: The signal to open the dialog.
|
||||||
/// - initialFolder: The URL to the folder open when being opened.
|
/// - initialFolder: The URL to the folder open when being opened.
|
||||||
/// - extensions: The accepted file extensions.
|
/// - extensions: The accepted file extensions.
|
||||||
/// - folders: Whether folders are accepted.
|
|
||||||
/// - onOpen: Run this when a file for importing has been chosen.
|
/// - onOpen: Run this when a file for importing has been chosen.
|
||||||
/// - onClose: Run this when the user cancelled the action.
|
/// - onClose: Run this when the user cancelled the action.
|
||||||
public func fileImporter(
|
public func fileImporter(
|
||||||
@ -144,14 +143,34 @@ extension AnyView {
|
|||||||
onClose: @escaping () -> Void
|
onClose: @escaping () -> Void
|
||||||
) -> AnyView {
|
) -> AnyView {
|
||||||
FileDialog(
|
FileDialog(
|
||||||
importer: true,
|
type: .importer(folder: false, extensions: extensions),
|
||||||
open: open,
|
open: open,
|
||||||
child: self,
|
child: self,
|
||||||
result: onOpen,
|
result: onOpen,
|
||||||
cancel: onClose,
|
cancel: onClose,
|
||||||
initialFolder: initialFolder,
|
initialFolder: initialFolder
|
||||||
initialName: nil,
|
)
|
||||||
extensions: extensions
|
}
|
||||||
|
|
||||||
|
/// Create an importer file dialog for folders.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - open: The signal to open the dialog.
|
||||||
|
/// - initialFolder: The URL to the folder open when being opened.
|
||||||
|
/// - onOpen: Run this when a file for importing has been chosen.
|
||||||
|
/// - onClose: Run this when the user cancelled the action.
|
||||||
|
public func folderImporter(
|
||||||
|
open: Signal,
|
||||||
|
initialFolder: URL? = nil,
|
||||||
|
onOpen: @escaping (URL) -> Void,
|
||||||
|
onClose: @escaping () -> Void
|
||||||
|
) -> AnyView {
|
||||||
|
FileDialog(
|
||||||
|
type: .importer(folder: true, extensions: nil),
|
||||||
|
open: open,
|
||||||
|
child: self,
|
||||||
|
result: onOpen,
|
||||||
|
cancel: onClose,
|
||||||
|
initialFolder: initialFolder
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,13 +189,12 @@ extension AnyView {
|
|||||||
onClose: @escaping () -> Void
|
onClose: @escaping () -> Void
|
||||||
) -> AnyView {
|
) -> AnyView {
|
||||||
FileDialog(
|
FileDialog(
|
||||||
importer: false,
|
type: .exporter(initialName: initialName),
|
||||||
open: open,
|
open: open,
|
||||||
child: self,
|
child: self,
|
||||||
result: onSave,
|
result: onSave,
|
||||||
cancel: onClose,
|
cancel: onClose,
|
||||||
initialFolder: initialFolder,
|
initialFolder: initialFolder
|
||||||
initialName: initialName
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,26 @@ gtui_filedialog_open (uint64_t dialog, uint64_t data, uint64_t window)
|
|||||||
gtk_file_dialog_open (dialog, window, NULL, G_CALLBACK (gtui_filedialog_open_finish), (void *)data);
|
gtk_file_dialog_open (dialog, window, NULL, G_CALLBACK (gtui_filedialog_open_finish), (void *)data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtui_filedialog_open_folder_finish (uint64_t dialog, uint64_t result, uint64_t data)
|
||||||
|
{
|
||||||
|
GFile *file = gtk_file_dialog_select_folder_finish (dialog, result, NULL);
|
||||||
|
if (file != NULL) {
|
||||||
|
const char *path = g_file_peek_path (file);
|
||||||
|
g_object_unref (file);
|
||||||
|
filedialog_on_open_cb (dialog, path, data);
|
||||||
|
} else {
|
||||||
|
filedialog_on_open_cb (dialog, NULL, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtui_filedialog_open_folder (uint64_t dialog, uint64_t data, uint64_t window)
|
||||||
|
{
|
||||||
|
swift_retain (data);
|
||||||
|
gtk_file_dialog_select_folder (dialog, window, NULL, G_CALLBACK (gtui_filedialog_open_folder_finish), (void *)data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtui_alertdialog_cb (uint64_t dialog, uint64_t result, uint64_t data)
|
gtui_alertdialog_cb (uint64_t dialog, uint64_t result, uint64_t data)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -11,54 +11,92 @@ import Foundation
|
|||||||
/// A structure representing a file dialog window.
|
/// A structure representing a file dialog window.
|
||||||
public struct FileDialog: AdwaitaWidget {
|
public struct FileDialog: AdwaitaWidget {
|
||||||
|
|
||||||
/// Whether the dialog is an importer.
|
/// The dialog type.
|
||||||
var importer: Bool
|
var type: DialogType
|
||||||
/// Whether the dialog should open.
|
/// Whether the dialog should open.
|
||||||
var open: Signal
|
var open: Signal
|
||||||
/// The dialog's child.
|
/// The dialog's child.
|
||||||
var child: AnyView
|
var child: AnyView
|
||||||
/// The initial folder.
|
/// The initial folder.
|
||||||
var initialFolder: URL?
|
var initialFolder: URL?
|
||||||
/// The initial file name for the file exporter.
|
|
||||||
var initialName: String?
|
|
||||||
/// The accepted extensions for the file importer.
|
|
||||||
var extensions: [String]?
|
|
||||||
/// The closure to run when the import or export is successful.
|
/// The closure to run when the import or export is successful.
|
||||||
var result: (URL) -> Void
|
var result: (URL) -> Void
|
||||||
/// The closure to run when the import or export is not successful.
|
/// The closure to run when the import or export is not successful.
|
||||||
var cancel: () -> Void
|
var cancel: () -> Void
|
||||||
|
|
||||||
// swiftlint:disable function_default_parameter_at_end
|
|
||||||
/// Initialize the file dialog wrapper.
|
/// Initialize the file dialog wrapper.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
/// - importer: Whether it is an importer.
|
/// - type: The dialog type.
|
||||||
/// - open: The signal.
|
/// - open: The signal.
|
||||||
/// - child: The wrapped view.
|
/// - child: The wrapped view.
|
||||||
/// - initialFolder: The initial URL.
|
|
||||||
/// - initialName: The initial name.
|
|
||||||
/// - extensions: The file extensions.
|
|
||||||
/// - result: Run when the import or export succeeds.
|
/// - result: Run when the import or export succeeds.
|
||||||
/// - cancel: Run when the import or export is not successful.
|
/// - cancel: Run when the import or export is not successful.
|
||||||
|
/// - initialFolder: The initial folder.
|
||||||
public init(
|
public init(
|
||||||
importer: Bool = true,
|
type: DialogType,
|
||||||
`open`: Signal,
|
`open`: Signal,
|
||||||
child: AnyView,
|
child: AnyView,
|
||||||
result: @escaping (URL) -> Void,
|
result: @escaping (URL) -> Void,
|
||||||
cancel: @escaping () -> Void,
|
cancel: @escaping () -> Void,
|
||||||
initialFolder: URL? = nil,
|
initialFolder: URL? = nil,
|
||||||
initialName: String? = nil,
|
|
||||||
extensions: [String]? = nil
|
|
||||||
) {
|
) {
|
||||||
self.importer = importer
|
self.type = type
|
||||||
self.open = open
|
self.open = open
|
||||||
self.child = child
|
self.child = child
|
||||||
self.result = result
|
self.result = result
|
||||||
self.cancel = cancel
|
self.cancel = cancel
|
||||||
self.initialFolder = initialFolder
|
self.initialFolder = initialFolder
|
||||||
self.initialName = initialName
|
|
||||||
self.extensions = extensions
|
|
||||||
}
|
}
|
||||||
// swiftlint:enable function_default_parameter_at_end
|
|
||||||
|
/// The different types of dialogs and their properties.
|
||||||
|
public enum DialogType {
|
||||||
|
|
||||||
|
/// An importer dialog.
|
||||||
|
case importer(folder: Bool, extensions: [String]?)
|
||||||
|
/// An exporter dialog.
|
||||||
|
case exporter(initialName: String?)
|
||||||
|
|
||||||
|
/// Whether the dialog is an importer.
|
||||||
|
var isImporter: Bool {
|
||||||
|
switch self {
|
||||||
|
case .importer:
|
||||||
|
true
|
||||||
|
default:
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The supported extensions.
|
||||||
|
var extensions: [String]? {
|
||||||
|
switch self {
|
||||||
|
case let .importer(folder: _, extensions: extensions):
|
||||||
|
extensions
|
||||||
|
default:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether to import folders.
|
||||||
|
var folder: Bool {
|
||||||
|
switch self {
|
||||||
|
case let .importer(folder: folder, extensions: _):
|
||||||
|
folder
|
||||||
|
default:
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The initial name.
|
||||||
|
var initialName: String? {
|
||||||
|
switch self {
|
||||||
|
case let .exporter(initialName: initialName):
|
||||||
|
initialName
|
||||||
|
default:
|
||||||
|
nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// The view storage.
|
/// The view storage.
|
||||||
/// - Parameters:
|
/// - Parameters:
|
||||||
@ -94,10 +132,10 @@ public struct FileDialog: AdwaitaWidget {
|
|||||||
var unref: [OpaquePointer?] = []
|
var unref: [OpaquePointer?] = []
|
||||||
let pointer = gtk_file_dialog_new()
|
let pointer = gtk_file_dialog_new()
|
||||||
unref.append(pointer)
|
unref.append(pointer)
|
||||||
if let initialName {
|
if let initialName = self.type.initialName {
|
||||||
gtk_file_dialog_set_initial_name(pointer, initialName)
|
gtk_file_dialog_set_initial_name(pointer, initialName)
|
||||||
}
|
}
|
||||||
if let extensions {
|
if let extensions = self.type.extensions {
|
||||||
let filter = gtk_file_filter_new()
|
let filter = gtk_file_filter_new()
|
||||||
for name in extensions {
|
for name in extensions {
|
||||||
gtk_file_filter_add_suffix(filter, name)
|
gtk_file_filter_add_suffix(filter, name)
|
||||||
@ -125,7 +163,9 @@ public struct FileDialog: AdwaitaWidget {
|
|||||||
storage.fields["callbacks"] = callbacks
|
storage.fields["callbacks"] = callbacks
|
||||||
let ptr = UInt64(Int(bitPattern: pointer))
|
let ptr = UInt64(Int(bitPattern: pointer))
|
||||||
let window = UInt64(Int(bitPattern: gtk_widget_get_root(mainStorage.opaquePointer?.cast())))
|
let window = UInt64(Int(bitPattern: gtk_widget_get_root(mainStorage.opaquePointer?.cast())))
|
||||||
if importer {
|
if self.type.isImporter && self.type.folder {
|
||||||
|
gtui_filedialog_open_folder(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
||||||
|
} else if self.type.isImporter {
|
||||||
gtui_filedialog_open(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
gtui_filedialog_open(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
||||||
} else {
|
} else {
|
||||||
gtui_filedialog_save(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
gtui_filedialog_save(ptr, unsafeBitCast(callbacks, to: UInt64.self), window)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user