The Trunk: Morphic-mt.1610.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: Morphic-mt.1610.mcz

commits-2
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1610.mcz

==================== Summary ====================

Name: Morphic-mt.1610
Author: mt
Time: 18 December 2019, 4:31:47.223146 pm
UUID: 569aa27b-a8eb-0247-a758-b9ef6f53fa97
Ancestors: Morphic-mt.1609

Fixes a serious regression in text widgets and all other scroll panes.

- There were too many layout invalidations when scrolling through a pane's scroll bars. See #moveSliderTo: for the fix.
- There was a control-flow contract violation in ScrollPane >> #scrollToShow:.
- The text field discarderd mark-and-point information when replacing its editor. See, for example, #scrollSelectionIntoView:.
- All transform morphs triggered redraw requests on offset updates even if the new offset was not different. That made code in ScrollPanes unnecessarily complex.

I documented all the other quirks to be tackled after the 5.3 release. :-)

=============== Diff against Morphic-mt.1609 ===============

Item was changed:
  ----- Method: Morph>>position: (in category 'geometry') -----
  position: aPoint
  "Change the position of this morph, which is the top left corner of its bounds."
 
  | delta box |
  delta := (aPoint - self bounds topLeft) rounded.
 
  "Skip drawing and layout updates for null changes."
  (delta x = 0 and: [delta y = 0])
  ifTrue: [^ self].
 
  "Optimize drawing. Record one damage rectangle for short distance and two damage rectangles for large distances."
  box := self fullBounds.
  (delta dotProduct: delta) > 100 "More than 10 pixels?"
  ifTrue: [self
  invalidRect: box;
  invalidRect: (box translateBy: delta)]
  ifFalse: [self
  invalidRect: (box merge: (box translateBy: delta))].
 
  "Move this morph and *all* of its submorphs."
  self privateFullMoveBy: delta.
 
  "For all known layout policies, my layout and the layout of my children is fine. Only the layout of my owner might be affected. So, tell about it."
+ self owner ifNotNil: [:o |
+ self flag: #todo. "mt: Maybe we can save a lot of effort and troubles by only calling #layoutChanged if the owner has a layout policy installed? Take the thumbs of scroll-bars as an example..."
+ o layoutChanged].!
- self owner ifNotNil: [:o | o layoutChanged].!

Item was changed:
  ----- Method: PluggableTextMorph>>mouseLeave: (in category 'event handling') -----
  mouseLeave: event
  "Save the selection interval for later."
 
+ self flag: #fixIntervalCache. "mt: We should find a better design for discarding unused text editors in text morphs and restoring them on demand."
+ selectionInterval := textMorph editor markIndex to: textMorph editor pointIndex -1.
- selectionInterval := textMorph editor selectionInterval.
 
  super mouseLeave: event.
 
  Preferences mouseOverForKeyboardFocus
  ifTrue: [event hand releaseKeyboardFocus: self]!

Item was changed:
  ----- Method: PluggableTextMorph>>printIt (in category 'menu commands') -----
  printIt
  | oldEditor |
  textMorph editor selectFrom: selectionInterval first to: selectionInterval last;
  model: model.  "For, eg, evaluateSelection"
  textMorph handleEdit: [(oldEditor := textMorph editor) evaluateSelectionAndDo:
  [:result |
+ self flag: #fixIntervalCache. "mt: We should find a better design for discarding unused text editors in text morphs and restoring them on demand."
+ selectionInterval := oldEditor markIndex to: oldEditor pointIndex -1.
- selectionInterval := oldEditor selectionInterval.
  textMorph installEditorToReplace: oldEditor.
  textMorph handleEdit: [oldEditor afterSelectionInsertAndSelect: result printString].
+ selectionInterval := oldEditor markIndex to: oldEditor pointIndex -1.
- selectionInterval := oldEditor selectionInterval.
 
  textMorph editor selectFrom: selectionInterval first to: selectionInterval last.
  self scrollSelectionIntoView]]!

