global gRsZoneViewData, gRsZoneViewFuncs callbacks.removeScripts id:#RsZoneView if (gRsZoneViewData != undefined) do ( RsZoneViewFuncs.CloseTool() ) -- Struct holding data and control-links for tool: struct RsZoneViewData ( ToolName = "PopZone Viewer", VersionNum = 1.06, VersionName = "Rhetorical Sun", ToolWidth = 700, ToolHeight = 400, zoneDataFolder = (RsConfigGetCommonDir core:True) + "data/levels/" + (RsConfigGetProjectName core:True), zonebindPath = zoneDataFolder + "/zonebind.meta", popZonePath = zoneDataFolder + "/popzone.ipl", ToolDialog = undefined, ItemListCtrl = undefined, SelectTimer = undefined, DoObjects = True, ViewLabels = True, ShowPlantIdxClr = False, ShowDirtClr = False, ShowAreaClr = True, DrawWireframe = False, PopZonesList = #(), ZoneTypeList = (filterString (GetControlData "RsPopZone" "Zone type") ","), -- Colours to use when colouring zones by plantsMgrTxdIdx: -- 0 = nothing - gray -- 1 = countryside - green -- 2 = ocean - so blue -- 3 = Not used yet - bright pink -- 4 = Not used yet - bright pink -- 5 = Not used yet - bright pink -- 6 = Not used yet - bright pink -- 7 = Default, memory hungry, so RED plantsMgrClrs = #((color 180 180 180), (color 0 180 0), (color 0 0 180), (red + blue), (red + blue), (red + blue), (red + blue), (red)) ) -- Struct used to hold data for individual popZones: struct popZoneStruct ( name, obj, meshNode, meta, boxMin, boxMax, boxSize, boxVol, boxArea, areaName, zoneType=0, dirtColour=(red + blue), subBoxes = #(), vfxRegion="", plantsIdx=7, listCtrlRow, -- Return values for building list-rows: fn GetListLabels = #("Zone Name", "Zone Type", "Area Name", "VFX Region", "PlantsMgrTxdIdx", "Has Metadata"), fn GetRowStrings = ( local zoneName = This.Name local zoneTypeStr = gRsZoneViewData.ZoneTypeList[This.ZoneType + 1] local zoneArea = This.AreaName local hasMeta = (This.Meta != undefined) return #(zoneName, zoneTypeStr, zoneArea, vfxRegion, plantsIdx, hasMeta) ), fn getMetaAttrib attribName = ( if (meta == undefined) or not (meta.ContainsKey attribName) do return undefined return (meta.Item attribName).Value ), fn getDirtColour useMeta:meta = ( local vals = for attribName in #("dirtRed", "dirtGreen", "dirtBlue") collect ( (useMeta.Item attribName).Value as integer ) color vals[1] vals[2] vals[3] ), -- Return colour to use for object: fn UseObjColour = ( case of ( (gRsZoneViewData.ShowPlantIdxClr):(gRsZoneViewData.plantsMgrClrs[plantsIdx + 1]) (gRsZoneViewData.ShowDirtClr):(dirtColour) Default: --(gRsZoneViewData.ShowAreaClr): ( -- Set colour-seed based on area-name, to give each area same colour: seed (getHashValue (toLower areaName) 1) RsGetRandomColour() ) ) ), fn generateObj = undo off ( if (subBoxes.count == 0) do return undefined local objName = (areaName + ":" + name) local zoneSize = boxMax - boxMin local zonePos = boxMin + [zoneSize.x / 2, zoneSize.y / 2, 0] local colour = UseObjColour() obj = (Editable_Mesh name:objName wireColor:colour pos:ZonePos backFaceCull:True) -- Set transform-locks on obj: setTransformLockFlags obj #{1..9} if (meshNode == undefined) do ( local vertPosList = #() local faceVertLists = #() for item in subBoxes do ( local subBoxMin = item.boxMin local subBoxMax = item.boxMax local subBoxSize = (subBoxMax - subBoxMin) subBoxMin.Z = 0 subBoxMax.Z = 0 local corners = #(subBoxMin, [subBoxMax.X, subBoxMin.Y, 0], subBoxMax, [subBoxMin.X, subBoxMax.Y, 0]) local faceVerts = for cornerPos in corners collect ( local vertNum = findItem vertPosList cornerPos if (vertNum == 0) do ( append vertPosList cornerPos vertNum = vertPosList.count ) vertNum ) append faceVertLists [faceVerts[1], faceVerts[2], faceVerts[3]] append faceVertLists [faceVerts[1], faceVerts[3], faceVerts[4]] ) -- Create a mesh from the loaded data: local newMesh = TriMesh() setMesh newMesh vertices:vertPosList faces:faceVertLists if (subBoxes.count > 1) then ( -- Optimise generated mesh: meshop.optimize newMesh 0.1 1.0 0.0 0.0 saveMatBoundries:false saveSmoothBoundries:false autoEdge:true ) else ( -- Hide middle edges: setEdgeVis newMesh 1 3 False setEdgeVis newMesh 2 1 False ) -- Move verts: meshop.moveVert newMesh #all -ZonePos -- Invert faces, if using wireframe-mode: if gRsZoneViewData.DrawWireframe do ( meshop.flipNormals newMesh #all ) -- Store mesh seperately for easy retrieval: meshNode = (createInstance Editable_Mesh) meshNode.mesh = newMesh ) -- Retrieve previously-generated mesh: obj.mesh = (copy meshNode.mesh) return objzZ ) ) struct RsZoneViewFuncs ( fn SetStatusTitle PromptText DoPushPrompt:False = ( local NewText = gRsZoneViewData.ToolName + (if (PromptText == "") then "" else (": " + PromptText)) gRsZoneViewData.ToolDialog.Text = NewText if DoPushPrompt do ( PushPrompt PromptText ) return OK ), fn SelectCallback = ( --print "SELECTY" -- Focus on ItemList control: local ItemListCtrl = gRsZoneViewData.ItemListCtrl ItemListCtrl.Focus() -- Make sure deferred-selection timer is stopped: gRsZoneViewData.SelectTimer.Stop() -- Update list-selections: local showFirstRow = True for item in gRsZoneViewData.PopZonesList do ( local newSel = (isValidNode item.obj) and (item.obj.isSelected) if (item.listCtrlRow.Selected != newSel) do ( item.listCtrlRow.Selected = newSel if newSel and showFirstRow do ( ItemListCtrl.CurrentCell = item.listCtrlRow.Cells.Item[0] showFirstRow = False ) ) ) -- Stop timer again (it'll have been started by the selection-changing above) gRsZoneViewData.SelectTimer.Stop() return OK ), fn genMissingObjs popZones: = ( if (popZones == unsupplied) do ( popZones = gRsZoneViewData.PopZonesList ) local regenItems = for item in popZones where (not isValidNode item.obj) collect item if (regenItems.count != 0) do ( SetStatusTitle "Generating Zone Meshes..." DoPushPrompt:True --local TimeStart = TimeStamp() for item in regenItems do ( item.generateObj() ) completeRedraw() --format "Time to generate: %s\n" ((TimeStamp() - TimeStart) / 1000) popPrompt() ) return OK ), fn deleteObjs = undo off ( local popZones = gRsZoneViewData.PopZonesList local delObjs = for item in popZones where (isValidNode item.obj) collect item.obj if (delObjs.count != 0) do ( delete delObjs ) ), fn preSaveCallback = ( -- Remove callbacks and objects during save: gRsZoneViewFuncs.RemoveCallbacks() gRsZoneViewFuncs.DeleteObjs() callbacks.addScript #filePostSaveProcess "gRsZoneViewFuncs.postSaveCallback()" id:#RsZoneView ), fn postSaveCallback = ( gRsZoneViewFuncs.GenMissingObjs() gRsZoneViewFuncs.AddCallbacks() ), -- Called to close the dialog and clear data-struct: fn CloseTool = ( --print "CloseTool" if (gRsZoneViewData != undefined) and (gRsZoneViewData.ToolDialog != undefined) do ( gRsZoneViewData.ToolDialog.Close() ) gRsZoneViewData = undefined return OK ), -- Called when viewport redraws: fn viewportDraw = ( local ToolDialog = if (gRsZoneViewData == undefined) then undefined else gRsZoneViewData.ToolDialog if (ToolDialog == undefined) or (not ToolDialog.Visible) do ( gRsZoneViewFuncs.removeCallbacks() ) if not (gRsZoneViewData.ViewLabels) do return False local drawClr = White gw.setTransform (Matrix3 1) for item in gRsZoneViewData.PopZonesList where (isValidNode item.obj) and (item.listCtrlRow.Selected) do ( local pos = (gw.wtransPoint item.obj.pos) gw.wMarker pos #hollowBox color:drawClr pos.X += 2 pos.Y += 8 gw.wtext pos (" zone: " + item.name) color:drawClr pos.X += 2 pos.Y += 12 gw.wtext pos (" area: " + item.areaName) color:drawClr ) gw.enlargeUpdateRect #whole gw.updateScreen() return OK ), fn RemoveCallbacks = ( callbacks.removeScripts id:#RsZoneView unregisterRedrawViewsCallback viewportDraw ), fn AddCallbacks = ( RemoveCallbacks() callbacks.addScript #selectionSetChanged "gRsZoneViewFuncs.SelectCallback()" id:#RsZoneView callbacks.addScript #nodePostDelete "gRsZoneViewFuncs.genMissingObjs()" id:#RsZoneView callbacks.addScript #filePreSaveProcess "gRsZoneViewFuncs.preSaveCallback()" id:#RsZoneView callbacks.addScript #filePreOpenProcess "gRsZoneViewFuncs.closeTool()" id:#RsZoneView callbacks.addScript #preSystemShutdown "gRsZoneViewFuncs.closeTool()" id:#RsZoneView callbacks.addScript #systemPreReset "gRsZoneViewFuncs.closeTool()" id:#RsZoneView callbacks.addScript #systemPreNew "gRsZoneViewFuncs.closeTool()" id:#RsZoneView registerRedrawViewsCallback viewportDraw ), fn LoadPopZones = ( gRsZoneViewData.popZonesList = #() local popZonesList = gRsZoneViewData.popZonesList local zonebindPath = gRsZoneViewData.zonebindPath local popZonePath = gRsZoneViewData.popZonePath local doObjects = gRsZoneViewData.doObjects format "%\n" zonebindPath format "%\n" popZonePath SetStatusTitle "Perforce Sync..." gRsPerforce.sync #(zonebindPath, popZonePath) if not doesFileExist zonebindPath do ( print ("zonebind.meta doesn't exist!\n" + zonebindPath) return false ) if not doesFileExist popZonePath do ( print ("popzone.ipl doesn't exist!\n" + popZonePath) return false ) -- Read in PopZone.ipl: ( SetStatusTitle "Reading PopZone.ipl..." DoPushPrompt:True local popzoneFile = openFile popZonePath skipToString popzoneFile "zone" local continueReading = True while continueReading and (not eof popzoneFile) do ( local thisLine = readline popzoneFile local lineTokens = filterString thisLine ", \t" case of ( (lineTokens.count == 0):() (lineTokens[1] == "end"):(continueReading = False) Default: ( local zoneName = (toLower lineTokens[1]) local popZone = popZoneStruct name:zoneName -- Load sizes: popZone.boxMin = [lineTokens[2] as float, lineTokens[3] as float, lineTokens[4] as float] popZone.boxMax = [lineTokens[5] as float, lineTokens[6] as float, lineTokens[7] as float] popZone.areaName = (lineTokens[8] as string) popZone.zoneType = (lineTokens[9] as integer) local boxSize = (popZone.boxMax - popZone.boxMin) popZone.boxVol = (boxSize.X * boxSize.Y * boxSize.Z) popZone.boxArea = (boxSize.X * boxSize.Y) -- Add popzone to list: append popZonesList popZone ) ) ) close popzoneFile popPrompt() ) -- Read in ZoneBind.meta: if doObjects do ( SetStatusTitle "Reading ZoneBind.meta..." DoPushPrompt:True local metaManager = RsGetMetaDataManager() metaManager.LoadWithMetaFile zonebindPath local zoneList = metaManager.FindFirstStructureNamed "zones" for zoneIdx = 0 to (zoneList.length - 1) do ( local zoneNode = zoneList.Item zoneIdx local zoneName = toLower (zoneNode.Item "zoneName").Value -- Find PopZone(s) with matching name: local theseZones = for popZone in popZonesList where (popZone.name == zoneName) collect popZone if (theseZones.count != 0) do ( local dirtColour = popZoneStruct.getDirtColour useMeta:zoneNode theseZones.meta = zoneNode theseZones.dirtColour = dirtColour ) if (zoneNode.ContainsKey "vfxRegion") do ( theseZones.vfxRegion = (zoneNode.Item "vfxRegion").Value ) if (zoneNode.ContainsKey "plantsMgrTxdIdx") do ( theseZones.plantsIdx = (zoneNode.Item "plantsMgrTxdIdx").Value ) ) popPrompt() ) -- Sorts zones from smallest to largest (smallest one is used in-game when zones overlap) fn sortZoneVols v1 v2 = ( case of ( (v1.boxVol < v2.boxVol):-1 (v1.boxVol > v2.boxVol):1 Default:0 ) ) local BoxHashes = #() -- Find groups of intersecting zones, and chop those up into sub-zone boxes: if doObjects do ( local intersectZones = #() local intersectTested = #{} intersectTested.count = popZonesList.count local Cancelled = False local zoneCount = popZonesList.count for initialZoneNum = 1 to zoneCount where not intersectTested[initialZoneNum] while (not Cancelled) do ( SetStatusTitle "Finding intersecting zones..." DoPushPrompt:True local theseIntersectNums = #(initialZoneNum) local theseIntersectBits = #{initialZoneNum} local intersectZoneIdx = 0 while (intersectZoneIdx < theseIntersectNums.count) and (not Cancelled) do ( --format "% < %; %\n" intersectZoneIdx theseIntersectNums.count (intersectTested as string) intersectZoneIdx += 1 local intersectZoneNum = theseIntersectNums[intersectZoneIdx] local thisIntersectZone = popZonesList[intersectZoneNum] intersectTested[intersectZoneNum] = True -- Test 'thisIntersectZone' against all zones that haven't been tested yet: for testZoneNum = 1 to zoneCount where not (intersectTested[testZoneNum] or theseIntersectBits[testZoneNum]) do ( local testZone = popZonesList[testZoneNum] -- If zones intersect, add it to 'theseIntersectNums': if ( (testZone.boxMin.X < thisIntersectZone.boxMax.X) and (testZone.boxMax.X > thisIntersectZone.boxMin.X) and (testZone.boxMin.Y < thisIntersectZone.boxMax.Y) and (testZone.boxMax.Y > thisIntersectZone.boxMin.Y) ) do ( append theseIntersectNums testZoneNum theseIntersectBits[testZoneNum] = True ) ) Cancelled = keyboard.escPressed ) PopPrompt() if (theseIntersectNums.count == 1) then ( -- Single box that doesn't intersect anything: local thisZone = popZonesList[initialZoneNum] append thisZone.subBoxes (dataPair boxMin:thisZone.boxMin boxMax:thisZone.boxMax) ) else ( SetStatusTitle "Gridding Zones into sub-boxes..." DoPushPrompt:True -- Sort cluster of intersecting zones by volume: -- (smaller zone is used if point is in multiple zones) local foundZones = for zoneNum in theseIntersectNums collect popZonesList[zoneNum] qsort foundZones sortZoneVols -- Build lists of box-edge x/y values: local xEdges = #() local yEdges = #() for popZone in foundZones do ( join xEdges #(popZone.boxMin.X, popZone.boxMax.X) join yEdges #(popZone.boxMin.Y, popZone.boxMax.Y) ) -- Make values unique, sort: xEdges = (makeUniqueArray xEdges) yEdges = (makeUniqueArray yEdges) sort xEdges sort yEdges -- Chop each zone up into unique sub-boxes: for ThisZone in FoundZones while (not Cancelled) do ( local ZoneMinX = ThisZone.boxMin.X local ZoneMaxX = ThisZone.boxMax.X local ZoneMinY = ThisZone.boxMin.Y local ZoneMaxY = ThisZone.boxMax.Y local ZoneXEdges = for Val in xEdges where (Val >= ZoneMinX) while (Val <= ZoneMaxX) collect Val local ZoneYEdges = for Val in yEdges where (Val >= ZoneMinY) while (Val <= ZoneMaxY) collect Val for y = 1 to (ZoneYEdges.count - 1) do ( local minVal = [0, ZoneYEdges[y], 0] local maxVal = [0, ZoneYEdges[y + 1], 0] for x = 1 to (ZoneXEdges.count - 1) do ( minVal.x = ZoneXEdges[x] maxVal.x = ZoneXEdges[x + 1] local hashArrayIdx = ((abs (0.1 * minVal.X) as integer) + 1) local hashArray = boxHashes[hashArrayIdx] -- Collect box, if similar one hasn't already been used: local isUnique = True local boxHash = GetHashValue #(minVal, maxVal) 1 local hashArray = boxHashes[hashArrayIdx] if (hashArray == undefined) then ( boxHashes[hashArrayIdx] = #(boxHash) ) else ( isUnique = (appendIfUnique hashArray boxHash) ) if isUnique do ( append ThisZone.SubBoxes (DataPair boxMin:(copy minVal) boxMax:(copy maxVal)) ) ) ) Cancelled = keyboard.escPressed ) -- Dispose of hash-array data... for Item in boxHashes where (isKindOf Item Array) do ( Item.Count == 0 ) PopPrompt() ) PopPrompt() ) ) BoxHashes.Count = 0 return True ), ----------------------------- -- CONTROL EVENTS: -- ----------------------------- -- Event: Triggered by "Draw Labels" tickybox fn ShowLabel_Changed Sender Args = ( gRsZoneViewData.ViewLabels = Sender.Checked CompleteRedraw() -- Make sure list-selection is retained: gRsZoneViewFuncs.SelectCallback() ), -- Event: Triggered by "Wireframe" tickybox fn Wireframe_Changed Sender Args = ( gRsZoneViewData.DrawWireframe = Sender.Checked -- Flip faces to show Wireframe border: for ThisZone in gRsZoneViewData.PopZonesList do ( Meshop.FlipNormals ThisZone.MeshNode.Mesh #all ThisZone.Obj.Mesh = (copy ThisZone.MeshNode.Mesh) ) -- Inverted-faces trick needs 'Edge Faces' to be active: if gRsZoneViewData.DrawWireframe do ( viewport.SetShowEdgeFaces True ) CompleteRedraw() -- Make sure list-selection is retained: gRsZoneViewFuncs.SelectCallback() ), -- Event: Triggered when radiobuttons are clicked: fn ShowClrBtn_Changed Sender Args = ( -- Which button was clicked? local btnList = Sender.Tag.Value local btnIdx = (findItem btnList Sender) local newStates = #{btnIdx} -- Set states: gRsZoneViewData.ShowPlantIdxClr = newStates[1] gRsZoneViewData.ShowDirtClr = newStates[2] gRsZoneViewData.ShowAreaClr = newStates[3] -- Set object wirecolours to match new state: for Item in gRsZoneViewData.PopZonesList where (isValidNode Item.Obj) do ( Item.Obj.WireColor = (Item.UseObjColour()) ) ), -- Event: Selects objects after timer interval: fn SelectTimer_Tick Sender Args = ( --print "SelectTimer_Tick" Sender.Stop() gRsZoneViewFuncs.removeCallbacks() local zoneList = gRsZoneViewData.PopZonesList local selObjs = for item in zoneList where (item.listCtrlRow.Selected) and (isValidNode item.obj) collect (item.obj) if (selObjs.count != 0) do ( select selObjs max tool ZoomExtents ) gRsZoneViewFuncs.addCallbacks() ), -- Event: Called when ItemListCtrl is clicked - brings up rightclick menu: fn ItemList_Clicked Sender Args = ( if (args.RowIndex < 0) do return false local rightClick = args.button.equals args.button.right if rightClick do ( -- Exclusive-select row if it's not currently selected: local clickRow = Sender.Rows.Item[args.RowIndex] if not clickRow.Selected do ( sender.ClearSelection() clickRow.Selected = true ) -- Rightclick menu: rcmenu RSmenu_dialogList ( local ItemListCtrl, SelRows fn HasSel = (SelRows.Count != 0) menuItem itmCopy "Copy selected to clipboard" filter:HasSel on itmCopy picked do ( -- Build text-list for copying to clipboard: local copyText = stringStream "" for SelRowNum = 1 to SelRows.Count do ( local Row = SelRows[SelRowNum] for ColNum = 1 to Row.Cells.Count do ( format "%" row.cells.item[ColNum - 1].value to:copyText if (ColNum != Row.Cells.Count) do ( format ", " to:copyText ) ) if selRowNum != SelRows.Count do ( format "\n" to:copyText ) ) setclipboardText (copyText as string) ) on RSmenu_dialogList open do ( ItemListCtrl = gRsZoneViewData.ItemListCtrl SelRows = (for n = 0 to (ItemListCtrl.SelectedRows.count - 1) collect ItemListCtrl.SelectedRows.Item[n]) ) ) popUpMenu RSmenu_dialogList ) ), -- Event: Triggered when list-selection changes: fn ItemList_SelChanged Sender Args = ( --print "ItemList_SelChanged" -- Reset/start action-deferrer timer: local selectTimer = gRsZoneViewData.SelectTimer selectTimer.Stop() selectTimer.Start() ), -- Event: Clears list-selection when the form is activated: fn ToolDialog_Activated sender args = ( gRsZoneViewData.ItemListCtrl.clearSelection() ), -- Event: Triggered when ToolDialog is closed fn ToolDialog_Close Sender Args = ( --print "ToolDialog_Close" gRsZoneViewFuncs.RemoveCallbacks() -- Kill deferred-selection timer: gRsZoneViewData.SelectTimer.Dispose() gRsZoneViewFuncs.deleteObjs() gRsZoneViewData.ToolDialog.Dispose() gRsZoneViewData.ToolDialog = undefined ), ----------------------------- -- /CONTROL EVENTS -- ----------------------------- fn CreateTool = ( -- Add deferred-action selector-timer: ( local SelectTimer = dotNetObject "Timer" gRsZoneViewData.SelectTimer = SelectTimer SelectTimer.Tag = ItemListCtrl SelectTimer.interval = 200 dotNet.addEventHandler SelectTimer "Tick" SelectTimer_Tick ) -- Define form: ( --DotNet properties local DockStyle_Fill = (dotNetClass "DockStyle").Fill local SizeType_Absolute = (dotNetClass "SizeType").Absolute local SizeType_Percent = (dotNetClass "SizeType").Percent local ToolDialog = (dotNetObject "MaxCustomControls.MaxForm") gRsZoneViewData.ToolDialog = ToolDialog SetStatusTitle "" ToolDialog.Width = gRsZoneViewData.ToolWidth ToolDialog.Height = gRsZoneViewData.ToolHeight -- Make list-dialog resizable: ToolDialog.FormBorderStyle = ToolDialog.FormBorderStyle.Sizable ToolDialog.MinimizeBox = false ToolDialog.MaximizeBox = false ToolDialog.StartPosition = ToolDialog.StartPosition.CenterScreen dotNet.addEventHandler ToolDialog "Activated" ToolDialog_Activated dotNet.addEventHandler ToolDialog "FormClosing" ToolDialog_Close dotNet.setLifetimeControl ToolDialog #dotnet -- Main layout-table: ( -- Set up main layout-table, with three rows: Banner, list, extra bits: local MainTable = dotNetObject "TableLayoutPanel" MainTable.Dock = DockStyle_Fill ToolDialog.Controls.Add MainTable MainTable.cellBorderStyle = MainTable.CellBorderStyle.None MainTable.RowCount = 3 -- TechArt Banner: ( MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Absolute 40) local BannerPanel = dotNetObject "Panel" BannerPanel.dock = DockStyle_Fill MainTable.Controls.Add BannerPanel 0 0 local VerNum = gRsZoneViewData.VersionNum local VerName = gRsZoneViewData.VersionName local TheBanner = MakeRsBanner dn_Panel:BannerPanel wiki:"PopZone Viewer" versionNum:VerNum versionName:VerName filename:(getThisScriptFilename()) TheBanner.Setup() ) -- Set up ItemListCtrl: ( MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Percent 100) -- Make sure "RsCustomDataGridView" is defined: RS_CustomDataGrid() local ItemListCtrl = dotNetObject "RsCustomDataGridView" gRsZoneViewData.ItemListCtrl = ItemListCtrl ItemListCtrl.dock = DockStyle_Fill MainTable.Controls.Add ItemListCtrl 0 1 dotNet.addEventHandler ItemListCtrl "CellMouseUp" ItemList_Clicked dotNet.addEventHandler ItemListCtrl "SelectionChanged" ItemList_SelChanged dotNet.setLifetimeControl ItemListCtrl #dotnet ItemListCtrl.ReadOnly = False ItemListCtrl.SelectionMode = ItemListCtrl.SelectionMode.FullRowSelect ItemListCtrl.AllowUserToAddRows = False ItemListCtrl.AllowUserToDeleteRows = False ItemListCtrl.AllowUserToOrderColumns = False ItemListCtrl.AllowUserToResizeColumns = True ItemListCtrl.AllowUserToResizeRows = False ItemListCtrl.AllowDrop = False ItemListCtrl.MultiSelect = True ItemListCtrl.DefaultCellStyle.WrapMode = ItemListCtrl.DefaultCellStyle.WrapMode.True ItemListCtrl.AutoSizeRowsMode = ItemListCtrl.AutoSizeRowsMode.AllCells local textClr = (colorMan.getColor #windowText) * 255 local windowClr = (colorMan.getColor #window) * 255 ItemListCtrl.DefaultCellStyle.backColor = (dotNetClass "System.Drawing.Color").FromArgb windowClr[1] windowClr[2] windowClr[3] ItemListCtrl.DefaultCellStyle.foreColor = (dotNetClass "System.Drawing.Color").FromArgb textClr[1] textClr[2] textClr[3] ItemListCtrl.AutoSizeColumnsMode = ItemListCtrl.AutoSizeColumnsMode.Fill ItemListCtrl.ColumnHeadersVisible = True -- Add text-columns: local listLabels = popZoneStruct.GetListLabels() for n = 1 to listLabels.count do ( local textCol = dotNetObject "DataGridViewTextBoxColumn" textCol.ReadOnly = true -- Set last column-size to fill: textCol.AutoSizeMode = if (n == listLabels.count) then textCol.AutoSizeMode.Fill else textCol.AutoSizeMode.AllCells local newColNum = ItemListCtrl.Columns.Add textCol textCol.HeaderText = listLabels[newColNum + 1] ) ) -- Set up the rest of the option-controls: ( MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Absolute 30) local OptionPanel = dotNetObject "FlowLayoutPanel" OptionPanel.dock = DockStyle_Fill MainTable.Controls.Add OptionPanel 0 2 -- "Draw Labels" button ( local NewCtrl = dotNetObject "CheckBox" NewCtrl.Text = "Draw Labels for Selected" NewCtrl.checked = gRsZoneViewData.ViewLabels NewCtrl.FlatStyle = NewCtrl.FlatStyle.System NewCtrl.AutoSize = True dotNet.addEventHandler NewCtrl "CheckedChanged" ShowLabel_Changed dotNet.setLifetimeControl NewCtrl #dotnet OptionPanel.Controls.Add NewCtrl ) -- 'Wireframe' button ( local NewCtrl = dotNetObject "CheckBox" NewCtrl.Text = "Wireframe" NewCtrl.checked = gRsZoneViewData.DrawWireframe NewCtrl.FlatStyle = NewCtrl.FlatStyle.System NewCtrl.AutoSize = True dotNet.addEventHandler NewCtrl "CheckedChanged" Wireframe_Changed dotNet.setLifetimeControl NewCtrl #dotnet OptionPanel.Controls.Add NewCtrl ) -- Label: ( local NewCtrl = dotNetObject "Label" NewCtrl.Text = "Show Colours:" NewCtrl.AutoSize = True NewCtrl.Margin = dotNetObject "Padding" 0 4 0 0 OptionPanel.Controls.Add NewCtrl ) -- Object-colour radiobuttons local ShowClrBtns = #() for Item in #(dataPair Text:"PlantIdx" Val:gRsZoneViewData.ShowPlantIdxClr, dataPair Text:"Dirt" Val:gRsZoneViewData.ShowDirtClr, dataPair Text:"Area Name" Val:gRsZoneViewData.ShowAreaClr) collect ( local NewCtrl = dotNetObject "RadioButton" NewCtrl.Text = Item.Text NewCtrl.Checked = Item.Val NewCtrl.Tag = (dotNetMXSValue ShowClrBtns) NewCtrl.AutoSize = True dotNet.addEventHandler NewCtrl "CheckedChanged" ShowClrBtn_Changed dotNet.setLifetimeControl NewCtrl #dotnet OptionPanel.Controls.Add NewCtrl append ShowClrBtns NewCtrl ) ) ) ToolDialog.ShowModeless() ) -- Force UI to draw: Windows.ProcessPostedMessages() -- Load and show data: ( -- Load data: SetStatusTitle "Loading Data..." if (not LoadPopZones()) do ( RsZoneViewFuncs.CloseTool() return False ) -- Add data to list: ( SetStatusTitle "Showing List..." local showListData = for item in gRsZoneViewData.popZonesList collect (dataPair zoneData:Item rowStrings:(Item.GetRowStrings())) local ItemListCtrl = gRsZoneViewData.ItemListCtrl -- Add list-rows: for Item in ShowListData do ( local rowIdx = ItemListCtrl.Rows.Add Item.RowStrings local ThisRow = ItemListCtrl.Rows.Item[rowIdx] -- Add number to row's tag, so it remembers it if reordered: ThisRow.tag = (rowIdx + 1) -- Link row-control to ZoneData struct: Item.ZoneData.ListCtrlRow = ThisRow ) ) ) -- Trigger object-generation: if gRsZoneViewData.doObjects and (gRsZoneViewData.popZonesList.count != 0) do ( genMissingObjs popZones:gRsZoneViewData.popZonesList -- Set up Max callbacks: addCallbacks() completeRedraw() ) SetStatusTitle "" return OK ) ) gRsZoneViewData = RsZoneViewData() gRsZoneViewFuncs = RsZoneViewFuncs() gRsZoneViewFuncs.CreateTool()