The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniGraffle General (http://forums.omnigroup.com/forumdisplay.php?f=10)
-   -   Script: 'Inner shadow' for recessed cut-out effect (http://forums.omnigroup.com/showthread.php?t=23872)

RobTrew 2012-04-04 04:26 AM

Script: 'Inner shadow' for recessed cut-out effect
 
1 Attachment(s)
OG 5 Pro currently lacks the option to give a shape an inner shadow, to create a recessed cut-out effect.

[IMG]http://forums.omnigroup.com/attachment.php?attachmentid=2332&stc=1&d=1333542013[/IMG]

If inner shadows would be useful to you, the best thing is to send a request through [B]Help > Send Feedback[/B] in the OG menu.

In the meanwhile, the example above was created by an OG 5 Pro script (below).

Select one or more shapes, and run the script. When the script has finished running, move the original shape(s) to reveal the cut-out(s) below.

NB the script creates a framing mask to hide the external shadow of a subtracted cut-out. It may be helpful to group the mask with the cut-out.

[CODE]-- A WORK-AROUND TO COMPENSATE FOR THE LACK OF "INTERNAL" SHADOW (FOR A RECESSED EFFECT) IN OG5

-- MAKE CUT-OUT COPIES (BENEATH THE SELECTED SHAPE(S))
-- WITH INTERNAL SHADOWS, AND A FRAME WHICH MASKS THEIR EXTERNAL SHADOWS

-- WHEN THE SCRIPT HAS RUN, MOVE THE ORIGINAL SHAPE TO REVEAL THE CUT-OUT HOLE BENEATH IT

-- USAGE: SELECT ONE OR MORE SHAPES AND RUN THE SCRIPT

property pTitle : "Internal Shadow"
property pVer : ".002"

property nMargin : 10
property plstShadowColor : {0, 0, 0}
property prShadowFuzz : 8.0
property plstShadowVector : {3.0, 3.0}

property pblnMaskStroke : false


tell application id "OGfl"
set oWin to front window
tell oWin
-- GET THE CURRENT SELECTION AND READ ITS SHADOW PROPERTIES
set lstSeln to selection
set oCanvas to its canvas
repeat with oShape in lstSeln
--set refGraphics to a reference to graphics of its canvas
tell oShape
set blnShadow to draws shadow
if blnShadow then set {plstShadowColor, prShadowFuzz, plstShadowVector} to ¬
{shadow color, shadow fuzziness, shadow vector}
set {{rXShape, rYShape}, {rWShape, rHShape}} to {origin, size}

-- MAKE A COPY OF THE ORIGINAL SHAPE, LEAVING IT IN PLACE
tell oCanvas to duplicate (contents of oShape) to end of graphics
end tell

-- CREATE THE CUTOUT SHAPE AND GIVE IT THE SAME SHADOW PROPERTIES AS THE SELECTED SHAPE
-- (or fall back to a set of default properties, if the selection has no shadow
set {rWCutout, rHCutout} to {rWShape + nMargin, rHShape + nMargin}
set nHalf to nMargin / 2
set {rXCutout, rYCutout} to {rXShape - nHalf, rYShape - nHalf}

tell oCanvas
set refGraphics to (a reference to graphics)
set oCutout to make new shape with properties ¬
{origin:{rXCutout, rYCutout}, size:{rWCutout, rHCutout}, shadow color:plstShadowColor, shadow fuzziness:prShadowFuzz, shadow vector:plstShadowVector, draws shadow:true, draws stroke:pblnMaskStroke} ¬
at end of refGraphics
end tell
set selection of oWin to {oShape, oCutout}
tell application id "OGfl" to activate
tell application id "sevs" to click (my GetMenuItem("OGfl", {"Edit", "Shapes", "Subtract Shapes"}))

-- PREPARE THE MASK, TO HIDE THE OUTER SHADOW OF THE SUBTRACTED SHAPE
set {rXShadow, rYShadow} to plstShadowVector
set rShadowMask to prShadowFuzz * 1.2
set {rXShadow, rYShadow} to {rXShadow + (rShadowMask * 2) + 2, rYShadow + (rShadowMask * 2) + 2}
set {rWMask, rHMask} to {rWCutout + rXShadow, rHCutout + rYShadow}
set {rXMask, rYMask} to {rXCutout - (rXShadow / 2), rYCutout - (rYShadow / 2)}
set oMask to make new shape with properties {origin:{rXMask, rYMask}, size:{rWMask, rHMask}, draws shadow:false, draws stroke:pblnMaskStroke} at front of refGraphics
set oHole to make new shape with properties {origin:{rXShape - 1, rYShape - 1}, size:{rWShape + 2, rHShape + 2}, draws shadow:false, draws stroke:false} at front of refGraphics
set selection of oWin to {oMask, oHole}
tell application id "OGfl" to activate
tell application id "sevs" to click (my GetMenuItem("OGfl", {"Edit", "Shapes", "Subtract Shapes"}))
end repeat
end tell
true
end tell

-- RETURNS A REFERENCE TO A CLICKABLE MENU ITEM
-- E.G. set mnuZoomFit to GetMenuItem("OGfl", {"View", "Zoom", "Zoom to Selection"})
on GetMenuItem(strAppCode, lstMenu)
set lngChain to length of lstMenu
if lngChain < 2 then return missing value

tell application id "sevs"
set lstApps to every application process where its creator type = strAppCode
if length of lstApps < 1 then return missing value
tell first item of lstApps
-- GET THE TOP LEVEL MENU
set strMenu to item 1 of lstMenu
set oMenu to menu strMenu of menu bar item strMenu of menu bar 1

-- TRAVEL DOWN THROUGH ANY SUB-MENUS
repeat with i from 2 to (lngChain - 1)
set strMenu to item i of lstMenu
set oMenu to menu strMenu of menu item strMenu of oMenu
end repeat

-- AND RETURN THE FINAL MENU ITEM
return menu item (item -1 of lstMenu) of oMenu
end tell
end tell
end GetMenuItem

on GUIEnabled()
tell application id "sevs"
if UI elements enabled then
return true
else
activate
display dialog "This script depends on enabling access for assistive devices in system preferences" buttons "OK" default button "OK" with title pTitle & " " & pVer
tell application id "sprf"
activate
set current pane to pane id "com.apple.preference.universalaccess"
end tell
return false
end if
end tell
end GUIEnabled
[/CODE]

RobTrew 2012-04-05 12:09 AM

One of the key strengths of Omni products is that when your work hits an Omni-bug, or a design limitation, you can reach for the Applescript duct tape, and script a work-around.

I have been surprised, however, to discover that doing this in the case of OmniGraffle often seems to uncover a bug in the duct tape itself.

In this case, the Ninjas confirm that there is an existing bug in their database which records a blind patch in the scripting of shadows. Shadow color, vector, and fuzziness are scriptable, but the 'shadow cast attribute' somehow got left out.

This means that you can't script the option between: [LIST][*]'Shadow behind all other objects in the same layer'[*]'Shadow immediately beneath this object'[/LIST]A pity, because one really needs to be able to do this in the script above ...

As it is, one has to move the framing mask aside, manually set the option for the shadowed cut-out below, reposition the framing mask, and group the two.

Bugs in applescript are liable to get neglected by Omni's bug priority voting system. (A bit like arguing that fire extinguishers don't need to be maintained on the democratic grounds that not many people use them :-)

If, therefore, this bug does seem to affect your work-flow (or if you simply believe in maintaining fire extinguishers in good order, just in case) do send a brief bug fix request through [B]Help > Send Feedback ...[/B]


All times are GMT -8. The time now is 12:05 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.