I am seeing what seems like strange behavior when trying to draw a simple shape to the screen. In the program below, I set the content view of the window to my script’s class, and the script’s parent is NSView.
script DrawOutsideAppDelegate
property parent : class "NSView"
property contentView : missing value --IBOutlet for the window's content view
on applicationWillFinishLaunching_(aNotification)
--makeSquare_(me)
end applicationWillFinishLaunching_
on mouseDown_(theEvent)
makeSquare_(me)
end mouseDown_
on makeSquare_(sender) --IBAction for a button
current application's NSColor's redColor()'s |set|()
set theRect to current application's NSBezierPath's bezierPathWithRect_({{30, 30}, {50, 50}})
theRect's fill()
log theRect
end makeSquare_
end script
Here is the behavior that I see:
If I run the program as shown, and call makeSquare_ by clicking the button, I get nothing on the screen.
If I uncomment out the line in the applicationWillFinishLaunching method, I get a red square on the screen.
If I click in the view, and makeSquare_ gets called from the mouseDown_ method, I initially see nothing, but if I roll the mouse over the window’s close/resize buttons the red square appears.
So, the same method, called 3 different ways gives 3 different results. Can anyone explain to me what is going on here, and what I need to do to get a drawing to show up on the screen reliably?
Actually the property was left over from another larger program, and it’s not even used in this one. So, I can just delete it and I get the same results.
Hmm… I guess I hadn’t tried displayIfNeeded(), I thought I tried all of those things. The weird thing is that if you just do |display|() it not only doesn’t display the red square, but it no longer appears when you do a mouse rollover on the close/resize buttons either. If you look at the descriptions of “display” and “displayIfNeeded”, it looks like they should both do the same thing. Curious.
I wonder if the mouse rollover causes the window to send a displayIfNeeded()?
I don’t know. The displayIfNeeded should send a lockFocus message too, but that doesn’t seem to work with the button. I also noticed that if I put a performSelector_withObject_afterDelay_ in the applicationWillFinishLaunching method and have the method named by selector call makeSquare, the red square again doesn’t appear – so I’m guessing that the redisplay must be done by applicationWillFinishLaunching too.
Anyway, the button isn’t important, I was just exploring how to draw, and testing various methods to call it. I just can’t understand why calling makeSquare from a button should be any different than calling it from code.