Cocoa get the screen location on an NSMenu or NSMenuItem - objective-c

Is it possible to get the location (frame) of an NSMenu or one of the NSMenuItems inside it?
I have tried adding a custom view to one of the menu items and getting its frame, however it returns zero. All I need is the x coordinate, relative to the screen.
Edit
Calling [[view window] frame] on the NSView inside the NSMenuItem after the menu is visible works, however window is deprecated as of 10.6. I'll use this unless someone posts a better way...

Related

Find the top-most NSView object located under NSPoint position

I know this question was already asked here in few forms but unfortunately non of the suggested solutions worked for me.I am implementing a multi-touch capability for my osx app.My problem:I need to resolve a location on the screen, described by NSPoint in screen coordinates, to the very top NSView object from my application that resides under this location (if any).This is a bit like HWND WindowFromPoint( Point) under Windows OS.
Few points to consider:
My application manage several NSWindows, where each window contains an hierarchy of several NSViews,
The NSView that I am interested in is not necessarily the application Key Window or Main Window, as it can be any of my other currently non-active NSView objects that happen to be under this screen location,
It is possible that under a particular NSPoint I will have more then one NSWindows and/or NSViews. In this case I wll be interested only in the very top-most NSView,
It is possible that NSView A is on top of NSView B, partialy hiding it, but the NSPoint location is present only on B, which is not the very top-most window of the application (but only the very top-most for this location). Here again I will be interested in B.
Things that I managed todo:
Enumerate NSApp for all its windows (NSApp.windows),
Enumerate NSWindow for its views (NSWindow.contentView.subviews),
Enumerate NSView for its sub-views (NSView.subviews)
Doing this I managed to enumerate all NSViews of my application, but I still need to filter out non-relevant NSViews, which are not visible.
Things that did not work for me:
NSView.hitTest returned nil for valid locations,
NSView.layer.zPosition alwyas is zero (0),
The order of the NSView.subviews list also does not reflacts the current GUI layout,
Testing if NSView is Visible also did not help as it returns true also if this window is hidden by other window.
My environment:Mac, OSX El-Capitan, XCode-7, Cocoa, Objective-C
Thanks for any help!PazO
Found it:
// 1. Get the Window-Number of the NSWindow object owning this point:
NSInteger wndNumber = [NSWindow windowNumberAtPoint:(point) belowWindowWithWindowNumber:(0)];
// 2. Get the NSWindow object associated with this particular Window-Number:
NSWindow* window = [NSApp windowWithWindowNumber:(wndNumber)];
// 3. Convert NSPoint values from System-coordinates to NSWindow-coordinates (Thanks #Willeke for his comment)
NSRect rctScreen;
rctScreen.origin = point;
rctScreen.size.height = rctScreen.size.width = 0;
NSRect rctWindow = [window convertRectFromScreen:rctScreen];
// 4. Now do the hitTest:
NSView* viewFound = [[window contentView] hitTest:rctWindow.origin];
Obviously each line should be tested for nil, but I leave this out for code brevity.

NSTextView sometimes get grayed out and unable to interact with

