"Fossies" - the Fresh Open Source Software Archive 
Member "jitsi-meet-7563/ios/sdk/src/picture-in-picture/DragGestureController.swift" (2 Oct 2023, 4350 Bytes) of package /linux/misc/jitsi-meet-7563.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Swift source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 * Copyright @ 2017-present Atlassian Pty Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 import UIKit
18
19 final class DragGestureController {
20 var insets: UIEdgeInsets = UIEdgeInsets.zero
21 var currentPosition: PiPViewCoordinator.Position? = nil
22
23 private var frameBeforeDragging: CGRect = CGRect.zero
24 private weak var view: UIView?
25 private lazy var panGesture: UIPanGestureRecognizer = {
26 UIPanGestureRecognizer(target: self,
27 action: #selector(handlePan(gesture:)))
28 }()
29
30 func startDragListener(inView view: UIView) {
31 self.view = view
32 view.addGestureRecognizer(panGesture)
33 panGesture.isEnabled = true
34 }
35
36 func stopDragListener() {
37 panGesture.isEnabled = false
38 view?.removeGestureRecognizer(panGesture)
39 view = nil
40 }
41
42 @objc private func handlePan(gesture: UIPanGestureRecognizer) {
43 guard let view = view else { return }
44
45 let translation = gesture.translation(in: view.superview)
46 let velocity = gesture.velocity(in: view.superview)
47 var frame = frameBeforeDragging
48
49 switch gesture.state {
50 case .began:
51 frameBeforeDragging = view.frame
52
53 case .changed:
54 frame.origin.x = floor(frame.origin.x + translation.x)
55 frame.origin.y = floor(frame.origin.y + translation.y)
56 view.frame = frame
57
58 case .ended:
59 let currentPos = view.frame.origin
60 let finalPos = calculateFinalPosition()
61
62 let distance = CGPoint(x: currentPos.x - finalPos.x,
63 y: currentPos.y - finalPos.y)
64 let distanceMagnitude = magnitude(vector: distance)
65 let velocityMagnitude = magnitude(vector: velocity)
66 let animationDuration = 0.5
67 let initialSpringVelocity =
68 velocityMagnitude / distanceMagnitude / CGFloat(animationDuration)
69
70 frame.origin = CGPoint(x: finalPos.x, y: finalPos.y)
71
72 UIView.animate(withDuration: animationDuration,
73 delay: 0,
74 usingSpringWithDamping: 0.9,
75 initialSpringVelocity: initialSpringVelocity,
76 options: .curveLinear,
77 animations: {
78 view.frame = frame })
79
80 default:
81 break
82 }
83 }
84
85 private func calculateFinalPosition() -> CGPoint {
86 guard
87 let view = view,
88 let bounds = view.superview?.frame
89 else {
90 return CGPoint.zero
91 }
92
93 let currentSize = view.frame.size
94 let adjustedBounds = bounds.inset(by: insets)
95 let threshold: CGFloat = 20.0
96 let velocity = panGesture.velocity(in: view.superview)
97 let location = panGesture.location(in: view.superview)
98
99 let goLeft: Bool
100 if abs(velocity.x) > threshold {
101 goLeft = velocity.x < -threshold
102 } else {
103 goLeft = location.x < bounds.midX
104 }
105
106 let goUp: Bool
107 if abs(velocity.y) > threshold {
108 goUp = velocity.y < -threshold
109 } else {
110 goUp = location.y < bounds.midY
111 }
112
113 if (goLeft && goUp) {
114 currentPosition = .upperLeftCorner
115 }
116
117 if (!goLeft && goUp) {
118 currentPosition = .upperRightCorner
119 }
120
121 if (!goLeft && !goUp) {
122 currentPosition = .lowerRightCorner
123 }
124
125 if (goLeft && !goUp) {
126 currentPosition = .lowerLeftCorner
127 }
128
129 return currentPosition!.getOriginIn(bounds: adjustedBounds, size: currentSize)
130 }
131
132 private func magnitude(vector: CGPoint) -> CGFloat {
133 sqrt(pow(vector.x, 2) + pow(vector.y, 2))
134 }
135 }