Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.1025.mcz
==================== Summary ====================
Name: Collections-eem.1025
Author: eem
Time: 23 November 2022, 6:43:09.849872 am
UUID: b326199c-16c6-4df6-9f70-fc55b0718f20
Ancestors: Collections-eem.1024
Respond to Marcel's excellent suggestion. Rename SequenceableCollection>>subStrings: to subsequences: and implement String>>subStrings: upon it.
=============== Diff against Collections-eem.1024 ===============
Item was removed:
- ----- Method: SequenceableCollection>>subStrings: (in category 'converting') -----
- subStrings: separatorsOrElement
- "Answer an array containing the substrings in the receiver separated
- by the elements of separatorsOrElement, if it is a Collection, or a
- singleton separator object, if it is not."
-
- | result size thing subsequenceStart |
- result := OrderedCollection new.
- size := self size.
- separatorsOrElement isCollection
- ifTrue:
- [1 to: size do:
- [:i|
- thing := self at: i.
- (separatorsOrElement includes: thing)
- ifTrue:
- [subsequenceStart ifNotNil:
- [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
- subsequenceStart := nil]
- ifFalse:
- [subsequenceStart ifNil: [subsequenceStart := i]]]]
- ifFalse:
- [1 to: size do:
- [:i|
- thing := self at: i.
- separatorsOrElement = thing
- ifTrue:
- [subsequenceStart ifNotNil:
- [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
- subsequenceStart := nil]
- ifFalse:
- [subsequenceStart ifNil: [subsequenceStart := i]]]].
- subsequenceStart ifNotNil:
- [result addLast: (self copyFrom: subsequenceStart to: size)].
- ^result asArray
-
- "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: Character space"
-
- "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: ' ,.-'"!
Item was added:
+ ----- Method: SequenceableCollection>>subsequences: (in category 'converting') -----
+ subsequences: separatorsOrElement
+ "Answer an array containing the subsequences in the receiver separated
+ by the elements of separatorsOrElement, if it is a Collection, or a
+ single separator object, if it is not."
+
+ | result size thing subsequenceStart |
+ result := OrderedCollection new.
+ size := self size.
+ separatorsOrElement isCollection
+ ifTrue:
+ [1 to: size do:
+ [:i|
+ thing := self at: i.
+ (separatorsOrElement includes: thing)
+ ifTrue:
+ [subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
+ subsequenceStart := nil]
+ ifFalse:
+ [subsequenceStart ifNil: [subsequenceStart := i]]]]
+ ifFalse:
+ [1 to: size do:
+ [:i|
+ thing := self at: i.
+ separatorsOrElement = thing
+ ifTrue:
+ [subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
+ subsequenceStart := nil]
+ ifFalse:
+ [subsequenceStart ifNil: [subsequenceStart := i]]]].
+ subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: size)].
+ ^result asArray
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: Character space"
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: ' ,.-'"!
Item was changed:
----- Method: String>>subStrings: (in category 'converting') -----
subStrings: separators
"Answer an array containing the substrings in the receiver separated
by the elements of separators, which should be a collection of Characters,
or, for convenience, a single character.."
(separators isCharacter or: [separators isString or:[separators allSatisfy: [:element | element isCharacter]]]) ifTrue:
+ [^self subsequences: separators].
- [^super subStrings: separators].
^self error: 'separators must be Characters.'
"'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: Character space"
"'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: ' ,.-'"!
Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.1024.mcz
==================== Summary ====================
Name: Collections-eem.1024
Author: eem
Time: 22 November 2022, 7:37:55.158009 pm
UUID: 4c57a48d-50a0-4209-a01b-643c0da598f6
Ancestors: Collections-eem.1023
Replace the two implementations of [Byte]String>>substrings with one using the same scheme as SequenceableCollection>>subStrings:; it's at least 23% faster.
=============== Diff against Collections-eem.1023 ===============
Item was removed:
- ----- Method: ByteString>>substrings (in category 'converting') -----
- substrings
- "Answer an array of the substrings that compose the receiver."
-
- ^Array streamContents: [ :stream |
- | end start |
- end := 1.
- "find one substring each time through this loop"
- [ "find the beginning of the next substring"
- (start := self
- indexOfAnyOf: CharacterSet nonSeparators
- startingAt: end) = 0 ]
- whileFalse: [
- "find the end"
- end := self
- indexOfAnyOf: CharacterSet separators
- startingAt: start
- ifAbsent: [ self size + 1 ].
- stream nextPut: (self copyFrom: start to: end - 1) ] ]!
Item was changed:
----- Method: String>>substrings (in category 'converting') -----
substrings
"Answer an array of the substrings that compose the receiver."
+ | result size subsequenceStart |
+ result := OrderedCollection new.
+ size := self size.
+ 1 to: size do:
+ [:i|
+ (self at: i) isSeparator
+ ifTrue:
+ [subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
+ subsequenceStart := nil]
+ ifFalse:
+ [subsequenceStart ifNil: [subsequenceStart := i]]].
+ subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: size)].
+ ^result asArray
+ !
- | result end beginning |
- result := WriteStream on: (Array new: 10).
- end := 0.
- "find one substring each time through this loop"
- [ "find the beginning of the next substring"
- beginning := end+1.
- [beginning <= self size and:[(self at: beginning) isSeparator]]
- whileTrue:[beginning := beginning + 1].
- beginning <= self size] whileTrue: [
- "find the end"
- end := beginning.
- [end <= self size and:[(self at: end) isSeparator not]]
- whileTrue:[end := end + 1].
- end := end - 1.
- result nextPut: (self copyFrom: beginning to: end).
- ].
- ^result contents!
Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.1023.mcz
==================== Summary ====================
Name: Collections-eem.1023
Author: eem
Time: 22 November 2022, 7:12:52.434373 pm
UUID: 9c7f84f0-35b9-476f-9d51-75cc12248c26
Ancestors: Collections-eem.1022
Reimplement subStrings: in SequenceableCollection (this is where it belongs; subStrings: on arbitrary sequeances is useful). Allow the argument to be a singleton, if not a collection. Reimplement to use an index and copyFrom:to: instead of consing up a string on each element.
=============== Diff against Collections-eem.1022 ===============
Item was added:
+ ----- Method: SequenceableCollection>>subStrings: (in category 'converting') -----
+ subStrings: separatorsOrElement
+ "Answer an array containing the substrings in the receiver separated
+ by the elements of separatorsOrElement, if it is a Collection, or a
+ singleton separator object, if it is not."
+
+ | result size thing subsequenceStart |
+ result := OrderedCollection new.
+ size := self size.
+ separatorsOrElement isCollection
+ ifTrue:
+ [1 to: size do:
+ [:i|
+ thing := self at: i.
+ (separatorsOrElement includes: thing)
+ ifTrue:
+ [subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
+ subsequenceStart := nil]
+ ifFalse:
+ [subsequenceStart ifNil: [subsequenceStart := i]]]]
+ ifFalse:
+ [1 to: size do:
+ [:i|
+ thing := self at: i.
+ separatorsOrElement = thing
+ ifTrue:
+ [subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: i - 1)].
+ subsequenceStart := nil]
+ ifFalse:
+ [subsequenceStart ifNil: [subsequenceStart := i]]]].
+ subsequenceStart ifNotNil:
+ [result addLast: (self copyFrom: subsequenceStart to: size)].
+ ^result asArray
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: Character space"
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: ' ,.-'"!
Item was changed:
----- Method: String>>subStrings: (in category 'converting') -----
subStrings: separators
"Answer an array containing the substrings in the receiver separated
+ by the elements of separators, which should be a collection of Characters,
+ or, for convenience, a single character.."
+ (separators isCharacter or: [separators isString or:[separators allSatisfy: [:element | element isCharacter]]]) ifTrue:
+ [^super subStrings: separators].
+ ^self error: 'separators must be Characters.'
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: Character space"
+
+ "'Now is the time for all good people to come to the aid of the cause of world peace. It is just fine, even desirable, to love your country, if that means wanting it to play a beneficial role in the course of world events and be the best possible example of a good society. But if it means wanting dominion over the rest of the world, it is not love but defensiveness or self-glorification, and will lead only to oblivion.' subStrings: ' ,.-'"!
- by the elements of separators."
- | char result sourceStream subString |
- #Collectn.
- "Changed 2000/04/08 For ANSI <readableString> protocol."
- (separators isString or:[separators allSatisfy: [:element | element isCharacter]]) ifFalse:
- [^ self error: 'separators must be Characters.'].
- sourceStream := ReadStream on: self.
- result := OrderedCollection new.
- subString := String new.
- [sourceStream atEnd]
- whileFalse:
- [char := sourceStream next.
- (separators includes: char)
- ifTrue: [subString notEmpty
- ifTrue:
- [result add: subString copy.
- subString := String new]]
- ifFalse: [subString := subString , (String with: char)]].
- subString notEmpty ifTrue: [result add: subString copy].
- ^ result asArray!
Eliot Miranda uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-eem.494.mcz
==================== Summary ====================
Name: Tests-eem.494
Author: eem
Time: 22 November 2022, 4:48:01.49217 am
UUID: 6a6ee2f8-2a13-4372-b7cc-d43e0bbb8ffe
Ancestors: Tests-mt.493
Test that various RawBitsArrays are serializable on DataStream et al.
=============== Diff against Tests-mt.493 ===============
Item was added:
+ ----- Method: DataStreamTest>>testRawBits (in category 'tests') -----
+ testRawBits
+ ((RawBitsArray subclasses reject: #isAbstract), ((RawBitsArray subclasses select: #isAbstract) collect: #subclasses)) flatten do:
+ [:class| | instance |
+ instance := class new: 10.
+ instance first isColor
+ ifTrue:
+ [1 to: instance size do: [:i| instance at: i put: (Color r: i * 1 g: i * 2 b: i * 3)]]
+ ifFalse:
+ [1 to: instance size do: [:i| instance at: i put: i]].
+ self assert: instance equals: (self testObject: instance) description: 'A ', class name, ' should be serializable']!
Eliot Miranda uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-eem.1022.mcz
==================== Summary ====================
Name: Collections-eem.1022
Author: eem
Time: 21 November 2022, 9:26:32.233055 pm
UUID: 11b99e4c-0597-4f7d-b3bf-667ea9ad2edf
Ancestors: Collections-nice.1021
Fix PositionableStream>>#isBinary, which was implemented in terms of ByteArray, implemented using the new Collection>>isUnsignedIntegerArray. Add Collection>>isSignedIntegerArray for symmetry.
=============== Diff against Collections-nice.1021 ===============
Item was added:
+ ----- Method: Collection>>isSignedIntegerArray (in category 'testing') -----
+ isSignedIntegerArray
+ ^false!
Item was added:
+ ----- Method: Collection>>isUnsignedIntegerArray (in category 'testing') -----
+ isUnsignedIntegerArray
+ ^false!
Item was changed:
----- Method: PositionableStream>>isBinary (in category 'testing') -----
isBinary
+ "Answer if the receiver is a binary stream"
+ ^collection isCollection and: [collection isUnsignedIntegerArray]!
- "Return true if the receiver is a binary byte stream"
- ^collection class == ByteArray!
Item was added:
+ ----- Method: SignedIntegerArray>>isSignedIntegerArray (in category 'testing') -----
+ isSignedIntegerArray
+ ^true!
Item was added:
+ ----- Method: UnsignedIntegerArray>>isUnsignedIntegerArray (in category 'testing') -----
+ isUnsignedIntegerArray
+ ^true!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.2053.mcz
==================== Summary ====================
Name: Morphic-mt.2053
Author: mt
Time: 21 November 2022, 11:26:08.284072 am
UUID: e5103676-4f14-f245-8dee-e81e3f692664
Ancestors: Morphic-ct.2052
More commentary for mouse and keyboard events.
=============== Diff against Morphic-ct.2052 ===============
Item was changed:
----- Method: Morph>>handleKeyDown: (in category 'events-processing') -----
handleKeyDown: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesKeyboard: and #keyDown: in your custom morphs."
+
- "System level event handling."
anEvent wasHandled ifTrue: [^ self].
(self handlesKeyboard: anEvent) ifFalse: [^ self].
(anEvent hand keyboardFocus ~~ self
and: [self handlesKeyboardOnlyOnFocus])
ifTrue: [^ self].
anEvent wasHandled: true.
^ self keyDown: anEvent!
Item was changed:
----- Method: Morph>>handleKeyUp: (in category 'events-processing') -----
handleKeyUp: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesKeyboard: and #keyUp: in your custom morphs."
+
- "System level event handling."
anEvent wasHandled ifTrue: [^ self].
(self handlesKeyboard: anEvent) ifFalse: [^ self].
(anEvent hand keyboardFocus ~~ self
and: [self handlesKeyboardOnlyOnFocus])
ifTrue: [^ self].
anEvent wasHandled: true.
^ self keyUp: anEvent!
Item was changed:
----- Method: Morph>>handleKeystroke: (in category 'events-processing') -----
handleKeystroke: anEvent
+ "System level event handling. Supports automatically grabbing the keyboard focus via keyboard focus delegate; see #newKeyboardFocus:.
- "System level event handling. Has support for automatically grabbing the keyboard focus considering the keyboard focus delegate. See #newKeyboardFocus:"
+ AVOID OVERRIDE if possible. Instead, please use #handlesKeyboard: and #keyStroke: in your custom morphs."
+
| handler |
anEvent wasHandled ifTrue: [^ self].
(self handlesKeyboard: anEvent) ifFalse: [^ self].
(anEvent hand keyboardFocus ~~ self
and: [self handlesKeyboardOnlyOnFocus])
ifTrue: [^ self].
handler := self wantsKeyboardFocus
ifFalse: [self]
ifTrue: [(anEvent hand newKeyboardFocus: self) ifNil: [self]].
anEvent handler: handler.
anEvent wasHandled: true.
^ handler keyStroke: anEvent!
Item was changed:
----- Method: Morph>>handleMouseDown: (in category 'events-processing') -----
handleMouseDown: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesMouseDown: and #mouseDown: in your custom morphs. See #handlerForMouseDown: and #mouseDownPriority."
+
- "System level event handling."
anEvent wasHandled ifTrue:[^self]. "not interested"
anEvent hand removePendingBalloonFor: self.
anEvent hand removePendingHaloFor: self.
anEvent wasHandled: true.
"Make me modal during mouse transitions"
anEvent hand newMouseFocus: self event: anEvent.
"this mouse down could be the start of a gesture, or the end of a gesture focus"
(self isGestureStart: anEvent)
ifTrue: [^ self gestureStart: anEvent].
self mouseDown: anEvent.
(self handlesMouseStillDown: anEvent) ifTrue:[
self startStepping: #handleMouseStillDown:
at: Time millisecondClockValue + self mouseStillDownThreshold
arguments: {anEvent copy resetHandlerFields}
stepTime: self mouseStillDownStepRate ].
!
Item was changed:
----- Method: Morph>>handleMouseEnter: (in category 'events-processing') -----
handleMouseEnter: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesMouseOver: and #mouseEnter: in your custom morphs. Also see/use #handlesMouseOverDragging: and #mouseEnterDragging:."
+
- "System level event handling."
(anEvent isDraggingEvent) ifTrue:[
(self handlesMouseOverDragging: anEvent) ifTrue:[
anEvent wasHandled: true.
self mouseEnterDragging: anEvent].
^self].
self wantsHalo "If receiver wants halo and balloon, trigger balloon after halo"
ifTrue:[anEvent hand triggerHaloFor: self after: self haloDelayTime]
ifFalse:[self wantsBalloon
ifTrue:[anEvent hand triggerBalloonFor: self after: self balloonHelpDelayTime]].
(self handlesMouseOver: anEvent) ifTrue:[
anEvent wasHandled: true.
self mouseEnter: anEvent.
].!
Item was changed:
----- Method: Morph>>handleMouseLeave: (in category 'events-processing') -----
handleMouseLeave: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesMouseOver: and #mouseLeave: in your custom morphs. Also see/use #handlesMouseOverDragging: and #mouseLeaveDragging:."
+
- "System level event handling."
anEvent hand removePendingBalloonFor: self.
anEvent hand removePendingHaloFor: self.
anEvent isDraggingEvent ifTrue:[
(self handlesMouseOverDragging: anEvent) ifTrue:[
anEvent wasHandled: true.
self mouseLeaveDragging: anEvent].
^self].
(self handlesMouseOver: anEvent) ifTrue:[
anEvent wasHandled: true.
self mouseLeave: anEvent.
].
!
Item was changed:
----- Method: Morph>>handleMouseMove: (in category 'events-processing') -----
handleMouseMove: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesMouseMove: and #mouseMove: in your custom morphs. Also see/use #wantsEveryMouseMove."
+
- "System level event handling."
anEvent wasHandled ifTrue: [ ^ self ].
"not interested"
(self handlesMouseMove: anEvent) ifFalse: [ ^ self ].
anEvent wasHandled: true.
self mouseMove: anEvent.
(self handlesMouseStillDown: anEvent) ifTrue:
[ "Step at the new location"
self
startStepping: #handleMouseStillDown:
at: Time millisecondClockValue
arguments: {anEvent copy resetHandlerFields}
stepTime: self mouseStillDownStepRate ]!
Item was changed:
----- Method: Morph>>handleMouseOver: (in category 'events-processing') -----
handleMouseOver: anEvent
+ "System level event handling. DO NOT OVERRIDE. See #handleMouseMove:, #handleMouseEnter:, #handleMouseLeave:."
+
- "System level event handling."
anEvent hand mouseFocus == self ifTrue:[
"Got this directly through #handleFocusEvent: so check explicitly"
(self containsPoint: anEvent position event: anEvent) ifFalse:[^self]].
anEvent hand noticeMouseOver: self event: anEvent!
Item was changed:
----- Method: Morph>>handleMouseUp: (in category 'events-processing') -----
handleMouseUp: anEvent
+ "System level event handling. Complements #handleMouseDown: (and #mouseDown:). AVOID OVERRIDE if possible. Instead, please use #handlesMouseDown: and #mouseUp: in your custom morphs. See #handlerForMouseDown: and #mouseDownPriority."
+
- "System level event handling."
anEvent wasHandled ifTrue:[^self]. "not interested"
anEvent hand mouseFocus == self ifFalse:[^self]. "Not interested in other parties"
anEvent hand releaseMouseFocus: self.
anEvent wasHandled: true.
self mouseUp: anEvent.
self stopSteppingSelector: #handleMouseStillDown:.!
Item was changed:
----- Method: Morph>>handleMouseWheel: (in category 'events-processing') -----
handleMouseWheel: anEvent
+ "System level event handling. AVOID OVERRIDE if possible. Instead, please use #handlesMouseWheel: and #mouseWheel: in your custom morphs."
- "System level event handling."
anEvent wasHandled ifTrue: [^self].
(self handlesMouseWheel: anEvent) ifFalse: [^ self].
anEvent wasHandled: true.
^ self mouseWheel: anEvent!
Item was changed:
----- Method: Morph>>keyDown: (in category 'event handling') -----
keyDown: anEvent
+ "Handle a key down event. The default response is to let my eventHandler, if any, handle it. Ask anEvent for #key to work with a cross-platform representation of virtual-key presses. DO NOT access #keyValue or #keyCharacter as those are for #keyStroke: only.
+
+ For #virtualModifiers, ask for #shiftPressed, #controlKeyPressed, #optionKeyPressed, or #commandKeyPressed. Note that if you want to SHOW platform-specific information about modifiers (e.g., ALT on Windows), see #physicalModifiers. For control-flow expressions (e.g., #ifTrue:), only use #virtualModifiers to remain cross-platform compatible."
- "Handle a key down event. The default response is to let my eventHandler, if any, handle it."
self eventHandler ifNotNil:
[self eventHandler keyDown: anEvent fromMorph: self].
!
Item was changed:
----- Method: Morph>>keyStroke: (in category 'event handling') -----
keyStroke: anEvent
+ "Handle a keystroke event. The default response is to let my eventHandler, if any, handle it. Ask anEvent for #keyCharacter to work with the (Unicode) character the user entered. See class comment in Character.
+
+ Please implement keyboard shortcuts via #keyDown: instead. Here, as in #keyDown: and #keyUp, you may ask anEvent for #key but should do that in #keyDown: or #keyUp: if possible.
+
+ Please AVOID checking #modifiers (or #virtualModifiers) in combination with #keyCharacter as, for example, #shiftPressed has an effect on #keyCharacter as well. This is not the case for #key (or #virtualKey)."
- "Handle a keystroke event. The default response is to let my eventHandler, if any, handle it."
self eventHandler ifNotNil:
[self eventHandler keyStroke: anEvent fromMorph: self].
!
Item was changed:
----- Method: Morph>>keyUp: (in category 'event handling') -----
keyUp: anEvent
+ "Handle a key up event. The default response is to let my eventHandler, if any, handle it. Ask anEvent for #key to work with a cross-platform representation of virtual-key releases. DO NOT access #keyValue or #keyCharacter as those are for #keyStroke: only.
+
+ For #virtualModifiers, ask for #shiftPressed, #controlKeyPressed, #optionKeyPressed, or #commandKeyPressed. Note that if you want to SHOW platform-specific information about modifiers (e.g., ALT on Windows), see #physicalModifiers. For control-flow expressions (e.g., #ifTrue:), only use #virtualModifiers to remain cross-platform compatible."
- "Handle a key up event. The default response is to let my eventHandler, if any, handle it."
self eventHandler ifNotNil:
[self eventHandler keyUp: anEvent fromMorph: self].
!
Christoph Thiede uploaded a new version of EToys to project The Trunk:
http://source.squeak.org/trunk/EToys-ct.486.mcz
==================== Summary ====================
Name: EToys-ct.486
Author: ct
Time: 19 November 2022, 7:04:16.24343 pm
UUID: 7824dd20-441e-3342-a4bf-18f7463f6c65
Ancestors: EToys-ct.485
Makes WatchMorph scale-factor-aware.
=============== Diff against EToys-ct.485 ===============
Item was changed:
----- Method: WatchMorph>>initialize (in category 'initialization') -----
initialize
"initialize the state of the receiver"
super initialize.
""
self handsColor: Color red.
self centerColor: Color gray.
romanNumerals := false.
antialias := false.
fontName := 'NewYork'.
+ self extent: 130 px @ 130 px.
- self extent: 130 @ 130.
self start!