<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<meta content="text/html; charset=UTF-8">
<style type="text/css" style="">
<!--
p
{margin-top:0;
margin-bottom:0}
-->
</style>
<div dir="ltr">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:#000000; font-family:Calibri,Helvetica,sans-serif">
<p>Hm, the diff looks weird again. Did I make some mistake or is this some issue with the "diff server" (unknowing any details on how this online stuff works)? Chris, could you maybe enlighten me? :)</p>
<div id="x_Signature">
<div id="x_divtagdefaultwrapper" dir="ltr" style="font-size:12pt; color:rgb(0,0,0); font-family:Calibri,Helvetica,sans-serif,EmojiFont,"Apple Color Emoji","Segoe UI Emoji",NotoColorEmoji,"Segoe UI Symbol","Android Emoji",EmojiSymbols">
<div name="x_divtagdefaultwrapper" style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:; margin:0">
<div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">
<div class="x__rp_U4 x_ms-font-weight-regular x_ms-font-color-neutralDark x_rpHighlightAllClass x_rpHighlightBodyClass" id="x_Item.MessageUniqueBody" style="font-family:wf_segoe-ui_normal,"Segoe UI","Segoe WP",Tahoma,Arial,sans-serif,serif,EmojiFont">
<div dir="ltr">
<div id="x_divtagdefaultwrapper"><font face="Calibri,Helvetica,sans-serif,EmojiFont,Apple Color Emoji,Segoe UI Emoji,NotoColorEmoji,Segoe UI Symbol,Android Emoji,EmojiSymbols">
<div id="x_Signature">
<div style="margin:0px"><font style="font-family:Calibri,Arial,Helvetica,sans-serif,serif,EmojiFont"></font></div>
</div>
</font></div>
</div>
</div>
</div>
<div class="x__rp_T4" id="x_Item.MessagePartBody"><br>
</div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">Best,</div>
<div class="x__rp_T4" id="x_Item.MessagePartBody">Christoph</div>
</div>
<div><font size="2" color="#808080"></font></div>
</div>
</div>
</div>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von commits@source.squeak.org <commits@source.squeak.org><br>
<b>Gesendet:</b> Sonntag, 12. Januar 2020 03:34:33<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org<br>
<b>Betreff:</b> [squeak-dev] The Inbox: Morphic-ct.1617.mcz</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Christoph Thiede uploaded a new version of Morphic to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Morphic-ct.1617.mcz">http://source.squeak.org/inbox/Morphic-ct.1617.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-ct.1617<br>
Author: ct<br>
Time: 12 January 2020, 3:34:20.453555 am<br>
UUID: d75dd5ad-8420-c443-9314-c01d96409fae<br>
Ancestors: Morphic-tpr.1616<br>
<br>
Fixes #applyUserInterfaceTheme on SystemProgressMorph really!<br>
<br>
Explanation: Resetting the ProgressMorph from the class side is definively bad, because it deletes the progress morph if currently visible. The current instance-side implementation was not reliable either, because if the UniqueInstance is not in world, it cannot
apply the new UI theme. Thus we need to override #canApplyUserInterfaceTheme from Morph.<br>
<br>
This commit replaces Morphic-ct.1615. See also: <a href="http://forum.world.st/SystemProgressMorph-applyUserInterfaceTheme-td5108129.html">
http://forum.world.st/SystemProgressMorph-applyUserInterfaceTheme-td5108129.html</a><br>
<br>
=============== Diff against Morphic-tpr.1616 ===============<br>
<br>
Item was added:<br>
+ ----- Method: AlternatePluggableListMorphOfMany>>mouseLeaveDragging: (in category 'event handling') -----<br>
+ mouseLeaveDragging: anEvent<br>
+ "Dragging means changing the list's multi-selection state. Thus, there is no support for drag-and-drop of elements within a selection."<br>
+ <br>
+ self hoverRow: nil.<br>
+ self resetPotentialDropRow.!<br>
<br>
Item was changed:<br>
----- Method: FontChooserTool>>selectedPointSizeIndex: (in category 'point size') -----<br>
selectedPointSizeIndex: anIndex<br>
<br>
anIndex = 0 ifTrue: [^self].<br>
pointSize := (self pointSizeList at: anIndex) withBlanksTrimmed asNumber.<br>
+ self changed: #selectedPointSizeIndex.<br>
self changed: #pointSizeList.<br>
self changed: #contents.!<br>
<br>
Item was changed:<br>
Morph subclass: #HandMorph<br>
+ instanceVariableNames: 'mouseFocus keyboardFocus eventListeners mouseListeners keyboardListeners eventCaptureFilters mouseCaptureFilters keyboardCaptureFilters mouseClickState mouseOverHandler mouseWheelState lastMouseEvent targetOffset damageRecorder
cacheCanvas cachedCanvasHasHoles temporaryCursor temporaryCursorOffset hardwareCursor hasChanged savedPatch userInitials lastEventBuffer genieGestureProcessor keyboardInterpreter'<br>
+ classVariableNames: 'CompositionWindowManager DoubleClickTime DragThreshold EventStats NewEventRules NormalCursor PasteBuffer SendMouseWheelToKeyboardFocus ShowEvents SynthesizeMouseWheelEvents'<br>
- instanceVariableNames: 'mouseFocus keyboardFocus eventListeners mouseListeners keyboardListeners eventCaptureFilters mouseCaptureFilters keyboardCaptureFilters mouseClickState mouseOverHandler targetOffset lastMouseEvent damageRecorder cacheCanvas
cachedCanvasHasHoles temporaryCursor temporaryCursorOffset hardwareCursor hasChanged savedPatch userInitials lastEventBuffer genieGestureProcessor keyboardInterpreter'<br>
- classVariableNames: 'CompositionWindowManager DoubleClickTime DragThreshold EventStats MinimalWheelDelta NewEventRules NormalCursor PasteBuffer SendMouseWheelToKeyboardFocus ShowEvents SynthesizeMouseWheelEvents'<br>
poolDictionaries: 'EventSensorConstants'<br>
category: 'Morphic-Kernel'!<br>
<br>
!HandMorph commentStamp: '<historical>' prior: 0!<br>
The cursor may be thought of as the HandMorph. The hand's submorphs hold anything being carried by dragging.
<br>
<br>
There is some minimal support for multiple hands in the same world.!<br>
<br>
Item was removed:<br>
- ----- Method: HandMorph class>>minimumWheelDelta (in category 'preferences') -----<br>
- minimumWheelDelta<br>
- <preference: 'Minimal Mouse Wheel Scroll Delta'<br>
- categoryList: #(Morphic mouse)<br>
- description: 'Answer the minimal scroll increment taken into account<br>
- Defaults to 120, corresponding to a single mouse wheel notch.<br>
- Use a lower value (20) if wanting smoother scrolling with trackpads.'<br>
- type: #Number><br>
- ^MinimalWheelDelta ifNil: [120].!<br>
<br>
Item was removed:<br>
- ----- Method: HandMorph class>>minimumWheelDelta: (in category 'preferences') -----<br>
- minimumWheelDelta: anInteger<br>
- MinimalWheelDelta := anInteger ifNotNil: [anInteger clampLow: 20 high: 120]!<br>
<br>
Item was changed:<br>
----- Method: HandMorph>>generateMouseWheelEvent: (in category 'private events') -----<br>
generateMouseWheelEvent: evtBuf<br>
"Generate the appropriate mouse wheel event for the given raw event buffer"<br>
<br>
+ | buttons modifiers deltaX deltaY stamp |<br>
- | buttons modifiers deltaX deltaY stamp nextEvent |<br>
stamp := evtBuf second.<br>
stamp = 0 ifTrue: [stamp := Time eventMillisecondClock].<br>
deltaX := evtBuf third.<br>
deltaY := evtBuf fourth.<br>
+ modifiers := evtBuf fifth.<br>
+ buttons := (modifiers bitShift: 3) bitOr: (lastMouseEvent buttons bitAnd: 7).<br>
- buttons := evtBuf fifth.<br>
- modifiers := evtBuf sixth.<br>
- [(deltaX abs + deltaY abs < self class minimumWheelDelta)<br>
- and: [(nextEvent := Sensor peekEvent) notNil<br>
- and: [nextEvent first = evtBuf first<br>
- and: [nextEvent fifth = evtBuf fifth <br>
- and: [nextEvent sixth = evtBuf sixth]<br>
- and: [nextEvent third isZero = evtBuf third isZero "both horizontal or vertical"]]]]]<br>
- whileTrue:<br>
- ["nextEvent is similar. Remove it from the queue, and check the next."<br>
- nextEvent := Sensor nextEvent.<br>
- deltaX := deltaX + nextEvent third.<br>
- deltaY := deltaY + nextEvent fourth].<br>
^ MouseWheelEvent new<br>
setType: #mouseWheel<br>
position: self position<br>
delta: deltaX@deltaY<br>
+ direction: 2r0000<br>
buttons: buttons <br>
hand: self<br>
stamp: stamp!<br>
<br>
Item was changed:<br>
----- Method: HandMorph>>handleEvent: (in category 'events-processing') -----<br>
handleEvent: unfilteredEvent<br>
<br>
| filteredEvent |<br>
owner ifNil: [^ unfilteredEvent "not necessary but good style -- see Morph >> #handleEvent:"].<br>
<br>
self logEvent: unfilteredEvent.<br>
<br>
"Mouse-over events occur really, really, really often. They are kind of the heart beat of the Morphic UI process."<br>
unfilteredEvent isMouseOver ifTrue: [^ self sendMouseEvent: unfilteredEvent].<br>
<br>
self showEvent: unfilteredEvent.<br>
self sendListenEvents: unfilteredEvent.<br>
<br>
filteredEvent := self sendFilterEventCapture: unfilteredEvent for: nil.<br>
"filteredEvent := unfilteredEvent" " <-- use this to disable global capture filters"<br>
<br>
filteredEvent wasIgnored ifTrue: [<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
filteredEvent isWindowEvent ifTrue: [<br>
self sendEvent: filteredEvent focus: nil.<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
filteredEvent isKeyboard ifTrue:[<br>
self sendKeyboardEvent: filteredEvent.<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
filteredEvent isDropEvent ifTrue:[<br>
self sendEvent: filteredEvent focus: nil.<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
filteredEvent isMouse ifFalse: [<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
" ********** MOUSE EVENT *********** "<br>
<br>
lastMouseEvent := filteredEvent.<br>
<br>
"Check for pending drag or double click operations."<br>
mouseClickState ifNotNil:[<br>
(mouseClickState handleEvent: filteredEvent from: self) ifFalse:[<br>
"Possibly dispatched #click: or something and will not re-establish otherwise"<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent]].<br>
<br>
filteredEvent isMouseWheel ifTrue: [<br>
+ mouseWheelState ifNil: [mouseWheelState := MouseWheelState new].<br>
+ mouseWheelState handleEvent: filteredEvent from: self.<br>
- self class sendMouseWheelToKeyboardFocus<br>
- ifFalse: [self sendMouseEvent: filteredEvent]<br>
- ifTrue: [self sendEvent: filteredEvent focus: self keyboardFocus clear: [self keyboardFocus: nil]].<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
filteredEvent isMove ifTrue:[<br>
self position: filteredEvent position.<br>
self sendMouseEvent: filteredEvent.<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent].<br>
<br>
"Issue a synthetic move event if we're not at the position of the event"<br>
filteredEvent position = self position<br>
ifFalse: [self moveToEvent: filteredEvent].<br>
<br>
"Drop submorphs on button events"<br>
self hasSubmorphs<br>
ifTrue:[self dropMorphs: filteredEvent]<br>
ifFalse:[self sendMouseEvent: filteredEvent].<br>
<br>
self mouseOverHandler processMouseOver: lastMouseEvent.<br>
^ filteredEvent "not necessary but good style -- see Morph >> #handleEvent:" !<br>
<br>
Item was removed:<br>
- ----- Method: MouseWheelEvent>>setDirection (in category 'initialization') -----<br>
- setDirection<br>
- delta x > 0 ifTrue: [self setWheelRight].<br>
- delta x < 0 ifTrue: [self setWheelLeft].<br>
- <br>
- delta y > 0 ifTrue: [self setWheelUp].<br>
- delta y < 0 ifTrue: [self setWheelDown].!<br>
<br>
Item was removed:<br>
- ----- Method: MouseWheelEvent>>setType:position:delta:buttons:hand:stamp: (in category 'private') -----<br>
- setType: evtType position: evtPos delta: evtDelta buttons: evtButtons hand: evtHand stamp: stamp<br>
- type := evtType.<br>
- position := evtPos.<br>
- buttons := evtButtons.<br>
- source := evtHand.<br>
- wasHandled := false.<br>
- direction := 2r0000.<br>
- delta := evtDelta.<br>
- timeStamp := stamp.<br>
- self setDirection!<br>
<br>
Item was added:<br>
+ Object subclass: #MouseWheelState<br>
+ instanceVariableNames: 'currentDelta'<br>
+ classVariableNames: ''<br>
+ poolDictionaries: ''<br>
+ category: 'Morphic-Events'!<br>
<br>
Item was added:<br>
+ ----- Method: MouseWheelState>>handleEvent:from: (in category 'event processing') -----<br>
+ handleEvent: aMouseWheelEvent from: aHand<br>
+ "Every 120 units, raise the wheel flags for convenient mouse wheel programming. We choose not to send multiple mouse-wheel events for multiples of 120 because applications can always react to the actual delta values if they want to do more scrolling
or zooming."<br>
+ <br>
+ | sign |<br>
+ currentDelta := currentDelta + aMouseWheelEvent wheelDelta.<br>
+ <br>
+ sign := currentDelta sign.<br>
+ currentDelta := currentDelta abs.<br>
+ <br>
+ (currentDelta x // 120) > 0 ifTrue: [<br>
+ sign x = 1<br>
+ ifTrue: [aMouseWheelEvent setWheelRight]<br>
+ ifFalse: [aMouseWheelEvent setWheelLeft]].<br>
+ <br>
+ (currentDelta y // 120) > 0 ifTrue: [<br>
+ sign y = 1<br>
+ ifTrue: [aMouseWheelEvent setWheelUp]<br>
+ ifFalse: [aMouseWheelEvent setWheelDown]].<br>
+ <br>
+ currentDelta := currentDelta \\ 120.<br>
+ currentDelta := currentDelta * sign.<br>
+ <br>
+ "Finally, send the event."<br>
+ HandMorph sendMouseWheelToKeyboardFocus<br>
+ ifFalse: [aHand sendMouseEvent: aMouseWheelEvent]<br>
+ ifTrue: [aHand sendEvent: aMouseWheelEvent focus: aHand keyboardFocus clear: [aHand keyboardFocus: nil]].<br>
+ !<br>
<br>
Item was added:<br>
+ ----- Method: MouseWheelState>>initialize (in category 'initialize-release') -----<br>
+ initialize<br>
+ <br>
+ super initialize.<br>
+ currentDelta := 0@0.!<br>
<br>
Item was changed:<br>
----- Method: PluggableListMorph>>mouseUp: (in category 'event handling') -----<br>
mouseUp: event <br>
<br>
| row |<br>
model okToChange ifFalse: [^ self].<br>
+ (self containsPoint: event position) ifFalse: [^ self].<br>
<br>
row := self rowAtLocation: event position.<br>
row = self selectionIndex<br>
ifTrue: [(autoDeselect ifNil: [true]) ifTrue: [row = 0 ifFalse: [self changeModelSelection: 0] ]]<br>
ifFalse: [self changeModelSelection: (self modelIndexFor: row)].<br>
<br>
event hand newKeyboardFocus: self. <br>
hasFocus := true.<br>
Cursor normal show.!<br>
<br>
Item was changed:<br>
----- Method: ScrollPane>>mouseWheel: (in category 'event handling') -----<br>
mouseWheel: evt<br>
<br>
+ evt isWheelUp ifTrue: [scrollBar scrollUp: 3].<br>
+ evt isWheelDown ifTrue: [scrollBar scrollDown: 3].!<br>
- evt isWheelUp ifTrue: [scrollBar scrollUp: (3 * evt wheelDelta y abs // 120 max: 1)].<br>
- evt isWheelDown ifTrue: [scrollBar scrollDown: (3 * evt wheelDelta y abs // 120 max: 1)].<br>
- evt isWheelLeft ifTrue: [hScrollBar scrollUp: (3 * evt wheelDelta x abs // 120 max: 1)].<br>
- evt isWheelRight ifTrue: [hScrollBar scrollDown: (3 * evt wheelDelta x abs // 120 max: 1)].!<br>
<br>
Item was changed:<br>
----- Method: StringMorph>>contents: (in category 'accessing') -----<br>
contents: newContents <br>
<br>
newContents isText<br>
ifTrue: [^ self initializeFromText: newContents].<br>
<br>
contents = newContents<br>
+ ifTrue: [^ self "No substantive change."].<br>
- ifTrue: [^ self "no substantive change"].<br>
<br>
contents := newContents.<br>
+ self changed. "New contents need to be drawn."<br>
+ <br>
+ self fitContents. "Resize if necessary."!<br>
- <br>
- self fitContents.!<br>
<br>
Item was changed:<br>
----- Method: StringMorph>>fitContents (in category 'layout') -----<br>
fitContents<br>
<br>
+ self extent: self measureContents.!<br>
- | newBounds boundsChanged |<br>
- newBounds := self measureContents.<br>
- boundsChanged := bounds extent ~= newBounds.<br>
- self extent: newBounds. "default short-circuits if bounds not changed"<br>
- boundsChanged ifFalse: [self changed]!<br>
<br>
Item was removed:<br>
- ----- Method: SystemProgressMorph class>>applyUserInterfaceTheme (in category 'preferences') -----<br>
- applyUserInterfaceTheme<br>
- <br>
- self reset.!<br>
<br>
Item was added:<br>
+ ----- Method: SystemProgressMorph>>canApplyUserInterfaceTheme (in category 'updating') -----<br>
+ canApplyUserInterfaceTheme<br>
+ <br>
+ ^ true!<br>
<br>
Item was changed:<br>
----- Method: UpdatingStringMorph>>fitContents (in category 'layout') -----<br>
fitContents<br>
+ "Overridden to respect minimum and maximum widfth."<br>
+ <br>
- <br>
| newExtent |<br>
+ newExtent := self measureContents.<br>
+ self extent: ((newExtent x max: self minimumWidth) min: self maximumWidth) @ newExtent y.!<br>
- newExtent := self measureContents.<br>
- newExtent := ((newExtent x max: self minimumWidth) min: self maximumWidth) @ newExtent y.<br>
- (self extent = newExtent) ifFalse:<br>
- [self extent: newExtent.<br>
- self changed]<br>
- !<br>
<br>
Item was changed:<br>
----- Method: UpdatingStringMorph>>updateContentsFrom: (in category 'stepping') -----<br>
updateContentsFrom: aValue<br>
self growable<br>
ifTrue:<br>
+ [self contentsFitted: aValue]<br>
- [self contents: aValue]<br>
ifFalse:<br>
[self contentsClipped: aValue]!<br>
<br>
<br>
</div>
</span></font>
</body>
</html>