You are not logged in.
I'm trying to convert an old ASS app to ASobjC.
Seems that many things aren't that easy (for me) as they used to be be.
The old code is:
Applescript:
set pPanel to window "progressPanel"
tell pPanel
set textField to text field 1
set content of textField to ("Converting titles") as string
end
display panel window "progressPanel" attached to window "main"
set i to 0
repeat with titlePath in pathNameList
set content of textField to ("Converting title " & i & " of " & nodeCount) as string
...
end
close panel window "progressPanel"
or
Applescript:
set startUpPanel to (window "startUpPanel")
tell startUpPanel
set background color to dark_WindowColor
center
set toolName to (text field "startUpToolName")
set (content of toolName) to "Start Check"
tell progress indicator 1 to start
set visible to true
end tell
repeat
set (content of toolName) to "A"
...
set (content of toolName) to "B"
...
end
tell progress indicator 1 of startUpPanel to stop
hide startUpPanel
I can't find any working examples :-(
Offline
It can be a pain when you're from ASS and move to ASObjC. While ASS was always trying to keep it's syntax AppleScript style and also the object's design strict to AS designs, ASObjC is more like an alien within AppleScript which makes it very difficult at first.
The 1:1 ASObjC code of ASS sheet is the NSApp's beginSheet: method. Showing an window/panel as sheet is not an window task but technically an application task. The method to show the window is beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: (reed more…).
However (NSApp) sheets are deprecated and shouldn't be used any more. If you want to update from ASS to ASObjC I wouldn't use old deprecated code and go for an normal modal window.
Last edited by DJ Bazzie Wazzie (2018-08-07 08:50:13 pm)
Offline
However sheets are deprecated and shouldn't be used any more.
I think you might be mis-reading the documentation -- sheets are not deprecated. What is deprecated is showing them using NSApplication's beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo: -- the recommended way is to use NSWindow's beginSheet:completionHandler: method.
The problem for scripters, though, is that the latter uses blocks, which can't be used in AppleScript.
There are two possible solutions. One is to keep using the old method. It's a soft deprecation more about promoting the new approach, IMO, and I'd be very surprised if it went away anytime soon, or at least without considerable warning.
The other solution is to use my Myriad Helpers here:
https://www.macosxautomation.com/apples … lpers.html
It has an Objective-C category called NSWindow+MyriadHelpers that wraps the new method in code that makes it suitable (and simple) to use from AppleScript:
Applescript:
theSheet's showOver:mainWindow
There's also a similar NSAlert+MyriadHelpers category for alerts.
It's just a matter of dragging the relevant .h and .m files into the Xcode project.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
I think you might be mis-reading the documentation
Better said; poor wording from my side or I may have taken the ASS->ASObjC conversion too literal. Anonymous C functions (known as blocks in Objective-C) are a no-go in ASObjC and will never be supported by technicality. The only way without help from 3rd party code is using the deprecated NSApp method.
Another difference is that the ASS sheet is application based, which means it can be queued. Only the NSApp's deprecated method can be queued and is identical to ASS implementation, not the NSWindow method. They're technically not the same even if they carry the same name (and behave differently).
There tons of UI libraries available with alternatives that are close or identical to the ASS solutions but a 1:1 conversion without 3rd party code is impossible. Therefore my statement "sheets are deprecated and shouldn't be used any more." is still valid for an out-of-the-box ASObjC solution.
p.s. I'll edit my previous topic to make it more clearer.
Offline
Therefore my statement "sheets are deprecated and shouldn't be used any more." is still valid for an out-of-the-box ASObjC solution.
Really, it's not. If you want to show a window as a sheet, you can still use the block-based API, just passing missing value for the block:
Applescript:
mainWindow's beginSheet:customWindow completionHandler:(missing value)
You don't actually need the block; you can put any continuation code in the buttons' action handlers.
For alerts it's similar:
Applescript:
on showAlertSheet:sender
set theAlert to current application's NSAlert's alloc()'s init()
tell theAlert
its setMessageText:"An alert"
its setInformativeText:"Blah blah blah"
set okButton to its addButtonWithTitle:"OK"
okButton's setAction:"doOK:"
okButton's setTarget:me
set cancelButton to its addButtonWithTitle:"Cancel"
cancelButton's setAction:"doCancel:"
cancelButton's setTarget:me
its beginSheetModalForWindow:theWindow completionHandler:(missing value)
end tell
end showAlertSheet:
on doOK:sender
theWindow's endSheet:(sender's |window|())
-- do whatever
end doOK:
on doCancel:sender
theWindow's endSheet:(sender's |window|())
-- do whatever
end doCancel:
That said, Myriad Helpers makes the whole process so much simpler, I'm not sure why anyone would bother with the hard way.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
It can't be queued and completion handler was used in ASS so it's not the same as ASS sheets.
Last edited by DJ Bazzie Wazzie (2018-08-08 06:28:30 am)
Offline
It can't be queued
For sure -- the approach has to be quite different. And it's made more complicated by the fact that these days there's no simple way to force an update to the UI for the duration of a method that handles an event.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
I can't find any working examples :-(
Download Myriad Helpers and add the NSWindow+MyriadHelpers files to your project.
Find the CustomSheetTest.applescript file and add a property like this:
Applescript:
property textField : missing value
And change the showCustomSheet: handler to this:
Applescript:
on showCustomSheet:sender -- triggered by button in window
customWindow's showOver:mainWindow
repeat with i from 1 to 10
(textField's performSelectorOnMainThread:"setStringValue:" withObject:("Progress " & i) waitUntilDone:true)
delay 1
end repeat
mainWindow's endSheet:customWindow
end showCustomSheet:
Now in IB go to MainMenu.xib, control-click on the Custom Sheet Test object, and connect the textField outlet to the text field on the Custom Window, where it says "Custom sheet".
Run, click Show More, then click Show custom sheet.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
Hi,
I would like to know how to close a sheet Window after finishing a process, for example I am uploading a photo and a sheet Window is displayed saying "Wait for the photo to load" so when you finish loading the photo this sheet Window can close without the need to hit the "OK" button or any other.
I use this:
Applescript:
set alert to current application's NSAlert's alloc's init()
tell alert
its setMessageText:""
its setInformativeText: ""
its setAlertStyle:2
its setShowsSuppressionButton:false
its beginSheetModalForWindow:theWindow modalDelegate:me didEndSelector:(missing value) contextInfo:(missing value)
end tell
Offline
You call -endSheet:. It the window showing the sheet is mainWindow, then:
Applescript:
mainWindow's endSheet:(mainWindow's attachedSheet())
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
Thanks @Shane Stanley, working like a charm!
one more question:
Is there any way to insert a progress bar or an indeterminate progress indicator, if so how would it be done?
Offline
Either use a window instead of an alert as the sheet, or add it as the alert's accessoryView.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
I never used alert's accessoryView but I will try, thanks!:)
Offline
or add it as the alert's accessoryView.
If not asking too much could you give me an example?
Offline
If the view you want to appear in the alert is called someView, it's:
Applescript:
alert's setAccessoryView:someView
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
If the view you want to appear in the alert is called someView, it's:
Applescript:
alert's setAccessoryView:someView
Thanks for the answer,
Honestly I could not, alias I did not quite understand how would add a Progress Indicator there a Panel Sheet.
Offline
You call -endSheet:. It the window showing the sheet is mainWindow, then:
Applescript:
mainWindow's endSheet:(mainWindow's attachedSheet())
Is there any way to launch the App with a certain window and after a few seconds this window will close automatically and open a second window? if so how could i do?
I know I can use
Applescript:
orderOut_ (me)
to hide and
Applescript:
makeKeyAndOrderFront_ (me)
to show another window.
but how can i close the first automatically after a few seconds?
Offline
You can use an NSTimer.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
thanks for the help Shane.
Offline
If the view you want to appear in the alert is called someView, it's:
Applescript:
alert's setAccessoryView:someView
Is there any way to display a sheet window without the app icon?
Offline
You can display any window as a sheet, so it's just a matter of building your own window.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
@shane,
Would it be too much to ask you for an example?
Offline
It's not code -- you create a new window in Xcode. Add whatever buttons you want, and connect them to handlers that close the sheet. Then have your main window call beginSheet:completionHandler:, passing an outlet to the sheet window and missing value.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline
@shane,
I try this but not working:
[applescript]script AppDelegate
property parent : class "NSObject"
-- IBOutlets
property theWindow : missing value
property Window : missing value ---outlet for the new window
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
on openSheet:sender
tell class "NSApplication" of current application
its sharedApplication's beginSheet_modalForWindow_modalDelegate_didEndSelector_contextInfo_(Window, theWindow, me, missing value, missing value)
end tell
end openSheet:
end script[/AppleScript]
button "Open" is create in the mainWindow aka theWindow.
Offline
Perhaps you should try what I posted.
Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com
Offline