Drawing Problems

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?

Ric

Hi Ric,

I’m not sure to understand your hierarchy:

and then:

is it possible that your hierarchy get confused?

Regards,

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.

Ric

If I add

   my displayIfNeeded()

into your on makeSquare_, I get the bezier curve at mouseDown. But the button refuses to draw anything, even if the handler is fired. Strange.

If I call on makeSquare_(sender) via a menu command, I get your square drawn, too.

When I worked with QuickDraw, I often had problems with these two calls:

  • setPort (to set the port where drawings occurs)
  • clipRgn (when it was not set to the window entire frame)

I don’t know the Cocoa equivalence.

When you click on the button, is it possible that one of these parameters is changed?

Regards,

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()?

Ric

I get the drawing if I resize the window, which certainly send a displayIfNeeded().

And if I call my lockFocus()

I get the square when I click on the button (that made me think to a “set port” error. but I get this error, too:

2011-05-07 01:59:35.633 Square[59648:903] Unlocking Focus on wrong view (<NSButton: 0x2006e7cc0>), expected <SquareAppDelegate @0x2006c4a00: OSAID(4)>

Does it help?

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.

Ric