0

I would like to have a progress bar in a secondary window that stays active just like a NSAlert window. I especially like how it plays a sound when the user tries to click off of it.

I figured out how to force the window to stay active by invoking:

[[NSNotificationCenter defaultCenter] addObserver: self
                                         selector: @selector(windowChange:)
                                             name: NSWindowDidBecomeKeyNotification
                                           object: nil];

and then in the notification method I do:

-(void) windowChange:(NSNotification*) notification {
    NSWindow *window = [notification object];
    if (window == myMainWindow) {
        [myProgressWindow makeKeyAndOrderFront:nil];
    }
}

This doesn't do everything I'd like. Mostly I want to stop the user from pressing anything on my main window and to keep my progress bar window active/front.

-GW

GW.Rodriguez
  • 1,181
  • 8
  • 18
  • If I am understanding you right, what you are looking for is NSApplication's `-runModalForWindow:` method. It prevents interaction with anything in your app that isn't in that window until the modal loop is stopped. – Gerd K Sep 26 '13 at 04:56
  • That just might be it. I'll give it a try and get back to you. – GW.Rodriguez Sep 26 '13 at 05:22
  • So this didn't quite do it. It caused all other tasks to freeze. – GW.Rodriguez Sep 27 '13 at 04:33
  • Well, alert panels use exactly that method. And it certainly doesn't freeze tasks. The main event loop will not be running though, so NSTimers and other objects needing a runloop need to be configured properly. – Gerd K Sep 27 '13 at 14:59
  • Ohhhh. That's what it is then. I have a bunch of NSTimers running using the scheduledTimerWithTimeInterval:. How should I config it to still run? – GW.Rodriguez Sep 27 '13 at 19:14
  • Use the non-schedule variants to create the timers and manually add them. Check the 'Scheduling Timers in Run Loops' section in the NSTimer documentation. I think you need to add the timers to the `NSModalPanelRunLoopMode` mode. – Gerd K Sep 28 '13 at 01:50
  • Well I found something that'll work. Overriding windowDidMove and windowWillMove and using addChildWindow accomplishes basically what I want. The progress view is as big as the original so the user cant click anything, moving the main view moves the secondary view, and if the user moves the second view it snaps back to over the main. – GW.Rodriguez Sep 28 '13 at 05:27

1 Answers1

0

Try this one:

  -(void) windowChange:(NSNotification*) notification 

    {

        NSWindow *window = [notification object];

        if (window == myMainWindow) {

            [myProgressWindow makeKeyAndOrderFront:nil];

            for (NSView *item in [self.myMainWindow.contentView subviews])
            {
                if ([item isKindOfClass:[NSTextField class]] || [item isKindOfClass:[NSButton class]])
                {
                    [(id)item setEnabled:NO];
                }
            }

        }

    }
PR Singh
  • 653
  • 5
  • 15
  • Close. I like that it disables everything, but it's not quite what I'm looking for. Thanks though – GW.Rodriguez Sep 27 '13 at 04:26
  • will you explain little more that what are you looking for ?... i will try to do that.. – PR Singh Sep 27 '13 at 05:18
  • No prob. So if you have a blank cocoa app and run a NSAlert a window pops up. Notice that when you try to click off of it to the original window it makes a sound and doesn't allow you to switch windows. It keeps the alert window front and doesn't allow you to click anything else on the app. That's what I'm looking for. I don't need the sound, although that'd be cool. – GW.Rodriguez Sep 27 '13 at 05:54
  • have you used this before [NSApp runModalForWindow: myProgressWindow];, it is behaving same as alert panel. – PR Singh Sep 27 '13 at 09:12
  • I did. The problem is it halts all background processes. – GW.Rodriguez Sep 27 '13 at 19:13