Plug-Ins: Modifier Keys
The Application class for Omni applications, on both macOS and iPadOS (with Magic Keyboard), contains instance properties for identifying the use of modifier keys when action are triggered:
commandKeyDown (Boolean r/o) • Is the Command key (⌘) pressed when the action is triggered?.
optionKeyDown (Boolean r/o) • Is the Option key (⌥) pressed when the action is triggered?.
shiftKeyDown (Boolean r/o) • Is the Shift key (⇧) pressed when the action is triggered?.
controlKeyDown (Boolean r/o) • Is the Control key (⌃) pressed when the action is triggered?.
These properties can be used in Omni Automation actions to determine if the user has pressed any of the standard Apple modifier keys.
Here’s a simple plug-in that will display a dialog indicating which modifier keys (if any) are pressed when the action is executed:
Modifier Key Sensor
/*{
"type": "action",
"targets": ["omnioutliner",
"omnigraffle", "omniplan", "omnifocus"], "author": "Otto Automator",
"identifier": "com.omni-automation.all.modifier-key-sensor",
"version": "1.1",
"description": "This action will display an alert showing which modifier keys are pressed when the action is triggered.",
"label": "Modifier Key Sensor",
"shortLabel": "Modifier Key Sensor",
"paletteLabel": "Modifier Key Sensor",
"image": "gear"
}*/
(() => {
const action = new PlugIn.Action(function(selection, sender){
// action code
keys = new Array()
if (app.commandKeyDown){keys.push("Command Key " + '\u2318')}
if (app.optionKeyDown){keys.push("Option Key " + '\u2325')}
if (app.shiftKeyDown){keys.push("Shift Key " + '\u21E7')}
if (app.controlKeyDown){keys.push("Control Key " + '\u2303')}
if (keys.length === 0){keys = ["No modifier keys were pressed."]}
alertStr = keys.join("\n")
alert = new Alert('\uF8FF' + ' Modifier Keys',alertStr)
alert.show()
});
action.validate = function(selection, sender){
// validation code
return true
};
return action;
})();
Attach|Detach Actions using Modifiers
In OmniGraffle, Omni Automation actions can be “attached to” or “assigned to” graphic objects in documents. A graphic’s “assigned” action can be triggered using the Browser tool (hold down B key):
Using Omni Automation in OmniGraffle, you can programmatically attach and detach actions to and from graphic objects. In your actions, you can add routines for attaching and detaching the action based upon the use of modifier keys.
In the following action example, if the user presses the Option key (⌥) while selecting the action from the Automation memu, a dialog will be presented to the user for confirming that they wish to attach the action to the currently selected graphics.
If approved by the user, the action will attach itself to the selected graphics.
Conversely, if the user presses the Shift key (⇧) while selecting the action from the Automation menu, a dialog will be presented to the user for confirming the detachment of any existing actions assigned to the selected graphics.
Detailed explanation of the script is placed above and below the featured code:
Flower-tize the Selected Graphic
/*{
"type": "action",
"targets": ["omnigraffle"],
"identifier": "com.omni-automation.og.flowertize-graphic",
"author": "Otto Automator",
"version": "1.5",
"description": "Creates a flower pattern of clones from the selected graphic.",
"label": "Flower-tize Selected Graphic",
"shortLabel": "Flower-tize Graphic",
"paletteLabel": "Flower-tize Graphic",
"image":"tree.fill"
}*/
(() => {
const action = new PlugIn.Action(function(selection, sender){
try {
if(app.optionKeyDown){
alertTitle = 'CONFIRM ACTION ATTACHMENT'
alertMessage = 'Attach this action to each of the selected graphics?'
var alert = new Alert(alertTitle, alertMessage)
alert.addOption("Attach")
alert.addOption("Cancel")
alert.show(buttonIndex => {
if (buttonIndex == 0){
pluginID = action.plugIn.identifier
actionID = action.name
selection.solids.forEach(solid => {
solid.automationAction = [pluginID, actionID]
})
console.log('Action attached')
}
})
} else if(app.shiftKeyDown){
alertTitle = 'CONFIRM ACTION DETACHMENT'
alertMessage = 'Detach any actions from each of the selected graphics?'
var alert = new Alert(alertTitle, alertMessage)
alert.addOption("Detach")
alert.addOption("Cancel")
alert.show(buttonIndex => {
if (buttonIndex == 0){
selection.solids.forEach(solid => {
solid.automationAction = []
})
console.log('Action detached.')
}
})
} else {
var cnvs = document.windows[0].selection.canvas
selection.solids.forEach(s => {
g = s.geometry
c = s.fillColor
c1 = Color.RGB(c.red * 0.9,c.green * 0.9,c.blue * 0.9)
c2 = Color.RGB(c.red * 0.2,c.green * 0.2,c.blue * 0.2)
// 1
d = s.duplicateTo(new Point(g.maxX,g.maxY),null)
d.fillType = FillType.Linear
d.gradientColor = c2
d.gradientAngle = 225
// 2
d = s.duplicateTo(new Point(g.minX-g.width,g.maxY),null)
d.fillType = FillType.Linear
d.gradientColor = c2
d.gradientAngle = 315
// 3
d = s.duplicateTo(new Point(g.minX-g.width,g.minY-g.height),null)
d.fillType = FillType.Linear
d.gradientColor = c2
d.gradientAngle = 45
//4
d = s.duplicateTo(new Point(g.maxX,g.minY-g.height),null)
d.fillType = FillType.Linear
d.gradientColor = c2
d.gradientAngle = 135
// 5
d = s.duplicateTo(new Point(g.maxX,g.minY),null)
d.rotation = 45
d.fillType = FillType.Linear
d.fillColor = Color.white
d.gradientColor = c1
d.gradientAngle = 135
// 6
d = s.duplicateTo(new Point(g.x,g.maxY),null)
d.rotation = 45
d.fillType = FillType.Linear
d.fillColor = Color.white
d.gradientColor = c1
d.gradientAngle = 225
// 7
d = s.duplicateTo(new Point(g.x-g.width,g.minY),null)
d.rotation = 45
d.fillType = FillType.Linear
d.fillColor = Color.white
d.gradientColor = c1
d.gradientAngle = 315
// 8
d = s.duplicateTo(new Point(g.x,g.minY-g.height),null)
d.rotation = 45
d.fillType = FillType.Linear
d.fillColor = Color.white
d.gradientColor = c1
d.gradientAngle = 45
// center circle
aRect = g.insetBy(g.width/5,g.height/5)
circle = cnvs.addShape('Circle', aRect)
circle.fillType = FillType.Radial
circle.fillColor = Color.white
circle.gradientColor = c2
// original square
s.fillType = FillType.Radial
s.fillColor = Color.white
s.gradientColor = c2
})
}
}
catch(err){
new Alert(err.name, err.message).show()
}
});
action.validate = function(selection, sender){
return (selection.solids.length > 0)
};
return action;
})();
|
OmniGraffle Action Attach/Detach Template
OmniGraffle Action Attach/Detach Template
/*{
"type": "action",
"targets": ["omnigraffle"],
"identifier": "com.omni-automation.og.xxxxxxxxx",
"author": "Your Name or Org",
"version": "1.0",
"description": "Description.",
"label": "Menu Title",
"shortLabel": "Menu Title",
"paletteLabel": "Menu Title",
"image":"gear"
}*/
(() => {
const action = new PlugIn.Action(async function(selection, sender){
try {
if(app.optionKeyDown){
alertTitle = 'CONFIRM ACTION ATTACHMENT'
alertMessage = 'Attach this action to each of the selected graphics?'
var alert = new Alert(alertTitle, alertMessage)
alert.addOption("Attach")
alert.addOption("Cancel")
alert.show(buttonIndex => {
if (buttonIndex == 0){
pluginID = action.plugIn.identifier
actionID = action.name
selection.solids.forEach(solid => {
solid.automationAction = [pluginID, actionID]
})
console.log('Plug-in action attached.')
}
})
} else if(app.shiftKeyDown){
alertTitle = 'CONFIRM ACTION DETACHMENT'
alertMessage = 'Detach any actions from each of the selected graphics?'
var alert = new Alert(alertTitle, alertMessage)
alert.addOption("Detach")
alert.addOption("Cancel")
alert.show(buttonIndex => {
if (buttonIndex == 0){
selection.solids.forEach(solid => {
solid.automationAction = []
})
console.log('Plug-in action detached.')
}
})
} else {
// PROCESSING STATEMENTS GO HERE
}
}
catch(err){
if(!err.causedByUserCancelling){
new Alert(err.name, err.message).show()
}
}
});
action.validate = function(selection, sender){
// ONE OR MORE SOLID GRAPHICS SELECTED
return (selection.solids.length > 0)
};
return action;
})();