-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathCGChatListIndicator.swift
More file actions
139 lines (115 loc) · 4.01 KB
/
Copy pathCGChatListIndicator.swift
File metadata and controls
139 lines (115 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// CGChatListIndicator.swift
// Telegram
//
// Created by Mikhail Filimonov on 09.12.2020.
// Copyright © 2020 Telegram. All rights reserved.
//
import Foundation
import TGUIKit
import SwiftSignalKit
final class GCChatListIndicator : View {
var color: NSColor = NSColor.white {
didSet {
CATransaction.begin()
CATransaction.setDisableActions(true)
(self.layer as? CAShapeLayer)?.fillColor = color.cgColor
CATransaction.commit()
}
}
init(color: NSColor) {
self.color = color
super.init(frame: NSMakeRect(0, 0, 10, 20))
self.layer = SimpleShapeLayer()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
required init(frame frameRect: NSRect) {
fatalError("init(frame:) has not been implemented")
}
private var animator: DisplayLinkAnimator?
private let keyDispose = MetaDisposable()
deinit {
keyDispose.dispose()
}
override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
if window == nil || isLite(.animations) {
stopAnimation()
keyDispose.set(nil)
progressStage = 8
innerProgress = 0.5
} else {
startAnimation()
if let window = window as? Window {
keyDispose.set(window.visibility.start(next: { [weak self] value in
if value {
self?.startAnimation()
} else {
self?.stopAnimation()
}
}))
}
}
}
func startAnimation() {
self.animator = DisplayLinkAnimator(duration: 0.4, from: innerProgress, to: 1, update: { [weak self] value in
self?.innerProgress = value
}, completion: { [weak self] in
self?.startAnimation()
})
}
func stopAnimation() {
self.animator = nil
}
private var progressStage: Int = 0
private var innerProgress: CGFloat = 0 {
didSet {
if (innerProgress >= 1.0) {
progressStage += 1
if (progressStage >= 8) {
progressStage = 0
}
innerProgress = 0
}
let layer = (self.layer as? CAShapeLayer)
layer?.path = genPath()
}
}
private func genPath() -> CGPath {
let rect = self.bounds
var size1: CGFloat = 0;
var size2: CGFloat = 0;
if (progressStage == 0) {
size1 = 2 + 8 * innerProgress
size2 = 6 - 4 * innerProgress
} else if (progressStage == 1) {
size1 = 10 - 8 * innerProgress
size2 = 2 + 8 * innerProgress
} else if (progressStage == 2) {
size1 = 2 + 4 * innerProgress
size2 = 10 - 8 * innerProgress
} else if (progressStage == 3) {
size1 = 6 - 4 * innerProgress
size2 = 2 + 4 * innerProgress
} else if (progressStage == 4) {
size1 = 2 + 8 * innerProgress
size2 = 6 - 4 * innerProgress
} else if (progressStage == 5) {
size1 = 10 - 8 * innerProgress
size2 = 2 + 8 * innerProgress
} else if (progressStage == 6) {
size1 = 2 + 8 * innerProgress
size2 = 10 - 8 * innerProgress
} else {
size1 = 10 - 8 * innerProgress
size2 = 2 + 4 * innerProgress
}
let p1 = CGMutablePath()
p1.addRoundedRect(in: .init(origin: NSMakePoint(0, rect.midY - size2 / 2), size: NSMakeSize(2, size2)), cornerWidth: 1, cornerHeight: 1)
p1.addRoundedRect(in: .init(origin: NSMakePoint(4, rect.midY - size1 / 2), size: NSMakeSize(2, size1)), cornerWidth: 1, cornerHeight: 1)
p1.addRoundedRect(in: .init(origin: NSMakePoint(8, rect.midY - size2 / 2), size: NSMakeSize(2, size2)), cornerWidth: 1, cornerHeight: 1)
return p1
}
}