Making a Cocoa App Pop Up a Widget instead of a Window - cocoa

I have never made an app using XCode and Cocoa but I think following these instruction:
http://developer.apple.com/Mac/library/documentation/GraphicsImaging/Reference/IKImagePicker_Class/IKImagePicker_Reference.html
I could easily make an app that pops up a window that allows you to push a button to bring up the IKPictureTaker, but this is not quite what I want. I want my app to just automatically bring up the PictureTaker. I assume to do this I would have to abandon the interface builder altogether and do the whole thing programatically but I can't figure out what call will tell the Cocoa app to use this class or method at start up. Where would this be done programatically? I am trying to do all this in a Cocoa app that will be run in OSX.
alt text http://www.freeimagehosting.net/image.php?38f459584c.png][img=http://www.freeimagehosting.net/uploads/th.38f459584c.png

You'll want to use the beginPictureTakerWithDelegate:didEndSelector:contextInfo: method, which will give you a stand-alone pictureTaker window.
IKPictureTaker *sharedPictureTaker = [IKPictureTaker pictureTaker];
[sharedPictureTaker setValue:[NSNumber numberWithBool:YES] forKey:IKPictureTakerShowEffectsKey];
[sharedPictureTaker beginPictureTakerWithDelegate:self didEndSelector:#selector(pictureTakerDidEnd:returnCode:contextInfo:) contextInfo:nil];
If you put that somewhere, like in your Application Delegate's applicationDidFinishLaunching: method, you'll get the picture taker window # startup.

If you want a more custom solution you can look into the QuicktimeKit. It's not as easy as the three liner posted above but it's relatively pain-free. You'll have much more flexibility in the look of your picture taker window, be able to select from any number of inputs, be able to add your own filters, etc. Could be worth a look.
I'm not totally familiar with the IKPictureTaker. If it does something I'm not crediting it then let me know.

The way to automatically instantiate a class in Xcode /Cocoa is, strangely enough, through Interface Builder (IB). Open your MainMenu.xib in IB and make sure you can see the Document window (menu Window >> Document). Now, in the Library expand Cocoa >> Objects & Controllers >> Controllers. You'll see a number of controller, among them a blue cube. Drag this blue cube to your MainMenu.xib document window. You'll see that File's Owner and Font Manager sport the same blue cubes as their logo. Now, select your blue cube and in the Inspector choose the Identitiy panel (letter i on blue circle). Set the Class to the class you created before in Xcode, and save MainMenu.xib.
When you run your program, your class will automatically be instantiated. Your starting point from where you can start calling other methods or instantiating other objects is
- (void)awakeFromNib
{
NSLog(#"%# I'm alive!", [self class]);
}

Related

Add an NSView around cursor?

Simple question, starting out with macOS stuff – I’d like to create a small radial menu around my cursor, top-most, above whatever application is currently active, whenever a specific mouse button is pressed.
I have the specific mouse button over all application down, but I’m wondering where I need to draw that NSView, i.e. “topmost”. I guess on iOS this would be at the UIWindow level, but would NSWindow be the wrong approach here?
this is purely an opinion-based question, but basically if you want to present any custom content on the desktop, that should use NSWindow, and you can customise the window's content for your wish.
NOTE: you can find more information about the NSWindow class in Apple's Class Reference Docs.

OSX application without #NSApplicationMain

So here i was trying to get rid of #NSApplicationMain to get familiar on how things work more in depth.
I found this nice answer from musically_ut here OSX application without storyboard or xib files using Swift
However, its not quite working !
Here's the weird result : the view is not linked to the window, furthermore, the window is not where it should be!
the image can be found here http://imgur.com/e4EXnpW
I started the xcode project without using storyboard, then created main.swift, AppDelegate.swift, ViewController.swift, and pasted each of the content the guy provided. However its not working.
Could someone kindly provide a reliable way to start an OSX App without
#NSApplicationMain ?
It looks like your code actually is working, but that there's a few other things you need to do to get it to work the way you want it to. You have one window that is being loaded from the MainMenu.xib in Interface Builder - that is the window with "911" in the title bar. You've got the second window that you are creating programmatically. That is the window in the lower left corner of the screen.
First, it looks like you still have a Window in your MainMenu.xib file. Click on MainMenu.xib, and when it opens in Interface Builder, look at the items on the left-hand pane. I'm guessing that there is a Window icon. You want to click on that and delete it.
After that you will just have the single window in the lower-left hand corner. It looks like a "view" that is unattached to a window because you haven't configured the window's styleMask property. You probably want a styleMask that looks like this:
let styleMask = NSTitledWindowMask
| NSClosableWindowMask
| NSMiniaturizableWindowMask
| NSResizableWindowMask
You say that the window also isn't where it is supposed to be. I don't know where you want it to be, but you can change its position and size by changing the contentRect parameter when you initialize it. Make a NSRect that positions and sizes your window where you want it, call it something convenient like myRect, and then initialize your window like this (this assumes you defined the styleMask constant from above):
newWindow = NSWindow(contentRect: myRect, styleMask: styleMask, backing: NSBackingStoreType.Buffered, defer: false)
That should do it. For an alternative version of main.swift, see this gist on github.

MacRuby + Interface Builder: How to display, then close, then display a window again

I'm a complete n00b with MacRuby and Cocoa, so keep that in mind when answering - I need lots of details and explanation. :)
I've set up a simple project that has 2 windows in it, both of which are built with Interface Builder. The first window is a simple list of accounts using a table view. It has a "+" button below the table. When I click the + button, I want to show an "Add New Account" window.
I also have an AccountsController < NSWindowController and a AddNewAccountController < NSWindowController class, set up as the delegates for these windows, with the appropriate button click methods wired up, and outlets to reference the needed windows.
When I click the "+" button in the Accounts window, I have this code fire:
#add_account.center
#add_account.display
#add_account.makeKeyAndOrderFront(nil)
#add_account.orderFrontRegardless
this works great the first time I click the + button. Everything shows up, I'm able to enter my data and have it bind to my model. however, when I close the add new account form, things start going bad.
if I set the add new account window to release on close, then the second time I click the + button, the window will still pop up but it's frozen. i can't click any buttons, enter any data, or even close the form. i assume this is because the form's code has been released, so there is no message loop processing the form... but i'm not entirely sure about this.
if i set the add new account window to not release on close, then the second time i click the + button, the window shows up fine and it is usable - but it still has all the data that i had previously entered... it's still bound to my previous Account class instance.
what am I doing wrong? what's the correct way to create a new instance of the Add New Account form, create a new Account model, bind that model to the form and show the form, when I click the + button on the Accounts form?
... this is all being done on OSX 10.6.6, 64bit, with XCode 3.2.4
The issue is that it doesn't create the window each time. Release on close is a bit of an annoying option and generally is only used if you know the window controller is also being released when the window closes. (Note I've never used MacRuby so I'll be giving code in Obj-C as I know that it is correct, hopefully you can convert it. I'll be assuming GC is on as it should be with MacRuby).
Now there are two ways to do this. I'm not entirely sure how your NIB/classes are set up as it could be one of two ways.
--
The first way to solve it is to use the outlets you use to reference the form elements to blank them out when you display the window again eg [myTextField setStringValue:#""]. If you're using cocoa bindings then it's a little trickier, but basically you have to make sure the bound object is blanked out. I would recommend against bindings though if you are new to Cocoa.
--
The second way is to make the AddNewAccountController class a subclass of NSWindowController. When you press the + button you would then create a new instance of it and display it (remember to store it in an ivar). The best way to do it would be as so:
if (!addAccountController) {
addAccountController = [[AddNewAccountController alloc] initWithWindowNibName:#"AddNewAccountController"];
[[addAccountController window] setDelegate:self];
}
[addAccountController showWindow:self];
This prevents a new instance being made if the window is already visible. You then need to implement the delegate:
- (void)windowWillClose:(NSNotification *)notification {
//If you don't create the account in the AddNewAccountController then do it here
addAccountController = nil;
}
Obviously you would need to move the window to a separate NIB called "AddNewAccountController". In this NIB make sure to set the class of the File's Owner to AddNewAccountController and then to connect the File's Owner's window outlet to the window.
When all this is set up, you will get a fresh controller/window each time. It also has the benefit of splitting up nibs and controllers into more focused units.
--
One last thing. While it is fine to do something like this in a window, you may want to eventually look at doing this via a sheet, as it would then prevent the possibility of the add account window getting hidden behind other windows.

Forcing Interface Builder to change class of objects(UIButton->UIControl)

I have a UIView filled with buttons that are all nicely hooked up to actions and outlets. However, in my infinite wisdom, I decided that I really would rather have the button behavior to be different and subclassed a UIControl.
My plan was to hop into Interface Builder, change the class of the buttons to my new UIControl subclass, and then be up and running. This would preserve all of outlet and action connections.
In IB (View Identity Inspector) when I type in my UIControl subclass into the class field, it reverts back to UIButton when I tab out. Any UIButton subclass works, but not a UIControl. I can go down the inheritance tree but not up....
The first plan was to go to XCode and change the superclass of my new control temporarily to UIButton, change the 'class' of my IB buttons, and then change the XCode code superclass back to UIControl. IB accepted and changed the class, but running the app gives me non-visible buttons. The IB Attributes inspector still shows it as a button.
Creating the control from scratch and rewiring works, but I was hoping to not rewire all the buttons if it could be avoided. (This is a change I was hoping to roll across multiple apps, so it is a bit more painful that it sounds)
Anyone know any way around this?
many thanks!
I'm a year late on this, but maybe it will help someone in the future. Perhaps you could open the .xib in a text editor and figure out what text you would have to change to get it to work (try it on a sample project first), then use find and replace to fix all of them at once.

Cocoa Pop-up Window Similar to iCal

I want to open an overlay window (pop up window) when a user selects a cell in my NSTableView similar to selecting an event in iCal. Selecting the event in iCal shows a Window to edit the event, but does so by smoothly animating the window open and adding an arrow pointing to the even in the underlying calendar. Does anyone know what is being used here? Is this a bunch of hidden/custom APIs or is this available for public use?
The editor pane appears to be a custom borderless, transparent window with a custom view (the view defines the shape and therefore the shadow it casts). Learn more here. You might even use MAAttachedWindow.
Regarding animation, it's as simple as asking the window's animator to animate the frame and the alpha value (grouping them together). You'll probably want to set everything up directly in its "start position" first (ie, while the window is off-screen, set its alpha to zero, and its frame to some smaller version so it "zooms in" a la iCal), then put it on screen and start the grouped animation:
[NSAnimationContext beginGrouping];
[[window animator] setFrame:someNewSlightlyLargerFrame];
[[window animator] setAlphaValue:1.0];
[NSAnimationContext endGrouping];
Once the grouping is ended, the animation will begin (asynchronously) and your code execution will continue. Something to think about is getting everything "staged" first (including making sure the subviews of your window are already updated beforehand, so they don't change in the middle of your animation ... unless you want them to).
So the two separate techniques you need to understand are a custom window and basic Cocoa animation.
If you're using OSX 10.7 and above, NSPopover will do the job you're looking for.
Are you talking about selecting even from a list at the bottom of iCal app?
Not sure what exactly you are referring to but there is an api for animating transformations within a timespan.
Looking at other Apple's applications, Apple's developers utilize the same api available to anyone else (mostly I guess). There is lots of stuff that can be customized and Apple customizes whatever is required until it looks right from design point of view ...

Resources