The Trunk: Morphic-mt.1445.mcz

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

The Trunk: Morphic-mt.1445.mcz

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

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

Name: Morphic-mt.1445
Author: mt
Time: 31 May 2018, 10:32:00.706975 am
UUID: 5bb479eb-ac7f-4d42-a614-96468d8dd517
Ancestors: Morphic-mt.1444

Refactor the halo-navigation improvement from Morphic-cmm.1443. The actual change is not in the initial halo invocation but in the transferring of halos between morphs. Thus, still exit the event filter in PasteUpMorph as early as possible to just deal with regular event dispatch. See the line "anEvent hand halo ifNotNil: [^ self]" in #tryInvokeHalo.

=============== Diff against Morphic-mt.1444 ===============

Item was changed:
  ----- Method: PasteUpMorph>>tryInvokeHalo: (in category 'events-processing') -----
+ tryInvokeHalo: anEvent
+
+ | innerMost target |
+ anEvent hand halo ifNotNil: [^ self "No invocation needed. Halo will handle transfer itself."].
+ Preferences noviceMode ifTrue: [^ self "No halo in novice mode."].
+ Morph haloForAll ifFalse: [^ self].
+
+ innerMost := (self morphsAt: anEvent position unlocked: true) first.
+
+ "1) Try to use innermost morph but skip all the ones that do not want to show a halo along the owner chain."
+ target := innerMost.
+ [target isNil or: [target wantsHaloFromClick]]
+ whileFalse: [target := target owner].
+ target ifNil: [^ self].
+
+ "2) Without a modifier, which is normal, find the outermost container for that inner morph."
+ (innerMost == self or: [anEvent shiftPressed]) ifFalse: [
+ | previousTargets |
+ previousTargets := OrderedCollection new.
+ [target notNil and: [target owner ~~ self]] whileTrue: [
+ previousTargets add: target.
+ target := target owner].
+ target ifNil: [^ self].
+ [previousTargets isEmpty or: [target wantsHaloFromClick]] whileFalse: [
+ target := previousTargets removeLast].
+ target wantsHaloFromClick ifFalse: [^ self]].
+
+ "3) Now that we have the target, show the halo. Abort event dispatching, too, to avoid confusion."
+ anEvent hand newMouseFocus: target event: anEvent.
+ target invokeHaloOrMove: anEvent.
+ anEvent ignore.!
- tryInvokeHalo: aUserInputEvent
- "Invoke halos around the top-most world container at aUserInputEvent's #position.  If it was already halo'd, zero-in on its next inward component morph at that position.  Holding Shift during the click reverses this traversal order."
- | stack target owners |
- Preferences noviceMode ifTrue: [^self ].
- Morph haloForAll ifFalse: [^self].
- "the stack is the top-most morph to bottom-most."
- stack := (self morphsAt: aUserInputEvent position unlocked: true) select: [ : each | each wantsHaloFromClick ].
- stack ifEmpty: [^self].
- target :=
- aUserInputEvent hand halo
- ifNil: [ stack first ]
- ifNotNil:
- [ : existingHalo |
- stack allButFirst "halo's are always topmost on the stack"
- detect: [ : each | each owner == self ]
- ifFound:
- [ : topMostWhereClicked |
- (existingHalo target withAllOwners includes: topMostWhereClicked)
- ifTrue: [ "No invocation needed. Halo will handle transfer itself." ^self ]
- ifFalse:
- [ "Transfer halo to new world container."
- aUserInputEvent hand removeHalo.
- aUserInputEvent shiftPressed
- ifTrue: [ stack second ]
- ifFalse: [ topMostWhereClicked ] ]  ]
- ifNone: ["Okay, invoke halos on the world." self ]  ].
- "With a modifier, we want the innermost, otherwise the outermost."
- owners := target withAllOwners select: [ : each | each wantsHaloFromClick ].
- "the last owner is expected to be self."
- target := aUserInputEvent shiftPressed ifTrue: [ owners first ] ifFalse: [ owners at: owners size-1 ifAbsent: [self] ].
- "Now that we have the target, show the halo. Abort event dispatching, too, to avoid confusion."
- aUserInputEvent hand newMouseFocus: target event: aUserInputEvent.
- target invokeHaloOrMove: aUserInputEvent.
- "aUserInputEvent has been consumed, don't let it cause any further side-effects."
- aUserInputEvent ignore!

