I occasionally need a dialog that obtains two bits of information from the user and thought I would adapt db123’s suggestion from the following thread:
https://macscripter.net/viewtopic.php?id=48658
My script with db123s handler works as written:
-- use framework "Foundation"
-- use scripting additions
--> Can’t continue AEInteractWithUser
on main()
set dialogResult to my showDialog()
if dialogResult is missing value then
return
end if
set {stringOne, stringTwo} to {stringOne, stringTwo} of dialogResult
end main
on showDialog()
script theScript
use scripting additions
use framework "Foundation"
use framework "AppKit"
use framework "Carbon"
property ca : current application
property dialogWindow : missing value
property stringOneTextField : missing value
property stringTwoTextField : missing value
property cancelButton : missing value
property okButton : missing value
property stringOne : missing value
property stringTwo : missing value
property okClicked : false
on showDialog()
if current application's AEInteractWithUser(-1, missing value, missing value) ≠ 0 then
return missing value
end if
if ca's NSThread's isMainThread() then
my performDialog:(missing value)
else
its performSelectorOnMainThread:"performDialog:" withObject:(missing value) waitUntilDone:true
end if
if my okClicked then
return {stringOne:my stringOne as text, stringTwo:my stringTwo as text}
end if
return missing value
end showDialog
on performDialog:args
set stringOneLabel to ca's NSTextField's labelWithString:"One:"
stringOneLabel's setFrame:(ca's NSMakeRect(20, 85, 70, 20))
set my stringOneTextField to ca's NSTextField's textFieldWithString:""
stringOneTextField's setFrame:(ca's NSMakeRect(87, 85, 245, 20))
stringOneTextField's setEditable:true
stringOneTextField's setBordered:true
stringOneTextField's setPlaceholderString:"String One Default"
stringOneTextField's setDelegate:me
set stringTwoLabel to ca's NSTextField's labelWithString:"Two:"
stringTwoLabel's setFrame:(ca's NSMakeRect(20, 55, 70, 20))
set my stringTwoTextField to ca's NSTextField's textFieldWithString:""
stringTwoTextField's setFrame:(ca's NSMakeRect(87, 55, 245, 20))
stringTwoTextField's setEditable:true
stringTwoTextField's setBordered:true
stringTwoTextField's setPlaceholderString:"String Two Default"
set my cancelButton to ca's NSButton's buttonWithTitle:"Cancel" target:me action:"buttonAction:"
cancelButton's setFrameSize:{94, 32}
cancelButton's setFrameOrigin:{150, 10}
cancelButton's setKeyEquivalent:(character id 27)
set my okButton to ca's NSButton's buttonWithTitle:"OK" target:me action:"buttonAction:"
okButton's setFrameSize:{94, 32}
okButton's setFrameOrigin:{245, 10}
okButton's setKeyEquivalent:return
okButton's setEnabled:false
set windowSize to ca's NSMakeRect(0, 0, 355, 125)
set winStyle to (ca's NSWindowStyleMaskTitled as integer) + (ca's NSWindowStyleMaskClosable as integer)
set my dialogWindow to ca's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:(ca's NSBackingStoreBuffered) defer:true
dialogWindow's contentView()'s addSubview:stringOneLabel
dialogWindow's contentView()'s addSubview:stringOneTextField
dialogWindow's contentView()'s addSubview:stringTwoLabel
dialogWindow's contentView()'s addSubview:stringTwoTextField
dialogWindow's contentView()'s addSubview:cancelButton
dialogWindow's contentView()'s addSubview:okButton
dialogWindow's setTitle:"Dialog Title"
dialogWindow's setLevel:(ca's NSModalPanelWindowLevel)
dialogWindow's setDelegate:me
dialogWindow's orderFront:me
dialogWindow's |center|()
ca's NSApp's activateIgnoringOtherApps:true
ca's NSApp's runModalForWindow:dialogWindow
end performDialog:
on buttonAction:sender
if sender is my okButton then
set my stringOne to stringOneTextField's stringValue()
set my stringTwo to stringTwoTextField's stringValue()
set my okClicked to true
end if
my dialogWindow's |close|()
end buttonAction:
on controlTextDidChange:aNotification
set sender to aNotification's object()
if sender is my stringOneTextField then
if sender's stringValue() as text ≠ "" then
my (okButton's setEnabled:true)
else
my (okButton's setEnabled:false)
end if
end if
end controlTextDidChange:
on windowWillClose:aNotification
ca's NSApp's stopModal()
end windowWillClose:
end script
return theScript's showDialog()
end showDialog
main()
However, if I include use statements for ASObjC, the script throws an error. How can I fix this? Thanks.
I think it has to do with the fact the the use statements are already in the script object.
I don’t think you can have 2 of them in the same script file? not sure
I changed the script below to not have a script object.
use framework "Foundation"
use framework "AppKit"
use framework "Carbon"
use scripting additions
property ca : current application
property dialogWindow : missing value
property stringOneTextField : missing value
property stringTwoTextField : missing value
property cancelButton : missing value
property okButton : missing value
property stringOne : missing value
property stringTwo : missing value
property okClicked : false
on run {}
set dialogResult to my showDialog()
if dialogResult is missing value then
return
end if
set {stringOne, stringTwo} to {stringOne, stringTwo} of dialogResult
end run
on showDialog()
if current application's AEInteractWithUser(-1, missing value, missing value) ≠ 0 then
return missing value
end if
if ca's NSThread's isMainThread() then
my performDialog:(missing value)
else
its performSelectorOnMainThread:"performDialog:" withObject:(missing value) waitUntilDone:true
end if
if my okClicked then
return {stringOne:my stringOne as text, stringTwo:my stringTwo as text}
end if
return missing value
end showDialog
on performDialog:args
set stringOneLabel to ca's NSTextField's labelWithString:"One:"
stringOneLabel's setFrame:(ca's NSMakeRect(20, 85, 70, 20))
set my stringOneTextField to ca's NSTextField's textFieldWithString:""
stringOneTextField's setFrame:(ca's NSMakeRect(87, 85, 245, 20))
stringOneTextField's setEditable:true
stringOneTextField's setBordered:true
stringOneTextField's setPlaceholderString:"String One Default"
stringOneTextField's setDelegate:me
set stringTwoLabel to ca's NSTextField's labelWithString:"Two:"
stringTwoLabel's setFrame:(ca's NSMakeRect(20, 55, 70, 20))
set my stringTwoTextField to ca's NSTextField's textFieldWithString:""
stringTwoTextField's setFrame:(ca's NSMakeRect(87, 55, 245, 20))
stringTwoTextField's setEditable:true
stringTwoTextField's setBordered:true
stringTwoTextField's setPlaceholderString:"String Two Default"
set my cancelButton to ca's NSButton's buttonWithTitle:"Cancel" target:me action:"buttonAction:"
cancelButton's setFrameSize:{94, 32}
cancelButton's setFrameOrigin:{150, 10}
cancelButton's setKeyEquivalent:(character id 27)
set my okButton to ca's NSButton's buttonWithTitle:"OK" target:me action:"buttonAction:"
okButton's setFrameSize:{94, 32}
okButton's setFrameOrigin:{245, 10}
okButton's setKeyEquivalent:return
okButton's setEnabled:false
set windowSize to ca's NSMakeRect(0, 0, 355, 125)
set winStyle to (ca's NSWindowStyleMaskTitled as integer) + (ca's NSWindowStyleMaskClosable as integer)
set my dialogWindow to ca's NSWindow's alloc()'s initWithContentRect:windowSize styleMask:winStyle backing:(ca's NSBackingStoreBuffered) defer:true
dialogWindow's contentView()'s addSubview:stringOneLabel
dialogWindow's contentView()'s addSubview:stringOneTextField
dialogWindow's contentView()'s addSubview:stringTwoLabel
dialogWindow's contentView()'s addSubview:stringTwoTextField
dialogWindow's contentView()'s addSubview:cancelButton
dialogWindow's contentView()'s addSubview:okButton
dialogWindow's setTitle:"Dialog Title"
dialogWindow's setLevel:(ca's NSModalPanelWindowLevel)
dialogWindow's setDelegate:me
dialogWindow's orderFront:me
dialogWindow's |center|()
ca's NSApp's activateIgnoringOtherApps:true
ca's NSApp's runModalForWindow:dialogWindow
end performDialog:
on buttonAction:sender
if sender is my okButton then
set my stringOne to stringOneTextField's stringValue()
set my stringTwo to stringTwoTextField's stringValue()
set my okClicked to true
end if
my dialogWindow's |close|()
end buttonAction:
on controlTextDidChange:aNotification
set sender to aNotification's object()
if sender is my stringOneTextField then
if sender's stringValue() as text ≠ "" then
my (okButton's setEnabled:true)
else
my (okButton's setEnabled:false)
end if
end if
end controlTextDidChange:
on windowWillClose:aNotification
ca's NSApp's stopModal()
end windowWillClose:
Also, have you looked at Dialog Toolkit Plus by Shane Stanley.
It is an AppleScript Library. It’s very good
Is is available at https://latenightsw.com/freeware/
Thanks robertfern–that works great. I do use Shane’s AppleScript libraries, which are excellent, but there are instances where I need a standalone script.
Shane’s library scripts can be used in standalone scripts.
Thanks Ed–I didn’t know that. How would one go about including Shane’s library script in a standalone script.
In the Finder select your applet’s icon and control-click, select Show Package Contents from the popup. In the contents folder make a folder named “Library” (if it’s not already there) and inside the Library folder make a folder named “Script Libraries” (if that’s not already there) and put the library scptd file in that folder. (See below)
AppleScript will look there for libraries on compile and run.
“<YourApp.app>:Contents:Library:Script Libraries:<ScriptLibrary.scptd>”
Ed’s given you one way, but you can also use two other ways in Script Debugger:
-
Click the Bundle Export option Include used user script libraries and then export your script as run-only.
-
In the Contents section of the script’s Resources tab, click on Resources then control-click and choose Add Script Libraries Folder. Then drag your file from the Finder into the new folder, or control-click and choose Add existing file……
Thanks Ed and Shane. I’m going to use Dialog Toolkit in a script I’m currently working on.