Item was changed:
  ----- Method: PluggableTextMorph>>scrollSelectionIntoView: (in category 'editor access') -----
  scrollSelectionIntoView: event
  "Scroll my text into view. Due to line composition mechanism, we must never use the right of a character block because the lines last character block right value always comes from a global container and is *not* line specific."
+
+ self flag: #fixIntervalCache. "mt: We should find a better design for discarding unused text editors in text morphs and restoring them on demand."
+ selectionInterval := textMorph editor markIndex to: textMorph editor pointIndex - 1.
 
- selectionInterval := textMorph editor selectionInterval.
-
  textMorph editor hasSelection
  ifFalse: [self scrollToShow: (textMorph editor startBlock withWidth: 1)]
  ifTrue: [
  self scrollToShow: (textMorph editor startBlock topLeft corner: textMorph editor stopBlock bottomLeft).
  self scrollToShow: (textMorph editor pointBlock withWidth: 1). "Ensure text cursor visibility."].
 
  ^ true!

Item was changed:
  ----- Method: ScrollPane>>scrollToShow: (in category 'scrolling') -----
  scrollToShow: aRectangle
 
  | newOffset |
  newOffset := self offsetToShow: aRectangle.
+ self hScrollBar setValue: newOffset x.
+ self vScrollBar setValue: newOffset y.!
- scroller offset = newOffset ifTrue: [^ self].
- scroller offset: newOffset.
- self layoutChanged.!

Item was changed:
  ----- Method: Slider>>computeSlider (in category 'geometry') -----
  computeSlider
  | r v |
  r := self roomToMove.
  v := self maximumValue = self minimumValue
  ifTrue: [0]
  ifFalse: [(value - self minimumValue) / (self maximumValue - self minimumValue)].
  self descending
  ifFalse:
+ [self moveSliderTo: (self orientation == #horizontal
- [slider position: (self orientation == #horizontal
  ifTrue: [r topLeft + ((r width * v) asInteger @ 0)]
  ifFalse: [r topLeft + (0 @ (r height * v)  asInteger)])]
  ifTrue:
+ [self moveSliderTo: (self orientation == #horizontal
- [slider position: (self orientation == #horizontal
  ifTrue: [r bottomRight - ((r width * v) asInteger @ 0)]
  ifFalse: [r bottomRight - ((0 @ (r height * v) asInteger))])].
+ self resizeSliderTo: self sliderExtent.!
- slider extent: self sliderExtent!

Item was added:
+ ----- Method: Slider>>moveSliderTo: (in category 'geometry') -----
+ moveSliderTo: newPosition
+ "Sliently move the slider (or thumb) to not trigger any #layoutChanged events."
+
+ | delta |
+ self flag: #codeDuplication. "mt: We need a better way to silently do position changes. See Morph >> #position:."
+
+ delta := (newPosition - slider position) rounded.
+ delta = (0@0) ifTrue: [^ self].
+
+ slider privateFullMoveBy: delta.
+ self changed.
+ !

Item was added:
+ ----- Method: Slider>>resizeSliderTo: (in category 'geometry') -----
+ resizeSliderTo: newExtent
+
+ slider extent: newExtent.!

Item was changed:
  ----- Method: Slider>>showSliderShadow (in category 'other events') -----
  showSliderShadow
 
  sliderShadow color: self sliderShadowColor.
  sliderShadow cornerStyle: slider cornerStyle.
+ sliderShadow privateBounds: slider bounds. "mt: Avoid #layoutChanged. See #moveSliderTo:."
- sliderShadow bounds: slider bounds.
  sliderShadow show.!

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 selectionInterval.
  self startOfTyping.
  emphasisHere}!

Item was changed:
  ----- Method: TransformMorph>>offset: (in category 'accessing') -----
  offset: newOffset
 
+ self offset = newOffset ifTrue: [^ self].
  transform := transform withOffset: newOffset - self innerBounds topLeft.
+ self changed.!
- self changed!