[squeak-dev] The Inbox: Morphic-ct.1999.mcz

commits at source.squeak.org commits at source.squeak.org
Thu May 26 20:03:15 UTC 2022

A new version of Morphic was added to project The Inbox:

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

Name: Morphic-ct.1999
Author: ct
Time: 26 May 2022, 10:03:07.52347 pm
UUID: 0e5a40e5-675c-6f45-a908-6423f87d56a9
Ancestors: Morphic-tonyg.1997

Proposal to fix halo transfer for sibling morph in front of common sibling.

Here is an example:

	(Morph newBounds: (100 asPoint rect: 300 asPoint) color: Color blue) openInWorld.
	(Morph newBounds: (80 asPoint rect: 150 asPoint) color: Color red) openInWorld.
	(Morph newBounds: (250 asPoint rect: 350 asPoint) color: Color yellow) openInWorld

Blue-click the yellow morph to open a halo on it, then blue-click the red morph to transfer the halo. Without this patch, instead of the red morph, the blue morph receives the halo.

Could this ever be an expected behavior? I don't think so - this setting has confused me for months or maybe years, as the common background morph is often not easy to recognize, and I use blue-drag frequently to rearrange my windows in the world. (What we, however, independently of this patch, might want to consider is whether halo transfer should always start in the owner of the current morph, so that you could easier transfer an open halo on one button in a row to a sibling button.) Please discuss. Given the controversial potential of this patch, it might be a better idea not to include it into the ongoing release.

=============== Diff against Morphic-tonyg.1997 ===============

Item was changed:
  ----- Method: MorphicHaloDispatcher>>dispatchHalo:createFor: (in category 'dispatching') -----
  dispatchHalo: anEvent createFor: aContainer
  	"Invoke a halo on any aContainer's submorph that wants it. Dispatch uses anEvent's #position. The dispatch only ends in that container if no other morph wants it. Note that the event's #shiftPressed state determines whether the dispatch goes innermost-to-outermost (if pressed) or the other way around (if not pressed).
  	If there already is a halo, check whether the event still points into the same hierarchy. If it does, do nothing here but rely on the halo itself to process the event (see implementors of #transferHalo:from:). If, however, the event points to a different hierarchy in the container, invoke a new halo and discard the current one. We do this here because the current halo should not bother with its container but only its #target."
  	| stack innermost haloTarget |
  	"The stack is the frontmost (i.e. innermost) to backmost (i.e. outermost) morph."
  	stack := (aContainer morphsAt: anEvent position unlocked: true useFullBounds: true) select:
  		[ : each | each wantsHaloFromClick or: [ each isRenderer ] ].
  	"self assert: [ stack last == aContainer ]."
  	innermost := anEvent hand halo
  		ifNil: [ stack first ]
  			[ : existingHalo |
  			"self assert: [ existingHalo wantsHaloFromClick not ]. "
  				detect: [ : each | each owner == aContainer
  					and: [ existingHalo bounds intersects: (existingHalo haloBoundsFor: each) ] ]
  					[ : topInContainer | "Is existingHalo's target part of the same topInContainer as the morph clicked?"
  					(existingHalo target withAllOwners includes: topInContainer)
  						ifTrue: [ "same hierarchy, let #transferHalo: continue to handle it for now."  ^ false ]
  							[ "different hierarchy, remove + add."
  							anEvent hand removeHalo.
+ 							stack first ] ]
- 							anEvent shiftPressed
- 								ifTrue: [ stack first ]
- 								ifFalse: [ topInContainer ] ] ]
  				ifNone: [ "existingHalo is on the World, defer to #transferHalo: for now." ^ false ] ].
  	"If modifier key is pressed, start at innermost (the target), otherwise the outermost (direct child of the world (self))."
  	haloTarget := (innermost == aContainer or: [ anEvent shiftPressed ])
  		ifTrue: [ innermost ]
  			 [ "Find the outermost owner that wants it. Ignore containment above aContainer."
  			stack := innermost withAllOwners.
  			(stack first: (stack findFirst: [ : each | each owner == aContainer ])) reversed
  				detect: [ : each | each wantsHaloFromClick or: [ each isRenderer ] ]
  				ifNone: [ "haloTarget has its own mouseDown handler, don't halo."  ^ false ] ].
  	"Now that we have the haloTarget, show the halo."
  	self invokeHaloOrMove: anEvent on: haloTarget.
  	^ true!

More information about the Squeak-dev mailing list