ButtonController.st
changeset 125 3ffa271732f7
parent 121 4e63bbdb266a
child 126 40228f4fd66b
equal deleted inserted replaced
124:7abd3a234296 125:3ffa271732f7
    12 
    12 
    13 'From Smalltalk/X, Version:2.10.5 on 4-may-1995 at 6:17:35 am'!
    13 'From Smalltalk/X, Version:2.10.5 on 4-may-1995 at 6:17:35 am'!
    14 
    14 
    15 Controller subclass:#ButtonController
    15 Controller subclass:#ButtonController
    16 	 instanceVariableNames:'enabled pressed active entered isTriggerOnDown autoRepeat
    16 	 instanceVariableNames:'enabled pressed active entered isTriggerOnDown autoRepeat
    17                 repeatBlock initialDelay repeatDelay pressActionBlock
    17 		repeatBlock initialDelay repeatDelay pressActionBlock
    18                 releaseActionBlock isToggle'
    18 		releaseActionBlock isToggle'
    19 	 classVariableNames:''
    19 	 classVariableNames:''
    20 	 poolDictionaries:''
    20 	 poolDictionaries:''
    21 	 category:'Interface-Support'
    21 	 category:'Interface-Support'
    22 !
    22 !
    23 
    23 
    37 "
    37 "
    38 !
    38 !
    39 
    39 
    40 version
    40 version
    41 "
    41 "
    42 $Header: /cvs/stx/stx/libwidg/ButtonController.st,v 1.7 1995-05-06 14:16:24 claus Exp $
    42 $Header: /cvs/stx/stx/libwidg/ButtonController.st,v 1.8 1995-05-09 01:54:58 claus Exp $
    43 "
    43 "
    44 !
    44 !
    45 
    45 
    46 documentation
    46 documentation
    47 "
    47 "
    48     ButtonControllers are used with buttons and handle all user interaction.
    48     ButtonControllers are used with buttons and handle all user interaction.
    49     These are automatically created when a Button is created, therefore no manual
    49     These are automatically created when a Button is created, therefore no manual
    50     action is required for creation.
    50     action is required for creation.
       
    51     In normal applications, you dont have to care for the controller; access to the
       
    52     controllers behavior is also possible via messages to the button.
       
    53     (setting actions, controlling autorepeat etc.)
    51 
    54 
    52     Instance variables:
    55     Instance variables:
    53 
    56 
    54       enabled                 <Boolean>       pressing is allowed (default: true)
    57       enabled                 <Boolean>       pressing is allowed (default: true)
       
    58 
    55       pressed                 <Boolean>       true if currently pressed (read-only)
    59       pressed                 <Boolean>       true if currently pressed (read-only)
       
    60 
    56       entered                 <Boolean>       true if the cursor is currently in this view
    61       entered                 <Boolean>       true if the cursor is currently in this view
       
    62 
    57       isTriggerOnDown         <Boolean>       controls if the action should be executed on
    63       isTriggerOnDown         <Boolean>       controls if the action should be executed on
    58 					      press or on release (default: on release).
    64 					      press or on release (default: on release).
       
    65 
       
    66       isToggle                <Boolean>       controls if the button should show toggle
       
    67 					      behavior (as opposed to one-shot behavior)
       
    68 
    59       pressActionBlock        <Block>         block to evaluate when pressed (default: noop)
    69       pressActionBlock        <Block>         block to evaluate when pressed (default: noop)
       
    70 
    60       releaseActionBlock      <Block>         block to evaluate when released (default: noop)
    71       releaseActionBlock      <Block>         block to evaluate when released (default: noop)
       
    72 
    61       autoRepeat              <Boolean>       auto-repeats when pressed long enough (default: false)
    73       autoRepeat              <Boolean>       auto-repeats when pressed long enough (default: false)
       
    74 
    62       initialDelay            <Number>        seconds till first auto-repeat (default: 0.2)
    75       initialDelay            <Number>        seconds till first auto-repeat (default: 0.2)
       
    76 
    63       repeatDelay             <Number>        seconds of repeat intervall (default: 0.025)
    77       repeatDelay             <Number>        seconds of repeat intervall (default: 0.025)
       
    78 
    64       repeatBlock             <Block>         block evaluated for auto-repeat (internal)
    79       repeatBlock             <Block>         block evaluated for auto-repeat (internal)
       
    80 
    65       active                  <Boolean>       true during action evaluation (internal)
    81       active                  <Boolean>       true during action evaluation (internal)
    66 "
    82 "
    67 ! !
    83 ! !
    68 
    84 
    69 !ButtonController class methodsFor:'defaults'!
    85 !ButtonController class methodsFor:'defaults'!
    89 
   105 
    90     ^ pressed
   106     ^ pressed
    91 !
   107 !
    92 
   108 
    93 active
   109 active
    94     "return true, if I am active; that is currently performing my
   110     "return true, if I am active; 
    95      action."
   111      that is: currently performing my action.
       
   112      This query can be used to avoid multiple redraws."
    96 
   113 
    97     ^ active
   114     ^ active
    98 !
   115 !
    99 
   116 
   100 enabled
   117 enabled
   211 
   228 
   212 toggle
   229 toggle
   213     "toggle and perform the action"
   230     "toggle and perform the action"
   214 
   231 
   215     enabled ifTrue:[
   232     enabled ifTrue:[
   216         self toggleNoAction.
   233 	self toggleNoAction.
   217         self performAction.
   234 	self performAction.
   218         view changed:#toggle with:pressed
   235 	view changed:#toggle with:pressed
   219     ]
   236     ]
   220 !
   237 !
   221 
   238 
   222 pressAction
   239 pressAction
   223     "return the pressAction; thats the block which gets evaluated
   240     "return the pressAction; thats the block which gets evaluated
   246 
   263 
   247 buttonPress:button x:x y:y
   264 buttonPress:button x:x y:y
   248     |sym action|
   265     |sym action|
   249 
   266 
   250     (button == 1 or:[button == #select]) ifFalse:[
   267     (button == 1 or:[button == #select]) ifFalse:[
   251         ^ super buttonPress:button x:x y:y
   268 	^ super buttonPress:button x:x y:y
   252     ].
   269     ].
   253 
   270 
   254     enabled ifTrue:[
   271     enabled ifTrue:[
   255         isToggle ifTrue:[
   272 	isToggle ifTrue:[
   256             self toggle.
   273 	    self toggle.
   257             ^ self
   274 	    ^ self
   258         ].
   275 	].
   259 
   276 
   260         pressed ifFalse:[
   277 	pressed ifFalse:[
   261             pressed := true.
   278 	    pressed := true.
   262             view showActive.
   279 	    view showActive.
   263 
   280 
   264             (pressActionBlock notNil or:[model notNil]) ifTrue:[
   281 	    (pressActionBlock notNil or:[model notNil]) ifTrue:[
   265                 "
   282 		"
   266                  force output - so that button is drawn correctly in case
   283 		 force output - so that button is drawn correctly in case
   267                  of any long-computation (at high priority)
   284 		 of any long-computation (at high priority)
   268                 "
   285 		"
   269                 view device synchronizeOutput.
   286 		view device synchronizeOutput.
   270             ].
   287 	    ].
   271 
   288 
   272             active := true.
   289 	    self performAction.
   273 
   290 
   274             self performAction.
   291 	    autoRepeat ifTrue:[
   275 
   292 		Processor addTimedBlock:repeatBlock afterSeconds:initialDelay
   276             active := false.
   293 	    ]
   277 
   294 	]
   278             autoRepeat ifTrue:[
       
   279                 Processor addTimedBlock:repeatBlock afterSeconds:initialDelay
       
   280             ]
       
   281         ]
       
   282     ]
   295     ]
   283 !
   296 !
   284 
   297 
   285 buttonRelease:button x:x y:y
   298 buttonRelease:button x:x y:y
   286     "button was released - if enabled, perform releaseaction"
   299     "button was released - if enabled, perform releaseaction"
   287 
   300 
   288     |sym|
   301     |sym|
   289 
   302 
   290     (button == 1 or:[button == #select]) ifFalse:[
   303     (button == 1 or:[button == #select]) ifFalse:[
   291         ^ super buttonRelease:button x:x y:y
   304 	^ super buttonRelease:button x:x y:y
   292     ].
   305     ].
   293 
   306 
   294     isToggle ifTrue:[
   307     isToggle ifTrue:[
   295         ^ self
   308 	^ self
   296     ].
   309     ].
   297 
   310 
   298     pressed ifTrue:[
   311     pressed ifTrue:[
   299         autoRepeat ifTrue:[
   312 	autoRepeat ifTrue:[
   300             Processor removeTimedBlock:repeatBlock
   313 	    Processor removeTimedBlock:repeatBlock
   301         ].
   314 	].
   302         pressed := false.
   315 	pressed := false.
   303         view showPassive.
   316 	view showPassive.
   304 
   317 
   305         enabled ifTrue:[
   318 	enabled ifTrue:[
   306             "
   319 	    "
   307              only perform action if released within myself
   320 	     only perform action if released within myself
   308             "
   321 	    "
   309             ((x >= 0) 
   322 	    ((x >= 0) 
   310             and:[x <= view width
   323 	    and:[x <= view width
   311             and:[y >= 0
   324 	    and:[y >= 0
   312             and:[y <= view height]]]) ifTrue:[
   325 	    and:[y <= view height]]]) ifTrue:[
   313                 (releaseActionBlock notNil or:[model notNil]) ifTrue:[
   326 		(releaseActionBlock notNil or:[model notNil]) ifTrue:[
   314                     "
   327 		    "
   315                      force output - so that button is drawn correctly in case
   328 		     force output - so that button is drawn correctly in case
   316                      of any long-computation (at high priority)
   329 		     of any long-computation (at high priority)
   317                     "
   330 		    "
   318                     view device synchronizeOutput.
   331 		    view device synchronizeOutput.
   319                 ].
   332 		].
   320 
   333 
   321                 active := true.
   334 		self performAction.
   322 
   335 	    ]
   323                 self performAction.
   336 	]
   324 
       
   325                 active := false.
       
   326             ]
       
   327         ]
       
   328     ]
   337     ]
   329 !
   338 !
   330 
   339 
   331 pointerEnter:state x:x y:y
   340 pointerEnter:state x:x y:y
   332     "redraw with enteredColors if they differ from the normal colors"
   341     "mouse pointer entered my view.
       
   342      Redraw with enteredColors if they differ from the normal colors"
   333 
   343 
   334     entered := true.
   344     entered := true.
   335     pressed ifTrue:[
   345     enabled ifTrue:[
   336 	"
   346 	pressed ifTrue:[
   337 	 reentered after a leave with mouse-button down;
   347 	    "
   338 	 restart autorepeating and/or if I am a button with
   348 	     reentered after a leave with mouse-button down;
   339 	 isTriggerOnDown, show active again.
   349 	     restart autorepeating and/or if I am a button with
   340 	"
   350 	     triggerOnDown, show active again.
   341 	enabled ifTrue:[
   351 	    "
   342 	    autoRepeat ifTrue:[
   352 	    autoRepeat ifTrue:[
   343 		Processor addTimedBlock:repeatBlock afterSeconds:initialDelay
   353 		Processor addTimedBlock:repeatBlock afterSeconds:initialDelay
   344 	    ].
   354 	    ].
   345 	    isTriggerOnDown ifFalse:[
   355 	    isTriggerOnDown ifFalse:[
   346 		view showActive.
   356 		view showActive.
   347 	    ]
   357 	    ]
   348 	]
   358 	] ifFalse:[
   349     ] ifFalse:[
       
   350 	enabled ifTrue:[
       
   351 	    view redraw
   359 	    view redraw
   352 	]
   360 	]
   353     ]
   361     ]
   354 !
   362 !
   355 
   363 
   356 pointerLeave:state
   364 pointerLeave:state
   357     "redraw with normal colors if they differ from enteredColors"
   365     "mouse pointer left my view.
       
   366      Redraw with normal colors if they differ from enteredColors"
   358 
   367 
   359     entered := false.
   368     entered := false.
   360     pressed ifTrue:[
   369     pressed ifTrue:[
   361 	"
   370 	"
   362 	 leave with mouse-button down;
   371 	 leave with mouse-button down;
   377 !
   386 !
   378 
   387 
   379 performAction
   388 performAction
   380     |action|
   389     |action|
   381 
   390 
       
   391     "
       
   392      ST/X style actionBlock evaluation ...
       
   393     "
   382     pressed ifTrue:[
   394     pressed ifTrue:[
   383         action := pressActionBlock
   395 	action := pressActionBlock
   384     ] ifFalse:[
   396     ] ifFalse:[
   385         action := releaseActionBlock
   397 	action := releaseActionBlock
   386     ].
   398     ].
   387     action notNil ifTrue:[action value].
   399     action notNil ifTrue:[
   388 
   400 	active := true.
       
   401 	action numArgs == 0 ifTrue:[
       
   402 	    action value
       
   403 	] ifFalse:[
       
   404 	    action value:pressed
       
   405 	].
       
   406 	active := false.
       
   407     ].
       
   408 
       
   409     "
       
   410      ST-80 style model notification ...
       
   411     "
   389     (isToggle
   412     (isToggle
   390     or:[(isTriggerOnDown and:[pressed])
   413     or:[(isTriggerOnDown and:[pressed])
   391     or:[isTriggerOnDown not and:[pressed not]]]) ifTrue:[
   414     or:[isTriggerOnDown not and:[pressed not]]]) ifTrue:[
   392         "the ST-80 way of doing things"
   415 	"the ST-80 way of doing things"
   393         view notNil ifTrue:[
   416 	view notNil ifTrue:[
   394             view sendChangeMessageWith:pressed.
   417 	    active := true.
   395         ].
   418 	    view sendChangeMessageWith:pressed.
       
   419 	    active := false.
       
   420 	].
   396     ].
   421     ].
   397 !
   422 !
   398 
   423 
   399 buttonMultiPress:button x:x y:y
   424 buttonMultiPress:button x:x y:y
   400     ^ self buttonPress:button x:x y:y
   425     ^ self buttonPress:button x:x y:y
   401 !
   426 !
   402 
   427 
   403 keyPress:key x:x y:y
   428 keyPress:key x:x y:y
   404     "only trigger, if I am the focusView of my group"
   429     "trigger on Return and space, if I am the focusView of my group
   405 
   430      (i.e. if I got an explicit focus)"
   406     |group|
   431 
   407 
   432     (key == #Return or:[key == Character space]) ifTrue:[
   408     ((group := view windowGroup) notNil 
   433 	view hasFocus ifTrue:[
   409     and:[group focusView == view]) ifTrue:[
       
   410 	(key == #Return or:[key == Character space]) ifTrue:[
       
   411 	    "just simulate a buttonPress/release here."
   434 	    "just simulate a buttonPress/release here."
   412 	    self buttonPress:1 x:0 y:0.
   435 	    self buttonPress:1 x:0 y:0.
   413 	    self buttonRelease:1 x:0 y:0.
   436 	    self buttonRelease:1 x:0 y:0.
   414 	    ^ self.
   437 	    ^ self.
   415 	]
   438 	]