Is it possible to get a NSTextDidChangeNotification in Xcode Cocoa-Applescript App?

Discussion in 'Mac Programming' started by jpefjr, Dec 11, 2011.

  1. macrumors regular

    jpefjr

    Joined:
    Jul 8, 2008
    #1
    I was wondering if it was possible for a Cocoa-Applescript app to receive NSTextDidChangeNotifications? I've looked at the NSNotificationCenter documentation and specifically at the addObserver:selector:name:eek:bject: method but don't see how I could get the parameters for it.

    I assume I'd need something like this:
    Code:
    tell defaultCenter() of current application's NSNotificationCenter
        addObserver_selector_name_object_(...)
    end tell
    
    But I'm not even sure it's possible to pass an Applescript function as an observer. And if so is there a syntax I could use for the textDidChange selector? And would I use the following for the name parameter?:
    Code:
    current application's NSTextDidChangeNotification
    And the object parameter would be the property that I associated with the NSTextField in Interface Builder?

    And just in case I'm looking at the problem wrong, I have a "Connect" button that I want to keep disabled until the user has at least typed something into both the username and hostname fields. If I could get the textDidChange notifications for those text fields I could check and see if both fields are not empty and then call connectButton's setEnabled_(true). Is there a better way to go about doing that?
     
  2. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #2
    You can add a delegate method to get the notification - see the NSTextDelegate Protocol Reference. You might also be able to bind the value of the text field to the button's enabled property.
     
  3. thread starter macrumors regular

    jpefjr

    Joined:
    Jul 8, 2008
    #3
    Thanks for the reply. I know I could add a delegate in an objective-C program but I'm writing an Applescript program so I can't figure out how to add the delegate.
     
  4. macrumors 65816

    Partron22

    Joined:
    Apr 13, 2011
    #4
    Going thru NSWorkspace to get the NSNotificationCenter works for disk events:
    Code:
    set ws to current application's NSWorkspace's sharedWorkspace()
    set pNotificationCenter to ws's notificationCenter()
    
    if selector is equal to "add" then
    	pNotificationCenter's addObserver_selector_name_object_(me, "diskMountedUnmountedorRenamed_:", "NSWorkspaceDidMountNotification", missing value)
    end if
    That beautifully titled 'diskMountedUnmountedorRenamed_:' is a straight Applescript function.
    Code:
    on diskMountedUnmountedorRenamed__(sender)
    	beep ()
    end diskMountedUnmountedorRenamed__
    You may have to fiddle with the number of args the Applescript function takes depending on the notification you're after.
     
  5. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #5
    You connect the delegate to your script object the same as in Objective-C. The methods are also the same, just the naming conventions are a little bit different - refer to the AppleScriptObjC Release Notes for translating the method definitions, for example:

    Code:
    on textDidChange_(aNotification)
    	-- do your stuff
    end textDidChange_
     
  6. thread starter macrumors regular

    jpefjr

    Joined:
    Jul 8, 2008
    #6
    Thanks guys. I'm just blown away by how powerful and flexible Applescript. Time to go play with my program. :)
     
  7. thread starter macrumors regular

    jpefjr

    Joined:
    Jul 8, 2008
    #7
    Well, I can't seem to get notifications.

    In my applicationWillFinishLanching_() I have:

    Code:
    property hostnameTextBox : missing value
    .
    .
    .
    set ws to current application's NSWorkspace's sharedWorkspace()
    set pNotificationCenter to ws's notificationCenter()
    pNotificationCenter's addObserver_selector_name_object_(me, "textChanged_:", "NSTextDidChangeNotification", hostnameTextBox)
    
    And then after that I have:
    Code:
        on textChanged__(sender)
            log "Text Changed"
        end textChanged__
    
    hostnameTextBox is the Referencing Outlet setup in IB by ctrl-dragging from the App Delegate box to the text field.

    Any suggestions as to what I'm doing wrong? Thanks!
     
  8. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #8
    You have an extra underline in the selector parameter (the selector uses the same naming as the equivalent Objective-C method, i.e. textChanged:), but all you should have to do is connect the text field's delegate outlet to your AppDelegate and add a on textDidChange_(aNotification) handler.
     
  9. macrumors 603

    Joined:
    Aug 9, 2009
    #9
  10. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #10
    oops, after looking at one of my old projects I had a bit of a goof there, and must apologize for sending you in the wrong direction - I referred you to the NSText Delegate stuff instead of the NSTextField Delegate stuff. NSObject has a controlTextDidChange: method that should be what you are looking for, so by connecting your text field's delegate outlet to the AppDelegate and adding

    Code:
    	on controlTextDidChange_(aNotification)
    		log "controlTextDidChange_"
    	end textDidChange_
    you should get a notification when the text field changes.
     
  11. thread starter macrumors regular

    jpefjr

    Joined:
    Jul 8, 2008
    #11
    Red Menace,
    thank you very much - that's got it! I did as you said and created a controlTextDidChange_() method, used IB to connect the delegate of the my NSTextField to the AppDelegate and sure enough, every time I type into the text field the controlTextDidChange_() function gets called.

    Thanks again for all the help.
     

Share This Page