Hello,
I'm trying to learn Smalltalk and to understand the Squeak environment. I've done a couple of small applications and I've been learning basics of the language itself and the environment but now I'd like to learn something more concrete about Squeak. I thought that I would try to make some improvements and customizations for myself and learn that way. The first project: to modify those quite comic-like balloon tooltips. But I'm not sure where to start. I have been poking around with BalloonMorph and managed to change the border width and the tooltip color, but I'm not sure if that is the right place to modify the appearance of the tooltips. I also don't understand where the tooltip gets those polygon coordinates that shape the balloon. Could anyone give me some pointers, how to get started with the tooltip customization? Thanks, Matti Kärki |
MJK wrote:
> I also > don't understand where the tooltip gets those polygon coordinates that shape > the balloon. As far as I can tell it is in BalloonMorph class getVertices: Hope that helps, David _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Thank you! That was it! I already looked the getVertices: method but didn't realize that the code there actually created the balloon shape. It took me a while to understand what was going on. Now that I can see what is happening, I was able to rewrite the method and now my tooltips look much more enjoyable: http://i.imgur.com/BXdMA.png -Matti |
I think it is neat how succinctly the code creates the triangular
callout pointing to the target. I found that it was particularly hard to figure out how BalloonMorph works, because when I put a breakpoint in it, Squeak would usually freeze and wouldn't respond to the user interrupt. I am not sure why: I think that by hovering over a morph with a balloonText, I created a flood of breaks. My alternate hypothesis is that it somehow blocked the process that gave me control of the hand pointer. I just updated my image from 4.3 to trunk, and while the freeze still occurs, the new image saved a useful SqueakDebug.log file at the breakpoint. Have fun! David BreakPoint: 27 January 2012 1:57:07.022 pm VM: Mac OS - Smalltalk Image: Squeak4.3 [latest update: #11860] SecurityManager state: Restricted: false FileAccess: true SocketAccess: true Working Dir /Users/dcorking/Applications/squeak/Squeak4.3 Trusted Dir /foobar/tooBar/forSqueak/bogus Untrusted Dir /Users/dcorking/Library/Preferences/Squeak/Internet/My Squeak BalloonMorph class(Object)>>break Receiver: BalloonMorph Arguments and temporary variables: Receiver's instance variables: superclass: PolygonMorph methodDict: a MethodDictionary(#adjustedCenter->(BalloonMorph>>#adjustedCenter ...etc... format: 172 instanceVariables: #('target' 'offsetFromTarget' 'balloonOwner') organization: ('accessing' balloonOwner) ('initialization' defaultBorderColor d...etc... subclasses: nil name: #BalloonMorph classPool: a Dictionary(#BalloonColor->(TranslucentColor r: 0.91 g: 0.94 b: 1.0...etc... sharedPools: nil environment: Smalltalk globals "a SystemDictionary with lots of globals" category: #'Morphic-Widgets' BalloonMorph class>>getVertices: Receiver: BalloonMorph Arguments and temporary variables: t1: 0@0 corner: 104@14 t2: nil Receiver's instance variables: superclass: PolygonMorph methodDict: a MethodDictionary(#adjustedCenter->(BalloonMorph>>#adjustedCenter ...etc... format: 172 instanceVariables: #('target' 'offsetFromTarget' 'balloonOwner') organization: ('accessing' balloonOwner) ('initialization' defaultBorderColor d...etc... subclasses: nil name: #BalloonMorph classPool: a Dictionary(#BalloonColor->(TranslucentColor r: 0.91 g: 0.94 b: 1.0...etc... sharedPools: nil environment: Smalltalk globals "a SystemDictionary with lots of globals" category: #'Morphic-Widgets' BalloonMorph class>>string:for:corner: Receiver: BalloonMorph Arguments and temporary variables: str: 'browse class hierarchy' morph: a PluggableButtonMorphPlus(3898) cornerName: #bottomLeft tm: a TextMorph(3026) vertices: nil Receiver's instance variables: superclass: PolygonMorph methodDict: a MethodDictionary(#adjustedCenter->(BalloonMorph>>#adjustedCenter ...etc... format: 172 instanceVariables: #('target' 'offsetFromTarget' 'balloonOwner') organization: ('accessing' balloonOwner) ('initialization' defaultBorderColor d...etc... subclasses: nil name: #BalloonMorph classPool: a Dictionary(#BalloonColor->(TranslucentColor r: 0.91 g: 0.94 b: 1.0...etc... sharedPools: nil environment: Smalltalk globals "a SystemDictionary with lots of globals" category: #'Morphic-Widgets' BalloonMorph class>>string:for: Receiver: BalloonMorph Arguments and temporary variables: str: 'browse class hierarchy' morph: a PluggableButtonMorphPlus(3898) Receiver's instance variables: superclass: PolygonMorph methodDict: a MethodDictionary(#adjustedCenter->(BalloonMorph>>#adjustedCenter ...etc... format: 172 instanceVariables: #('target' 'offsetFromTarget' 'balloonOwner') organization: ('accessing' balloonOwner) ('initialization' defaultBorderColor d...etc... subclasses: nil name: #BalloonMorph classPool: a Dictionary(#BalloonColor->(TranslucentColor r: 0.91 g: 0.94 b: 1.0...etc... sharedPools: nil environment: Smalltalk globals "a SystemDictionary with lots of globals" category: #'Morphic-Widgets' PluggableButtonMorphPlus(Morph)>>showBalloon:hand: Receiver: a PluggableButtonMorphPlus(3898) Arguments and temporary variables: msgString: 'browse class hierarchy' aHand: a HandMorph(3216) w: a PasteUpMorph(1622) [world] balloon: nil h: a HandMorph(3216) Receiver's instance variables: bounds: 505@221 corner: 581@243 owner: a PluggablePanelMorph(3222) submorphs: {an AlignmentMorph(1790)} fullBounds: 505@221 corner: 581@243 color: (Color r: 0.906 g: 0.906 b: 0.906) extension: a MorphExtension (3108) [balloonText] [other: (layoutPolicy -> a T...etc... borderWidth: 1 borderColor: Color gray model: a Browser label: 'hierarchy' getStateSelector: nil actionSelector: #classHierarchy getLabelSelector: nil getMenuSelector: nil shortcutCharacter: nil askBeforeChanging: false triggerOnMouseDown: false offColor: Color white onColor: Color veryLightGray feedbackColor: Color red showSelectionFeedback: false allButtons: nil arguments: nil argumentsProvider: nil argumentsSelector: nil style: nil enabled: true action: nil getColorSelector: nil getEnabledSelector: nil updateMap: nil HandMorph>>spawnBalloonFor: Receiver: a HandMorph(3216) Arguments and temporary variables: aMorph: a PluggableButtonMorphPlus(3898) Receiver's instance variables: bounds: 549@233 corner: 565@249 owner: a PasteUpMorph(1622) [world] submorphs: #() fullBounds: 549@233 corner: 565@249 color: Color blue extension: a MorphExtension (539) [eventHandler = an EventHandler] mouseFocus: nil keyboardFocus: nil eventListeners: nil mouseListeners: nil keyboardListeners: a WeakArray(a DockingBarMorph(3368)) mouseClickState: nil mouseOverHandler: a MouseOverHandler lastMouseEvent: [549@232 549@233 mouseMove 177917] targetOffset: 8@4 damageRecorder: a DamageRecorder cacheCanvas: nil cachedCanvasHasHoles: true temporaryCursor: nil temporaryCursorOffset: nil hardwareCursor: nil hasChanged: true savedPatch: nil userInitials: '' lastEventBuffer: #(1 177917 549 233 0 0 0 1) genieGestureProcessor: nil keyboardInterpreter: a MacUnicodeInputInterpreter MorphicAlarm(MessageSend)>>value Receiver: MorphicAlarm(#spawnBalloonFor: -> a HandMorph(3216)) Arguments and temporary variables: Receiver's instance variables: receiver: a HandMorph(3216) selector: #spawnBalloonFor: arguments: {a PluggableButtonMorphPlus(3898)} scheduledTime: 178460 sequenceNumber: 1951 numArgs: 1 MorphicAlarm>>value: Receiver: MorphicAlarm(#spawnBalloonFor: -> a HandMorph(3216)) Arguments and temporary variables: anArgument: 178466 nArgs: 1 Receiver's instance variables: receiver: a HandMorph(3216) selector: #spawnBalloonFor: arguments: {a PluggableButtonMorphPlus(3898)} scheduledTime: 178460 sequenceNumber: 1951 numArgs: 1 [] in WorldState>>triggerAlarmsBefore: Receiver: a WorldState Arguments and temporary variables: nowTime: a MorphicAlarmQueue() pending: 178466 Receiver's instance variables: hands: {a HandMorph(3216)} activeHand: a HandMorph(3216) viewBox: 0@0 corner: 800@600 canvas: a FormCanvas on: DisplayScreen(800x600x32) damageRecorder: a DamageRecorder stepList: a Heap(StepMessage(#stepAt: -> a ClockMorph(3002)'1:57:06 pm')(a Cloc...etc... lastStepTime: 178446 lastStepMessage: nil lastCycleTime: 178511 commandHistory: a CommandHistory alarms: a MorphicAlarmQueue() lastAlarmTime: 178446 remoteServer: nil multiCanvas: nil [] in WorldState>>lockAlarmsDuring: Receiver: a WorldState Arguments and temporary variables: actionBlock: [closure] in WorldState>>triggerAlarmsBefore: Receiver's instance variables: hands: {a HandMorph(3216)} activeHand: a HandMorph(3216) viewBox: 0@0 corner: 800@600 canvas: a FormCanvas on: DisplayScreen(800x600x32) damageRecorder: a DamageRecorder stepList: a Heap(StepMessage(#stepAt: -> a ClockMorph(3002)'1:57:06 pm')(a Cloc...etc... lastStepTime: 178446 lastStepMessage: nil lastCycleTime: 178511 commandHistory: a CommandHistory alarms: a MorphicAlarmQueue() lastAlarmTime: 178446 remoteServer: nil multiCanvas: nil BlockClosure>>ensure: Receiver: [closure] in WorldState>>lockAlarmsDuring: Arguments and temporary variables: aBlock: [closure] in [] in Mutex>>critical: complete: nil returnValue: nil Receiver's instance variables: outerContext: WorldState>>lockAlarmsDuring: startpc: 40 numArgs: 0 [] in Mutex>>critical: Receiver: a Mutex Arguments and temporary variables: aBlock: [closure] in WorldState>>lockAlarmsDuring: activeProcess: a Process in nil Receiver's instance variables: semaphore: a Semaphore(a Process in [] in Semaphore>>critical:) owner: a Process in nil [] in Semaphore>>critical: Receiver: a Semaphore(a Process in [] in Semaphore>>critical:) Arguments and temporary variables: mutuallyExcludedBlock: [closure] in Mutex>>critical: caught: #(true) Receiver's instance variables: firstLink: a Process in [] in Semaphore>>critical: lastLink: a Process in [] in Semaphore>>critical: excessSignals: 0 BlockClosure>>ensure: Receiver: [closure] in Semaphore>>critical: Arguments and temporary variables: aBlock: [closure] in Semaphore>>critical: complete: nil returnValue: nil Receiver's instance variables: outerContext: Semaphore>>critical: startpc: 38 numArgs: 0 Semaphore>>critical: Receiver: a Semaphore(a Process in [] in Semaphore>>critical:) Arguments and temporary variables: mutuallyExcludedBlock: [closure] in Mutex>>critical: caught: #(true) Receiver's instance variables: firstLink: a Process in [] in Semaphore>>critical: lastLink: a Process in [] in Semaphore>>critical: excessSignals: 0 Mutex>>critical: Receiver: a Mutex Arguments and temporary variables: aBlock: [closure] in WorldState>>lockAlarmsDuring: activeProcess: a Process in nil Receiver's instance variables: semaphore: a Semaphore(a Process in [] in Semaphore>>critical:) owner: a Process in nil WorldState>>lockAlarmsDuring: Receiver: a WorldState Arguments and temporary variables: actionBlock: [closure] in WorldState>>triggerAlarmsBefore: Receiver's instance variables: hands: {a HandMorph(3216)} activeHand: a HandMorph(3216) viewBox: 0@0 corner: 800@600 canvas: a FormCanvas on: DisplayScreen(800x600x32) damageRecorder: a DamageRecorder stepList: a Heap(StepMessage(#stepAt: -> a ClockMorph(3002)'1:57:06 pm')(a Cloc...etc... lastStepTime: 178446 lastStepMessage: nil lastCycleTime: 178511 commandHistory: a CommandHistory alarms: a MorphicAlarmQueue() lastAlarmTime: 178446 remoteServer: nil multiCanvas: nil WorldState>>triggerAlarmsBefore: Receiver: a WorldState Arguments and temporary variables: nowTime: 178466 Receiver's instance variables: hands: {a HandMorph(3216)} activeHand: a HandMorph(3216) viewBox: 0@0 corner: 800@600 canvas: a FormCanvas on: DisplayScreen(800x600x32) damageRecorder: a DamageRecorder stepList: a Heap(StepMessage(#stepAt: -> a ClockMorph(3002)'1:57:06 pm')(a Cloc...etc... lastStepTime: 178446 lastStepMessage: nil lastCycleTime: 178511 commandHistory: a CommandHistory alarms: a MorphicAlarmQueue() lastAlarmTime: 178446 remoteServer: nil multiCanvas: nil WorldState>>runLocalStepMethodsIn: Receiver: a WorldState Arguments and temporary variables: aWorld: a PasteUpMorph(1622) [world] now: 178466 morphToStep: nil stepTime: nil priorWorld: a PasteUpMorph(1622) [world] Receiver's instance variables: hands: {a HandMorph(3216)} activeHand: a HandMorph(3216) viewBox: 0@0 corner: 800@600 canvas: a FormCanvas on: DisplayScreen(800x600x32) damageRecorder: a DamageRecorder stepList: a Heap(StepMessage(#stepAt: -> a ClockMorph(3002)'1:57:06 pm')(a Cloc...etc... lastStepTime: 178446 lastStepMessage: nil lastCycleTime: 178511 commandHistory: a CommandHistory alarms: a MorphicAlarmQueue() lastAlarmTime: 178446 remoteServer: nil multiCanvas: nil --- The full stack --- BalloonMorph class(Object)>>break BalloonMorph class>>getVertices: BalloonMorph class>>string:for:corner: BalloonMorph class>>string:for: PluggableButtonMorphPlus(Morph)>>showBalloon:hand: HandMorph>>spawnBalloonFor: MorphicAlarm(MessageSend)>>value MorphicAlarm>>value: [] in WorldState>>triggerAlarmsBefore: [] in WorldState>>lockAlarmsDuring: BlockClosure>>ensure: [] in Mutex>>critical: [] in Semaphore>>critical: BlockClosure>>ensure: Semaphore>>critical: Mutex>>critical: WorldState>>lockAlarmsDuring: WorldState>>triggerAlarmsBefore: WorldState>>runLocalStepMethodsIn: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WorldState>>runStepMethodsIn: PasteUpMorph>>runStepMethods WorldState>>doOneCycleNowFor: WorldState>>doOneCycleFor: PasteUpMorph>>doOneCycle [] in Project class>>spawnNewProcess [] in BlockClosure>>newProcess _______________________________________________ Beginners mailing list [hidden email] http://lists.squeakfoundation.org/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |