You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
6.2 KiB

  1. // Copyright (c) RxSwiftCommunity
  2. // Permission is hereby granted, free of charge, to any person obtaining a copy
  3. // of this software and associated documentation files (the "Software"), to deal
  4. // in the Software without restriction, including without limitation the rights
  5. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  6. // copies of the Software, and to permit persons to whom the Software is
  7. // furnished to do so, subject to the following conditions:
  8. // The above copyright notice and this permission notice shall be included in
  9. // all copies or substantial portions of the Software.
  10. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  14. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  15. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  16. // THE SOFTWARE.
  17. #if os(iOS)
  18. import UIKit
  19. #elseif os(OSX)
  20. import AppKit
  21. #endif
  22. import RxSwift
  23. import RxCocoa
  24. public struct GestureRecognizerDelegatePolicy<PolicyInput> {
  25. public typealias PolicyBody = (PolicyInput) -> Bool
  26. private let policy: PolicyBody
  27. private init(policy: @escaping PolicyBody) {
  28. self.policy = policy
  29. }
  30. public static func custom(_ policy: @escaping PolicyBody)
  31. -> GestureRecognizerDelegatePolicy<PolicyInput> {
  32. .init(policy: policy)
  33. }
  34. public static var always: GestureRecognizerDelegatePolicy<PolicyInput> {
  35. .init { _ in true }
  36. }
  37. public static var never: GestureRecognizerDelegatePolicy<PolicyInput> {
  38. .init { _ in false }
  39. }
  40. public func isPolicyPassing(with args: PolicyInput) -> Bool {
  41. policy(args)
  42. }
  43. }
  44. public func || <PolicyInput>(lhs: GestureRecognizerDelegatePolicy<PolicyInput>, rhs: GestureRecognizerDelegatePolicy<PolicyInput>) -> GestureRecognizerDelegatePolicy<PolicyInput> {
  45. .custom { input in
  46. lhs.isPolicyPassing(with: input) || rhs.isPolicyPassing(with: input)
  47. }
  48. }
  49. public func && <PolicyInput>(lhs: GestureRecognizerDelegatePolicy<PolicyInput>, rhs: GestureRecognizerDelegatePolicy<PolicyInput>) -> GestureRecognizerDelegatePolicy<PolicyInput> {
  50. .custom { input in
  51. lhs.isPolicyPassing(with: input) && rhs.isPolicyPassing(with: input)
  52. }
  53. }
  54. public final class GenericRxGestureRecognizerDelegate<Gesture: RxGestureRecognizer>: NSObject, RxGestureRecognizerDelegate {
  55. /// Corresponding delegate method: gestureRecognizerShouldBegin(:_)
  56. public var beginPolicy: GestureRecognizerDelegatePolicy<Gesture> = .always
  57. /// Corresponding delegate method: gestureRecognizer(_:shouldReceive:)
  58. public var touchReceptionPolicy: GestureRecognizerDelegatePolicy<(Gesture, RxGestureTouch)> = .always
  59. /// Corresponding delegate method: gestureRecognizer(_:shouldBeRequiredToFailBy:)
  60. public var selfFailureRequirementPolicy: GestureRecognizerDelegatePolicy<(Gesture, RxGestureRecognizer)> = .never
  61. /// Corresponding delegate method: gestureRecognizer(_:shouldRequireFailureOf:)
  62. public var otherFailureRequirementPolicy: GestureRecognizerDelegatePolicy<(Gesture, RxGestureRecognizer)> = .never
  63. /// Corresponding delegate method: gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
  64. public var simultaneousRecognitionPolicy: GestureRecognizerDelegatePolicy<(Gesture, RxGestureRecognizer)> = .always
  65. #if os(iOS)
  66. // Workaround because we can't have stored properties with @available annotation
  67. private var _pressReceptionPolicy: Any?
  68. /// Corresponding delegate method: gestureRecognizer(_:shouldReceive:)
  69. public var pressReceptionPolicy: GestureRecognizerDelegatePolicy<(Gesture, UIPress)> {
  70. get {
  71. _pressReceptionPolicy as? GestureRecognizerDelegatePolicy<(Gesture, UIPress)> ?? .always
  72. }
  73. set {
  74. _pressReceptionPolicy = newValue
  75. }
  76. }
  77. #endif
  78. #if os(OSX)
  79. /// Corresponding delegate method: gestureRecognizer(_:shouldAttemptToRecognizeWith:)
  80. public var eventRecognitionAttemptPolicy: GestureRecognizerDelegatePolicy<(Gesture, NSEvent)> = .always
  81. #endif
  82. public func gestureRecognizerShouldBegin(
  83. _ gestureRecognizer: RxGestureRecognizer
  84. ) -> Bool {
  85. beginPolicy.isPolicyPassing(with: gestureRecognizer as! Gesture)
  86. }
  87. public func gestureRecognizer(
  88. _ gestureRecognizer: RxGestureRecognizer,
  89. shouldReceive touch: RxGestureTouch
  90. ) -> Bool {
  91. touchReceptionPolicy.isPolicyPassing(
  92. with: (gestureRecognizer as! Gesture, touch)
  93. )
  94. }
  95. public func gestureRecognizer(
  96. _ gestureRecognizer: RxGestureRecognizer,
  97. shouldRequireFailureOf otherGestureRecognizer: RxGestureRecognizer
  98. ) -> Bool {
  99. otherFailureRequirementPolicy.isPolicyPassing(
  100. with: (gestureRecognizer as! Gesture, otherGestureRecognizer)
  101. )
  102. }
  103. public func gestureRecognizer(
  104. _ gestureRecognizer: RxGestureRecognizer,
  105. shouldBeRequiredToFailBy otherGestureRecognizer: RxGestureRecognizer
  106. ) -> Bool {
  107. selfFailureRequirementPolicy.isPolicyPassing(
  108. with: (gestureRecognizer as! Gesture, otherGestureRecognizer)
  109. )
  110. }
  111. public func gestureRecognizer(
  112. _ gestureRecognizer: RxGestureRecognizer,
  113. shouldRecognizeSimultaneouslyWith otherGestureRecognizer: RxGestureRecognizer
  114. ) -> Bool {
  115. simultaneousRecognitionPolicy.isPolicyPassing(
  116. with: (gestureRecognizer as! Gesture, otherGestureRecognizer)
  117. )
  118. }
  119. #if os(iOS)
  120. public func gestureRecognizer(
  121. _ gestureRecognizer: RxGestureRecognizer,
  122. shouldReceive press: UIPress
  123. ) -> Bool {
  124. pressReceptionPolicy.isPolicyPassing(
  125. with: (gestureRecognizer as! Gesture, press)
  126. )
  127. }
  128. #endif
  129. #if os(OSX)
  130. public func gestureRecognizer(
  131. _ gestureRecognizer: RxGestureRecognizer,
  132. shouldAttemptToRecognizeWith event: NSEvent
  133. ) -> Bool {
  134. eventRecognitionAttemptPolicy.isPolicyPassing(
  135. with: (gestureRecognizer as! Gesture, event)
  136. )
  137. }
  138. #endif
  139. }