Skip to content

Commit 2932df7

Browse files
committed
Merge Toggle into Button
1 parent 65db8ec commit 2932df7

File tree

2 files changed

+146
-257
lines changed

2 files changed

+146
-257
lines changed

Sources/GateEngine/UI/Button.swift

Lines changed: 146 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,39 @@ open class Button: Control {
3636
}
3737
}
3838

39+
public enum Kind {
40+
case momentaryPush
41+
case toggle
42+
}
43+
public let kind: Kind
44+
45+
public var _value: Bool = false
46+
public var value: Bool {
47+
get {
48+
switch self.kind {
49+
case .momentaryPush:
50+
return self.state == .selected
51+
case .toggle:
52+
return _value
53+
}
54+
}
55+
set {
56+
switch self.kind {
57+
case .momentaryPush:
58+
break
59+
case .toggle:
60+
self._value = newValue
61+
if self.state != .highlighted {
62+
if self._value {
63+
self.setState(.selected, sendActions: false)
64+
}else{
65+
self.setState(.normal, sendActions: false)
66+
}
67+
}
68+
}
69+
}
70+
}
71+
3972
open override func canBeHit() -> Bool {
4073
return true
4174
}
@@ -45,107 +78,187 @@ open class Button: Control {
4578
public var rawValue: RawValue
4679

4780
public static let pressed = Self(rawValue: 1 << 0)
81+
public static let stateChanged = Self(rawValue: 1 << 1)
4882

4983
public init(rawValue: RawValue) {
5084
self.rawValue = rawValue
5185
}
5286
}
5387

54-
private var eventActionStorage: [Event: [(Button)->()]] = [:]
88+
private var eventActionStorage: [Event: [(_ button: Button)->()]] = [:]
5589

