<div dir="ltr">I&#39;m getting a failed update:<div><br></div><div><div>This package depends on the following classes:</div><div>  NewBalloonMorph</div><div>You must resolve these dependencies before you will be able to load these definitions: </div><div>  NewBalloonMorph&gt;&gt;isBalloonHelp</div></div><div><br></div><div>latest update: #14275<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 31, 2015 at 2:38 AM,  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Marcel Taeumel uploaded a new version of Morphic to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Morphic-mt.794.mcz" target="_blank">http://source.squeak.org/trunk/Morphic-mt.794.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-mt.794<br>
Author: mt<br>
Time: 31 March 2015, 11:38:42.253 am<br>
UUID: 765a2201-af4c-0948-b90d-72414d335160<br>
Ancestors: Morphic-mt.793<br>
<br>
New-style balloon morph added and used. Can be switched back to old-style balloon morphs via preferences.<br>
<br>
New-style balloon morphs support:<br>
- text (not only strings)<br>
- layouting via text paragraph (not hard-cutted via: #noLineLongerThan:)<br>
- positioning at current hand position (if not supplied with other reference point)<br>
<br>
In general, new-style balloon morphs have an improved readability.<br>
<br>
=============== Diff against Morphic-mt.793 ===============<br>
<br>
Item was changed:<br>
  ----- Method: BalloonMorph class&gt;&gt;string:for:corner: (in category &#39;instance creation&#39;) -----<br>
  string: str for: morph corner: cornerName<br>
        &quot;Make up and return a balloon for morph. Find the quadrant that<br>
        clips the text the least, using cornerName as a tie-breaker. tk 9/12/97&quot;<br>
        | tm vertices |<br>
+       tm := self<br>
+               getTextMorph: (str asString withNoLineLongerThan: Preferences maxBalloonHelpLineLength)<br>
+               for: morph.<br>
-       tm := self getTextMorph: str for: morph.<br>
        vertices := self getVertices: tm bounds.<br>
        vertices := self<br>
                                getBestLocation: vertices<br>
                                for: morph<br>
                                corner: cornerName.<br>
        ^ self new color: morph balloonColor;<br>
                 setVertices: vertices;<br>
                 addMorph: tm;<br>
                 setTarget: morph!<br>
<br>
Item was changed:<br>
  ----- Method: MenuMorph&gt;&gt;showKeyboardHelp (in category &#39;keystroke helpers&#39;) -----<br>
  showKeyboardHelp<br>
<br>
        | help |<br>
+       help := self balloonMorphClass<br>
+               string: &#39;Enter text to narrow selection\down to matching items &#39; withCRs<br>
-       help := BalloonMorph<br>
-               string: &#39;Enter text to\narrow selection down\to matching items &#39; withCRs<br>
                for: self<br>
                corner: #topLeft.<br>
+       help popUpAt: self topCenter forHand: self activeHand!<br>
-       help popUpForHand: self activeHand!<br>
<br>
Item was added:<br>
+ ----- Method: Morph&gt;&gt;balloonMorphClass (in category &#39;halos and balloon help&#39;) -----<br>
+ balloonMorphClass<br>
+<br>
+       ^ NewBalloonMorph useNewBalloonMorph<br>
+               ifTrue: [NewBalloonMorph]<br>
+               ifFalse: [BalloonMorph]!<br>
<br>
Item was changed:<br>
  ----- Method: Morph&gt;&gt;showBalloon:hand: (in category &#39;halos and balloon help&#39;) -----<br>
  showBalloon: msgString hand: aHand<br>
        &quot;Pop up a balloon containing the given string,<br>
        first removing any existing BalloonMorphs in the world.&quot;<br>
<br>
        | w balloon h |<br>
        (w := self world) ifNil: [^ self].<br>
        h := aHand.<br>
        h ifNil:[<br>
                h := w activeHand].<br>
+       balloon := self balloonMorphClass<br>
+               string: msgString<br>
-       balloon := BalloonMorph<br>
-               string: (msgString asString withNoLineLongerThan: Preferences maxBalloonHelpLineLength)<br>
                for: self balloonHelpAligner.<br>
        balloon popUpFor: self hand: h.!<br>
<br>
Item was added:<br>
+ Morph subclass: #NewBalloonMorph<br>
+       instanceVariableNames: &#39;balloonOwner textMorph maximumWidth orientation hasTail&#39;<br>
+       classVariableNames: &#39;UseNewBalloonMorph&#39;<br>
+       poolDictionaries: &#39;&#39;<br>
+       category: &#39;Morphic-Widgets&#39;!<br>
+<br>
+ !NewBalloonMorph commentStamp: &#39;mt 3/31/2015 10:15&#39; prior: 0!<br>
+ A balloon is a bubble with an optional tail. It contains rich text, which describes something about its balloon-owner.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph class&gt;&gt;string:for: (in category &#39;instance creation&#39;) -----<br>
+ string: str for: morph<br>
+<br>
+       ^ self string: str for: morph corner: #bottomLeft!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph class&gt;&gt;string:for:corner: (in category &#39;instance creation&#39;) -----<br>
+ string: message for: morph corner: symbol<br>
+<br>
+       ^ self new<br>
+               balloonOwner: morph;<br>
+               setText: message;<br>
+               orientation: symbol;<br>
+               yourself!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph class&gt;&gt;useNewBalloonMorph (in category &#39;preferences&#39;) -----<br>
+ useNewBalloonMorph<br>
+<br>
+       &lt;preference: &#39;Use new-style balloon morphs&#39;<br>
+               category: #Morphic<br>
+               description: &#39;The new-style balloon morphs are improved for better reading quality and support rich text.&#39;<br>
+               type: #Boolean&gt;<br>
+       ^ UseNewBalloonMorph ifNil: [true]!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph class&gt;&gt;useNewBalloonMorph: (in category &#39;preferences&#39;) -----<br>
+ useNewBalloonMorph: aBoolean<br>
+<br>
+       UseNewBalloonMorph := aBoolean.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;balloonOwner (in category &#39;accessing&#39;) -----<br>
+ balloonOwner<br>
+<br>
+       ^ balloonOwner!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;balloonOwner: (in category &#39;accessing&#39;) -----<br>
+ balloonOwner: aMorph<br>
+<br>
+       balloonOwner := aMorph.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;bubbleBounds (in category &#39;geometry&#39;) -----<br>
+ bubbleBounds<br>
+<br>
+       ^ self bounds insetBy: (0 @ self tailHeight corner: 0 @ self tailHeight)!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;bubbleInset (in category &#39;geometry&#39;) -----<br>
+ bubbleInset<br>
+<br>
+       ^ 5@2!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;defaultBorderColor (in category &#39;initialization&#39;) -----<br>
+ defaultBorderColor<br>
+<br>
+       ^ self defaultColor muchDarker&quot;Color black&quot;!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;defaultBorderWidth (in category &#39;initialization&#39;) -----<br>
+ defaultBorderWidth<br>
+<br>
+       ^ 1!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;defaultColor (in category &#39;initialization&#39;) -----<br>
+ defaultColor<br>
+<br>
+       ^ BalloonMorph balloonColor!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;drawDropShadowOn: (in category &#39;drawing&#39;) -----<br>
+ drawDropShadowOn: aCanvas<br>
+<br>
+       aCanvas<br>
+               translateBy: self shadowOffset<br>
+               during: [ :shadowCanvas |<br>
+                       (shadowCanvas isVisible: self bubbleBounds) ifTrue: [<br>
+                               self wantsRoundedCorners<br>
+                                       ifTrue: [shadowCanvas fillRoundRect: self bubbleBounds radius: self class preferredCornerRadius fillStyle: self shadowColor]<br>
+                                       ifFalse: [shadowCanvas fillRectangle: self bubbleBounds fillStyle: self shadowColor]].<br>
+<br>
+                               self hasTail ifTrue: [<br>
+                                       shadowCanvas<br>
+                                               drawPolygon: self verticesForTail<br>
+                                               fillStyle: self shadowColor]].<br>
+<br>
+ !<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;drawOn: (in category &#39;drawing&#39;) -----<br>
+ drawOn: aCanvas<br>
+<br>
+       &quot;Bubble.&quot;<br>
+       self wantsRoundedCorners<br>
+               ifTrue: [aCanvas<br>
+                       frameAndFillRoundRect: self bubbleBounds<br>
+                       radius: self class preferredCornerRadius fillStyle: self fillStyle borderWidth: self borderStyle width borderColor: self borderStyle color]<br>
+               ifFalse: [aCanvas<br>
+                       fillRectangle: self bubbleBounds<br>
+                       fillStyle: self fillStyle borderStyle: self borderStyle].<br>
+<br>
+       &quot;Tail.&quot;<br>
+       self hasTail ifTrue: [<br>
+               self verticesForTail in: [:points |<br>
+                       | pixelOffset |<br>
+                       pixelOffset := points first y &lt; points second y<br>
+                               ifFalse: [points first x &lt; points second x<br>
+                                       ifTrue: [self borderStyle width negated @ self borderStyle width] &quot;bottomLeft&quot;<br>
+                                       ifFalse: [self borderStyle width @ self borderStyle width]] &quot;bottomRight&quot;<br>
+                               ifTrue: [points first x &lt; points second x<br>
+                                       ifTrue: [self borderStyle width negated @ self borderStyle width negated] &quot;topLeft&quot;<br>
+                                       ifFalse: [self borderStyle width @ self borderStyle width negated]]. &quot;topRight&quot;<br>
+<br>
+                       aCanvas<br>
+                               drawPolygon: points<br>
+                               fillStyle: self fillStyle.<br>
+                       aCanvas<br>
+                               line: points first<br>
+                               to: points second + pixelOffset<br>
+                               width: self borderStyle width<br>
+                               color: self borderStyle color.<br>
+                       aCanvas<br>
+                               line: points first<br>
+                               to: points third + pixelOffset<br>
+                               width: self borderStyle width<br>
+                               color: self borderStyle color]]!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;hasTail (in category &#39;accessing&#39;) -----<br>
+ hasTail<br>
+<br>
+       ^ hasTail ifNil: [true]!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;hasTail: (in category &#39;accessing&#39;) -----<br>
+ hasTail: aBoolean<br>
+<br>
+       hasTail := aBoolean.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;initialize (in category &#39;initialization&#39;) -----<br>
+ initialize<br>
+<br>
+       super initialize.<br>
+<br>
+       self<br>
+               borderWidth: self defaultBorderWidth;<br>
+               borderColor: self defaultBorderColor;<br>
+               color: (self defaultColor alpha: 1.0); &quot;no alpha due to drop shadow&quot;<br>
+               hasDropShadow: true;<br>
+               shadowOffset: 1@1;<br>
+               shadowColor: (self color muchDarker muchDarker alpha: 0.333);<br>
+               orientation: #bottomLeft.<br>
+<br>
+       MenuMorph roundedMenuCorners<br>
+               ifTrue: [self cornerStyle: #rounded].<br>
+<br>
+       textMorph := TextMorph new<br>
+               wrapFlag: false;<br>
+               lock;<br>
+               yourself.<br>
+<br>
+       self addMorph: textMorph.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;maximumWidth (in category &#39;accessing&#39;) -----<br>
+ maximumWidth<br>
+<br>
+       ^ maximumWidth ifNil: [<br>
+               maximumWidth := (self balloonOwner balloonFont widthOf: $m) * Preferences maxBalloonHelpLineLength]!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;maximumWidth: (in category &#39;accessing&#39;) -----<br>
+ maximumWidth: anInteger<br>
+<br>
+       maximumWidth := anInteger.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;morphicLayerNumber (in category &#39;WiW support&#39;) -----<br>
+ morphicLayerNumber<br>
+<br>
+       &quot;helpful for insuring some morphs always appear in front of or behind others.<br>
+       smaller numbers are in front&quot;<br>
+<br>
+       ^5              &quot;Balloons are very front-like things&quot;!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;move: (in category &#39;geometry&#39;) -----<br>
+ move: targetPoint<br>
+<br>
+       self perform: (self orientation, #:) asSymbol with: targetPoint.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;orientation (in category &#39;accessing&#39;) -----<br>
+ orientation<br>
+       &quot;Encodes the position of the tail. #topLeft, #topRight, #bottomLeft, #bottomRight&quot;<br>
+<br>
+       ^ orientation!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;orientation: (in category &#39;accessing&#39;) -----<br>
+ orientation: aSymbol<br>
+<br>
+       orientation := aSymbol.<br>
+       self changed.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;popUpAt:forHand: (in category &#39;initialization&#39;) -----<br>
+ popUpAt: point forHand: aHand<br>
+       &quot;Pop up the receiver as balloon help for the given hand&quot;<br>
+<br>
+       #(bottomLeft bottomRight topLeft topRight) detect: [:nextOrientation |<br>
+               self orientation: nextOrientation.<br>
+               self move: point.<br>
+               self bounds: (self bounds translatedToBeWithin: aHand world bounds).<br>
+               (self bounds perform: self orientation) = point] ifNone: [&quot;Keep last try.&quot;].<br>
+<br>
+       aHand world addMorphFront: self.<br>
+       aHand balloonHelp: self.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;popUpFor:hand: (in category &#39;initialization&#39;) -----<br>
+ popUpFor: aMorph hand: aHand<br>
+       &quot;Pop up the receiver as balloon help for the given hand&quot;<br>
+<br>
+       self balloonOwner: aMorph.<br>
+       self popUpForHand: aHand.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;popUpForHand: (in category &#39;initialization&#39;) -----<br>
+ popUpForHand: aHand<br>
+<br>
+       self popUpAt: aHand position forHand: aHand.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;setText: (in category &#39;initialization&#39;) -----<br>
+ setText: stringOrText<br>
+<br>
+       | text |<br>
+       text := stringOrText asText.<br>
+       text addAttribute: (TextFontReference toFont: (self balloonOwner ifNil: [BalloonMorph]) balloonFont).<br>
+<br>
+       self textMorph wrapFlag: false.<br>
+       self textMorph newContents: text.<br>
+       self textMorph fullBounds.<br>
+<br>
+       (self maximumWidth &gt; 0 and: [self textMorph width &gt; self maximumWidth])<br>
+               ifTrue: [<br>
+                       self textMorph<br>
+                               wrapFlag: true;<br>
+                               width: self maximumWidth].<br>
+<br>
+       self updateLayout.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;tailHeight (in category &#39;geometry&#39;) -----<br>
+ tailHeight<br>
+<br>
+       ^ 8!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;tailPosition (in category &#39;geometry&#39;) -----<br>
+ tailPosition<br>
+<br>
+       ^ self innerBounds perform: self orientation!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;tailWidth (in category &#39;geometry&#39;) -----<br>
+ tailWidth<br>
+<br>
+       ^ 15!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;textMorph (in category &#39;accessing - ui&#39;) -----<br>
+ textMorph<br>
+<br>
+       ^ textMorph!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;updateLayout (in category &#39;layout&#39;) -----<br>
+ updateLayout<br>
+<br>
+       self textMorph fullBounds.<br>
+       self extent: self textMorph extent + (2* self bubbleInset) +  (0 @ (2*self tailHeight)).<br>
+       self textMorph center: self center.!<br>
<br>
Item was added:<br>
+ ----- Method: NewBalloonMorph&gt;&gt;verticesForTail (in category &#39;drawing&#39;) -----<br>
+ verticesForTail<br>
+<br>
+       | offset factorX factorY tpos bpos |<br>
+       offset := 5 + (self wantsRoundedCorners<br>
+               ifTrue: [self class preferredCornerRadius]<br>
+               ifFalse: [0]).<br>
+       tpos := self tailPosition.<br>
+       factorX := tpos x &lt; self center x ifTrue: [1] ifFalse: [-1].<br>
+       factorY := tpos y &gt; self center y ifTrue: [1] ifFalse: [-1].<br>
+       bpos := self bubbleBounds perform: self orientation.<br>
+<br>
+       ^ {<br>
+               tpos.<br>
+               bpos + (((offset + self tailWidth) * factorX) @ (self borderStyle width negated * factorY)).<br>
+               bpos + ((offset * factorX) @ (self borderStyle width negated * factorY)).}!<br>
<br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">best,<div>Eliot</div></div>
</div>