@@ -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