The very helpful tutorial material at omni-automation.com shows a step-by-step approach to:
- Setting a series of Alert object properties, and then
- performing ‘actions’ inside the scope of a call-back function.
At my advanced age this feels a little complex, and I might be discouraged by having to do it repeatedly, every time I wanted to enable a user choice.
Not sure why, but I personally happen to find it a bit quicker, more reliable, and less mentally taxing to assemble scripts by snapping them together from simpler building blocks – single function calls which take an argument or two, and return a usable value.
I would like, for example, to be able to write:
const maybeChoice = buttonChoiceMay(
'Preference',
'Which do you prefer to build scripts with ?',
['Statements', 'Functions returning values']
);
return show(maybeChoice);
defining a dialog like:
which returns a two-part ‘option’ value, with a Boolean true|false
to let me know if the user cancelled, and, if they didn’t, then also a String containing the chosen button name.
I like cancellation to return the dictionary value {"nothing":true}
, while an option choice returns something like:
{"nothing":false,"just":"Functions returning values"}
This lets me test the boolean before trying to use a choice.
To enable this, whenever I need an omniJS dialog, I paste, from my snippet library, the following function:
// buttonChoiceMay :: String -> String -> [String] -> Maybe String
const buttonChoiceMay = (title, msg, buttons) => {
const
options = ['Cancel'].concat(buttons)
.reverse();
var result = undefined;
return (
// IO ------------------------------------------------------------
options.reduce((a, k) => (
a.addOption(k),
a
), new Alert(title, msg))
.show(n => result = n),
// Value ---------------------------------------------------------
result !== buttons.length ? {
nothing: false,
just: options[result]
} : {
nothing: true
}
);
};
and a call might look like this:
(() => {
'use strict';
// buttonChoiceMay :: String -> String -> [String] -> Maybe String
const buttonChoiceMay = (title, msg, buttons) => {
const
options = ['Cancel'].concat(buttons)
.reverse();
var result = undefined;
return (
// IO ------------------------------------------------------------
options.reduce((a, k) => (
a.addOption(k),
a
), new Alert(title, msg))
.show(n => result = n),
// Value ---------------------------------------------------------
result !== buttons.length ? {
nothing: false,
just: options[result]
} : {
nothing: true
}
);
};
const maybeChoice = buttonChoiceMay(
'Preference',
'Which do you prefer to build scripts with ?',
['Statements', 'Functions returning values']
);
return maybeChoice.nothing ? 'User cancelled ...' : maybeChoice.just;
})();
(To test, copy the whole of the latter script, pasting and entering it into the Automation Console of a recent build of OmniGraffle (or OmniOutliner).