<div dir="ltr">Hi Marcel and Christoph,<div><br></div><div>After further thought the other day, I had arrived at the same concerns as Christoph and you; and had this version sitting dirty in my image. In addition to yours, I myself also didn't care for passing the non-well-formed Event object which the method might in the future couple to beyond the type test. Plus, the extra garbage.</div><div><br></div><div>All this is somewhat ameliorated in this edition, by simply allowing a Symbolic "directive" to be passed in alternately from an Event object (which would not be used even if it was).</div><div><br></div><div>This was done a few days ago. Since then, Marcel submitted his workaround in Tools which is fine for now, but I just wanted to capture this latest version in the Inbox for future discussion rather than lose it.</div><div><br></div><div>Best,</div><div> Chris</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 6, 2020 at 10:08 PM <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Chris Muller uploaded a new version of Morphic to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Morphic-cmm.1616.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/inbox/Morphic-cmm.1616.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-cmm.1616<br>
Author: cmm<br>
Time: 6 January 2020, 10:07:44.246015 pm<br>
UUID: d5855100-f308-4287-b83d-2e51c3b4688c<br>
Ancestors: Morphic-mt.1615<br>
<br>
When a text selection cannot fit into its text pane, start by scrolling to its upper-left, rather than its lower-right until the next edit is made, at which point scroll to the edit.<br>
<br>
=============== Diff against Morphic-mt.1615 ===============<br>
<br>
Item was changed:<br>
----- Method: PluggableTextMorph>>handleEdit: (in category 'editor access') -----<br>
handleEdit: editBlock<br>
| result |<br>
textMorph editor selectFrom: selectionInterval first to: selectionInterval last;<br>
model: model. "For, eg, evaluateSelection"<br>
result := textMorph handleEdit: editBlock. "Update selection after edit"<br>
+ self scrollSelectionIntoView: #scrollToPointBlock. "Special directive to scroll to text cursor"<br>
- self scrollSelectionIntoView.<br>
^ result!<br>
<br>
Item was changed:<br>
----- Method: PluggableTextMorph>>scrollSelectionIntoView: (in category 'editor access') -----<br>
+ scrollSelectionIntoView: eventOrDirective<br>
- scrollSelectionIntoView: event <br>
"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."<br>
+ self flag: #fixIntervalCache.<br>
+ "mt: We should find a better design for discarding unused text editors in text morphs and restoring them on demand."<br>
- <br>
- self flag: #fixIntervalCache. "mt: We should find a better design for discarding unused text editors in text morphs and restoring them on demand."<br>
selectionInterval := textMorph editor markIndex to: textMorph editor pointIndex - 1.<br>
+ self scrollToShow:<br>
+ (textMorph editor hasSelection<br>
+ ifTrue: [ textMorph editor startBlock topLeft corner: textMorph editor stopBlock bottomLeft ]<br>
+ ifFalse: [ textMorph editor startBlock withWidth: 1 ]).<br>
+ (eventOrDirective notNil and: [ eventOrDirective = #scrollToPointBlock or: [ eventOrDirective isKeyboard ] ]) ifTrue:<br>
+ [ self scrollToShow: (textMorph editor pointBlock withWidth: 1) ].<br>
- <br>
- textMorph editor hasSelection<br>
- ifFalse: [self scrollToShow: (textMorph editor startBlock withWidth: 1)]<br>
- ifTrue: [<br>
- self scrollToShow: (textMorph editor startBlock topLeft corner: textMorph editor stopBlock bottomLeft).<br>
- self scrollToShow: (textMorph editor pointBlock withWidth: 1). "Ensure text cursor visibility."].<br>
- <br>
^ true!<br>
<br>
Item was changed:<br>
----- Method: ScrollPane>>keyStroke: (in category 'event handling') -----<br>
+ keyStroke: aKeyboardEvent<br>
+ "If pane is not empty, let the last submorph handle the event."<br>
+ scroller submorphs ifNotEmpty: [ : subs | subs last keyStroke: aKeyboardEvent ]!<br>
- keyStroke: evt<br>
- "If pane is not empty, pass the event to the last submorph,<br>
- assuming it is the most appropriate recipient (!!)"<br>
- <br>
- scroller submorphs last keyStroke: evt!<br>
<br>
Item was changed:<br>
----- Method: ScrollPane>>offsetToShow: (in category 'scrolling') -----<br>
offsetToShow: aRectangle<br>
"Calculate the offset necessary to show the rectangle."<br>
<br>
| offset scrollRange target |<br>
self fullBounds. "We need updated bounds."<br>
offset := scroller offset.<br>
scrollRange := self hTotalScrollRange @ self vTotalScrollRange.<br>
<br>
"Normalize the incoming rectangle."<br>
target := <br>
+ aRectangle left @ aRectangle top<br>
- (scroller width < aRectangle width<br>
- ifTrue: [offset x < aRectangle left "Coming from left?"<br>
- ifTrue: [aRectangle right - scroller width]<br>
- ifFalse: [aRectangle left]]<br>
- ifFalse: [aRectangle left])<br>
- @<br>
- (scroller height < aRectangle height<br>
- ifTrue: [offset y < aRectangle top "Coming from top?"<br>
- ifTrue: [aRectangle bottom - scroller height]<br>
- ifFalse: [aRectangle top]]<br>
- ifFalse: [aRectangle top])<br>
corner: <br>
(scroller width < aRectangle width<br>
ifTrue: [offset x + scroller width > aRectangle right "Coming from right?"<br>
ifTrue: [aRectangle left + scroller width]<br>
ifFalse: [aRectangle right]]<br>
ifFalse: [aRectangle right])<br>
@<br>
(scroller height < aRectangle height<br>
ifTrue: [offset y + scroller height > aRectangle bottom "Coming from bottom?"<br>
ifTrue: [aRectangle top + scroller height]<br>
ifFalse: [aRectangle bottom]]<br>
ifFalse: [aRectangle bottom]).<br>
<br>
"Vertical Scrolling"<br>
- target top < offset y<br>
- ifTrue: [offset := offset x @ target top]. <br>
target bottom > (offset y + scroller height)<br>
ifTrue: [offset := offset x @ (target bottom - scroller height)].<br>
+ target top < offset y<br>
+ ifTrue: [offset := offset x @ target top]. <br>
<br>
"Horizontal Scrolling"<br>
- target left < offset x<br>
- ifTrue: [offset := target left @ offset y].<br>
target right > (offset x + scroller width)<br>
ifTrue: [offset := (target right - scroller width) @ offset y].<br>
+ target left < offset x<br>
+ ifTrue: [offset := target left @ offset y].<br>
<br>
^ (offset min: scrollRange - scroller extent) max: 0@0!<br>
<br>
Item was changed:<br>
----- Method: TextMorphForEditView>>keyStroke: (in category 'event handling') -----<br>
keyStroke: evt<br>
| view |<br>
<br>
editView deleteBalloon.<br>
self editor model: editView model. "For evaluateSelection"<br>
view := editView. "Copy into temp for case of a self-mutating doit"<br>
(acceptOnCR and: [evt keyCharacter = Character cr])<br>
ifTrue: [^ self editor accept].<br>
<br>
view hasUserEdited: false.<br>
super keyStroke: evt.<br>
+ view scrollSelectionIntoView: evt.<br>
- view scrollSelectionIntoView.<br>
<br>
view hasUserEdited<br>
ifTrue: [ view textEdited: self contents].!<br>
<br>
<br>
</blockquote></div>