Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.698.mcz
==================== Summary ====================
Name: Collections-ul.698
Author: ul
Time: 2 June 2016, 11:47:32.688405 pm
UUID: cf02bd5c-5cfa-499c-88df-c00ae1760a38
Ancestors: Collections-ul.697
Heap revamp #3:
- Heap is a subclass of Collection instead of SequenceableCollection.
- Heap has it's own category Collections-Heap; just like how it is with Stack.
- Updated class comment.
=============== Diff against Collections-ul.697 ===============
Item was changed:
SystemOrganization addCategory: #'Collections-Abstract'!
SystemOrganization addCategory: #'Collections-Arrayed'!
SystemOrganization addCategory: #'Collections-Cache'!
SystemOrganization addCategory: #'Collections-Exceptions'!
SystemOrganization addCategory: #'Collections-Sequenceable'!
SystemOrganization addCategory: #'Collections-Stack'!
SystemOrganization addCategory: #'Collections-Streams'!
SystemOrganization addCategory: #'Collections-Strings'!
SystemOrganization addCategory: #'Collections-Support'!
SystemOrganization addCategory: #'Collections-Text'!
SystemOrganization addCategory: #'Collections-Unordered'!
SystemOrganization addCategory: #'Collections-Weak'!
+ SystemOrganization addCategory: #'Collections-Heap'!
Item was changed:
+ Collection subclass: #Heap
- SequenceableCollection subclass: #Heap
instanceVariableNames: 'array tally sortBlock indexUpdateBlock'
classVariableNames: ''
poolDictionaries: ''
+ category: 'Collections-Heap'!
- category: 'Collections-Sequenceable'!
+ !Heap commentStamp: 'ul 6/2/2016 23:45' prior: 0!
+ I implement a special data structure called Binary Heap [ https://en.wikipedia.org/wiki/Binary_heap ], which is the most commonly used variant of the Heap data structure [ https://en.wikipedia.org/wiki/Heap_%28data_structure%29 ].
- !Heap commentStamp: 'nice 9/30/2010 23:22' prior: 0!
- Class Heap implements a special data structure commonly referred to as 'heap' [ http://en.wikipedia.org/wiki/Heap_%28data_structure%29 ]
A Heap is a kind of binary tree stored in a linear array - see details after the instance variables description.
Heaps are good at handling priority queues because:
1) greatest priority element according to the sort block will be stored in first position and thus accessed in O(1) operations
2) worse time for inserting or removing an element is in O(log n) operations, where n is the size of the Heap
Insertion/Removal times are more efficient than above upper bound, provided that:
a) Elements are only removed at the beginning
b) Elements are added with arbitrary sort order.
3) there is no need to fully sort the Heap, which makes it more efficient than a SortedCollection
+ The heap can be fully sorted by sending the message #sort.
- The heap can be fully sorted by sending the message #fullySort.
Worse time for fully sorting the Heap is in O(n log n) operations, but this is rarely used a feature.
Remind that the Heap does not fully sort the collection if you don't ask.
Thus don't expect #do: and other iterators to enumerate elements according to the sortBlock order.
Instance variables:
+ array <Array> The data repository
- array <Array> The data repository
tally <Integer> The number of elements in the heap
sortBlock <Block|nil> A two-argument block defining the sort order,
or nil in which case the default sort order is
[:element1 :element2| element1 <= element2]
indexUpdateBlock <Block|nil>
A two-argument block of the form [:data :index | ... ]
which allows an application object to keep track of its
index within the heap. Useful for quick heap update
when object's sort value changes (for example, when an
object in a priority queue has its priority increased
by an external event, you don't want to have to search
through the whole heap to find the index before fixing
the heap). No update occurs if nil.
The Heap can be viewed as a binary tree (every node in the tree has at most two children).
The root is stored in first slot of internal array.
The children are stored in next two slots.
The children of children in next four slots.
etc...
For a node A of index i (1 based), the two children B1 and B2 are thus stored in indices (2*i) and (2*i+1).
Of course, the children indices must be less than the tally otherwise they are considered inexistent.
The Heap does arrange to preserve the following invariant:
+ For any children B of a node A, A is sorted before B, in other words, (sortBlock value: A value: B) = true
- For any children B of a node A, A is sorted before B, in other words, (self sort: A before: B) = true
This implies that the root is always the first element according to sort order.
!
tim Rowledge uploaded a new version of Multilingual to project The Trunk:
http://source.squeak.org/trunk/Multilingual-tpr.214.mcz
==================== Summary ====================
Name: Multilingual-tpr.214
Author: tpr
Time: 6 June 2016, 5:59:22.145354 pm
UUID: 221bdccd-de05-41df-a529-c2ad22dd7762
Ancestors: Multilingual-topa.213
make the preferred position for compositing input window take into account any effect of height offset. Why work out the position and then modify it with ugly code when you can do it right first time? See also Morphic-tpr.1168
=============== Diff against Multilingual-topa.213 ===============
Item was changed:
----- Method: ImmX11>>keyboardFocusForAMorph: (in category 'keyboard') -----
keyboardFocusForAMorph: aMorph
aMorph ifNil: [^ self].
[
| left bottom pos |
pos := aMorph preferredKeyboardPosition.
left := (pos x min: Display width max: 0) asInteger.
+ bottom := (pos y min: Display height max: 0) asInteger.
- bottom := (pos y min: Display height max: 0) asInteger
- + (aMorph paragraph
- characterBlockForIndex: aMorph editor selectionInterval first) height.
self setCompositionWindowPositionX: left y: bottom
] on: Error
do: [:ex |].
!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1166.mcz
==================== Summary ====================
Name: Morphic-mt.1166
Author: mt
Time: 5 June 2016, 9:31:27.57571 am
UUID: b8c7c456-a88e-3143-8c24-09fae212f9b9
Ancestors: Morphic-mt.1165
Fixes the bug where the text cursor was not blinking in text morphs after a dialog box appeared and was closed again.
For blinking text cursors, make the ifNil-check for paragraphs useful again. Using the accessor #paragraph will always create a paragraph. We have to directly check the instance variable to make this improvement effective.
Note that regular TextMorphs do not keep track of their editors and paragraphs after they lose keyboard focus. I am not sure why but this seems to be a performance optimization.
=============== Diff against Morphic-mt.1165 ===============
Item was changed:
----- Method: TextMorph>>keyboardFocusChange: (in category 'event handling') -----
+ keyboardFocusChange: weHaveFocus
+
+ paragraph ifNotNil: [:para | para focused: weHaveFocus].
+
+ weHaveFocus
+ ifTrue: [ "A hand is wanting to send us characters..."
- keyboardFocusChange: aBoolean
- | w |
- paragraph isNil ifFalse:[paragraph focused: aBoolean].
- aBoolean ifTrue:["A hand is wanting to send us characters..."
self hasFocus ifFalse: [self editor "Forces install"].
+ Editor blinkingCursor
+ ifTrue: [self startBlinking]
+ ifFalse: [self resetBlinkCursor "ensure caret visible"]]
+ ifFalse: [ "A hand has clicked elsewhere..."
+ self world ifNotNil: [:w |
+ self flag: #suspicious. "mt: Why should this be called with 'false' if a hand holds on the focus? Do hands not talk to each other before sending this call? They should..."
+ w handsDo: [:h | h keyboardFocus == self ifTrue: [^self]].
+ "Release control unless some hand is still holding on"
+ self releaseEditor].
+ self stopBlinking].
- Editor blinkingCursor ifTrue: [ self startBlinking ].
- ] ifFalse:["A hand has clicked elsewhere..."
- (w := self world) ifNotNil:[
- w handsDo: [:h | h keyboardFocus == self ifTrue: [^self]].
- "Release control unless some hand is still holding on"
- self releaseEditor].
- self stopBlinking.
- ].
!
Item was changed:
----- Method: TextMorph>>onBlinkCursor (in category 'blinking') -----
onBlinkCursor
+
- "Blink the cursor"
| para |
+ para := paragraph ifNil: [^nil].
+ Time millisecondClockValue < self blinkStart
+ ifTrue: [para showCaret: para focused]
+ ifFalse: [para showCaret: para showCaret not].
- para := self paragraph ifNil:[^nil].
- Time millisecondClockValue < self blinkStart ifTrue:[
- "don't blink yet"
- ^para showCaret: para focused.
- ].
- para showCaret: para showCaret not.
para caretRect ifNotNil: [ :r | self invalidRect: r].!
Item was changed:
----- Method: TextMorph>>resetBlinkCursor (in category 'blinking') -----
resetBlinkCursor
"Reset the blinking cursor"
| para |
self blinkStart: Time millisecondClockValue + 500.
+ para := paragraph ifNil: [^self].
- para := self paragraph ifNil:[^self].
para showCaret = para focused ifFalse:[
para caretRect ifNotNil: [ :r | self invalidRect: r].
para showCaret: para focused.
].
!
Item was changed:
----- Method: TextMorph>>stopBlinking (in category 'blinking') -----
stopBlinking
self stopSteppingSelector: #onBlinkCursor.
+ self resetBlinkCursor. "Ensure caret visible."!
- !
Item was changed:
----- Method: TextMorphForEditView>>keyboardFocusChange: (in category 'event handling') -----
+ keyboardFocusChange: weHaveFocus
+ "Overwritten because we do not want to release the editor if we do not have the focus. Editors and their paragraphs store the text selection, which we want to reuse after getting keyboard focus again. This supports keyboard navigation."
+
+ paragraph ifNotNil: [:para | para focused: weHaveFocus].
+
+ weHaveFocus
+ ifFalse: [self stopBlinking]
- keyboardFocusChange: aBoolean
- "rr 3/21/2004 22:55 : removed the #ifFalse: branch,
- which was responsible of the deselection of text when the
- paragraph lost focus. This way selection works in a more standard
- way, and this permits the menu keyboard control to be really effective"
- paragraph isNil ifFalse:[paragraph focused: aBoolean].
- aBoolean
ifTrue: [
+ self hasFocus
+ ifFalse: [self editor "forces install"].
+ Editor blinkingCursor
+ ifTrue: [self startBlinking]
+ ifFalse: [self resetBlinkCursor "ensure caret visible"]].
+
- "A hand is wanting to send us characters..."
- self hasFocus ifFalse: [self editor "Forces install"].
- Editor blinkingCursor ifTrue: [self startBlinking]]
- ifFalse:[
- self stopBlinking].
self changed.
"Tell my edit-view about this because I am his delegate."
+ self editView keyboardFocusChange: weHaveFocus.
- self editView keyboardFocusChange: aBoolean.
!
Item was changed:
----- Method: UserDialogBoxMorph>>runModalIn:forHand:at: (in category 'running') -----
runModalIn: aWorld forHand: aHand at: aPointOrNil
"Ensure that we have a reasonable minimum size"
| oldFocus pos offset |
(ProvideAnswerNotification signal: self label asString) ifNotNil:[:answer| ^answer].
self openInWorld: aWorld.
pos := aPointOrNil ifNil: [
"If called after a longer UI operation, be sure to use the current mouse cursor. Hand position is not up-to-date. Do one world cycle does not help if there are currently no mouse events. So, we *have to be* this extreme."
Sensor cursorPoint].
offset := aPointOrNil
ifNil: [selectedButton fullBounds origin - (selectedButton fullBounds extent // 2 * (-1@1))]
ifNotNil: [self fullBounds extent // 2].
self setConstrainedPosition: pos - offset hangOut: false.
oldFocus := aHand keyboardFocus.
aHand newMouseFocus: self.
aHand newKeyboardFocus: self.
savedLabel := selectedButton label.
[self isInWorld] whileTrue:[aWorld doOneSubCycle].
+ oldFocus ifNotNil:[aHand newKeyboardFocus: oldFocus].
- oldFocus ifNotNil:[aHand keyboardFocus: oldFocus].
^value!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1165.mcz
==================== Summary ====================
Name: Morphic-mt.1165
Author: mt
Time: 4 June 2016, 7:29:48.10522 pm
UUID: befe813b-f402-eb44-91db-cbe5582acd62
Ancestors: Morphic-mt.1164
Event listeners receive event copies again. For backwards compatibility.
Note that we can now use event filters to implement keyboard shortcuts. A handled shortcut can ignore the respective event directly in the event filter.
We might want to remove event listeners in the future.
=============== Diff against Morphic-mt.1164 ===============
Item was changed:
----- Method: HandMorph>>sendListenEvent:to: (in category 'private events') -----
sendListenEvent: anEvent to: listenerGroup
"Send the event to the given group of listeners"
listenerGroup ifNil:[^self].
listenerGroup do:[:listener|
+ listener ifNotNil:[listener handleListenEvent: anEvent copy]].!
- listener ifNotNil:[listener handleListenEvent: anEvent]].!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1164.mcz
==================== Summary ====================
Name: Morphic-mt.1164
Author: mt
Time: 4 June 2016, 7:23:27.090866 pm
UUID: 5e45c00f-7313-1449-86b4-7193cc8c0a62
Ancestors: Morphic-mt.1163
Fixes regression with system windows that get locked-in modally and thus have modal owners or a modal child. There was an endless loop then trying to #comeToFront.
CMD+K spawns a font chooser in every text morph, for example, which is modally locked to the underlying code editing window.
=============== Diff against Morphic-mt.1163 ===============
Item was changed:
----- Method: SystemWindow>>comeToFront (in category 'top window') -----
comeToFront
- "If I am modal, bring along my modal owning window and my model child as well. Ensure that my label is visible."
+ "Modal windows: Walk along the modal owner chain, the bring all to top."
+ self modalOwner ifNotNil: [:mo | mo isSystemWindow ifTrue: [
+ ^ mo modalOwner
+ ifNil: [mo comeToFrontModally]
+ ifNotNil: [:omo | omo comeToFront]]].
+ self modalChild ifNotNil: [^ self comeToFrontModally].
+
- "Model window: Bring up my modal owner behind me."
- self modalOwner ifNotNil:
- [ : mo | mo isSystemWindow ifTrue:
- [ mo comeToFront ] ].
-
"Now show me."
super comeToFront.
+
-
- "Modal window: Bring up my modal children in front of me."
- self modalChild ifNotNil:
- [ : modalChild | modalChild owner ifNotNil:
- [ modalChild comeToFront.
- ^ modalChild modalChild ifNil: [ modalChild flash ] ] ].
-
"Label should be visible to interact with."
self assureLabelAreaVisible.
"Handle historic companions. May be removed in the future."
self extantSketchEditor ifNotNil: [:sketchEditor |
sketchEditor comeToFront.
(self world findA: PaintBoxMorph) ifNotNil: [:pal | pal comeToFront]].!
Item was added:
+ ----- Method: SystemWindow>>comeToFrontModally (in category 'top window') -----
+ comeToFrontModally
+ "If I am modal, bring along my modal owning window and my model child as well."
+
+ super comeToFront.
+
+ "Bring up my modal children in front of me."
+ self modalChild ifNotNil: [:wnd |
+ wnd comeToFrontModally.
+ wnd modalChild ifNil: [wnd flash]].!