Another idea I have is sorting the list of items to find the leftmost, topmost, rightmost, and bottommost items. It should be quick and I need to write that kind of sorter anyway but I was hoping to monkey around some more before I did that. It appears to be the best idea I've got though.
The only other thing I can think of messes with the UI again by setting everything that isn't selected invisible and getting the bounds of the doc. Presumably, as long as I don't call redraw, the user should be none the wiser. This might be easier than the second and it's better than the first, but I still feel there has to be something better.
It seems such a simple problem for these somewhat convoluted solutions. Am I just overlooking something?
anyHelp = manyThanks
I have had that same thought about this same problem. I am still fairly new to Applescript, but it seems to me that there should be an easy solution to return the bounds of a selection. If you find it let me know.
What I ended up doing sounds like the direction you're heading. Make a list of the bounds of each item in the selection, then sort through it to get the outermost bounds. It works well, but it just seems far more complicated than it should be.
Good luck
Jason
Since they now have AI9 and AI10 script support, I'm hoping Adobe will soon start an Illustrator Scripting forum.
boundsOfSelection(0) -- demos handler
on boundsOfSelection(boundsType)
-- boundsType: 0 = geometric, 1 = visual, 2 = control
try
tell front document of application "Adobe Illustrator 10" to return my boundsOfItems(selection, boundsType)
end try
end boundsOfSelection
on boundsOfItems(itemList, boundsType)
-- boundsType: 0 = geometric, 1 = visual, 2 = control
-- takes a list of page item references
-- and returns outermost bounds of all items
set {x1f, y1f, x2f, y2f} to {0, 0, 0, 0}
set {x1List, y1List, x2List, y2List} to {{}, {}, {}, {}}
tell application "Adobe Illustrator 10"
repeat with thisItem in itemList
if boundsType = 0 then
copy geometric bounds of thisItem to {x1, y1, x2, y2}
else if boundsType = 1 then
copy visible bounds of thisItem to {x1, y1, x2, y2}
else if boundsType = 2 then
copy control bounds of thisItem to {x1, y1, x2, y2}
end if
copy x1 to end of x1List
copy y1 to end of y1List
copy x2 to end of x2List
copy y2 to end of y2List
end repeat
end tell
set x1f to item (lowNumIndex(x1List)) of x1List
set y1f to item (highNumIndex(y1List)) of y1List
set x2f to item (highNumIndex(x2List)) of x2List
set y2f to item (lowNumIndex(y2List)) of y2List
return {x1f, y1f, x2f, y2f}
end boundsOfItems
on highNumIndex(thisList)
-- takes a list of numbers, {18, 5, 270, -500}
-- and returns the index of the high number
set highIndex to 0
set compareNum to -1.0E+16
repeat with i from 1 to count of thisList
set thisNum to item i of thisList
if thisNum > compareNum then
set compareNum to thisNum
set highIndex to i
end if
end repeat
return highIndex
end highNumIndex
on lowNumIndex(thisList)
-- REQUIRES highNumIndex()
-- takes a list of numbers, {18, 5, 270, -500}
-- and returns the index of the low number
set lowIndex to 0
set compareNum to item (highNumIndex(thisList)) of thisList
repeat with i from 1 to count of thisList
set thisNum to item i of thisList
if thisNum < compareNum then
set compareNum to thisNum
set lowIndex to i
end if
end repeat
return lowIndex
end lowNumIndex
set artToBounds to selection
-- Create a list of the bounds of each item of the selection
set boundsList to {}
set bl to 1
set total to count of items in artToBounds
repeat until bl > total
set vb to visible bounds of item bl of artToBounds
set boundsList to boundsList & {vb}
set bl to bl + 1
end repeat
--Subroutine to take the list of bounds and return only the outermost bounds
set outerBounds to my findOuterBounds(boundsList)
on findOuterBounds(xList)
set {leftRes, topRes, rightRes, bottomRes} to xList's first item
repeat with boundsRef in rest of xList
set {leftVal, topVal, rightVal, bottomVal} to boundsRef's contents
if (leftVal is less than leftRes) then set leftRes to leftVal
if (topVal is greater than topRes) then set topRes to topVal
if (rightVal is greater than rightRes) then set rightRes to rightVal
if (bottomVal is less than bottomRes) then set bottomRes to bottomVal
end repeat
return {leftRes, topRes, rightRes, bottomRes}
end findOuterBounds