how to write a toggle method to open/close a window? - cocoa

I have an NSPanel window in my app that I want to toggle open and close with a button on the toolbar. This seems like a fairly basic operation, and indeed one I see in many apps (like Inspector views). However, I'm struggling to find the right way to do this.
I've looked at the performClose: and the makeKeyAndOrderFront: methods, but I can't work out how to make them work in my method. Basically, I want something like this
-(IBAction)togglePanel:(id)sender {
if ( ) //what do i put here to assess if _myPanel is already open?
// tell _myPanel to close
else {
//tell _myPanel to open
}
}

Answering my own question, here. But got what I wanted thus:
- (IBAction)togglePanel:(id)sender {
if (_myPanel.isVisible == 0)
[_myPanel makeKeyAndOrderFront:self];
else {
[_myPanel performClose:self];
}
}

Related

Mac NSTextField won't resign firstResponder

I have a window with some NSTextFields. When I click in one and edit the value and press return, I want the focus to go back to what it was before. I don't want the blue ring around the text field and I don't want further keystrokes going to that text field. I would have thought this would happen automatically.
I tried these, and none of them work
sender.resignFirstResponder()
sender.window?.makeFirstResponder(nil)
InspectorWindowController.window?.makeFirstResponder(nil)
AnotherWindowController.window?.becomeFirstResponder()
I'm doing these at the end of my IBAction associated with the text field. Maybe I have to do it from somewhere else?
Thanks
I figured this out. I guess the sent action is happening on another thread. So you have to call makeFirstResponder using Dispatch async.
DispatchQueue.main.async { //omg
sender.window?.makeFirstResponder(nil)
}
I needed to dismiss first responder in my SwiftUI macOS app and here what I found working in a way I need:
func controlTextDidEndEditing(_ obj: Notification) {
DispatchQueue.main.async {
guard let window = self.textField.window else {
return
}
// https://stackoverflow.com/questions/5999148/how-to-determine-whether-an-nssearchfield-nstextfield-has-input-focus
// We need to make sure that our text field is still first responder.
guard let textView = window.firstResponder as? NSTextView,
textView.delegate === self.textField else {
return
}
window.makeFirstResponder(nil)
}
}

How to show NSWindow only once in a document based cocoa application?

- (void)showPromotionWindow
{
[_promotionWindow showWindow:self];
[_promotionWindow.window makeKeyAndOrderFront:self];
}
My project is document based application, so when call showPromotionWindow, each document window will launch a window, but i want only launch the window once for multiple document. How to implement this?
Edit
I found one method is to custom this window such as PromotionWindow, and then check if all the windows contains a PromotionWindow:
for(id window in [[NSApplication sharedApplication]windows])
{
if([[window className]isEqualToString:#"PromotionToolsWindow"])
{
}
}
Edit2
Another method is to use static
static PromotionWindow *promotionWindow;
Do you have any other better methods?

How to stop NSPanel from stealing input of another app

I have an NSPanel. It's purpose is to sit on top of everything in all spaces and it does that just fine.
I don't want it to ever become firstResponder and take focus from another app.
I sub classed NSPanel like so
class SomePanelClass: NSPanel {
override var acceptsFirstResponder: Bool{
return false
}
}
When the window shows or I drag it around the app I was in still appears to have focus and it's name is in the menu but keystrokes do not register in that app until I click back into it's window.
Is there something else I can do to prevent my app and panel from stealing input?
You probably want to override canBecomeKeyWindow on your Panel subclass to return NO.
- (BOOL) canBecomeKeyWindow {
return NO;
}

How to focus window after show?

I have window with global shortcut registered:
RegisterHotKey(SHOWHIDE_HOTKEY, wxMOD_CONTROL, VK_OEM_3);
with it's handle looking like this:
if (IsShown()) {
Hide();
} else {
Show();
SetFocus();
}
The hiding/showing of the window works fine, the focus part doesn't. Any ideas how can I achieve it?

I need assistance with xcode buttons

So I'm trying to make an event happen with buttons in xcode, and it's working fine, and executing the way I want it to, but now I want a different section of code to run if the button is not being pushed. I don't know how to test for if a button is NOT being pushed. Any ideas?
While a NSButton is pressed its state is non-zero.
if (myButton.state) {
// My button is pushed!
}
Here's something that can help you. Define a var ,notPushed whose value can be checked to see if button is called or not.
var notPushed:Bool=true
#IBAction func buttonPressed(sender:UIButton)
{
//....
notPushed=false
}
To check wether the button is pressed :
if notPushed==true{
//...
} else {
//...
}
Link your button to the buttonPressed.

Resources