Skip to content

Commit 07fc8d3

Browse files
committed
Rename onClick modifier to onTapGesture, fix Gtk3Backend compilation
1 parent a9f959a commit 07fc8d3

File tree

8 files changed

+111
-73
lines changed

8 files changed

+111
-73
lines changed

Sources/AppKitBackend/AppKitBackend.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,36 +1079,41 @@ public final class AppKitBackend: AppBackend {
10791079
}
10801080
}
10811081

1082-
public func createClickTarget(wrapping child: Widget) -> Widget {
1082+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
10831083
let container = NSView()
10841084

10851085
container.addSubview(child)
1086-
child.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
1087-
child.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
1086+
child.leadingAnchor.constraint(equalTo: container.leadingAnchor)
1087+
.isActive = true
1088+
child.topAnchor.constraint(equalTo: container.topAnchor)
1089+
.isActive = true
10881090
child.translatesAutoresizingMaskIntoConstraints = false
10891091

1090-
let clickTarget = NSCustomClickTarget()
1091-
container.addSubview(clickTarget)
1092-
clickTarget.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
1093-
clickTarget.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
1094-
clickTarget.trailingAnchor.constraint(equalTo: container.trailingAnchor).isActive = true
1095-
clickTarget.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
1096-
clickTarget.translatesAutoresizingMaskIntoConstraints = false
1092+
let tapGestureTarget = NSCustomTapGestureTarget()
1093+
container.addSubview(tapGestureTarget)
1094+
tapGestureTarget.leadingAnchor.constraint(equalTo: container.leadingAnchor)
1095+
.isActive = true
1096+
tapGestureTarget.topAnchor.constraint(equalTo: container.topAnchor)
1097+
.isActive = true
1098+
tapGestureTarget.trailingAnchor.constraint(equalTo: container.trailingAnchor)
1099+
.isActive = true
1100+
tapGestureTarget.bottomAnchor.constraint(equalTo: container.bottomAnchor)
1101+
.isActive = true
1102+
tapGestureTarget.translatesAutoresizingMaskIntoConstraints = false
10971103

10981104
return container
1099-
11001105
}
11011106

1102-
public func updateClickTarget(
1107+
public func updateTapGestureTarget(
11031108
_ container: Widget,
1104-
clickHandler handleClick: @escaping () -> Void
1109+
action: @escaping () -> Void
11051110
) {
1106-
let clickTarget = container.subviews[1] as! NSCustomClickTarget
1107-
clickTarget.leftClickHandler = handleClick
1111+
let tapGestureTarget = container.subviews[1] as! NSCustomTapGestureTarget
1112+
tapGestureTarget.leftClickHandler = action
11081113
}
11091114
}
11101115

