9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
12 |
13 Controller subclass:#ButtonController |
13 Controller subclass:#ButtonController |
14 instanceVariableNames:'enabled pressed active entered triggerOnDown autoRepeat |
14 instanceVariableNames:'enabled pressed active entered isTriggerOnDown autoRepeat |
15 repeatBlock initialDelay repeatDelay |
15 repeatBlock initialDelay repeatDelay |
16 pressActionBlock releaseActionBlock' |
16 pressActionBlock releaseActionBlock isToggle' |
17 classVariableNames:'' |
17 classVariableNames:'' |
18 poolDictionaries:'' |
18 poolDictionaries:'' |
19 category:'Interface-Support' |
19 category:'Interface-Support' |
20 ! |
20 ! |
21 |
21 |
50 Instance variables: |
50 Instance variables: |
51 |
51 |
52 enabled <Boolean> pressing is allowed (default: true) |
52 enabled <Boolean> pressing is allowed (default: true) |
53 pressed <Boolean> true if currently pressed (read-only) |
53 pressed <Boolean> true if currently pressed (read-only) |
54 entered <Boolean> true if the cursor is currently in this view |
54 entered <Boolean> true if the cursor is currently in this view |
55 triggerOnDown <Boolean> controls if the action should be executed on |
55 isTriggerOnDown <Boolean> controls if the action should be executed on |
56 press or on release (default: on release). |
56 press or on release (default: on release). |
57 pressActionBlock <Block> block to evaluate when pressed (default: noop) |
57 pressActionBlock <Block> block to evaluate when pressed (default: noop) |
58 releaseActionBlock <Block> block to evaluate when released (default: noop) |
58 releaseActionBlock <Block> block to evaluate when released (default: noop) |
59 autoRepeat <Boolean> auto-repeats when pressed long enough (default: false) |
59 autoRepeat <Boolean> auto-repeats when pressed long enough (default: false) |
60 initialDelay <Number> seconds till first auto-repeat (default: 0.2) |
60 initialDelay <Number> seconds till first auto-repeat (default: 0.2) |
90 pressed := false. |
90 pressed := false. |
91 entered := false. |
91 entered := false. |
92 autoRepeat := false. |
92 autoRepeat := false. |
93 initialDelay := self class defaultInitialDelay. |
93 initialDelay := self class defaultInitialDelay. |
94 repeatDelay := self class defaultRepeatDelay. |
94 repeatDelay := self class defaultRepeatDelay. |
95 triggerOnDown := false. |
95 isTriggerOnDown := false. |
|
96 isToggle := false. |
96 ! ! |
97 ! ! |
97 |
98 |
98 !ButtonController methodsFor:'accessing'! |
99 !ButtonController methodsFor:'accessing'! |
|
100 |
|
101 beToggle |
|
102 "make the receiver act like a toggle" |
|
103 |
|
104 isTriggerOnDown := true. |
|
105 isToggle := true |
|
106 ! |
99 |
107 |
100 beTriggerOnUp |
108 beTriggerOnUp |
101 "make the receiver act on button release" |
109 "make the receiver act on button release" |
102 |
110 |
103 triggerOnDown := false |
111 isTriggerOnDown := false |
104 ! |
112 ! |
105 |
113 |
106 beTriggerOnDown |
114 beTriggerOnDown |
107 "make the receiver act on button press" |
115 "make the receiver act on button press" |
108 |
116 |
109 triggerOnDown := true |
117 isTriggerOnDown := true |
110 ! |
118 ! |
111 |
119 |
112 triggerOnDown:aBoolean |
120 triggerOnDown:aBoolean |
113 "set/clear the flag which controls if the action block is to be evaluated |
121 "set/clear the flag which controls if the action block is to be evaluated |
114 on press or on release. |
122 on press or on release. |
115 (see also ST-80 compatibility methods beTriggerOn*)" |
123 (see also ST-80 compatibility methods beTriggerOn*)" |
116 |
124 |
117 triggerOnDown := aBoolean |
125 isTriggerOnDown := aBoolean |
118 ! |
126 ! |
119 |
127 |
120 isTriggerOnDown |
128 isTriggerOnDown |
121 "return true, if I trigger on press |
129 "return true, if I trigger on press |
122 (in contrast to triggering on up, which is the default)" |
130 (in contrast to triggering on up, which is the default)" |
123 |
131 |
124 ^ triggerOnDown |
132 ^ isTriggerOnDown |
125 ! |
133 ! |
126 |
134 |
127 pressAction |
135 pressAction |
128 "return the pressAction; thats the block which gets evaluated |
136 "return the pressAction; thats the block which gets evaluated |
129 when the button is pressed (if non-nil)" |
137 when the button is pressed (if non-nil)" |
153 action:aBlock |
161 action:aBlock |
154 "convenient method: depending on the setting the triggerOnDown flag, |
162 "convenient method: depending on the setting the triggerOnDown flag, |
155 either set the press-action clear any release-action or |
163 either set the press-action clear any release-action or |
156 vice versa, set the release-action and clear the press-action." |
164 vice versa, set the release-action and clear the press-action." |
157 |
165 |
158 triggerOnDown ifTrue:[ |
166 isTriggerOnDown ifTrue:[ |
159 releaseActionBlock := nil. |
167 releaseActionBlock := nil. |
160 pressActionBlock := aBlock |
168 pressActionBlock := aBlock |
161 ] ifFalse:[ |
169 ] ifFalse:[ |
162 releaseActionBlock := aBlock. |
170 releaseActionBlock := aBlock. |
163 pressActionBlock := nil |
171 pressActionBlock := nil |
222 pressed := aBoolean |
230 pressed := aBoolean |
223 ! |
231 ! |
224 |
232 |
225 active:aBoolean |
233 active:aBoolean |
226 active := aBoolean |
234 active := aBoolean |
|
235 ! |
|
236 |
|
237 toggleNoAction |
|
238 "toggle, but do NOT perform any action" |
|
239 |
|
240 pressed ifTrue:[ |
|
241 view turnOff. |
|
242 pressed := false. |
|
243 ] ifFalse:[ |
|
244 view turnOn. |
|
245 pressed := true. |
|
246 ]. |
|
247 ! |
|
248 |
|
249 toggle |
|
250 "toggle and perform the action" |
|
251 |
|
252 enabled ifTrue:[ |
|
253 self toggleNoAction. |
|
254 self performAction. |
|
255 view sendChangeMessageWith:pressed. |
|
256 view changed:#toggle with:pressed |
|
257 ] |
227 ! ! |
258 ! ! |
228 |
259 |
229 !ButtonController methodsFor:'event handling'! |
260 !ButtonController methodsFor:'event handling'! |
230 |
261 |
|
262 performAction |
|
263 |action| |
|
264 |
|
265 pressed ifTrue:[ |
|
266 action := pressActionBlock |
|
267 ] ifFalse:[ |
|
268 action := releaseActionBlock |
|
269 ]. |
|
270 action notNil ifTrue:[action value]. |
|
271 ! |
|
272 |
231 buttonPress:button x:x y:y |
273 buttonPress:button x:x y:y |
232 |sym| |
274 |sym action| |
233 |
275 |
234 (button == 1 or:[button == #select]) ifFalse:[ |
276 (button == 1 or:[button == #select]) ifFalse:[ |
235 ^ super buttonPress:button x:x y:y |
277 ^ super buttonPress:button x:x y:y |
236 ]. |
278 ]. |
237 |
279 |
238 pressed ifFalse:[ |
280 enabled ifTrue:[ |
239 enabled ifTrue:[ |
281 isToggle ifTrue:[ |
|
282 self toggle. |
|
283 ^ self |
|
284 ]. |
|
285 |
|
286 pressed ifFalse:[ |
240 pressed := true. |
287 pressed := true. |
241 view showActive. |
288 view showActive. |
242 |
289 |
243 (pressActionBlock notNil or:[model notNil]) ifTrue:[ |
290 (pressActionBlock notNil or:[model notNil]) ifTrue:[ |
244 " |
291 " |
325 entered := true. |
374 entered := true. |
326 pressed ifTrue:[ |
375 pressed ifTrue:[ |
327 " |
376 " |
328 reentered after a leave with mouse-button down; |
377 reentered after a leave with mouse-button down; |
329 restart autorepeating and/or if I am a button with |
378 restart autorepeating and/or if I am a button with |
330 triggerOnDown, show active again. |
379 isTriggerOnDown, show active again. |
331 " |
380 " |
332 enabled ifTrue:[ |
381 enabled ifTrue:[ |
333 autoRepeat ifTrue:[ |
382 autoRepeat ifTrue:[ |
334 Processor addTimedBlock:repeatBlock afterSeconds:initialDelay |
383 Processor addTimedBlock:repeatBlock afterSeconds:initialDelay |
335 ]. |
384 ]. |
336 triggerOnDown ifFalse:[ |
385 isTriggerOnDown ifFalse:[ |
337 view showActive. |
386 view showActive. |
338 ] |
387 ] |
339 ] |
388 ] |
340 ] ifFalse:[ |
389 ] ifFalse:[ |
341 enabled ifTrue:[ |
390 enabled ifTrue:[ |