Applescript to re-order objects by x,y coords?
Has anyone already written up an AppleScript that will re-layer a selection of objects such that they are layered according to their vertical position?
With the item at the smallest y coord being behind all the rest, the next y-coord item being in front of that, and so on through to the item with the greatest y-coord being in front of all. (Yikes, not easy to describe without getting confused about highest, top, down and up, and so on ;-) |
Not sure how legible this is, but at one point of this function it passes a textual list of shape IDs with coordinates to a numeric sort on those coordinates. It then uses the ids to retrieve a list of shapes in spatial order.
[CODE]-- GET THE CHILDREN OF THE NODE IN THEIR LEFT RIGHT (OR TOP DOWN) SEQUENCE -- (The OG Applescript library doesn't expose outline structure, -- so we have to assume that Automatic Layout has been run, so that we can read the sibling sequence spatially) on GetChildren(oParent, iAxis) tell application id "OGfl" -- Create a textual list of fields ID + horiz or vert position set {lstOrigin, lstID} to {origin, id} of (destination of outgoing lines of oParent) set strRows to "" set lngID to length of lstID repeat with i from 1 to lngID set strRows to strRows & (item iAxis of (item i of lstOrigin)) & tab & item i of lstID & linefeed end repeat if strRows ≠ "" then set lstID to paragraphs of (do shell script "echo " & quoted form of (texts 1 thru -2 of strRows) & " | sort -n | cut -f 2") set lstChiln to {} tell canvas of oParent repeat with strID in lstID set lngID to strID as integer if not (plstSeen contains lngID) then set end of plstSeen to lngID set oChild to shape id lngID set end of lstChiln to {oChild, my GetChildren(oChild, iAxis)} end if end repeat end tell return lstChiln else return {} end if end tell end GetChildren [/CODE] |
Thanks, that's given me some leads.
One bugfix: [CODE]… set lstChiln to {} set plstSeen to {} -- ADD THIS MISSING LINE tell canvas of oParent …[/CODE] |
Here's my working script
[code] -- relayers items of the selection according to their Y (vertical) coordinate -- select all the items you want brought to front tell application id "OGfl" tell front window -- get a text list of Y coord & object ID set theSelection to the selection if theSelection is not {} then set theText to "" repeat with theItem in theSelection set theOrigin to origin of theItem set theY to item 2 of (theOrigin) set theID to the id of theItem set theText to theText & theY & tab & theID & linefeed -- use linefeed, not return! end repeat -- sort the text list set sortedIDs to paragraphs 2 through -1 of ¬ (do shell script "echo " & quoted form of (theText) & " | sort -n | cut -f 2") -- bring each to front, in sorted sequence set refGraphics to (a reference to graphics of its canvas) repeat with theID in sortedIDs set oGraphic to (a reference to graphic id (theID as number)) move oGraphic to beginning of refGraphics end repeat else beep end if end tell end tell [/code] |
[QUOTE=ericscheid;124639]
[CODE]… set lstChiln to {} set plstSeen to {} -- ADD THIS MISSING LINE tell canvas of oParent …[/CODE][/QUOTE] FWIW declaring large lists as script-level properties rather than local variables seems to improve their performance in Applescript. (Hence the absence of a declaration for that list property within the function – I should probably have pasted a preceding property declaration for you to make it a bit clearer). |
Ah ok. Good tip.
Oh, that's what "p" "lst" probably means too =) The script as it stands throws an error of "[I]The variable plstSeen is not defined[/I]" at the line [I]if not (plstSeen contains lngID) then[/I] |
Oh, just realised it needs to be a property since it's a list of all nodes seen so far (to avoid cross links revisiting), not just nodes seen in this particular calling of the function, and thus needs to store values across multiple calls and recursive calls.
So, example code might be [code] on run tell application id "OGfl" tell front window set theSelection to the selection if theSelection is not {} then set plstSeen to {} -- initialise for a new tree set theResult to my GetChildren(item 1 of theSelection, 2) end if end tell end tell end run property plstSeen : {} -- persistent storage of seen nodes on GetChildren(oParent, iAxis) -- etc end GetChildren [/code] |
All times are GMT -8. The time now is 12:34 AM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.