Last mouse down in a view

Is there a possibility to get the last event in a view?

I’d like to intercept a mouseDown in a view – which is created programmatically and already has a handler to handle a click by:

myView’s setAction_(“myClickRoutine”)
on myClickRoutine()

Can I define a selector with:

myView’s setAction_(“myClickRoutine:”)
on myClickRoutine_(aParameter)

and get the last event from aParameter? I know that aParameter return the object clicked (not really a scoop.)


Your method that is set with setAction_ , won’t contain any info about the mouse click. If you want that info you have to implement mouseDown:. The parameter to that method is the mouse event which has info about where and when the mouse was clicked. Since mouseDown is called every time you click down on the mouse in your view, the event you get, by definition, will be the last event.



Before sending my first post, I tried to implement the mouseDown_ handler, as the NSMatrix is a NSResponder, but it was never fired. Then I tried to make the matrix the first responder (with the NSWindow method)-- but the matrix didn’t call the mouseDown_, so I’m a bit lost, I must confess. The things are always more complicated as they seem to be in Cocoa.


Was your script a subclass of NSMatrix? It has to be for the mouseDown to be called, and your matrix needs to be set to your script’s class.


My script has already been a subclass of NSTextView, then reverted to NSObject – and if possible it should stay as it is.

What about this NSMatrix method:

Maybe there is a workaround to get the first and the last cell on a mouseDown-dragMouse-mouseUp on a matrix, but if you have a look on this post: you may understand my problem (I’m not sure that I exposed it clearly, actually)


I looked at that post, and I understand your problem, but I don’t know any other way to do this other than implementing mouseDown and mouseUp in a script that’s a subclass of NSMatrix. As far as I know, that’s the only way to override the mouseDown method.



I thought about a way to avoid changing the class of my script, and even avoid NSMatrix’s mouseDown_ , and I think I found something:

Before you proposed to use selectedCells () to select a group of cells, I used selectedCell () which returns the cell where mouseUp occurs – that is, actually, the last selected cell.

If I compare this cell with the cell corners of the rectangular group of cells, I always determines which direction the selection has been extended - what do you think?

And if I get the direction, I can also determinate how to adjust the atan function, which always returns an angle (converted to degrees) from 0 to 90.

I’ll keep you informed if it works (and even if it doesn’t.)


Ric and others,

I solved this with nothing more than the C atan function (thanks to Shane) and the standard methods of NSMatrix. There is how:

-- get the rectangular selection with it's top left (first) and bottom right (last) cell

set {b, r1, c1} to gMap's mMap's getRow_column_ofCell_(reference, reference, (gMap's mMap's selectedCells())'s objectAtIndex_(0))
set {b, r2, c2} to gMap's mMap's getRow_column_ofCell_(reference, reference, (gMap's mMap's selectedCells())'s lastObject())

-- get the last selected cell (where mouse went up)

set {b, rL, cL} to gMap's mMap's getRow_column_ofCell_(reference, reference, gMap's mMap's selectedCell())

-- calculate the horizontal distance with raw Applescript

set my mapHorDist to (((c2 - c1) ^ 2) + ((r2 - r1) ^ 2)) ^ (1 / 2) * (gMap's mGridSize) -- it's the scale

-- call the arctangent home-made function - return in degrees (360°)

set angle to arctan(c1, r1, c2, r2, cL, rL)

-- orient the compass needle using the reverse returned angle

mapCompassNeedle's setFrameCenterRotation_(-angle)


on arctan(x1, y1, x2, y2, xL, yL) -- arc tangent in 360°
	-- test division by zero and eventually return
	if (y1 = y2) and (xL = x1) then return 270
	if (y1 = y2) and (xL = x2) then return 90
	-- raw arctangent
	set trigger to current application's MyTrigClass's alloc()'s init() -- this is a custom class, thanks to Shane.
	set angle to (trigger's findAtan_((x2 - x1) / (y2 - y1))) * 180 / 3.1415926535
	-- adjust
	if (x1 = xL) and (y1 = yL) then --to NW
		return 360 - angle
	else if (x2 = xL) and (y2 = yL) then --to SE
		return 180 - angle
	else if (x1 = xL) then --to SW
		return 180 + angle
	else --to NE
		return angle
	end if
end arctan

OK, my real job is to teach literature. My memories of geometry are thirty years old, so forgive my possible clumsiness.



Well, that certainly looks like it should work – that’s a neat trick.

An aside here — Have you gotten the selection by dragging to work on a matrix made in IB (made by dragging in a button and imbedding it in a matrix)? I can’t seem to get that to work. I have the “rectangular” check box checked in IB, and I’ve tried doing it in code with setSelectionByRect_(1), but neither works. If I create the matrix in code, like we’ve done for your project, it works fine.



I tried the matrix with various options and different kinds of buttons, all I get is single selection: no way to extend it by the standard ways (caps + click, option, command + click and so on).

One more question: when you create a matrix programmatically, your prototype cell is actually a prototype. All the cells behave the same manner, they are true clones of the prototype one.

In IB, when you create a button, control, etc, and you embed it in a matrix, the first one should also be a prototype (for example, in a two-radio buttons matrix (group) there are always three cells, so I supposed that the first one was a prototype). But when you modify this “prototype”, the changes are not passed to the others. you have to change them all (which can take a delay if there is a lot of them).

So, I’m not sure a programmatically created matrix and one created in IB are the same. In fact, I’m pretty sure they are not.