[ENH] Scrolling w/ keyboard and wheel mouse

Bert Freudenberg bert at isgnw.CS.Uni-Magdeburg.De
Wed Apr 14 12:30:49 UTC 1999


> Has anyone been able to use a scroll-wheel mouse with Squeak?

Yes. Requires a VM change, though. Attached is a Squeak changeset and a
VM patch for Linux. The wheel up/down events are translated to
command+up/down keyboard events. Shouldn't be hard to adapt for other
VMs :-)

"Change Set:		scrolling-bf
Date:			14 April 1999
Author:			Bert Freudenberg

Makes command+up/down scrolling. For use with a scrollwheel mouse, but can
be used with the keyboard as well. See ScrollController>>#scrollByKeyboard
(MVC) and ScrollPane>>#scrollByKeyboard: (Morphic)"

[Question] How about a general event mechanism from the VM to the image? 

/bert

-- 
 Bert Freudenberg                                       Department of 
                                                        Simulation and
 mailto:bert at isg.cs.uni-magdeburg.de                    Computer Graphics
 http://isgwww.cs.uni-magdeburg.de/isg/bert.html        Univ. of Magdeburg


Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME="scrolling-bf.cs"
Content-ID: <Pine.LNX.3.96.990414141721.9595E at balloon.cs.uni-magdeburg.de>
Content-Description: 

'From Squeak 2.3 of January 14, 1999 on 14 April 1999 at 1:01:22 pm'!
"Change Set:		scrolling-bf
Date:			14 April 1999
Author:			Bert Freudenberg

Makes command+up/down scrolling. For use with a scrollwheel mouse, but can be used with the keyboard as well. See ScrollController>>#scrollByKeyboard (MVC) and ScrollPane>>#scrollByKeyboard: (Morphic)"!


!ScrollBar methodsFor: 'scrolling' stamp: 'bf 4/14/1999 12:03'!
scrollDown: count
	self setValue: (value + (scrollDelta * count) + 0.000001 min: 1.0)! !

!ScrollBar methodsFor: 'scrolling' stamp: 'bf 4/14/1999 12:03'!
scrollUp: count
	self setValue: (value - (scrollDelta * count) - 0.000001 max: 0.0)! !


!ScrollController methodsFor: 'control defaults' stamp: 'bf 4/14/1999 12:27'!
controlActivity
	self scrollByKeyboard ifTrue: [^self].
	self scrollBarContainsCursor
				ifTrue: [self scroll]
				ifFalse: [super controlActivity]! !

!ScrollController methodsFor: 'scrolling' stamp: 'bf 4/14/1999 12:56'!
scrollByKeyboard
	| keyEvent |
	keyEvent _ sensor keyboardPeek.
	keyEvent ifNil: [^false].
	sensor commandKeyPressed ifFalse: [^false].
	keyEvent asciiValue = 30 ifTrue:
		[sensor keyboard.
		self scrollViewDown ifTrue: [self moveMarker].
		^true].
	keyEvent asciiValue = 31 ifTrue:
		[sensor keyboard.
		self scrollViewUp ifTrue: [self moveMarker].
		^true].
	^ false! !


!ListController methodsFor: 'control defaults' stamp: 'bf 4/14/1999 12:41'!
controlActivity
	self scrollByKeyboard ifTrue: [^self].
	self processKeyboard.
	super controlActivity.
! !


!ParagraphEditor methodsFor: 'controlling' stamp: 'bf 4/14/1999 12:41'!
controlActivity
	self scrollByKeyboard ifTrue: [^self].
	self scrollBarContainsCursor
		ifTrue: [self scroll]
		ifFalse: [self processKeyboard.
				self processMouseButtons]! !


!PluggableListController methodsFor: 'all' stamp: 'bf 4/14/1999 12:41'!
controlActivity
	"Overridden to handle keystrokes."
	self scrollByKeyboard ifTrue: [^self].
	sensor keyboardPressed ifTrue: [view handleKeystroke: sensor keyboard].
	super controlActivity.! !


