I have added my NSScrollView over the content view of my NSWindow object. Now I need to know the mouse location over the scrollview.
I have tried the following. But nothing gives the correct location.
- (void)mouseDown:(NSEvent *)theEvent{
NSPoint eventLocation = [theEvent locationInWindow];
NSPoint locationInScroll = [inputScrollView convertPoint:eventLocation toView:nil];
//Both gives the wrong location.
}
The code is correct, assuming that inputScrollView is the document view and the NSScrollView itself.
Another potential problem could be if you change the orientation of the coordinate system in one of the views?
Related
I'm a newbie to this and remaking an app. I am trying to use UITapGestureRecognizer. It works in the initial project file but not the new one. The only difference is that the old one uses a navigational controller but mine doesn't.
In the new one the self distance:location to:centre is stuck at 640 no matter where you press on the screen.
Can anyone help? I have no idea why it isn't working.
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
CGPoint centre = CGPointMake(512,768 / 2);
NSInteger msg = [self distance:location to:centre];
NSLog(#"location to centre: %d", msg);
if ([self distance:location to:centre] < 330)
The part that looks suspicious to me is [recognizer.view superview].
When the gesture recognizer was added to self.view in a UIViewController that is not inside a container controller (e.g. a Navigation Controller) that view does not have a superview. If you send the superview message to self.view without a container view controller it will return nil.
So your message looked basically like this
CGPoint location = [recognizer locationInView:nil];
This will return the location in the window, which is also a valid CGPoint that tells you were you tapped the screen.
Since this didn't work I guess in [self distance:location to:centre] you do something that does only work with coordinates relative to the view. Maybe it's related to rotation, because the coordinates of the window don't rotate when you rotate the device.
Without knowing your code I'm not sure what the problem is, but it probably doesn't matter.
Just replace [recognizer.view superview] with recognizer.view.
Refer below Link, You may get your answer. It's an example if Gesture Recognition.
http://www.techotopia.com/index.php/An_iPhone_iOS_6_Gesture_Recognition_Tutorial
I can use [NSEvent mouseLocation] to get the cursor's location, but this gives me the screen coordinates. How do I get the coordinates of the cursor relative to the view, when it is in it? I searched the Apple documentation and couldn't find an answer.
If it makes a difference I will want to be continually retrieving the mouse position as it will be used in every frame update.
For completeness, there is a direct way to get the mouse position in window co-ordinates (using NSWindow). Depending on your window layout, this may be equivalent to the view's co-ordinates.
NSWindow *myWindow;
NSPoint mousePos;
...
mousePos = [myWindow mouseLocationOutsideOfEventStream];
The co-ordinates returned are in window co-ords, so if the mouse is left of/below the window then a negative value is returned. If the mouse is right of/above the window then the co-ordinate will exceed the window's size.
NSPoint myPoint =
[myView convertPoint:[myWindow convertScreenToBase:[NSEvent mouseLocation]]
fromView:nil];
- (void)mouseMoved:(NSEvent *)event
{
NSPoint locationInView = [self convertPoint:[event locationInWindow]
fromView:nil];
}
Also make sure you have enabled mouseMoved events:
[window setAcceptsMouseMovedEvents:YES];
How to implement the feature of resizing NSTableView created programmatically ? Interface builder should not be used. It should be like click and drag to change the size of the NSTableView. Is it possible? If yes, please help. . . .
I am afraid you need to write a bit of code to make it working. This is how I would do it.
Make a special Resize View that will track the mouse events and call delegate methods providing how the tracking position changes.
- (void)mouseDown:(NSEvent *)theEvent
{
_startPoint = [theEvent locationInWindow];
[_delegate resizingDidStart];
}
- (void)mouseDragged:(NSEvent *)theEvent
{
NSPoint hitPoint = [theEvent locationInWindow];
[_delegate resizeWithDeltaX:(hitPoint.x - _startPoint.x) deltaY:(hitPoint.y - _startPoint.y)];
}
Put this view in the right bottom corner of the Base View. Set the autoresizing mask so this view always stays in the right bottom corner.
Put the table view along with its scroll view on to the Base View. Set autoresizing mask of the scroll view so its size and width are sizeable.
In the delegate of the Resize View process changes in the mouse position and set the frame of the Base View.
- (void)resizingDidStart
{
_initialRect = [_baseView frame];
}
- (void)resizeWithDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY
{
[_baseView setFrame:NSMakeRect(_initialRect.origin.x, _initialRect.origin.y + deltaY, _initialRect.size.width + deltaX, _initialRect.size.height - deltaY)];
}
Of course the scroll view should be under the resize view. You can draw some ind of a handle on the resize view, etc.
I have an NSView which I am adding as a sub-view of another NSView. I want to be able to drag the first NSView around the parent view. I have some code that is partially working but there's an issue with the NSView moving in the opposite direction on the Y axis from my mouse drag. (i.e. I drag down, it goes up and the inverse of that).
Here's my code:
// -------------------- MOUSE EVENTS ------------------- \\
- (BOOL) acceptsFirstMouse:(NSEvent *)e {
return YES;
}
- (void)mouseDown:(NSEvent *) e {
//get the mouse point
lastDragLocation = [e locationInWindow];
}
- (void)mouseDragged:(NSEvent *)theEvent {
NSPoint newDragLocation = [theEvent locationInWindow];
NSPoint thisOrigin = [self frame].origin;
thisOrigin.x += (-lastDragLocation.x + newDragLocation.x);
thisOrigin.y += (-lastDragLocation.y + newDragLocation.y);
[self setFrameOrigin:thisOrigin];
lastDragLocation = newDragLocation;
}
The view is flipped, though I changed that back to the default and it didn't seem to make a difference. What am I doing wrong?
The best way to approach this problem is by starting with a solid understanding of coordinate spaces.
First, it is critical to understand that when we talk about the "frame" of a window, it is in the coordinate space of the superview. This means that adjusting the flippedness of the view itself won't actually make a difference, because we haven't been changing anything inside the view itself.
But your intuition that the flippedness is important here is correct.
By default your code, as typed, seems like it would work; perhaps your superview has been flipped (or not flipped), and it is in a different coordinate space than you expect.
Rather than just flipping and unflipping views at random, it is best to convert the points you're dealing with into a known coordinate space.
I've edited your above code to always convert into the superview's coordinate space, because we're working with the frame origin. This will work if your draggable view is placed in a flipped, or non-flipped superview.
// -------------------- MOUSE EVENTS ------------------- \\
- (BOOL) acceptsFirstMouse:(NSEvent *)e {
return YES;
}
- (void)mouseDown:(NSEvent *) e {
// Convert to superview's coordinate space
self.lastDragLocation = [[self superview] convertPoint:[e locationInWindow] fromView:nil];
}
- (void)mouseDragged:(NSEvent *)theEvent {
// We're working only in the superview's coordinate space, so we always convert.
NSPoint newDragLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];
NSPoint thisOrigin = [self frame].origin;
thisOrigin.x += (-self.lastDragLocation.x + newDragLocation.x);
thisOrigin.y += (-self.lastDragLocation.y + newDragLocation.y);
[self setFrameOrigin:thisOrigin];
self.lastDragLocation = newDragLocation;
}
Additionally, I'd recommend refactoring your code to simply deal with the original mouse-down location, and the current location of the pointer, rather than deal with the deltas between mouseDragged events. This could lead to unexpected results down the line.
Instead simply store the offset between the origin of dragged view and the mouse pointer (where the mouse pointer is within the view), and set the frame origin to the location of the mouse pointer, minus the offset.
Here is some additional reading:
Cocoa Drawing Guide
Cocoa Event Handling Guide
I think you should calculate according to the position of mouse, cause according to my test,it gets more smooth.Because The way like below only provide the position inside the application's window coordinate system:
[[self superview] convertPoint:[theEvent locationInWindow] fromView:nil];
What I am suggesting is something like this:
lastDrag = [NSEvent mouseLocation];
other codes are just the same.
I am making an image editor (just a simple editor for a program I am making), and I need to find the position of the mouse. Is it possible to do this in Objective-C? If so, how?
EDIT: I just thought I should mention that I have done some research on this and I haven't found anything that works. The code I have in my header file is as follows:
#import <Cocoa/Cocoa.h>
#interface test : NSWindow <NSWindowDelegate> {
}
#end
I can handle any outlets and actions that are needed; I just need to know how to find the position of the mouse.
If you are catching it through an event, such as mouseDown, it will look like this:
- (void)mouseDown:(NSEvent *)theEvent {
NSPoint mouseDownPos = [theEvent locationInWindow];
}
Otherwise, use:
[NSEvent mouseLocation];
EDIT: (Sorry, I wrote NSPoint *, which is wrong, since it's a struct)
Inside a mouse event handler (mouseDown:, mouseUp:, mouseMoved:, etc.), you can ask the event for its locationInWindow. If you need the mouse location at some arbitrary time (generally you won't want to do that, since it's rare for a program to have a one-off need to discover the mouse location), you can do [NSEvent mouseLocation] and it will return the mouse's location at the time in screen coordinates.
If you want the coordinates from the origin of the view itself, use:
NSPoint locationInView = [self convertPoint:[theEvent locationInWindow] fromView:nil];
You can use this NSPoint directly to draw in the NSView coordinates; otherwise with
[theEvent locationInWindow]
you will have the coordinates of the mouse in the window, which is probably not what you want.