Item was changed:
  ----- Method: SimpleHaloMorph>>transferHalo: (in category 'pop up') -----
  transferHalo: event
+ "Transfer the halo to the next likely recipient. Switch between siblings if overlapping."
- "Transfer the halo to the next likely recipient"
 
+ (self target world morphsAt: event position) allButFirst "... the halo itself"
+ detect: [:morph |
+ "Sibling found?"
+ (morph owner == self target owner
+ and: [morph ~~ self target])
+ ifTrue: [
+ ^ morph invokeHaloOrMove: event].
+ "No sibling possible anymore?"
+ morph == self target].
+
  self target
  transferHalo: (event transformedBy: (self target transformedFrom: self))
  from: self target.!


Reply | Threaded
Open this post in threaded view
|

Re: The Trunk: Morphic-mt.1445.mcz

Chris Muller-3
Hey Marcel,

I was wondering whether "transfer halo" is a useful first-class
abstraction to keep factored out above "remove"+"invoke" halo?

I was just thinking about some potential alternative uses of halos,
but the whole idea of "transfer" seems to get in the way...  For
example, it's hard to understand how "transfer" would fit in a world
where multiple objects could simply have their halos toggled on/off
independently?  Or, how would "transfer" fit if we wanted each Morph
to be able to provide its own custom set of halos?  They wouldn't want
a "transfer" of the other guys halos, but to "invoke" their own.

I know this may sound crazy, but would you be open to the idea of
seeing if we can get rid of the concept of "transfer" and just use
the elemental "remove" and "invoke" in its place?

Right now, the #tryInvokeHalo: (called from the event filter mech) is
tied in with distant code (regular event handler)... totally different
places, and we both know that's bad.  So if we could jettison the
"transfer" idea, maybe we could the code too, leaving it neatly all in
one place..?   What do you think?

Best,
  Chris



On Thu, May 31, 2018 at 3:32 AM,  <[hidden email]> wrote:

> Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
> http://source.squeak.org/trunk/Morphic-mt.1445.mcz
>
> ==================== Summary ====================
>
> Name: Morphic-mt.1445
> Author: mt
> Time: 31 May 2018, 10:32:00.706975 am
> UUID: 5bb479eb-ac7f-4d42-a614-96468d8dd517
> Ancestors: Morphic-mt.1444
>
> Refactor the halo-navigation improvement from Morphic-cmm.1443. The actual change is not in the initial halo invocation but in the transferring of halos between morphs. Thus, still exit the event filter in PasteUpMorph as early as possible to just deal with regular event dispatch. See the line "anEvent hand halo ifNotNil: [^ self]" in #tryInvokeHalo.
>
> =============== Diff against Morphic-mt.1444 ===============
>
> Item was changed:
>   ----- Method: PasteUpMorph>>tryInvokeHalo: (in category 'events-processing') -----
> + tryInvokeHalo: anEvent
> +
> +       | innerMost target |
> +       anEvent hand halo ifNotNil: [^ self "No invocation needed. Halo will handle transfer itself."].
> +       Preferences noviceMode ifTrue: [^ self "No halo in novice mode."].
> +       Morph haloForAll ifFalse: [^ self].
> +
> +       innerMost := (self morphsAt: anEvent position unlocked: true) first.
> +
> +       "1) Try to use innermost morph but skip all the ones that do not want to show a halo along the owner chain."
> +       target := innerMost.
> +       [target isNil or: [target wantsHaloFromClick]]
> +               whileFalse: [target := target owner].
> +       target ifNil: [^ self].
> +
> +       "2) Without a modifier, which is normal, find the outermost container for that inner morph."
> +       (innerMost == self or: [anEvent shiftPressed]) ifFalse: [
> +               | previousTargets |
> +               previousTargets := OrderedCollection new.
> +               [target notNil and: [target owner ~~ self]] whileTrue: [
> +                       previousTargets add: target.
> +                       target := target owner].
> +               target ifNil: [^ self].
> +               [previousTargets isEmpty or: [target wantsHaloFromClick]] whileFalse: [
> +                       target := previousTargets removeLast].
> +               target wantsHaloFromClick ifFalse: [^ self]].
> +
> +       "3) Now that we have the target, show the halo. Abort event dispatching, too, to avoid confusion."
> +       anEvent hand newMouseFocus: target event: anEvent.
> +       target invokeHaloOrMove: anEvent.
> +       anEvent ignore.!
> - tryInvokeHalo: aUserInputEvent
> -       "Invoke halos around the top-most world container at aUserInputEvent's #position.  If it was already halo'd, zero-in on its next inward component morph at that position.  Holding Shift during the click reverses this traversal order."
> -       | stack target owners |
> -       Preferences noviceMode ifTrue: [^self ].
> -       Morph haloForAll ifFalse: [^self].
> -       "the stack is the top-most morph to bottom-most."
> -       stack := (self morphsAt: aUserInputEvent position unlocked: true) select: [ : each | each wantsHaloFromClick ].
> -       stack ifEmpty: [^self].
> -       target :=
> -               aUserInputEvent hand halo
> -                       ifNil: [ stack first ]
> -                       ifNotNil:
> -                               [ : existingHalo |
> -                               stack allButFirst "halo's are always topmost on the stack"
> -                                       detect: [ : each | each owner == self ]
> -                                       ifFound:
> -                                               [ : topMostWhereClicked |
> -                                               (existingHalo target withAllOwners includes: topMostWhereClicked)
> -                                                       ifTrue: [ "No invocation needed. Halo will handle transfer itself." ^self ]
> -                                                       ifFalse:
> -                                                               [ "Transfer halo to new world container."
> -                                                               aUserInputEvent hand removeHalo.
> -                                                               aUserInputEvent shiftPressed
> -                                                                       ifTrue: [ stack second ]
> -                                                                       ifFalse: [ topMostWhereClicked ] ]  ]
> -                                       ifNone: ["Okay, invoke halos on the world." self ]  ].
> -       "With a modifier, we want the innermost, otherwise the outermost."
> -       owners := target withAllOwners select: [ : each | each wantsHaloFromClick ].
> -       "the last owner is expected to be self."
> -       target := aUserInputEvent shiftPressed ifTrue: [ owners first ] ifFalse: [ owners at: owners size-1 ifAbsent: [self] ].
> -       "Now that we have the target, show the halo. Abort event dispatching, too, to avoid confusion."
> -       aUserInputEvent hand newMouseFocus: target event: aUserInputEvent.
> -       target invokeHaloOrMove: aUserInputEvent.
> -       "aUserInputEvent has been consumed, don't let it cause any further side-effects."
> -       aUserInputEvent ignore!
>
> Item was changed:
>   ----- Method: SimpleHaloMorph>>transferHalo: (in category 'pop up') -----
>   transferHalo: event
> +       "Transfer the halo to the next likely recipient. Switch between siblings if overlapping."
> -       "Transfer the halo to the next likely recipient"
>
> +       (self target world morphsAt: event position) allButFirst "... the halo itself"
> +               detect: [:morph |
> +                       "Sibling found?"
> +                       (morph owner == self target owner
> +                               and: [morph ~~ self target])
> +                                       ifTrue: [
> +                                               ^ morph invokeHaloOrMove: event].
> +                       "No sibling possible anymore?"
> +                       morph == self target].
> +
>         self target
>                 transferHalo: (event transformedBy: (self target transformedFrom: self))
>                 from: self target.!
>
>