Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Sources/Gtk/Utility/GActionMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,4 @@ extension GActionMap {
public func addAction(_ action: any GAction) {
g_action_map_add_action(actionMapPointer, action.actionPointer)
}

public func addAction(named name: String, action: @escaping () -> Void) {
let simpleAction = GSimpleAction(name: name, action: action)
addAction(simpleAction)
}
}
74 changes: 55 additions & 19 deletions Sources/Gtk/Utility/GSimpleAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,26 @@ public class GSimpleAction: GAction, GObjectRepresentable {

@GObjectProperty(named: "enabled") var enabled: Bool

private class Action {
var run: () -> Void

init(_ action: @escaping () -> Void) {
run = action
}
}
private typealias ActionHandler =
@convention(c) (
UnsafeMutableRawPointer,
OpaquePointer,
UnsafeMutableRawPointer
) -> Void

public init(name: String, action: @escaping () -> Void) {
actionPointer = g_simple_action_new(name, nil)

class Action {
var action: () -> Void
init(_ action: @escaping () -> Void) { self.action = action }
}
let wrappedAction = Action(action)

let handler:
@convention(c) (
UnsafeMutableRawPointer,
OpaquePointer,
UnsafeMutableRawPointer
) -> Void =
{ _, _, data in
let action = Unmanaged<Action>.fromOpaque(data)
.takeUnretainedValue()
action.run()
}
let handler: ActionHandler = { _, _, data in
let action = Unmanaged<Action>.fromOpaque(data).takeUnretainedValue()
action.action()
}

g_signal_connect_data(
UnsafeMutableRawPointer(actionPointer),
Expand All @@ -46,5 +42,45 @@ public class GSimpleAction: GAction, GObjectRepresentable {
)
}

public func registerSignals() {}
public init(name: String, state: Bool, action: @escaping (Bool) -> Void) {
actionPointer = g_simple_action_new_stateful(
name,
nil,
g_variant_new_boolean(state.toGBoolean())
)

class Action {
var action: (Bool) -> Void
init(_ action: @escaping (Bool) -> Void) { self.action = action }
}
let wrappedAction = Action(action)

let handler: ActionHandler = { actionPointer, _, data in
// Get the current state...
let stateVariant = g_action_get_state(OpaquePointer(actionPointer))
let state = g_variant_get_boolean(stateVariant).toBool()

// ...toggle it...
let newState = !state
g_simple_action_set_state(
OpaquePointer(actionPointer),
g_variant_new_boolean(newState.toGBoolean())
)

// ...then get the action and call it with the new state.
let action = Unmanaged<Action>.fromOpaque(data).takeUnretainedValue()
action.action(newState)
}

g_signal_connect_data(
UnsafeMutableRawPointer(actionPointer),
"activate",
gCallback(handler),
Unmanaged<Action>.passRetained(wrappedAction).toOpaque(),
{ data, _ in
Unmanaged<Action>.fromOpaque(data!).release()
},
G_CONNECT_AFTER
)
}
}
5 changes: 0 additions & 5 deletions Sources/Gtk3/Utility/GActionMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,4 @@ extension GActionMap {
public func addAction(_ action: any GAction) {
g_action_map_add_action(actionMapPointer, action.actionPointer)
}

public func addAction(named name: String, action: @escaping () -> Void) {
let simpleAction = GSimpleAction(name: name, action: action)
addAction(simpleAction)
}
}
72 changes: 55 additions & 17 deletions Sources/Gtk3/Utility/GSimpleAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,68 @@ public class GSimpleAction: GAction, GObjectRepresentable {

@GObjectProperty(named: "enabled") var enabled: Bool

private class Action {
var run: () -> Void
private typealias ActionHandler =
@convention(c) (
UnsafeMutableRawPointer,
OpaquePointer,
UnsafeMutableRawPointer
) -> Void

init(_ action: @escaping () -> Void) {
run = action
public init(name: String, action: @escaping () -> Void) {
actionPointer = g_simple_action_new(name, nil)

class Action {
var action: () -> Void
init(_ action: @escaping () -> Void) { self.action = action }
}
let wrappedAction = Action(action)

let handler: ActionHandler = { _, _, data in
let action = Unmanaged<Action>.fromOpaque(data).takeUnretainedValue()
action.action()
}

g_signal_connect_data(
UnsafeMutableRawPointer(actionPointer),
"activate",
gCallback(handler),
Unmanaged<Action>.passRetained(wrappedAction).toOpaque(),
{ data, _ in
Unmanaged<Action>.fromOpaque(data!).release()
},
G_CONNECT_AFTER
)
}

public init(name: String, action: @escaping () -> Void) {
actionPointer = g_simple_action_new(name, nil)
public init(name: String, state: Bool, action: @escaping (Bool) -> Void) {
actionPointer = g_simple_action_new_stateful(
name,
nil,
g_variant_new_boolean(state.toGBoolean())
)

class Action {
var action: (Bool) -> Void
init(_ action: @escaping (Bool) -> Void) { self.action = action }
}
let wrappedAction = Action(action)

let handler:
@convention(c) (
UnsafeMutableRawPointer,
OpaquePointer,
UnsafeMutableRawPointer
) -> Void =
{ _, _, data in
let action = Unmanaged<Action>.fromOpaque(data)
.takeUnretainedValue()
action.run()
}
let handler: ActionHandler = { actionPointer, _, data in
// Get the current state...
let stateVariant = g_action_get_state(OpaquePointer(actionPointer))
let state = g_variant_get_boolean(stateVariant).toBool()

// ...toggle it...
let newState = !state
g_simple_action_set_state(
OpaquePointer(actionPointer),
g_variant_new_boolean(newState.toGBoolean())
)

// ...then get the action and call it with the new state.
let action = Unmanaged<Action>.fromOpaque(data).takeUnretainedValue()
action.action(newState)
}

g_signal_connect_data(
UnsafeMutableRawPointer(actionPointer),
Expand Down
9 changes: 6 additions & 3 deletions Sources/Gtk3Backend/Gtk3Backend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,16 @@ public final class Gtk3Backend: AppBackend {
switch item {
case .button(let label, let action):
if let action {
actionMap.addAction(named: actionName, action: action)
actionMap.addAction(GSimpleAction(name: actionName, action: action))
}

model.appendItem(label: label, actionName: "\(actionNamespace).\(actionName)")
case .toggle(let label, let value, let onChange):
// FIXME: Implement
logger.warning("menu toggles not implemented")
actionMap.addAction(
GSimpleAction(name: actionName, state: value, action: onChange)
)

model.appendItem(label: label, actionName: "\(actionNamespace).\(actionName)")
case .submenu(let submenu):
model.appendSubmenu(
label: submenu.label,
Expand Down
9 changes: 6 additions & 3 deletions Sources/GtkBackend/GtkBackend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
return 0
#else
if window.showMenuBar {
// TODO: Don't hardcode this (if possible), because some Gtk

Check warning on line 166 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Don't hardcode this (if possib...) (todo)
// themes may affect the height of the menu bar.
25
} else {
Expand All @@ -179,7 +179,7 @@
}

public func isWindowProgrammaticallyResizable(_ window: Window) -> Bool {
// TODO: Detect whether window is fullscreen

Check warning on line 182 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Detect whether window is fulls...) (todo)
return true
}

Expand Down Expand Up @@ -275,13 +275,16 @@
switch item {
case .button(let label, let action):
if let action {
actionMap.addAction(named: actionName, action: action)
actionMap.addAction(GSimpleAction(name: actionName, action: action))
}

model.appendItem(label: label, actionName: "\(actionNamespace).\(actionName)")
case .toggle(let label, let value, let onChange):
// FIXME: Implement
logger.warning("menu toggles not implemented")
actionMap.addAction(
GSimpleAction(name: actionName, state: value, action: onChange)
)

model.appendItem(label: label, actionName: "\(actionNamespace).\(actionName)")
case .submenu(let submenu):
model.appendSubmenu(
label: submenu.label,
Expand Down Expand Up @@ -386,14 +389,14 @@
}

public func setRootEnvironmentChangeHandler(to action: @escaping () -> Void) {
// TODO: React to theme changes

Check warning on line 392 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (React to theme changes) (todo)
}

public func computeWindowEnvironment(
window: Window,
rootEnvironment: EnvironmentValues
) -> EnvironmentValues {
// TODO: Record window scale factor in here

Check warning on line 399 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Record window scale factor in ...) (todo)
rootEnvironment
}

Expand All @@ -401,7 +404,7 @@
of window: Window,
to action: @escaping () -> Void
) {
// TODO: Notify when window scale factor changes

Check warning on line 407 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Notify when window scale facto...) (todo)
}

public func setIncomingURLHandler(to action: @escaping (URL) -> Void) {
Expand Down Expand Up @@ -686,7 +689,7 @@

// private let tables = Tables()

// TODO: Implement tables

Check warning on line 692 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Implement tables) (todo)
// public func createTable(rows: Int, columns: Int) -> Widget {
// let widget = Grid()

Expand Down Expand Up @@ -763,7 +766,7 @@
environment: EnvironmentValues,
action: @escaping () -> Void
) {
// TODO: Update button label color using environment

Check warning on line 769 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (Update button label color usin...) (todo)
let button = button as! Gtk.Button
button.sensitive = environment.isEnabled
button.label = label
Expand Down Expand Up @@ -1179,7 +1182,7 @@
}
},
window: window ?? windows[0]
) { result in

Check warning on line 1185 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
switch result {
case .success(let urls):
handleResult(.success(urls[0]))
Expand Down Expand Up @@ -1212,7 +1215,7 @@
configure(chooser)

chooser.registerSignals()
chooser.response = { (_: NativeDialog, response: Int) -> Void in

Check warning on line 1218 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Redundant Void Return Violation: Returning Void in a function declaration is redundant (redundant_void_return)
// Release our intentional retain cycle which ironically only exists
// because of this line. The retain cycle keeps the file chooser
// around long enough for the user to respond (it gets released
Expand Down Expand Up @@ -1584,7 +1587,7 @@
}

public func createSheet(content: Widget) -> Sheet {
// TODO: dismissing a sheet with nested sheets doesn't trigger the onDismiss handlers of the nested sheets

Check warning on line 1590 in Sources/GtkBackend/GtkBackend.swift

View workflow job for this annotation

GitHub Actions / swift-lint

Todo Violation: TODOs should be resolved (dismissing a sheet with nested...) (todo)
// TODO: dismissing a sheet with nested sheets causes the app to freeze/deadlock or something along those lines...

let sheet = Sheet()
Expand Down
Loading