Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1072.mcz
==================== Summary ====================
Name: Tools-mt.1072
Author: mt
Time: 23 November 2021, 2:07:24.430922 pm
UUID: a0289326-43fe-3148-b3e6-ec35b8155669
Ancestors: Tools-ct.1071
In code browsers, adds "browse trait users" to class-list menu when a trait is selected in the class list.
Note that the "*tools-traits" extension was already there. I considered adding a TraitsTools package but this here is easier for now.
Thanks to Christoph (ct) for the idea! See http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-October/216830.…
=============== Diff against Tools-ct.1071 ===============
Item was added:
+ ----- Method: Browser>>traitsMenu: (in category '*Tools-traits') -----
+ traitsMenu: aMenu
+ <classListMenuShifted: false>
+ <menuPriority: 140>
+
+ self selectedClass isTrait ifTrue: [
+ aMenu add: 'browse trait users' action: #browseTraitUsers].
+ ^ aMenu!
Item was added:
+ ----- Method: StringHolder>>browseTraitUsers (in category '*Tools-traits') -----
+ browseTraitUsers
+
+ self selectedClass ifNotNil: [:classOrTrait |
+ classOrTrait isTrait ifTrue: [self systemNavigation browseAllUsersOfTrait: classOrTrait]]
+ !
Item was added:
+ ----- Method: SystemNavigation>>allUsersOfTrait: (in category '*tools-traits') -----
+ allUsersOfTrait: aTrait
+
+ ^ aTrait users collect: [:class | MethodReference class: class selector: #Definition]!
Item was added:
+ ----- Method: SystemNavigation>>browseAllUsersOfTrait: (in category '*tools-traits') -----
+ browseAllUsersOfTrait: aTrait
+
+ ^ self
+ browseMessageList: [self allUsersOfTrait: aTrait]
+ name: 'Users of ', aTrait name!
Christoph Thiede uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1252.mcz
==================== Summary ====================
Name: System-ct.1252
Author: ct
Time: 22 November 2021, 6:47:47.026308 pm
UUID: 41cfb410-42cc-e44b-9c2d-9650f6c85866
Ancestors: System-ct.1251
Cleans up Preferences class >> #categoryList. The unclassified category has no special semantics when editing or accessing preferences. It is only added to every preference with zero categories by default. If there is any unclassified category, it will already contain #unclassified in its category list.
=============== Diff against System-ct.1251 ===============
Item was changed:
----- Method: Preferences class>>categoryList (in category 'support') -----
categoryList
"Return all available categories. No duplicates."
| aSet |
aSet := Set new.
self allPreferences do: [ :aPreference |
aSet addAll: (
aPreference categoryList collect: [ :aCategory |
aCategory asSymbol ]) ].
-
- aSet add: self unclassifiedCategory.
-
^aSet!
Christoph Thiede uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1251.mcz
==================== Summary ====================
Name: System-ct.1251
Author: ct
Time: 22 November 2021, 6:32:12.888308 pm
UUID: 7fb5f187-f812-0c40-9234-d7a6773c3ecd
Ancestors: System-ct.1250, System-ct.1243
Merges System-ct.1243 (categories an unclassified preference).
=============== Diff against System-ct.1250 ===============
Item was changed:
(PackageInfo named: 'System') postscript: '"Add the new primitive error codes to the specialObjectsArray if they are not there yet."
Smalltalk primitiveErrorTable size < 26 ifTrue:
+ [Smalltalk recreateSpecialObjectsArray].
+
+ (Preferences preferenceAt: #debugLogTimestamp) categoryList: #(''debug'').'!
- [Smalltalk recreateSpecialObjectsArray]'!
Christoph Thiede uploaded a new version of Morphic to project The Treated Inbox:
http://source.squeak.org/treated/Morphic-ct.1795.mcz
==================== Summary ====================
Name: Morphic-ct.1795
Author: ct
Time: 22 November 2021, 1:36:10.830759 pm
UUID: a529485a-fba0-134c-a5ad-8eb105313e13
Ancestors: Morphic-ct.1794
Proposal: Inverts the preference "halo encloses full bounds" by pressing the control key while invocating a halo.
Implementation notes: Extends the state of a halo with the current value of the full bounds behavior. Cleans up and deduplicates halo's bounds management. Depends indeed on Morphic-ct.1794 to for the fix of "halo encloses full bounds" during halo dispatching.
=============== Diff against Morphic-ct.1794 ===============
Item was changed:
----- Method: HaloMorph>>addCircleHandles (in category 'private') -----
addCircleHandles
| box |
simpleMode := false.
target isWorldMorph ifTrue: [^ self addHandlesForWorldHalos].
self removeAllMorphs. "remove old handles, if any"
+ self updateBounds.
- self bounds: target renderedMorph worldBoundsForHalo. "update my size"
box := self basicBox.
target addHandlesTo: self box: box.
self addName.
growingOrRotating := false.
self layoutChanged.
+ self changed.!
- self changed.
- !
Item was changed:
----- Method: HaloMorph>>addSimpleHandles (in category 'private') -----
addSimpleHandles
target isWorldMorph ifTrue: [^ self addHandlesForWorldHalos].
self removeAllMorphs. "remove old handles, if any"
+ self updateBounds.
- self bounds: target renderedMorph worldBoundsForHalo. "update my size"
self innerTarget addSimpleHandlesTo: self box: self basicBoxForSimpleHalos
!
Item was changed:
----- Method: HaloMorph>>addSimpleHandlesTo:box: (in category 'halos and balloon help') -----
addSimpleHandlesTo: aHaloMorph box: aBox
| aHandle |
simpleMode := true.
target isWorldMorph ifTrue: [^ self addSimpleHandlesForWorldHalos].
self removeAllMorphs. "remove old handles, if any"
+ self updateBounds.
- self bounds: target renderedMorph worldBoundsForHalo. "update my size"
self addHandleAt: (((aBox topLeft + aBox leftCenter) // 2) + self simpleFudgeOffset) color: Color paleBuff icon: 'Halo-MoreHandles'
on: #mouseDown send: #addFullHandles to: self.
aHandle := self addGraphicalHandle: #Rotate at: aBox bottomLeft on: #mouseDown send: #startRot:with: to: self.
aHandle on: #mouseMove send: #doRot:with: to: self.
(target isFlexMorph and: [target renderedMorph ~~ target])
ifTrue: [(self addGraphicalHandle: #Scale at: aBox bottomRight on: #mouseDown send: #startScale:with: to: self)
on: #mouseMove send: #doScale:with: to: self]
ifFalse: [(self addGraphicalHandle: #Scale at: aBox bottomRight on: #mouseDown send: #startGrow:with: to: self)
on: #mouseMove send: #doGrow:with: to: self].
innerTarget wantsSimpleSketchMorphHandles ifTrue:
[self addSimpleSketchMorphHandlesInBox: aBox].
growingOrRotating := false.
self layoutChanged.
+ self changed.!
- self changed.
- !
Item was changed:
----- Method: HaloMorph>>basicBoxForSimpleHalos (in category 'private') -----
basicBoxForSimpleHalos
| w |
w := self world ifNil:[target outermostWorldMorph].
+ ^ ((self haloBoundsFor: target topRendererOrSelf) expandBy: self handleAllowanceForIconicHalos)
- ^ (target topRendererOrSelf worldBoundsForHalo expandBy: self handleAllowanceForIconicHalos)
intersect: (w bounds insetBy: 8@8)
!
Item was changed:
----- Method: HaloMorph>>doResizeTarget: (in category 'dragging or resizing') -----
doResizeTarget: evt
| newExtent |
newExtent := originalExtent + (evt position - positionOffset * 2).
(newExtent x > 1 and: [ newExtent y > 1 ]) ifTrue:
[ | oldExtent dockingBarBottom newPosition |
oldExtent := target extent.
dockingBarBottom := owner mainDockingBars
inject: 0
into: [ : bottomMostBottom : each | bottomMostBottom max: each bottom ].
target setExtentFromHalo: (newExtent min: owner extent x @ (owner extent y - dockingBarBottom)).
newPosition := target position - (target extent - oldExtent // 2).
newPosition := (newPosition x
min: owner extent x - newExtent x
max: 0) @
(newPosition y
min: owner extent y - newExtent y
max: dockingBarBottom).
target
setConstrainedPosition: newPosition
hangOut: true ].
+ self updateBounds.!
- self bounds: self target worldBoundsForHalo!
Item was changed:
----- Method: HaloMorph>>localHaloBoundsFor: (in category 'stepping') -----
localHaloBoundsFor: aMorph
"aMorph may be in the hand and perhaps not in our world"
| r |
+ r := (self haloBoundsFor: aMorph) truncated.
- r := aMorph worldBoundsForHalo truncated.
aMorph world = self world ifFalse: [^r].
^((self transformFromOutermostWorld) globalBoundsToLocal: r) truncated!
Item was changed:
----- Method: Morph>>createHalo (in category 'halos and balloon help') -----
createHalo
+ ^ (Smalltalk at: self haloClass ifAbsent: [HaloMorph]) new!
- ^ (Smalltalk at: self haloClass ifAbsent: [HaloMorph]) new
- bounds: self worldBoundsForHalo
- yourself!
Item was changed:
----- Method: Morph>>worldBoundsForHalo (in category 'geometry - misc') -----
worldBoundsForHalo
- "Answer the rectangle to be used as the inner dimension of my halos.
- Allow for showing either bounds or fullBounds, and compensate for the optional bounds rectangle."
+ self deprecated.
+ ^ self worldBoundsForHalo: Preferences haloEnclosesFullBounds!
- | r |
- r := (Preferences haloEnclosesFullBounds)
- ifFalse: [ self boundsIn: nil ]
- ifTrue: [ self fullBoundsInWorld ].
- Preferences showBoundsInHalo ifTrue: [ ^r outsetBy: 2 ].
- ^r!
Item was added:
+ ----- Method: Morph>>worldBoundsForHalo: (in category 'geometry - misc') -----
+ worldBoundsForHalo: fullBounds
+ "Answer the rectangle to be used as the inner dimension of my halos.
+ Allow for showing either bounds or fullBounds, and compensate for the optional bounds rectangle."
+
+ ^ fullBounds
+ ifFalse: [ self boundsIn: nil ]
+ ifTrue: [ self fullBoundsInWorld ].!
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:
[ : 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 ]. "
+ existingHalo initializeEnclosesFullBounds: anEvent.
stack
detect: [ : each | each owner == aContainer
+ and: [ existingHalo bounds intersects: (existingHalo haloBoundsFor: each) ] ]
- and: [ existingHalo bounds intersects: each worldBoundsForHalo ] ]
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!
Item was changed:
Morph subclass: #SimpleHaloMorph
+ instanceVariableNames: 'target positionOffset enclosesFullBounds'
- instanceVariableNames: 'target positionOffset'
classVariableNames: ''
poolDictionaries: ''
category: 'Morphic-Widgets'!
!SimpleHaloMorph commentStamp: 'mt 11/6/2015 09:59' prior: 0!
This is a simple base class for halos in the system. It represents the minimal interface used to implement custom halo morphs.
It provides:
- event handling code to invoke and transfer a halo when clicking the meta-button (blue)
- move the halo's target (morph) when click-hold-drag the meta-button
- one close button as a minimal handle (see #addHandles)
In general, the halo concept consists of one dedicated user interaction (meta-button click) to invoke an additional, interactive view (the halo) for any morph. This interactive view is itself a morph that can have submorphs (e.g. buttons or text fields) to enrich the target morph. Besides button-based interactions (e.g. resize, move, duplicate, etc.), this could also be used to show other, even domain-specific, information.
Use the halo concept to provide means to explore and modify interactive, graphical elements in Squeak and your application. You can benefit from this concept without wasting additional screen space. In non-Squeak applications, the meta-key (typically the mouse-wheel button) is often without real functionality for the user. There, it makes scrolling more convenient---at best. In Squeak, you can easily take advantage of this button click.
Notice that direct user input is very limited. Many keyboard shortcuts (such as [ctrl]+[c]) are already pre-defined and should not be remapped for your domain-specific applications to avoid user confusion. Key chords (such as [ctrl]+[alt]+[v], [a] from Visual Studio) have to be learned with great effort.
The left mouse click (red) selects something.
The right mouse click (yellow) invokes a context menu.
Only the middle click, the meta-key, the blue button, is unused in many environments.
This is where the halo concept comes in.
[For two- or single-button mice, the meta-key can be simulated.]!
Item was changed:
----- Method: SimpleHaloMorph>>doDragTarget: (in category 'dragging') -----
doDragTarget: event
self target
setConstrainedPosition: (self target point: (event position - self positionOffset) from: self owner)
hangOut: true.
+ self updateBounds.!
- self bounds: self target worldBoundsForHalo.!
Item was added:
+ ----- Method: SimpleHaloMorph>>enclosesFullBounds (in category 'accessing') -----
+ enclosesFullBounds
+
+ ^ enclosesFullBounds!
Item was added:
+ ----- Method: SimpleHaloMorph>>enclosesFullBounds: (in category 'accessing') -----
+ enclosesFullBounds: aBoolean
+
+ enclosesFullBounds := aBoolean.!
Item was added:
+ ----- Method: SimpleHaloMorph>>haloBoundsFor: (in category 'initialization') -----
+ haloBoundsFor: aMorph
+
+ | rect |
+ rect := aMorph worldBoundsForHalo: self enclosesFullBounds.
+
+ Preferences showBoundsInHalo ifFalse: [^ rect].
+ ^ rect outsetBy: 2!
Item was changed:
----- Method: SimpleHaloMorph>>initialize (in category 'initialization') -----
initialize
super initialize.
self morphicLayerNumber: self class haloLayer.
"Each halo is a (kind of global) overlay that should not be bothered with the world's current layout policy. For example, a halo must match the target's bounds, which can be any inner part of the graphical hierarchy."
+ self disableLayout: true.
+
+ self initializeEnclosesFullBounds.!
- self disableLayout: true.!
Item was added:
+ ----- Method: SimpleHaloMorph>>initializeEnclosesFullBounds (in category 'initialization') -----
+ initializeEnclosesFullBounds
+
+ ^ self initializeEnclosesFullBounds: self currentEvent!
Item was added:
+ ----- Method: SimpleHaloMorph>>initializeEnclosesFullBounds: (in category 'initialization') -----
+ initializeEnclosesFullBounds: anEvent
+
+ self enclosesFullBounds: (Preferences haloEnclosesFullBounds xor: anEvent controlKeyPressed).!
Item was added:
+ ----- Method: SimpleHaloMorph>>updateBounds (in category 'updating') -----
+ updateBounds
+
+ self bounds: (self haloBoundsFor: self target).!
Christoph Thiede uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-ct.1798.mcz
==================== Summary ====================
Name: Morphic-ct.1798
Author: ct
Time: 22 November 2021, 4:27:18.413933 pm
UUID: a6a8cfa0-add2-e947-80bc-88097d156d9b
Ancestors: Morphic-mt.1797
Documents an insane halo mouse gesture for resizing morphs. (Hold Ctrl while dragging the blue button on a morph to resize it.)
=============== Diff against Morphic-mt.1797 ===============
Item was changed:
----- Method: Morph>>balloonHelpTextForHandle: (in category 'halos and balloon help') -----
balloonHelpTextForHandle: aHandle
"Answer a string providing balloon help for the
given halo handle"
| itsSelector |
itsSelector := aHandle eventHandler firstMouseSelector.
itsSelector == #doRecolor:with:
ifTrue: [^ Preferences propertySheetFromHalo
ifTrue: ['Open a property sheet.']
ifFalse: ['Change color']].
itsSelector == #mouseDownInDimissHandle:with:
ifTrue: [^ TrashCanMorph preserveTrash
ifTrue: ['Move to trash']
ifFalse: ['Remove from screen']].
+ #(#(#addFullHandles 'More halo handles') #(#addSimpleHandles 'Fewer halo handles') #(#chooseEmphasisOrAlignment 'Emphasis & alignment') #(#chooseFont 'Change font') #(#chooseNewGraphicFromHalo 'Choose a new graphic') #(#chooseStyle 'Change style') #(#dismiss 'Remove') #(#doDebug:with: 'Debug') #(#doDirection:with: 'Choose forward direction') #(#doDup:with: 'Duplicate') #(#doMakeSibling:with: 'Make a sibling') #(#doMenu:with: 'Menu') #(#doGrab:with: 'Pick up') #(#editButtonsScript 'See the script for this button') #(#editDrawing 'Repaint') #(#doDupOrMakeSibling:with: 'Duplicate (press shift to make a sibling)') #(#doMakeSiblingOrDup:with: 'Make a sibling (press shift to make simple duplicate)') #(#makeNascentScript 'Make a scratch script') #(#makeNewDrawingWithin 'Paint new object') #(#mouseDownInCollapseHandle:with: 'Collapse') #(#mouseDownOnHelpHandle: 'Help') #(#openViewerForArgument 'Open a Viewer for me. Press shift for a snapshot.') #(#openViewerForTarget:with: 'Open a Viewer
for me. Press shift for a snapshot.') #(#paintBackground 'Paint background') #(#prepareToTrackCenterOfRotation:with: 'Move object or set center of rotation') #(#presentViewMenu 'Present the Viewing menu') #(#startDrag:with: 'Move') #(#startGrow:with: 'Change size (Ctrl + drag blue button)') #(#startRot:with: 'Rotate') #(#startScale:with: 'Change scale') #(#tearOffTile 'Make a tile representing this object') #(#tearOffTileForTarget:with: 'Make a tile representing this object') #(#trackCenterOfRotation:with: 'Set center of rotation') )
- #(#(#addFullHandles 'More halo handles') #(#addSimpleHandles 'Fewer halo handles') #(#chooseEmphasisOrAlignment 'Emphasis & alignment') #(#chooseFont 'Change font') #(#chooseNewGraphicFromHalo 'Choose a new graphic') #(#chooseStyle 'Change style') #(#dismiss 'Remove') #(#doDebug:with: 'Debug') #(#doDirection:with: 'Choose forward direction') #(#doDup:with: 'Duplicate') #(#doMakeSibling:with: 'Make a sibling') #(#doMenu:with: 'Menu') #(#doGrab:with: 'Pick up') #(#editButtonsScript 'See the script for this button') #(#editDrawing 'Repaint') #(#doDupOrMakeSibling:with: 'Duplicate (press shift to make a sibling)') #(#doMakeSiblingOrDup:with: 'Make a sibling (press shift to make simple duplicate)') #(#makeNascentScript 'Make a scratch script') #(#makeNewDrawingWithin 'Paint new object') #(#mouseDownInCollapseHandle:with: 'Collapse') #(#mouseDownOnHelpHandle: 'Help') #(#openViewerForArgument 'Open a Viewer for me. Press shift for a snapshot.') #(#openViewerForTarget:with: 'Open a Viewer
for me. Press shift for a snapshot.') #(#paintBackground 'Paint background') #(#prepareToTrackCenterOfRotation:with: 'Move object or set center of rotation') #(#presentViewMenu 'Present the Viewing menu') #(#startDrag:with: 'Move') #(#startGrow:with: 'Change size') #(#startRot:with: 'Rotate') #(#startScale:with: 'Change scale') #(#tearOffTile 'Make a tile representing this object') #(#tearOffTileForTarget:with: 'Make a tile representing this object') #(#trackCenterOfRotation:with: 'Set center of rotation') )
do: [:pair | itsSelector == pair first
ifTrue: [^ pair last]].
^ 'unknown halo handle'translated!
Christoph Thiede uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ct.1242.mcz
==================== Summary ====================
Name: System-ct.1242
Author: ct
Time: 3 October 2021, 3:03:42.480874 pm
UUID: 65b8dbdb-0855-2440-bec4-b96c5d72468a
Ancestors: System-mt.1241
Adds missing standard query to Preferences.
=============== Diff against System-mt.1241 ===============
Item was added:
+ ----- Method: Preferences class>>allowEtoyUserCustomEvents (in category 'standard queries') -----
+ allowEtoyUserCustomEvents
+ ^ self
+ valueOfFlag: #allowEtoyUserCustomEvents
+ ifAbsent: [false]!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1797.mcz
==================== Summary ====================
Name: Morphic-mt.1797
Author: mt
Time: 22 November 2021, 3:52:20.61133 pm
UUID: 20ca4712-f68a-9649-84fd-20222029e155
Ancestors: Morphic-ct.1796
Adds check to avoid image freeze when trying to add your owner as a submorph. Thanks to Jens Lincke (jl)!!! Long time squeaker by heart. :-)
Note that I kept the style of error reporting like the existing range check. Needs to be improved. Maybe like Collection's #error* messages.
=============== Diff against Morphic-ct.1796 ===============
Item was changed:
----- Method: Morph>>privateAddAllMorphs:atIndex: (in category 'private') -----
privateAddAllMorphs: aCollection atIndex: index
"Private. Add aCollection of morphs to the receiver"
| myWorld otherSubmorphs offset |
(index between: 1 and: submorphs size+1)
ifFalse: [^ self error: 'index out of range'].
+ (aCollection anySatisfy: [:newMorph | self hasOwner: newMorph])
+ ifTrue: [^ self error: 'tried to add your (indirect) owner as new submorph'].
+ myWorld := self world.
- myWorld := self world.
otherSubmorphs := submorphs copyWithoutAll: aCollection.
offset := aCollection count: [:m | (submorphs indexOf: m) between: 1 and: index - 1].
submorphs := otherSubmorphs copyReplaceFrom: index-offset to: index-offset-1 with: aCollection.
aCollection do: [:m | | itsOwner itsWorld |
itsOwner := m owner.
itsOwner ifNotNil: [
itsWorld := m world.
(itsWorld == myWorld) ifFalse: [
itsWorld ifNotNil: [self privateInvalidateMorph: m].
m outOfWorld: itsWorld].
(itsOwner ~~ self) ifTrue: [
m owner privateRemove: m.
m owner removedMorph: m ]].
m privateOwner: self.
myWorld ifNotNil: [self privateInvalidateMorph: m].
(myWorld == itsWorld) ifFalse: [m intoWorld: myWorld].
itsOwner == self ifFalse: [
self addedMorph: m.
m noteNewOwner: self ].
].
self layoutChanged.
!
Item was changed:
----- Method: Morph>>privateAddMorph:atIndex: (in category 'private') -----
privateAddMorph: aMorph atIndex: index
| oldIndex myWorld itsWorld oldOwner |
+
((index >= 1) and: [index <= (submorphs size + 1)])
ifFalse: [^ self error: 'index out of range'].
+ (self hasOwner: aMorph)
+ ifTrue: [^ self error: 'tried to add your (indirect) owner as new submorph'].
myWorld := self world.
oldOwner := aMorph owner.
(oldOwner == self and: [(oldIndex := submorphs indexOf: aMorph) > 0]) ifTrue:[
"aMorph's position changes within in the submorph chain"
oldIndex < index ifTrue:[
"moving aMorph to back"
submorphs replaceFrom: oldIndex to: index-2 with: submorphs startingAt: oldIndex+1.
submorphs at: index-1 put: aMorph.
] ifFalse:[
"moving aMorph to front"
oldIndex-1 to: index by: -1 do:[:i|
submorphs at: i+1 put: (submorphs at: i)].
submorphs at: index put: aMorph.
].
] ifFalse:[
"adding a new morph"
oldOwner ifNotNil:[
itsWorld := aMorph world.
itsWorld ifNotNil: [self privateInvalidateMorph: aMorph].
(itsWorld == myWorld) ifFalse: [aMorph outOfWorld: itsWorld].
oldOwner privateRemove: aMorph.
oldOwner removedMorph: aMorph.
].
aMorph privateOwner: self.
submorphs := submorphs copyReplaceFrom: index to: index-1 with: (Array with: aMorph).
(itsWorld == myWorld) ifFalse: [aMorph intoWorld: myWorld].
].
myWorld ifNotNil:[self privateInvalidateMorph: aMorph].
self layoutChanged.
oldOwner == self ifFalse: [
self addedMorph: aMorph.
aMorph noteNewOwner: self ].
!
Item was changed:
(PackageInfo named: 'Morphic') postscript: 'SystemProgressMorph reset. "New layer number"
+ "Morphic-ct.1796 - Inverts the preference ''halo encloses full bounds'' by pressing the control key while invocating a halo."
+ (Preferences preferenceAt: #haloEnclosesFullBounds) instVarNamed: ''helpString'' put: ''If enabled, halos will enclose the full bounds of the target morph, rather than just the bounds. You can also invert this behavior temporarily by holding down Ctrl while invoking a halo on a morph.''.'!
- "Morphic-ct.1796 - Inverts the preference "halo encloses full bounds" by pressing the control key while invocating a halo."
- (Preferences preferenceAt: #haloEnclosesFullBounds) instVarNamed: ''helpString'' put: ''If enabled, halos will enclose the full bounds of the target morph, rather than just the bounds. You can also invert this behavior temporarily by holding down Ctrl while invoking a halo'' on a morph.''.'!