!ScrollPane methodsFor: 'pane events' stamp: 'bf 4/14/1999 12:39'!
keyStroke: evt
	"If pane is not full, pass the event to the last submorph,
	assuming it is the most appropriate recipient (!!)"

	(self scrollByKeyboard: evt) ifTrue: [^self].
	scroller submorphs last keyStroke: evt! !

!ScrollPane methodsFor: 'pane events' stamp: 'bf 4/14/1999 12:38'!
scrollByKeyboard: event
	"If event is option+up/down then scroll and answer true"

	event commandKeyPressed ifFalse: [^false].
	event keyValue = 30 ifTrue: [scrollBar scrollUp: 3. ^true].
	event keyValue = 31 ifTrue: [scrollBar scrollDown: 3. ^true].
	^false! !


!PluggableListMorph methodsFor: 'model access' stamp: 'bf 4/14/1999 12:39'!
keyStroke: event
	"Process potential command keys"
	| args aCharacter |
	(self scrollByKeyboard: event) ifTrue: [^ nil].
	keystrokeActionSelector == nil ifTrue: [^ nil].
	aCharacter _ event keyCharacter.
	(args _ keystrokeActionSelector numArgs) = 1
		ifTrue: [^ model perform: keystrokeActionSelector with: aCharacter].
	args = 2
		ifTrue: [^ model perform: keystrokeActionSelector with: aCharacter with: self].

	^ self error: 'The keystrokeActionSelector must be a 1- or 2-keyword symbol'! !


!TextMorphForEditView methodsFor: 'all' stamp: 'bf 4/14/1999 12:39'!
keyStroke: evt
	| view |
	(editView scrollByKeyboard: evt) ifTrue: [^self].
	self editor model: editView model.  "For evaluateSelection"
	view _ editView.  "Copy into temp for case of a self-mutating doit"
	(acceptOnCR and: [evt keyCharacter = Character cr])
		ifTrue: [^ self editor accept].
	super keyStroke: evt.
	view scrollSelectionIntoView! !


ScrollPane removeSelector: #handleScrollEvent:!
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; NAME="scrollwheel.diff"
Content-ID: <Pine.LNX.3.96.990414141721.9595F at balloon.cs.uni-magdeburg.de>
Content-Description: 

*** ftp/sqXWindow.c	Wed Apr 14 10:05:57 1999
--- src/sqXWindow.c	Wed Apr 14 13:22:56 1999
***************
*** 986,991 ****
--- 1011,1030 ----
  }
  
  
+ void keyBufAppend(int keystate)
+ {
+   /* bug: this should be rewritten to cope with nConv > 1 */
+   keyBuf[keyBufPut]= keystate;
+   keyBufPut= (keyBufPut + 1) % KEYBUF_SIZE;
+   if (keyBufGet == keyBufPut)
+     {
+       /* buffer overflow; drop the last character */
+       keyBufGet= (keyBufGet + 1) % KEYBUF_SIZE;
+       keyBufOverflows++;
+     }
+ }
+ 
+ 
  void recordKeystroke(XKeyEvent *theEvent)
  {
    int keystate;
***************
*** 1014,1028 ****
      }
    else
      {
!       /* bug: this should be rewritten to cope with nConv > 1 */
!       keyBuf[keyBufPut]= keystate;
!       keyBufPut= (keyBufPut + 1) % KEYBUF_SIZE;
!       if (keyBufGet == keyBufPut)
! 	{
! 	  /* buffer overflow; drop the last character */
! 	  keyBufGet= (keyBufGet + 1) % KEYBUF_SIZE;
! 	  keyBufOverflows++;
! 	}
      }
  }
  
--- 1052,1058 ----
      }
    else
      {
!       keyBufAppend(keystate);
      }
  }
  
***************
*** 1035,1040 ****
--- 1065,1075 ----
      case 1: stButtons= 4; break;
      case 2: stButtons= 2; break;
      case 3: stButtons= 1; break;
+     case 4:
+     case 5: keyBufAppend( (theEvent->button + 26)        /* Up/Down */
+ 		       | (8 << 8)                        /* Command  */
+ 		       | (modifierMap[(theEvent->state) & 0xF] << 8));
+             return;
      default: ioBeep(); break;
      }





More information about the Squeak-dev mailing list