5690
public final func sendActions(forEvent event: Event) {
57-
if let eventActionStorage = eventActionStorage[event] {
58-
weak let unownedSelf: Button! = self
91+
if let eventActionStorage = self.eventActionStorage[event] {
5992
for block in eventActionStorage {
60-
block(unownedSelf)
93+
Task(priority: .userInitiated) { @MainActor in
94+
block(self)
95+
}
6196
}
6297
}
6398
}
6499

65-
public final func action(completion: @escaping (Button)->()) {
66-
var array = eventActionStorage[.pressed] ?? []
100+
public final func addAction(forEvent event: Event, completion: @escaping (_ button: Button)->()) {
101+
var array = eventActionStorage[event] ?? []
67102
array.append(completion)
68-
eventActionStorage[.pressed] = array
103+
eventActionStorage[event] = array
69104
}
70105

71106
public enum State {
72107
case normal
73108
case highlighted
74109
case selected
75110
}
76-
public var state: State = .normal {
77-
didSet {
78-
if state != oldValue {
79-
self.stateDidChange()
80-
if let color = backgroundColors[state] {
81-
self.backgroundColor = color
82-
}
83-
if labelCreated {
84-
if let color = textColors[state] {
85-
self.label.textColor = color
86-
}
87-
}
111+
private var _state: State = .normal
112+
public var state: State {
113+
get {
114+
return _state
115+
}
116+
set {
117+
self.setState(newValue, sendActions: false)
118+
}
119+
}
120+
121+
private func setState(_ state: State, sendActions: Bool = true) {
122+
let previousState = self._state
123+
self._state = state
124+
if previousState != state {
125+
self._stateDidChange(sendActions: sendActions)
126+
}
127+
}
128+
129+
final func _stateDidChange(sendActions: Bool) {
130+
if let color = backgroundColors[state] {
131+
self.backgroundColor = color
132+
}
133+
if labelCreated {
134+
if let color = textColors[state] {
135+
self.label.textColor = color
88136
}
89137
}
138+
if sendActions {
139+
self.sendActions(forEvent: .stateChanged)
140+
}
141+
self.stateDidChange()
90142
}
91143

92144
open func stateDidChange() {
93145

94146
}
95147

96148
open override func cursorEntered(_ cursor: Mouse) {
97-
self.state = .highlighted
149+
self.setState(.highlighted)
98150
}
99151

100152
open override func cursorExited(_ cursor: Mouse) {
101-
self.state = .normal
153+
switch self.kind {
154+
case .momentaryPush:
155+
self.setState(.normal)
156+
case .toggle:
157+
if value {
158+
self.setState(.selected)
159+
}else{
160+
self.setState(.normal)
161+
}
162+
}
102163
}
103164

104165
open override func cursorButtonDown(button: MouseButton, mouse: Mouse) {
166+
self.setState(.selected)
105167
if let mouseLocation = mouse.locationInView(self) {
106168
if self.bounds.contains(mouseLocation) {
169+
switch self.kind {
170+
case .momentaryPush:
171+
break
172+
case .toggle:
173+
self._value.toggle()
174+
}
107175
self.sendActions(forEvent: .pressed)
108176
}
109177
}
110-
self.state = .selected
111178
}
112179

113180
open override func cursorButtonUp(button: MouseButton, mouse: Mouse) {
114181
if mouse.isInsideView(self) {
115-
self.state = .highlighted
182+
self.setState(.highlighted)
116183
}else{
117-
self.state = .normal
184+
switch kind {
185+
case .momentaryPush:
186+
self.setState(.normal)
187+
case .toggle:
188+
if _value {
189+
self.setState(.selected)
190+
}else{
191+
self.setState(.normal)
192+
}
193+
}
118194
}
119195
}
120196

121197
open override func touchesBegan(_ touches: Set<Touch>) {
122-
self.state = .selected
198+
self.setState(.selected)
123199
}
124200

125201
open override func touchesMoved(_ touches: Set<Touch>) {
126-
self.state = .normal
202+
var nextState: State = .normal
203+
switch self.kind {
204+
case .momentaryPush:
205+
break
206+
case .toggle:
207+
if _value {
208+
nextState = .selected
209+
}else{
210+
nextState = .normal
211+
}
212+
}
213+
127214
for touch in touches {
128215
if touch.isInsideView(self) {
129-
self.state = .selected
216+
nextState = .selected
130217
}
131218
}
219+
self.setState(nextState)
132220
}
133221

134222
open override func touchesEnded(_ touches: Set<Touch>) {
135-
self.state = .normal
136223
for touch in touches {
137224
if touch.isInsideView(self) {
225+
switch self.kind {
226+
case .momentaryPush:
227+
break
228+
case .toggle:
229+
self._value.toggle()
230+
}
138231
self.sendActions(forEvent: .pressed)
139232
break
140233
}
141234
}
235+
switch self.kind {
236+
case .momentaryPush:
237+
self.setState(.normal)
238+
case .toggle:
239+
if _value {
240+
self.setState(.selected)
241+
}else{
242+
self.setState(.normal)
243+
}
244+
}
142245
}
143246

144247
open override func touchesCanceled(_ touches: Set<Touch>) {
145-
self.state = .normal
248+
switch kind {
249+
case .momentaryPush:
250+
self.setState(.normal)
251+
case .toggle:
252+
if _value {
253+
self.setState(.selected)
254+
}else{
255+
self.setState(.normal)
256+
}
257+
}
146258
}
147259

148-
public init(size: Size2? = nil, label: String? = nil, textColor: Color = .white, backgroundColor: Color = .blue, cornorRadius: Float? = nil, action: ((Button)->())? = nil) {
260+
public init(kind: Kind = .momentaryPush, size: Size2? = nil, label: String? = nil, textColor: Color = .white, backgroundColor: Color = .blue, cornorRadius: Float? = nil, action: ((_ button: Button)->())? = nil) {
261+
self.kind = kind
149262
super.init()
150263

151264
self.clipToBounds = true
@@ -166,20 +279,20 @@ open class Button: Control {
166279
self.label.textColor = textColor
167280
}
168281
if let action {
169-
self.eventActionStorage[.pressed] = [action]
282+
self.addAction(forEvent: .pressed, completion: action)
170283
}
171284

172285
if let cornorRadius {
173286
self.cornerRadius = cornorRadius
174287
}
175288

176-
self.stateDidChange()
289+
self.setState(.normal, sendActions: false)
177290
}
178291

179292
private var labelCreated: Bool = false
180293
weak var _label: Label! = nil
181294
func createLabel() {
182-
let label = Label(text: "Button", font: .default, fontSize: 18, style: .bold, textColor: self.textColors[.normal] ?? .white)
295+
let label = Label(text: kind == .momentaryPush ? "Button" : "Toggle", font: .default, fontSize: 18, style: .bold, textColor: self.textColors[.normal] ?? .white)
183296
label.centerXAnchor.constrain(to: self.centerXAnchor)
184297
label.centerYAnchor.constrain(to: self.centerYAnchor)
185298
label.widthAnchor.constrain(to: self.widthAnchor)

0 commit comments

Comments
 (0)