Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.2129.mcz
==================== Summary ====================
Name: Morphic-mt.2129 Author: mt Time: 19 September 2023, 9:56:14.547349 am UUID: 88ff3046-2fb5-3546-ac13-948c116518d7 Ancestors: Morphic-mt.2128
Fix an annoying layout issue where a flaky answer to #minExtent in a ScrollPane resulted in a (table-)layouted sibling that as height-for-width properties to not be finished after its second layout run.
For example: Create any container (morph) with a TableLayout and add two children (or submorphs), one a ScrollPane and one a PluggableTextMorph. Let them be #spaceFill in all directions except for the text widget, which should #shrinkWrap for #vReszing (and #wrapFlag be true like the MorphicToolBuilder does implementing #softLineWrap in #buildPluggableText:). Now, if scrollbars are set to #whenNeeded, a too tiny container and that scrollpane with a not-too-small-not-too-big scrollable content (morph) will change #layoutBounds after the first layout run, which should not be. Morph >> #minExtent expects a steady answer between two runs (see senders of #doLayoutAgain to understand that two-pass mechanism).
So, the original override of #innerBounds (from 2015!... by me :o), which is needed by #layoutBounds, in ScrollPane was conceptually wrong. Even if ScrollPane implements its own layout strategy without using a #layoutPolicy, those #layoutBounds affect all the receiver's things: two scrollbars and the scroller. Not just the scroller. Rename the calculation and use it as #newScrollerBounds.
Even if this change has no super-serious implications in past projects, I will backport it to Squeak 6.0 so that people can create more interactive tools and combine PluggableScrollPane and PluggableTextMorph there. We currently do this in a University-related project. :-)
=============== Diff against Morphic-mt.2128 ===============
Item was removed: - ----- Method: ScrollPane>>innerBounds (in category 'geometry') ----- - innerBounds - - | inner bottomOffset leftOffset rightOffset | - (retractableScrollBar or: [self vIsScrollbarShowing not]) - ifTrue: [leftOffset := rightOffset := 0] - ifFalse: [ - scrollBarOnLeft - ifTrue: [ - leftOffset := self scrollBarThickness - self borderWidth. - rightOffset := 0.] - ifFalse: [ - leftOffset := 0. - rightOffset := self scrollBarThickness - self borderWidth]]. - - (retractableScrollBar or: [self hIsScrollbarShowing not]) - ifTrue: [bottomOffset := 0] - ifFalse: [bottomOffset := self scrollBarThickness - self borderWidth]. - - inner := super innerBounds. - ^ (inner left + leftOffset) @ (inner top "+ topOffset") - corner: (inner right - rightOffset) @ (inner bottom - bottomOffset)!
Item was added: + ----- Method: ScrollPane>>newScrollerBounds (in category 'layout') ----- + newScrollerBounds + "Answer the new bounds for the receiver's scrolling area. Should be called after a #layoutChanged." + + | inner bottomOffset leftOffset rightOffset | + (retractableScrollBar or: [self vIsScrollbarShowing not]) + ifTrue: [leftOffset := rightOffset := 0] + ifFalse: [ + scrollBarOnLeft + ifTrue: [ + leftOffset := self scrollBarThickness - self borderWidth. + rightOffset := 0.] + ifFalse: [ + leftOffset := 0. + rightOffset := self scrollBarThickness - self borderWidth]]. + + (retractableScrollBar or: [self hIsScrollbarShowing not]) + ifTrue: [bottomOffset := 0] + ifFalse: [bottomOffset := self scrollBarThickness - self borderWidth]. + + inner := self innerBounds. + ^ (inner left + leftOffset) @ (inner top "+ topOffset") + corner: (inner right - rightOffset) @ (inner bottom - bottomOffset)!
Item was changed: ----- Method: ScrollPane>>resizeScroller (in category 'layout - resizing') ----- resizeScroller
scroller + bounds: self newScrollerBounds; - bounds: self layoutBounds; fullBounds. "To make #shrinkWrap work."!
Item was changed: ----- Method: SimpleHierarchicalListMorph>>resizeScroller (in category 'layout - resizing') ----- resizeScroller "For performance, skip re-layouting all items if layout only changed from the outside, which we know if our scroller still has its fullBounds. This happens, for example, when the receiver is resized via #extent:."
| doLayout | doLayout := scroller layoutComputed not. + scroller privateBounds: self newScrollerBounds. - scroller privateBounds: self layoutBounds. doLayout ifTrue: [scroller fullBounds] ifFalse: [scroller privateFullBounds: scroller bounds].!
squeak-dev@lists.squeakfoundation.org