Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1643.mcz
==================== Summary ====================
Name: Morphic-mt.1643
Author: mt
Time: 4 April 2020, 11:06:42.760864 am
UUID: 81efe0e9-ec69-1b45-ba8e-b81bbb649355
Ancestors: Morphic-mt.1642
Fixes the recently discovered layout bug. Thanks to Christoph (ct)!
=============== Diff against Morphic-mt.1642 ===============
Item was changed:
----- Method: TableLayout>>computeExtraSpacing:in:horizontal:target: (in category 'layout') -----
computeExtraSpacing: arrangement in: newBounds horizontal: aBool target: aMorph
"Compute the required extra spacing for laying out the cells"
"match newBounds extent with arrangement's orientation"
| extent extra centering n extraPerCell cell last hFill vFill max amount allow |
extent := newBounds extent.
aBool ifFalse: [extent := extent transposed].
"figure out if we have any horizontal or vertical space fillers"
hFill := vFill := false.
max := 0 @ 0.
arrangement do:
[:c |
max := (max x max: c cellSize x) @ (max y + c cellSize y).
max := max max: c cellSize.
hFill := hFill or: [c hSpaceFill].
vFill := vFill or: [c vSpaceFill]].
"Take client's shrink wrap constraints into account.
Note: these are only honored when there are no #spaceFill children,
or when #rubberBandCells is set."
allow := properties rubberBandCells not.
aMorph hResizing == #shrinkWrap
ifTrue:
[aBool
ifTrue: [allow & hFill ifFalse: [extent := max x @ (max y max: extent y)]]
ifFalse: [allow & vFill ifFalse: [extent := (max x max: extent x) @ max y]]].
aMorph vResizing == #shrinkWrap
ifTrue:
[aBool
ifFalse: [allow & hFill ifFalse: [extent := max x @ (max y max: extent y)]]
ifTrue: [allow & vFill ifFalse: [extent := (max x max: extent x) @ max y]]].
"Now compute the extra v space"
extra := extent y
- (arrangement inject: 0 into: [:sum :c | sum + c cellSize y]).
extra > 0
ifTrue:
["Check if we have any #spaceFillers"
vFill
ifTrue:
["use only #spaceFillers"
n := arrangement inject: 0
into: [:sum :c | c vSpaceFill ifTrue: [sum + 1] ifFalse: [sum]].
n isZero ifFalse: [extraPerCell := extra asFloat / n asFloat].
extra := last := 0.
arrangement do:
[:c |
c vSpaceFill
ifTrue:
[extra := (last := extra) + extraPerCell.
amount := 0 @ (extra truncated - last truncated).
c do: [:cc | cc cellSize: cc cellSize + amount]]]]
ifFalse:
["no #spaceFillers; distribute regularly"
centering := properties wrapCentering.
"centering == #topLeft ifTrue:[]." "add all extra space to the last cell; e.g., do nothing"
centering == #bottomRight
ifTrue:
["add all extra space to the first cell"
+ arrangement ifNotEmpty: [:cells | cells first addExtraSpace: 0 @ extra]].
- arrangement first addExtraSpace: 0 @ extra].
centering == #center
ifTrue:
["add 1/2 extra space to the first and last cell"
+ arrangement ifNotEmpty: [:cells | cells first addExtraSpace: 0 @ (extra // 2)]].
- arrangement first addExtraSpace: 0 @ (extra // 2)].
centering == #justified
ifTrue:
["add extra space equally distributed to each cell"
n := arrangement size - 1 max: 1.
extraPerCell := extra asFloat / n asFloat.
extra := last := 0.
arrangement do:
[:c |
c addExtraSpace: 0 @ (extra truncated - last truncated).
extra := (last := extra) + extraPerCell]]]].
"Now compute the extra space for the primary direction"
centering := properties listCentering.
1 to: arrangement size
do:
[:i |
cell := arrangement at: i.
extra := extent x - cell cellSize x.
extra > 0
ifTrue:
["Check if we have any #spaceFillers"
cell := cell nextCell.
cell hSpaceFill
ifTrue:
["use only #spaceFillers"
n := cell inject: 0
into: [:sum :c | c hSpaceFill ifTrue: [sum + c target spaceFillWeight] ifFalse: [sum]].
n isZero ifFalse: [extraPerCell := extra asFloat / n asFloat].
extra := last := 0.
cell do:
[:c |
c hSpaceFill
ifTrue:
[extra := (last := extra) + (extraPerCell * c target spaceFillWeight).
amount := extra truncated - last truncated.
c cellSize: c cellSize + (amount @ 0)]]]
ifFalse:
["no #spaceFiller; distribute regularly"
"centering == #topLeft ifTrue:[]" "add all extra space to the last cell; e.g., do nothing"
centering == #bottomRight
ifTrue:
["add all extra space to the first cell"
cell addExtraSpace: extra @ 0].
centering == #center
ifTrue:
["add 1/2 extra space to the first and last cell"
cell addExtraSpace: (extra // 2) @ 0].
centering == #justified
ifTrue:
["add extra space equally distributed to each cell"
n := cell size - 1 max: 1.
extraPerCell := extra asFloat / n asFloat.
extra := last := 0.
cell do:
[:c |
c addExtraSpace: (extra truncated - last truncated) @ 0.
extra := (last := extra) + extraPerCell]]]]]!
Marcel Taeumel uploaded a new version of MorphicTests to project The Trunk:
http://source.squeak.org/trunk/MorphicTests-mt.61.mcz
==================== Summary ====================
Name: MorphicTests-mt.61
Author: mt
Time: 4 April 2020, 11:06:00.417864 am
UUID: 6e50f97d-ac59-0143-ac2e-d2908a269f9a
Ancestors: MorphicTests-mt.60
Adds a test for the recently discovered layout bug. Thanks to Christoph (ct)!
=============== Diff against MorphicTests-mt.60 ===============
Item was added:
+ ----- Method: TableLayoutTest>>testDisableLayoutEmptyArrangement (in category 'tests') -----
+ testDisableLayoutEmptyArrangement
+
+ container := Morph new
+ layoutPolicy: TableLayout new;
+ listDirection: #rightToLeft; "... to not get into the layout's fast lane ..."
+ wrapCentering: #center; "... to actually trigger the bug ..."
+ addMorphBack: Morph new;
+ addMorphBack: Morph new;
+ yourself.
+
+ container submorphsDo: [:m | m disableLayout: true].
+ self shouldnt: [self ensureLayout: container] raise: Error.!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1642.mcz
==================== Summary ====================
Name: Morphic-mt.1642
Author: mt
Time: 3 April 2020, 5:52:32.157206 pm
UUID: 774f60b6-f208-a246-bbd8-f07c0d5d0fb4
Ancestors: Morphic-spfa.1641
Adds a missing reset of the potential drop row to avoid visual glitches. As you can see, the hover row and the potential-drop row are both related.
=============== Diff against Morphic-spfa.1641 ===============
Item was changed:
----- Method: PluggableListMorph>>mouseLeave: (in category 'event handling') -----
mouseLeave: event
super mouseLeave: event.
self hoverRow: nil.
+ self resetPotentialDropRow.
Preferences mouseOverForKeyboardFocus
ifTrue: [event hand releaseKeyboardFocus: self].!
Marcel Taeumel uploaded a new version of ToolBuilder-Morphic to project The Trunk:
http://source.squeak.org/trunk/ToolBuilder-Morphic-mt.256.mcz
==================== Summary ====================
Name: ToolBuilder-Morphic-mt.256
Author: mt
Time: 3 April 2020, 5:50:25.120206 pm
UUID: 7666414e-e468-234e-9ad7-85db6d6cdb5e
Ancestors: ToolBuilder-Morphic-mt.255
Fixes a drag-and-drop bug in pluggable lists whose models do not provide a wantsDropSelector.
As you can see in #acceptDrop..., the pluggable list itself depends on the morph to be a TransferMorph. We might want to change #isKindOf: to #isTransferMorph or #respondsTo: in the future. Well, drag-and-drop is kind of important and it may deserve an #isTransferMorph in Morph to be added.
=============== Diff against ToolBuilder-Morphic-mt.255 ===============
Item was changed:
----- Method: PluggableListMorphPlus>>wantsDroppedMorph:event: (in category 'drag and drop') -----
wantsDroppedMorph: aTransferMorph event: anEvent
dropItemSelector ifNil: [^ false].
+ (aTransferMorph isKindOf: TransferMorph) ifFalse: [^ false].
wantsDropSelector ifNil: [^ true].
- (aTransferMorph isKindOf: TransferMorph) ifFalse: [^ false].
-
^ model perform: wantsDropSelector withEnoughArguments: {
aTransferMorph passenger.
aTransferMorph dragTransferType.
aTransferMorph source.
aTransferMorph}!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-spfa.1641.mcz
==================== Summary ====================
Name: Morphic-spfa.1641
Author: spfa
Time: 2 April 2020, 11:31:57.845097 pm
UUID: be701ee2-5637-c34d-8765-d2527e1d5785
Ancestors: Morphic-mt.1640
Add inst. var. lastParenLocation to TextEditor #stateArray (used to transfer state to a newly installed editor). This ensures that #clearParens works as expected in all circumstances.
=============== Diff against Morphic-mt.1640 ===============
Item was changed:
----- Method: TextEditor>>stateArray (in category 'initialize-release') -----
stateArray
^ {ChangeText.
FindText.
history ifNil: [TextEditorCommandHistory new]. "Convert old instances"
self markIndex to: self pointIndex - 1.
self startOfTyping.
+ emphasisHere.
+ lastParenLocation}!
- emphasisHere}!
Item was changed:
----- Method: TextEditor>>stateArrayPut: (in category 'initialize-release') -----
stateArrayPut: stateArray
| sel |
ChangeText := stateArray at: 1.
FindText := stateArray at: 2.
history := stateArray at: 3.
sel := stateArray at: 4.
self selectFrom: sel first to: sel last.
beginTypeInIndex := stateArray at: 5.
+ emphasisHere := stateArray at: 6.
+ lastParenLocation := stateArray at: 7!
- emphasisHere := stateArray at: 6!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1640.mcz
==================== Summary ====================
Name: Morphic-mt.1640
Author: mt
Time: 2 April 2020, 7:04:01.023784 pm
UUID: efcf5cf1-ceb9-784e-ab5a-af7de2dc2c71
Ancestors: Morphic-mt.1639
Fixes a drag-and-drop bug for lists with frequently updating elements, which might not yield any visual changes ... but the model claims so.
So, if you are just about to drop something, then the list changes, then the mouse button goes up ... that drop would fail because the potential drop row got reset --- even though the user did see the changing list and could as well abort the dragging manually.
Hover rows and drop rows are kind of similar concepts here. And we see that the hover row did not get reset but the drop row did, which was kind of strange anyway. We might want to bring both concepts closer together in the future. Look for "hoverRow: nil" for that other reset.
=============== Diff against Morphic-mt.1639 ===============
Item was changed:
----- Method: PluggableListMorph>>updateList: (in category 'updating') -----
updateList: modelList
"Keeps the current filter as it is."
fullList := modelList.
- self resetPotentialDropRow.
self updateListFilter.!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1639.mcz
==================== Summary ====================
Name: Morphic-mt.1639
Author: mt
Time: 2 April 2020, 9:57:01.627769 am
UUID: f6179063-73e6-7d47-b156-db672067b49a
Ancestors: Morphic-eem.1638
Fixes some unnecessary visual updates in lists, which caused extra (maybe expensive) model access:
(1) Menu invocation for list items should first check whether to update the selection and then ask the model #okToChange.
(2) Avoid scrolling to the selection to be visible if there is no change in the selection index. Only make users aware of changes. Models can still force such scrolling with de-selecting and immediately selecting an item. --- If list contents changed, the list filter got updated and tried to re-select the same element in the (maybe filtered) list. That caused the redunant updates and scrolling.
(3) To make (2) work, the must not clear the selectedRow in LazyListMorph because PluggableListMorph has no own tracking of the selected row.
=============== Diff against Morphic-eem.1638 ===============
Item was changed:
----- Method: LazyListMorph>>listChanged (in category 'layout') -----
listChanged
"set newList to be the list of strings to display"
listItems := nil.
listIcons := nil.
listFilterOffsets := nil.
maxWidth := nil.
+ "selectedRow := nil. --- avoid reset to keep UI stable. See PluggableListMorph >> #selectionIndex and #selectionIndex:."
- selectedRow := nil.
selectedRows := PluggableSet integerSet.
preSelectedRow := nil.
self layoutChanged.
self changed.
!
Item was changed:
----- Method: PluggableListMorph>>mouseDown: (in category 'event handling') -----
mouseDown: evt
| selectors row |
row := self rowAtLocation: evt position.
evt yellowButtonPressed "First check for option (menu) click"
ifTrue: [
+ ((self selectionIndex ~= row
+ and: [self class menuRequestUpdatesSelection])
+ and: [model okToChange]) ifTrue: [
+ "Models depend on the correct selection:"
+ self changeModelSelection: (self modelIndexFor: row)].
- (self class menuRequestUpdatesSelection and: [model okToChange]) ifTrue: [
- "Models depend on the correct selection:"
- self selectionIndex = row
- ifFalse: [self changeModelSelection: (self modelIndexFor: row)]].
^ self yellowButtonActivity: evt shiftPressed].
row = 0 ifTrue: [^super mouseDown: evt].
"self dragEnabled ifTrue: [aMorph highlightForMouseDown]."
selectors := Array
with: #click:
with: (doubleClickSelector ifNotNil:[#doubleClick:])
with: nil
with: (self dragEnabled ifTrue:[#startDrag:] ifFalse:[nil]).
evt hand waitForClicksOrDrag: self event: evt selectors: selectors threshold: HandMorph dragThreshold "pixels".!
Item was changed:
----- Method: PluggableListMorph>>selectionIndex: (in category 'selection') -----
selectionIndex: viewIndex
"Called internally to select the index-th item."
+ self selectionIndex = viewIndex ifTrue: [^ self].
+
self unhighlightSelection.
self listMorph selectedRow: (viewIndex min: self listSize).
self highlightSelection.
self scrollSelectionIntoView.!