1111-
final class NSCustomClickTarget: NSView {
1116+
final class NSCustomTapGestureTarget: NSView {
11121117
var leftClickHandler: (() -> Void)?
11131118

11141119
override func mouseDown(with event: NSEvent) {

Sources/Gtk3Backend/Gtk3Backend.swift

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ public final class Gtk3Backend: AppBackend {
2626
public let defaultTableRowContentHeight = 20
2727
public let defaultTableCellVerticalPadding = 4
2828
public let defaultPaddingAmount = 10
29+
public let requiresToggleSwitchSpacer = false
2930
public let scrollBarWidth = 0
31+
public let defaultToggleStyle = ToggleStyle.button
3032

3133
var gtkApp: Application
3234

@@ -116,6 +118,11 @@ public final class Gtk3Backend: AppBackend {
116118
return SIMD2(size.width, size.height)
117119
}
118120

121+
public func isWindowProgrammaticallyResizable(_ window: Window) -> Bool {
122+
// TODO: Detect whether window is fullscreen
123+
return true
124+
}
125+
119126
public func setSize(ofWindow window: Window, to newSize: SIMD2<Int>) {
120127
let child = window.child! as! CustomRootWidget
121128
child.preemptAllocatedSize(
@@ -217,7 +224,16 @@ public final class Gtk3Backend: AppBackend {
217224

218225
public func openExternalURL(_ url: URL) throws {
219226
// Used instead of gtk_uri_launcher_launch to maintain <4.10 compatibility
220-
gtk_show_uri(nil, url.absoluteString, guint(GDK_CURRENT_TIME))
227+
var error: UnsafeMutablePointer<GError>? = nil
228+
gtk_show_uri(nil, url.absoluteString, guint(GDK_CURRENT_TIME), &error)
229+
230+
if let error {
231+
throw Gtk3Error(
232+
code: Int(error.pointee.code),
233+
domain: Int(error.pointee.domain),
234+
message: String(cString: error.pointee.message)
235+
)
236+
}
221237
}
222238

223239
class ThreadActionContext {
@@ -898,18 +914,18 @@ public final class Gtk3Backend: AppBackend {
898914
gtk_native_dialog_show(chooser.gobjectPointer.cast())
899915
}
900916

901-
public func createClickTarget(wrapping child: Widget) -> Widget {
917+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
902918
let eventBox = Gtk3.EventBox()
903919
eventBox.setChild(to: child)
904920
eventBox.aboveChild = true
905921
return eventBox
906922
}
907923

908-
public func updateClickTarget(
909-
_ clickTarget: Widget,
910-
clickHandler handleClick: @escaping () -> Void
924+
public func updateTapGestureTarget(
925+
_ tapGestureTarget: Widget,
926+
action: @escaping () -> Void
911927
) {
912-
clickTarget.onButtonPress = { _, buttonEvent in
928+
tapGestureTarget.onButtonPress = { _, buttonEvent in
913929
let eventType = buttonEvent.type
914930
guard
915931
eventType == GDK_BUTTON_PRESS
@@ -918,7 +934,7 @@ public final class Gtk3Backend: AppBackend {
918934
else {
919935
return
920936
}
921-
handleClick()
937+
action()
922938
}
923939
}
924940

@@ -987,3 +1003,13 @@ extension UnsafeMutablePointer {
9871003
return UnsafeMutablePointer<T>(mutating: pointer)
9881004
}
9891005
}
1006+
1007+
struct Gtk3Error: LocalizedError {
1008+
var code: Int
1009+
var domain: Int
1010+
var message: String
1011+
1012+
var errorDescription: String? {
1013+
"gerror: code=\(code), domain=\(domain), message=\(message)"
1014+
}
1015+
}

Sources/GtkBackend/GtkBackend.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -938,22 +938,22 @@ public final class GtkBackend: AppBackend {
938938
gtk_native_dialog_show(chooser.gobjectPointer.cast())
939939
}
940940

941-
public func createClickTarget(wrapping child: Widget) -> Widget {
941+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
942942
let gesture = Gtk.GestureClick()
943943
child.addEventController(gesture)
944944
return child
945945
}
946946

947-
public func updateClickTarget(
948-
_ clickTarget: Widget,
949-
clickHandler handleClick: @escaping () -> Void
947+
public func updateTapGestureTarget(
948+
_ tapGestureTarget: Widget,
949+
action: @escaping () -> Void
950950
) {
951-
let gesture = clickTarget.eventControllers[0] as! Gtk.GestureClick
951+
let gesture = tapGestureTarget.eventControllers[0] as! Gtk.GestureClick
952952
gesture.pressed = { _, nPress, _, _ in
953953
guard nPress == 1 else {
954954
return
955955
}
956-
handleClick()
956+
action()
957957
}
958958
}
959959

Sources/SwiftCrossUI/Backend/AppBackend.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,15 @@ public protocol AppBackend {
479479
resultHandler handleResult: @escaping (DialogResult<URL>) -> Void
480480
)
481481

482-
/// Wraps a view in a container that can receive click events. Some
483-
/// backends may not have to wrap the child, in which case they have the
484-
/// freedom to just return the child as is.
485-
func createClickTarget(wrapping child: Widget) -> Widget
486-
/// Update the click target with a new click handler. Replaces the old
487-
/// click handler.
488-
func updateClickTarget(
489-
_ clickTarget: Widget,
490-
clickHandler handleClick: @escaping () -> Void
482+
/// Wraps a view in a container that can receive tap gestures. Some
483+
/// backends may not have to wrap the child, in which case they may
484+
/// just return the child as is.
485+
func createTapGestureTarget(wrapping child: Widget) -> Widget
486+
/// Update the tap gesture target with a new action. Replaces the old
487+
/// action.
488+
func updateTapGestureTarget(
489+
_ tapGestureTarget: Widget,
490+
action: @escaping () -> Void
491491
)
492492
}
493493

@@ -787,12 +787,12 @@ extension AppBackend {
787787
todo()
788788
}
789789

790-
public func createClickTarget(wrapping child: Widget) -> Widget {
790+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
791791
todo()
792792
}
793-
public func updateClickTarget(
793+
public func updateTapGestureTarget(
794794
_ clickTarget: Widget,
795-
clickHandler handleClick: @escaping () -> Void
795+
action: @escaping () -> Void
796796
) {
797797
todo()
798798
}

Sources/SwiftCrossUI/Modifiers/OnClickModifier.swift renamed to Sources/SwiftCrossUI/Modifiers/OnTapGestureModifier.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
extension View {
2+
/// Adds an action to perform when the user taps or clicks this view.
3+
///
4+
/// Any tappable elements within the view will no longer be tappable.
5+
public func onTapGesture(perform action: @escaping () -> Void) -> some View {
6+
OnTapGestureModifier(body: TupleView1(self), action: action)
7+
}
8+
29
/// Adds an action to run when this view is clicked. Any clickable elements
310
/// within the view will no longer be clickable.
11+
@available(*, deprecated, message: "Renamed to onTapGesture")
412
public func onClick(perform action: @escaping () -> Void) -> some View {
5-
OnClickModifier(body: TupleView1(self), action: action)
13+
onTapGesture(perform: action)
614
}
715
}
816

9-
struct OnClickModifier<Content: View>: TypeSafeView {
17+
struct OnTapGestureModifier<Content: View>: TypeSafeView {
1018
typealias Children = TupleView1<Content>.Children
1119

1220
var body: TupleView1<Content>
@@ -28,7 +36,7 @@ struct OnClickModifier<Content: View>: TypeSafeView {
2836
_ children: Children,
2937
backend: Backend
3038
) -> Backend.Widget {
31-
backend.createClickTarget(wrapping: children.child0.widget.into())
39+
backend.createTapGestureTarget(wrapping: children.child0.widget.into())
3240
}
3341

3442
func update<Backend: AppBackend>(
@@ -47,7 +55,7 @@ struct OnClickModifier<Content: View>: TypeSafeView {
4755
)
4856
if !dryRun {
4957
backend.setSize(of: widget, to: childResult.size.size)
50-
backend.updateClickTarget(widget, clickHandler: action)
58+
backend.updateTapGestureTarget(widget, action: action)
5159
}
5260
return childResult
5361
}

Sources/UIKitBackend/UIKitBackend+Control.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ final class TextFieldWidget: WrapperWidget<UITextField>, UITextFieldDelegate {
103103
}
104104
#endif
105105

106-
final class ClickableWidget: ContainerWidget {
106+
final class TappableWidget: ContainerWidget {
107107
private var gestureRecognizer: UITapGestureRecognizer!
108-
var onClick: (() -> Void)?
108+
var onTap: (() -> Void)?
109109

110110
override init(child: some WidgetProtocol) {
111111
super.init(child: child)
@@ -117,7 +117,7 @@ final class ClickableWidget: ContainerWidget {
117117

118118
@objc
119119
func viewTouched() {
120-
onClick?()
120+
onTap?()
121121
}
122122
}
123123

@@ -230,16 +230,16 @@ extension UIKitBackend {
230230
wrapper.setOn(state)
231231
}
232232

233-
public func createClickTarget(wrapping child: Widget) -> Widget {
234-
ClickableWidget(child: child)
233+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
234+
TappableWidget(child: child)
235235
}
236236

237-
public func updateClickTarget(
238-
_ clickTarget: Widget,
239-
clickHandler handleClick: @escaping () -> Void
237+
public func updateTapGestureTarget(
238+
_ tapGestureTarget: Widget,
239+
action: @escaping () -> Void
240240
) {
241-
let wrapper = clickTarget as! ClickableWidget
242-
wrapper.onClick = handleClick
241+
let wrapper = tapGestureTarget as! TappableWidget
242+
wrapper.onTap = action
243243
}
244244

245245
#if os(iOS)

Sources/UIKitBackend/UIViewRepresentable.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ where Content == Never {
4646
///
4747
/// The default implementation uses `uiView.intrinsicContentSize` and `uiView.systemLayoutSizeFitting(_:)`
4848
/// to determine the return value.
49-
@MainActor
5049
func determineViewSize(
5150
for proposal: SIMD2<Int>, uiView: UIViewType,
5251
context: UIViewRepresentableContext<Coordinator>

Sources/WinUIBackend/WinUIBackend.swift

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -998,35 +998,35 @@ public final class WinUIBackend: AppBackend {
998998
// ) {
999999
// }
10001000

1001-
public func createClickTarget(wrapping child: Widget) -> Widget {
1002-
let clickTarget = ClickTarget()
1003-
addChild(child, to: clickTarget)
1004-
clickTarget.child = child
1001+
public func createTapGestureTarget(wrapping child: Widget) -> Widget {
1002+
let tapGestureTarget = TapGestureTarget()
1003+
addChild(child, to: tapGestureTarget)
1004+
tapGestureTarget.child = child
10051005

10061006
// Set a background so that the click target's entire area gets hit
10071007
// tested. The background we set is transparent so that it doesn't
10081008
// change the visual appearance of the view.
10091009
let brush = SolidColorBrush()
10101010
brush.color = UWP.Color(a: 0, r: 0, g: 0, b: 0)
1011-
clickTarget.background = brush
1011+
tapGestureTarget.background = brush
10121012

1013-
clickTarget.pointerPressed.addHandler { [weak clickTarget] _, _ in
1014-
guard let clickTarget else {
1013+
tapGestureTarget.pointerPressed.addHandler { [weak tapGestureTarget] _, _ in
1014+
guard let tapGestureTarget else {
10151015
return
10161016
}
1017-
clickTarget.clickHandler?()
1017+
tapGestureTarget.clickHandler?()
10181018
}
1019-
return clickTarget
1019+
return tapGestureTarget
10201020
}
10211021

1022-
public func updateClickTarget(
1023-
_ clickTarget: Widget,
1024-
clickHandler handleClick: @escaping () -> Void
1022+
public func updateTapGestureTarget(
1023+
_ tapGestureTarget: Widget,
1024+
action: @escaping () -> Void
10251025
) {
1026-
let clickTarget = clickTarget as! ClickTarget
1027-
clickTarget.clickHandler = handleClick
1028-
clickTarget.width = clickTarget.child!.width
1029-
clickTarget.height = clickTarget.child!.height
1026+
let tapGestureTarget = tapGestureTarget as! TapGestureTarget
1027+
tapGestureTarget.clickHandler = action
1028+
tapGestureTarget.width = tapGestureTarget.child!.width
1029+
tapGestureTarget.height = tapGestureTarget.child!.height
10301030
}
10311031

10321032
// public func createTable(rows: Int, columns: Int) -> Widget {
@@ -1159,7 +1159,7 @@ final class CustomSplitView: SplitView {
11591159
var sidebarResizeHandler: (() -> Void)?
11601160
}
11611161

1162-
final class ClickTarget: WinUI.Canvas {
1162+
final class TapGestureTarget: WinUI.Canvas {
11631163
var clickHandler: (() -> Void)?
11641164
var child: WinUI.FrameworkElement?
11651165
}

0 commit comments

Comments
 (0)