Edit db123's dialog for use with ASObjC

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. :slight_smile: 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.