I have a NSView inside of my "menubar". I have a button where which i click on and add a new NSMenuItem to the menu. However when i run this code which is inside my custom view in the init method sometimes the view will get grayed out and I'm unable to select it. Any ideas what this could be the cause of this. The problem seems to affect all created NSMenuItems after this problem occur.
-(id)initWithFrame:(NSRect)frameRect andTag:(int)tagz{
textfeild = [[NSTextView alloc]initWithFrame:CGRectMake(19,1 , 110, 18)];
[textfeild setFont:[NSFont fontWithName:#"Helvetica" size:15]];
[textfeild setString:[NSString stringWithFormat:#"Notespace %d",tagz]];
[textfeild selectAll:self];
[self addSubview:textfeild];
}
I don't think you are supposed to use [self addSubview:] on a menu item. Instead, you are supposed to create an NSView and place your custom view inside it. Documentation is here: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MenuList/Articles/ViewsInMenuItems.html
However, according to the documentation views inside a menu item may not receive keyboard events. It may work sometimes, but since the documentation specifically mentions it you should not place any view that needs keyboard events inside a menu.
What you should do instead, is avoid NSMenu altogether and simply create an NSWindow where the menu would normally appear. You can make your window look/behave like a menu.

Interact with other views while a popover is active

I have a toolBar and I have setup two UIBarButtonItem on it. Both UIBarButtonItem are containing UIButtons as their customViews.
I activate a popover for their Touch Up Inside event as below,
[popover1 presentPopoverFromBarButtonItem:buttonItem1 permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I have another UIButton named clearFilters inside the main view. (Also this is the view which is containing the above toolBar.) I have declared a method for clearFilters button's Touch Up Inside event.
My problem is,
I can not interact with the clearFilters button while a popover is active. So, I'm looking for a solution to interact with this clearFilters button, while a popover is active.
I tried by adding passthroughViews property for a popover as below and it do not work as I expect.
popover1.passthroughViews = [NSArray arrayWithObject:clearFiltersButton];
What could be the reason. As the documentation has mentioned I can not see any issue.
I expect if the above things are correct, then the Touch Up Inside event of the the clearFilters button's should be fire up.
So, please show me if there is any issue or a necessary way to work on this thing.
I'm working on XCode4 and iOS 4.3.
Thanks.
The UIPopoverController documentation reveals why the other bar buttons can be tapped while the popover is visible:
“When presenting the popover, this method adds the toolbar that owns the button to the popover’s list of passthrough views.”
Try querying and logging the popover’s passthrough views. Does it already have things in it? Perhaps something like this would work?
myPopover.passthroughViews = [myPopover.passthroughViews arrayByAddingObject:clearFilters];
I haven’t tested this code, but it’s worth a try.

MAAttachedWindow for NSStatusItem without a custom view

I have a simple app that has a NSStatusItem, which only displays an icon.
I would now like to add functionality that would make a MAAttachedWindow appear under the NSStatusItem.
I saw the demo code Matt Gemmel provided; the code he uses to make the MAAttachedWindow appear under the NSStatusItem is:
NSRect frame = [[self window] frame];
NSPoint pt = NSMakePoint(NSMidX(frame), NSMinY(frame));
[controller toggleAttachedWindowAtPoint:pt];
The above is done in the custom view of the NSStatusItem. However, my NSStatusItem has no custom view. How can I add the MAAttachedWindow in my case?
You can't afaik. You have to have a way to get coordinates to attach the window to, and the only way i've been able to get that to work is to use a custom view so you can get the coordinates on mouse down and the only way i've seen is to use your own view. Anything else would probably be a little hacky unless there is some way to get the view for a status item without a custom view and it wouldn't be good to display the MSAttachedWindow and a menu.
I just settled on doing a NSStatusitem with a custom view and faking selection by drawing a background gradient when its selected.
Have you considered using NSPopover ?

Confusing behavior from UIPopoverController

I'm trying to set up a popover to appear that displays a UIDatePicker when I press a button, however I'm getting some very confusing behavior. I created a view controller that housed nothing but the UIDatePicker, wired one up in the class i needed it in, and added it to a new UIPopoverController like this:
self.timePickerPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.timePickerViewController];
then I present it like so:
[timePickerPopoverController presentPopoverFromRect:prepTimeButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
(prepTimeButton being the button that was pressed). However, I just get the following result:
Instead of it displaying next to the button that was pressed and at the target size (it's way too tall right now; should only be the size of the date picker). I also tried giving it a custom view of the proper location and size in which to display, but that didn't help much (just shifted the popover to the right half of the screen). What am I doing wrong and how do I fix it?
Is self.view the direct superview of prepTimeButton? Perhaps prepTimeButton is nested in a subview, in that case you'd need to use that as the inView: parameter (or convert the coordinates).
Did you set the contentSizeForViewInPopover property of your view controller?
Make sure to set both contentSizeForViewInPopover on the internal view controller and popoverContentSize on the UIPopoverController itself.