Why the splash window can’t show before the App launch? - cocoa

I want to show a splash Screen before the App lunch. First I make the SplashWindow subclassing the NSWindow, the code is :
- (id)initWithContentRect(NSRect)contentRect
styleMask(unsigned int)aStyle
backing(NSBackingStoreType)bufferingType
defer(BOOL)flag {
self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[self setBackgroundColor:
[NSColor clearColor]];
[self setLevel: NSStatusWindowLevel];
[self setAlphaValue:1.0];
[self setOpaque:NO];
[self setHasShadow: YES];
return self;
}
and then in the awake from nib in the main app controller:
loadWindow = [[NSWindow alloc] initWithContentRect:[loadWindow frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
[loadWindow setContentView:theView];
[loadWindow setHasShadow:YES]; [
loadWindow setLevel:NSStatusWindowLevel];
[loadWindow makeKeyAndOrderFront:self];
and then I let the loadWindow closed after 3 secondes, I used the method [loadWindow orderOut:self], but when the splash window closed , the mainwinow didn't show . what am I missing? My App is a multi_Documents . and in the mainMenu.nib there was one window(loadwindow),in IB I have connected up the loadWindow outlet in the main controller. I have also connected the view and image. and I changed another way : in the delegate method:applicationWillFinishLaunching: I orderFront the loadWindow , in the method:applicationDidFinishLaunching: I orderOut the loadWindow after 3 seconds, but the mainWindow didn't show too.Somebody can give some advice or codes the result the problem? Thank you very much!

Answer to title: Because your app isn't running yet. An application that isn't running can't do anything.
Serious answer to question:
First, you don't need to subclass NSWindow.
Second, you aren't instantiating your subclass, you're instantiating NSWindow. That's why you're not getting your subclass's behavior. (And this is what you should be doing, since you don't need the subclass.)
Third, you're trying to ask a window that doesn't exist yet for the frame you'll use to create it. loadWindow is nil until after you create something and store it there.
Fourth, because you are asking nil for its frame, you are getting a garbage rectangle back. Then you create a window with this garbage rectangle. Unsurprisingly, when you put this window on the screen, it appears in a random position (probably off-screen) with a random size (probably either too large to create or negative).
Fifth, what makes you think that telling a window to order out would cause some other window to order in? How is it supposed to know what window to order in?
Leaving aside the undeniable reality that the very existence of a splash screen punishes the user for using your application, you should be using NSWindowController to load the window and to do your set-up such as setBackgroundColor: and setLevel:. And in your timer method, where you order out the splash window, you must also explicitly order in the main window.

I don't see anything that would make another window show in the code you posted. Why don't you try sending your main window makeKeyAndOrderFront:?

Related

NSWindow won't draw immediately after app launch

The problem: Attempting to display a window with text from applicationWillFinishLaunching will NOT draw itself if other processor-intensive non-UI code is immediately called.
Background: I have a helper app that when launched may or may not interact with the end user. While it is "deciding" if it needs to put up a window to ask user questions, there may be anywhere from 1 second to 10 seconds that elapse (after launch it's off in non-UI capable library code communicating over the internet).
So I wanted to be kind to the user and put up a "mini-alert"* window with "working, please wait...", prior to heading into that library code, which I will dismiss once that processing has elapsed.
It seems as if the app itself doesn't have time after launch to even draw this mini-alert (it's just an NSWindow, with an NSView, some text, and no buttons).
If after the library code returns and want to put up either an error alert or a query window for the user -- then at that point the mini-alert draws as expected. However, if I close the mini-alert (see below) and then put up an NSAlert -- the mini-alert doesn't have enough time to dismiss itself.
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[NSApp activateIgnoringOtherApps:YES];
briefAlertWindowController = [[NSWindowController alloc] initWithWindowNibName:#"BriefAlertWindow"];
[[briefAlertWindowController window] center];
[briefAlertWindowController showWindow:self ];
[[briefAlertWindowController window] orderFront:self ];
[[briefAlertWindowController window] display];
[[briefAlertWindowController window] makeKeyAndOrderFront:nil];
}
and dismissing the mini-alert:
- (void)dismissMiniAlert
{
NSWindow * theWindow = [briefAlertWindowController window];
[theWindow orderOut:nil];
}
NOTE that neither NSWindow not NSWindowController have been derived/subclassed for this mini-alert.
I'm using the term "mini-alert", because I've noticed people get annoyed about the concept of a "splash screen". While the functionality IS similar -- I'm really just trying to let the user know that an unavoidably long operation is taking place.
It sounds like a threading problem. The splash window can't draw itself on the main thread because the main thread is busy doing the processor-intensive operation. Properly, your processor-intensive stuff should all be happening on a background thread. If you can't do that, you need at least to get off the main thread long enough to give the runloop a chance to draw your window. Just introduce a delay.

AppDelegate stops getting windowDidResize

I have a single window cocoa app. In appDidFinishLaunching I have [[self window] setDelegate: self]. When the app first launches windowDidResize gets called without issue. After a few actions, it doesn't get called again. I haven't closed the window or called anything to do with the window. Haven't changed the delegate, window or self. If I drop in a few
NSLog(#"Window: %# Self: %# Delegate: %#", [self window], self, [_window delegate]);
it's exactly the same before and after it stops working. I do do a fair bit with the notification center, posting and acting on my own notifications but delegates don't rely on notification center, correct? Any tips on figuring out what's happening here?

Cocoa get main window

I want to create 3 windows like this:
NSWindow *win1 = [[NSWindow alloc] initWithContentRect:rect1
styleMask:uiStyle
backing:backingStoreStyle
defer:NO];
and make one of them the main window, then get the main window, but I always get nil.
[win1 makeKeyAndOrderFront:win1];
[win2 makeKeyAndOrderFront:win2];
[win3 makeKeyAndOrderFront:win3];
[win2 makeMainWindow];
And all of these are nil:
NSLog(#"%#", [app mainWindow]);
NSLog(#"%#", [win1 isMainWindow]);
NSLog(#"%#", [win2 isMainWindow]);
NSLog(#"%#", [win3 isMainWindow]);
I tried your code. It does return an instantiated NSWindow object. I didn't get nil at all. Can you please post more context to code snippet?
Secondly, it is far easier and manageable to create window in IB. Thirdly, check - (BOOL)canBecomeMainWindow before passing it the message makeMainWindow.
If you want to create custom windows programaticaly, I would suggest create a Window in MainMenu.xib. Get it's IBOutlet, for example window. Then create your windows win1, win2 etc and add then as child windows to your window using addChildWindow.

How to create a QTMovieView within an NSWindow that is able to be moved and resized within that window?

I am creating a Cocoa NSWindow, inside this (via IB) are a QTCaptureView, QTMovieView and various buttons and text fields.
Programmatically, I have done the following:
Created a new QTMovie:
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError
{
QTMovie *movie = [QTMovie movieWithURL:url error:outError];
if (movie){
[self setMovie:movie];
}
return (movie != nil);
}
and then set up the QTMovieView accordingly:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[movieView setShowsResizeIndicator:YES];
[[movieView window] setShowsResizeIndicator:NO];
mainWindow = [aController window];
[[mainWindow contentView] addSubview:movieView];
}
The movie plays fine and my web cam is captured and displayed.
I have two problems that I can not seem to solve;
I would like to resize the QTMovieView according to the QTMovie Aspect ratio. I kind of do this within IB but the QTMovieView window remains the same size, only the movie plays at the desired size.
I would also like to resize and move the QTMovieView around the NSWindow.
I have searched the web and haven't found an answer, so most probably it's not something that can't be done but a problem with my code.
I have been working from the 'QTKit Application Tutorial' document.
[Edit 25/05/2012]
On page 28 onwards it describes how to resize the window to the movies natural size attribute. I followed this but the main window resized and not the QTMovieView window.
[[movieView window] setContentSize:contentSize];
So I guess my understanding was incorrect, and the QTMovieView window is the main window. There is NO additional child window that the QTMovieView window sits in, just the one I placed it in!
[Edit 26/05/2012]
In Cocoa there is only one window and there is no concept of child windows!
To allow the QTMovieView to be dragged you have to get it to accept mouse events.
To do this you have to subclass it and override;
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
Basically read Apples 'Handling Mouse Events' document.
As for resizing, I'm working on that now.
[End Edit]
Any ideas would be most appreciated.
Thanks.

Gray border when using NSBorderlessWindowMask

Whenever I try to create a custom window using NSBorderlessWindowMask and set an NSView (for example an NSImageView) as its contentView, I get a 1px gray border around the NSView and I don't seem to be able to get rid of it.
I have followed several approaches including Apple's RoundTransparentWindow sample code as well as several suggestions on StackOverflow.
I suspect the gray border is either coming from the window itself or the NSView.
Have any of you experienced this problem or do you have a possible solution?
The code is fairly straightforward. This is the init method of the custom window:
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
if (self != nil) {
[self setAlphaValue:1.0];
[self setBackgroundColor:[NSColor clearColor]];
[self setOpaque:NO];
}
return self;
}
To test this, in IB I place an NSImageView in that custom window WITHOUT border and yet the image in the NSImageView has a border. The same goes for other NSView subclasses, such as NSTextField, NSTableView.
In addition, I also noticed that the same is happening with the sample application (RoundTransparentWindow) of Apple. Is it even possible to draw an NSView in a custom window without a 1px border?
Thanks
Are you sure this happens when you use a regular NSView with no drawing? I bet not. Other controls (like NSImageView)have borders. Maybe you should double check to make sure they're turned off whe possible.
Update - How do you get your view into your window? You don't include that code. I created a basic test project (download it here) with an image well and it works just fine. See for yourself.

Resources