126 lines
4.0 KiB
Swift
126 lines
4.0 KiB
Swift
//
|
|
// AdwaitaApp.swift
|
|
// Adwaita
|
|
//
|
|
// Created by david-swift on 31.07.2024.
|
|
//
|
|
|
|
import CAdw
|
|
import Foundation
|
|
@_exported import Meta
|
|
@_exported import MetaSQLite
|
|
|
|
/// The Meta app storage for the Adwaita backend.
|
|
public class AdwaitaApp: AppStorage {
|
|
|
|
/// The scene element type of the Adwaita backend.
|
|
public typealias SceneElementType = AdwaitaSceneElement
|
|
/// The widget type of the Adwaita backend.
|
|
public typealias WidgetType = AdwaitaWidget
|
|
/// The wrapper type of the Adwaita backend.
|
|
public typealias WrapperType = VStack
|
|
|
|
/// The app storage.
|
|
public var storage: StandardAppStorage = .init()
|
|
/// The signal data for running.
|
|
var runSignal: SignalData?
|
|
/// The application's pointer.
|
|
var pointer: UnsafeMutablePointer<GtkApplication>?
|
|
/// Fields for storing closure data.
|
|
var signals: [String: SignalData] = [:]
|
|
|
|
/// Initialize the app storage.
|
|
/// - Parameter id: The identifier.
|
|
public required init(id: String) {
|
|
pointer = adw_application_new(id, G_APPLICATION_DEFAULT_FLAGS)?.cast()
|
|
DatabaseInformation.setPath(Self.userDataDir().appendingPathComponent("data.sqlite").path)
|
|
}
|
|
|
|
/// Copy a string to the clipboard.
|
|
public static func copy(_ text: String) {
|
|
let clipboard = gdk_display_get_clipboard(gdk_display_get_default())
|
|
gdk_clipboard_set_text(clipboard, text)
|
|
}
|
|
|
|
/// The directory used for storing user data.
|
|
/// - Returns: The URL.
|
|
public static func userDataDir() -> URL {
|
|
.init(fileURLWithPath: .init(cString: g_get_user_data_dir()))
|
|
}
|
|
|
|
/// Execute the app.
|
|
/// - Parameter setup: Set the scene elements up.
|
|
public func run(setup: @escaping () -> Void) {
|
|
let data = SignalData {
|
|
setup()
|
|
}
|
|
runSignal = data
|
|
data.connect(pointer: pointer, signal: "activate")
|
|
g_application_run(pointer?.cast(), 0, nil)
|
|
}
|
|
|
|
/// Quit the app.
|
|
public func quit() {
|
|
g_application_quit(pointer?.cast())
|
|
}
|
|
|
|
/// Add a keyboard shortcut to the application.
|
|
/// - Parameters:
|
|
/// - shortcut: The keyboard shortcut.
|
|
/// - id: The action's id.
|
|
/// - window: Optionally an application window.
|
|
/// - handler: The action's handler.
|
|
func addKeyboardShortcut(
|
|
_ shortcut: String,
|
|
id: String,
|
|
window: AdwaitaWindow? = nil,
|
|
handler: @escaping () -> Void
|
|
) {
|
|
if window == nil, let data = signals[id] {
|
|
data.closure = { _ in handler() }
|
|
return
|
|
} else if let data = window?.signals[id] {
|
|
data.closure = { _ in handler() }
|
|
return
|
|
}
|
|
let action = g_simple_action_new(id, nil)
|
|
let data = SignalData(closure: handler)
|
|
g_signal_connect_data(
|
|
action?.cast(),
|
|
"activate",
|
|
unsafeBitCast(data.threeParamsHandler, to: GCallback.self),
|
|
Unmanaged.passUnretained(data).toOpaque().cast(),
|
|
nil,
|
|
G_CONNECT_AFTER
|
|
)
|
|
if let window {
|
|
g_action_map_add_action(.init(window.pointer), action)
|
|
window.signals[id] = data
|
|
} else {
|
|
g_action_map_add_action(.init(pointer), action)
|
|
signals[id] = data
|
|
}
|
|
let array = [shortcut].cArray
|
|
gtk_application_set_accels_for_action(pointer, (window == nil ? "app." : "win.") + id, array)
|
|
array?.deallocate()
|
|
}
|
|
|
|
/// Remove a keyboard shortcut from the application.
|
|
/// - Parameters:
|
|
/// - id: The keyboard shortcut's id.
|
|
/// - window: Optionally an application window.
|
|
func removeKeyboardShortcut(
|
|
id: String,
|
|
window: AdwaitaWindow? = nil
|
|
) {
|
|
if let window {
|
|
g_action_map_remove_action(.init(window.pointer), id)
|
|
window.signals.removeValue(forKey: id)
|
|
} else {
|
|
g_action_map_remove_action(.init(pointer), id)
|
|
signals.removeValue(forKey: id)
|
|
}
|
|
}
|
|
|
|
}
|