-
All replies
-
Helpful answers
-
Aug 17, 2016 7:07 PM in response to ionahby red_menace,Cocoa does not support cascading or nested sheets - per Apple's Human Interface Guidelines, you need to close the first sheet before opening the second.
As for the beginSheetModalForWindow method, the current API uses a block (a closure/lambda/anonymous function used as a callback), but blocks are not supported in AppleScriptObjC. All is not lost though, you can just use an Objective-C helper category, since Objective-C can use blocks. Using a category is also handy in that it just extends an existing class, so you don't have to do anything but add it to your project. A couple I've been using for a while are the NSWindow+MyriadHelpers and NSAlert+MyriadHelpers categories from Myriad Helpers.
The NSWindow category uses the current beginSheetModalForWindow:completionHandler: method, while the NSAlert category uses the beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: method which is deprecated as of 10.10 Yosemite. For an example using the NSAlert+MyriadHelpers category, add the category .h and .m files to a new Cocoa-AppleScript project, add the following handlers, and call doSheet when the application finishes launching:
on doSheetStuff() set theAlert to current application's NSAlert's makeAlert:"Sheet Test" buttons:{"OK", "Whatever"} |text|:"This is a test... This is only a test..." theAlert's showOver:theWindow calling:"finishAlert:" end doSheetStuff on finishAlert:theButton log theButton -- the name of the button pressed end finishAlert: -
Aug 18, 2016 1:08 PM in response to red_menaceby red_menace,Myriad Helpers has been updated and is now compatible with OS X 10.11 El Capitan.
-
Aug 20, 2016 1:35 AM in response to red_menaceby ionah,@red_menace
[I could not find a minute to read your posts last 2 days]
…
I know Shane's site, Myriad Helpers and other stuff I'm already using.
But in the actual case, it's about a script in bundled format, not an XCcode project.
-
Aug 30, 2016 6:36 AM in response to ionahby red_menace,★HelpfulYou aren't going to have much fun without some Objective-C helpers. You can chain together alert sheets, but the beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo: method doesn't appear to return a button result code (so you are limited to the default "OK" button), and in my tests just adding buttons will crash the application (or the Script Editor).
From your previous posts I am going to guess that this won't do what you are wanting, but the following is an example using simple alert sheets:
use framework "Cocoa" property myWindow : missing value on run set myWindow to current application's NSWindow's alloc's initWithContentRect:{{200, 400}, {400, 200}} styleMask:7 backing:(current application's NSBackingStoreBuffered) defer:true tell myWindow to makeKeyAndOrderFront:me tell current application's NSAlert's alloc's init() its setMessageText:"Alert" its setInformativeText:"This is a test. It is only a test." its beginSheetModalForWindow:myWindow modalDelegate:me didEndSelector:"alertDidEnd:returnCode:contextInfo:" contextInfo:(missing value) end tell end run on alertDidEnd:alert returnCode:returnCode contextInfo:contextInfo alert's |window|'s orderOut:me -- hide the sheet first for better animation myWindow's endSheet:alert showSecondSheet() end alertDidEnd:returnCode:contextInfo: on showSecondSheet() tell current application's NSAlert's alloc's init() its setMessageText:"Another Alert" its setInformativeText:"This is a another test. It is still only a test." its beginSheetModalForWindow:myWindow modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell end showSecondSheet -
Aug 22, 2016 3:52 AM in response to red_menaceby ionah,I don't want to display 2 alerts on a main window.
Just to display a help alert as a sheet on a first alert.
Something like this:
-- show the main alert set theAlert to current application's NSAlert's alloc's init() tell theAlert its setDelegate:me its setShowsHelp:true its setMessageText:"Main alert message." its setInformativeText:"Main alert informative text." its setAlertStyle() its addButtonWithTitle:"OK" its runModal() end tell -- show the help alert on alertShowHelp:theAlert tell current application's NSAlert's alloc's init() its setMessageText:"Help alert message." its setInformativeText:"Help alert informative text." its runModal() --its beginSheetModalForWindow:theAlert modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell return true end alertShowHelp:
In the alertShowHelp handler, the its runModal() command runs fine.
If I replace it with the line below, the help alert will not show.
…But I'm beginning to guess that the trick is not possible…
-
Aug 22, 2016 7:30 AM in response to ionahby Hiroto,Hello
You'd need to specify alert's window obtained by NSAlert -window method as the beginSheetModalForWindow argument.
It would be something like the following in AppleScriptObjC. Not tested because I don't use AppleScriptObjC.
on alertShowHelp:theAlert tell current application's NSAlert's alloc's init() its setMessageText:"Help alert message." its setInformativeText:"Help alert informative text." its beginSheetModalForWindow:theAlert's window() modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell return true end alertShowHelp:
---
Here's PyObjC version tested with pyobjc 2.2b3 and python 2.6.1 under OS X 10.6.8.
#!/usr/bin/python # coding: utf-8 # # NSAlert alert help shown as sheet on parent alert window # from AppKit import * class AppDelegate(NSObject): def init(self): self = super(AppDelegate, self).init() return self def applicationDidFinishLaunching_(self, notif): try: NSApp.activateIgnoringOtherApps_(True) alert = NSAlert.alloc().init() alert.setDelegate_(self) alert.setShowsHelp_(True) alert.setMessageText_('Main alert message') alert.setInformativeText_('Main alert informative text') alert.addButtonWithTitle_('OK') alert.runModal() except: NSApp.terminate_(self) raise def applicationShouldTerminateAfterLastWindowClosed_(self, app): return True def applicationShouldTerminate_(self, sender): return NSTerminateNow def alertShowHelp_(self, alert): help = NSAlert.alloc().init() help.setMessageText_('Help alert message') help.setInformativeText_('Help alert informative text') help.beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_( alert.window(), self, None, None ) return True def main(): app = NSApplication.sharedApplication() delegate = AppDelegate.alloc().init() app.setDelegate_(delegate) app.run() main()Good luck,
H
-
Aug 30, 2016 6:37 AM in response to ionahby red_menace,★HelpfulAs Hiroto mentioned, you need to use the alert's window - don't forget to put pipes around the term 'window', since it is a reserved word. For some reason my Script Editor crashes quite a bit when going back and forth from Xcode with this, but the following seems to be stable from the Script Editor when run in the foreground (it still goes against Apple's HIG):
use framework "Cocoa" property theWindow : missing value property myAlert : missing value on run set theWindow to current application's NSWindow's alloc's initWithContentRect:{{200, 400}, {400, 200}} styleMask:7 backing:(current application's NSBackingStoreBuffered) defer:true tell theWindow to makeKeyAndOrderFront:me -- show the main alert set myAlert to current application's NSAlert's alloc's init() tell myAlert its setDelegate:me its setShowsHelp:true its setMessageText:"Main alert message." its setInformativeText:"Main alert informative text." its beginSheetModalForWindow:theWindow modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell end run on alertShowHelp:theAlert -- show the help alert tell current application's NSAlert's alloc's init() its setMessageText:"Help alert message." its setInformativeText:"Help alert informative text." its beginSheetModalForWindow:(theAlert's |window|()) modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell return true end alertShowHelp: -
Aug 29, 2016 4:57 PM in response to red_menaceby ionah,Sorry, folks.
I can't do nothing with your examples.
I'm totally confused and not able to understand how all that is working.
I'm giving up.
After all, it's not so important.
Thanks for your time!
-
Aug 29, 2016 5:07 PM in response to ionahby red_menace,You couldn't get the script to work? It was just a slight variation on the one you posted - the first alert was changed to a sheet on the application window, and the help was changed to a sheet over the first alert's window.
NSAlert's runModal will do just that (run a modal alert not attached to any window), while the beginSheetModalForWindow: method will run the alert as a modal sheet over the specified window, calling the specified didEndSelector: when a button is pressed, so you need to pick one or the other.
-
Aug 30, 2016 2:58 AM in response to red_menaceby ionah,@ red_menace
It works!
Thank you for your encouragements.
As I said before, I don't want 3 windows.
This is the definitive code:
use framework "AppKit" on run -- show the main alert set mainAlert to current application's NSAlert's alloc's init() tell mainAlert its setDelegate:me its setShowsHelp:true its setMessageText:"Main alert message." its setInformativeText:"Main alert informative text." its runModal() end tell end run on alertShowHelp:parentAlert -- show the help alert tell current application's NSAlert's alloc's init() its setMessageText:"Help alert message." its setInformativeText:"Help alert informative text." its beginSheetModalForWindow:(parentAlert's |window|()) modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell return true end alertShowHelp:
I hope this will help some one else…
-
Aug 30, 2016 3:02 AM in response to ionahby Hiroto,Hello
My AppleScriptObjC snippet should have been as follows as red_menace explained. Terminalogy conflict on term "window" must be evaded by using enclosing pipes around symbol; i.e., |window|() in lieu of window().
on alertShowHelp:theAlert tell current application's NSAlert's alloc()'s init() its setMessageText:"Help alert message." its setInformativeText:"Help alert informative text." its beginSheetModalForWindow:theAlert's |window|() modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value) end tell return true end alertShowHelp:
By the way, as far as I have tested under OS X 10.6.8, passing (missing value) to didEndSelector reports error in console. The following version does not throw error.
(I used positional parameters syntax here because there's no such thing as interleaved parameters syntax in AppleScript 2.1.2 under OS X 10.6.8)
on alertShowHelp_(alert) set alert_help to current application's NSAlert's alloc()'s init() tell alert_help its setMessageText_("Help alert message.") its setInformativeText_("Help alert informative text.") its beginSheetModalForWindow_modalDelegate_didEndSelector_contextInfo_(¬ alert's |window|(), ¬ me, ¬ "alertDidEnd:returnCode:contextInfo:", ¬ missing value) end tell return true end alertShowHelp_ on alertDidEnd_returnCode_contextInfo_(alert, ret, cinfo) return end alertDidEnd_returnCode_contextInfo_Good luck,
H
PS. As for pyobjc script, you may simply run it in terminal. E.g,, save the script as ~/Desktop/a.py and in Terminal:
python ~/Desktop/a.py
or
~/Desktop/a.py
/H
-
Aug 30, 2016 5:07 AM in response to Hirotoby ionah,@Hiroto,
There's no error in console under Yosemite.
Only this warning: "30/08/2016 13:59:56,464 Script Debugger[28820]: CoreAnimation: warning, deleted thread with uncommitted CATransaction; set CA_DEBUG_TRANSACTIONS=1 in environment to log backtraces."
Is it a problem?
Thanks for the tip to run Python code.
-
Aug 30, 2016 5:21 AM in response to ionahby Hiroto,Hello
Good to hear ASObjC bridge has been somehow refined under 10.10. For the record, the following is the error I get under OS X 10.6.8 when passing missing value to selector argument in ASObjC.
[NSAlert beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:]: unable to set argument 4 because the AppleScript value <NSAppleEventDescriptor: 'msng'> could not be coerced to type :.
As for the warning about CoreAnimation, I'm not sure but I'd disregard it as the irrelevant.
All the best,
Hiroto
-
Aug 30, 2016 6:35 AM in response to Hirotoby ionah,Hiroto wrote:
As for the warning about CoreAnimation, I'm not sure but I'd disregard it as the irrelevant.
That's what I thought, because every runModal() method triggers this warning.
I really appreciate the interest you're showing for my query.