[squeak-dev] The Trunk: Morphic-ct.1794.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Nov 22 12:59:41 UTC 2021


Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ct.1794.mcz

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

Name: Morphic-ct.1794
Author: ct
Time: 22 November 2021, 1:31:13.419759 pm
UUID: aa34a2c3-e57e-7148-ae6f-e308699ff311
Ancestors: Morphic-eem.1784

Makes it possible to open halos on protuding submorphs if the the preference "haloEnclosesFullBounds" is turned on. This was formerly impossible because #morphsAt:unlocked: would not ever consider the full bounds of a morph.

Given the significance of halos and the technical complexity of their invocation, I would prefer if a Morphic expert could take a short look at this first. Marcel? :-)

=============== Diff against Morphic-eem.1784 ===============

Item was changed:
  ----- Method: Morph>>morphsAt:unlocked: (in category 'submorphs - accessing') -----
  morphsAt: aPoint unlocked: aBool
+ 
+ 	^ self morphsAt: aPoint unlocked: aBool fullBounds: false!
- 	"Return a collection of all morphs in this morph structure that contain the given point, possibly including the receiver itself.  The order is deepest embedding first."
- 	| mList |
- 	mList := WriteStream on: #().
- 	self morphsAt: aPoint unlocked: aBool do:[:m| mList nextPut: m].
- 	^mList contents!

Item was changed:
  ----- Method: Morph>>morphsAt:unlocked:do: (in category 'submorphs - enumerating') -----
  morphsAt: aPoint unlocked: aBool do: aBlock
+ 
+ 	^ self morphsAt: aPoint unlocked: aBool fullBounds: false do: aBlock!
- 	"Evaluate aBlock with all the morphs starting at the receiver which appear at aPoint. If aBool is true take only visible, unlocked morphs into account."
- 	
- 	(self fullBounds containsPoint: aPoint) ifFalse:[^self].
- 	(aBool and:[self isLocked or:[self visible not]]) ifTrue:[^self].
- 	self submorphsDo:[:m| | tfm |
- 		tfm := m transformedFrom: self.
- 		m morphsAt: (tfm globalPointToLocal: aPoint) unlocked: aBool do: aBlock].
- 	(self containsPoint: aPoint) ifTrue:[aBlock value: self].!

Item was added:
+ ----- Method: Morph>>morphsAt:unlocked:fullBounds: (in category 'submorphs - accessing') -----
+ morphsAt: aPoint unlocked: unlocked fullBounds: fullBounds
+ 	"Return a collection of all morphs in this morph structure that contain the given point,  possibly including the receiver itself.  The order is deepest embedding first."
+ 	| mList |
+ 	mList := WriteStream on: #().
+ 	self morphsAt: aPoint unlocked: unlocked fullBounds: fullBounds do:[:m| mList nextPut: m].
+ 	^mList contents!

Item was added:
+ ----- Method: Morph>>morphsAt:unlocked:fullBounds:do: (in category 'submorphs - enumerating') -----
+ morphsAt: aPoint unlocked: unlocked fullBounds: fullBounds do: aBlock
+ 	"Evaluate aBlock with all the morphs starting at the receiver which appear at aPoint, honoring its #fullBounds if fullBounds is true. If unlocked is true take only visible, unlocked morphs into account."
+ 	
+ 	(self fullBounds containsPoint: aPoint) ifFalse:[^self].
+ 	(unlocked and:[self isLocked or:[self visible not]]) ifTrue:[^self].
+ 	self submorphsDo:[:m| | tfm |
+ 		tfm := m transformedFrom: self.
+ 		m
+ 			morphsAt: (tfm globalPointToLocal: aPoint)
+ 			unlocked: unlocked
+ 			fullBounds: fullBounds
+ 			do: aBlock].
+ 	(fullBounds
+ 		ifTrue: [self fullContainsPoint: aPoint]
+ 		ifFalse: [self containsPoint: aPoint])
+ 			ifTrue: [aBlock value: self].!

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 fullBounds: true) select:
- 	stack := (aContainer morphsAt: anEvent position unlocked: true) select:
  		[ : each | each wantsHaloFromClick or: [ each isRenderer ] ].
  	"self assert: [ stack last == aContainer ]."
  	innermost := anEvent hand halo
  		ifNil: [ stack first ]
  		ifNotNil:
  			[ : existingHalo |
  			"self assert: [ existingHalo wantsHaloFromClick not ]. "
  			stack
+ 				detect: [ : each | each owner == aContainer
+ 					and: [ existingHalo bounds intersects: each worldBoundsForHalo ] ]
- 				detect: [ : each | each owner == aContainer ]
  				ifFound:
  					[ : 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 ]
  						ifFalse:
  							[ "different hierarchy, remove + add."
  							anEvent hand removeHalo.
  							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 ]
  		ifFalse:
  			 [ "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