[ENH] Occam's menu keys

Henrik Gedenryd h.gedenryd at open.ac.uk
Mon Dec 10 08:56:55 UTC 2001


The UI for new menu key functionality takes the user for a wild visual ride.
This change set tries to reduce the induced nausea to a minimum, by simply
deactivating non-matching menu items instead of removing them. It is
definitely meant as an update candidate.

Henrik

-------------- next part --------------
'From Squeak3.2alpha of 1 November 2001 [latest update: #4586] on 8 December 2001 at 2:37:51 pm'!
"Change Set:		OccamsMenuKeys-hg
Date:			8 December 2001
Author:			Henrik Gedenryd

Improve the usability of the new menu shortcuts by cutting down on the noise of the new interface."!


!MenuItemMorph methodsFor: 'accessing' stamp: 'hg 12/8/2001 13:22'!
isEnabled: aBoolean

	isEnabled = aBoolean ifTrue: [^ self].
	isEnabled _ aBoolean.
	self color: (aBoolean ifTrue: [Color black] ifFalse: [Color lightGray]).
! !


!MenuMorph methodsFor: 'keyboard control' stamp: 'hg 12/8/2001 13:36'!
keyStroke: evt
	| matchString char asc selectable |
	self deleteBalloon.
	(evt commandKeyPressed and: [self commandKeyHandler notNil]) ifTrue:
			[self commandKeyHandler commandKeyTypedIntoMenu: evt.
			^ self deleteIfPopUp: evt].
	char _ evt keyCharacter.
	char = Character cr ifTrue:
		[selectedItem ifNotNil:
			[selectedItem hasSubMenu
			ifTrue: [evt hand newMouseFocus: selectedItem subMenu.
					^ evt hand newKeyboardFocus: selectedItem subMenu]
			ifFalse: ["self delete."
					^ selectedItem invokeWithEvent: evt]].
		(selectable _ self items) size = 1
			ifTrue: [^ selectable first invokeWithEvent: evt].
		^ self].
	((asc _ char asciiValue) between: 27 and: 31) ifTrue:
		[asc = 27 ifTrue:   "escape key"
			[(self hasProperty: #matchString) ifTrue: [
				"If filtered, first ESC removes filter"
				self setProperty: #matchString toValue: String new.
				self selectItem: nil event: evt.
				^self displayFiltered: evt].
			"If a stand-alone menu, just delete it"
			popUpOwner ifNil: [^ self delete].
			"If a sub-menu, then deselect, and return focus to outer menu"
			self selectItem: nil event: evt.
			evt hand newMouseFocus: popUpOwner owner.
			^ evt hand newKeyboardFocus: popUpOwner owner].
		(asc = 28 or: [asc = 29]) ifTrue:		"left or right arrow key"
			[(selectedItem ~~ nil and: [selectedItem hasSubMenu]) ifTrue:
					[evt hand newMouseFocus: selectedItem subMenu.
					^ evt hand newKeyboardFocus: selectedItem subMenu]].
		asc = 30 ifTrue: [^ self moveSelectionDown: -1 event: evt].		"up arrow key"
		asc = 31 ifTrue: [^ self moveSelectionDown: 1 event: evt].		"down arrow key"
		].
	matchString _ self valueOfProperty: #matchString ifAbsentPut: [String new].
	matchString _ char = Character backspace
		ifTrue: [matchString isEmpty
				ifTrue: [matchString]
				ifFalse: [matchString allButLast]]
		ifFalse: [matchString copyWith: evt keyCharacter].
	self setProperty: #matchString toValue: matchString.
	self displayFiltered: evt! !

!MenuMorph methodsFor: 'drawing' stamp: 'hg 12/8/2001 12:49'!
drawOn: aCanvas

	super drawOn: aCanvas.
	ActiveHand keyboardFocus == self ifTrue:
		[aCanvas frameAndFillRectangle: self innerBounds fillColor: Color transparent borderWidth: 1 borderColor: self color darker darker]
! !

!MenuMorph methodsFor: 'as yet unclassified' stamp: 'hg 12/8/2001 14:31'!
displayFiltered: evt
	| matchStr allItems isMatch matches feedbackMorph |
	matchStr _ self valueOfProperty: #matchString.
	allItems _ self submorphs select: [:m | m isKindOf: MenuItemMorph].
	matches _  allItems select: [:m | 
		isMatch _ 
			matchStr isEmpty or: [
				m contents includesSubstring: matchStr caseSensitive: false].
		m isEnabled: isMatch.
		isMatch].
	feedbackMorph _ self valueOfProperty: #feedbackMorph.
	feedbackMorph ifNil: [
		feedbackMorph _ 
			TextMorph new 
				autoFit: true;
				color: Color gray.
		self addMorphBack: feedbackMorph lock.
		self setProperty: #feedbackMorph toValue: feedbackMorph.
		self fullBounds.  "Lay out for submorph adjacency"].
	feedbackMorph contents: '<', matchStr, '>'.
	matchStr isEmpty ifTrue: [
		feedbackMorph delete.
		self removeProperty: #feedbackMorph].
	matches size = 1 ifTrue: [
		self selectItem: matches first event: evt]
! !



More information about the Squeak-dev mailing list