-- Tag-n-Possess -- Dani Rosen - Feb 15, 2006 -- Lists objects in the scene that are tagged for export. -- Used for vignette CSP exports. -- -- The script actually only checks for entries in the User Defined -- section of Object Properties. It doesn't actually check for -- propper tagging. -- -- 1.2: Feb 16, 2006 - added notes functionality showing "possession" and -- - allowing for possessing and depossessing. -- - Notes fields resize accordingly. Height resize on refresh. -- 1.3: Mar 09, 2006 - Added DeTagging functionality. The list would become very long -- when unneeded tagged objects showed up. -- 1.5: Apr 12, 2006 - Fixed a bug with empty note tracks. -- - Added Camera Cuts functionality -- - renamed "Tagged Objects" to "Tag n' Possess" -- 2.0: Jun 27, 2006 - Changed code to Activex's ListView with Tagging feature and a whole remake -- 2.1: Jul 07, 2006 - Added resizing functionality. Made it so only top of hierarchies show up in list. -- 2.15: Jul 12, 2006 - small bug fix to allow cameras to be children -- 2.5: Aug 29, 2006 - changed buttons to dropdownlist with multiple note choices -- 2.6: Aug 31, 2006 - supressed unrecognizeable NoteTrack alert - since Max doesn't retain NoteTrack names on save. -- 2.7: Aug 31, 2006 - fixed a bug where the tool would crash if there were multiple note-keys at the same time -- (i.e. - two note-keys at frame 0) macroScript TagPossess category:"DaniTools" internalcategory:"DaniTools" tooltip:"Tag n' Possess" buttontext:"Tag n' Possess" Icon:#("TrackViewTools",95) ( -- ################# GLOBALS global TaggedRol ObjList = #() allObj = #() filteredObj = #() global userDef notesArray = #() checksArray = #() global PosGo global SKLfilename global WorkDirArr = #() global SkeletonArr = #() -- ################# FUNCTIONS fn GetWorkDir = ( MaxRoot = getdir #maxroot CSPpref = (MaxRoot + "\CSPExporterPreferences.txt") if (getFiles CSPpref).count == 0 then ( global WorkingDir = "No Directory Selected" ) else ( f = openFile CSPpref try ( global WorkingDir = readLine f WorkDirArr = filterstring WorkingDir "\\" ) catch ( global WorkingDir = "No Directory Selected" ) close f ) ) fn ObjList = ( allObj = #() for p in objects do ( if (classof p == Targetcamera) or (classof p == Freecamera) then append allObj p if (classof p == Box) or (classof p == Sphere) or (classof p == Cylinder) then ( if p.parent == undefined then append allObj p ) ) filteredObj = allObj ) fn NoteList = ( notesArray = #() for n in filteredObj do ( if (hasNoteTracks n) == true then ( multiNote = undefined if (numNoteTracks n) > 1 then -- multiple noteTracks ( for u in 1 to (numNoteTracks n) do -- try to find the one created by this script ( if ((getNoteTrack n u) as string) == "Notetrack:posNote" then multiNote = u ) ) if multiNote != undefined then ( global ns = getNoteTrack n multiNote ) else ( global ns = getNoteTrack n 1 ) if ns.keys[1] == undefined then ( nsValue = "no Note keys" ) else ( global nText = undefined -- about to test multi-line notes testVal = ns.keys[1].value as stringstream while not eof testVal do ( if nText != undefined then ( nText2 = (readline testVal) if nText2 != "" then nText = (nText + " \xac " + nText2) ) else ( nText = readline testVal ) ) if nText == undefined then nText = "empty key" nsValue = (((ns.keys[1].time.frame as integer) as string) + ": " + nText) if ns.keys.count > 1 then ( for c in 2 to ns.keys.count do ( global nText = undefined -- about to test multi-line notes testVal = ns.keys[c].value as stringstream while not eof testVal do ( if nText != undefined then ( nText2 = (readline testVal) if nText2 != "" then nText = (nText + " \xac " + nText2) ) else ( nText = readline testVal ) ) if nText == undefined then nText = "empty key" nsValue = (nsValue + ", " + ((ns.keys[c].time.frame as integer) as string) + ": " + nText) ) ) ) append notesArray nsValue ) else ( append notesArray "not possessed" ) ) ) GetWorkDir() ObjList() NoteList() -- ################# ROLLOUT rollout TaggedRol "Tag n' Possess 2.7" ( button bDir "Set Working Directory..." height:17 pos:[5,5] label lDir "" align:#left pos:[140,6] button bRefresh "Refresh" tooltip:"populate the list" width:55 height:18 pos:[370,3] button bAbout "?" tooltip:"About..." width:20 height:18 pos:[428,3] label lNoteName "Note:" pos:[5,31] Dropdownlist dNoteName "" items:#("Possess", "UnPossess", "Camera Cut", "Letterbox on", \ "Letterbox off", "Fade in", "Fade out", "Custom:") pos:[40,28] width:90 enabled:true edittext eCustom "+" width:80 height:20 pos:[132,28] enabled:true spinner cc "Time: " range:[0,10000,0] type:#integer fieldwidth:40 pos:[220,30] enabled:true label lAction "Action:" pos:[5,57] Dropdownlist dAction "" items:#("Add", "Delete", "Move", "Remove NoteTrack", "Drop NoteTrack") pos:[40,54] width:120 spinner cMove "to:" range:[0,10000,0] type:#integer fieldwidth:35 pos:[163,58] enabled:false button bDoIt "DO IT!" tooltip:"Select an item to activate this" width:70 height:20 pos:[230,56] enabled:false groupBox gHide "Hide:" pos:[309,22] width:137 height:54 checkbox Hboxes "Boxes" checked:false pos:[315,40] checkbox Hspheres "Spheres" checked:false pos:[380,40] checkbox Hcylinders "Cylinders" checked:false pos:[315,55] checkbox Hcameras "Cameras" checked:false pos:[380,55] label lseparator "" height:3 fn HideObjects = ( filteredObj = #() for h in allObj do ( if (classof h == Targetcamera) or (classof h == Freecamera) then (if Hcameras.checked == false then (append filteredObj h)) if (classof h == Box) then (if Hboxes.checked == false then (append filteredObj h)) if (classof h == Sphere) then (if Hspheres.checked == false then (append filteredObj h)) if (classof h == Cylinder) then (if Hcylinders.checked == false then (append filteredObj h)) ) ) fn initListView lv = ( lv.gridLines = true lv.View = #lvwReport lv.fullRowSelect = true lv.backColor = color 225 215 210 lv.checkboxes = true -- lv.mousePointer = #ccArrowQuestion lv.LabelEdit = #lvwManual layout_def = #(#("Tag",35), #("Object Name",120), #("Notes",270)) for i in layout_def do ( column = lv.ColumnHeaders.add() column.text = i[1] ) LV_FIRST = 0x1000 LV_SETCOLUMNWIDTH = (LV_FIRST + 30) for i = 0 to layout_def.count-1 do windows.sendMessage lv.hwnd LV_SETCOLUMNWIDTH i layout_def[1+i][2] ) fn fillInSpreadSheet lv = ( lv.ListItems.clear() checksArray = #() for o in filteredObj do ( li = lv.ListItems.add() global checkCheck = false if (getUserPropBuffer o) != "" then ( userDef = (getUserPropBuffer o) as stringstream while not eof userDef do ( f = readline userDef if (matchPattern f pattern:"csp_export*") then ( li.checked = true append checksArray true checkCheck = true exit ) ) if checkCheck != true then append checksArray false ) else ( li.checked = false append checksArray false ) li.ToolTipText = "Tag / Detag (click header to select all tagged)" sub_li = li.ListSubItems.add() sub_li.text = o.name sub_li.bold = true sub_li.ForeColor = color 90 60 10 sub_li.ToolTipText = "Double-Click to select (click header to select all objects)" sub_li = li.ListSubItems.add() if (hasNoteTracks o) == true then ( multiNote = undefined if (numNoteTracks o) > 1 then -- multiple noteTracks ( for u in 1 to (numNoteTracks o) do -- try to find the one created by this script ( if ((getNoteTrack o u) as string) == "Notetrack:posNote" then multiNote = u ) ) if multiNote != undefined then ( global ns = getNoteTrack o multiNote ) else ( global ns = getNoteTrack o 1 ) if ns.keys[1] == undefined then ( nsValue = "no Note keys" ) else ( global nText = undefined -- about to test multi-line notes testVal = ns.keys[1].value as stringstream while not eof testVal do ( if nText != undefined then ( nText2 = (readline testVal) if nText2 != "" then nText = (nText + " \xac " + nText2) ) else ( nText = readline testVal ) ) if nText == undefined then nText = "empty key" nsValue = (((ns.keys[1].time.frame as integer) as string) + ": " + nText) if ns.keys.count > 1 then ( for c in 2 to ns.keys.count do ( global nText = undefined -- about to test multi-line notes testVal = ns.keys[c].value as stringstream while not eof testVal do ( if nText != undefined then ( nText2 = (readline testVal) if nText2 != "" then nText = (nText + " \xac " + nText2) ) else ( nText = readline testVal ) ) if nText == undefined then nText = "empty key" nsValue = (nsValue + ", " + ((ns.keys[c].time.frame as integer) as string) + ": " + nText) ) ) ) sub_li.text = nsValue ) else ( sub_li.text = "not possessed" ) sub_li.ToolTipText = "Double-Click to select" ) bDoIt.enabled = false ) activeXControl lv_objects "MSComctlLib.ListViewCtrl" width:442 height:158 align:#center on TaggedRol open do ( lDir.text = WorkingDir initListView lv_objects fillInSpreadSheet lv_objects ) -- ################# HIDE on Hboxes changed state do ( HideObjects() fillInSpreadSheet lv_objects ) on Hspheres changed state do ( HideObjects() fillInSpreadSheet lv_objects ) on Hcylinders changed state do ( HideObjects() fillInSpreadSheet lv_objects ) on Hcameras changed state do ( HideObjects() fillInSpreadSheet lv_objects ) -- ################# SELECT-ITEM on lv_objects ItemClick cList do ( bDoIt.enabled = true ) on lv_objects DblClick do ( select filteredObj[lv_objects.selectedItem.index] bDoIt.enabled = false ) on lv_objects ColumnClick ColClicked do ( if ColClicked.index == 1 then -- select all Tagged ( global SelectTag=#() for w in 1 to checksArray.count do ( if lv_objects.ListItems[w] != undefined then ( if lv_objects.ListItems[w].checked == true then append SelectTag filteredObj[w] ) ) select SelectTag ) if ColClicked.index == 2 then select filteredObj -- select all objects ) -- ################# CSP WORKING DIR on bDir pressed do ( WorkingDir = getSavePath caption:"Set Working Directory" if WorkingDir == undefined then return 0 MaxRoot = getdir #maxroot CSPpref = (MaxRoot + "\CSPExporterPreferences.txt") if (getFiles CSPpref).count == 0 then ( CSPstream = createFile CSPpref f = openFile CSPpref format "%\n" WorkingDir to:CSPstream close f close CSPstream ) lDir.text = WorkingDir ) -- ################# REFRESH on bRefresh pressed do ( ObjList() NoteList() HideObjects() fillInSpreadSheet lv_objects ) -- ################# ACTION STATES on dAction selected ActionState do ( if (ActionState == 4) or (ActionState == 5) then -- time enabler on Remove or Drop selected ( cc.enabled = false ) else ( cc.enabled = true ) if (ActionState == 3) or (ActionState == 2) or (ActionState == 4) or (ActionState == 5) then -- note enabler on all except Add ( dNoteName.enabled = false eCustom.enabled = false ) else ( dNoteName.enabled = true eCustom.enabled = true ) if ActionState == 3 then -- move-time enabler on Move selected ( cMove.enabled = true ) else ( cMove.enabled = false ) ) -- ################# ACTION FUNCTIONS fn fProcess ThisObject NoteType NoteCustom NoteTime NoteAction NewNoteTime multiNoteNum = ( global noteTag case of ( (NoteType == 1): noteTag = "possess" (NoteType == 2): noteTag = "unpossess" (NoteType == 3): noteTag = "cut" (NoteType == 4): noteTag = "letterbox on" (NoteType == 5): noteTag = "letterbox off" (NoteType == 6): noteTag = "fade in" (NoteType == 7): noteTag = "fade out" (NoteType == 8): noteTag = "" ) if multiNoteNum != undefined then ( thisNoteTrack = getNoteTrack ThisObject multiNoteNum ) else ( thisNoteTrack = getNoteTrack ThisObject 1 ) NoteTrackKeyArray = thisNoteTrack.keys if NoteAction == 1 then --#### ACTION - ADD ( if NoteTrackKeyArray.count != 0 then ( -- make sure there's no overlap global overlapKey = undefined for y in 1 to NoteTrackKeyArray.count do ( if (NoteTrackKeyArray[y].time.frame as integer) == NoteTime then overlapKey = y ) if overlapKey != undefined then ( case (YesNoCancelBox ("A note-key already exists on the selected time.\nWould you like to " + \ "add a new line to the same key\nwith the new note?\n\n" + \ "(Yes) - Add new line\n(No) - Replace current key with the new note\n(Cancel) - Cancel") \ title:"Key found at selected time") of ( #yes: NoteTrackKeyArray[overlapKey].value = (NoteTrackKeyArray[overlapKey].value + "\n" + noteTag + NoteCustom) #no: NoteTrackKeyArray[overlapKey].value = (noteTag + NoteCustom) #cancel: return 0 ) ) else ( -- no overlap addNewNoteKey NoteTrackKeyArray NoteTime NoteTrackKeyArray[(getNoteKeyIndex thisNoteTrack NoteTime)].value = (noteTag + NoteCustom) ) ) else ( -- no other keys addNewNoteKey NoteTrackKeyArray NoteTime NoteTrackKeyArray[(getNoteKeyIndex thisNoteTrack NoteTime)].value = (noteTag + NoteCustom) ) ) if NoteAction == 2 then --#### ACTION - DELETE ( try ( deleteNoteKey NoteTrackKeyArray (getNoteKeyIndex thisNoteTrack NoteTime) ) catch ( messagebox ("There is no key on frame " + (NoteTime as string)) return 0 ) ) if NoteAction == 3 then --#### ACTION - MOVE ( if NoteTrackKeyArray.count != 0 then ( -- make sure there's no overlap on target frame global overlapKey = undefined for y in 1 to NoteTrackKeyArray.count do ( if (NoteTrackKeyArray[y].time.frame as integer) == NewNoteTime then overlapKey = y ) if overlapKey != undefined then ( if (queryBox ("A note-key already exists on the target frame.\n" + \ "Would you like to replace it?") title:"Frame-Overlap detected") then ( deleteNoteKey NoteTrackKeyArray overlapKey NoteTrackKeyArray[(getNoteKeyIndex thisNoteTrack NoteTime)].time = NewNoteTime ) else ( return 0 ) ) else ( -- no overlap NoteTrackKeyArray[(getNoteKeyIndex thisNoteTrack NoteTime)].time = NewNoteTime ) ) else ( -- no other keys messagebox ("There are no note-keys on " + (ThisObject.name as string)) return 0 ) ) ) -- ################# DO-IT on bDoIt pressed do ( if (dAction.selection == 4) or (dAction.selection == 5) then -- REMOVE or DROP NOTE-TRACK ( if dAction.selection == 4 then -- REMOVE NOTE-TRACK ( if (querybox ("This will Remove the Note Track from \"" + filteredObj[lv_objects.selectedItem.index].name + "\".\n Continue?") \ title:"Confirm Note-Track Removal") then ( p = filteredObj[lv_objects.selectedItem.index] if (hasNoteTracks p) == true then ( if (numNoteTracks p) > 1 then -- multiple noteTracks ( deletedTrack = false for n in 1 to (numNoteTracks p) do -- try to find the one created by this script ( if ((getNoteTrack p n) as string) == "Notetrack:posNote" then ( deleteNoteTrack p (getNoteTrack p n) deletedTrack == true ) ) if deletedTrack == false then ( if (querybox ("Mutliple Note-Tracks detected.\nDelete the first one?") \ title:"Confirm Note-Track Removal") then ( deleteNoteTrack p (getNoteTrack p 1) ) else ( bDoIt.enabled = false return 0 ) ) ) else ( -- only one note track deleteNoteTrack p (getNoteTrack p 1) ) NoteList() fillInSpreadSheet lv_objects bDoIt.enabled = false ) else ( -- has no note track messagebox ("\"" + filteredObj[lv_objects.selectedItem.index].name + "\" has no Note Track") bDoIt.enabled = false return 0 ) ) else ( -- refused removal of track on confirmation bDoIt.enabled = false return 0 ) ) -- no Removal else ( -- begin Drop if (querybox ("The Drop process will attempt to drop the Note-Track down one level if multiple NoteTracks\n" + \ "exist, exposing the top one to the tool.\n" + \ "If there's only one Note-Track but not one you want to work on (i.e. - subtitles), then the\n" + \ "Drop process will create a new Note-Track above the existing one.\n\n" +\ "Continue with Drop on \"" + filteredObj[lv_objects.selectedItem.index].name + "\"?") \ title:"Confirm Note-Track Drop") then ( p = filteredObj[lv_objects.selectedItem.index] if (hasNoteTracks p) == true then ( if (numNoteTracks p) > 1 then -- multiple noteTracks ( -- deleting and undoing note-tracks changes their order (hack). undo on ( deletenotetrack p (getnotetrack p 1) ) max undo ) else ( -- only one note track npos = NoteTrack "posNote" addNoteTrack p npos ) NoteList() fillInSpreadSheet lv_objects bDoIt.enabled = false ) else ( -- has no note track messagebox ("\"" + filteredObj[lv_objects.selectedItem.index].name + "\" has no Note Tracks") bDoIt.enabled = false return 0 ) ) else ( -- refused drop of track on confirmation bDoIt.enabled = false return 0 ) ) -- no Drop ) -- no NoteTrack Removal or Drop selected else ( -- pick NoteTrack p = filteredObj[lv_objects.selectedItem.index] global multiNote = undefined if (hasNoteTracks p) == true then ( global posNoteTrack = false if (numNoteTracks p) > 1 then -- multiple noteTracks ( for n in 1 to (numNoteTracks p) do -- try to find the one created by this script ( if ((getNoteTrack p n) as string) == "Notetrack:posNote" then ( posNoteTrack = true multiNote = n ) ) ) else ( --one note track if ((getNoteTrack p 1) as string) == "Notetrack:posNote" then posNoteTrack = true ) if posNoteTrack == false then ( -- supressing query since Max doesn't retain NoteTrack names upon Save: --if (querybox ("\"" + filteredObj[lv_objects.selectedItem.index].name + "\" has one or more Note-Tracks that weren't created by this " +\ --"tool.\nShould I use the first one found and convert it?\n(choosing Yes will correct the NoteTrack and keep the keys intact.)") \ --title:"Unrecognizeable Note-Tracks") then --( -- using first, undefined, noteTrack (getNoteTrack p 1).name = "posNote" fProcess p dNoteName.selection eCustom.text cc.value dAction.selection cMove.value multiNote NoteList() fillInSpreadSheet lv_objects bDoIt.enabled = false --) else ( -- bDoIt.enabled = false -- return 0 --) ) else ( fProcess p dNoteName.selection eCustom.text cc.value dAction.selection cMove.value multiNote NoteList() fillInSpreadSheet lv_objects bDoIt.enabled = false ) ) else ( -- has no note track if (querybox ("\"" +filteredObj[lv_objects.selectedItem.index].name + "\" has no Note Track.\nDo you want to add one?") \ title:"Missing Note Track") then ( npos = NoteTrack "posNote" addNoteTrack p npos fProcess p dNoteName.selection eCustom.text cc.value dAction.selection cMove.value multiNote NoteList() fillInSpreadSheet lv_objects bDoIt.enabled = false ) else ( bDoIt.enabled = false return 0 ) ) ) ) -- end DoIt -- ################# TAG on lv_objects ItemCheck tagItem do ( for w in 1 to checksArray.count do ( global checknum = w if lv_objects.ListItems[w] != undefined then ( if lv_objects.ListItems[w].checked != checksArray[w] do ( TagState = lv_objects.ListItems[w].checked if TagState == false then ( if queryBox ("This will remove the Tag from \"" + filteredObj[w].name \ + "\"\nAre you sure?") title:"Confirm Tag Removal" then ( setUserPropBuffer filteredObj[w] "" deleteItem checksArray w insertItem false checksArray w ) else ( lv_objects.ListItems[w].checked = true ) ) else ( global RolCheck = checknum if WorkingDir == "No Directory Selected" then ( messagebox "Please choose a Working Directory first" title:"Missing Working Folder" lv_objects.ListItems[w].checked = false return 0 ) if filteredObj[RolCheck].parent != undefined then ( if (classof filteredObj[RolCheck] != Targetcamera) and (classof filteredObj[RolCheck] != Freecamera) then ( messagebox "Object must be at top-level \n(must not be linked under another)" title:"Illegal tagging" lv_objects.ListItems[w].checked = false return 0 ) ) if (classof filteredObj[RolCheck] == Targetcamera) or (classof filteredObj[RolCheck] == Freecamera) then ( setUserPropBuffer filteredObj[RolCheck] "csp_export = " deleteItem checksArray RolCheck insertItem true checksArray RolCheck return 1 ) rollout TagObject "Tag Object" ( button bSKL "Skeleton file:" width:80 pos:[12,15] height:20 button bSGP "SGP file:" width:80 pos:[12,45] height:20 enabled:false editText eSKL "" pos:[100,15] width:184 height:20 editText eSGP "" text:"Not Used" pos:[100,45] width:184 height:20 enabled:false label lGObject "Game Object:" pos:[16,82] editText eGObject "" pos:[100,80] width:150 height:20 button bTag "Tag" pos:[40,120] width:100 height:25 enabled:false button bCancel "Cancel" pos:[170,120] width:100 height:25 on eSKL changed state do ( if eSKL.text != "" and eGObject.text != "" then ( bTag.enabled = true ) else ( bTag.enabled = false ) ) -- on eSGP changed state do -- ( -- if eSKL.text != "" and eSGP.text != "" and eGObject.text != "" then -- ( -- bTag.enabled = true -- ) else ( -- bTag.enabled = false -- ) -- ) -- on bSGP pressed do -- ( -- ) on eGObject changed state do ( if eSKL.text != "" and eGObject.text != "" then ( bTag.enabled = true ) else ( bTag.enabled = false ) ) on bSKL pressed do ( SKLfilename = getOpenFileName caption:"SKL file to open:" \ types:"SKL Skeleton File (*.skl)|*.skl|" filename:(WorkingDir + "\\") if SKLfilename == undefined then return 0 SkeletonArr = filterstring SKLfilename "\\" for c in 1 to WorkDirArr.count do ( if (matchpattern WorkDirArr[c] pattern:SkeletonArr[c] ignorecase:true) != true then ( messagebox ("Skeleton file is not part of the Working Directory path" + \ "\nPlease change the Working Directory or the location of the Skeleton File") \ title:"Mismatch paths" return 0 ) ) global SKLentry = undefined for d in (WorkDirArr.count + 1) to (SkeletonArr.count - 1) do ( if SKLentry == undefined then ( SKLentry = SkeletonArr[d] ) else ( SKLentry = (SKLentry + "/" + SkeletonArr[d]) ) ) SKLnoExt = filterstring SkeletonArr[SkeletonArr.count] "." SKLentry = (SKLentry + "/" + SKLnoExt[1]) eSKL.text = ((SKLentry as string) + "." + (SKLnoExt[2] as string)) ) on bTag pressed do ( if (getUserPropBuffer filteredObj[RolCheck]) != "" then ( setUserPropBuffer filteredObj[RolCheck] ((getUserPropBuffer filteredObj[RolCheck]) + \ "\n" + "csp_export = \r\n" + "csp_game_object = " + eGObject.text + "\r\n" + \ "csp_skeleton = " + SKLentry + "\r\n") ) else ( setUserPropBuffer filteredObj[RolCheck] ("csp_export = \r\n" + \ "csp_game_object = " + eGObject.text + "\r\n" + \ "csp_skeleton = " + SKLentry + "\r\n") ) deleteItem checksArray RolCheck insertItem true checksArray RolCheck destroydialog TagObject ) on bCancel pressed do ( lv_objects.ListItems[RolCheck].checked = false destroydialog TagObject return 0 ) on TagObject close do ( fillInSpreadSheet lv_objects ) ) -- end rollout createdialog TagObject width:300 height:170 pos:[(getdialogpos taggedrol)[1]+200,(getdialogpos taggedrol)[2]+207] ) ) --end compare ) else ( -- end lv_objects not undefined messagebox "Problem with selected item. Please contact author to fix this code" title:"Error!" ) ) --end w loop ) -- ################# ABOUT on bAbout pressed do ( rollout rolAbout "About" ( label ab1 "Tag n' Possess v2.7" label ab2 "Dani Rosen \xa9 2006" progressBar horizLine "ProgressBar" height:3 enabled:true value:100 color:(color 10 10 0) label ab3 "This tool lists objects in the scene that are tagged and/or" align:#left label ab4 "taggable for export. Used for game vignette exports." align:#left height:20 label ab5 "Click an item to modify it; double-click to select it." align:#left label ab6 "Click TAG header to select all Tagged objects." align:#left label ab7 "Click OBJECT NAME header to select all objects." align:#left height:20 label ab8 "The CUSTOM box doesn't add a space by default - so" align:#left label ab9 "creating a note in the form of \"fade out 5\" will require" align:#left label ab10 "putting \" 5\" in the Custom box (with a space before the 5)." align:#left height:20 label ab11 "Adding a note where a note already exists will give you" align:#left label ab12 "the option of adding it as another note in a form of a" align:#left label ab13 "new line, or replacing it." align:#left height:20 label ab14 "If there are multiple NoteTracks available for one object," align:#left label ab15 "the tool should pick up the right one that it created." align:#left label ab16 "Otherwise, it chooses the first one it finds. If the first note-" align:#left label ab18 "track is not the one you want to work on (say - the subtitle" align:#left label ab19 "track), then choose the option to DROP the NoteTrack," align:#left label ab20 "which will attempt to expose the next one to the tool." align:#left label ab21 "If only one note-track exists, the DROP option will create" align:#left label ab22 "a new one to work on." align:#left ) createdialog rolAbout width:300 height:420 ) -- ################# RESIZE on TaggedRol resized newSize do ( lv_objects.size = [(TaggedRol.width - 8),(TaggedRol.height - 87)] ) ) try(destroyDialog TaggedRol)catch() createdialog TaggedRol 450 245 style:#(#style_titlebar, #style_border, #style_sysmenu, #style_resizing) )