'From Squeak3.2alpha of 2 October 2001 [latest update: #4596] on 10 December 2001 at 10:26:26 pm'! "Change Set: OccamsMenuKeys-hg Date: 8 December 2001 Author: Henrik Gedenryd Improve the usability of the new menu shortcuts by disabling rather than deleting excluded menu items. Merged with overlapping changes and slightly tweaked by Dan Ingalls. Also (DI) fixes a bug in rootMenu, and places menus high enough so the pattern item will show."! !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: 'accessing' stamp: 'di 12/10/2001 22:11'! rootMenu popUpOwner ifNil: [^ self]. popUpOwner owner ifNil: [^ self]. ^ popUpOwner owner rootMenu! ! !MenuMorph methodsFor: 'keyboard control' stamp: 'hg 12/8/2001 15:03'! 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 darkGray. self addLine; addMorphBack: feedbackMorph lock. self setProperty: #feedbackMorph toValue: feedbackMorph. self fullBounds. "Lay out for submorph adjacency"]. feedbackMorph contents: '<', matchStr, '>'. matchStr isEmpty ifTrue: [ feedbackMorph delete. self submorphs last delete. self removeProperty: #feedbackMorph]. matches size = 1 ifTrue: [ self selectItem: matches first event: evt] ! ! !MenuMorph methodsFor: 'keyboard control' stamp: 'di 12/10/2001 22:14'! keyStroke: evt | matchString char asc selectable | (self rootMenu hasProperty: #hasUsedKeyboard) ifFalse: [self rootMenu setProperty: #hasUsedKeyboard toValue: true. self changed]. (evt commandKeyPressed and: [self commandKeyHandler notNil]) ifTrue: [self commandKeyHandler commandKeyTypedIntoMenu: evt. ^ self deleteIfPopUp: evt]. char _ evt keyCharacter. asc _ char asciiValue. 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 = 27 ifTrue: "escape key" [self valueOfProperty: #matchString ifPresentDo: [:str | str isEmpty ifFalse: ["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. selectedItem subMenu moveSelectionDown: 1 event: evt. ^ 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" asc = 11 ifTrue: [^ self moveSelectionDown: -5 event: evt]. "page up key" asc = 12 ifTrue: [^ self moveSelectionDown: 5 event: evt]. "page down 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: 'private' stamp: 'di 12/10/2001 22:20'! positionAt: aPoint relativeTo: aMenuItem inWorld: aWorld "Note: items may not be laid out yet (I found them all to be at 0@0), so we have to add up heights of items above the selected item." | i yOffset sub delta | self fullBounds. "force layout" i _ 0. yOffset _ 0. [(sub _ self submorphs at: (i _ i + 1)) == aMenuItem] whileFalse: [yOffset _ yOffset + sub height]. self position: aPoint - (2 @ (yOffset + 8)). "If it doesn't fit, show it to the left, not to the right of the hand." self right > aWorld worldBounds right ifTrue: [self left: self left - self width + 4]. "Make sure that the menu fits in the world." delta _ self bounds amountToTranslateWithin: (aWorld worldBounds withHeight: aWorld worldBounds height - 18). delta = (0 @ 0) ifFalse: [self position: self position + delta]! ! !PasteUpMorph methodsFor: 'world menu' stamp: 'di 12/10/2001 22:02'! putUpWorldMenuFromEscapeKey ^ self putUpWorldMenu: ActiveEvent! !